enable pointer on layer surfaces

This commit is contained in:
Guido Cella 2020-09-04 07:38:14 +02:00
parent b26ede4727
commit d98ca07a64

54
dwl.c
View File

@ -267,6 +267,8 @@ static void unmapnotify(struct wl_listener *listener, void *data);
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
static void view(const Arg *arg); static void view(const Arg *arg);
static Client *xytoclient(double x, double y); 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 Monitor *xytomon(double x, double y);
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
@ -1234,8 +1236,16 @@ void
maplayersurfacenotify(struct wl_listener *listener, void *data) maplayersurfacenotify(struct wl_listener *listener, void *data)
{ {
LayerSurface *layersurface = wl_container_of(listener, layersurface, map); 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); 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 void
@ -1306,7 +1316,7 @@ motionnotify(uint32_t time)
{ {
double sx = 0, sy = 0; double sx = 0, sy = 0;
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
Client *c; Client *c = NULL;
/* Update selmon (even while dragging a window) */ /* Update selmon (even while dragging a window) */
if (sloppyfocus) if (sloppyfocus)
@ -1325,17 +1335,23 @@ motionnotify(uint32_t time)
return; 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 #ifdef XWAYLAND
/* Find an independent under the pointer and send the event along. */ /* 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, surface = wlr_surface_surface_at(c->surface.xwayland->surface,
cursor->x - c->surface.xwayland->x - c->bw, cursor->x - c->surface.xwayland->x - c->bw,
cursor->y - c->surface.xwayland->y - c->bw, &sx, &sy); cursor->y - c->surface.xwayland->y - c->bw, &sx, &sy);
/* Otherwise, find the client under the pointer and send the event along. */ /* Otherwise, find the client under the pointer and send the event along. */
} else }
#endif #endif
if ((c = xytoclient(cursor->x, cursor->y))) { else if ((c = xytoclient(cursor->x, cursor->y))) {
#ifdef XWAYLAND #ifdef XWAYLAND
if (c->type != XDGShell) if (c->type != XDGShell)
surface = wlr_surface_surface_at(c->surface.xwayland->surface, 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->x - c->geom.x - c->bw,
cursor->y - c->geom.y - c->bw, &sx, &sy); 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 /* 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 * default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */ * 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. */ * of its surfaces, and make keyboard focus follow if desired. */
wlr_seat_pointer_notify_enter(seat, surface, sx, sy); wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
if (!c)
return;
#if XWAYLAND #if XWAYLAND
if (c->type == X11Unmanaged) if (c->type == X11Unmanaged)
return; return;
@ -2126,6 +2152,24 @@ xytoclient(double x, double y)
return NULL; 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 * Monitor *
xytomon(double x, double y) xytomon(double x, double y)
{ {