decompose wl_backend.c: extract wl_keyboard.c

This commit is contained in:
Window Maker 2026-06-02 15:43:44 +02:00
parent 6df031f834
commit a1a23099ba
3 changed files with 111 additions and 102 deletions

View File

@ -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

View File

@ -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 */

View File

@ -0,0 +1,107 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/util/log.h>
#include <wlr/backend/session.h>
#include <xkbcommon/xkbcommon.h>
#include "../../screen.h"
/* Forward declarations */
int wWaylandKeyPress(unsigned int keycode, unsigned int modifiers);
#include "wl_types.h"
#include <WINGs/WINGsP.h>
/* 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);
}