forked from mirror/dwl
create a dedicated layer for fullscreen clients
Bug: https://github.com/djpohly/dwl/issues/327
This commit is contained in:
parent
05eca0e2d9
commit
caec566286
1 changed files with 25 additions and 23 deletions
48
dwl.c
48
dwl.c
|
@ -73,7 +73,7 @@
|
||||||
/* enums */
|
/* enums */
|
||||||
enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
|
enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
|
||||||
enum { XDGShell, LayerShell, X11Managed, X11Unmanaged }; /* client types */
|
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
|
#ifdef XWAYLAND
|
||||||
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
|
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
|
||||||
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
|
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
|
||||||
|
@ -102,7 +102,6 @@ typedef struct {
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
||||||
struct wlr_scene_tree *scene_surface;
|
struct wlr_scene_tree *scene_surface;
|
||||||
struct wlr_scene_rect *fullscreen_bg; /* See setfullscreen() for info */
|
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list flink;
|
struct wl_list flink;
|
||||||
union {
|
union {
|
||||||
|
@ -171,6 +170,7 @@ struct Monitor {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wlr_output *wlr_output;
|
struct wlr_output *wlr_output;
|
||||||
struct wlr_scene_output *scene_output;
|
struct wlr_scene_output *scene_output;
|
||||||
|
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
|
||||||
struct wl_listener frame;
|
struct wl_listener frame;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wlr_box m; /* monitor area, layout-relative */
|
struct wlr_box m; /* monitor area, layout-relative */
|
||||||
|
@ -445,6 +445,9 @@ arrange(Monitor *m)
|
||||||
if (c->mon == m)
|
if (c->mon == m)
|
||||||
wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, 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)
|
if (m && m->lt[m->sellt]->arrange)
|
||||||
m->lt[m->sellt]->arrange(m);
|
m->lt[m->sellt]->arrange(m);
|
||||||
motionnotify(0);
|
motionnotify(0);
|
||||||
|
@ -655,6 +658,7 @@ cleanupmon(struct wl_listener *listener, void *data)
|
||||||
m->wlr_output->data = NULL;
|
m->wlr_output->data = NULL;
|
||||||
wlr_output_layout_remove(output_layout, m->wlr_output);
|
wlr_output_layout_remove(output_layout, m->wlr_output);
|
||||||
wlr_scene_output_destroy(m->scene_output);
|
wlr_scene_output_destroy(m->scene_output);
|
||||||
|
wlr_scene_node_destroy(&m->fullscreen_bg->node);
|
||||||
|
|
||||||
closemon(m);
|
closemon(m);
|
||||||
free(m);
|
free(m);
|
||||||
|
@ -874,6 +878,18 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
wl_list_insert(&mons, &m->link);
|
wl_list_insert(&mons, &m->link);
|
||||||
printstatus();
|
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.
|
/* 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
|
* 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[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[2]->node, 0, c->bw);
|
||||||
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, 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 */
|
/* wlroots makes this a no-op if size hasn't changed */
|
||||||
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
|
c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||||
|
@ -1833,32 +1847,16 @@ setfullscreen(Client *c, int fullscreen)
|
||||||
return;
|
return;
|
||||||
c->bw = fullscreen ? 0 : borderpx;
|
c->bw = fullscreen ? 0 : borderpx;
|
||||||
client_set_fullscreen(c, fullscreen);
|
client_set_fullscreen(c, fullscreen);
|
||||||
|
wlr_scene_node_reparent(&c->scene->node, layers[fullscreen
|
||||||
|
? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
c->prev = c->geom;
|
c->prev = c->geom;
|
||||||
resize(c, c->mon->m, 0);
|
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 {
|
} else {
|
||||||
/* restore previous size instead of arrange for floating windows since
|
/* restore previous size instead of arrange for floating windows since
|
||||||
* client positions are set by the user and cannot be recalculated */
|
* client positions are set by the user and cannot be recalculated */
|
||||||
resize(c, c->prev, 0);
|
resize(c, c->prev, 0);
|
||||||
if (c->fullscreen_bg) {
|
|
||||||
wlr_scene_node_destroy(&c->fullscreen_bg->node);
|
|
||||||
c->fullscreen_bg = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
arrange(c->mon);
|
arrange(c->mon);
|
||||||
printstatus();
|
printstatus();
|
||||||
|
@ -1976,6 +1974,7 @@ setup(void)
|
||||||
layers[LyrBottom] = wlr_scene_tree_create(&scene->tree);
|
layers[LyrBottom] = wlr_scene_tree_create(&scene->tree);
|
||||||
layers[LyrTile] = wlr_scene_tree_create(&scene->tree);
|
layers[LyrTile] = wlr_scene_tree_create(&scene->tree);
|
||||||
layers[LyrFloat] = 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[LyrTop] = wlr_scene_tree_create(&scene->tree);
|
||||||
layers[LyrOverlay] = wlr_scene_tree_create(&scene->tree);
|
layers[LyrOverlay] = wlr_scene_tree_create(&scene->tree);
|
||||||
layers[LyrDragIcon] = 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 */
|
/* Don't move clients to the left output when plugging monitors */
|
||||||
arrange(m);
|
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.enabled = 1;
|
||||||
config_head->state.mode = m->wlr_output->current_mode;
|
config_head->state.mode = m->wlr_output->current_mode;
|
||||||
config_head->state.x = m->m.x;
|
config_head->state.x = m->m.x;
|
||||||
|
@ -2411,7 +2413,7 @@ xytonode(double x, double y, struct wlr_surface **psurface,
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
const int *layer;
|
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++) {
|
for (layer = focus_order; layer < END(focus_order); layer++) {
|
||||||
if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) {
|
if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) {
|
||||||
|
|
Loading…
Reference in a new issue