This parallels the LISTEN macro for statically allocated listeners, and it allows us to remove almost all of the global wl_listener declarations.
This also fixes a bug with the axisnotify listener, which was declared with a compound literal. At block scope, these have automatic storage duration 1, so the listener was no longer valid after setup() returned. (The option to declare it static explicitly was standardized in C23, if that ever gains suckless traction.)
ΔSLOC: -27
YCC55JJHQR3BEO3ZTP6NVDKTFU4NNNJP2SW755QMMUAIEBMXXIRAC
MJZ6RCUUOK7R2RMXPXMLRWBAEM6234D2IS7RGPHAE5UN2S64GLGAC
JTZBFGPCDJDJWECXH2LLXY3SUAQNCP45HLJQKG3V7XGTPLD634WAC
FXT4YHEK6Q56BYLNUJJJZC5ZG6AJ2KNXROZIJNXSTOWIRH3A6XDQC
OVLCSHYEKV3OPPZ3GC7KEAMF7YOWHFWE5J6KYGE3OXWQAS62S4XAC
ERBETXYU7NGSWW5LHQ3NSJA2N27JNMDDYMZ74B6IVQTEQMLRP6PAC
7B74AT3BXYB7PVW4F6SGQNPMHOU5TEV5TZ54CG6VSQI46XSEKWXQC
E7UO6NRGXFDMBU3BSJYRDNOA3Y7VHD7NWPHI5PHCPHQF6ZNOPZLQC
BOH54DATFCM5ZC6GDQKEU23PQSIOOINLX3UAI47STL7PP56PQUYAC
PYRALXEFRJ5O2NSVSR7WFJ56QNW2VMWYTBKKGJMDLZCHEU4JXZKQC
6OWRW24NFJB3AYE4GRX346CXWOTA3O5XRNCF6KIG4JRR5BEKA26QC
Q3BFKMS4YCHJ66QGNXGPCBEL5HOL5VXNJNR7MZEY4TPO2XH2C4KAC
LYYPWYVJLPUXGDW4QBAUY3643G3ZUNLL65VCYM42Z7WPGYE3E6JQC
NOI4U573ODSPVF6CUC4T7QSYHZGZFHJ4EKTP5Y73LMUZPXK35FKQC
MIZBQX6SKECIVNNGBF3LCR3IHXQVWQ5BJURMRSBNEVEUWFBH3MTQC
SMPVNWKUULOMWGJELCISIFGBRVX6IKCOQVKIIZMQKDNVVAFRHQYAC
XGXZF5T7UFWJQES25XVBJZ4BN53SJ3SXZH3YUB2JUYVPN2PDRPJAC
NLOBELMSKHUSKSMPZ2QSDVIOJRGWV7HNXNIKZ55TMUCH7DI73TAAC
G3QIBFHUXIPZOPRBEVWZ73FN2NVFNK342LFTAE4B2QFMMEZGKIYQC
HWS332I73ETH3YIIOCQO7WB7VPQICME6GGXFJ7EUWDH5O3KA27QQC
VCNLR5X75OAXVKPZQHF5RUZ7BONBUC6RPGO2NZEUD3FZ7TEVL66AC
6ZKVISYIRGGLYDMIHGXDCHV6N6WYJP2DK3CRJL4AMCZY65OSEYDAC
IIWDZCVWWDAJITIXQXCFIAF7Z46DTFV2FYCUYMS4P7JMP34A6BUQC
7QP2Q5MUDMETQEZD2FRAVIFPIFNURQDKWJ32LJCK3XJU56BCPFFAC
WMNBUD2PGH4XJP7UJNQXULQ475EIQUPEDPZOVU4AT2ALU3FHKFEQC
4QUF4MKRSB5LYYS5FSYTCDSIEMYIERI2BQZLRGJ3GIGVYCPJVEPAC
DGJFEKNKYTSZNU4VGJXLHBOQGRGKYQVDN6IHN25DPKPDEGYQBBAQC
ZIXAFAJJEKSFECJJW57MQ2Z666IZSJXU5FVAQ2JLG34BEJIV322AC
EQRGODLKSVSPFSUZU7BV5ER72U4QS4ATSBKV544XXQVKKTOSC7EAC
/* global event handlers */
static struct wl_listener cursor_axis = {.notify = axisnotify};
static struct wl_listener cursor_button = {.notify = buttonpress};
static struct wl_listener cursor_frame = {.notify = cursorframe};
static struct wl_listener cursor_motion = {.notify = motionrelative};
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
static struct wl_listener drag_icon_destroy = {.notify = destroydragicon};
static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor};
static struct wl_listener idle_inhibitor_destroy = {.notify = destroyidleinhibitor};
static struct wl_listener layout_change = {.notify = updatemons};
static struct wl_listener new_input = {.notify = inputdevice};
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
static struct wl_listener new_output = {.notify = createmon};
static struct wl_listener new_xdg_surface = {.notify = createnotify};
static struct wl_listener new_xdg_decoration = {.notify = createdecoration};
static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface};
static struct wl_listener output_mgr_apply = {.notify = outputmgrapply};
static struct wl_listener output_mgr_test = {.notify = outputmgrtest};
static struct wl_listener request_activate = {.notify = urgent};
static struct wl_listener request_cursor = {.notify = setcursor};
static struct wl_listener request_gamma = {.notify = setgamma};
static struct wl_listener request_set_psel = {.notify = setpsel};
static struct wl_listener request_set_sel = {.notify = setsel};
static struct wl_listener request_start_drag = {.notify = requeststartdrag};
static struct wl_listener start_drag = {.notify = startdrag};
static struct wl_listener session_lock_create_lock = {.notify = locksession};
static struct wl_listener session_lock_mgr_destroy = {.notify = destroysessionmgr};
wl_signal_add(&session_lock_mgr->events.new_lock, &session_lock_create_lock);
wl_signal_add(&session_lock_mgr->events.destroy, &session_lock_mgr_destroy);
wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener);
LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr);
wl_signal_add(&cursor->events.motion, &cursor_motion);
wl_signal_add(&cursor->events.motion_absolute, &cursor_motion_absolute);
wl_signal_add(&cursor->events.button, &cursor_button);
wl_signal_add(&cursor->events.axis, &cursor_axis);
wl_signal_add(&cursor->events.frame, &cursor_frame);
LISTEN_STATIC(&cursor->events.motion, motionrelative);
LISTEN_STATIC(&cursor->events.motion_absolute, motionabsolute);
LISTEN_STATIC(&cursor->events.button, buttonpress);
LISTEN_STATIC(&cursor->events.axis, axisnotify);
LISTEN_STATIC(&cursor->events.frame, cursorframe);
wl_signal_add(&seat->events.request_set_cursor, &request_cursor);
wl_signal_add(&seat->events.request_set_selection, &request_set_sel);
wl_signal_add(&seat->events.request_set_primary_selection, &request_set_psel);
wl_signal_add(&seat->events.request_start_drag, &request_start_drag);
wl_signal_add(&seat->events.start_drag, &start_drag);
LISTEN_STATIC(&seat->events.request_set_cursor, setcursor);
LISTEN_STATIC(&seat->events.request_set_selection, setsel);
LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel);
LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag);
LISTEN_STATIC(&seat->events.start_drag, startdrag);