[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - vcl/inc vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Tue Oct 5 08:50:57 UTC 2021


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

New commits:
commit 03ea50373b37f2a0e5d44649a6ccc9c89d1e3244
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Oct 1 12:42:26 2021 +0100
Commit:     Michael Stahl <michael.stahl at allotropia.de>
CommitDate: Tue Oct 5 10:50:23 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/+/122928
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index b1ddd52913b8..fd4ab4af66da 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -392,6 +392,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 e55cb791e90c..a402e0d15ec1 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 14f2a2e76c59..a7ba7eec9cdb 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>
@@ -3737,6 +3738,41 @@ gboolean GtkSalFrame::signalUnmap(GtkWidget*, GdkEvent*, gpointer frame)
 #endif
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
+
+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);
@@ -3749,6 +3785,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_pDrawingArea);
         if (bFocusInAnotherGtkWidget)


More information about the Libreoffice-commits mailing list