aboutsummaryrefslogtreecommitdiff
path: root/dwl.c
diff options
context:
space:
mode:
authorDevin J. Pohly <djpohly@gmail.com>2020-07-31 13:53:33 -0500
committerDevin J. Pohly <djpohly@gmail.com>2020-07-31 13:53:33 -0500
commit90d80c0de900b03d36c081423855b18c5fa02f56 (patch)
tree07367a783313d3b1754f64f447a59f29c408d6dc /dwl.c
parent0a59f47c18a0fd033f62640f5b94a78fc9b3e929 (diff)
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.
Diffstat (limited to 'dwl.c')
-rw-r--r--dwl.c83
1 files changed, 34 insertions, 49 deletions
diff --git a/dwl.c b/dwl.c
index 7cc022d..a8ce00c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -681,62 +681,47 @@ dirtomon(int dir)
void
focusclient(Client *c, struct wlr_surface *surface, int lift)
{
- Client *sel = selclient();
- struct wlr_keyboard *kb;
- /* Previously focused surface */
- struct wlr_surface *psurface = seat->keyboard_state.focused_surface;
-
- if (c) {
- /* assert(VISIBLEON(c, c->mon)); ? */
- /* Use top-level wlr_surface if nothing more specific given */
- if (!surface)
- surface = WLR_SURFACE(c);
-
- /* Focus the correct monitor (must come after selclient!) */
- selmon = c->mon;
-
- /* Move the client to the front of the focus stack */
- wl_list_remove(&c->flink);
- wl_list_insert(&fstack, &c->flink);
-
- /* Also raise client in stacking order if requested */
- if (lift) {
- wl_list_remove(&c->slink);
- wl_list_insert(&stack, &c->slink);
- }
+ Client *old = selclient();
+ struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
+
+ /* Use top-level wlr_surface if nothing more specific is given */
+ if (c && !surface)
+ surface = WLR_SURFACE(c);
+
+ /* Deactivate old client if focus is changing */
+ if (c != old && old) {
+ if (old->type != XDGShell)
+ wlr_xwayland_surface_activate(old->xwayland_surface, 0);
+ else
+ wlr_xdg_toplevel_set_activated(old->xdg_surface, 0);
}
- /*
- * If the focused surface has changed, tell the seat to have the
- * keyboard enter the new surface. wlroots will keep track of this and
- * automatically send key events to the appropriate clients. If surface
- * is NULL, we clear the focus instead.
- */
- if (!surface) {
+ /* Update wlroots' keyboard focus */
+ if (!c) {
+ /* With no client, all we have left is to clear focus */
wlr_seat_keyboard_notify_clear_focus(seat);
- } else if (surface != psurface) {
- kb = wlr_seat_get_keyboard(seat);
+ return;
+ }
+ /* Otherwise, update the focus if it has changed */
+ if (surface != seat->keyboard_state.focused_surface)
wlr_seat_keyboard_notify_enter(seat, surface,
kb->keycodes, kb->num_keycodes, &kb->modifiers);
- }
- /*
- * If the focused toplevel has changed, deactivate the old one. Always
- * activate the current one. This lets the clients know to repaint
- * accordingly, e.g. show/hide a caret.
- */
- 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);
+ /* 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 (c->type != XDGShell)
+ wlr_xwayland_surface_activate(c->xwayland_surface, 1);
+ else
+ wlr_xdg_toplevel_set_activated(c->xdg_surface, 1);
}
void