vcl/inc/unx/gtk/gtkframe.hxx   |    2 ++
 vcl/inc/unx/gtk/gtksalmenu.hxx |    1 +
 vcl/unx/gtk3/gtkframe.cxx      |   41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+)

New commits:
commit 7abf811bcbb92562a8da965d2ff03b9d53853e09
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Oct 1 12:42:26 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Oct 1 22:51:24 2021 +0200

    tdf#144846 launch gtk3 menubar menus from LibreOffice code
    
    rather than using the builtin gtk mechanism so we can avoid
    duplicate mnemonics in the sidebar getting used instead.
    
    Change-Id: I6c761ae63ae25d835de9444b0e298c63996a83a7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122926
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index b71d40785200..ced3613ad0ca 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -410,6 +410,8 @@ class GtkSalFrame final : public SalFrame
 
     void SetIcon(const char* pIcon);
 
+    bool HandleMenubarMnemonic(guint eState, guint nKeyval);
+
 public:
     cairo_surface_t*                m_pSurface;
     basegfx::B2IVector              m_aFrameSize;
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 36b695a2ccc9..8b68391b1fc9 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -121,6 +121,7 @@ public:
     GtkSalMenu*                 GetTopLevel();
     void                        SetNeedsUpdate();
 
+    GtkWidget*                  GetMenuBarWidget() const { return 
mpMenuBarWidget; }
     GtkWidget*                  GetMenuBarContainerWidget() const { return 
mpMenuBarContainerWidget; }
 
     void CreateMenuBarWidget();
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index a62bdd67162b..aa1d5b600187 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -24,6 +24,7 @@
 #include <unx/gtk/gtksalmenu.hxx>
 #include <unx/gtk/hudawareness.h>
 #include <vcl/event.hxx>
+#include <vcl/i18nhelp.hxx>
 #include <vcl/keycodes.hxx>
 #include <unx/geninst.h>
 #include <headless/svpgdi.hxx>
@@ -3847,6 +3848,40 @@ static bool key_forward(GdkEventKey* pEvent, GtkWindow* 
pDest)
     return bHandled;
 }
 
+static bool activate_menubar_mnemonic(GtkWidget* pWidget, guint nKeyval)
+{
+    const char* pLabel = gtk_menu_item_get_label(GTK_MENU_ITEM(pWidget));
+    gunichar cAccelChar = 0;
+    if (!pango_parse_markup(pLabel, -1, '_', nullptr, nullptr, &cAccelChar, 
nullptr))
+        return false;
+    if (!cAccelChar)
+        return false;
+    auto nMnemonicKeyval = 
gdk_keyval_to_lower(gdk_unicode_to_keyval(cAccelChar));
+    if (nKeyval == nMnemonicKeyval)
+        return gtk_widget_mnemonic_activate(pWidget, false);
+    return false;
+}
+
+bool GtkSalFrame::HandleMenubarMnemonic(guint eState, guint nKeyval)
+{
+    bool bUsedInMenuBar = false;
+    if (eState & GDK_ALT_MASK)
+    {
+        if (GtkWidget* pMenuBar = m_pSalMenu ? m_pSalMenu->GetMenuBarWidget() 
: nullptr)
+        {
+            GList* pChildren = 
gtk_container_get_children(GTK_CONTAINER(pMenuBar));
+            for (GList* pChild = g_list_first(pChildren); pChild; pChild = 
g_list_next(pChild))
+            {
+                bUsedInMenuBar = 
activate_menubar_mnemonic(static_cast<GtkWidget*>(pChild->data), nKeyval);
+                if (bUsedInMenuBar)
+                    break;
+            }
+            g_list_free(pChildren);
+        }
+    }
+    return bUsedInMenuBar;
+}
+
 gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, 
gpointer frame)
 {
     UpdateLastInputEventTime(pEvent->time);
@@ -3859,6 +3894,12 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, 
GdkEventKey* pEvent, gpointe
 
     if (GTK_IS_WINDOW(pThis->m_pWindow))
     {
+        // tdf#144846 If this is registered as a menubar mnemonic then ensure
+        // that any other widget won't be considered as a candidate by taking
+        // over the task of launch the menubar menu outself
+        if (pThis->HandleMenubarMnemonic(pEvent->state, pEvent->keyval))
+            return true;
+
         GtkWidget* pFocusWindow = 
gtk_window_get_focus(GTK_WINDOW(pThis->m_pWindow));
         bFocusInAnotherGtkWidget = pFocusWindow && pFocusWindow != 
GTK_WIDGET(pThis->m_pFixedContainer);
         if (bFocusInAnotherGtkWidget)

Reply via email to