[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 22374f2122: Fix user time handling bug on GNOME Shell and Metacit
From: |
Po Lu |
Subject: |
master 22374f2122: Fix user time handling bug on GNOME Shell and Metacity |
Date: |
Sun, 9 Oct 2022 07:58:28 -0400 (EDT) |
branch: master
commit 22374f21229da6052a4d8f13916c79515dddf4f1
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Fix user time handling bug on GNOME Shell and Metacity
* src/xfns.c (x_window): Avoid extraneous
XChangeWindowAttributes.
* src/xterm.c (x_display_set_last_user_time): New argument
SET_PROPERTY. Do not change the user time property if it is not
true. All callers changed.
(handle_one_xevent): Avoid setting the user time property on
LeaveNotify and XI_Leave events.
---
src/xfns.c | 14 +++++++-----
src/xterm.c | 72 +++++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 55 insertions(+), 31 deletions(-)
diff --git a/src/xfns.c b/src/xfns.c
index 8cea93c669..9112448899 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4179,11 +4179,15 @@ x_window (struct frame *f)
{
/* XIM server might require some X events. */
unsigned long fevent = NoEventMask;
- XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
- attributes.event_mask |= fevent;
- attribute_mask = CWEventMask;
- XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- attribute_mask, &attributes);
+
+ if (fevent)
+ {
+ XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
+ attributes.event_mask |= fevent;
+ attribute_mask = CWEventMask;
+ XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ attribute_mask, &attributes);
+ }
}
}
#endif /* HAVE_X_I18N */
diff --git a/src/xterm.c b/src/xterm.c
index aaf2e7988b..a374b13780 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7601,11 +7601,25 @@ static void x_check_font (struct frame *, struct font
*);
user time. We don't sanitize timestamps from events sent by the X
server itself because some Lisp might have set the user time to a
ridiculously large value, and this way a more reasonable timestamp
- can be obtained upon the next event. */
+ can be obtained upon the next event.
+
+ SET_PROPERTY specifies whether or not to change the user time
+ property for the active frame. The important thing is to not set
+ the last user time upon leave events; on Metacity and GNOME Shell,
+ mapping a new frame on top of the old frame potentially causes
+ LeaveNotify or XI_Leave to be sent to the old frame if it contains
+ the pointer, as the new frame will initially stack above the old
+ frame. If _NET_WM_USER_TIME is changed at that point, then GNOME
+ may get notified about the user time change on the old frame before
+ it tries to focus the new frame, which will make it consider the
+ new frame (whose user time property will not have been updated at
+ that point, due to not being focused) as having been mapped
+ out-of-order, and lower the new frame, which is typically not what
+ users want. */
static void
x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
- bool send_event)
+ bool send_event, bool set_property)
{
#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
uint_fast64_t monotonic_time;
@@ -7678,7 +7692,8 @@ x_display_set_last_user_time (struct x_display_info
*dpyinfo, Time time,
#ifndef USE_GTK
/* Don't waste bandwidth if the time hasn't actually changed. */
- if (focus_frame && old_time != dpyinfo->last_user_time)
+ if (focus_frame && old_time != dpyinfo->last_user_time
+ && set_property)
{
time = dpyinfo->last_user_time;
@@ -7719,6 +7734,7 @@ x_set_gtk_user_time (struct frame *f, Time time)
itself. */
#ifndef USE_GTK
+
static void
x_update_frame_user_time_window (struct frame *f)
{
@@ -7782,13 +7798,14 @@ x_update_frame_user_time_window (struct frame *f)
}
}
}
+
#endif
void
x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
Time time)
{
- x_display_set_last_user_time (dpyinfo, time, true);
+ x_display_set_last_user_time (dpyinfo, time, true, true);
}
@@ -12761,7 +12778,7 @@ xi_focus_handle_for_device (struct x_display_info
*dpyinfo,
/* The last-focus-change time of the device changed, so update the
frame's user time. */
x_display_set_last_user_time (dpyinfo, event->time,
- event->send_event);
+ event->send_event, true);
device->focus_frame = mentioned_frame;
device->focus_frame_time = event->time;
@@ -12771,7 +12788,7 @@ xi_focus_handle_for_device (struct x_display_info
*dpyinfo,
/* The last-focus-change time of the device changed, so update the
frame's user time. */
x_display_set_last_user_time (dpyinfo, event->time,
- event->send_event);
+ event->send_event, false);
device->focus_frame = NULL;
@@ -14153,7 +14170,8 @@ XTmouse_position (struct frame **fp, int insist,
Lisp_Object *bar_window,
< dpyinfo->last_mouse_movement_time))
x_display_set_last_user_time (dpyinfo,
dpyinfo->last_mouse_movement_time,
-
dpyinfo->last_mouse_movement_time_send_event);
+
dpyinfo->last_mouse_movement_time_send_event,
+ true);
if ((!f1 || FRAME_TOOLTIP_P (f1))
&& (EQ (track_mouse, Qdropping)
@@ -14769,7 +14787,8 @@ xg_scroll_callback (GtkRange *range, GtkScrollType
scroll,
dpyinfo = FRAME_DISPLAY_INFO (f);
if (time != GDK_CURRENT_TIME)
- x_display_set_last_user_time (dpyinfo, time, true);
+ x_display_set_last_user_time (dpyinfo, time, true,
+ true);
switch (scroll)
{
@@ -18091,7 +18110,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
required for SetInputFocus to work correctly after
taking the input focus. */
x_display_set_last_user_time (dpyinfo, event->xclient.data.l[1],
- true);
+ true, true);
goto done;
}
@@ -19079,7 +19098,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case KeyPress:
x_display_set_last_user_time (dpyinfo, event->xkey.time,
- event->xkey.send_event);
+ event->xkey.send_event,
+ true);
ignore_next_mouse_click_timeout = 0;
coding = Qlatin_1;
@@ -19558,7 +19578,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case EnterNotify:
x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
- event->xcrossing.send_event);
+ event->xcrossing.send_event, true);
#ifdef HAVE_XINPUT2
/* For whatever reason, the X server continues to deliver
@@ -19681,7 +19701,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case LeaveNotify:
x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
- event->xcrossing.send_event);
+ event->xcrossing.send_event, false);
#ifdef HAVE_XINPUT2
/* For whatever reason, the X server continues to deliver
@@ -20496,7 +20516,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (event->xbutton.type == ButtonPress)
x_display_set_last_user_time (dpyinfo, event->xbutton.time,
- event->xbutton.send_event);
+ event->xbutton.send_event, true);
#ifdef HAVE_XWIDGETS
struct xwidget_view *xvw = xwidget_view_from_window
(event->xbutton.window);
@@ -20548,7 +20568,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (event->type == ButtonPress)
{
x_display_set_last_user_time (dpyinfo, event->xbutton.time,
- event->xbutton.send_event);
+ event->xbutton.send_event, true);
dpyinfo->grabbed |= (1 << event->xbutton.button);
dpyinfo->last_mouse_frame = f;
@@ -21105,7 +21125,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
ev.send_event = enter->send_event;
x_display_set_last_user_time (dpyinfo, enter->time,
- enter->send_event);
+ enter->send_event, true);
#ifdef USE_MOTIF
use_copy = true;
@@ -21291,7 +21311,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
x_display_set_last_user_time (dpyinfo, leave->time,
- leave->send_event);
+ leave->send_event, false);
#ifdef HAVE_XWIDGETS
{
@@ -21566,7 +21586,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
state = xi_convert_event_state (xev);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (found_valuator)
xwidget_scroll (xv, xev->event_x, xev->event_y,
@@ -21586,7 +21606,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (found_valuator)
{
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
#if defined USE_GTK && !defined HAVE_GTK3
@@ -22077,7 +22097,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->evtype == XI_ButtonPress)
{
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
dpyinfo->grabbed |= (1 << xev->detail);
dpyinfo->last_mouse_frame = f;
@@ -22120,7 +22140,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->flags & XIPointerEmulated)
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event,
true);
#endif
x_dnd_note_self_wheel (dpyinfo,
x_dnd_last_seen_window,
@@ -22356,7 +22376,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->evtype == XI_ButtonPress)
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
source = xi_device_from_id (dpyinfo, xev->sourceid);
device = xi_device_from_id (dpyinfo, xev->deviceid);
@@ -22735,7 +22755,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
ignore_next_mouse_click_timeout = 0;
f = x_any_window_to_frame (dpyinfo, xev->event);
@@ -23374,7 +23394,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23472,7 +23492,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23519,7 +23539,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23560,7 +23580,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, pev->deviceid);
source = xi_device_from_id (dpyinfo, pev->sourceid);
x_display_set_last_user_time (dpyinfo, pev->time,
- pev->send_event);
+ pev->send_event, true);
if (!device)
goto XI_OTHER;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 22374f2122: Fix user time handling bug on GNOME Shell and Metacity,
Po Lu <=