enable pointer on layer surfaces

This commit is contained in:
Guido Cella 2020-09-04 07:38:14 +02:00
parent b26ede4727
commit d98ca07a64
1 changed files with 49 additions and 5 deletions

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 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)
{