Avoid more motion events before deactivating menus

Resolves: RHEL-47037
This commit is contained in:
Matthias Clasen 2025-10-31 16:02:02 -04:00
parent 8e4d3d21c0
commit 2d90546920
2 changed files with 100 additions and 1 deletions

View File

@ -0,0 +1,94 @@
From a7fabc99d5e9c5d11d02b1eea55e4b4bb5b45bf8 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 6 Oct 2025 18:53:15 +0200
Subject: [PATCH] gtkmenu: Await more motion events before deactivating on
release
Under some circumstances, it is possible to get into situations where
a GtkMenu is popped down immediately on button release even on short
clicks. The circumstances that exhibit this behavior are:
- The GtkMenu has to pop up underneath the pointer. E.g. comboboxes,
but not necessarily just that.
- The compositor has to send a motion event between button press and
release. E.g. RDP and EIS do that, in order to ensure the button
release happens in the right coordinates. But this might as well
happen in other circumstances, input devices and compositors.
This results in GtkMenu thinking that this motion event was triggered
by user input, thus deeming it no longer necessary to keep the menu
opened after a short press+release.
While this behavior makes some sense, doing so on the first synthetic
motion event received is a bit too eager, so fix this by expecting
a (low) number of motion events before considering that an item was
definitely selected. Fixes these quickly dismissing popups in
comboboxes (and other places) when interacting through RDP.
Part-of: <https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/9022>
---
gtk/gtkmenu.c | 13 ++++++++++++-
gtk/gtkmenuprivate.h | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 18bef6957d..500194929b 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -154,6 +154,10 @@
#define MENU_POPUP_DELAY 225
#define MENU_POPDOWN_DELAY 1000
+#define N_MOTION_EVENTS 3 /* Expected motion events before
+ * allowing to popdown on release
+ */
+
#define ATTACH_INFO_KEY "gtk-menu-child-attach-info-key"
#define ATTACHED_MENUS "gtk-attached-menus"
@@ -4051,6 +4055,7 @@ static gboolean
gtk_menu_motion_notify (GtkWidget *widget,
GdkEventMotion *event)
{
+ GtkMenuPrivate *priv;
GtkWidget *menu_item;
GtkMenu *menu;
GtkMenuShell *menu_shell;
@@ -4090,8 +4095,12 @@ gtk_menu_motion_notify (GtkWidget *widget,
menu_shell = GTK_MENU_SHELL (parent);
menu = GTK_MENU (menu_shell);
+ priv = menu->priv;
- if (definitely_within_item (menu_item, event->x, event->y))
+ priv->n_motion_events++;
+
+ if (priv->n_motion_events >= N_MOTION_EVENTS &&
+ definitely_within_item (menu_item, event->x, event->y))
menu_shell->priv->activate_time = 0;
need_enter = (gtk_menu_has_navigation_triangle (menu) || menu_shell->priv->ignore_enter);
@@ -4468,6 +4477,8 @@ gtk_menu_enter_notify (GtkWidget *widget,
source_device = gdk_event_get_source_device ((GdkEvent *) event);
menu_item = gtk_get_event_widget ((GdkEvent*) event);
+ GTK_MENU (widget)->priv->n_motion_events = 0;
+
if (GTK_IS_MENU (widget) &&
gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN)
{
diff --git a/gtk/gtkmenuprivate.h b/gtk/gtkmenuprivate.h
index 0918d83e7b..36c9dd46ba 100644
--- a/gtk/gtkmenuprivate.h
+++ b/gtk/gtkmenuprivate.h
@@ -87,6 +87,7 @@ struct _GtkMenuPrivate
gint scroll_offset;
gint saved_scroll_offset;
gint scroll_step;
+ gint n_motion_events;
guint scroll_timeout;
--
2.51.1

View File

@ -20,7 +20,7 @@
Name: gtk3
Version: 3.24.43
Release: 4%{?dist}
Release: 5%{?dist}
Summary: GTK+ graphical user interface library
License: LGPL-2.0-or-later
@ -30,6 +30,7 @@ Source0: https://download.gnome.org/sources/gtk+/3.24/gtk+-%{version}.tar.xz
Patch: 0001-testsuite-Stop-relying-on-xpms.patch
Patch: 0001-Avoid-criticals-on-headless-systems.patch
Patch: gtk3-3.24.30-entry-no-emoji-context-menu.patch
Patch: 0001-gtkmenu-Await-more-motion-events-before-deactivating.patch
BuildRequires: pkgconfig(atk) >= %{atk_version}
BuildRequires: pkgconfig(atk-bridge-2.0)
@ -315,6 +316,10 @@ gtk-query-immodules-3.0-%{__isa_bits} --update-cache &>/dev/null || :
%{_datadir}/installed-tests/
%changelog
* Fri Nov 14 2025 Matthias Clasen <mclasen@redhat.com> - 3.24.43-5
- Await more motion events before deactivating menus
Resolves: RHEL-47037
* Mon Mar 10 2025 Matthias Clasen <mclasen@redhat.com> - 3.24.43-4
- Stop relying on xpms in the testsuite
Resolves: RHEL-69453