Merge branch 'main' into wlroots-next

This commit is contained in:
Leonardo Hernández Hernández 2022-11-21 20:51:30 -06:00
commit ea1b2dda63
No known key found for this signature in database
GPG key ID: E538897EE11B9624
2 changed files with 51 additions and 52 deletions

View file

@ -1,7 +1,6 @@
/* appearance */ /* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */ static const int sloppyfocus = 1; /* focus follows mouse */
static const unsigned int borderpx = 1; /* border pixel of windows */ 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 rootcolor[] = {0.3, 0.3, 0.3, 1.0};
static const float bordercolor[] = {0.5, 0.5, 0.5, 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}; static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};

102
dwl.c
View file

@ -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 wl_listener request_state; struct wl_listener request_state;
@ -448,6 +448,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);
@ -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_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area);
wlr_scene_node_set_position(&layersurface->popups->node, wlr_scene_node_set_position(&layersurface->popups->node,
layersurface->scene->node.x, layersurface->scene->node.y); 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) checkidleinhibitor(struct wlr_surface *exclude)
{ {
int inhibited = 0; int inhibited = 0;
struct wlr_scene_tree *tree;
struct wlr_idle_inhibitor_v1 *inhibitor; struct wlr_idle_inhibitor_v1 *inhibitor;
wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
Client *c; if (exclude != inhibitor->surface && (tree = inhibitor->surface->data)
if (exclude == inhibitor->surface) && tree->node.enabled) {
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)) {
inhibited = 1; inhibited = 1;
break; break;
} }
@ -661,6 +662,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);
@ -812,7 +814,7 @@ createlayersurface(struct wl_listener *listener, void *data)
layers[wlr_layer_surface->pending.layer], wlr_layer_surface); layers[wlr_layer_surface->pending.layer], wlr_layer_surface);
layersurface->scene = layersurface->scene_layer->tree; layersurface->scene = layersurface->scene_layer->tree;
layersurface->popups = wlr_layer_surface->surface->data = 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; layersurface->scene->node.data = layersurface;
@ -881,6 +883,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
@ -1145,7 +1159,7 @@ focusstack(const Arg *arg)
{ {
/* Focus the next or previous client (in tiling order) on selmon */ /* Focus the next or previous client (in tiling order) on selmon */
Client *c, *sel = selclient(); Client *c, *sel = selclient();
if (!sel || (sel->isfullscreen && lockfullscreen)) if (!sel || sel->isfullscreen)
return; return;
if (arg->i > 0) { if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) { 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[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,
@ -1845,32 +1857,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();
@ -1988,6 +1984,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);
@ -2149,9 +2146,6 @@ void
startdrag(struct wl_listener *listener, void *data) startdrag(struct wl_listener *listener, void *data)
{ {
struct wlr_drag *drag = 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) if (!drag->icon)
return; return;
@ -2357,6 +2351,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;
@ -2426,7 +2423,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))) {
@ -2499,14 +2496,19 @@ configurex11(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, configure); Client *c = wl_container_of(listener, c, configure);
struct wlr_xwayland_surface_configure_event *event = data; struct wlr_xwayland_surface_configure_event *event = data;
wlr_xwayland_surface_configure(c->surface.xwayland, if (!c->mon)
event->x, event->y, event->width, event->height); 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 void
createnotifyx11(struct wl_listener *listener, void *data) createnotifyx11(struct wl_listener *listener, void *data)
{ {
struct wlr_xwayland_surface *xwayland_surface = data; struct wlr_xwayland_surface *xsurface = data;
Client *c; Client *c;
/* TODO: why we unset fullscreen when a xwayland client is created? */ /* TODO: why we unset fullscreen when a xwayland client is created? */
wl_list_for_each(c, &clients, link) wl_list_for_each(c, &clients, link)
@ -2514,22 +2516,20 @@ createnotifyx11(struct wl_listener *listener, void *data)
setfullscreen(c, 0); setfullscreen(c, 0);
/* Allocate a Client for this surface */ /* Allocate a Client for this surface */
c = xwayland_surface->data = ecalloc(1, sizeof(*c)); c = xsurface->data = ecalloc(1, sizeof(*c));
c->surface.xwayland = xwayland_surface; c->surface.xwayland = xsurface;
c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed; c->type = xsurface->override_redirect ? X11Unmanaged : X11Managed;
c->bw = borderpx; c->bw = borderpx;
/* Listen to the various events it can emit */ /* Listen to the various events it can emit */
LISTEN(&xwayland_surface->events.map, &c->map, mapnotify); LISTEN(&xsurface->events.map, &c->map, mapnotify);
LISTEN(&xwayland_surface->events.unmap, &c->unmap, unmapnotify); LISTEN(&xsurface->events.unmap, &c->unmap, unmapnotify);
LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11); LISTEN(&xsurface->events.request_activate, &c->activate, activatex11);
LISTEN(&xwayland_surface->events.request_configure, &c->configure, LISTEN(&xsurface->events.request_configure, &c->configure, configurex11);
configurex11); LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints);
LISTEN(&xwayland_surface->events.set_hints, &c->set_hints, sethints); LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle);
LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle); LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify);
LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify); LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, fullscreennotify);
LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,
fullscreennotify);
} }
Atom Atom