fix WINGs dialog input: skip wManageWindow for WINGs dialogs, connect XDG scene node to fake leader tree, adopt WINGs view ID

This commit is contained in:
Window Maker 2026-06-04 13:48:26 +02:00
parent e090b929a4
commit 340e23ddc6
1 changed files with 46 additions and 56 deletions

View File

@ -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);
}
}
}