PopupMenu does not work on Wayland with default pointer position. (Issue #23892)

71 views
Skip to first unread message

dsa-t

unread,
Sep 21, 2023, 3:09:17 PM9/21/23
to wx-...@googlegroups.com, Subscribed

Description

Calling PopupMenu with default position arguments on a frame does not work on Wayland when there's no current gtk event or trigger event.

See screenshot from KiCad. gtk_menu_popup_at_rect fails because rect_window is NULL.
image

Stack trace in KiCad:

libgtk-3.so.0!gtk_menu_popup_at_rect(GtkMenu * menu, GdkWindow * rect_window, const GdkRectangle * rect, GdkGravity rect_anchor, GdkGravity menu_anchor, const GdkEvent * trigger_event) (.../gtk+3.0/gtk+3.0-3.24.37/gtk/gtkmenu.c:2280)
libgtk-3.so.0!gtk_menu_popup_at_pointer(GtkMenu * menu, const GdkEvent * trigger_event) (.../gtk+3.0/gtk+3.0-3.24.37/gtk/gtkmenu.c:2430)
libwx_gtk3u_core-3.3.so.0!wxWindow::DoPopupMenu(wxWindow * const this, wxMenu * menu, int x, int y) (.../wxWidgets/src/gtk/window.cpp:6088)
libwx_gtk3u_core-3.3.so.0!wxWindowBase::PopupMenu(wxWindowBase * const this, wxMenu * menu, int x, int y) (.../wxWidgets/src/common/wincmn.cpp:3028)
_eeschema.kiface!wxWindowBase::PopupMenu(wxWindowBase * const this, wxMenu * menu, const wxPoint & pos) (/usr/local/include/wx-3.3/wx/window.h:1349)
_eeschema.kiface!TOOL_MANAGER::DispatchContextMenu(TOOL_MANAGER * const this, const TOOL_EVENT & aEvent) (.../kicad/common/tool/tool_manager.cpp:940)
_eeschema.kiface!TOOL_MANAGER::processEvent(TOOL_MANAGER * const this, const TOOL_EVENT & aEvent) (.../kicad/common/tool/tool_manager.cpp:1208)
_eeschema.kiface!TOOL_MANAGER::ProcessEvent(TOOL_MANAGER * const this, const TOOL_EVENT & aEvent) (.../kicad/common/tool/tool_manager.cpp:1018)
_eeschema.kiface!TOOL_DISPATCHER::handleMouseButton(TOOL_DISPATCHER * const this, wxEvent & aEvent, int aIndex, bool aMotion) (.../kicad/common/tool/tool_dispatcher.cpp:257)
_eeschema.kiface!TOOL_DISPATCHER::DispatchWxEvent(TOOL_DISPATCHER * const this, wxEvent & aEvent) (.../kicad/common/tool/tool_dispatcher.cpp:488)
_eeschema.kiface!EDA_DRAW_PANEL_GAL::OnEvent(EDA_DRAW_PANEL_GAL * const this, wxEvent & aEvent) (.../kicad/common/draw_panel_gal.cpp:581)
libwx_baseu-3.3.so.0!wxAppConsoleBase::HandleEvent(const wxAppConsoleBase * const this, wxEvtHandler * handler, wxEventFunction func, wxEvent & event) (.../wxWidgets/src/common/appbase.cpp:643)
libwx_baseu-3.3.so.0!wxAppConsoleBase::CallEventHandler(const wxAppConsoleBase * const this, wxEvtHandler * handler, wxEventFunctor & functor, wxEvent & event) (.../wxWidgets/src/common/appbase.cpp:655)
libwx_baseu-3.3.so.0!wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase & entry, wxEvtHandler * handler, wxEvent & event) (.../wxWidgets/src/common/event.cpp:1394)
libwx_baseu-3.3.so.0!wxEvtHandler::SearchDynamicEventTable(wxEvtHandler * const this, wxEvent & event) (.../wxWidgets/src/common/event.cpp:1854)
libwx_baseu-3.3.so.0!wxEvtHandler::TryHereOnly(wxEvtHandler * const this, wxEvent & event) (.../wxWidgets/src/common/event.cpp:1577)
libwx_baseu-3.3.so.0!wxEvtHandler::TryBeforeAndHere(wxEvtHandler * const this, wxEvent & event) (.../wxWidgets/include/wx/event.h:3991)
libwx_baseu-3.3.so.0!wxEvtHandler::ProcessEventLocally(wxEvtHandler * const this, wxEvent & event) (.../wxWidgets/src/common/event.cpp:1514)
libwx_baseu-3.3.so.0!wxEvtHandler::ProcessEvent(wxEvtHandler * const this, wxEvent & event) (.../wxWidgets/src/common/event.cpp:1487)
libwx_baseu-3.3.so.0!wxEvtHandler::ProcessPendingEvents(wxEvtHandler * const this) (.../wxWidgets/src/common/event.cpp:1361)
libwx_baseu-3.3.so.0!wxAppConsoleBase::ProcessPendingEvents(wxAppConsoleBase * const this) (.../wxWidgets/src/common/appbase.cpp:552)
libwx_gtk3u_core-3.3.so.0!wxApp::DoIdle(wxApp * const this) (.../wxWidgets/src/gtk/app.cpp:147)
libwx_gtk3u_core-3.3.so.0!wxapp_idle_callback() (.../wxWidgets/src/gtk/app.cpp:99)
libglib-2.0.so.0!g_main_context_dispatch (Unknown Source:0)
libglib-2.0.so.0![Unknown/Just-In-Time compiled code] (Unknown Source:0)
libglib-2.0.so.0!g_main_loop_run (Unknown Source:0)
libgtk-3.so.0!gtk_main() (.../gtk+3.0/gtk+3.0-3.24.37/gtk/gtkmain.c:1329)
libwx_gtk3u_core-3.3.so.0!wxGUIEventLoop::DoRun(wxGUIEventLoop * const this) (.../wxWidgets/src/gtk/evtloop.cpp:61)
libwx_baseu-3.3.so.0!wxEventLoopBase::Run(wxEventLoopBase * const this) (.../wxWidgets/src/common/evtloopcmn.cpp:87)
libwx_baseu-3.3.so.0!wxAppConsoleBase::MainLoop(wxAppConsoleBase * const this) (.../wxWidgets/src/common/appbase.cpp:363)
libwx_baseu-3.3.so.0!wxAppConsoleBase::OnRun(wxAppConsoleBase * const this) (.../wxWidgets/src/common/appbase.cpp:281)
libwx_gtk3u_core-3.3.so.0!wxAppBase::OnRun(wxAppBase * const this) (.../wxWidgets/src/common/appcmn.cpp:334)
APP_SINGLE_TOP::OnRun(APP_SINGLE_TOP * const this) (.../kicad/common/single_top.cpp:206)
libwx_baseu-3.3.so.0!wxEntry(int & argc, wxChar ** argv) (.../wxWidgets/src/common/init.cpp:492)
libwx_baseu-3.3.so.0!wxEntry(int & argc, char ** argv) (.../wxWidgets/src/common/init.cpp:503)
main(int argc, char ** argv) (.../kicad/common/single_top.cpp:286)

Platform and version information

  • wxWidgets version you use: 3.3 (master)
  • wxWidgets port you use: wxGTK
  • OS and its version: Ubuntu 23.04
  • GTK version: 3.24.37
  • Which GDK backend is used: Wayland
  • Wayland compositors: Mutter (GNOME), KWin (KDE), Weston


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892@github.com>

dsa-t

unread,
Sep 21, 2023, 3:12:40 PM9/21/23
to wx-...@googlegroups.com, Subscribed

Commit that introduced gtk_menu_popup_at_pointer: a261c80


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730152785@github.com>

dsa-t

unread,
Sep 21, 2023, 5:26:56 PM9/21/23
to wx-...@googlegroups.com, Subscribed

The following patch fixes the issue (I don't know if it is 100% correct of course).

Inspired by https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=7714fdbf1ce0110744da9c164486c12254d5bd6f

diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index 48b8621cc7..7aae931dd2 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -6085,7 +6085,26 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
     if (wxGTKImpl::IsWayland(window) && wx_is_at_least_gtk3(22))
     {
         if (x == -1 && y == -1)
-            gtk_menu_popup_at_pointer(GTK_MENU(menu->m_menu), nullptr);
+        {
+            GdkEvent * event = gtk_get_current_event();
+
+            if (!event)
+            {
+                event = gdk_event_new(GDK_BUTTON_PRESS);
+                event->button.type = GDK_BUTTON_PRESS;
+                event->button.window = g_object_ref(window);
+                event->button.time = GDK_CURRENT_TIME;
+
+                GdkDisplay* display = gdk_window_get_display(window);
+                wxGCC_WARNING_SUPPRESS(deprecated-declarations)
+                GdkDeviceManager * device_manager = gdk_display_get_device_manager(display);
+                event->button.device = gdk_device_manager_get_client_pointer(device_manager);
+                wxGCC_WARNING_RESTORE()
+            }
+
+            gtk_menu_popup_at_pointer(GTK_MENU(menu->m_menu), event);
+            gdk_event_free(event);
+        }
         else
         {
             const GdkRectangle rect = { x, y, 1, 1 };


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730325427@github.com>

VZ

unread,
Sep 21, 2023, 5:27:06 PM9/21/23
to wx-...@googlegroups.com, Subscribed

I guess the correct solution here is to keep a copy of the "trigger event", i.e. the last mouse event probably, and pass it to gtk_menu_popup_at_pointer()?

But the simplest solution would be to check if we're dispatching a (non-idle) event and use the old function in this case -- this would result in a warning but would still work, wouldn't it?


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730325602@github.com>

dsa-t

unread,
Sep 21, 2023, 5:38:52 PM9/21/23
to wx-...@googlegroups.com, Subscribed

This patch also works, and gets rid of this assert:

Gdk-Message: 00:33:34.360: Window 0x56341abc59d0 is a temporary window without parent, application will not be able to position it on screen.

(menu:177467): Gdk-CRITICAL **: 00:33:34.363: gdk_wayland_window_handle_configure_popup: assertion 'impl->transient_for' failed

diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index 48b8621cc7..1c3c813c6f 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -6080,24 +6080,11 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
     }
 
     menu->m_popupShown = true;
-#if GTK_CHECK_VERSION(3,22,0)
-    GdkWindow* window = gtk_widget_get_window(m_wxwindow ? m_wxwindow : m_widget);
-    if (wxGTKImpl::IsWayland(window) && wx_is_at_least_gtk3(22))
-    {
-        if (x == -1 && y == -1)
-            gtk_menu_popup_at_pointer(GTK_MENU(menu->m_menu), nullptr);
-        else
-        {
-            const GdkRectangle rect = { x, y, 1, 1 };
-            gtk_menu_popup_at_rect(GTK_MENU(menu->m_menu),
-                window, &rect, GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST, nullptr);
-        }
-    }
-    else
-#endif // GTK_CHECK_VERSION(3,22,0)
     {
         wxGCC_WARNING_SUPPRESS(deprecated-declarations)
 
+        gtk_menu_attach_to_widget(GTK_MENU(menu->m_menu), GTK_WIDGET(m_widget), nullptr);
+
         gtk_menu_popup(
                   GTK_MENU(menu->m_menu),
                   nullptr,           // parent menu shell


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730336969@github.com>

dsa-t

unread,
Sep 21, 2023, 8:40:50 PM9/21/23
to wx-...@googlegroups.com, Subscribed

With any of these fixes, press-and-hold left mouse button action to show a menu (via wxTimerEvent) does not work in KiCad. The menu disappears then the mouse button gets released. While the mouse button is down, the menu entries can not be selected using mouse.

https://github.com/wxWidgets/wxWidgets/assets/37658952/6462335d-c1f6-4282-927f-2dde66940611


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730544220@github.com>

dsa-t

unread,
Sep 21, 2023, 8:53:30 PM9/21/23
to wx-...@googlegroups.com, Subscribed

Turns out the above is only an issue in Plasma (KDE), not in GNOME, GNOME Classic, Ubuntu, Weston sessions.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1730572541@github.com>

VZ

unread,
Sep 23, 2023, 7:22:57 PM9/23/23
to wx-...@googlegroups.com, Subscribed

BTW, I can reproduce the problem under GNOME with just

diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 5f32257c6b..d4e68c726c 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -175,6 +175,14 @@ MyFrame::MyFrame(const wxString& title)
     CreateStatusBar(2);
     SetStatusText("Welcome to wxWidgets!");
 #endif // wxUSE_STATUSBAR
+
+    Bind(wxEVT_RIGHT_UP, [this](wxMouseEvent&) {
+        CallAfter([this]() {
+            wxMenu menu;
+            menu.Append(wxID_ABOUT, "About me");
+            PopupMenu(&menu);
+        });
+    });
 }
 
 

and I can confirm that the fixes above work -- at least when using the default position of the menu. If the position is specified, the menu doesn't appear at all for me when using Wayland.

So I've decided to not use the position at all as it seems better than maybe (because apparently it does get shown in some circumstances, if it works for you?) not showing it at all.

Please see #23896, and let me know if you see any problem with it. If not, I'd like to apply it to 3.2.3 too. TIA!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1732431163@github.com>

VZ

unread,
Oct 3, 2023, 1:00:42 PM10/3/23
to wx-...@googlegroups.com, Subscribed

Closed #23892 as completed.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/23892/issue_event/10541093710@github.com>

VZ

unread,
Oct 3, 2023, 1:00:42 PM10/3/23
to wx-...@googlegroups.com, Subscribed

This has been fixed in master and will be part of 3.2.3, so closing.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23892/1745377893@github.com>

Reply all
Reply to author
Forward
0 new messages