decompose wl_backend.c: extract wl_focus.c

This commit is contained in:
Window Maker 2026-06-02 11:59:38 +02:00
parent 6044c6418b
commit 89668f0202
4 changed files with 68 additions and 52 deletions

View File

@ -173,7 +173,8 @@ wmaker_SOURCES += \
backend/wayland/wl_badge.c \
backend/wayland/wl_fakeleader.c \
backend/wayland/wl_extensions.c \
backend/wayland/wl_events.c
backend/wayland/wl_events.c \
backend/wayland/wl_focus.c
endif
if USE_NESTED_FUNC

View File

@ -319,7 +319,7 @@ frame_timer_cb(void *data)
int wl_catch_xwayland_error(Display *edpy, XErrorEvent *error);
/* Phase 43: forward declaration — defined in the focus section below. */
static void wl_focus_set(WNativeWindow win, int revert_to, unsigned long timestamp);
void wl_focus_set(WNativeWindow win, int revert_to, unsigned long timestamp);
/* Phase 50: forward declaration — defined in client section below. */
int wl_client_get_pid(WNativeWindow win);
/* Phase 13: forward declarations — defined in pointer section below. */
@ -3882,56 +3882,6 @@ wl_show_crash_dialog(int sig)
/* ------------------------------------------------------------------ */
/* Frame buffer (pixman + wlr_scene_buffer) */
/* ------------------------------------------------------------------ */
/* Focus */
/* ------------------------------------------------------------------ */
static void
wl_focus_set(WNativeWindow win, int revert_to, unsigned long timestamp)
{
/* Phase 43/62: deliver keyboard focus to the XDG toplevel, or clear it. */
(void)revert_to; (void)timestamp;
if (!wl_state.seat || !wl_state.keyboard_dev)
return;
/* WNATIVE_NONE or the focus-sink window → clear Wayland keyboard focus.
* no_focus_xwin is the off-screen InputOnly window created in
* wl_screen_create_internals; focusing it on the Xlib side is harmless
* (it's a real window), but on the Wayland side we clear seat focus. */
if (win == WNATIVE_NONE ||
(wl_state.no_focus_xwin && win == (WNativeWindow)wl_state.no_focus_xwin)) {
wlr_seat_keyboard_clear_focus(wl_state.seat);
return;
}
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v) return;
/* Phase 17: XWayland windows need both X11 focus and Wayland seat focus. */
if (v->xw_surface) {
wlr_xwayland_surface_activate(v->xw_surface, true);
if (v->xw_surface->surface) {
if (wl_state.keyboard_dev) {
struct wlr_keyboard *kb = wlr_keyboard_from_input_device(wl_state.keyboard_dev);
wlr_seat_set_keyboard(wl_state.seat, kb);
}
wlr_seat_keyboard_notify_enter(wl_state.seat,
v->xw_surface->surface,
NULL, 0, NULL);
}
return;
}
if (!v->xdg_surface || !v->xdg_surface->surface)
return;
if (wl_state.keyboard_dev) {
struct wlr_keyboard *kb = wlr_keyboard_from_input_device(wl_state.keyboard_dev);
wlr_seat_set_keyboard(wl_state.seat, kb);
}
/* Flush pending events to client so it has processed wl_seat.capabilities
* and bound wl_keyboard before we send keyboard.enter. */
wl_display_flush_clients(wl_state.display);
wlr_seat_keyboard_notify_enter(wl_state.seat,
v->xdg_surface->surface,
NULL, 0, NULL);
}
/* ------------------------------------------------------------------ */
/* Key / button grabs */
/* ------------------------------------------------------------------ */

View File

@ -0,0 +1,64 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <wayland-server-core.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/xwayland.h>
#include "wl_types.h"
/* Forward declarations */
struct wl_toplevel_view *wl_find_view_by_id(WNativeWindow id);
/* ------------------------------------------------------------------ */
/* Focus */
/* ------------------------------------------------------------------ */
void
wl_focus_set(WNativeWindow win, int revert_to, unsigned long timestamp)
{
/* Phase 43/62: deliver keyboard focus to the XDG toplevel, or clear it. */
(void)revert_to; (void)timestamp;
if (!wl_state.seat || !wl_state.keyboard_dev)
return;
/* WNATIVE_NONE or the focus-sink window → clear Wayland keyboard focus.
* no_focus_xwin is the off-screen InputOnly window created in
* wl_screen_create_internals; focusing it on the Xlib side is harmless
* (it's a real window), but on the Wayland side we clear seat focus. */
if (win == WNATIVE_NONE ||
(wl_state.no_focus_xwin && win == (WNativeWindow)wl_state.no_focus_xwin)) {
wlr_seat_keyboard_clear_focus(wl_state.seat);
return;
}
struct wl_toplevel_view *v = wl_find_view_by_id(win);
if (!v) return;
/* Phase 17: XWayland windows need both X11 focus and Wayland seat focus. */
if (v->xw_surface) {
wlr_xwayland_surface_activate(v->xw_surface, true);
if (v->xw_surface->surface) {
if (wl_state.keyboard_dev) {
struct wlr_keyboard *kb = wlr_keyboard_from_input_device(wl_state.keyboard_dev);
wlr_seat_set_keyboard(wl_state.seat, kb);
}
wlr_seat_keyboard_notify_enter(wl_state.seat,
v->xw_surface->surface,
NULL, 0, NULL);
}
return;
}
if (!v->xdg_surface || !v->xdg_surface->surface)
return;
if (wl_state.keyboard_dev) {
struct wlr_keyboard *kb = wlr_keyboard_from_input_device(wl_state.keyboard_dev);
wlr_seat_set_keyboard(wl_state.seat, kb);
}
/* Flush pending events to client so it has processed wl_seat.capabilities
* and bound wl_keyboard before we send keyboard.enter. */
wl_display_flush_clients(wl_state.display);
wlr_seat_keyboard_notify_enter(wl_state.seat,
v->xdg_surface->surface,
NULL, 0, NULL);
}

View File

@ -541,3 +541,4 @@ void wl_event_loop_terminate(void);
/* Events module (extracted to wl_events.c) */
Bool wl_noop_screen_get_head_usable_area(WScreen *scr, int head, int *x1, int *y1, int *x2, int *y2);
int wl_coords_translate(WNativeWindow src, WNativeWindow dst, int src_x, int src_y, int *dst_x, int *dst_y);
void wl_focus_set(WNativeWindow win, int revert_to, unsigned long timestamp);