summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-10-10 18:00:46 +0100
committerCaolán McNamara <caolanm@redhat.com>2021-10-10 20:32:32 +0200
commite354e36c9e3f3c418973819208e0bf3e327b7c7c (patch)
tree843840da72413188eaecf8a3997b7b25334ab3e1 /vcl
parent522983d79aa03bd5cc83a8a8b5b385f3b6cfe998 (diff)
gtk3: popdown context menus on toggling radio/check buttons too
like we do for menubar menus (tdf#125803) Change-Id: Ib70b90bd9ec9b1f624b1cdff5ba6d304f75f8919 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123344 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/unx/gtk/gtksalmenu.hxx1
-rw-r--r--vcl/unx/gtk3/gtksalmenu.cxx58
2 files changed, 35 insertions, 24 deletions
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 8b68391b1fc9..85c0f5d3d893 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -48,6 +48,7 @@ private:
BitmapEx maPersonaBitmap;
GtkWidget* mpMenuAllowShrinkWidget;
GtkWidget* mpMenuBarWidget;
+ GtkWidget* mpMenuWidget;
GtkCssProvider* mpMenuBarContainerProvider;
GtkCssProvider* mpMenuBarProvider;
GtkWidget* mpCloseButton;
diff --git a/vcl/unx/gtk3/gtksalmenu.cxx b/vcl/unx/gtk3/gtksalmenu.cxx
index a202f75760e3..f001a17c75d8 100644
--- a/vcl/unx/gtk3/gtksalmenu.cxx
+++ b/vcl/unx/gtk3/gtksalmenu.cxx
@@ -428,12 +428,12 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
UpdateFull();
#if !GTK_CHECK_VERSION(4, 0, 0)
- GtkWidget *pWidget = gtk_menu_new_from_model(mpMenuModel);
- gtk_menu_attach_to_widget(GTK_MENU(pWidget), mpFrame->getMouseEventWidget(), nullptr);
+ mpMenuWidget = gtk_menu_new_from_model(mpMenuModel);
+ gtk_menu_attach_to_widget(GTK_MENU(mpMenuWidget), mpFrame->getMouseEventWidget(), nullptr);
#else
- GtkWidget *pWidget = gtk_popover_menu_new_from_model(mpMenuModel);
- gtk_widget_set_parent(pWidget, mpFrame->getMouseEventWidget());
- gtk_popover_set_has_arrow(GTK_POPOVER(pWidget), false);
+ mpMenuWidget = gtk_popover_menu_new_from_model(mpMenuModel);
+ gtk_widget_set_parent(mpMenuWidget, mpFrame->getMouseEventWidget());
+ gtk_popover_set_has_arrow(GTK_POPOVER(mpMenuWidget), false);
#endif
gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", mpActionGroup);
@@ -443,9 +443,9 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
//until the gtk menu is destroyed
GMainLoop* pLoop = g_main_loop_new(nullptr, true);
#if GTK_CHECK_VERSION(4, 0, 0)
- g_signal_connect_swapped(G_OBJECT(pWidget), "closed", G_CALLBACK(g_main_loop_quit), pLoop);
+ g_signal_connect_swapped(G_OBJECT(mpMenuWidget), "closed", G_CALLBACK(g_main_loop_quit), pLoop);
#else
- g_signal_connect_swapped(G_OBJECT(pWidget), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop);
+ g_signal_connect_swapped(G_OBJECT(mpMenuWidget), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop);
#endif
@@ -464,18 +464,18 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
GdkRectangle rect {static_cast<int>(aFloatRect.Left()), static_cast<int>(aFloatRect.Top()),
static_cast<int>(aFloatRect.GetWidth()), static_cast<int>(aFloatRect.GetHeight())};
- gtk_popover_set_pointing_to(GTK_POPOVER(pWidget), &rect);
+ gtk_popover_set_pointing_to(GTK_POPOVER(mpMenuWidget), &rect);
if (nFlags & FloatWinPopupFlags::Left)
- gtk_popover_set_position(GTK_POPOVER(pWidget), GTK_POS_LEFT);
+ gtk_popover_set_position(GTK_POPOVER(mpMenuWidget), GTK_POS_LEFT);
else if (nFlags & FloatWinPopupFlags::Up)
- gtk_popover_set_position(GTK_POPOVER(pWidget), GTK_POS_TOP);
+ gtk_popover_set_position(GTK_POPOVER(mpMenuWidget), GTK_POS_TOP);
else if (nFlags & FloatWinPopupFlags::Right)
- gtk_popover_set_position(GTK_POPOVER(pWidget), GTK_POS_RIGHT);
+ gtk_popover_set_position(GTK_POPOVER(mpMenuWidget), GTK_POS_RIGHT);
else
- gtk_popover_set_position(GTK_POPOVER(pWidget), GTK_POS_BOTTOM);
+ gtk_popover_set_position(GTK_POPOVER(mpMenuWidget), GTK_POS_BOTTOM);
- gtk_popover_popup(GTK_POPOVER(pWidget));
+ gtk_popover_popup(GTK_POPOVER(mpMenuWidget));
#else
#if GTK_CHECK_VERSION(3,22,0)
if (gtk_check_version(3, 22, 0) == nullptr)
@@ -503,7 +503,7 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
}
GdkSurface* gdkWindow = widget_get_surface(mpFrame->getMouseEventWidget());
- gtk_menu_popup_at_rect(GTK_MENU(pWidget), gdkWindow, &rect, rect_anchor, menu_anchor, nullptr);
+ gtk_menu_popup_at_rect(GTK_MENU(mpMenuWidget), gdkWindow, &rect, rect_anchor, menu_anchor, nullptr);
}
else
#endif
@@ -532,7 +532,7 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
Point aPos = FloatingWindow::ImplCalcPos(pWin, rRect, nFlags, nArrangeIndex);
aPos = FloatingWindow::ImplConvertToAbsPos(xParent, aPos);
- gtk_menu_popup(GTK_MENU(pWidget), nullptr, nullptr, MenuPositionFunc,
+ gtk_menu_popup(GTK_MENU(mpMenuWidget), nullptr, nullptr, MenuPositionFunc,
&aPos, nButton, nTime);
}
#endif
@@ -547,10 +547,11 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangl
gtk_widget_insert_action_group(mpFrame->getMouseEventWidget(), "win", nullptr);
#if !GTK_CHECK_VERSION(4, 0, 0)
- gtk_widget_destroy(pWidget);
+ gtk_widget_destroy(mpMenuWidget);
#else
- g_clear_pointer(&pWidget, gtk_widget_unparent);
+ g_clear_pointer(&mpMenuWidget, gtk_widget_unparent);
#endif
+ mpMenuWidget = nullptr;
g_object_unref(mpActionGroup);
ClearActionGroupAndMenuModel();
@@ -577,6 +578,7 @@ GtkSalMenu::GtkSalMenu( bool bMenuBar ) :
mpMenuBarContainerWidget( nullptr ),
mpMenuAllowShrinkWidget( nullptr ),
mpMenuBarWidget( nullptr ),
+ mpMenuWidget( nullptr ),
mpMenuBarContainerProvider( nullptr ),
mpMenuBarProvider( nullptr ),
mpCloseButton( nullptr ),
@@ -1398,19 +1400,27 @@ void GtkSalMenu::DispatchCommand(const gchar *pCommand)
MenuAndId aMenuAndId = decode_command(pCommand);
GtkSalMenu* pSalSubMenu = aMenuAndId.first;
GtkSalMenu* pTopLevel = pSalSubMenu->GetTopLevel();
+
+ // tdf#125803 spacebar will toggle radios and checkbuttons without automatically
+ // closing the menu. To handle this properly I imagine we need to set groups for the
+ // radiobuttons so the others visually untoggle when the active one is toggled and
+ // we would further need to teach vcl that the state can change more than once.
+ //
+ // or we could unconditionally deactivate the menus if regardless of what particular
+ // type of menu item got activated
if (pTopLevel->mpMenuBarWidget)
{
#if !GTK_CHECK_VERSION(4, 0, 0)
- // tdf#125803 spacebar will toggle radios and checkbuttons without automatically
- // closing the menu. To handle this properly I imagine we need to set groups for the
- // radiobuttons so the others visually untoggle when the active one is toggled and
- // we would further need to teach vcl that the state can change more than once.
- //
- // or we could unconditionally deactivate the menus if regardless of what particular
- // type of menu item got activated
gtk_menu_shell_deactivate(GTK_MENU_SHELL(pTopLevel->mpMenuBarWidget));
#endif
}
+ if (pTopLevel->mpMenuWidget)
+ {
+#if !GTK_CHECK_VERSION(4, 0, 0)
+ gtk_menu_shell_deactivate(GTK_MENU_SHELL(pTopLevel->mpMenuWidget));
+#endif
+ }
+
pTopLevel->GetMenu()->HandleMenuCommandEvent(pSalSubMenu->GetMenu(), aMenuAndId.second);
}