summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dwl.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/dwl.c b/dwl.c
index 42e8198..3b1b999 100644
--- a/dwl.c
+++ b/dwl.c
@@ -267,6 +267,8 @@ static void unmapnotify(struct wl_listener *listener, void *data);
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static Client *xytoclient(double x, double y);
+static struct wlr_surface *xytolayersurface(struct wl_list *layer_surfaces,
+ double x, double y, double *sx, double *sy);
static Monitor *xytomon(double x, double y);
static void zoom(const Arg *arg);
@@ -1234,8 +1236,16 @@ void
maplayersurfacenotify(struct wl_listener *listener, void *data)
{
LayerSurface *layersurface = wl_container_of(listener, layersurface, map);
+ double sx = 0.0, sy = 0.0;
+ struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
+ layersurface->layer_surface,
+ cursor->x - layersurface->geo.x,
+ cursor->y - layersurface->geo.y,
+ &sx, &sy);
wlr_surface_send_enter(layersurface->layer_surface->surface, layersurface->layer_surface->output);
- /* XXX recheck pointer focus */
+ if (sub)
+ wlr_seat_pointer_notify_enter(seat, sub, sx, sy);
+ /* XXX check if the layer surface is below a client */
}
void
@@ -1306,7 +1316,7 @@ motionnotify(uint32_t time)
{
double sx = 0, sy = 0;
struct wlr_surface *surface = NULL;
- Client *c;
+ Client *c = NULL;
/* Update selmon (even while dragging a window) */
if (sloppyfocus)
@@ -1325,17 +1335,23 @@ motionnotify(uint32_t time)
return;
}
+ if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
+ cursor->x, cursor->y, &sx, &sy)))
+ ;
+ else if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
+ cursor->x, cursor->y, &sx, &sy)))
+ ;
#ifdef XWAYLAND
/* Find an independent under the pointer and send the event along. */
- if ((c = xytoindependent(cursor->x, cursor->y))) {
+ else if ((c = xytoindependent(cursor->x, cursor->y))) {
surface = wlr_surface_surface_at(c->surface.xwayland->surface,
cursor->x - c->surface.xwayland->x - c->bw,
cursor->y - c->surface.xwayland->y - c->bw, &sx, &sy);
/* Otherwise, find the client under the pointer and send the event along. */
- } else
+ }
#endif
- if ((c = xytoclient(cursor->x, cursor->y))) {
+ else if ((c = xytoclient(cursor->x, cursor->y))) {
#ifdef XWAYLAND
if (c->type != XDGShell)
surface = wlr_surface_surface_at(c->surface.xwayland->surface,
@@ -1347,6 +1363,13 @@ motionnotify(uint32_t time)
cursor->x - c->geom.x - c->bw,
cursor->y - c->geom.y - c->bw, &sx, &sy);
}
+ else if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
+ cursor->x, cursor->y, &sx, &sy)))
+ ;
+ else if ((surface = xytolayersurface(&selmon->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
+ cursor->x, cursor->y, &sx, &sy))) { // gcc complains without these braces
+ ;
+ }
/* If there's no client surface under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */
@@ -1424,6 +1447,9 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
* of its surfaces, and make keyboard focus follow if desired. */
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
+ if (!c)
+ return;
+
#if XWAYLAND
if (c->type == X11Unmanaged)
return;
@@ -2126,6 +2152,24 @@ xytoclient(double x, double y)
return NULL;
}
+struct wlr_surface *
+xytolayersurface(struct wl_list *layer_surfaces, double x, double y,
+ double *sx, double *sy)
+{
+ LayerSurface *layersurface;
+ wl_list_for_each_reverse(layersurface, layer_surfaces, link) {
+ struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
+ layersurface->layer_surface,
+ x - layersurface->geo.x,
+ y - layersurface->geo.y,
+ sx, sy);
+ if (sub)
+ return sub;
+
+ }
+ return NULL;
+}
+
Monitor *
xytomon(double x, double y)
{