birdwl

birdwl - mrgrouse's fork of djpohly's dwl with patches, fork not currently maintained.
Log | Files | Refs | README | LICENSE

dwl.c (102542B)


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