dwl

My patch set and modifications to dwl
git clone git://git.ethandl.dev/dwl
Log | Files | Refs | README | LICENSE

dwl.c (113626B)


      1 /*
      2  * See LICENSE file for copyright and license details.
      3  */
      4 #include <getopt.h>
      5 #include <libinput.h>
      6 #include <linux/input-event-codes.h>
      7 #include <math.h>
      8 #include <libdrm/drm_fourcc.h>
      9 #include <signal.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <sys/wait.h>
     13 #include <time.h>
     14 #include <unistd.h>
     15 #include <wayland-server-core.h>
     16 #include <wlr/backend.h>
     17 #include <wlr/backend/libinput.h>
     18 #include <wlr/render/allocator.h>
     19 #include <wlr/render/wlr_renderer.h>
     20 #include <wlr/types/wlr_alpha_modifier_v1.h>
     21 #include <wlr/types/wlr_compositor.h>
     22 #include <wlr/types/wlr_cursor.h>
     23 #include <wlr/types/wlr_cursor_shape_v1.h>
     24 #include <wlr/types/wlr_data_control_v1.h>
     25 #include <wlr/types/wlr_data_device.h>
     26 #include <wlr/types/wlr_drm.h>
     27 #include <wlr/types/wlr_export_dmabuf_v1.h>
     28 #include <wlr/types/wlr_fractional_scale_v1.h>
     29 #include <wlr/types/wlr_gamma_control_v1.h>
     30 #include <wlr/types/wlr_idle_inhibit_v1.h>
     31 #include <wlr/types/wlr_idle_notify_v1.h>
     32 #include <wlr/types/wlr_input_device.h>
     33 #include <wlr/types/wlr_keyboard.h>
     34 #include <wlr/types/wlr_keyboard_group.h>
     35 #include <wlr/types/wlr_layer_shell_v1.h>
     36 #include <wlr/types/wlr_linux_dmabuf_v1.h>
     37 #include <wlr/types/wlr_output.h>
     38 #include <wlr/types/wlr_output_layout.h>
     39 #include <wlr/types/wlr_output_management_v1.h>
     40 #include <wlr/types/wlr_output_power_management_v1.h>
     41 #include <wlr/types/wlr_pointer.h>
     42 #include <wlr/types/wlr_pointer_constraints_v1.h>
     43 #include <wlr/types/wlr_presentation_time.h>
     44 #include <wlr/types/wlr_primary_selection.h>
     45 #include <wlr/types/wlr_primary_selection_v1.h>
     46 #include <wlr/types/wlr_relative_pointer_v1.h>
     47 #include <wlr/types/wlr_scene.h>
     48 #include <wlr/types/wlr_screencopy_v1.h>
     49 #include <wlr/types/wlr_seat.h>
     50 #include <wlr/types/wlr_server_decoration.h>
     51 #include <wlr/types/wlr_session_lock_v1.h>
     52 #include <wlr/types/wlr_single_pixel_buffer_v1.h>
     53 #include <wlr/types/wlr_subcompositor.h>
     54 #include <wlr/types/wlr_viewporter.h>
     55 #include <wlr/types/wlr_virtual_keyboard_v1.h>
     56 #include <wlr/types/wlr_virtual_pointer_v1.h>
     57 #include <wlr/types/wlr_xcursor_manager.h>
     58 #include <wlr/types/wlr_xdg_activation_v1.h>
     59 #include <wlr/types/wlr_xdg_decoration_v1.h>
     60 #include <wlr/types/wlr_xdg_output_v1.h>
     61 #include <wlr/types/wlr_xdg_shell.h>
     62 #include <wlr/interfaces/wlr_buffer.h>
     63 #include <wlr/util/log.h>
     64 #include <wlr/util/region.h>
     65 #include <xkbcommon/xkbcommon.h>
     66 #ifdef XWAYLAND
     67 #include <wlr/xwayland.h>
     68 #include <xcb/xcb.h>
     69 #include <xcb/xcb_icccm.h>
     70 #endif
     71 
     72 #include "util.h"
     73 #include "drwl.h"
     74 
     75 /* macros */
     76 #define MAX(A, B)               ((A) > (B) ? (A) : (B))
     77 #define MIN(A, B)               ((A) < (B) ? (A) : (B))
     78 #define CLEANMASK(mask)         (mask & ~WLR_MODIFIER_CAPS)
     79 #define VISIBLEON(C, M)         ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
     80 #define LENGTH(X)               (sizeof X / sizeof X[0])
     81 #define END(A)                  ((A) + LENGTH(A))
     82 #define TAGMASK                 ((1u << LENGTH(tags)) - 1)
     83 #define LISTEN(E, L, H)         wl_signal_add((E), ((L)->notify = (H), (L)))
     84 #define LISTEN_STATIC(E, H)     do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0)
     85 #define TEXTW(mon, text)        (drwl_font_getwidth(mon->drw, text) + mon->lrpad)
     86 
     87 /* enums */
     88 enum { SchemeNorm, SchemeSel, SchemeUrg }; /* color schemes */
     89 enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
     90 enum { XDGShell, LayerShell, X11 }; /* client types */
     91 enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */
     92 enum { ClkTagBar, ClkLtSymbol, ClkStatus, ClkTitle, ClkClient, ClkRoot }; /* clicks */
     93 #ifdef XWAYLAND
     94 enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
     95 	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
     96 #endif
     97 
     98 typedef union {
     99 	int i;
    100 	uint32_t ui;
    101 	float f;
    102 	const void *v;
    103 } Arg;
    104 
    105 typedef struct {
    106 	unsigned int click;
    107 	unsigned int mod;
    108 	unsigned int button;
    109 	void (*func)(const Arg *);
    110 	const Arg arg;
    111 } Button;
    112 
    113 typedef struct Monitor Monitor;
    114 typedef struct {
    115 	/* Must keep these three elements in this order */
    116 	unsigned int type; /* XDGShell or X11* */
    117 	struct wlr_box geom; /* layout-relative, includes border */
    118 	Monitor *mon;
    119 	struct wlr_scene_tree *scene;
    120 	struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
    121 	struct wlr_scene_tree *scene_surface;
    122 	struct wl_list link;
    123 	struct wl_list flink;
    124 	union {
    125 		struct wlr_xdg_surface *xdg;
    126 		struct wlr_xwayland_surface *xwayland;
    127 	} surface;
    128 	struct wlr_xdg_toplevel_decoration_v1 *decoration;
    129 	struct wl_listener commit;
    130 	struct wl_listener map;
    131 	struct wl_listener maximize;
    132 	struct wl_listener unmap;
    133 	struct wl_listener destroy;
    134 	struct wl_listener set_title;
    135 	struct wl_listener fullscreen;
    136 	struct wl_listener set_decoration_mode;
    137 	struct wl_listener destroy_decoration;
    138 	struct wlr_box prev; /* layout-relative, includes border */
    139 	struct wlr_box bounds;
    140 #ifdef XWAYLAND
    141 	struct wl_listener activate;
    142 	struct wl_listener associate;
    143 	struct wl_listener dissociate;
    144 	struct wl_listener configure;
    145 	struct wl_listener set_hints;
    146 #endif
    147 	unsigned int bw;
    148 	uint32_t tags;
    149 	int isfloating, isurgent, isfullscreen;
    150 	uint32_t resize; /* configure serial of a pending resize */
    151 } Client;
    152 
    153 typedef struct {
    154 	uint32_t mod;
    155 	xkb_keysym_t keysym;
    156 	void (*func)(const Arg *);
    157 	const Arg arg;
    158 } Key;
    159 
    160 typedef struct {
    161 	struct wl_list link;
    162 	struct wlr_keyboard_group *wlr_group;
    163 
    164 	int nsyms;
    165 	const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
    166 	uint32_t mods; /* invalid if nsyms == 0 */
    167 	struct wl_event_source *key_repeat_source;
    168 
    169 	struct wl_listener modifiers;
    170 	struct wl_listener key;
    171 	struct wl_listener destroy;
    172 } KeyboardGroup;
    173 
    174 typedef struct {
    175 	/* Must keep these three elements in this order */
    176 	unsigned int type; /* LayerShell */
    177 	struct wlr_box geom;
    178 	Monitor *mon;
    179 	struct wlr_scene_tree *scene;
    180 	struct wlr_scene_tree *popups;
    181 	struct wlr_scene_layer_surface_v1 *scene_layer;
    182 	struct wl_list link;
    183 	int mapped;
    184 	struct wlr_layer_surface_v1 *layer_surface;
    185 
    186 	struct wl_listener destroy;
    187 	struct wl_listener unmap;
    188 	struct wl_listener surface_commit;
    189 } LayerSurface;
    190 
    191 typedef struct {
    192 	const char *symbol;
    193 	void (*arrange)(Monitor *);
    194 } Layout;
    195 
    196 typedef struct {
    197 	struct wlr_buffer base;
    198 	struct wl_listener release;
    199 	bool busy;
    200 	Img *image;
    201 	uint32_t data[];
    202 } Buffer;
    203 
    204 struct Monitor {
    205 	struct wl_list link;
    206 	struct wlr_output *wlr_output;
    207 	struct wlr_scene_output *scene_output;
    208 	struct wlr_scene_buffer *scene_buffer; /* bar buffer */
    209 	struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
    210 	struct wl_listener frame;
    211 	struct wl_listener destroy;
    212 	struct wl_listener request_state;
    213 	struct wl_listener destroy_lock_surface;
    214 	struct wlr_session_lock_surface_v1 *lock_surface;
    215 	struct wlr_box m; /* monitor area, layout-relative */
    216 	struct {
    217 		int width, height;
    218 		int real_width, real_height; /* non-scaled */
    219 		float scale;
    220 	} b; /* bar area */
    221 	struct wlr_box w; /* window area, layout-relative */
    222 	struct wl_list layers[4]; /* LayerSurface.link */
    223 	const Layout *lt[2];
    224 	int gappih;           /* horizontal gap between windows */
    225 	int gappiv;           /* vertical gap between windows */
    226 	int gappoh;           /* horizontal outer gaps */
    227 	int gappov;           /* vertical outer gaps */
    228 	unsigned int seltags;
    229 	unsigned int sellt;
    230 	uint32_t tagset[2];
    231 	float mfact;
    232 	int gamma_lut_changed;
    233 	int nmaster;
    234 	char ltsymbol[16];
    235 	int asleep;
    236 	Drwl *drw;
    237 	Buffer *pool[2];
    238 	int lrpad;
    239 };
    240 
    241 typedef struct {
    242 	const char *name;
    243 	float mfact;
    244 	int nmaster;
    245 	float scale;
    246 	const Layout *lt;
    247 	enum wl_output_transform rr;
    248 	int x, y;
    249 } MonitorRule;
    250 
    251 typedef struct {
    252 	struct wlr_pointer_constraint_v1 *constraint;
    253 	struct wl_listener destroy;
    254 } PointerConstraint;
    255 
    256 typedef struct {
    257 	const char *id;
    258 	const char *title;
    259 	uint32_t tags;
    260 	int isfloating;
    261 	int monitor;
    262 } Rule;
    263 
    264 typedef struct {
    265 	struct wlr_scene_tree *scene;
    266 
    267 	struct wlr_session_lock_v1 *lock;
    268 	struct wl_listener new_surface;
    269 	struct wl_listener unlock;
    270 	struct wl_listener destroy;
    271 } SessionLock;
    272 
    273 /* function declarations */
    274 static void applybounds(Client *c, struct wlr_box *bbox);
    275 static void applyrules(Client *c);
    276 static void arrange(Monitor *m);
    277 static void arrangelayer(Monitor *m, struct wl_list *list,
    278 		struct wlr_box *usable_area, int exclusive);
    279 static void arrangelayers(Monitor *m);
    280 static void axisnotify(struct wl_listener *listener, void *data);
    281 static bool baracceptsinput(struct wlr_scene_buffer *buffer, double *sx, double *sy);
    282 static void bufdestroy(struct wlr_buffer *buffer);
    283 static bool bufdatabegin(struct wlr_buffer *buffer, uint32_t flags,
    284 		void **data, uint32_t *format, size_t *stride);
    285 static void bufdataend(struct wlr_buffer *buffer);
    286 static Buffer *bufmon(Monitor *m);
    287 static void bufrelease(struct wl_listener *listener, void *data);
    288 static void buttonpress(struct wl_listener *listener, void *data);
    289 static void chvt(const Arg *arg);
    290 static void checkidleinhibitor(struct wlr_surface *exclude);
    291 static void cleanup(void);
    292 static void cleanupmon(struct wl_listener *listener, void *data);
    293 static void closemon(Monitor *m);
    294 static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
    295 static void commitnotify(struct wl_listener *listener, void *data);
    296 static void commitpopup(struct wl_listener *listener, void *data);
    297 static void createdecoration(struct wl_listener *listener, void *data);
    298 static void createidleinhibitor(struct wl_listener *listener, void *data);
    299 static void createkeyboard(struct wlr_keyboard *keyboard);
    300 static KeyboardGroup *createkeyboardgroup(void);
    301 static void createlayersurface(struct wl_listener *listener, void *data);
    302 static void createlocksurface(struct wl_listener *listener, void *data);
    303 static void createmon(struct wl_listener *listener, void *data);
    304 static void createnotify(struct wl_listener *listener, void *data);
    305 static void createpointer(struct wlr_pointer *pointer);
    306 static void createpointerconstraint(struct wl_listener *listener, void *data);
    307 static void createpopup(struct wl_listener *listener, void *data);
    308 static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
    309 static void cursorframe(struct wl_listener *listener, void *data);
    310 static void cursorwarptohint(void);
    311 static void defaultgaps(const Arg *arg);
    312 static void destroydecoration(struct wl_listener *listener, void *data);
    313 static void destroydragicon(struct wl_listener *listener, void *data);
    314 static void destroyidleinhibitor(struct wl_listener *listener, void *data);
    315 static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
    316 static void destroylock(SessionLock *lock, int unlocked);
    317 static void destroylocksurface(struct wl_listener *listener, void *data);
    318 static void destroynotify(struct wl_listener *listener, void *data);
    319 static void destroypointerconstraint(struct wl_listener *listener, void *data);
    320 static void destroysessionlock(struct wl_listener *listener, void *data);
    321 static void destroysessionmgr(struct wl_listener *listener, void *data);
    322 static void destroykeyboardgroup(struct wl_listener *listener, void *data);
    323 static Monitor *dirtomon(enum wlr_direction dir);
    324 static void drawbar(Monitor *m);
    325 static void drawbars(void);
    326 static void focusclient(Client *c, int lift);
    327 static void focusmon(const Arg *arg);
    328 static void focusstack(const Arg *arg);
    329 static Client *focustop(Monitor *m);
    330 static void fullscreennotify(struct wl_listener *listener, void *data);
    331 static void gpureset(struct wl_listener *listener, void *data);
    332 static void handlesig(int signo);
    333 static void incnmaster(const Arg *arg);
    334 static void incgaps(const Arg *arg);
    335 static void incigaps(const Arg *arg);
    336 static void incihgaps(const Arg *arg);
    337 static void incivgaps(const Arg *arg);
    338 static void incogaps(const Arg *arg);
    339 static void incohgaps(const Arg *arg);
    340 static void incovgaps(const Arg *arg);
    341 static void inputdevice(struct wl_listener *listener, void *data);
    342 static int keybinding(uint32_t mods, xkb_keysym_t sym);
    343 static void keypress(struct wl_listener *listener, void *data);
    344 static void keypressmod(struct wl_listener *listener, void *data);
    345 static int keyrepeat(void *data);
    346 static void killclient(const Arg *arg);
    347 static void locksession(struct wl_listener *listener, void *data);
    348 static void mapnotify(struct wl_listener *listener, void *data);
    349 static void maximizenotify(struct wl_listener *listener, void *data);
    350 static void monocle(Monitor *m);
    351 static void motionabsolute(struct wl_listener *listener, void *data);
    352 static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx,
    353 		double sy, double sx_unaccel, double sy_unaccel);
    354 static void motionrelative(struct wl_listener *listener, void *data);
    355 static void moveresize(const Arg *arg);
    356 static void outputmgrapply(struct wl_listener *listener, void *data);
    357 static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
    358 static void outputmgrtest(struct wl_listener *listener, void *data);
    359 static void pointerfocus(Client *c, struct wlr_surface *surface,
    360 		double sx, double sy, uint32_t time);
    361 static void powermgrsetmode(struct wl_listener *listener, void *data);
    362 static void quit(const Arg *arg);
    363 static void rendermon(struct wl_listener *listener, void *data);
    364 static void requestdecorationmode(struct wl_listener *listener, void *data);
    365 static void requeststartdrag(struct wl_listener *listener, void *data);
    366 static void requestmonstate(struct wl_listener *listener, void *data);
    367 static void resize(Client *c, struct wlr_box geo, int interact);
    368 static void run(char *startup_cmd);
    369 static void setcursor(struct wl_listener *listener, void *data);
    370 static void setcursorshape(struct wl_listener *listener, void *data);
    371 static void setfloating(Client *c, int floating);
    372 static void setfullscreen(Client *c, int fullscreen);
    373 static void setgamma(struct wl_listener *listener, void *data);
    374 static void setgaps(int oh, int ov, int ih, int iv);
    375 static void setlayout(const Arg *arg);
    376 static void setmfact(const Arg *arg);
    377 static void setmon(Client *c, Monitor *m, uint32_t newtags);
    378 static void setpsel(struct wl_listener *listener, void *data);
    379 static void setsel(struct wl_listener *listener, void *data);
    380 static void setup(void);
    381 static void spawn(const Arg *arg);
    382 static void startdrag(struct wl_listener *listener, void *data);
    383 static int statusin(int fd, unsigned int mask, void *data);
    384 static void tag(const Arg *arg);
    385 static void tagmon(const Arg *arg);
    386 static void tile(Monitor *m);
    387 static void togglebar(const Arg *arg);
    388 static void togglefloating(const Arg *arg);
    389 static void togglefullscreen(const Arg *arg);
    390 static void togglegaps(const Arg *arg);
    391 static void toggletag(const Arg *arg);
    392 static void toggleview(const Arg *arg);
    393 static void unlocksession(struct wl_listener *listener, void *data);
    394 static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
    395 static void unmapnotify(struct wl_listener *listener, void *data);
    396 static void updatemons(struct wl_listener *listener, void *data);
    397 static void updatebar(Monitor *m);
    398 static void updatetitle(struct wl_listener *listener, void *data);
    399 static void urgent(struct wl_listener *listener, void *data);
    400 static void view(const Arg *arg);
    401 static void virtualkeyboard(struct wl_listener *listener, void *data);
    402 static void virtualpointer(struct wl_listener *listener, void *data);
    403 static Monitor *xytomon(double x, double y);
    404 static void xytonode(double x, double y, struct wlr_surface **psurface,
    405 		Client **pc, LayerSurface **pl, double *nx, double *ny);
    406 static void zoom(const Arg *arg);
    407 
    408 /* variables */
    409 static const char broken[] = "broken";
    410 static pid_t child_pid = -1;
    411 static int locked;
    412 static void *exclusive_focus;
    413 static struct wl_display *dpy;
    414 static struct wl_event_loop *event_loop;
    415 static struct wlr_backend *backend;
    416 static struct wlr_scene *scene;
    417 static struct wlr_scene_tree *layers[NUM_LAYERS];
    418 static struct wlr_scene_tree *drag_icon;
    419 /* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
    420 static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay };
    421 static struct wlr_renderer *drw;
    422 static struct wlr_allocator *alloc;
    423 static struct wlr_compositor *compositor;
    424 static struct wlr_session *session;
    425 
    426 static struct wlr_xdg_shell *xdg_shell;
    427 static struct wlr_xdg_activation_v1 *activation;
    428 static struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
    429 static struct wl_list clients; /* tiling order */
    430 static struct wl_list fstack;  /* focus order */
    431 static struct wlr_idle_notifier_v1 *idle_notifier;
    432 static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
    433 static struct wlr_layer_shell_v1 *layer_shell;
    434 static struct wlr_output_manager_v1 *output_mgr;
    435 static struct wlr_gamma_control_manager_v1 *gamma_control_mgr;
    436 static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
    437 static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
    438 static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
    439 static struct wlr_output_power_manager_v1 *power_mgr;
    440 
    441 static struct wlr_pointer_constraints_v1 *pointer_constraints;
    442 static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
    443 static struct wlr_pointer_constraint_v1 *active_constraint;
    444 
    445 static struct wlr_cursor *cursor;
    446 static struct wlr_xcursor_manager *cursor_mgr;
    447 
    448 static struct wlr_scene_rect *root_bg;
    449 static struct wlr_session_lock_manager_v1 *session_lock_mgr;
    450 static struct wlr_scene_rect *locked_bg;
    451 static struct wlr_session_lock_v1 *cur_lock;
    452 static struct wl_listener lock_listener = {.notify = locksession};
    453 
    454 static struct wlr_seat *seat;
    455 static KeyboardGroup *kb_group;
    456 static unsigned int cursor_mode;
    457 static Client *grabc;
    458 static int grabcx, grabcy; /* client-relative */
    459 
    460 static struct wlr_output_layout *output_layout;
    461 static struct wlr_box sgeom;
    462 static struct wl_list mons;
    463 static Monitor *selmon;
    464 
    465 static char stext[256];
    466 static struct wl_event_source *status_event_source;
    467 
    468 static const struct wlr_buffer_impl buffer_impl = {
    469     .destroy = bufdestroy,
    470     .begin_data_ptr_access = bufdatabegin,
    471     .end_data_ptr_access = bufdataend,
    472 };
    473 
    474 static int enablegaps = 1;   /* enables gaps, used by togglegaps */
    475 
    476 #ifdef XWAYLAND
    477 static void activatex11(struct wl_listener *listener, void *data);
    478 static void associatex11(struct wl_listener *listener, void *data);
    479 static void configurex11(struct wl_listener *listener, void *data);
    480 static void createnotifyx11(struct wl_listener *listener, void *data);
    481 static void dissociatex11(struct wl_listener *listener, void *data);
    482 static xcb_atom_t getatom(xcb_connection_t *xc, const char *name);
    483 static void sethints(struct wl_listener *listener, void *data);
    484 static void xwaylandready(struct wl_listener *listener, void *data);
    485 static struct wlr_xwayland *xwayland;
    486 static xcb_atom_t netatom[NetLast];
    487 #endif
    488 
    489 /* configuration, allows nested code to access above variables */
    490 #include "config.h"
    491 
    492 /* attempt to encapsulate suck into one file */
    493 #include "client.h"
    494 
    495 /* function implementations */
    496 void
    497 applybounds(Client *c, struct wlr_box *bbox)
    498 {
    499 	/* set minimum possible */
    500 	c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width);
    501 	c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height);
    502 
    503 	if (c->geom.x >= bbox->x + bbox->width)
    504 		c->geom.x = bbox->x + bbox->width - c->geom.width;
    505 	if (c->geom.y >= bbox->y + bbox->height)
    506 		c->geom.y = bbox->y + bbox->height - c->geom.height;
    507 	if (c->geom.x + c->geom.width <= bbox->x)
    508 		c->geom.x = bbox->x;
    509 	if (c->geom.y + c->geom.height <= bbox->y)
    510 		c->geom.y = bbox->y;
    511 }
    512 
    513 void
    514 applyrules(Client *c)
    515 {
    516 	/* rule matching */
    517 	const char *appid, *title;
    518 	uint32_t newtags = 0;
    519 	int i;
    520 	const Rule *r;
    521 	Monitor *mon = selmon, *m;
    522 
    523 	c->isfloating = client_is_float_type(c);
    524 	if (!(appid = client_get_appid(c)))
    525 		appid = broken;
    526 	if (!(title = client_get_title(c)))
    527 		title = broken;
    528 
    529 	for (r = rules; r < END(rules); r++) {
    530 		if ((!r->title || strstr(title, r->title))
    531 				&& (!r->id || strstr(appid, r->id))) {
    532 			c->isfloating = r->isfloating;
    533 			newtags |= r->tags;
    534 			i = 0;
    535 			wl_list_for_each(m, &mons, link) {
    536 				if (r->monitor == i++)
    537 					mon = m;
    538 			}
    539 		}
    540 	}
    541 	setmon(c, mon, newtags);
    542 }
    543 
    544 void
    545 arrange(Monitor *m)
    546 {
    547 	Client *c;
    548 
    549 	if (!m->wlr_output->enabled)
    550 		return;
    551 
    552 	wl_list_for_each(c, &clients, link) {
    553 		if (c->mon == m) {
    554 			wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m));
    555 			client_set_suspended(c, !VISIBLEON(c, m));
    556 		}
    557 	}
    558 
    559 	wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
    560 			(c = focustop(m)) && c->isfullscreen);
    561 
    562 	strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
    563 
    564 	/* We move all clients (except fullscreen and unmanaged) to LyrTile while
    565 	 * in floating layout to avoid "real" floating clients be always on top */
    566 	wl_list_for_each(c, &clients, link) {
    567 		if (c->mon != m || c->scene->node.parent == layers[LyrFS])
    568 			continue;
    569 
    570 		wlr_scene_node_reparent(&c->scene->node,
    571 				(!m->lt[m->sellt]->arrange && c->isfloating)
    572 						? layers[LyrTile]
    573 						: (m->lt[m->sellt]->arrange && c->isfloating)
    574 								? layers[LyrFloat]
    575 								: c->scene->node.parent);
    576 	}
    577 
    578 	if (m->lt[m->sellt]->arrange)
    579 		m->lt[m->sellt]->arrange(m);
    580 	motionnotify(0, NULL, 0, 0, 0, 0);
    581 	checkidleinhibitor(NULL);
    582 }
    583 
    584 void
    585 arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive)
    586 {
    587 	LayerSurface *l;
    588 	struct wlr_box full_area = m->m;
    589 
    590 	wl_list_for_each(l, list, link) {
    591 		struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
    592 
    593 		if (exclusive != (layer_surface->current.exclusive_zone > 0))
    594 			continue;
    595 
    596 		wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area);
    597 		wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y);
    598 		l->geom.x = l->scene->node.x;
    599 		l->geom.y = l->scene->node.y;
    600 	}
    601 }
    602 
    603 void
    604 arrangelayers(Monitor *m)
    605 {
    606 	int i;
    607 	struct wlr_box usable_area = m->m;
    608 	LayerSurface *l;
    609 	uint32_t layers_above_shell[] = {
    610 		ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
    611 		ZWLR_LAYER_SHELL_V1_LAYER_TOP,
    612 	};
    613 	if (!m->wlr_output->enabled)
    614 		return;
    615 
    616 	if (m->scene_buffer->node.enabled) {
    617 		usable_area.height -= m->b.real_height;
    618 		usable_area.y += topbar ? m->b.real_height : 0;
    619 	}
    620 
    621 	/* Arrange exclusive surfaces from top->bottom */
    622 	for (i = 3; i >= 0; i--)
    623 		arrangelayer(m, &m->layers[i], &usable_area, 1);
    624 
    625 	if (!wlr_box_equal(&usable_area, &m->w)) {
    626 		m->w = usable_area;
    627 		arrange(m);
    628 	}
    629 
    630 	/* Arrange non-exlusive surfaces from top->bottom */
    631 	for (i = 3; i >= 0; i--)
    632 		arrangelayer(m, &m->layers[i], &usable_area, 0);
    633 
    634 	/* Find topmost keyboard interactive layer, if such a layer exists */
    635 	for (i = 0; i < (int)LENGTH(layers_above_shell); i++) {
    636 		wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) {
    637 			if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped)
    638 				continue;
    639 			/* Deactivate the focused client. */
    640 			focusclient(NULL, 0);
    641 			exclusive_focus = l;
    642 			client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
    643 			return;
    644 		}
    645 	}
    646 }
    647 
    648 void
    649 axisnotify(struct wl_listener *listener, void *data)
    650 {
    651 	/* This event is forwarded by the cursor when a pointer emits an axis event,
    652 	 * for example when you move the scroll wheel. */
    653 	struct wlr_pointer_axis_event *event = data;
    654 	wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
    655 	/* TODO: allow usage of scroll whell for mousebindings, it can be implemented
    656 	 * checking the event's orientation and the delta of the event */
    657 	/* Notify the client with pointer focus of the axis event. */
    658 	wlr_seat_pointer_notify_axis(seat,
    659 			event->time_msec, event->orientation, event->delta,
    660 			event->delta_discrete, event->source, event->relative_direction);
    661 }
    662 
    663 bool
    664 baracceptsinput(struct wlr_scene_buffer *buffer, double *sx, double *sy)
    665 {
    666 	return true;
    667 }
    668 
    669 void
    670 bufdestroy(struct wlr_buffer *wlr_buffer)
    671 {
    672 	Buffer *buf = wl_container_of(wlr_buffer, buf, base);
    673 	if (buf->busy)
    674 		wl_list_remove(&buf->release.link);
    675 	drwl_image_destroy(buf->image);
    676 	free(buf);
    677 }
    678 
    679 bool
    680 bufdatabegin(struct wlr_buffer *wlr_buffer, uint32_t flags,
    681 		void **data, uint32_t *format, size_t *stride)
    682 {
    683 	Buffer *buf = wl_container_of(wlr_buffer, buf, base);
    684 
    685 	if (flags & WLR_BUFFER_DATA_PTR_ACCESS_WRITE) return false;
    686 
    687 	*data   = buf->data;
    688 	*stride = wlr_buffer->width * 4;
    689 	*format = DRM_FORMAT_ARGB8888;
    690 
    691 	return true;
    692 }
    693 
    694 void
    695 bufdataend(struct wlr_buffer *wlr_buffer)
    696 {
    697 }
    698 
    699 Buffer *
    700 bufmon(Monitor *m)
    701 {
    702 	size_t i;
    703 	Buffer *buf = NULL;
    704 
    705 	for (i = 0; i < LENGTH(m->pool); i++) {
    706 		if (m->pool[i]) {
    707 			if (m->pool[i]->busy)
    708 				continue;
    709 			buf = m->pool[i];
    710 			break;
    711 		}
    712 
    713 		buf = ecalloc(1, sizeof(Buffer) + (m->b.width * 4 * m->b.height));
    714 		buf->image = drwl_image_create(NULL, m->b.width, m->b.height, buf->data);
    715 		wlr_buffer_init(&buf->base, &buffer_impl, m->b.width, m->b.height);
    716 		m->pool[i] = buf;
    717 		break;
    718 	}
    719 	if (!buf)
    720 		return NULL;
    721 
    722 	buf->busy = true;
    723 	LISTEN(&buf->base.events.release, &buf->release, bufrelease);
    724 	wlr_buffer_lock(&buf->base);
    725 	drwl_setimage(m->drw, buf->image);
    726 	return buf;
    727 }
    728 
    729 void
    730 bufrelease(struct wl_listener *listener, void *data)
    731 {
    732 	Buffer *buf = wl_container_of(listener, buf, release);
    733 	buf->busy = false;
    734 	wl_list_remove(&buf->release.link);
    735 }
    736 
    737 void
    738 buttonpress(struct wl_listener *listener, void *data)
    739 {
    740 	unsigned int i = 0, x = 0;
    741 	double cx;
    742 	unsigned int click;
    743 	struct wlr_pointer_button_event *event = data;
    744 	struct wlr_keyboard *keyboard;
    745 	struct wlr_scene_node *node;
    746 	struct wlr_scene_buffer *buffer;
    747 	uint32_t mods;
    748 	Arg arg = {0};
    749 	Client *c;
    750 	const Button *b;
    751 
    752 	wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
    753 
    754 	click = ClkRoot;
    755 	xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
    756 	if (c)
    757 		click = ClkClient;
    758 
    759 	switch (event->state) {
    760 	case WL_POINTER_BUTTON_STATE_PRESSED:
    761 		cursor_mode = CurPressed;
    762 		selmon = xytomon(cursor->x, cursor->y);
    763 		if (locked)
    764 			break;
    765 
    766 		if (!c && !exclusive_focus &&
    767 			(node = wlr_scene_node_at(&layers[LyrBottom]->node, cursor->x, cursor->y, NULL, NULL)) &&
    768 			(buffer = wlr_scene_buffer_from_node(node)) && buffer == selmon->scene_buffer) {
    769 			cx = (cursor->x - selmon->m.x) * selmon->wlr_output->scale;
    770 			do
    771 				x += TEXTW(selmon, tags[i]);
    772 			while (cx >= x && ++i < LENGTH(tags));
    773 			if (i < LENGTH(tags)) {
    774 				click = ClkTagBar;
    775 				arg.ui = 1 << i;
    776 			} else if (cx < x + TEXTW(selmon, selmon->ltsymbol))
    777 				click = ClkLtSymbol;
    778 			else if (cx > selmon->b.width - (TEXTW(selmon, stext) - selmon->lrpad + 2)) {
    779 				click = ClkStatus;
    780 			} else
    781 				click = ClkTitle;
    782 		}
    783 
    784 		/* Change focus if the button was _pressed_ over a client */
    785 		xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
    786 		if (click == ClkClient && (!client_is_unmanaged(c) || client_wants_focus(c)))
    787 			focusclient(c, 1);
    788 
    789 		keyboard = wlr_seat_get_keyboard(seat);
    790 		mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
    791 		for (b = buttons; b < END(buttons); b++) {
    792 			if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && click == b->click && b->func) {
    793 				b->func(click == ClkTagBar && b->arg.i == 0 ? &arg : &b->arg);
    794 				return;
    795 			}
    796 		}
    797 		break;
    798 	case WL_POINTER_BUTTON_STATE_RELEASED:
    799 		/* If you released any buttons, we exit interactive move/resize mode. */
    800 		/* TODO should reset to the pointer focus's current setcursor */
    801 		if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) {
    802 			wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
    803 			cursor_mode = CurNormal;
    804 			/* Drop the window off on its new monitor */
    805 			selmon = xytomon(cursor->x, cursor->y);
    806 			setmon(grabc, selmon, 0);
    807 			return;
    808 		} else {
    809 			cursor_mode = CurNormal;
    810 		}
    811 		break;
    812 	}
    813 	/* If the event wasn't handled by the compositor, notify the client with
    814 	 * pointer focus that a button press has occurred */
    815 	wlr_seat_pointer_notify_button(seat,
    816 			event->time_msec, event->button, event->state);
    817 }
    818 
    819 void
    820 chvt(const Arg *arg)
    821 {
    822 	wlr_session_change_vt(session, arg->ui);
    823 }
    824 
    825 void
    826 checkidleinhibitor(struct wlr_surface *exclude)
    827 {
    828 	int inhibited = 0, unused_lx, unused_ly;
    829 	struct wlr_idle_inhibitor_v1 *inhibitor;
    830 	wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
    831 		struct wlr_surface *surface = wlr_surface_get_root_surface(inhibitor->surface);
    832 		struct wlr_scene_tree *tree = surface->data;
    833 		if (exclude != surface && (bypass_surface_visibility || (!tree
    834 				|| wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) {
    835 			inhibited = 1;
    836 			break;
    837 		}
    838 	}
    839 
    840 	wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited);
    841 }
    842 
    843 void
    844 cleanup(void)
    845 {
    846 #ifdef XWAYLAND
    847 	wlr_xwayland_destroy(xwayland);
    848 	xwayland = NULL;
    849 #endif
    850 	wl_display_destroy_clients(dpy);
    851 	if (child_pid > 0) {
    852 		kill(-child_pid, SIGTERM);
    853 		waitpid(child_pid, NULL, 0);
    854 	}
    855 	wlr_xcursor_manager_destroy(cursor_mgr);
    856 
    857 	destroykeyboardgroup(&kb_group->destroy, NULL);
    858 
    859 	/* If it's not destroyed manually it will cause a use-after-free of wlr_seat.
    860 	 * Destroy it until it's fixed in the wlroots side */
    861 	wlr_backend_destroy(backend);
    862 
    863 	wl_display_destroy(dpy);
    864 	/* Destroy after the wayland display (when the monitors are already destroyed)
    865 	   to avoid destroying them with an invalid scene output. */
    866 	wlr_scene_node_destroy(&scene->tree.node);
    867 
    868 	drwl_fini();
    869 }
    870 
    871 void
    872 cleanupmon(struct wl_listener *listener, void *data)
    873 {
    874 	Monitor *m = wl_container_of(listener, m, destroy);
    875 	LayerSurface *l, *tmp;
    876 	size_t i;
    877 
    878 	/* m->layers[i] are intentionally not unlinked */
    879 	for (i = 0; i < LENGTH(m->layers); i++) {
    880 		wl_list_for_each_safe(l, tmp, &m->layers[i], link)
    881 			wlr_layer_surface_v1_destroy(l->layer_surface);
    882 	}
    883 
    884 	for (i = 0; i < LENGTH(m->pool); i++)
    885 		wlr_buffer_drop(&m->pool[i]->base);
    886 
    887 	drwl_setimage(m->drw, NULL);
    888 	drwl_destroy(m->drw);
    889 
    890 	wl_list_remove(&m->destroy.link);
    891 	wl_list_remove(&m->frame.link);
    892 	wl_list_remove(&m->link);
    893 	wl_list_remove(&m->request_state.link);
    894 	m->wlr_output->data = NULL;
    895 	wlr_output_layout_remove(output_layout, m->wlr_output);
    896 	wlr_scene_output_destroy(m->scene_output);
    897 
    898 	closemon(m);
    899 	wlr_scene_node_destroy(&m->fullscreen_bg->node);
    900 	wlr_scene_node_destroy(&m->scene_buffer->node);
    901 	free(m);
    902 }
    903 
    904 void
    905 closemon(Monitor *m)
    906 {
    907 	/* update selmon if needed and
    908 	 * move closed monitor's clients to the focused one */
    909 	Client *c;
    910 	int i = 0, nmons = wl_list_length(&mons);
    911 	if (!nmons) {
    912 		selmon = NULL;
    913 	} else if (m == selmon) {
    914 		do /* don't switch to disabled mons */
    915 			selmon = wl_container_of(mons.next, selmon, link);
    916 		while (!selmon->wlr_output->enabled && i++ < nmons);
    917 
    918 		if (!selmon->wlr_output->enabled)
    919 			selmon = NULL;
    920 	}
    921 
    922 	wl_list_for_each(c, &clients, link) {
    923 		if (c->isfloating && c->geom.x > m->m.width)
    924 			resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y,
    925 					.width = c->geom.width, .height = c->geom.height}, 0);
    926 		if (c->mon == m)
    927 			setmon(c, selmon, c->tags);
    928 	}
    929 	focusclient(focustop(selmon), 1);
    930 	drawbars();
    931 }
    932 
    933 void
    934 commitlayersurfacenotify(struct wl_listener *listener, void *data)
    935 {
    936 	LayerSurface *l = wl_container_of(listener, l, surface_commit);
    937 	struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
    938 	struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->current.layer]];
    939 	struct wlr_layer_surface_v1_state old_state;
    940 
    941 	if (l->layer_surface->initial_commit) {
    942 		wlr_fractional_scale_v1_notify_scale(layer_surface->surface, l->mon->wlr_output->scale);
    943 		wlr_surface_set_preferred_buffer_scale(layer_surface->surface, (int32_t)ceilf(l->mon->wlr_output->scale));
    944 
    945 		/* Temporarily set the layer's current state to pending
    946 		 * so that we can easily arrange it */
    947 		old_state = l->layer_surface->current;
    948 		l->layer_surface->current = l->layer_surface->pending;
    949 		arrangelayers(l->mon);
    950 		l->layer_surface->current = old_state;
    951 		return;
    952 	}
    953 
    954 	if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
    955 		return;
    956 	l->mapped = layer_surface->surface->mapped;
    957 
    958 	if (scene_layer != l->scene->node.parent) {
    959 		wlr_scene_node_reparent(&l->scene->node, scene_layer);
    960 		wl_list_remove(&l->link);
    961 		wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link);
    962 		wlr_scene_node_reparent(&l->popups->node, (layer_surface->current.layer
    963 				< ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LyrTop] : scene_layer));
    964 	}
    965 
    966 	arrangelayers(l->mon);
    967 }
    968 
    969 void
    970 commitnotify(struct wl_listener *listener, void *data)
    971 {
    972 	Client *c = wl_container_of(listener, c, commit);
    973 
    974 	if (c->surface.xdg->initial_commit) {
    975 		/*
    976 		 * Get the monitor this client will be rendered on
    977 		 * Note that if the user set a rule in which the client is placed on
    978 		 * a different monitor based on its title this will likely select
    979 		 * a wrong monitor.
    980 		 */
    981 		applyrules(c);
    982 		if (c->mon) {
    983 			wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale));
    984 			wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale);
    985 		}
    986 		setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */
    987 
    988 		wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
    989 		wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0);
    990 		if (c->decoration)
    991 			requestdecorationmode(&c->set_decoration_mode, c->decoration);
    992 		return;
    993 	}
    994 
    995 	if (client_surface(c)->mapped && c->mon)
    996 		resize(c, c->geom, (c->isfloating && !c->isfullscreen));
    997 
    998 	/* mark a pending resize as completed */
    999 	if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
   1000 		c->resize = 0;
   1001 }
   1002 
   1003 void
   1004 commitpopup(struct wl_listener *listener, void *data)
   1005 {
   1006 	struct wlr_surface *surface = data;
   1007 	struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface);
   1008 	LayerSurface *l = NULL;
   1009 	Client *c = NULL;
   1010 	struct wlr_box box;
   1011 	int type = -1;
   1012 
   1013 	if (!popup->base->initial_commit)
   1014 		return;
   1015 
   1016 	type = toplevel_from_wlr_surface(popup->base->surface, &c, &l);
   1017 	if (!popup->parent || type < 0)
   1018 		return;
   1019 	popup->base->surface->data = wlr_scene_xdg_surface_create(
   1020 			popup->parent->data, popup->base);
   1021 	if ((l && !l->mon) || (c && !c->mon))
   1022 		return;
   1023 	box = type == LayerShell ? l->mon->m : c->mon->w;
   1024 	box.x -= (type == LayerShell ? l->geom.x : c->geom.x);
   1025 	box.y -= (type == LayerShell ? l->geom.y : c->geom.y);
   1026 	wlr_xdg_popup_unconstrain_from_box(popup, &box);
   1027 	wl_list_remove(&listener->link);
   1028 }
   1029 
   1030 void
   1031 createdecoration(struct wl_listener *listener, void *data)
   1032 {
   1033 	struct wlr_xdg_toplevel_decoration_v1 *deco = data;
   1034 	Client *c = deco->toplevel->base->data;
   1035 	c->decoration = deco;
   1036 
   1037 	LISTEN(&deco->events.request_mode, &c->set_decoration_mode, requestdecorationmode);
   1038 	LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration);
   1039 
   1040 	requestdecorationmode(&c->set_decoration_mode, deco);
   1041 }
   1042 
   1043 void
   1044 createidleinhibitor(struct wl_listener *listener, void *data)
   1045 {
   1046 	struct wlr_idle_inhibitor_v1 *idle_inhibitor = data;
   1047 	LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor);
   1048 
   1049 	checkidleinhibitor(NULL);
   1050 }
   1051 
   1052 void
   1053 createkeyboard(struct wlr_keyboard *keyboard)
   1054 {
   1055 	/* Set the keymap to match the group keymap */
   1056 	wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
   1057 
   1058 	/* Add the new keyboard to the group */
   1059 	wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard);
   1060 }
   1061 
   1062 KeyboardGroup *
   1063 createkeyboardgroup(void)
   1064 {
   1065 	KeyboardGroup *group = ecalloc(1, sizeof(*group));
   1066 	struct xkb_context *context;
   1067 	struct xkb_keymap *keymap;
   1068 
   1069 	group->wlr_group = wlr_keyboard_group_create();
   1070 	group->wlr_group->data = group;
   1071 
   1072 	/* Prepare an XKB keymap and assign it to the keyboard group. */
   1073 	context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
   1074 	if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules,
   1075 				XKB_KEYMAP_COMPILE_NO_FLAGS)))
   1076 		die("failed to compile keymap");
   1077 
   1078 	wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap);
   1079 	xkb_keymap_unref(keymap);
   1080 	xkb_context_unref(context);
   1081 
   1082 	wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, repeat_delay);
   1083 
   1084 	/* Set up listeners for keyboard events */
   1085 	LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress);
   1086 	LISTEN(&group->wlr_group->keyboard.events.modifiers, &group->modifiers, keypressmod);
   1087 
   1088 	group->key_repeat_source = wl_event_loop_add_timer(event_loop, keyrepeat, group);
   1089 
   1090 	/* A seat can only have one keyboard, but this is a limitation of the
   1091 	 * Wayland protocol - not wlroots. We assign all connected keyboards to the
   1092 	 * same wlr_keyboard_group, which provides a single wlr_keyboard interface for
   1093 	 * all of them. Set this combined wlr_keyboard as the seat keyboard.
   1094 	 */
   1095 	wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
   1096 	return group;
   1097 }
   1098 
   1099 void
   1100 createlayersurface(struct wl_listener *listener, void *data)
   1101 {
   1102 	struct wlr_layer_surface_v1 *layer_surface = data;
   1103 	LayerSurface *l;
   1104 	struct wlr_surface *surface = layer_surface->surface;
   1105 	struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->pending.layer]];
   1106 
   1107 	if (!layer_surface->output
   1108 			&& !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) {
   1109 		wlr_layer_surface_v1_destroy(layer_surface);
   1110 		return;
   1111 	}
   1112 
   1113 	l = layer_surface->data = ecalloc(1, sizeof(*l));
   1114 	l->type = LayerShell;
   1115 	LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify);
   1116 	LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify);
   1117 	LISTEN(&layer_surface->events.destroy, &l->destroy, destroylayersurfacenotify);
   1118 
   1119 	l->layer_surface = layer_surface;
   1120 	l->mon = layer_surface->output->data;
   1121 	l->scene_layer = wlr_scene_layer_surface_v1_create(scene_layer, layer_surface);
   1122 	l->scene = l->scene_layer->tree;
   1123 	l->popups = surface->data = wlr_scene_tree_create(layer_surface->current.layer
   1124 			< ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LyrTop] : scene_layer);
   1125 	l->scene->node.data = l->popups->node.data = l;
   1126 
   1127 	wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link);
   1128 	wlr_surface_send_enter(surface, layer_surface->output);
   1129 }
   1130 
   1131 void
   1132 createlocksurface(struct wl_listener *listener, void *data)
   1133 {
   1134 	SessionLock *lock = wl_container_of(listener, lock, new_surface);
   1135 	struct wlr_session_lock_surface_v1 *lock_surface = data;
   1136 	Monitor *m = lock_surface->output->data;
   1137 	struct wlr_scene_tree *scene_tree = lock_surface->surface->data
   1138 			= wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface);
   1139 	m->lock_surface = lock_surface;
   1140 
   1141 	wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);
   1142 	wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height);
   1143 
   1144 	LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, destroylocksurface);
   1145 
   1146 	if (m == selmon)
   1147 		client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat));
   1148 }
   1149 
   1150 void
   1151 createmon(struct wl_listener *listener, void *data)
   1152 {
   1153 	/* This event is raised by the backend when a new output (aka a display or
   1154 	 * monitor) becomes available. */
   1155 	struct wlr_output *wlr_output = data;
   1156 	const MonitorRule *r;
   1157 	size_t i;
   1158 	struct wlr_output_state state;
   1159 	Monitor *m;
   1160 
   1161 	if (!wlr_output_init_render(wlr_output, alloc, drw))
   1162 		return;
   1163 
   1164 	m = wlr_output->data = ecalloc(1, sizeof(*m));
   1165 	m->wlr_output = wlr_output;
   1166 
   1167 	for (i = 0; i < LENGTH(m->layers); i++)
   1168 		wl_list_init(&m->layers[i]);
   1169 
   1170 	m->gappih = gappih;
   1171 	m->gappiv = gappiv;
   1172 	m->gappoh = gappoh;
   1173 	m->gappov = gappov;
   1174 
   1175 	wlr_output_state_init(&state);
   1176 	/* Initialize monitor state using configured rules */
   1177 	m->tagset[0] = m->tagset[1] = 1;
   1178 	for (r = monrules; r < END(monrules); r++) {
   1179 		if (!r->name || strstr(wlr_output->name, r->name)) {
   1180 			m->m.x = r->x;
   1181 			m->m.y = r->y;
   1182 			m->mfact = r->mfact;
   1183 			m->nmaster = r->nmaster;
   1184 			m->lt[0] = r->lt;
   1185 			m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]];
   1186 			strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
   1187 			wlr_output_state_set_scale(&state, r->scale);
   1188 			wlr_output_state_set_transform(&state, r->rr);
   1189 			break;
   1190 		}
   1191 	}
   1192 
   1193 	/* The mode is a tuple of (width, height, refresh rate), and each
   1194 	 * monitor supports only a specific set of modes. We just pick the
   1195 	 * monitor's preferred mode; a more sophisticated compositor would let
   1196 	 * the user configure it. */
   1197 	wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
   1198 
   1199 	/* Set up event listeners */
   1200 	LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
   1201 	LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);
   1202 	LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate);
   1203 
   1204 	wlr_output_state_set_enabled(&state, 1);
   1205 	wlr_output_commit_state(wlr_output, &state);
   1206 	wlr_output_state_finish(&state);
   1207 
   1208 	if (!(m->drw = drwl_create()))
   1209 		die("failed to create drwl context");
   1210 
   1211 	m->scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL);
   1212 	m->scene_buffer->point_accepts_input = baracceptsinput;
   1213 	updatebar(m);
   1214 
   1215 	wl_list_insert(&mons, &m->link);
   1216 	drawbars();
   1217 
   1218 	/* The xdg-protocol specifies:
   1219 	 *
   1220 	 * If the fullscreened surface is not opaque, the compositor must make
   1221 	 * sure that other screen content not part of the same surface tree (made
   1222 	 * up of subsurfaces, popups or similarly coupled surfaces) are not
   1223 	 * visible below the fullscreened surface.
   1224 	 *
   1225 	 */
   1226 	/* updatemons() will resize and set correct position */
   1227 	m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg);
   1228 	wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0);
   1229 
   1230 	/* Adds this to the output layout in the order it was configured.
   1231 	 *
   1232 	 * The output layout utility automatically adds a wl_output global to the
   1233 	 * display, which Wayland clients can see to find out information about the
   1234 	 * output (such as DPI, scale factor, manufacturer, etc).
   1235 	 */
   1236 	m->scene_output = wlr_scene_output_create(scene, wlr_output);
   1237 	if (m->m.x == -1 && m->m.y == -1)
   1238 		wlr_output_layout_add_auto(output_layout, wlr_output);
   1239 	else
   1240 		wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
   1241 }
   1242 
   1243 void
   1244 createnotify(struct wl_listener *listener, void *data)
   1245 {
   1246 	/* This event is raised when a client creates a new toplevel (application window). */
   1247 	struct wlr_xdg_toplevel *toplevel = data;
   1248 	Client *c = NULL;
   1249 
   1250 	/* Allocate a Client for this surface */
   1251 	c = toplevel->base->data = ecalloc(1, sizeof(*c));
   1252 	c->surface.xdg = toplevel->base;
   1253 	c->bw = borderpx;
   1254 
   1255 	LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify);
   1256 	LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify);
   1257 	LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify);
   1258 	LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify);
   1259 	LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen, fullscreennotify);
   1260 	LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify);
   1261 	LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle);
   1262 }
   1263 
   1264 void
   1265 createpointer(struct wlr_pointer *pointer)
   1266 {
   1267 	struct libinput_device *device;
   1268 	if (wlr_input_device_is_libinput(&pointer->base)
   1269 			&& (device = wlr_libinput_get_device_handle(&pointer->base))) {
   1270 
   1271 		if (libinput_device_config_tap_get_finger_count(device)) {
   1272 			libinput_device_config_tap_set_enabled(device, tap_to_click);
   1273 			libinput_device_config_tap_set_drag_enabled(device, tap_and_drag);
   1274 			libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock);
   1275 			libinput_device_config_tap_set_button_map(device, button_map);
   1276 			if (libinput_device_config_scroll_has_natural_scroll(device))
   1277 				libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling);
   1278 		}
   1279 
   1280 		if (libinput_device_config_dwt_is_available(device))
   1281 			libinput_device_config_dwt_set_enabled(device, disable_while_typing);
   1282 
   1283 		if (libinput_device_config_left_handed_is_available(device))
   1284 			libinput_device_config_left_handed_set(device, left_handed);
   1285 
   1286 		if (libinput_device_config_middle_emulation_is_available(device))
   1287 			libinput_device_config_middle_emulation_set_enabled(device, middle_button_emulation);
   1288 
   1289 		if (libinput_device_config_scroll_get_methods(device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
   1290 			libinput_device_config_scroll_set_method (device, scroll_method);
   1291 
   1292 		if (libinput_device_config_click_get_methods(device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE)
   1293 			libinput_device_config_click_set_method (device, click_method);
   1294 
   1295 		if (libinput_device_config_send_events_get_modes(device))
   1296 			libinput_device_config_send_events_set_mode(device, send_events_mode);
   1297 
   1298 		if (libinput_device_config_accel_is_available(device)) {
   1299 			libinput_device_config_accel_set_profile(device, accel_profile);
   1300 			libinput_device_config_accel_set_speed(device, accel_speed);
   1301 		}
   1302 	}
   1303 
   1304 	wlr_cursor_attach_input_device(cursor, &pointer->base);
   1305 }
   1306 
   1307 void
   1308 createpointerconstraint(struct wl_listener *listener, void *data)
   1309 {
   1310 	PointerConstraint *pointer_constraint = ecalloc(1, sizeof(*pointer_constraint));
   1311 	pointer_constraint->constraint = data;
   1312 	LISTEN(&pointer_constraint->constraint->events.destroy,
   1313 			&pointer_constraint->destroy, destroypointerconstraint);
   1314 }
   1315 
   1316 void
   1317 createpopup(struct wl_listener *listener, void *data)
   1318 {
   1319 	/* This event is raised when a client (either xdg-shell or layer-shell)
   1320 	 * creates a new popup. */
   1321 	struct wlr_xdg_popup *popup = data;
   1322 	LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
   1323 }
   1324 
   1325 void
   1326 cursorconstrain(struct wlr_pointer_constraint_v1 *constraint)
   1327 {
   1328 	if (active_constraint == constraint)
   1329 		return;
   1330 
   1331 	if (active_constraint)
   1332 		wlr_pointer_constraint_v1_send_deactivated(active_constraint);
   1333 
   1334 	active_constraint = constraint;
   1335 	wlr_pointer_constraint_v1_send_activated(constraint);
   1336 }
   1337 
   1338 void
   1339 cursorframe(struct wl_listener *listener, void *data)
   1340 {
   1341 	/* This event is forwarded by the cursor when a pointer emits an frame
   1342 	 * event. Frame events are sent after regular pointer events to group
   1343 	 * multiple events together. For instance, two axis events may happen at the
   1344 	 * same time, in which case a frame event won't be sent in between. */
   1345 	/* Notify the client with pointer focus of the frame event. */
   1346 	wlr_seat_pointer_notify_frame(seat);
   1347 }
   1348 
   1349 void
   1350 cursorwarptohint(void)
   1351 {
   1352 	Client *c = NULL;
   1353 	double sx = active_constraint->current.cursor_hint.x;
   1354 	double sy = active_constraint->current.cursor_hint.y;
   1355 
   1356 	toplevel_from_wlr_surface(active_constraint->surface, &c, NULL);
   1357 	if (c && active_constraint->current.cursor_hint.enabled) {
   1358 		wlr_cursor_warp(cursor, NULL, sx + c->geom.x + c->bw, sy + c->geom.y + c->bw);
   1359 		wlr_seat_pointer_warp(active_constraint->seat, sx, sy);
   1360 	}
   1361 }
   1362 
   1363 void
   1364 defaultgaps(const Arg *arg)
   1365 {
   1366 	setgaps(gappoh, gappov, gappih, gappiv);
   1367 }
   1368 
   1369 void
   1370 destroydecoration(struct wl_listener *listener, void *data)
   1371 {
   1372 	Client *c = wl_container_of(listener, c, destroy_decoration);
   1373 	c->decoration = NULL;
   1374 
   1375 	wl_list_remove(&c->destroy_decoration.link);
   1376 	wl_list_remove(&c->set_decoration_mode.link);
   1377 }
   1378 
   1379 void
   1380 destroydragicon(struct wl_listener *listener, void *data)
   1381 {
   1382 	/* Focus enter isn't sent during drag, so refocus the focused node. */
   1383 	focusclient(focustop(selmon), 1);
   1384 	motionnotify(0, NULL, 0, 0, 0, 0);
   1385 }
   1386 
   1387 void
   1388 destroyidleinhibitor(struct wl_listener *listener, void *data)
   1389 {
   1390 	/* `data` is the wlr_surface of the idle inhibitor being destroyed,
   1391 	 * at this point the idle inhibitor is still in the list of the manager */
   1392 	checkidleinhibitor(wlr_surface_get_root_surface(data));
   1393 }
   1394 
   1395 void
   1396 destroylayersurfacenotify(struct wl_listener *listener, void *data)
   1397 {
   1398 	LayerSurface *l = wl_container_of(listener, l, destroy);
   1399 
   1400 	wl_list_remove(&l->link);
   1401 	wl_list_remove(&l->destroy.link);
   1402 	wl_list_remove(&l->unmap.link);
   1403 	wl_list_remove(&l->surface_commit.link);
   1404 	wlr_scene_node_destroy(&l->scene->node);
   1405 	wlr_scene_node_destroy(&l->popups->node);
   1406 	free(l);
   1407 }
   1408 
   1409 void
   1410 destroylock(SessionLock *lock, int unlock)
   1411 {
   1412 	wlr_seat_keyboard_notify_clear_focus(seat);
   1413 	if ((locked = !unlock))
   1414 		goto destroy;
   1415 
   1416 	wlr_scene_node_set_enabled(&locked_bg->node, 0);
   1417 
   1418 	focusclient(focustop(selmon), 0);
   1419 	motionnotify(0, NULL, 0, 0, 0, 0);
   1420 
   1421 destroy:
   1422 	wl_list_remove(&lock->new_surface.link);
   1423 	wl_list_remove(&lock->unlock.link);
   1424 	wl_list_remove(&lock->destroy.link);
   1425 
   1426 	wlr_scene_node_destroy(&lock->scene->node);
   1427 	cur_lock = NULL;
   1428 	free(lock);
   1429 }
   1430 
   1431 void
   1432 destroylocksurface(struct wl_listener *listener, void *data)
   1433 {
   1434 	Monitor *m = wl_container_of(listener, m, destroy_lock_surface);
   1435 	struct wlr_session_lock_surface_v1 *surface, *lock_surface = m->lock_surface;
   1436 
   1437 	m->lock_surface = NULL;
   1438 	wl_list_remove(&m->destroy_lock_surface.link);
   1439 
   1440 	if (lock_surface->surface != seat->keyboard_state.focused_surface)
   1441 		return;
   1442 
   1443 	if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) {
   1444 		surface = wl_container_of(cur_lock->surfaces.next, surface, link);
   1445 		client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
   1446 	} else if (!locked) {
   1447 		focusclient(focustop(selmon), 1);
   1448 	} else {
   1449 		wlr_seat_keyboard_clear_focus(seat);
   1450 	}
   1451 }
   1452 
   1453 void
   1454 destroynotify(struct wl_listener *listener, void *data)
   1455 {
   1456 	/* Called when the xdg_toplevel is destroyed. */
   1457 	Client *c = wl_container_of(listener, c, destroy);
   1458 	wl_list_remove(&c->destroy.link);
   1459 	wl_list_remove(&c->set_title.link);
   1460 	wl_list_remove(&c->fullscreen.link);
   1461 #ifdef XWAYLAND
   1462 	if (c->type != XDGShell) {
   1463 		wl_list_remove(&c->activate.link);
   1464 		wl_list_remove(&c->associate.link);
   1465 		wl_list_remove(&c->configure.link);
   1466 		wl_list_remove(&c->dissociate.link);
   1467 		wl_list_remove(&c->set_hints.link);
   1468 	} else
   1469 #endif
   1470 	{
   1471 		wl_list_remove(&c->commit.link);
   1472 		wl_list_remove(&c->map.link);
   1473 		wl_list_remove(&c->unmap.link);
   1474 	}
   1475 	free(c);
   1476 }
   1477 
   1478 void
   1479 destroypointerconstraint(struct wl_listener *listener, void *data)
   1480 {
   1481 	PointerConstraint *pointer_constraint = wl_container_of(listener, pointer_constraint, destroy);
   1482 
   1483 	if (active_constraint == pointer_constraint->constraint) {
   1484 		cursorwarptohint();
   1485 		active_constraint = NULL;
   1486 	}
   1487 
   1488 	wl_list_remove(&pointer_constraint->destroy.link);
   1489 	free(pointer_constraint);
   1490 }
   1491 
   1492 void
   1493 destroysessionlock(struct wl_listener *listener, void *data)
   1494 {
   1495 	SessionLock *lock = wl_container_of(listener, lock, destroy);
   1496 	destroylock(lock, 0);
   1497 }
   1498 
   1499 void
   1500 destroysessionmgr(struct wl_listener *listener, void *data)
   1501 {
   1502 	wl_list_remove(&lock_listener.link);
   1503 	wl_list_remove(&listener->link);
   1504 }
   1505 
   1506 void
   1507 destroykeyboardgroup(struct wl_listener *listener, void *data)
   1508 {
   1509 	KeyboardGroup *group = wl_container_of(listener, group, destroy);
   1510 	wl_event_source_remove(group->key_repeat_source);
   1511 	wlr_keyboard_group_destroy(group->wlr_group);
   1512 	wl_list_remove(&group->key.link);
   1513 	wl_list_remove(&group->modifiers.link);
   1514 	wl_list_remove(&group->destroy.link);
   1515 	free(group);
   1516 }
   1517 
   1518 Monitor *
   1519 dirtomon(enum wlr_direction dir)
   1520 {
   1521 	struct wlr_output *next;
   1522 	if (!wlr_output_layout_get(output_layout, selmon->wlr_output))
   1523 		return selmon;
   1524 	if ((next = wlr_output_layout_adjacent_output(output_layout,
   1525 			dir, selmon->wlr_output, selmon->m.x, selmon->m.y)))
   1526 		return next->data;
   1527 	if ((next = wlr_output_layout_farthest_output(output_layout,
   1528 			dir ^ (WLR_DIRECTION_LEFT|WLR_DIRECTION_RIGHT),
   1529 			selmon->wlr_output, selmon->m.x, selmon->m.y)))
   1530 		return next->data;
   1531 	return selmon;
   1532 }
   1533 
   1534 void
   1535 drawbar(Monitor *m)
   1536 {
   1537 	int x, w, tw = 0;
   1538 	int boxs = m->drw->font->height / 9;
   1539 	int boxw = m->drw->font->height / 6 + 2;
   1540 	uint32_t i, occ = 0, urg = 0;
   1541 	Client *c;
   1542 	Buffer *buf;
   1543 
   1544 	if (!m->scene_buffer->node.enabled)
   1545 		return;
   1546 	if (!(buf = bufmon(m)))
   1547 		return;
   1548 
   1549 	/* draw status first so it can be overdrawn by tags later */
   1550 	if (m == selmon) { /* status is only drawn on selected monitor */
   1551 		drwl_setscheme(m->drw, colors[SchemeNorm]);
   1552 		tw = TEXTW(m, stext) - m->lrpad + 2; /* 2px right padding */
   1553 		drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0);
   1554 	}
   1555 
   1556 	wl_list_for_each(c, &clients, link) {
   1557 		if (c->mon != m)
   1558 			continue;
   1559 		occ |= c->tags;
   1560 		if (c->isurgent)
   1561 			urg |= c->tags;
   1562 	}
   1563 	x = 0;
   1564 	c = focustop(m);
   1565 	for (i = 0; i < LENGTH(tags); i++) {
   1566 		w = TEXTW(m, tags[i]);
   1567 		drwl_setscheme(m->drw, colors[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
   1568 		drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, tags[i], urg & 1 << i);
   1569 		if (occ & 1 << i)
   1570 			drwl_rect(m->drw, x + boxs, boxs, boxw, boxw,
   1571 				m == selmon && c && c->tags & 1 << i,
   1572 				urg & 1 << i);
   1573 		x += w;
   1574 	}
   1575 	w = TEXTW(m, m->ltsymbol);
   1576 	drwl_setscheme(m->drw, colors[SchemeNorm]);
   1577 	x = drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, m->ltsymbol, 0);
   1578 
   1579 	if ((w = m->b.width - tw - x) > m->b.height) {
   1580 		if (c) {
   1581 			drwl_setscheme(m->drw, colors[m == selmon ? SchemeSel : SchemeNorm]);
   1582 			drwl_text(m->drw, x, 0, w, m->b.height, m->lrpad / 2, client_get_title(c), 0);
   1583 			if (c && c->isfloating)
   1584 				drwl_rect(m->drw, x + boxs, boxs, boxw, boxw, 0, 0);
   1585 		} else {
   1586 			drwl_setscheme(m->drw, colors[SchemeNorm]);
   1587 			drwl_rect(m->drw, x, 0, w, m->b.height, 1, 1);
   1588 		}
   1589 	}
   1590 
   1591 	wlr_scene_buffer_set_dest_size(m->scene_buffer,
   1592 		m->b.real_width, m->b.real_height);
   1593 	wlr_scene_node_set_position(&m->scene_buffer->node, m->m.x,
   1594 		m->m.y + (topbar ? 0 : m->m.height - m->b.real_height));
   1595 	wlr_scene_buffer_set_buffer(m->scene_buffer, &buf->base);
   1596 	wlr_buffer_unlock(&buf->base);
   1597 }
   1598 
   1599 void
   1600 drawbars(void)
   1601 {
   1602 	Monitor *m = NULL;
   1603 
   1604 	wl_list_for_each(m, &mons, link)
   1605 		drawbar(m);
   1606 }
   1607 
   1608 void
   1609 focusclient(Client *c, int lift)
   1610 {
   1611 	struct wlr_surface *old = seat->keyboard_state.focused_surface;
   1612 	int unused_lx, unused_ly, old_client_type;
   1613 	Client *old_c = NULL;
   1614 	LayerSurface *old_l = NULL;
   1615 
   1616 	if (locked)
   1617 		return;
   1618 
   1619 	/* Raise client in stacking order if requested */
   1620 	if (c && lift)
   1621 		wlr_scene_node_raise_to_top(&c->scene->node);
   1622 
   1623 	if (c && client_surface(c) == old)
   1624 		return;
   1625 
   1626 	if ((old_client_type = toplevel_from_wlr_surface(old, &old_c, &old_l)) == XDGShell) {
   1627 		struct wlr_xdg_popup *popup, *tmp;
   1628 		wl_list_for_each_safe(popup, tmp, &old_c->surface.xdg->popups, link)
   1629 			wlr_xdg_popup_destroy(popup);
   1630 	}
   1631 
   1632 	/* Put the new client atop the focus stack and select its monitor */
   1633 	if (c && !client_is_unmanaged(c)) {
   1634 		wl_list_remove(&c->flink);
   1635 		wl_list_insert(&fstack, &c->flink);
   1636 		selmon = c->mon;
   1637 		c->isurgent = 0;
   1638 		client_restack_surface(c);
   1639 
   1640 		/* Don't change border color if there is an exclusive focus or we are
   1641 		 * handling a drag operation */
   1642 		if (!exclusive_focus && !seat->drag)
   1643 			client_set_border_color(c, (float[])COLOR(colors[SchemeSel][ColBorder]));
   1644 	}
   1645 
   1646 	/* Deactivate old client if focus is changing */
   1647 	if (old && (!c || client_surface(c) != old)) {
   1648 		/* If an overlay is focused, don't focus or activate the client,
   1649 		 * but only update its position in fstack to render its border with its color
   1650 		 * and focus it after the overlay is closed. */
   1651 		if (old_client_type == LayerShell && wlr_scene_node_coords(
   1652 					&old_l->scene->node, &unused_lx, &unused_ly)
   1653 				&& old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
   1654 			return;
   1655 		} else if (old_c && old_c == exclusive_focus && client_wants_focus(old_c)) {
   1656 			return;
   1657 		/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
   1658 		 * and probably other clients */
   1659 		} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
   1660 			client_set_border_color(old_c, (float[])COLOR(colors[SchemeNorm][ColBorder]));
   1661 			client_activate_surface(old, 0);
   1662 		}
   1663 	}
   1664 	drawbars();
   1665 
   1666 	if (!c) {
   1667 		/* With no client, all we have left is to clear focus */
   1668 		wlr_seat_keyboard_notify_clear_focus(seat);
   1669 		return;
   1670 	}
   1671 
   1672 	/* Change cursor surface */
   1673 	motionnotify(0, NULL, 0, 0, 0, 0);
   1674 
   1675 	/* Have a client, so focus its top-level wlr_surface */
   1676 	client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
   1677 
   1678 	/* Activate the new client */
   1679 	client_activate_surface(client_surface(c), 1);
   1680 }
   1681 
   1682 void
   1683 focusmon(const Arg *arg)
   1684 {
   1685 	int i = 0, nmons = wl_list_length(&mons);
   1686 	if (nmons) {
   1687 		do /* don't switch to disabled mons */
   1688 			selmon = dirtomon(arg->i);
   1689 		while (!selmon->wlr_output->enabled && i++ < nmons);
   1690 	}
   1691 	focusclient(focustop(selmon), 1);
   1692 }
   1693 
   1694 void
   1695 focusstack(const Arg *arg)
   1696 {
   1697 	/* Focus the next or previous client (in tiling order) on selmon */
   1698 	Client *c, *sel = focustop(selmon);
   1699 	if (!sel || (sel->isfullscreen && !client_has_children(sel)))
   1700 		return;
   1701 	if (arg->i > 0) {
   1702 		wl_list_for_each(c, &sel->link, link) {
   1703 			if (&c->link == &clients)
   1704 				continue; /* wrap past the sentinel node */
   1705 			if (VISIBLEON(c, selmon))
   1706 				break; /* found it */
   1707 		}
   1708 	} else {
   1709 		wl_list_for_each_reverse(c, &sel->link, link) {
   1710 			if (&c->link == &clients)
   1711 				continue; /* wrap past the sentinel node */
   1712 			if (VISIBLEON(c, selmon))
   1713 				break; /* found it */
   1714 		}
   1715 	}
   1716 	/* If only one client is visible on selmon, then c == sel */
   1717 	focusclient(c, 1);
   1718 }
   1719 
   1720 /* We probably should change the name of this, it sounds like
   1721  * will focus the topmost client of this mon, when actually will
   1722  * only return that client */
   1723 Client *
   1724 focustop(Monitor *m)
   1725 {
   1726 	Client *c;
   1727 	wl_list_for_each(c, &fstack, flink) {
   1728 		if (VISIBLEON(c, m))
   1729 			return c;
   1730 	}
   1731 	return NULL;
   1732 }
   1733 
   1734 void
   1735 fullscreennotify(struct wl_listener *listener, void *data)
   1736 {
   1737 	Client *c = wl_container_of(listener, c, fullscreen);
   1738 	setfullscreen(c, client_wants_fullscreen(c));
   1739 }
   1740 
   1741 void
   1742 gpureset(struct wl_listener *listener, void *data)
   1743 {
   1744 	struct wlr_renderer *old_drw = drw;
   1745 	struct wlr_allocator *old_alloc = alloc;
   1746 	struct Monitor *m;
   1747 	if (!(drw = wlr_renderer_autocreate(backend)))
   1748 		die("couldn't recreate renderer");
   1749 
   1750 	if (!(alloc = wlr_allocator_autocreate(backend, drw)))
   1751 		die("couldn't recreate allocator");
   1752 
   1753 	LISTEN_STATIC(&drw->events.lost, gpureset);
   1754 
   1755 	wlr_compositor_set_renderer(compositor, drw);
   1756 
   1757 	wl_list_for_each(m, &mons, link) {
   1758 		wlr_output_init_render(m->wlr_output, alloc, drw);
   1759 	}
   1760 
   1761 	wlr_allocator_destroy(old_alloc);
   1762 	wlr_renderer_destroy(old_drw);
   1763 }
   1764 
   1765 void
   1766 handlesig(int signo)
   1767 {
   1768 	if (signo == SIGCHLD) {
   1769 #ifdef XWAYLAND
   1770 		siginfo_t in;
   1771 		/* wlroots expects to reap the XWayland process itself, so we
   1772 		 * use WNOWAIT to keep the child waitable until we know it's not
   1773 		 * XWayland.
   1774 		 */
   1775 		while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
   1776 				&& (!xwayland || in.si_pid != xwayland->server->pid))
   1777 			waitpid(in.si_pid, NULL, 0);
   1778 #else
   1779 		while (waitpid(-1, NULL, WNOHANG) > 0);
   1780 #endif
   1781 	} else if (signo == SIGINT || signo == SIGTERM) {
   1782 		quit(NULL);
   1783 	}
   1784 }
   1785 
   1786 void
   1787 incnmaster(const Arg *arg)
   1788 {
   1789 	if (!arg || !selmon)
   1790 		return;
   1791 	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
   1792 	arrange(selmon);
   1793 }
   1794 
   1795 void
   1796 incgaps(const Arg *arg)
   1797 {
   1798 	setgaps(
   1799 		selmon->gappoh + arg->i,
   1800 		selmon->gappov + arg->i,
   1801 		selmon->gappih + arg->i,
   1802 		selmon->gappiv + arg->i
   1803 	);
   1804 }
   1805 
   1806 void
   1807 incigaps(const Arg *arg)
   1808 {
   1809 	setgaps(
   1810 		selmon->gappoh,
   1811 		selmon->gappov,
   1812 		selmon->gappih + arg->i,
   1813 		selmon->gappiv + arg->i
   1814 	);
   1815 }
   1816 
   1817 void
   1818 incihgaps(const Arg *arg)
   1819 {
   1820 	setgaps(
   1821 		selmon->gappoh,
   1822 		selmon->gappov,
   1823 		selmon->gappih + arg->i,
   1824 		selmon->gappiv
   1825 	);
   1826 }
   1827 
   1828 void
   1829 incivgaps(const Arg *arg)
   1830 {
   1831 	setgaps(
   1832 		selmon->gappoh,
   1833 		selmon->gappov,
   1834 		selmon->gappih,
   1835 		selmon->gappiv + arg->i
   1836 	);
   1837 }
   1838 
   1839 void
   1840 incogaps(const Arg *arg)
   1841 {
   1842 	setgaps(
   1843 		selmon->gappoh + arg->i,
   1844 		selmon->gappov + arg->i,
   1845 		selmon->gappih,
   1846 		selmon->gappiv
   1847 	);
   1848 }
   1849 
   1850 void
   1851 incohgaps(const Arg *arg)
   1852 {
   1853 	setgaps(
   1854 		selmon->gappoh + arg->i,
   1855 		selmon->gappov,
   1856 		selmon->gappih,
   1857 		selmon->gappiv
   1858 	);
   1859 }
   1860 
   1861 void
   1862 incovgaps(const Arg *arg)
   1863 {
   1864 	setgaps(
   1865 		selmon->gappoh,
   1866 		selmon->gappov + arg->i,
   1867 		selmon->gappih,
   1868 		selmon->gappiv
   1869 	);
   1870 }
   1871 
   1872 void
   1873 inputdevice(struct wl_listener *listener, void *data)
   1874 {
   1875 	/* This event is raised by the backend when a new input device becomes
   1876 	 * available. */
   1877 	struct wlr_input_device *device = data;
   1878 	uint32_t caps;
   1879 
   1880 	switch (device->type) {
   1881 	case WLR_INPUT_DEVICE_KEYBOARD:
   1882 		createkeyboard(wlr_keyboard_from_input_device(device));
   1883 		break;
   1884 	case WLR_INPUT_DEVICE_POINTER:
   1885 		createpointer(wlr_pointer_from_input_device(device));
   1886 		break;
   1887 	default:
   1888 		/* TODO handle other input device types */
   1889 		break;
   1890 	}
   1891 
   1892 	/* We need to let the wlr_seat know what our capabilities are, which is
   1893 	 * communiciated to the client. In dwl we always have a cursor, even if
   1894 	 * there are no pointer devices, so we always include that capability. */
   1895 	/* TODO do we actually require a cursor? */
   1896 	caps = WL_SEAT_CAPABILITY_POINTER;
   1897 	if (!wl_list_empty(&kb_group->wlr_group->devices))
   1898 		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
   1899 	wlr_seat_set_capabilities(seat, caps);
   1900 }
   1901 
   1902 int
   1903 keybinding(uint32_t mods, xkb_keysym_t sym)
   1904 {
   1905 	/*
   1906 	 * Here we handle compositor keybindings. This is when the compositor is
   1907 	 * processing keys, rather than passing them on to the client for its own
   1908 	 * processing.
   1909 	 */
   1910 	const Key *k;
   1911 	for (k = keys; k < END(keys); k++) {
   1912 		if (CLEANMASK(mods) == CLEANMASK(k->mod)
   1913 				&& sym == k->keysym && k->func) {
   1914 			k->func(&k->arg);
   1915 			return 1;
   1916 		}
   1917 	}
   1918 	return 0;
   1919 }
   1920 
   1921 void
   1922 keypress(struct wl_listener *listener, void *data)
   1923 {
   1924 	int i;
   1925 	/* This event is raised when a key is pressed or released. */
   1926 	KeyboardGroup *group = wl_container_of(listener, group, key);
   1927 	struct wlr_keyboard_key_event *event = data;
   1928 
   1929 	/* Translate libinput keycode -> xkbcommon */
   1930 	uint32_t keycode = event->keycode + 8;
   1931 	/* Get a list of keysyms based on the keymap for this keyboard */
   1932 	const xkb_keysym_t *syms;
   1933 	int nsyms = xkb_state_key_get_syms(
   1934 			group->wlr_group->keyboard.xkb_state, keycode, &syms);
   1935 
   1936 	int handled = 0;
   1937 	uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
   1938 
   1939 	wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
   1940 
   1941 	/* On _press_ if there is no active screen locker,
   1942 	 * attempt to process a compositor keybinding. */
   1943 	if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
   1944 		for (i = 0; i < nsyms; i++)
   1945 			handled = keybinding(mods, syms[i]) || handled;
   1946 	}
   1947 
   1948 	if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
   1949 		group->mods = mods;
   1950 		group->keysyms = syms;
   1951 		group->nsyms = nsyms;
   1952 		wl_event_source_timer_update(group->key_repeat_source,
   1953 				group->wlr_group->keyboard.repeat_info.delay);
   1954 	} else {
   1955 		group->nsyms = 0;
   1956 		wl_event_source_timer_update(group->key_repeat_source, 0);
   1957 	}
   1958 
   1959 	if (handled)
   1960 		return;
   1961 
   1962 	wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
   1963 	/* Pass unhandled keycodes along to the client. */
   1964 	wlr_seat_keyboard_notify_key(seat, event->time_msec,
   1965 			event->keycode, event->state);
   1966 }
   1967 
   1968 void
   1969 keypressmod(struct wl_listener *listener, void *data)
   1970 {
   1971 	/* This event is raised when a modifier key, such as shift or alt, is
   1972 	 * pressed. We simply communicate this to the client. */
   1973 	KeyboardGroup *group = wl_container_of(listener, group, modifiers);
   1974 
   1975 	wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
   1976 	/* Send modifiers to the client. */
   1977 	wlr_seat_keyboard_notify_modifiers(seat,
   1978 			&group->wlr_group->keyboard.modifiers);
   1979 }
   1980 
   1981 int
   1982 keyrepeat(void *data)
   1983 {
   1984 	KeyboardGroup *group = data;
   1985 	int i;
   1986 	if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0)
   1987 		return 0;
   1988 
   1989 	wl_event_source_timer_update(group->key_repeat_source,
   1990 			1000 / group->wlr_group->keyboard.repeat_info.rate);
   1991 
   1992 	for (i = 0; i < group->nsyms; i++)
   1993 		keybinding(group->mods, group->keysyms[i]);
   1994 
   1995 	return 0;
   1996 }
   1997 
   1998 void
   1999 killclient(const Arg *arg)
   2000 {
   2001 	Client *sel = focustop(selmon);
   2002 	if (sel)
   2003 		client_send_close(sel);
   2004 }
   2005 
   2006 void
   2007 locksession(struct wl_listener *listener, void *data)
   2008 {
   2009 	struct wlr_session_lock_v1 *session_lock = data;
   2010 	SessionLock *lock;
   2011 	wlr_scene_node_set_enabled(&locked_bg->node, 1);
   2012 	if (cur_lock) {
   2013 		wlr_session_lock_v1_destroy(session_lock);
   2014 		return;
   2015 	}
   2016 	lock = session_lock->data = ecalloc(1, sizeof(*lock));
   2017 	focusclient(NULL, 0);
   2018 
   2019 	lock->scene = wlr_scene_tree_create(layers[LyrBlock]);
   2020 	cur_lock = lock->lock = session_lock;
   2021 	locked = 1;
   2022 
   2023 	LISTEN(&session_lock->events.new_surface, &lock->new_surface, createlocksurface);
   2024 	LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock);
   2025 	LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession);
   2026 
   2027 	wlr_session_lock_v1_send_locked(session_lock);
   2028 }
   2029 
   2030 void
   2031 mapnotify(struct wl_listener *listener, void *data)
   2032 {
   2033 	/* Called when the surface is mapped, or ready to display on-screen. */
   2034 	Client *p = NULL;
   2035 	Client *w, *c = wl_container_of(listener, c, map);
   2036 	Monitor *m;
   2037 	int i;
   2038 
   2039 	/* Create scene tree for this client and its border */
   2040 	c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]);
   2041 	wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell);
   2042 	c->scene_surface = c->type == XDGShell
   2043 			? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
   2044 			: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
   2045 	c->scene->node.data = c->scene_surface->node.data = c;
   2046 
   2047 	client_get_geometry(c, &c->geom);
   2048 
   2049 	/* Handle unmanaged clients first so we can return prior create borders */
   2050 	if (client_is_unmanaged(c)) {
   2051 		/* Unmanaged clients always are floating */
   2052 		wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]);
   2053 		wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
   2054 		if (client_wants_focus(c)) {
   2055 			focusclient(c, 1);
   2056 			exclusive_focus = c;
   2057 		}
   2058 		goto unset_fullscreen;
   2059 	}
   2060 
   2061 	for (i = 0; i < 4; i++) {
   2062 		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0,
   2063 			(float[])COLOR(colors[c->isurgent ? SchemeUrg : SchemeNorm][ColBorder]));
   2064 		c->border[i]->node.data = c;
   2065 	}
   2066 
   2067 	/* Initialize client geometry with room for border */
   2068 	client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
   2069 	c->geom.width += 2 * c->bw;
   2070 	c->geom.height += 2 * c->bw;
   2071 
   2072 	/* Insert this client into client lists. */
   2073 	if (clients.prev) {
   2074 		wl_list_insert(clients.prev, &c->link);
   2075 	} else {
   2076 		wl_list_insert(&clients, &c->link);
   2077 	}
   2078 	wl_list_insert(&fstack, &c->flink);
   2079 
   2080 	/* Set initial monitor, tags, floating status, and focus:
   2081 	 * we always consider floating, clients that have parent and thus
   2082 	 * we set the same tags and monitor than its parent, if not
   2083 	 * try to apply rules for them */
   2084 	if ((p = client_get_parent(c))) {
   2085 		c->isfloating = 1;
   2086 		setmon(c, p->mon, p->tags);
   2087 	} else {
   2088 		applyrules(c);
   2089 	}
   2090 	drawbars();
   2091 
   2092 unset_fullscreen:
   2093 	m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y);
   2094 	wl_list_for_each(w, &clients, link) {
   2095 		if (w != c && w != p && w->isfullscreen && m == w->mon && (w->tags & c->tags))
   2096 			setfullscreen(w, 0);
   2097 	}
   2098 }
   2099 
   2100 void
   2101 maximizenotify(struct wl_listener *listener, void *data)
   2102 {
   2103 	/* This event is raised when a client would like to maximize itself,
   2104 	 * typically because the user clicked on the maximize button on
   2105 	 * client-side decorations. dwl doesn't support maximization, but
   2106 	 * to conform to xdg-shell protocol we still must send a configure.
   2107 	 * Since xdg-shell protocol v5 we should ignore request of unsupported
   2108 	 * capabilities, just schedule a empty configure when the client uses <5
   2109 	 * protocol version
   2110 	 * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */
   2111 	Client *c = wl_container_of(listener, c, maximize);
   2112 	if (c->surface.xdg->initialized
   2113 			&& wl_resource_get_version(c->surface.xdg->toplevel->resource)
   2114 					< XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION)
   2115 		wlr_xdg_surface_schedule_configure(c->surface.xdg);
   2116 }
   2117 
   2118 void
   2119 monocle(Monitor *m)
   2120 {
   2121 	Client *c;
   2122 	int n = 0;
   2123 
   2124 	wl_list_for_each(c, &clients, link) {
   2125 		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
   2126 			continue;
   2127 		n++;
   2128 		if (!monoclegaps)
   2129 			resize(c, m->w, 0);
   2130 		else
   2131 			resize(c, (struct wlr_box){.x = m->w.x + gappoh, .y = m->w.y + gappov,
   2132 				.width = m->w.width - 2 * gappoh, .height = m->w.height - 2 * gappov}, 0);
   2133 	}
   2134 	if (n)
   2135 		snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);
   2136 	if ((c = focustop(m)))
   2137 		wlr_scene_node_raise_to_top(&c->scene->node);
   2138 }
   2139 
   2140 void
   2141 motionabsolute(struct wl_listener *listener, void *data)
   2142 {
   2143 	/* This event is forwarded by the cursor when a pointer emits an _absolute_
   2144 	 * motion event, from 0..1 on each axis. This happens, for example, when
   2145 	 * wlroots is running under a Wayland window rather than KMS+DRM, and you
   2146 	 * move the mouse over the window. You could enter the window from any edge,
   2147 	 * so we have to warp the mouse there. There is also some hardware which
   2148 	 * emits these events. */
   2149 	struct wlr_pointer_motion_absolute_event *event = data;
   2150 	double lx, ly, dx, dy;
   2151 
   2152 	if (!event->time_msec) /* this is 0 with virtual pointers */
   2153 		wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y);
   2154 
   2155 	wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, event->y, &lx, &ly);
   2156 	dx = lx - cursor->x;
   2157 	dy = ly - cursor->y;
   2158 	motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
   2159 }
   2160 
   2161 void
   2162 motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double dy,
   2163 		double dx_unaccel, double dy_unaccel)
   2164 {
   2165 	double sx = 0, sy = 0, sx_confined, sy_confined;
   2166 	Client *c = NULL, *w = NULL;
   2167 	LayerSurface *l = NULL;
   2168 	struct wlr_surface *surface = NULL;
   2169 	struct wlr_pointer_constraint_v1 *constraint;
   2170 
   2171 	/* Find the client under the pointer and send the event along. */
   2172 	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
   2173 
   2174 	if (cursor_mode == CurPressed && !seat->drag
   2175 			&& surface != seat->pointer_state.focused_surface
   2176 			&& toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) {
   2177 		c = w;
   2178 		surface = seat->pointer_state.focused_surface;
   2179 		sx = cursor->x - (l ? l->geom.x : w->geom.x);
   2180 		sy = cursor->y - (l ? l->geom.y : w->geom.y);
   2181 	}
   2182 
   2183 	/* time is 0 in internal calls meant to restore pointer focus. */
   2184 	if (time) {
   2185 		wlr_relative_pointer_manager_v1_send_relative_motion(
   2186 				relative_pointer_mgr, seat, (uint64_t)time * 1000,
   2187 				dx, dy, dx_unaccel, dy_unaccel);
   2188 
   2189 		wl_list_for_each(constraint, &pointer_constraints->constraints, link)
   2190 			cursorconstrain(constraint);
   2191 
   2192 		if (active_constraint && cursor_mode != CurResize && cursor_mode != CurMove) {
   2193 			toplevel_from_wlr_surface(active_constraint->surface, &c, NULL);
   2194 			if (c && active_constraint->surface == seat->pointer_state.focused_surface) {
   2195 				sx = cursor->x - c->geom.x - c->bw;
   2196 				sy = cursor->y - c->geom.y - c->bw;
   2197 				if (wlr_region_confine(&active_constraint->region, sx, sy,
   2198 						sx + dx, sy + dy, &sx_confined, &sy_confined)) {
   2199 					dx = sx_confined - sx;
   2200 					dy = sy_confined - sy;
   2201 				}
   2202 
   2203 				if (active_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED)
   2204 					return;
   2205 			}
   2206 		}
   2207 
   2208 		wlr_cursor_move(cursor, device, dx, dy);
   2209 		wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
   2210 
   2211 		/* Update selmon (even while dragging a window) */
   2212 		if (sloppyfocus)
   2213 			selmon = xytomon(cursor->x, cursor->y);
   2214 	}
   2215 
   2216 	/* Update drag icon's position */
   2217 	wlr_scene_node_set_position(&drag_icon->node, (int)round(cursor->x), (int)round(cursor->y));
   2218 
   2219 	/* If we are currently grabbing the mouse, handle and return */
   2220 	if (cursor_mode == CurMove) {
   2221 		/* Move the grabbed client to the new position. */
   2222 		resize(grabc, (struct wlr_box){.x = (int)round(cursor->x) - grabcx, .y = (int)round(cursor->y) - grabcy,
   2223 			.width = grabc->geom.width, .height = grabc->geom.height}, 1);
   2224 		return;
   2225 	} else if (cursor_mode == CurResize) {
   2226 		resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y,
   2227 			.width = (int)round(cursor->x) - grabc->geom.x, .height = (int)round(cursor->y) - grabc->geom.y}, 1);
   2228 		return;
   2229 	}
   2230 
   2231 	/* If there's no client surface under the cursor, set the cursor image to a
   2232 	 * default. This is what makes the cursor image appear when you move it
   2233 	 * off of a client or over its border. */
   2234 	if (!surface && !seat->drag)
   2235 		wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
   2236 
   2237 	pointerfocus(c, surface, sx, sy, time);
   2238 }
   2239 
   2240 void
   2241 motionrelative(struct wl_listener *listener, void *data)
   2242 {
   2243 	/* This event is forwarded by the cursor when a pointer emits a _relative_
   2244 	 * pointer motion event (i.e. a delta) */
   2245 	struct wlr_pointer_motion_event *event = data;
   2246 	/* The cursor doesn't move unless we tell it to. The cursor automatically
   2247 	 * handles constraining the motion to the output layout, as well as any
   2248 	 * special configuration applied for the specific input device which
   2249 	 * generated the event. You can pass NULL for the device if you want to move
   2250 	 * the cursor around without any input. */
   2251 	motionnotify(event->time_msec, &event->pointer->base, event->delta_x, event->delta_y,
   2252 			event->unaccel_dx, event->unaccel_dy);
   2253 }
   2254 
   2255 void
   2256 moveresize(const Arg *arg)
   2257 {
   2258 	if (cursor_mode != CurNormal && cursor_mode != CurPressed)
   2259 		return;
   2260 	xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
   2261 	if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen)
   2262 		return;
   2263 
   2264 	/* Float the window and tell motionnotify to grab it */
   2265 	setfloating(grabc, 1);
   2266 	switch (cursor_mode = arg->ui) {
   2267 	case CurMove:
   2268 		grabcx = (int)round(cursor->x) - grabc->geom.x;
   2269 		grabcy = (int)round(cursor->y) - grabc->geom.y;
   2270 		wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur");
   2271 		break;
   2272 	case CurResize:
   2273 		/* Doesn't work for X11 output - the next absolute motion event
   2274 		 * returns the cursor to where it started */
   2275 		wlr_cursor_warp_closest(cursor, NULL,
   2276 				grabc->geom.x + grabc->geom.width,
   2277 				grabc->geom.y + grabc->geom.height);
   2278 		wlr_cursor_set_xcursor(cursor, cursor_mgr, "se-resize");
   2279 		break;
   2280 	}
   2281 }
   2282 
   2283 void
   2284 outputmgrapply(struct wl_listener *listener, void *data)
   2285 {
   2286 	struct wlr_output_configuration_v1 *config = data;
   2287 	outputmgrapplyortest(config, 0);
   2288 }
   2289 
   2290 void
   2291 outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test)
   2292 {
   2293 	/*
   2294 	 * Called when a client such as wlr-randr requests a change in output
   2295 	 * configuration. This is only one way that the layout can be changed,
   2296 	 * so any Monitor information should be updated by updatemons() after an
   2297 	 * output_layout.change event, not here.
   2298 	 */
   2299 	struct wlr_output_configuration_head_v1 *config_head;
   2300 	int ok = 1;
   2301 
   2302 	wl_list_for_each(config_head, &config->heads, link) {
   2303 		struct wlr_output *wlr_output = config_head->state.output;
   2304 		Monitor *m = wlr_output->data;
   2305 		struct wlr_output_state state;
   2306 
   2307 		/* Ensure displays previously disabled by wlr-output-power-management-v1
   2308 		 * are properly handled*/
   2309 		m->asleep = 0;
   2310 
   2311 		wlr_output_state_init(&state);
   2312 		wlr_output_state_set_enabled(&state, config_head->state.enabled);
   2313 		if (!config_head->state.enabled)
   2314 			goto apply_or_test;
   2315 
   2316 		if (config_head->state.mode)
   2317 			wlr_output_state_set_mode(&state, config_head->state.mode);
   2318 		else
   2319 			wlr_output_state_set_custom_mode(&state,
   2320 					config_head->state.custom_mode.width,
   2321 					config_head->state.custom_mode.height,
   2322 					config_head->state.custom_mode.refresh);
   2323 
   2324 		wlr_output_state_set_transform(&state, config_head->state.transform);
   2325 		wlr_output_state_set_scale(&state, config_head->state.scale);
   2326 		wlr_output_state_set_adaptive_sync_enabled(&state,
   2327 				config_head->state.adaptive_sync_enabled);
   2328 
   2329 apply_or_test:
   2330 		ok &= test ? wlr_output_test_state(wlr_output, &state)
   2331 				: wlr_output_commit_state(wlr_output, &state);
   2332 
   2333 		/* Don't move monitors if position wouldn't change, this to avoid
   2334 		* wlroots marking the output as manually configured.
   2335 		* wlr_output_layout_add does not like disabled outputs */
   2336 		if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y))
   2337 			wlr_output_layout_add(output_layout, wlr_output,
   2338 					config_head->state.x, config_head->state.y);
   2339 
   2340 		wlr_output_state_finish(&state);
   2341 	}
   2342 
   2343 	if (ok)
   2344 		wlr_output_configuration_v1_send_succeeded(config);
   2345 	else
   2346 		wlr_output_configuration_v1_send_failed(config);
   2347 	wlr_output_configuration_v1_destroy(config);
   2348 
   2349 	/* https://codeberg.org/dwl/dwl/issues/577 */
   2350 	updatemons(NULL, NULL);
   2351 }
   2352 
   2353 void
   2354 outputmgrtest(struct wl_listener *listener, void *data)
   2355 {
   2356 	struct wlr_output_configuration_v1 *config = data;
   2357 	outputmgrapplyortest(config, 1);
   2358 }
   2359 
   2360 void
   2361 pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
   2362 		uint32_t time)
   2363 {
   2364 	struct timespec now;
   2365 
   2366 	if (surface != seat->pointer_state.focused_surface &&
   2367 			sloppyfocus && time && c && !client_is_unmanaged(c))
   2368 		focusclient(c, 0);
   2369 
   2370 	/* If surface is NULL, clear pointer focus */
   2371 	if (!surface) {
   2372 		wlr_seat_pointer_notify_clear_focus(seat);
   2373 		return;
   2374 	}
   2375 
   2376 	if (!time) {
   2377 		clock_gettime(CLOCK_MONOTONIC, &now);
   2378 		time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
   2379 	}
   2380 
   2381 	/* Let the client know that the mouse cursor has entered one
   2382 	 * of its surfaces, and make keyboard focus follow if desired.
   2383 	 * wlroots makes this a no-op if surface is already focused */
   2384 	wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
   2385 	wlr_seat_pointer_notify_motion(seat, time, sx, sy);
   2386 }
   2387 
   2388 
   2389 void
   2390 powermgrsetmode(struct wl_listener *listener, void *data)
   2391 {
   2392 	struct wlr_output_power_v1_set_mode_event *event = data;
   2393 	struct wlr_output_state state = {0};
   2394 	Monitor *m = event->output->data;
   2395 
   2396 	if (!m)
   2397 		return;
   2398 
   2399 	m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */
   2400 	wlr_output_state_set_enabled(&state, event->mode);
   2401 	wlr_output_commit_state(m->wlr_output, &state);
   2402 
   2403 	m->asleep = !event->mode;
   2404 }
   2405 
   2406 void
   2407 quit(const Arg *arg)
   2408 {
   2409 	wl_display_terminate(dpy);
   2410 }
   2411 
   2412 void
   2413 rendermon(struct wl_listener *listener, void *data)
   2414 {
   2415 	/* This function is called every time an output is ready to display a frame,
   2416 	 * generally at the output's refresh rate (e.g. 60Hz). */
   2417 	Monitor *m = wl_container_of(listener, m, frame);
   2418 	Client *c;
   2419 	struct wlr_output_state pending = {0};
   2420 	struct wlr_gamma_control_v1 *gamma_control;
   2421 	struct timespec now;
   2422 
   2423 	/* Render if no XDG clients have an outstanding resize and are visible on
   2424 	 * this monitor. */
   2425 	wl_list_for_each(c, &clients, link) {
   2426 		if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && !client_is_stopped(c))
   2427 			goto skip;
   2428 	}
   2429 
   2430 	/*
   2431 	 * HACK: The "correct" way to set the gamma is to commit it together with
   2432 	 * the rest of the state in one go, but to do that we would need to rewrite
   2433 	 * wlr_scene_output_commit() in order to add the gamma to the pending
   2434 	 * state before committing, instead try to commit the gamma in one frame,
   2435 	 * and commit the rest of the state in the next one (or in the same frame if
   2436 	 * the gamma can not be committed).
   2437 	 */
   2438 	if (m->gamma_lut_changed) {
   2439 		gamma_control
   2440 				= wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output);
   2441 		m->gamma_lut_changed = 0;
   2442 
   2443 		if (!wlr_gamma_control_v1_apply(gamma_control, &pending))
   2444 			goto commit;
   2445 
   2446 		if (!wlr_output_test_state(m->wlr_output, &pending)) {
   2447 			wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
   2448 			goto commit;
   2449 		}
   2450 		wlr_output_commit_state(m->wlr_output, &pending);
   2451 		wlr_output_schedule_frame(m->wlr_output);
   2452 	} else {
   2453 commit:
   2454 		wlr_scene_output_commit(m->scene_output, NULL);
   2455 	}
   2456 
   2457 skip:
   2458 	/* Let clients know a frame has been rendered */
   2459 	clock_gettime(CLOCK_MONOTONIC, &now);
   2460 	wlr_scene_output_send_frame_done(m->scene_output, &now);
   2461 	wlr_output_state_finish(&pending);
   2462 }
   2463 
   2464 void
   2465 requestdecorationmode(struct wl_listener *listener, void *data)
   2466 {
   2467 	Client *c = wl_container_of(listener, c, set_decoration_mode);
   2468 	if (c->surface.xdg->initialized)
   2469 		wlr_xdg_toplevel_decoration_v1_set_mode(c->decoration,
   2470 				WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
   2471 }
   2472 
   2473 void
   2474 requeststartdrag(struct wl_listener *listener, void *data)
   2475 {
   2476 	struct wlr_seat_request_start_drag_event *event = data;
   2477 
   2478 	if (wlr_seat_validate_pointer_grab_serial(seat, event->origin,
   2479 			event->serial))
   2480 		wlr_seat_start_pointer_drag(seat, event->drag, event->serial);
   2481 	else
   2482 		wlr_data_source_destroy(event->drag->source);
   2483 }
   2484 
   2485 void
   2486 requestmonstate(struct wl_listener *listener, void *data)
   2487 {
   2488 	struct wlr_output_event_request_state *event = data;
   2489 	wlr_output_commit_state(event->output, event->state);
   2490 	updatemons(NULL, NULL);
   2491 }
   2492 
   2493 void
   2494 resize(Client *c, struct wlr_box geo, int interact)
   2495 {
   2496 	struct wlr_box *bbox;
   2497 	struct wlr_box clip;
   2498 
   2499 	if (!c->mon || !client_surface(c)->mapped)
   2500 		return;
   2501 
   2502 	bbox = interact ? &sgeom : &c->mon->w;
   2503 
   2504 	client_set_bounds(c, geo.width, geo.height);
   2505 	c->geom = geo;
   2506 	applybounds(c, bbox);
   2507 
   2508 	/* Update scene-graph, including borders */
   2509 	wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
   2510 	wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
   2511 	wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
   2512 	wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw);
   2513 	wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw);
   2514 	wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw);
   2515 	wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
   2516 	wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
   2517 	wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
   2518 
   2519 	/* this is a no-op if size hasn't changed */
   2520 	c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
   2521 			c->geom.height - 2 * c->bw);
   2522 	client_get_clip(c, &clip);
   2523 	wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
   2524 }
   2525 
   2526 void
   2527 run(char *startup_cmd)
   2528 {
   2529 	/* Add a Unix socket to the Wayland display. */
   2530 	const char *socket = wl_display_add_socket_auto(dpy);
   2531 	if (!socket)
   2532 		die("startup: display_add_socket_auto");
   2533 	setenv("WAYLAND_DISPLAY", socket, 1);
   2534 
   2535 	/* Start the backend. This will enumerate outputs and inputs, become the DRM
   2536 	 * master, etc */
   2537 	if (!wlr_backend_start(backend))
   2538 		die("startup: backend_start");
   2539 
   2540 	/* Now that the socket exists and the backend is started, run the startup command */
   2541 	if (startup_cmd) {
   2542 		if ((child_pid = fork()) < 0)
   2543 			die("startup: fork:");
   2544 		if (child_pid == 0) {
   2545 			close(STDIN_FILENO);
   2546 			setsid();
   2547 			execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
   2548 			die("startup: execl:");
   2549 		}
   2550 	}
   2551 
   2552 	drawbars();
   2553 
   2554 	/* At this point the outputs are initialized, choose initial selmon based on
   2555 	 * cursor position, and set default cursor image */
   2556 	selmon = xytomon(cursor->x, cursor->y);
   2557 
   2558 	/* TODO hack to get cursor to display in its initial location (100, 100)
   2559 	 * instead of (0, 0) and then jumping. still may not be fully
   2560 	 * initialized, as the image/coordinates are not transformed for the
   2561 	 * monitor when displayed here */
   2562 	wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
   2563 	wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
   2564 
   2565 	/* Run the Wayland event loop. This does not return until you exit the
   2566 	 * compositor. Starting the backend rigged up all of the necessary event
   2567 	 * loop configuration to listen to libinput events, DRM events, generate
   2568 	 * frame events at the refresh rate, and so on. */
   2569 	wl_display_run(dpy);
   2570 }
   2571 
   2572 void
   2573 setcursor(struct wl_listener *listener, void *data)
   2574 {
   2575 	/* This event is raised by the seat when a client provides a cursor image */
   2576 	struct wlr_seat_pointer_request_set_cursor_event *event = data;
   2577 	/* If we're "grabbing" the cursor, don't use the client's image, we will
   2578 	 * restore it after "grabbing" sending a leave event, followed by a enter
   2579 	 * event, which will result in the client requesting set the cursor surface */
   2580 	if (cursor_mode != CurNormal && cursor_mode != CurPressed)
   2581 		return;
   2582 	/* This can be sent by any client, so we check to make sure this one is
   2583 	 * actually has pointer focus first. If so, we can tell the cursor to
   2584 	 * use the provided surface as the cursor image. It will set the
   2585 	 * hardware cursor on the output that it's currently on and continue to
   2586 	 * do so as the cursor moves between outputs. */
   2587 	if (event->seat_client == seat->pointer_state.focused_client)
   2588 		wlr_cursor_set_surface(cursor, event->surface,
   2589 				event->hotspot_x, event->hotspot_y);
   2590 }
   2591 
   2592 void
   2593 setcursorshape(struct wl_listener *listener, void *data)
   2594 {
   2595 	struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
   2596 	if (cursor_mode != CurNormal && cursor_mode != CurPressed)
   2597 		return;
   2598 	/* This can be sent by any client, so we check to make sure this one is
   2599 	 * actually has pointer focus first. If so, we can tell the cursor to
   2600 	 * use the provided cursor shape. */
   2601 	if (event->seat_client == seat->pointer_state.focused_client)
   2602 		wlr_cursor_set_xcursor(cursor, cursor_mgr,
   2603 				wlr_cursor_shape_v1_name(event->shape));
   2604 }
   2605 
   2606 void
   2607 setfloating(Client *c, int floating)
   2608 {
   2609 	Client *p = client_get_parent(c);
   2610 	c->isfloating = floating;
   2611 	/* If in floating layout do not change the client's layer */
   2612 	if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
   2613 		return;
   2614 	wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
   2615 			(p && p->isfullscreen) ? LyrFS
   2616 			: c->isfloating ? LyrFloat : LyrTile]);
   2617 	arrange(c->mon);
   2618 	drawbars();
   2619 }
   2620 
   2621 void
   2622 setfullscreen(Client *c, int fullscreen)
   2623 {
   2624 	c->isfullscreen = fullscreen;
   2625 	if (!c->mon || !client_surface(c)->mapped)
   2626 		return;
   2627 	c->bw = fullscreen ? 0 : borderpx;
   2628 	client_set_fullscreen(c, fullscreen);
   2629 	wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
   2630 			? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
   2631 
   2632 	if (fullscreen) {
   2633 		c->prev = c->geom;
   2634 		resize(c, c->mon->m, 0);
   2635 	} else {
   2636 		/* restore previous size instead of arrange for floating windows since
   2637 		 * client positions are set by the user and cannot be recalculated */
   2638 		resize(c, c->prev, 0);
   2639 	}
   2640 	arrange(c->mon);
   2641 	drawbars();
   2642 }
   2643 
   2644 void
   2645 setgamma(struct wl_listener *listener, void *data)
   2646 {
   2647 	struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
   2648 	Monitor *m = event->output->data;
   2649 	if (!m)
   2650 		return;
   2651 	m->gamma_lut_changed = 1;
   2652 	wlr_output_schedule_frame(m->wlr_output);
   2653 }
   2654 
   2655 void
   2656 setgaps(int oh, int ov, int ih, int iv)
   2657 {
   2658 	selmon->gappoh = MAX(oh, 0);
   2659 	selmon->gappov = MAX(ov, 0);
   2660 	selmon->gappih = MAX(ih, 0);
   2661 	selmon->gappiv = MAX(iv, 0);
   2662 	arrange(selmon);
   2663 }
   2664 
   2665 void
   2666 setlayout(const Arg *arg)
   2667 {
   2668 	if (!selmon)
   2669 		return;
   2670 	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
   2671 		selmon->sellt ^= 1;
   2672 	if (arg && arg->v)
   2673 		selmon->lt[selmon->sellt] = (Layout *)arg->v;
   2674 	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
   2675 	arrange(selmon);
   2676 	drawbar(selmon);
   2677 }
   2678 
   2679 /* arg > 1.0 will set mfact absolutely */
   2680 void
   2681 setmfact(const Arg *arg)
   2682 {
   2683 	float f;
   2684 
   2685 	if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange)
   2686 		return;
   2687 	f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f;
   2688 	if (f < 0.1 || f > 0.9)
   2689 		return;
   2690 	selmon->mfact = f;
   2691 	arrange(selmon);
   2692 }
   2693 
   2694 void
   2695 setmon(Client *c, Monitor *m, uint32_t newtags)
   2696 {
   2697 	Monitor *oldmon = c->mon;
   2698 
   2699 	if (oldmon == m)
   2700 		return;
   2701 	c->mon = m;
   2702 	c->prev = c->geom;
   2703 
   2704 	/* Scene graph sends surface leave/enter events on move and resize */
   2705 	if (oldmon)
   2706 		arrange(oldmon);
   2707 	if (m) {
   2708 		/* Make sure window actually overlaps with the monitor */
   2709 		resize(c, c->geom, 0);
   2710 		c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
   2711 		setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
   2712 		setfloating(c, c->isfloating);
   2713 	}
   2714 	focusclient(focustop(selmon), 1);
   2715 }
   2716 
   2717 void
   2718 setpsel(struct wl_listener *listener, void *data)
   2719 {
   2720 	/* This event is raised by the seat when a client wants to set the selection,
   2721 	 * usually when the user copies something. wlroots allows compositors to
   2722 	 * ignore such requests if they so choose, but in dwl we always honor
   2723 	 */
   2724 	struct wlr_seat_request_set_primary_selection_event *event = data;
   2725 	wlr_seat_set_primary_selection(seat, event->source, event->serial);
   2726 }
   2727 
   2728 void
   2729 setsel(struct wl_listener *listener, void *data)
   2730 {
   2731 	/* This event is raised by the seat when a client wants to set the selection,
   2732 	 * usually when the user copies something. wlroots allows compositors to
   2733 	 * ignore such requests if they so choose, but in dwl we always honor
   2734 	 */
   2735 	struct wlr_seat_request_set_selection_event *event = data;
   2736 	wlr_seat_set_selection(seat, event->source, event->serial);
   2737 }
   2738 
   2739 void
   2740 setup(void)
   2741 {
   2742 	int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
   2743 	struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
   2744 	sigemptyset(&sa.sa_mask);
   2745 
   2746 	for (i = 0; i < (int)LENGTH(sig); i++)
   2747 		sigaction(sig[i], &sa, NULL);
   2748 
   2749 
   2750 	wlr_log_init(log_level, NULL);
   2751 
   2752 	/* The Wayland display is managed by libwayland. It handles accepting
   2753 	 * clients from the Unix socket, manging Wayland globals, and so on. */
   2754 	dpy = wl_display_create();
   2755 	event_loop = wl_display_get_event_loop(dpy);
   2756 
   2757 	/* The backend is a wlroots feature which abstracts the underlying input and
   2758 	 * output hardware. The autocreate option will choose the most suitable
   2759 	 * backend based on the current environment, such as opening an X11 window
   2760 	 * if an X11 server is running. */
   2761 	if (!(backend = wlr_backend_autocreate(event_loop, &session)))
   2762 		die("couldn't create backend");
   2763 
   2764 	/* Initialize the scene graph used to lay out windows */
   2765 	scene = wlr_scene_create();
   2766 	root_bg = wlr_scene_rect_create(&scene->tree, 0, 0, rootcolor);
   2767 	for (i = 0; i < NUM_LAYERS; i++)
   2768 		layers[i] = wlr_scene_tree_create(&scene->tree);
   2769 	drag_icon = wlr_scene_tree_create(&scene->tree);
   2770 	wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node);
   2771 
   2772 	/* Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The user
   2773 	 * can also specify a renderer using the WLR_RENDERER env var.
   2774 	 * The renderer is responsible for defining the various pixel formats it
   2775 	 * supports for shared memory, this configures that for clients. */
   2776 	if (!(drw = wlr_renderer_autocreate(backend)))
   2777 		die("couldn't create renderer");
   2778 	LISTEN_STATIC(&drw->events.lost, gpureset);
   2779 
   2780 	/* Create shm, drm and linux_dmabuf interfaces by ourselves.
   2781 	 * The simplest way is call:
   2782 	 *      wlr_renderer_init_wl_display(drw);
   2783 	 * but we need to create manually the linux_dmabuf interface to integrate it
   2784 	 * with wlr_scene. */
   2785 	wlr_renderer_init_wl_shm(drw, dpy);
   2786 
   2787 	if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) {
   2788 		wlr_drm_create(dpy, drw);
   2789 		wlr_scene_set_linux_dmabuf_v1(scene,
   2790 				wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw));
   2791 	}
   2792 
   2793 	/* Autocreates an allocator for us.
   2794 	 * The allocator is the bridge between the renderer and the backend. It
   2795 	 * handles the buffer creation, allowing wlroots to render onto the
   2796 	 * screen */
   2797 	if (!(alloc = wlr_allocator_autocreate(backend, drw)))
   2798 		die("couldn't create allocator");
   2799 
   2800 	/* This creates some hands-off wlroots interfaces. The compositor is
   2801 	 * necessary for clients to allocate surfaces and the data device manager
   2802 	 * handles the clipboard. Each of these wlroots interfaces has room for you
   2803 	 * to dig your fingers in and play with their behavior if you want. Note that
   2804 	 * the clients cannot set the selection directly without compositor approval,
   2805 	 * see the setsel() function. */
   2806 	compositor = wlr_compositor_create(dpy, 6, drw);
   2807 	wlr_subcompositor_create(dpy);
   2808 	wlr_data_device_manager_create(dpy);
   2809 	wlr_export_dmabuf_manager_v1_create(dpy);
   2810 	wlr_screencopy_manager_v1_create(dpy);
   2811 	wlr_data_control_manager_v1_create(dpy);
   2812 	wlr_primary_selection_v1_device_manager_create(dpy);
   2813 	wlr_viewporter_create(dpy);
   2814 	wlr_single_pixel_buffer_manager_v1_create(dpy);
   2815 	wlr_fractional_scale_manager_v1_create(dpy, 1);
   2816 	wlr_presentation_create(dpy, backend);
   2817 	wlr_alpha_modifier_v1_create(dpy);
   2818 
   2819 	/* Initializes the interface used to implement urgency hints */
   2820 	activation = wlr_xdg_activation_v1_create(dpy);
   2821 	LISTEN_STATIC(&activation->events.request_activate, urgent);
   2822 
   2823 	gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy);
   2824 	LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma);
   2825 
   2826 	power_mgr = wlr_output_power_manager_v1_create(dpy);
   2827 	LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode);
   2828 
   2829 	/* Creates an output layout, which a wlroots utility for working with an
   2830 	 * arrangement of screens in a physical layout. */
   2831 	output_layout = wlr_output_layout_create(dpy);
   2832 	LISTEN_STATIC(&output_layout->events.change, updatemons);
   2833 	wlr_xdg_output_manager_v1_create(dpy, output_layout);
   2834 
   2835 	/* Configure a listener to be notified when new outputs are available on the
   2836 	 * backend. */
   2837 	wl_list_init(&mons);
   2838 	LISTEN_STATIC(&backend->events.new_output, createmon);
   2839 
   2840 	/* Set up our client lists, the xdg-shell and the layer-shell. The xdg-shell is a
   2841 	 * Wayland protocol which is used for application windows. For more
   2842 	 * detail on shells, refer to the article:
   2843 	 *
   2844 	 * https://drewdevault.com/2018/07/29/Wayland-shells.html
   2845 	 */
   2846 	wl_list_init(&clients);
   2847 	wl_list_init(&fstack);
   2848 
   2849 	xdg_shell = wlr_xdg_shell_create(dpy, 6);
   2850 	LISTEN_STATIC(&xdg_shell->events.new_toplevel, createnotify);
   2851 	LISTEN_STATIC(&xdg_shell->events.new_popup, createpopup);
   2852 
   2853 	layer_shell = wlr_layer_shell_v1_create(dpy, 3);
   2854 	LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface);
   2855 
   2856 	idle_notifier = wlr_idle_notifier_v1_create(dpy);
   2857 
   2858 	idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy);
   2859 	LISTEN_STATIC(&idle_inhibit_mgr->events.new_inhibitor, createidleinhibitor);
   2860 
   2861 	session_lock_mgr = wlr_session_lock_manager_v1_create(dpy);
   2862 	wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener);
   2863 	LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr);
   2864 	locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height,
   2865 			(float [4]){0.1f, 0.1f, 0.1f, 1.0f});
   2866 	wlr_scene_node_set_enabled(&locked_bg->node, 0);
   2867 
   2868 	/* Use decoration protocols to negotiate server-side decorations */
   2869 	wlr_server_decoration_manager_set_default_mode(
   2870 			wlr_server_decoration_manager_create(dpy),
   2871 			WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
   2872 	xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy);
   2873 	LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, createdecoration);
   2874 
   2875 	pointer_constraints = wlr_pointer_constraints_v1_create(dpy);
   2876 	LISTEN_STATIC(&pointer_constraints->events.new_constraint, createpointerconstraint);
   2877 
   2878 	relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy);
   2879 
   2880 	/*
   2881 	 * Creates a cursor, which is a wlroots utility for tracking the cursor
   2882 	 * image shown on screen.
   2883 	 */
   2884 	cursor = wlr_cursor_create();
   2885 	wlr_cursor_attach_output_layout(cursor, output_layout);
   2886 
   2887 	/* Creates an xcursor manager, another wlroots utility which loads up
   2888 	 * Xcursor themes to source cursor images from and makes sure that cursor
   2889 	 * images are available at all scale factors on the screen (necessary for
   2890 	 * HiDPI support). Scaled cursors will be loaded with each output. */
   2891 	cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
   2892 	setenv("XCURSOR_SIZE", "24", 1);
   2893 
   2894 	/*
   2895 	 * wlr_cursor *only* displays an image on screen. It does not move around
   2896 	 * when the pointer moves. However, we can attach input devices to it, and
   2897 	 * it will generate aggregate events for all of them. In these events, we
   2898 	 * can choose how we want to process them, forwarding them to clients and
   2899 	 * moving the cursor around. More detail on this process is described in
   2900 	 * https://drewdevault.com/2018/07/17/Input-handling-in-wlroots.html
   2901 	 *
   2902 	 * And more comments are sprinkled throughout the notify functions above.
   2903 	 */
   2904 	LISTEN_STATIC(&cursor->events.motion, motionrelative);
   2905 	LISTEN_STATIC(&cursor->events.motion_absolute, motionabsolute);
   2906 	LISTEN_STATIC(&cursor->events.button, buttonpress);
   2907 	LISTEN_STATIC(&cursor->events.axis, axisnotify);
   2908 	LISTEN_STATIC(&cursor->events.frame, cursorframe);
   2909 
   2910 	cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
   2911 	LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
   2912 
   2913 	/*
   2914 	 * Configures a seat, which is a single "seat" at which a user sits and
   2915 	 * operates the computer. This conceptually includes up to one keyboard,
   2916 	 * pointer, touch, and drawing tablet device. We also rig up a listener to
   2917 	 * let us know when new input devices are available on the backend.
   2918 	 */
   2919 	LISTEN_STATIC(&backend->events.new_input, inputdevice);
   2920 	virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy);
   2921 	LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard);
   2922 	virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy);
   2923 	LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, virtualpointer);
   2924 
   2925 	seat = wlr_seat_create(dpy, "seat0");
   2926 	LISTEN_STATIC(&seat->events.request_set_cursor, setcursor);
   2927 	LISTEN_STATIC(&seat->events.request_set_selection, setsel);
   2928 	LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel);
   2929 	LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag);
   2930 	LISTEN_STATIC(&seat->events.start_drag, startdrag);
   2931 
   2932 	kb_group = createkeyboardgroup();
   2933 	wl_list_init(&kb_group->destroy.link);
   2934 
   2935 	output_mgr = wlr_output_manager_v1_create(dpy);
   2936 	LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply);
   2937 	LISTEN_STATIC(&output_mgr->events.test, outputmgrtest);
   2938 
   2939 	drwl_init();
   2940 
   2941 	status_event_source = wl_event_loop_add_fd(wl_display_get_event_loop(dpy),
   2942 		STDIN_FILENO, WL_EVENT_READABLE, statusin, NULL);
   2943 
   2944 	/* Make sure XWayland clients don't connect to the parent X server,
   2945 	 * e.g when running in the x11 backend or the wayland backend and the
   2946 	 * compositor has Xwayland support */
   2947 	unsetenv("DISPLAY");
   2948 #ifdef XWAYLAND
   2949 	/*
   2950 	 * Initialise the XWayland X server.
   2951 	 * It will be started when the first X client is started.
   2952 	 */
   2953 	if ((xwayland = wlr_xwayland_create(dpy, compositor, 1))) {
   2954 		LISTEN_STATIC(&xwayland->events.ready, xwaylandready);
   2955 		LISTEN_STATIC(&xwayland->events.new_surface, createnotifyx11);
   2956 
   2957 		setenv("DISPLAY", xwayland->display_name, 1);
   2958 	} else {
   2959 		fprintf(stderr, "failed to setup XWayland X server, continuing without it\n");
   2960 	}
   2961 #endif
   2962 }
   2963 
   2964 void
   2965 spawn(const Arg *arg)
   2966 {
   2967 	if (fork() == 0) {
   2968 		close(STDIN_FILENO);
   2969 		dup2(STDERR_FILENO, STDOUT_FILENO);
   2970 		setsid();
   2971 		execvp(((char **)arg->v)[0], (char **)arg->v);
   2972 		die("dwl: execvp %s failed:", ((char **)arg->v)[0]);
   2973 	}
   2974 }
   2975 
   2976 void
   2977 startdrag(struct wl_listener *listener, void *data)
   2978 {
   2979 	struct wlr_drag *drag = data;
   2980 	if (!drag->icon)
   2981 		return;
   2982 
   2983 	drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node;
   2984 	LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon);
   2985 }
   2986 
   2987 int
   2988 statusin(int fd, unsigned int mask, void *data)
   2989 {
   2990 	char status[1024];
   2991 	ssize_t n;
   2992 
   2993 	if (mask & WL_EVENT_ERROR)
   2994 		die("status in event error");
   2995 	if (mask & WL_EVENT_HANGUP)
   2996 		wl_event_source_remove(status_event_source);
   2997 
   2998 	n = read(fd, status, sizeof(status) - 1);
   2999 	if (n < 0 && errno != EWOULDBLOCK)
   3000 		die("read:");
   3001 
   3002 	status[n] = '\0';
   3003 	status[strcspn(status, "\n")] = '\0';
   3004 
   3005 	strncpy(stext, status, sizeof(stext));
   3006 	drawbars();
   3007 
   3008 	return 0;
   3009 }
   3010 
   3011 void
   3012 tag(const Arg *arg)
   3013 {
   3014 	Client *sel = focustop(selmon);
   3015 	if (!sel || (arg->ui & TAGMASK) == 0)
   3016 		return;
   3017 
   3018 	sel->tags = arg->ui & TAGMASK;
   3019 	focusclient(focustop(selmon), 1);
   3020 	arrange(selmon);
   3021 	drawbars();
   3022 }
   3023 
   3024 void
   3025 tagmon(const Arg *arg)
   3026 {
   3027 	Client *sel = focustop(selmon);
   3028 	if (sel)
   3029 		setmon(sel, dirtomon(arg->i), 0);
   3030 }
   3031 
   3032 void
   3033 tile(Monitor *m)
   3034 {
   3035 	unsigned int mw, my, ty, h, r, oe = enablegaps, ie = enablegaps;
   3036 	int i, n = 0;
   3037 	Client *c;
   3038 
   3039 	wl_list_for_each(c, &clients, link)
   3040 		if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
   3041 			n++;
   3042 	if (n == 0)
   3043 		return;
   3044 
   3045 	if (smartgaps == n) {
   3046 		oe = 0; // outer gaps disabled
   3047 	}
   3048 
   3049 	if (n > m->nmaster)
   3050 		mw = m->nmaster ? (int)roundf((m->w.width + m->gappiv*ie) * m->mfact) : 0;
   3051 	else
   3052 		mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie;
   3053 	i = 0;
   3054 	my = ty = m->gappoh*oe;
   3055 	wl_list_for_each(c, &clients, link) {
   3056 		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
   3057 			continue;
   3058 		if (i < m->nmaster) {
   3059 			r = MIN(n, m->nmaster) - i;
   3060 			h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
   3061 			resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my,
   3062 				.width = mw - m->gappiv*ie, .height = h}, 0);
   3063 			my += c->geom.height + m->gappih*ie;
   3064 		} else {
   3065 			r = n - i;
   3066 			h = (m->w.height - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
   3067 			resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + ty,
   3068 				.width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0);
   3069 			ty += c->geom.height + m->gappih*ie;
   3070 		}
   3071 		i++;
   3072 	}
   3073 }
   3074 
   3075 void
   3076 togglebar(const Arg *arg)
   3077 {
   3078 	wlr_scene_node_set_enabled(&selmon->scene_buffer->node,
   3079 		!selmon->scene_buffer->node.enabled);
   3080 	arrangelayers(selmon);
   3081 }
   3082 
   3083 void
   3084 togglefloating(const Arg *arg)
   3085 {
   3086 	Client *sel = focustop(selmon);
   3087 	/* return if fullscreen */
   3088 	if (sel && !sel->isfullscreen)
   3089 		setfloating(sel, !sel->isfloating);
   3090 }
   3091 
   3092 void
   3093 togglefullscreen(const Arg *arg)
   3094 {
   3095 	Client *sel = focustop(selmon);
   3096 	if (sel)
   3097 		setfullscreen(sel, !sel->isfullscreen);
   3098 }
   3099 
   3100 void
   3101 togglegaps(const Arg *arg)
   3102 {
   3103 	enablegaps = !enablegaps;
   3104 	arrange(selmon);
   3105 }
   3106 
   3107 void
   3108 toggletag(const Arg *arg)
   3109 {
   3110 	uint32_t newtags;
   3111 	Client *sel = focustop(selmon);
   3112 	if (!sel || !(newtags = sel->tags ^ (arg->ui & TAGMASK)))
   3113 		return;
   3114 
   3115 	sel->tags = newtags;
   3116 	focusclient(focustop(selmon), 1);
   3117 	arrange(selmon);
   3118 	drawbars();
   3119 }
   3120 
   3121 void
   3122 toggleview(const Arg *arg)
   3123 {
   3124 	uint32_t newtagset;
   3125 	if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0))
   3126 		return;
   3127 
   3128 	selmon->tagset[selmon->seltags] = newtagset;
   3129 	focusclient(focustop(selmon), 1);
   3130 	arrange(selmon);
   3131 	drawbars();
   3132 }
   3133 
   3134 void
   3135 unlocksession(struct wl_listener *listener, void *data)
   3136 {
   3137 	SessionLock *lock = wl_container_of(listener, lock, unlock);
   3138 	destroylock(lock, 1);
   3139 }
   3140 
   3141 void
   3142 unmaplayersurfacenotify(struct wl_listener *listener, void *data)
   3143 {
   3144 	LayerSurface *l = wl_container_of(listener, l, unmap);
   3145 
   3146 	l->mapped = 0;
   3147 	wlr_scene_node_set_enabled(&l->scene->node, 0);
   3148 	if (l == exclusive_focus)
   3149 		exclusive_focus = NULL;
   3150 	if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
   3151 		arrangelayers(l->mon);
   3152 	if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
   3153 		focusclient(focustop(selmon), 1);
   3154 	motionnotify(0, NULL, 0, 0, 0, 0);
   3155 }
   3156 
   3157 void
   3158 unmapnotify(struct wl_listener *listener, void *data)
   3159 {
   3160 	/* Called when the surface is unmapped, and should no longer be shown. */
   3161 	Client *c = wl_container_of(listener, c, unmap);
   3162 	if (c == grabc) {
   3163 		cursor_mode = CurNormal;
   3164 		grabc = NULL;
   3165 	}
   3166 
   3167 	if (client_is_unmanaged(c)) {
   3168 		if (c == exclusive_focus) {
   3169 			exclusive_focus = NULL;
   3170 			focusclient(focustop(selmon), 1);
   3171 		}
   3172 	} else {
   3173 		wl_list_remove(&c->link);
   3174 		setmon(c, NULL, 0);
   3175 		wl_list_remove(&c->flink);
   3176 	}
   3177 
   3178 	wlr_scene_node_destroy(&c->scene->node);
   3179 	drawbars();
   3180 	motionnotify(0, NULL, 0, 0, 0, 0);
   3181 }
   3182 
   3183 void
   3184 updatemons(struct wl_listener *listener, void *data)
   3185 {
   3186 	/*
   3187 	 * Called whenever the output layout changes: adding or removing a
   3188 	 * monitor, changing an output's mode or position, etc. This is where
   3189 	 * the change officially happens and we update geometry, window
   3190 	 * positions, focus, and the stored configuration in wlroots'
   3191 	 * output-manager implementation.
   3192 	 */
   3193 	struct wlr_output_configuration_v1 *config
   3194 			= wlr_output_configuration_v1_create();
   3195 	Client *c;
   3196 	struct wlr_output_configuration_head_v1 *config_head;
   3197 	Monitor *m;
   3198 
   3199 	/* First remove from the layout the disabled monitors */
   3200 	wl_list_for_each(m, &mons, link) {
   3201 		if (m->wlr_output->enabled || m->asleep)
   3202 			continue;
   3203 		config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output);
   3204 		config_head->state.enabled = 0;
   3205 		/* Remove this output from the layout to avoid cursor enter inside it */
   3206 		wlr_output_layout_remove(output_layout, m->wlr_output);
   3207 		closemon(m);
   3208 		m->m = m->w = (struct wlr_box){0};
   3209 	}
   3210 	/* Insert outputs that need to */
   3211 	wl_list_for_each(m, &mons, link) {
   3212 		if (m->wlr_output->enabled
   3213 				&& !wlr_output_layout_get(output_layout, m->wlr_output))
   3214 			wlr_output_layout_add_auto(output_layout, m->wlr_output);
   3215 	}
   3216 
   3217 	/* Now that we update the output layout we can get its box */
   3218 	wlr_output_layout_get_box(output_layout, NULL, &sgeom);
   3219 
   3220 	wlr_scene_node_set_position(&root_bg->node, sgeom.x, sgeom.y);
   3221 	wlr_scene_rect_set_size(root_bg, sgeom.width, sgeom.height);
   3222 
   3223 	/* Make sure the clients are hidden when dwl is locked */
   3224 	wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y);
   3225 	wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height);
   3226 
   3227 	wl_list_for_each(m, &mons, link) {
   3228 		if (!m->wlr_output->enabled)
   3229 			continue;
   3230 		config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output);
   3231 
   3232 		/* Get the effective monitor geometry to use for surfaces */
   3233 		wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m);
   3234 		m->w = m->m;
   3235 		wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y);
   3236 
   3237 		wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
   3238 		wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
   3239 
   3240 		if (m->lock_surface) {
   3241 			struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data;
   3242 			wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);
   3243 			wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width, m->m.height);
   3244 		}
   3245 
   3246 		/* Calculate the effective monitor geometry to use for clients */
   3247 		arrangelayers(m);
   3248 		/* Don't move clients to the left output when plugging monitors */
   3249 		arrange(m);
   3250 		/* make sure fullscreen clients have the right size */
   3251 		if ((c = focustop(m)) && c->isfullscreen)
   3252 			resize(c, m->m, 0);
   3253 
   3254 		/* Try to re-set the gamma LUT when updating monitors,
   3255 		 * it's only really needed when enabling a disabled output, but meh. */
   3256 		m->gamma_lut_changed = 1;
   3257 
   3258 		config_head->state.x = m->m.x;
   3259 		config_head->state.y = m->m.y;
   3260 
   3261 		if (!selmon) {
   3262 			selmon = m;
   3263 		}
   3264 	}
   3265 
   3266 	if (selmon && selmon->wlr_output->enabled) {
   3267 		wl_list_for_each(c, &clients, link) {
   3268 			if (!c->mon && client_surface(c)->mapped)
   3269 				setmon(c, selmon, c->tags);
   3270 		}
   3271 		focusclient(focustop(selmon), 1);
   3272 		if (selmon->lock_surface) {
   3273 			client_notify_enter(selmon->lock_surface->surface,
   3274 					wlr_seat_get_keyboard(seat));
   3275 			client_activate_surface(selmon->lock_surface->surface, 1);
   3276 		}
   3277 	}
   3278 
   3279 	if (stext[0] == '\0')
   3280 		strncpy(stext, "dwl-"VERSION, sizeof(stext));
   3281 	wl_list_for_each(m, &mons, link) {
   3282 		updatebar(m);
   3283 		drawbar(m);
   3284 	}
   3285 
   3286 	/* FIXME: figure out why the cursor image is at 0,0 after turning all
   3287 	 * the monitors on.
   3288 	 * Move the cursor image where it used to be. It does not generate a
   3289 	 * wl_pointer.motion event for the clients, it's only the image what it's
   3290 	 * at the wrong position after all. */
   3291 	wlr_cursor_move(cursor, NULL, 0, 0);
   3292 
   3293 	wlr_output_manager_v1_set_configuration(output_mgr, config);
   3294 }
   3295 
   3296 void
   3297 updatebar(Monitor *m)
   3298 {
   3299 	size_t i;
   3300 	int rw, rh;
   3301 	char fontattrs[12];
   3302 
   3303 	wlr_output_transformed_resolution(m->wlr_output, &rw, &rh);
   3304 	m->b.width = rw;
   3305 	m->b.real_width = (int)((float)m->b.width / m->wlr_output->scale);
   3306 
   3307 	wlr_scene_node_set_enabled(&m->scene_buffer->node, m->wlr_output->enabled ? showbar : 0);
   3308 
   3309 	for (i = 0; i < LENGTH(m->pool); i++)
   3310 		if (m->pool[i]) {
   3311 			wlr_buffer_drop(&m->pool[i]->base);
   3312 			m->pool[i] = NULL;
   3313 		}
   3314 
   3315 	if (m->b.scale == m->wlr_output->scale && m->drw)
   3316 		return;
   3317 
   3318 	drwl_font_destroy(m->drw->font);
   3319 	snprintf(fontattrs, sizeof(fontattrs), "dpi=%.2f", 96. * m->wlr_output->scale);
   3320 	if (!(drwl_font_create(m->drw, LENGTH(fonts), fonts, fontattrs)))
   3321 		die("Could not load font");
   3322 
   3323 	m->b.scale = m->wlr_output->scale;
   3324 	m->lrpad = m->drw->font->height;
   3325 	m->b.height = m->drw->font->height + 2;
   3326 	m->b.real_height = (int)((float)m->b.height / m->wlr_output->scale);
   3327 }
   3328 
   3329 void
   3330 updatetitle(struct wl_listener *listener, void *data)
   3331 {
   3332 	Client *c = wl_container_of(listener, c, set_title);
   3333 	if (c == focustop(c->mon))
   3334 		drawbars();
   3335 }
   3336 
   3337 void
   3338 urgent(struct wl_listener *listener, void *data)
   3339 {
   3340 	struct wlr_xdg_activation_v1_request_activate_event *event = data;
   3341 	Client *c = NULL;
   3342 	toplevel_from_wlr_surface(event->surface, &c, NULL);
   3343 	if (!c || c == focustop(selmon))
   3344 		return;
   3345 
   3346 	c->isurgent = 1;
   3347 	drawbars();
   3348 
   3349 	if (client_surface(c)->mapped)
   3350 		client_set_border_color(c, (float[])COLOR(colors[SchemeUrg][ColBorder]));
   3351 }
   3352 
   3353 void
   3354 view(const Arg *arg)
   3355 {
   3356 	if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
   3357 		return;
   3358 	selmon->seltags ^= 1; /* toggle sel tagset */
   3359 	if (arg->ui & TAGMASK)
   3360 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
   3361 	focusclient(focustop(selmon), 1);
   3362 	arrange(selmon);
   3363 	drawbars();
   3364 }
   3365 
   3366 void
   3367 virtualkeyboard(struct wl_listener *listener, void *data)
   3368 {
   3369 	struct wlr_virtual_keyboard_v1 *kb = data;
   3370 	/* virtual keyboards shouldn't share keyboard group */
   3371 	KeyboardGroup *group = createkeyboardgroup();
   3372 	/* Set the keymap to match the group keymap */
   3373 	wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
   3374 	LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, destroykeyboardgroup);
   3375 
   3376 	/* Add the new keyboard to the group */
   3377 	wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard);
   3378 }
   3379 
   3380 void
   3381 virtualpointer(struct wl_listener *listener, void *data)
   3382 {
   3383 	struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
   3384 	struct wlr_input_device *device = &event->new_pointer->pointer.base;
   3385 
   3386 	wlr_cursor_attach_input_device(cursor, device);
   3387 	if (event->suggested_output)
   3388 		wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
   3389 }
   3390 
   3391 Monitor *
   3392 xytomon(double x, double y)
   3393 {
   3394 	struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
   3395 	return o ? o->data : NULL;
   3396 }
   3397 
   3398 void
   3399 xytonode(double x, double y, struct wlr_surface **psurface,
   3400 		Client **pc, LayerSurface **pl, double *nx, double *ny)
   3401 {
   3402 	struct wlr_scene_node *node, *pnode;
   3403 	struct wlr_surface *surface = NULL;
   3404 	struct wlr_scene_surface *scene_surface = NULL;
   3405 	Client *c = NULL;
   3406 	LayerSurface *l = NULL;
   3407 	int layer;
   3408 
   3409 	for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
   3410 		if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny)))
   3411 			continue;
   3412 
   3413 		if (node->type == WLR_SCENE_NODE_BUFFER) {
   3414 			scene_surface = wlr_scene_surface_try_from_buffer(
   3415 					wlr_scene_buffer_from_node(node));
   3416 			if (!scene_surface) continue;
   3417 			surface = scene_surface->surface;
   3418 		}
   3419 		/* Walk the tree to find a node that knows the client */
   3420 		for (pnode = node; pnode && !c; pnode = &pnode->parent->node)
   3421 			c = pnode->data;
   3422 		if (c && c->type == LayerShell) {
   3423 			c = NULL;
   3424 			l = pnode->data;
   3425 		}
   3426 	}
   3427 
   3428 	if (psurface) *psurface = surface;
   3429 	if (pc) *pc = c;
   3430 	if (pl) *pl = l;
   3431 }
   3432 
   3433 void
   3434 zoom(const Arg *arg)
   3435 {
   3436 	Client *c, *sel = focustop(selmon);
   3437 
   3438 	if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating)
   3439 		return;
   3440 
   3441 	/* Search for the first tiled window that is not sel, marking sel as
   3442 	 * NULL if we pass it along the way */
   3443 	wl_list_for_each(c, &clients, link) {
   3444 		if (VISIBLEON(c, selmon) && !c->isfloating) {
   3445 			if (c != sel)
   3446 				break;
   3447 			sel = NULL;
   3448 		}
   3449 	}
   3450 
   3451 	/* Return if no other tiled window was found */
   3452 	if (&c->link == &clients)
   3453 		return;
   3454 
   3455 	/* If we passed sel, move c to the front; otherwise, move sel to the
   3456 	 * front */
   3457 	if (!sel)
   3458 		sel = c;
   3459 	wl_list_remove(&sel->link);
   3460 	wl_list_insert(&clients, &sel->link);
   3461 
   3462 	focusclient(sel, 1);
   3463 	arrange(selmon);
   3464 }
   3465 
   3466 #ifdef XWAYLAND
   3467 void
   3468 activatex11(struct wl_listener *listener, void *data)
   3469 {
   3470 	Client *c = wl_container_of(listener, c, activate);
   3471 
   3472 	/* Only "managed" windows can be activated */
   3473 	if (!client_is_unmanaged(c))
   3474 		wlr_xwayland_surface_activate(c->surface.xwayland, 1);
   3475 }
   3476 
   3477 void
   3478 associatex11(struct wl_listener *listener, void *data)
   3479 {
   3480 	Client *c = wl_container_of(listener, c, associate);
   3481 
   3482 	LISTEN(&client_surface(c)->events.map, &c->map, mapnotify);
   3483 	LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify);
   3484 }
   3485 
   3486 void
   3487 configurex11(struct wl_listener *listener, void *data)
   3488 {
   3489 	Client *c = wl_container_of(listener, c, configure);
   3490 	struct wlr_xwayland_surface_configure_event *event = data;
   3491 	/* TODO: figure out if there is another way to do this */
   3492 	if (!c->mon) {
   3493 		wlr_xwayland_surface_configure(c->surface.xwayland,
   3494 				event->x, event->y, event->width, event->height);
   3495 		return;
   3496 	}
   3497 	if (c->isfloating || client_is_unmanaged(c))
   3498 		resize(c, (struct wlr_box){.x = event->x, .y = event->y,
   3499 				.width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0);
   3500 	else
   3501 		arrange(c->mon);
   3502 }
   3503 
   3504 void
   3505 createnotifyx11(struct wl_listener *listener, void *data)
   3506 {
   3507 	struct wlr_xwayland_surface *xsurface = data;
   3508 	Client *c;
   3509 
   3510 	/* Allocate a Client for this surface */
   3511 	c = xsurface->data = ecalloc(1, sizeof(*c));
   3512 	c->surface.xwayland = xsurface;
   3513 	c->type = X11;
   3514 	c->bw = client_is_unmanaged(c) ? 0 : borderpx;
   3515 
   3516 	/* Listen to the various events it can emit */
   3517 	LISTEN(&xsurface->events.associate, &c->associate, associatex11);
   3518 	LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify);
   3519 	LISTEN(&xsurface->events.dissociate, &c->dissociate, dissociatex11);
   3520 	LISTEN(&xsurface->events.request_activate, &c->activate, activatex11);
   3521 	LISTEN(&xsurface->events.request_configure, &c->configure, configurex11);
   3522 	LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, fullscreennotify);
   3523 	LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints);
   3524 	LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle);
   3525 }
   3526 
   3527 void
   3528 dissociatex11(struct wl_listener *listener, void *data)
   3529 {
   3530 	Client *c = wl_container_of(listener, c, dissociate);
   3531 	wl_list_remove(&c->map.link);
   3532 	wl_list_remove(&c->unmap.link);
   3533 }
   3534 
   3535 xcb_atom_t
   3536 getatom(xcb_connection_t *xc, const char *name)
   3537 {
   3538 	xcb_atom_t atom = 0;
   3539 	xcb_intern_atom_reply_t *reply;
   3540 	xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xc, 0, strlen(name), name);
   3541 	if ((reply = xcb_intern_atom_reply(xc, cookie, NULL)))
   3542 		atom = reply->atom;
   3543 	free(reply);
   3544 
   3545 	return atom;
   3546 }
   3547 
   3548 void
   3549 sethints(struct wl_listener *listener, void *data)
   3550 {
   3551 	Client *c = wl_container_of(listener, c, set_hints);
   3552 	struct wlr_surface *surface = client_surface(c);
   3553 	if (c == focustop(selmon))
   3554 		return;
   3555 
   3556 	c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
   3557 	drawbars();
   3558 
   3559 	if (c->isurgent && surface && surface->mapped)
   3560 		client_set_border_color(c, (float[])COLOR(colors[SchemeUrg][ColBorder]));
   3561 }
   3562 
   3563 void
   3564 xwaylandready(struct wl_listener *listener, void *data)
   3565 {
   3566 	struct wlr_xcursor *xcursor;
   3567 	xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL);
   3568 	int err = xcb_connection_has_error(xc);
   3569 	if (err) {
   3570 		fprintf(stderr, "xcb_connect to X server failed with code %d\n. Continuing with degraded functionality.\n", err);
   3571 		return;
   3572 	}
   3573 
   3574 	/* Collect atoms we are interested in. If getatom returns 0, we will
   3575 	 * not detect that window type. */
   3576 	netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG");
   3577 	netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH");
   3578 	netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR");
   3579 	netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY");
   3580 
   3581 	/* assign the one and only seat */
   3582 	wlr_xwayland_set_seat(xwayland, seat);
   3583 
   3584 	/* Set the default XWayland cursor to match the rest of dwl. */
   3585 	if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", 1)))
   3586 		wlr_xwayland_set_cursor(xwayland,
   3587 				xcursor->images[0]->buffer, xcursor->images[0]->width * 4,
   3588 				xcursor->images[0]->width, xcursor->images[0]->height,
   3589 				xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
   3590 
   3591 	xcb_disconnect(xc);
   3592 }
   3593 #endif
   3594 
   3595 int
   3596 main(int argc, char *argv[])
   3597 {
   3598 	char *startup_cmd = NULL;
   3599 	int c;
   3600 
   3601 	while ((c = getopt(argc, argv, "s:hdv")) != -1) {
   3602 		if (c == 's')
   3603 			startup_cmd = optarg;
   3604 		else if (c == 'd')
   3605 			log_level = WLR_DEBUG;
   3606 		else if (c == 'v')
   3607 			die("dwl " VERSION);
   3608 		else
   3609 			goto usage;
   3610 	}
   3611 	if (optind < argc)
   3612 		goto usage;
   3613 
   3614 	/* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */
   3615 	if (!getenv("XDG_RUNTIME_DIR"))
   3616 		die("XDG_RUNTIME_DIR must be set");
   3617 	setup();
   3618 	run(startup_cmd);
   3619 	cleanup();
   3620 	return EXIT_SUCCESS;
   3621 
   3622 usage:
   3623 	die("Usage: %s [-v] [-d] [-s startup command]", argv[0]);
   3624 }