From c08ea88c1f08c741637004c032fafac1d75bd36f Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 6 Aug 2020 15:32:55 +1000 Subject: [PATCH 1/4] #31 independents retain focus while mouse is over them --- dwl.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index fbdfbe0..813405b 100644 --- a/dwl.c +++ b/dwl.c @@ -224,6 +224,7 @@ static void unmapnotify(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); static void view(const Arg *arg); static Client *xytoclient(double x, double y); +static Client *xytoindependent(double x, double y); static Monitor *xytomon(double x, double y); static void zoom(const Arg *arg); @@ -677,7 +678,7 @@ focusclient(Client *old, Client *c, int lift) struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat); /* Raise client in stacking order if requested */ - if (c && lift) { + if (c && c->type != X11Unmanaged && lift) { wl_list_remove(&c->slink); wl_list_insert(&stack, &c->slink); } @@ -706,8 +707,10 @@ focusclient(Client *old, Client *c, int lift) kb->keycodes, kb->num_keycodes, &kb->modifiers); /* Put the new client atop the focus stack and select its monitor */ - wl_list_remove(&c->flink); - wl_list_insert(&fstack, &c->flink); + if (c->type != X11Unmanaged) { + wl_list_remove(&c->flink); + wl_list_insert(&fstack, &c->flink); + } selmon = c->mon; /* Activate the new client */ @@ -983,8 +986,14 @@ motionnotify(uint32_t time) return; } + /* Find an independent under the pointer and send the event along. */ + 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. */ - if ((c = xytoclient(cursor->x, cursor->y))) { + } else if (!c && (c = xytoclient(cursor->x, cursor->y))) { if (c->type != XDGShell) surface = wlr_surface_surface_at(c->surface.xwayland->surface, cursor->x - c->geom.x - c->bw, @@ -1771,6 +1780,25 @@ xytoclient(double x, double y) return NULL; } +Client * +xytoindependent(double x, double y) +{ + /* Find the topmost visible independent at point (x, y). + * For independents, the most recently created can be used as the "top". + * AMC TODO: factor monitor or owning client visibility in. */ + Client *c; + struct wlr_box geom; + wl_list_for_each_reverse(c, &independents, link) { + geom.x = c->surface.xwayland->x; + geom.y = c->surface.xwayland->y; + geom.width = c->surface.xwayland->width; + geom.height = c->surface.xwayland->height; + if (wlr_box_contains_point(&geom, x, y)) + return c; + } + return NULL; +} + Monitor * xytomon(double x, double y) { From 9d138ac95a4575f61893278791d23bd70d02d286 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Thu, 6 Aug 2020 15:41:04 +1000 Subject: [PATCH 2/4] #31 independents retain focus while mouse is over them --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 813405b..15c446b 100644 --- a/dwl.c +++ b/dwl.c @@ -993,7 +993,7 @@ motionnotify(uint32_t time) cursor->y - c->surface.xwayland->y - c->bw, &sx, &sy); /* Otherwise, find the client under the pointer and send the event along. */ - } else if (!c && (c = xytoclient(cursor->x, cursor->y))) { + } else if ((c = xytoclient(cursor->x, cursor->y))) { if (c->type != XDGShell) surface = wlr_surface_surface_at(c->surface.xwayland->surface, cursor->x - c->geom.x - c->bw, From 95515682526dc786a9c2a668274a85be46b44d03 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 9 Aug 2020 11:34:19 +1000 Subject: [PATCH 3/4] #31 independents retain focus while mouse is over them --- dwl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 15c446b..f5247b0 100644 --- a/dwl.c +++ b/dwl.c @@ -678,7 +678,7 @@ focusclient(Client *old, Client *c, int lift) struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat); /* Raise client in stacking order if requested */ - if (c && c->type != X11Unmanaged && lift) { + if (c && lift) { wl_list_remove(&c->slink); wl_list_insert(&stack, &c->slink); } @@ -707,10 +707,8 @@ focusclient(Client *old, Client *c, int lift) kb->keycodes, kb->num_keycodes, &kb->modifiers); /* Put the new client atop the focus stack and select its monitor */ - if (c->type != X11Unmanaged) { - wl_list_remove(&c->flink); - wl_list_insert(&fstack, &c->flink); - } + wl_list_remove(&c->flink); + wl_list_insert(&fstack, &c->flink); selmon = c->mon; /* Activate the new client */ @@ -1079,7 +1077,7 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, /* Otherwise, let the client know that the mouse cursor has entered one * of its surfaces, and make keyboard focus follow if desired. */ wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - if (sloppyfocus) + if (sloppyfocus && c->type != X11Unmanaged) focusclient(selclient(), c, 0); } From 5b464edf91b748a19cba2aa2c472f2d939f15220 Mon Sep 17 00:00:00 2001 From: Alexander Courtis Date: Sun, 9 Aug 2020 11:56:34 +1000 Subject: [PATCH 4/4] #31 independents retain focus while mouse is over them --- dwl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index f5247b0..342ff1e 100644 --- a/dwl.c +++ b/dwl.c @@ -1783,7 +1783,9 @@ xytoindependent(double x, double y) { /* Find the topmost visible independent at point (x, y). * For independents, the most recently created can be used as the "top". - * AMC TODO: factor monitor or owning client visibility in. */ + * We rely on the X11 convention of unmapping unmanaged when the "owning" + * client loses focus, which ensures that unmanaged are only visible on + * the current tag. */ Client *c; struct wlr_box geom; wl_list_for_each_reverse(c, &independents, link) {