From 340e23ddc647cb94a6b44ad5ebe82c562c1aec87 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Thu, 4 Jun 2026 13:48:26 +0200 Subject: [PATCH] fix WINGs dialog input: skip wManageWindow for WINGs dialogs, connect XDG scene node to fake leader tree, adopt WINGs view ID --- src/backend/wayland/wl_xdg.c | 102 ++++++++++++++++------------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/src/backend/wayland/wl_xdg.c b/src/backend/wayland/wl_xdg.c index a1c80d3..ee1901e 100644 --- a/src/backend/wayland/wl_xdg.c +++ b/src/backend/wayland/wl_xdg.c @@ -228,66 +228,56 @@ handle_toplevel_map(struct wl_listener *listener, void *data) view->xdg_surface->toplevel->app_id ? view->xdg_surface->toplevel->app_id : "(none)", view->xdg_surface->toplevel->title ? view->xdg_surface->toplevel->title : "(none)"); - /* Detect popup-style WINGs windows (menu editor items, etc.) — these - * need borderless presentation, no taskbar entry, and free positioning. */ + /* Detect WINGs dialogs: these are rendered by WINGs into an XDG + * toplevel but managed through a fake_leader (not as their own WM + * window). Skip wManageWindow and connect directly to the frame. */ const char *app_id_check = view->xdg_surface->toplevel->app_id; + int is_wings_dialog = (app_id_check && strcmp(app_id_check, "WINGs") == 0); int is_popup = (app_id_check && strcmp(app_id_check, "wings-popup") == 0); + /* For WINGs dialogs, find the frame buffer created by wl_client_reparent + * and adopt its ID so view_surface_at returns a WINGs-recognized ID. */ + if (is_wings_dialog) { + struct wl_frame_buf *_fb; + wl_list_for_each(_fb, &wl_state.frame_list, link) { + if (_fb->id >= 0x20000000 && !wl_find_view_by_id(_fb->id)) { + wwarning("wl_backend: WINGs dialog id 0x%lx", (unsigned long)_fb->id); + view->id = _fb->id; + view->frame_id = _fb->parent_id; + view->frame_rel_x = _fb->rel_x; + view->frame_rel_y = _fb->rel_y; + break; + } + } + } + { WScreen *scr = wScreenWithNumber(0); + WWindow *wwin = NULL; if (scr) { - WWindow *wwin = wManageWindow(scr, view->id); - if (wwin) { - if (is_popup) { - /* Set borderless + skip-taskbar attributes */ - wwin->client_flags.no_border = 1; - wwin->client_flags.no_titlebar = 1; - wwin->client_flags.no_closable = 1; - wwin->client_flags.no_miniaturizable = 1; - wwin->client_flags.no_resizable = 1; - wwin->client_flags.no_close_button = 1; - wwin->client_flags.no_miniaturize_button = 1; - wwin->client_flags.no_resizebar = 1; - wwin->client_flags.skip_window_list = 1; - wwin->client_flags.skip_switchpanel = 1; - wwin->user_flags = wwin->client_flags; - /* Rebuild frame without decorations */ - extern void wWindowConfigureBorders(WWindow *wwin); - wWindowConfigureBorders(wwin); - /* If the client requested a position via wmaker-popup-v1, - * apply it now that the frame is set up. */ - if (view->popup) - wmaker_popup_apply(view); - } - int pid = wl_client_get_pid(view->id); - /* Phase 62: focus delivered by wManageWindow via wSetFocusTo - * (auto_focus=1 set in wl_screen_create_internals); the - * direct wl_focus_set() call is no longer needed here. */ - - /* Bridge to WINGs view: if this XDG toplevel belongs to - * a WINGs dialog, adopt the WINGs view window ID so - * view_surface_at returns an ID that event dispatch can - * route back to the correct WINGs W_View. */ - { - const char *_app = view->xdg_surface->toplevel->app_id; - if (_app && (strcmp(_app, "WINGs") == 0 || - strcmp(_app, "wings-popup") == 0)) { - /* Find the WINGs frame buffer created by - * wl_client_reparent that hasn't been claimed yet. */ - struct wl_frame_buf *_fb; - wl_list_for_each(_fb, &wl_state.frame_list, link) { - if (_fb->id >= 0x20000000 && !wl_find_view_by_id(_fb->id)) { - wwarning("wl_backend: WINGs dialog id 0x%lx -> view", - (unsigned long)_fb->id); - view->id = _fb->id; - view->frame_id = _fb->parent_id; - view->frame_rel_x = _fb->rel_x; - view->frame_rel_y = _fb->rel_y; - break; - } - } + if (!is_wings_dialog) { + wwin = wManageWindow(scr, view->id); + if (wwin) { + if (is_popup) { + wwin->client_flags.no_border = 1; + wwin->client_flags.no_titlebar = 1; + wwin->client_flags.no_closable = 1; + wwin->client_flags.no_miniaturizable = 1; + wwin->client_flags.no_resizable = 1; + wwin->client_flags.no_close_button = 1; + wwin->client_flags.no_miniaturize_button = 1; + wwin->client_flags.no_resizebar = 1; + wwin->client_flags.skip_window_list = 1; + wwin->client_flags.skip_switchpanel = 1; + wwin->user_flags = wwin->client_flags; + extern void wWindowConfigureBorders(WWindow *wwin); + wWindowConfigureBorders(wwin); + if (view->popup) + wmaker_popup_apply(view); } + int pid = wl_client_get_pid(view->id); } + } /* Phase 18: add XDG surface to the scene graph. * @@ -329,7 +319,7 @@ handle_toplevel_map(struct wl_listener *listener, void *data) * newly managed window so pointer focus is immediately * delivered to its surface. The warp calls * wl_update_pointer_focus() internally. */ - { + if (wwin) { int cx = view->x + wwin->client.width / 2; int cy = view->y + wwin->client.height / 2; wl_pointer_warp_to(cx, cy); @@ -338,7 +328,7 @@ handle_toplevel_map(struct wl_listener *listener, void *data) /* Phase 35: create a foreign toplevel handle so taskbars * and docks (e.g. wlr-taskbar, waybar) can enumerate and * control this window. */ - if (wl_state.foreign_toplevel_mgr && !view->ft_handle) { + if (wwin && wl_state.foreign_toplevel_mgr && !view->ft_handle) { view->ft_handle = wlr_foreign_toplevel_handle_v1_create( wl_state.foreign_toplevel_mgr); @@ -354,8 +344,8 @@ handle_toplevel_map(struct wl_listener *listener, void *data) } } - wm_dock_app_add(view); - } + if (wwin) + wm_dock_app_add(view); } } }