Separate drag icon from layers array and Lyr enum

If we treat the drag icon as distinct from other layers (it doesn't have
contents that are interactive, focusable, etc.), then we can iterate
over layers meaningfully with a simple for loop.

ΔSLOC: -8
This commit is contained in:
Devin J. Pohly 2023-06-25 17:44:00 -05:00
parent 68a17f962e
commit eda0613cc4

49
dwl.c
View file

@ -74,7 +74,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, LyrFS, LyrDragIcon, LyrBlock, NUM_LAYERS }; /* scene layers */ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */
#ifdef XWAYLAND #ifdef XWAYLAND
enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
@ -330,6 +330,8 @@ static struct wl_display *dpy;
static struct wlr_backend *backend; static struct wlr_backend *backend;
static struct wlr_scene *scene; static struct wlr_scene *scene;
static struct wlr_scene_tree *layers[NUM_LAYERS]; static struct wlr_scene_tree *layers[NUM_LAYERS];
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay };
static struct wlr_renderer *drw; static struct wlr_renderer *drw;
static struct wlr_allocator *alloc; static struct wlr_allocator *alloc;
static struct wlr_compositor *compositor; static struct wlr_compositor *compositor;
@ -736,17 +738,16 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit); LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit);
struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface; struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;
struct wlr_output *wlr_output = wlr_layer_surface->output; struct wlr_output *wlr_output = wlr_layer_surface->output;
struct wlr_scene_tree *layer = layers[layermap[wlr_layer_surface->current.layer]];
/* For some reason this layersurface have no monitor, this can be because /* For some reason this layersurface have no monitor, this can be because
* its monitor has just been destroyed */ * its monitor has just been destroyed */
if (!wlr_output || !(layersurface->mon = wlr_output->data)) if (!wlr_output || !(layersurface->mon = wlr_output->data))
return; return;
if (layers[wlr_layer_surface->current.layer] != layersurface->scene->node.parent) { if (layer != layersurface->scene->node.parent) {
wlr_scene_node_reparent(&layersurface->scene->node, wlr_scene_node_reparent(&layersurface->scene->node, layer);
layers[wlr_layer_surface->current.layer]); wlr_scene_node_reparent(&layersurface->popups->node, layer);
wlr_scene_node_reparent(&layersurface->popups->node,
layers[wlr_layer_surface->current.layer]);
wl_list_remove(&layersurface->link); wl_list_remove(&layersurface->link);
wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->current.layer], wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->current.layer],
&layersurface->link); &layersurface->link);
@ -832,6 +833,7 @@ createlayersurface(struct wl_listener *listener, void *data)
struct wlr_layer_surface_v1 *wlr_layer_surface = data; struct wlr_layer_surface_v1 *wlr_layer_surface = data;
LayerSurface *layersurface; LayerSurface *layersurface;
struct wlr_layer_surface_v1_state old_state; struct wlr_layer_surface_v1_state old_state;
struct wlr_scene_tree *l = layers[layermap[wlr_layer_surface->pending.layer]];
if (!wlr_layer_surface->output) if (!wlr_layer_surface->output)
wlr_layer_surface->output = selmon ? selmon->wlr_output : NULL; wlr_layer_surface->output = selmon ? selmon->wlr_output : NULL;
@ -856,11 +858,9 @@ createlayersurface(struct wl_listener *listener, void *data)
layersurface->mon = wlr_layer_surface->output->data; layersurface->mon = wlr_layer_surface->output->data;
wlr_layer_surface->data = layersurface; wlr_layer_surface->data = layersurface;
layersurface->scene_layer = wlr_scene_layer_surface_v1_create( layersurface->scene_layer = wlr_scene_layer_surface_v1_create(l, 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(l);
wlr_scene_tree_create(layers[wlr_layer_surface->pending.layer]);
layersurface->scene->node.data = layersurface; layersurface->scene->node.data = layersurface;
@ -2127,6 +2127,8 @@ setsel(struct wl_listener *listener, void *data)
void void
setup(void) setup(void)
{ {
int layer;
/* Set up signal handlers */ /* Set up signal handlers */
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = sigchld}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = sigchld};
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
@ -2153,15 +2155,8 @@ setup(void)
/* Initialize the scene graph used to lay out windows */ /* Initialize the scene graph used to lay out windows */
scene = wlr_scene_create(); scene = wlr_scene_create();
layers[LyrBg] = wlr_scene_tree_create(&scene->tree); for (layer = 0; layer < NUM_LAYERS; layer++)
layers[LyrBottom] = wlr_scene_tree_create(&scene->tree); layers[layer] = 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);
layers[LyrBlock] = wlr_scene_tree_create(&scene->tree);
/* Create a renderer with the default implementation */ /* Create a renderer with the default implementation */
if (!(drw = wlr_renderer_autocreate(backend))) if (!(drw = wlr_renderer_autocreate(backend)))
@ -2350,11 +2345,13 @@ 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;
struct wlr_scene_tree *icon;
if (!drag->icon) if (!drag->icon)
return; return;
drag->icon->data = wlr_scene_subsurface_tree_create(layers[LyrDragIcon], drag->icon->surface); drag->icon->data = icon = wlr_scene_subsurface_tree_create(&scene->tree, drag->icon->surface);
wlr_scene_node_place_below(&icon->node, &layers[LyrBlock]->node);
motionnotify(0); motionnotify(0);
wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy); wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy);
} }
@ -2652,11 +2649,12 @@ xytonode(double x, double y, struct wlr_surface **psurface,
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
Client *c = NULL; Client *c = NULL;
LayerSurface *l = NULL; LayerSurface *l = NULL;
const int *layer; int layer;
int focus_order[] = { LyrBlock, LyrOverlay, LyrTop, LyrFS, LyrFloat, LyrTile, LyrBottom, LyrBg };
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny)))
continue;
for (layer = focus_order; layer < END(focus_order); layer++) {
if ((node = wlr_scene_node_at(&layers[*layer]->node, x, y, nx, ny))) {
if (node->type == WLR_SCENE_NODE_BUFFER) if (node->type == WLR_SCENE_NODE_BUFFER)
surface = wlr_scene_surface_from_buffer( surface = wlr_scene_surface_from_buffer(
wlr_scene_buffer_from_node(node))->surface; wlr_scene_buffer_from_node(node))->surface;
@ -2668,9 +2666,6 @@ xytonode(double x, double y, struct wlr_surface **psurface,
l = pnode->data; l = pnode->data;
} }
} }
if (surface)
break;
}
if (psurface) *psurface = surface; if (psurface) *psurface = surface;
if (pc) *pc = c; if (pc) *pc = c;