mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
input: workaround GNOME messing up pointer leave/enter after moving window
GNOME doesn’t send pointer enter after finishing a window move. In subsequent move operations, it is also possible to make it skip sending pointer leave when starting the move operations. This caused foot to assert in debug builds, and add the same button multiple times to the list of buttons currently being pressed.
This commit is contained in:
parent
a3cd8ebf3c
commit
a21bf1b4d9
1 changed files with 47 additions and 1 deletions
48
input.c
48
input.c
|
|
@ -1019,12 +1019,12 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
#if defined(_DEBUG) && defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
|
||||
char sym_name[100];
|
||||
xkb_keysym_get_name(sym, sym_name, sizeof(sym_name));
|
||||
#endif
|
||||
|
||||
LOG_DBG("%s (%u/0x%x): seat=%s, term=%p, serial=%u, "
|
||||
"mods=0x%08x, consumed=0x%08x, repeats=%d",
|
||||
sym_name, sym, sym, seat->name, (void *)term, serial,
|
||||
mods, consumed, should_repeat);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* User configurable bindings
|
||||
|
|
@ -1360,6 +1360,8 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
|
|||
LOG_DBG("pointer-enter: pointer=%p, serial=%u, surface = %p, new-moused = %p",
|
||||
(void *)wl_pointer, serial, (void *)surface, (void *)term);
|
||||
|
||||
xassert(tll_length(seat->mouse.buttons) == 0);
|
||||
|
||||
/* Scale may have changed */
|
||||
wayl_reload_xcursor_theme(seat, term->scale);
|
||||
|
||||
|
|
@ -1691,6 +1693,50 @@ fdm_csd_move(struct fdm *fdm, int fd, int events, void *data)
|
|||
|
||||
struct wl_window *win = seat->mouse_focus->window;
|
||||
|
||||
/*
|
||||
* Workaround GNOME bug
|
||||
*
|
||||
* Dragging the window, then stopping the drag (releasing the
|
||||
* mouse button), *without* moving the mouse, and then clicking
|
||||
* twice, waiting for the CSD timer, and finally clicking once
|
||||
* more, results in the follwing sequence (keyboard and other
|
||||
* irrelevant events filtered out, unless they’re needed to prove
|
||||
* a point):
|
||||
*
|
||||
* dbg: input.c:1551: cancelling drag timer, moving window
|
||||
* dbg: input.c:759: keyboard_leave: keyboard=0x607000003580, serial=873, surface=0x6070000036d0
|
||||
* dbg: input.c:1432: seat0: pointer-leave: pointer=0x607000003660, serial=874, surface = 0x6070000396e0, old-moused = 0x622000006100
|
||||
*
|
||||
* --> drag stopped here
|
||||
*
|
||||
* --> LMB clicked first time after the drag (generates the enter event on *release*, but no button events)
|
||||
* dbg: input.c:1360: pointer-enter: pointer=0x607000003660, serial=876, surface = 0x6070000396e0, new-moused = 0x622000006100
|
||||
*
|
||||
* --> LMB clicked, and held until the timer times out, second time after the drag
|
||||
* dbg: input.c:1712: BUTTON: pointer=0x607000003660, serial=877, button=110, state=1
|
||||
* dbg: input.c:1806: starting move timer
|
||||
* dbg: input.c:1692: move timer timed out
|
||||
* dbg: input.c:759: keyboard_leave: keyboard=0x607000003580, serial=878, surface=0x6070000036d0
|
||||
*
|
||||
* --> NOTE: ^^ no pointer leave event this time, only the keyboard leave
|
||||
*
|
||||
* --> LMB clicked one last time
|
||||
* dbg: input.c:697: seat0: keyboard_enter: keyboard=0x607000003580, serial=879, surface=0x6070000036d0
|
||||
* dbg: input.c:1712: BUTTON: pointer=0x607000003660, serial=880, button=110, state=1
|
||||
* err: input.c:1741: BUG in wl_pointer_button(): assertion failed: 'it->item.button != button'
|
||||
*
|
||||
* What are we seeing?
|
||||
*
|
||||
* - GNOME does *not* send a pointer *enter* event after the drag
|
||||
* has stopped
|
||||
* - The second drag does *not* generate a pointer *leave* event
|
||||
* - The missing leave event means we’re still tracking LMB as
|
||||
* being held down in our seat struct.
|
||||
* - This leads to an assert (debug builds) when LMB is clicked
|
||||
* again (seat’s button list already contains LMB).
|
||||
*/
|
||||
tll_free(seat->mouse.buttons);
|
||||
|
||||
win->csd.move_timeout_fd = -1;
|
||||
xdg_toplevel_move(win->xdg_toplevel, seat->wl_seat, win->csd.serial);
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue