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.
VYZMMYEO3CEHLATYEHS7G6XBGEVOWDMAXHMHMINACSNF75TH72UAC
XWIRQADLKJFFA2N4HCSVNGUOAMRKJD43MLDRKRR4MTYYYGPYUXOAC
MMYR67XHNJBNEHAYVCOBFCQIGMEMJ7WPIBVLQJ5H2KGD5DZQCO5QC
W32YIHMVPAREXUADJOAX45B6CTXZY42EE77RDDZYNJFEE2HLQ3HAC
2FBILAASURBC6XQLU7Q4NOOTAZMWFFSIB66S4YHWJ5JHYEUAMJWQC
7B74AT3BXYB7PVW4F6SGQNPMHOU5TEV5TZ54CG6VSQI46XSEKWXQC
UCSTVE5NIAIQ3NJL5YLDFDKDPOCJS6NMAGABSWG67RGCPH47JQEQC
HWS332I73ETH3YIIOCQO7WB7VPQICME6GGXFJ7EUWDH5O3KA27QQC
D64WESJYNP7BT2GW7BX6332GAXIWK72KRIBEKTE34ATA4APJMGNQC
ZJSS4UDVHV6NYWHSI2U4CHCP46CKN3S5XJ3LL2KT4V6FFYHD5D2QC
ZDQINUTDXQUS7OBW53UEYR6IN7DJLTPBOMRURGYQBGJ2FBROIQVAC
BOH54DATFCM5ZC6GDQKEU23PQSIOOINLX3UAI47STL7PP56PQUYAC
2SBFINJKOJLIY2COLC4PD2LRMOAAMVA7CJFU57GUL43XGS6QJF5QC
MO5ORR7VSER3YUNO77DZJVKGOVYC2KNDCSC72J4NF7JYOHHTLRQAC
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;
Client *old = selclient();
struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
/* Also raise client in stacking order if requested */
if (lift) {
wl_list_remove(&c->slink);
wl_list_insert(&stack, &c->slink);
}
/* 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 */
/*
* 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);
}
/* 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);