simplify focusclient

This arranges the function into some logical tasks: deactivate the old
client, update wlroots' keyboard focus, update our data structures, and
activate the new client.  The last two only need to be done when
focusing something new, so an early return saves some horizontal space.
This commit is contained in:
Devin J. Pohly 2020-07-31 13:53:33 -05:00
parent 0a59f47c18
commit 90d80c0de9
1 changed files with 32 additions and 47 deletions

79
dwl.c
View File

@ -681,62 +681,47 @@ dirtomon(int dir)
void void
focusclient(Client *c, struct wlr_surface *surface, int lift) focusclient(Client *c, struct wlr_surface *surface, int lift)
{ {
Client *sel = selclient(); Client *old = selclient();
struct wlr_keyboard *kb; struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
/* Previously focused surface */
struct wlr_surface *psurface = seat->keyboard_state.focused_surface;
if (c) { /* Use top-level wlr_surface if nothing more specific is given */
/* assert(VISIBLEON(c, c->mon)); ? */ if (c && !surface)
/* Use top-level wlr_surface if nothing more specific given */ surface = WLR_SURFACE(c);
if (!surface)
surface = WLR_SURFACE(c);
/* Focus the correct monitor (must come after selclient!) */ /* Deactivate old client if focus is changing */
selmon = c->mon; if (c != old && old) {
if (old->type != XDGShell)
/* Move the client to the front of the focus stack */ wlr_xwayland_surface_activate(old->xwayland_surface, 0);
wl_list_remove(&c->flink); else
wl_list_insert(&fstack, &c->flink); wlr_xdg_toplevel_set_activated(old->xdg_surface, 0);
/* Also raise client in stacking order if requested */
if (lift) {
wl_list_remove(&c->slink);
wl_list_insert(&stack, &c->slink);
}
} }
/* /* Update wlroots' keyboard focus */
* If the focused surface has changed, tell the seat to have the if (!c) {
* keyboard enter the new surface. wlroots will keep track of this and /* With no client, all we have left is to clear focus */
* automatically send key events to the appropriate clients. If surface
* is NULL, we clear the focus instead.
*/
if (!surface) {
wlr_seat_keyboard_notify_clear_focus(seat); wlr_seat_keyboard_notify_clear_focus(seat);
} else if (surface != psurface) { return;
kb = wlr_seat_get_keyboard(seat); }
/* Otherwise, update the focus if it has changed */
if (surface != seat->keyboard_state.focused_surface)
wlr_seat_keyboard_notify_enter(seat, surface, wlr_seat_keyboard_notify_enter(seat, surface,
kb->keycodes, kb->num_keycodes, &kb->modifiers); kb->keycodes, kb->num_keycodes, &kb->modifiers);
/* Select client's monitor, move it to the top of the focus stack, and
* raise it in the stacking order if requested. */
selmon = c->mon;
wl_list_remove(&c->flink);
wl_list_insert(&fstack, &c->flink);
if (lift) {
wl_list_remove(&c->slink);
wl_list_insert(&stack, &c->slink);
} }
/* /* Activate the new client */
* If the focused toplevel has changed, deactivate the old one. Always if (c->type != XDGShell)
* activate the current one. This lets the clients know to repaint wlr_xwayland_surface_activate(c->xwayland_surface, 1);
* accordingly, e.g. show/hide a caret. else
*/ wlr_xdg_toplevel_set_activated(c->xdg_surface, 1);
if (c != sel && sel) {
if (sel->type != XDGShell)
wlr_xwayland_surface_activate(sel->xwayland_surface, 0);
else
wlr_xdg_toplevel_set_activated(sel->xdg_surface, 0);
}
if (c) {
if (c->type != XDGShell)
wlr_xwayland_surface_activate(c->xwayland_surface, 1);
else
wlr_xdg_toplevel_set_activated(c->xdg_surface, 1);
}
} }
void void