~ruther/dwl

caec566286b1bbef1758bcf0599677650017c5b9 — Leonardo Hernández Hernández 2 years ago 05eca0e
create a dedicated layer for fullscreen clients

Bug: https://github.com/djpohly/dwl/issues/327
1 files changed, 25 insertions(+), 23 deletions(-)

M dwl.c
M dwl.c => dwl.c +25 -23
@@ 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 wlr_box m;      /* monitor area, layout-relative */


@@ 445,6 445,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);


@@ 655,6 658,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);


@@ 874,6 878,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


@@ 1724,8 1740,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,


@@ 1833,32 1847,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();


@@ 1976,6 1974,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);


@@ 2342,6 2341,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;


@@ 2411,7 2413,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))) {

Do not follow this link