From a1a23099bab906059c47eba0b5b723daa76fe5c1 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Tue, 2 Jun 2026 15:43:44 +0200 Subject: [PATCH] decompose wl_backend.c: extract wl_keyboard.c --- src/Makefile.am | 3 +- src/backend/wayland/wl_backend.c | 103 +--------------------------- src/backend/wayland/wl_keyboard.c | 107 ++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 102 deletions(-) create mode 100644 src/backend/wayland/wl_keyboard.c diff --git a/src/Makefile.am b/src/Makefile.am index 8bffd55..1d5d843 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -187,7 +187,8 @@ wmaker_SOURCES += \ backend/wayland/wl_dragicon.c \ backend/wayland/wl_pointer_motion.c \ backend/wayland/wl_pointer_focus.c \ - backend/wayland/wl_grab.c + backend/wayland/wl_grab.c \ + backend/wayland/wl_keyboard.c endif if USE_NESTED_FUNC diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 5dae8e7..7ea7298 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -349,6 +349,8 @@ static void handle_backend_new_output(struct wl_listener *listener, void *data); static void handle_output_frame(struct wl_listener *listener, void *data); extern void handle_pointer_motion_absolute(struct wl_listener *listener, void *data); static void handle_pointer_button(struct wl_listener *listener, void *data); +extern void handle_keyboard_key(struct wl_listener *listener, void *data); +extern void handle_keyboard_modifiers(struct wl_listener *listener, void *data); static void handle_pointer_frame(struct wl_listener *listener, void *data); extern void wl_grab_begin_move(struct wl_toplevel_view *view); extern void wl_grab_begin_resize(struct wl_toplevel_view *view, uint32_t edges); @@ -1515,107 +1517,6 @@ handle_xdg_new_toplevel(struct wl_listener *listener, void *data) toplevel->title ? toplevel->title : "(none)"); } -/* ------------------------------------------------------------------ */ -/* Phase 78: keyboard event handlers */ -/* ------------------------------------------------------------------ */ - -/* - * handle_keyboard_key — fires for every key press/release on the headless - * keyboard. On key-press, dispatches WM shortcuts via wWaylandKeyPress(); - * then notifies the focused Wayland client via wlr_seat_keyboard_notify_key. - * (The headless backend never actually fires these in practice, but the - * listener is wired so it works immediately when a real backend is used.) - */ -static void -handle_keyboard_key(struct wl_listener *listener, void *data) -{ - struct wlr_keyboard_key_event *event = data; - (void)listener; - - if (!wl_state.seat) - return; - - struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard; - if (!kb) return; - - /* Update modifier state */ - wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers); - - uint32_t keycode = event->keycode + 8; /* evdev → XKB keycode */ - uint32_t modifiers = wlr_keyboard_get_modifiers(kb); - - /* VT switching: Ctrl+Alt+Fn */ - if (wl_state.session && event->state == WL_KEYBOARD_KEY_STATE_PRESSED && - (modifiers & (WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) == - (WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) { - xkb_keysym_t sym = xkb_state_key_get_one_sym(kb->xkb_state, keycode); - if (sym >= XKB_KEY_XF86Switch_VT_1 && sym <= XKB_KEY_XF86Switch_VT_12) { - wlr_session_change_vt(wl_state.session, sym - XKB_KEY_XF86Switch_VT_1 + 1); - return; - } - } - - if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - /* Try WM shortcut dispatch first */ - if (!wl_state.keyboard_grabbed && wWaylandKeyPress((unsigned int)keycode, (unsigned int)modifiers)) - return; /* consumed — do not forward to client */ - } - - /* Phase A: enqueue native WMEvent for WINGs widgets */ - WMScreen *wmscr = wl_get_wmscreen(); - if (wmscr) { - WMEvent ev; - memset(&ev, 0, sizeof(ev)); - ev.type = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) - ? WME_KEY_PRESS : WME_KEY_RELEASE; - - /* Route to focused view */ - W_FocusInfo *finfo = wmscr->focusInfo; - W_View *target = (finfo && finfo->focused) ? finfo->focused - : (finfo && finfo->toplevel) ? finfo->toplevel : NULL; - if (!target && wmscr->modalView) - target = wmscr->modalView; - ev.window = target ? (WNativeWindow)target->window : WNATIVE_NONE; - - ev.u.key.keycode = keycode; - ev.u.key.state = modifiers; - ev.u.key.time = event->time_msec; - ev.u.key.x = wl_state.pointer_x; - ev.u.key.y = wl_state.pointer_y; - ev.u.key.x_root = wl_state.pointer_x; - ev.u.key.y_root = wl_state.pointer_y; - - /* Translate keycode → keysym + UTF-8 via xkb */ - if (kb->xkb_state) { - ev.u.key.keysym = xkb_state_key_get_one_sym(kb->xkb_state, keycode); - ev.u.key.utf8_len = xkb_state_key_get_utf8(kb->xkb_state, keycode, - ev.u.key.utf8, sizeof(ev.u.key.utf8)); - if (ev.u.key.utf8_len >= (int)sizeof(ev.u.key.utf8)) - ev.u.key.utf8_len = 0; - } else { - wwarning("handle_keyboard_key: kb->xkb_state is NULL, dropping key event (keycode=%u)", keycode); - return; - } - - W_WL_EnqueueEvent(wmscr, &ev, NULL); - } - - /* Forward non-shortcut key events to focused Wayland client (if any), - * but not during a keyboard grab (Alt-Tab cycling). */ - if (!wl_state.keyboard_grabbed && wl_state.seat->keyboard_state.focused_surface) - wlr_seat_keyboard_notify_key(wl_state.seat, - event->time_msec, event->keycode, event->state); -} - -static void -handle_keyboard_modifiers(struct wl_listener *listener, void *data) -{ - (void)listener; (void)data; - if (!wl_state.seat) return; - struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard; - if (!kb) return; - wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers); -} /* ------------------------------------------------------------------ */ /* Phase 20: real input device forwarding for nested mode */ diff --git a/src/backend/wayland/wl_keyboard.c b/src/backend/wayland/wl_keyboard.c new file mode 100644 index 0000000..8435ea0 --- /dev/null +++ b/src/backend/wayland/wl_keyboard.c @@ -0,0 +1,107 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include "../../screen.h" + +/* Forward declarations */ +int wWaylandKeyPress(unsigned int keycode, unsigned int modifiers); +#include "wl_types.h" +#include + +/* Forward declarations */ +WMScreen *wl_get_wmscreen(void); +void W_WL_EnqueueEvent(struct W_Screen *scr, const WMEvent *ev, struct W_View *target); + +/* ------------------------------------------------------------------ */ +/* Phase 78: keyboard event handlers */ +/* ------------------------------------------------------------------ */ + +void +handle_keyboard_key(struct wl_listener *listener, void *data) +{ + struct wlr_keyboard_key_event *event = data; + (void)listener; + + if (!wl_state.seat) + return; + + struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard; + if (!kb) return; + + wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers); + + uint32_t keycode = event->keycode + 8; + uint32_t modifiers = wlr_keyboard_get_modifiers(kb); + + if (wl_state.session && event->state == WL_KEYBOARD_KEY_STATE_PRESSED && + (modifiers & (WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) == + (WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT)) { + xkb_keysym_t sym = xkb_state_key_get_one_sym(kb->xkb_state, keycode); + if (sym >= XKB_KEY_XF86Switch_VT_1 && sym <= XKB_KEY_XF86Switch_VT_12) { + wlr_session_change_vt(wl_state.session, sym - XKB_KEY_XF86Switch_VT_1 + 1); + return; + } + } + + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if (!wl_state.keyboard_grabbed && wWaylandKeyPress((unsigned int)keycode, (unsigned int)modifiers)) + return; + } + + WMScreen *wmscr = wl_get_wmscreen(); + if (wmscr) { + WMEvent ev; + memset(&ev, 0, sizeof(ev)); + ev.type = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) + ? WME_KEY_PRESS : WME_KEY_RELEASE; + + W_FocusInfo *finfo = wmscr->focusInfo; + W_View *target = (finfo && finfo->focused) ? finfo->focused + : (finfo && finfo->toplevel) ? finfo->toplevel : NULL; + if (!target && wmscr->modalView) + target = wmscr->modalView; + ev.window = target ? (WNativeWindow)target->window : WNATIVE_NONE; + + ev.u.key.keycode = keycode; + ev.u.key.state = modifiers; + ev.u.key.time = event->time_msec; + ev.u.key.x = wl_state.pointer_x; + ev.u.key.y = wl_state.pointer_y; + ev.u.key.x_root = wl_state.pointer_x; + ev.u.key.y_root = wl_state.pointer_y; + + if (kb->xkb_state) { + ev.u.key.keysym = xkb_state_key_get_one_sym(kb->xkb_state, keycode); + ev.u.key.utf8_len = xkb_state_key_get_utf8(kb->xkb_state, keycode, + ev.u.key.utf8, sizeof(ev.u.key.utf8)); + if (ev.u.key.utf8_len >= (int)sizeof(ev.u.key.utf8)) + ev.u.key.utf8_len = 0; + } else { + wwarning("handle_keyboard_key: kb->xkb_state is NULL, dropping key event (keycode=%u)", keycode); + return; + } + + W_WL_EnqueueEvent(wmscr, &ev, NULL); + } + + if (!wl_state.keyboard_grabbed && wl_state.seat->keyboard_state.focused_surface) + wlr_seat_keyboard_notify_key(wl_state.seat, + event->time_msec, event->keycode, event->state); +} + +void +handle_keyboard_modifiers(struct wl_listener *listener, void *data) +{ + (void)listener; (void)data; + if (!wl_state.seat) return; + struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard; + if (!kb) return; + wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers); +}