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:
parent
e090b929a4
commit
340e23ddc6
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue