From 27b59ca388c5376fd2c4a0ea239a317891543c05 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Tue, 2 Jun 2026 16:11:42 +0200 Subject: [PATCH] decompose wl_backend.c: extract wl_xdg_activation.c --- src/Makefile.am | 1 + src/backend/wayland/wl_backend.c | 58 +------------------ src/backend/wayland/wl_xdg_activation.c | 75 +++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 57 deletions(-) create mode 100644 src/backend/wayland/wl_xdg_activation.c diff --git a/src/Makefile.am b/src/Makefile.am index d147e21..088e3a5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -191,6 +191,7 @@ wmaker_SOURCES += \ backend/wayland/wl_keyboard.c \ backend/wayland/wl_popup.c \ backend/wayland/wl_text_input.c \ + backend/wayland/wl_xdg_activation.c \ backend/wayland/wl_output_mgmt.c \ backend/wayland/wl_output.c \ backend/wayland/wl_xdg.c \ diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 2ecba3c..dcc6797 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -335,7 +335,7 @@ extern void handle_text_input_new(struct wl_listener *listener, void *data); extern void handle_input_method_new(struct wl_listener *listener, void *data); extern void handle_virtual_keyboard_new(struct wl_listener *listener, void *data); /* Phase 35: xdg_activation request_activate handler. */ -static void handle_xdg_activation_request(struct wl_listener *listener, void *data); +extern void handle_xdg_activation_request(struct wl_listener *listener, void *data); /* Phase 36: layer shell new_surface handler. */ static void handle_layer_shell_new_surface(struct wl_listener *listener, void *data); extern void handle_xdg_new_toplevel(struct wl_listener *listener, void *data); @@ -1704,62 +1704,6 @@ handle_new_shortcuts_inhibitor(struct wl_listener *listener, void *data) /* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */ -/* ------------------------------------------------------------------ */ -/* Phase 35: foreign toplevel management + xdg_activation */ -/* ------------------------------------------------------------------ */ - -/* - * handle_xdg_activation_request — a client requests focus for a surface - * using an activation token (xdg_activation_v1 protocol). - * Find the view owning that surface, deliver WM keyboard focus to it, and - * raise it to the top of the stacking order. - */ -static void -handle_xdg_activation_request(struct wl_listener *listener, void *data) -{ - (void)listener; - struct wlr_xdg_activation_v1_request_activate_event *ev = data; - if (!ev->surface) - return; - - /* Walk toplevel list to find a view whose wlr_surface matches. */ - struct wl_toplevel_view *view; - wl_list_for_each(view, &wl_state.toplevel_list, link) { - struct wlr_surface *surf = NULL; - if (view->xdg_surface) - surf = view->xdg_surface->surface; - else if (view->xw_surface) - surf = view->xw_surface->surface; - if (surf != ev->surface) - continue; - - WObjDescriptor *desc = wm_backend->context_find(view->id, WM_CTX_CLIENT_WIN); - if (desc && desc->parent_type == WCLASS_WINDOW) { - WWindow *wwin = (WWindow *)desc->parent; - wSetFocusTo(wScreenWithNumber(0), wwin); - /* Raise the entire window assembly (frame tree), not just the - * client scene_node — raising the client alone would push it - * above the titlebar and hide decorations. */ - if (view->frame_id) { - struct wl_frame_buf *fb = frame_buf_find(view->frame_id); - if (fb && fb->tree) - wlr_scene_node_raise_to_top(&fb->tree->node); - } else if (view->scene_node) { - wlr_scene_node_raise_to_top(&view->scene_node->node); - } - /* Move to front of toplevel list (Z-order). */ - wl_list_remove(&view->link); - wl_list_insert(wl_state.toplevel_list.prev, &view->link); - /* Update foreign toplevel activated state. */ - if (view->ft_handle) - wlr_foreign_toplevel_handle_v1_set_activated(view->ft_handle, true); - wwarning("wl_backend: xdg_activation focus granted id=0x%lx", view->id); - } - return; - } - wwarning("wl_backend: xdg_activation request for unknown surface (ignored)"); -} - /* ------------------------------------------------------------------ */ /* Phase 36: layer shell — panels, docks, wallpapers, overlays */ /* ------------------------------------------------------------------ */ diff --git a/src/backend/wayland/wl_xdg_activation.c b/src/backend/wayland/wl_xdg_activation.c new file mode 100644 index 0000000..6f3c104 --- /dev/null +++ b/src/backend/wayland/wl_xdg_activation.c @@ -0,0 +1,75 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../screen.h" +#include "wl_types.h" +#include "../../actions.h" +#include + +/* Forward declarations */ +struct wl_frame_buf *frame_buf_find(WNativeWindow id); + +/* Phase 35: foreign toplevel management + xdg_activation */ +/* ------------------------------------------------------------------ */ + +/* + * handle_xdg_activation_request — a client requests focus for a surface + * using an activation token (xdg_activation_v1 protocol). + * Find the view owning that surface, deliver WM keyboard focus to it, and + * raise it to the top of the stacking order. + */ +void +handle_xdg_activation_request(struct wl_listener *listener, void *data) +{ + (void)listener; + struct wlr_xdg_activation_v1_request_activate_event *ev = data; + if (!ev->surface) + return; + + /* Walk toplevel list to find a view whose wlr_surface matches. */ + struct wl_toplevel_view *view; + wl_list_for_each(view, &wl_state.toplevel_list, link) { + struct wlr_surface *surf = NULL; + if (view->xdg_surface) + surf = view->xdg_surface->surface; + else if (view->xw_surface) + surf = view->xw_surface->surface; + if (surf != ev->surface) + continue; + + WObjDescriptor *desc = wm_backend->context_find(view->id, WM_CTX_CLIENT_WIN); + if (desc && desc->parent_type == WCLASS_WINDOW) { + WWindow *wwin = (WWindow *)desc->parent; + wSetFocusTo(wScreenWithNumber(0), wwin); + /* Raise the entire window assembly (frame tree), not just the + * client scene_node — raising the client alone would push it + * above the titlebar and hide decorations. */ + if (view->frame_id) { + struct wl_frame_buf *fb = frame_buf_find(view->frame_id); + if (fb && fb->tree) + wlr_scene_node_raise_to_top(&fb->tree->node); + } else if (view->scene_node) { + wlr_scene_node_raise_to_top(&view->scene_node->node); + } + /* Move to front of toplevel list (Z-order). */ + wl_list_remove(&view->link); + wl_list_insert(wl_state.toplevel_list.prev, &view->link); + /* Update foreign toplevel activated state. */ + if (view->ft_handle) + wlr_foreign_toplevel_handle_v1_set_activated(view->ft_handle, true); + wwarning("wl_backend: xdg_activation focus granted id=0x%lx", view->id); + } + return; + } + wwarning("wl_backend: xdg_activation request for unknown surface (ignored)"); +} + +/* ------------------------------------------------------------------ */