summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h1
-rw-r--r--dwl.c102
2 files changed, 51 insertions, 52 deletions
diff --git a/config.def.h b/config.def.h
index b3caab3..0473b40 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,7 +1,6 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const unsigned int borderpx = 1; /* border pixel of windows */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
diff --git a/dwl.c b/dwl.c
index d630d06..1db0e40 100644
--- a/dwl.c
+++ b/dwl.c
@@ -73,7 +73,7 @@
/* enums */
enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
enum { XDGShell, LayerShell, X11Managed, X11Unmanaged }; /* client types */
-enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrDragIcon, NUM_LAYERS }; /* scene layers */
+enum { LyrBg, LyrBottom, LyrTop, LyrOverlay, LyrTile, LyrFloat, LyrFS, LyrDragIcon, NUM_LAYERS }; /* scene layers */
#ifdef XWAYLAND
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
@@ -102,7 +102,6 @@ typedef struct {
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface;
- struct wlr_scene_rect *fullscreen_bg; /* See setfullscreen() for info */
struct wl_list link;
struct wl_list flink;
union {
@@ -171,6 +170,7 @@ struct Monitor {
struct wl_list link;
struct wlr_output *wlr_output;
struct wlr_scene_output *scene_output;
+ struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
struct wl_listener frame;
struct wl_listener destroy;
struct wl_listener request_state;
@@ -448,6 +448,9 @@ arrange(Monitor *m)
if (c->mon == m)
wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m));
+ wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
+ (c = focustop(m)) && c->isfullscreen);
+
if (m && m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
motionnotify(0);
@@ -469,6 +472,8 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
wlr_scene_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area);
wlr_scene_node_set_position(&layersurface->popups->node,
layersurface->scene->node.x, layersurface->scene->node.y);
+ layersurface->geom.x = layersurface->scene->node.x;
+ layersurface->geom.y = layersurface->scene->node.y;
}
}
@@ -593,15 +598,11 @@ void
checkidleinhibitor(struct wlr_surface *exclude)
{
int inhibited = 0;
+ struct wlr_scene_tree *tree;
struct wlr_idle_inhibitor_v1 *inhibitor;
wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
- Client *c;
- if (exclude == inhibitor->surface)
- continue;
- /* In case we can't get a client from the surface assume that it is
- * visible, for example a layer surface */
- if (!(c = client_from_wlr_surface(inhibitor->surface))
- || VISIBLEON(c, c->mon)) {
+ if (exclude != inhibitor->surface && (tree = inhibitor->surface->data)
+ && tree->node.enabled) {
inhibited = 1;
break;
}
@@ -661,6 +662,7 @@ cleanupmon(struct wl_listener *listener, void *data)
m->wlr_output->data = NULL;
wlr_output_layout_remove(output_layout, m->wlr_output);
wlr_scene_output_destroy(m->scene_output);
+ wlr_scene_node_destroy(&m->fullscreen_bg->node);
closemon(m);
free(m);
@@ -812,7 +814,7 @@ createlayersurface(struct wl_listener *listener, void *data)
layers[wlr_layer_surface->pending.layer], wlr_layer_surface);
layersurface->scene = layersurface->scene_layer->tree;
layersurface->popups = wlr_layer_surface->surface->data =
- &wlr_scene_tree_create(layers[wlr_layer_surface->pending.layer])->node;
+ wlr_scene_tree_create(layers[wlr_layer_surface->pending.layer]);
layersurface->scene->node.data = layersurface;
@@ -881,6 +883,18 @@ createmon(struct wl_listener *listener, void *data)
wl_list_insert(&mons, &m->link);
printstatus();
+ /* The xdg-protocol specifies:
+ *
+ * If the fullscreened surface is not opaque, the compositor must make
+ * sure that other screen content not part of the same surface tree (made
+ * up of subsurfaces, popups or similarly coupled surfaces) are not
+ * visible below the fullscreened surface.
+ *
+ */
+ /* updatemons() will resize and set correct position */
+ m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg);
+ wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0);
+
/* Adds this to the output layout in the order it was configured in.
*
* The output layout utility automatically adds a wl_output global to the
@@ -1145,7 +1159,7 @@ focusstack(const Arg *arg)
{
/* Focus the next or previous client (in tiling order) on selmon */
Client *c, *sel = selclient();
- if (!sel || (sel->isfullscreen && lockfullscreen))
+ if (!sel || sel->isfullscreen)
return;
if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) {
@@ -1736,8 +1750,6 @@ resize(Client *c, struct wlr_box geo, int interact)
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
- if (c->fullscreen_bg)
- wlr_scene_rect_set_size(c->fullscreen_bg, c->geom.width, c->geom.height);
/* wlroots makes this a no-op if size hasn't changed */
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
@@ -1845,32 +1857,16 @@ setfullscreen(Client *c, int fullscreen)
return;
c->bw = fullscreen ? 0 : borderpx;
client_set_fullscreen(c, fullscreen);
+ wlr_scene_node_reparent(&c->scene->node, layers[fullscreen
+ ? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
if (fullscreen) {
c->prev = c->geom;
resize(c, c->mon->m, 0);
- /* The xdg-protocol specifies:
- *
- * If the fullscreened surface is not opaque, the compositor must make
- * sure that other screen content not part of the same surface tree (made
- * up of subsurfaces, popups or similarly coupled surfaces) are not
- * visible below the fullscreened surface.
- *
- * For brevity we set a black background for all clients
- */
- if (!c->fullscreen_bg) {
- c->fullscreen_bg = wlr_scene_rect_create(c->scene,
- c->geom.width, c->geom.height, fullscreen_bg);
- wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node);
- }
} else {
/* restore previous size instead of arrange for floating windows since
* client positions are set by the user and cannot be recalculated */
resize(c, c->prev, 0);
- if (c->fullscreen_bg) {
- wlr_scene_node_destroy(&c->fullscreen_bg->node);
- c->fullscreen_bg = NULL;
- }
}
arrange(c->mon);
printstatus();
@@ -1988,6 +1984,7 @@ setup(void)
layers[LyrBottom] = wlr_scene_tree_create(&scene->tree);
layers[LyrTile] = wlr_scene_tree_create(&scene->tree);
layers[LyrFloat] = wlr_scene_tree_create(&scene->tree);
+ layers[LyrFS] = wlr_scene_tree_create(&scene->tree);
layers[LyrTop] = wlr_scene_tree_create(&scene->tree);
layers[LyrOverlay] = wlr_scene_tree_create(&scene->tree);
layers[LyrDragIcon] = wlr_scene_tree_create(&scene->tree);
@@ -2149,9 +2146,6 @@ void
startdrag(struct wl_listener *listener, void *data)
{
struct wlr_drag *drag = data;
- /* During drag the focus isn't sent to clients, this causes that
- * we don't update border color acording the pointer coordinates */
- focusclient(NULL, 0);
if (!drag->icon)
return;
@@ -2357,6 +2351,9 @@ updatemons(struct wl_listener *listener, void *data)
/* Don't move clients to the left output when plugging monitors */
arrange(m);
+ wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
+ wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
+
config_head->state.enabled = 1;
config_head->state.mode = m->wlr_output->current_mode;
config_head->state.x = m->m.x;
@@ -2426,7 +2423,7 @@ xytonode(double x, double y, struct wlr_surface **psurface,
Client *c = NULL;
LayerSurface *l = NULL;
const int *layer;
- int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg };
+ int focus_order[] = { LyrOverlay, LyrTop, LyrFS, LyrFloat, LyrTile, LyrBottom, LyrBg };
for (layer = focus_order; layer < END(focus_order); layer++) {
if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) {
@@ -2499,14 +2496,19 @@ configurex11(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, configure);
struct wlr_xwayland_surface_configure_event *event = data;
- wlr_xwayland_surface_configure(c->surface.xwayland,
- event->x, event->y, event->width, event->height);
+ if (!c->mon)
+ return;
+ if (c->isfloating || c->type == X11Unmanaged)
+ resize(c, (struct wlr_box){.x = event->x, .y = event->y,
+ .width = event->width, .height = event->height}, 0);
+ else
+ arrange(c->mon);
}
void
createnotifyx11(struct wl_listener *listener, void *data)
{
- struct wlr_xwayland_surface *xwayland_surface = data;
+ struct wlr_xwayland_surface *xsurface = data;
Client *c;
/* TODO: why we unset fullscreen when a xwayland client is created? */
wl_list_for_each(c, &clients, link)
@@ -2514,22 +2516,20 @@ createnotifyx11(struct wl_listener *listener, void *data)
setfullscreen(c, 0);
/* Allocate a Client for this surface */
- c = xwayland_surface->data = ecalloc(1, sizeof(*c));
- c->surface.xwayland = xwayland_surface;
- c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
+ c = xsurface->data = ecalloc(1, sizeof(*c));
+ c->surface.xwayland = xsurface;
+ c->type = xsurface->override_redirect ? X11Unmanaged : X11Managed;
c->bw = borderpx;
/* Listen to the various events it can emit */
- LISTEN(&xwayland_surface->events.map, &c->map, mapnotify);
- LISTEN(&xwayland_surface->events.unmap, &c->unmap, unmapnotify);
- LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11);
- LISTEN(&xwayland_surface->events.request_configure, &c->configure,
- configurex11);
- LISTEN(&xwayland_surface->events.set_hints, &c->set_hints, sethints);
- LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);
- LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify);
- LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,
- fullscreennotify);
+ LISTEN(&xsurface->events.map, &c->map, mapnotify);
+ LISTEN(&xsurface->events.unmap, &c->unmap, unmapnotify);
+ LISTEN(&xsurface->events.request_activate, &c->activate, activatex11);
+ LISTEN(&xsurface->events.request_configure, &c->configure, configurex11);
+ LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints);
+ LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle);
+ LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify);
+ LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, fullscreennotify);
}
Atom