wayland: Phase 45 — pointer_query returns on-screen; focus path guarded
pointer_query / pointer_query_full: return 1 when compositor is running
(wl_state.started) so the same_screen check in wManageWindow passes and
wSetFocusTo is called for newly mapped XDG toplevels.
Guard frame-dependent calls in the focus update path:
- wWindowFocus (window.c): guard wFrameWindowChangeState on frame!=NULL
- wWindowUnfocus (window.c): same; also guard wFrameWindowPaint on
owner->frame when clearing semi-focus on transient owner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4574fe8873
commit
69cee6fb15
|
|
@ -25,6 +25,8 @@
|
|||
* device created and attached to seat; mapped toplevels auto-focused.
|
||||
* Phase 44: client_synth_configure, window_resize send XDG configure events
|
||||
* so clients receive size changes from the WM.
|
||||
* Phase 45: pointer_query returns 1 (always on-screen); wWindowFocus/Unfocus
|
||||
* guarded on frame!=NULL so wSetFocusTo works without a frame window.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -610,9 +612,10 @@ static void wl_pointer_warp_to(int x, int y) { (void)x; (void)y; }
|
|||
static int
|
||||
wl_pointer_query(WNativeWindow root, int *root_x, int *root_y)
|
||||
{
|
||||
/* Phase 45: the Wayland compositor IS the screen; always on-screen. */
|
||||
(void)root;
|
||||
*root_x = *root_y = 0;
|
||||
return 0;
|
||||
return wl_state.started ? 1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -621,11 +624,12 @@ wl_pointer_query_full(WNativeWindow root,
|
|||
int *root_x, int *root_y,
|
||||
unsigned int *buttons_out)
|
||||
{
|
||||
/* Phase 45: same — always on-screen when compositor is running. */
|
||||
(void)root;
|
||||
if (child_out) *child_out = WNATIVE_NONE;
|
||||
*root_x = *root_y = 0;
|
||||
if (buttons_out) *buttons_out = 0;
|
||||
return 0;
|
||||
return wl_state.started ? 1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1729,7 +1729,7 @@ void wWindowFocus(WWindow *wwin, WWindow *owin)
|
|||
|
||||
wwin->flags.semi_focused = 0;
|
||||
|
||||
if (wwin->flags.is_gnustep == 0)
|
||||
if (wwin->flags.is_gnustep == 0 && wwin->frame)
|
||||
wFrameWindowChangeState(wwin->frame, WS_FOCUSED);
|
||||
|
||||
wwin->flags.focused = 1;
|
||||
|
|
@ -1783,7 +1783,7 @@ void wWindowUnfocus(WWindow *wwin)
|
|||
{
|
||||
CloseWindowMenu(wwin->screen_ptr);
|
||||
|
||||
if (wwin->flags.is_gnustep == 0)
|
||||
if (wwin->flags.is_gnustep == 0 && wwin->frame)
|
||||
wFrameWindowChangeState(wwin->frame, wwin->flags.semi_focused ? WS_PFOCUSED : WS_UNFOCUSED);
|
||||
|
||||
if (wwin->transient_for != None && wwin->transient_for != wwin->screen_ptr->root_win) {
|
||||
|
|
@ -1793,7 +1793,8 @@ void wWindowUnfocus(WWindow *wwin)
|
|||
owner->flags.semi_focused = 0;
|
||||
if (owner->flags.mapped || owner->flags.shaded) {
|
||||
wWindowUnfocus(owner);
|
||||
wFrameWindowPaint(owner->frame);
|
||||
if (owner->frame)
|
||||
wFrameWindowPaint(owner->frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@
|
|||
# "wManageWindow succeeded" log includes geo= with non-zero size
|
||||
# 13. (Phase 43) focus_set delivers keyboard focus via wlr_seat: compositor
|
||||
# logs "focus_set id=" after wManageWindow succeeds
|
||||
# 14. (Phase 44) client_synth_configure/window_resize send XDG configure
|
||||
# events so clients receive WM-initiated size changes (no external check)
|
||||
# 15. (Phase 45) pointer_query returns 1 so wSetFocusTo fires from
|
||||
# wManageWindow; wWindowFocus/Unfocus guarded on frame!=NULL
|
||||
#
|
||||
# This test grows as wl_backend vtable slots are implemented.
|
||||
#
|
||||
|
|
|
|||
Loading…
Reference in New Issue