[Libreoffice-commits] core.git: vcl/inc vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Fri Aug 21 17:33:22 UTC 2020


 vcl/inc/unx/gtk/gtkframe.hxx  |    2 +
 vcl/unx/gtk3/gtk3gtkframe.cxx |    6 +++
 vcl/unx/gtk3/gtk3gtkinst.cxx  |   66 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 73 insertions(+), 1 deletion(-)

New commits:
commit c2f03b1f5d2579b33140cd910115fffff76c4f9e
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Aug 21 14:25:03 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Fri Aug 21 19:32:37 2020 +0200

    tdf#135965 let F1 in gtk widgets embedded in a GtkSalFrame call help
    
    Change-Id: I6eed15a54769a1a1dcc0a8a6ddb226bd9d7a4fcd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101143
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 3d4c803ff5be..3b82be6f4f7d 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -521,6 +521,8 @@ public:
     static sal_uInt16           GetKeyModCode(guint nState);
     static GdkEvent*            makeFakeKeyPress(GtkWidget* pWidget);
     static SalWheelMouseEvent   GetWheelEvent(GdkEventScroll& rEvent);
+    static void                 NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint,
+        GdkModifierType, gpointer pFrame);
 };
 
 #define OOO_TYPE_FIXED ooo_fixed_get_type()
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 48e8f56230b4..b4ddd142ca1d 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -1040,6 +1040,12 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle )
     else
     {
         m_pWindow = gtk_window_new(eWinType);
+
+        // hook up F1 to show help for embedded native gtk widgets
+        GtkAccelGroup *pGroup = gtk_accel_group_new();
+        GClosure* closure = g_cclosure_new(G_CALLBACK(GtkSalFrame::NativeWidgetHelpPressed), GTK_WINDOW(m_pWindow), nullptr);
+        gtk_accel_group_connect(pGroup, GDK_KEY_F1, static_cast<GdkModifierType>(0), GTK_ACCEL_LOCKED, closure);
+        gtk_window_add_accel_group(GTK_WINDOW(m_pWindow), pGroup);
     }
 
     g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this );
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index b2b5d59fcc46..671938d721c9 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -15777,6 +15777,12 @@ public:
         g_slist_foreach(m_pObjectList, postprocess, this);
 
         GenerateMissingMnemonics();
+
+        if (m_xInterimGlue)
+        {
+            assert(m_pParentWidget);
+            g_object_set_data(G_OBJECT(m_pParentWidget), "InterimWindowGlue", m_xInterimGlue.get());
+        }
     }
 
     void GenerateMissingMnemonics()
@@ -15836,7 +15842,13 @@ public:
     {
         g_slist_free(m_pObjectList);
         g_object_unref(m_pBuilder);
-        m_xInterimGlue.disposeAndClear();
+
+        if (m_xInterimGlue)
+        {
+            assert(m_pParentWidget);
+            g_object_set_data(G_OBJECT(m_pParentWidget), "InterimWindowGlue", nullptr);
+            m_xInterimGlue.disposeAndClear();
+        }
     }
 
     //ideally we would have/use weld::Container add and explicitly
@@ -16328,6 +16340,58 @@ weld::Builder* GtkInstance::CreateBuilder(weld::Widget* pParent, const OUString&
     return new GtkInstanceBuilder(pBuilderParent, rUIRoot, rUIFile, nullptr);
 }
 
+// tdf#135965 for the case of native widgets inside a GtkSalFrame and F1 pressed, run help
+// on gtk widget help ids until we hit a vcl parent and then use vcl window help ids
+void GtkSalFrame::NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer pFrame)
+{
+    Help* pHelp = Application::GetHelp();
+    if (!pHelp)
+        return;
+
+    GtkWindow* pWindow = static_cast<GtkWindow*>(pFrame);
+
+    vcl::Window* pChildWindow = nullptr;
+
+    //show help for widget with keyboard focus
+    GtkWidget* pWidget = gtk_window_get_focus(pWindow);
+    if (!pWidget)
+        pWidget = GTK_WIDGET(pWindow);
+    OString sHelpId = ::get_help_id(pWidget);
+    while (sHelpId.isEmpty())
+    {
+        pWidget = gtk_widget_get_parent(pWidget);
+        if (!pWidget)
+            break;
+        pChildWindow = static_cast<vcl::Window*>(g_object_get_data(G_OBJECT(pWidget), "InterimWindowGlue"));
+        if (pChildWindow)
+        {
+            sHelpId = pChildWindow->GetHelpId();
+            break;
+        }
+        sHelpId = ::get_help_id(pWidget);
+    }
+
+    if (pChildWindow)
+    {
+        while (sHelpId.isEmpty())
+        {
+            pChildWindow = pChildWindow->GetParent();
+            if (!pChildWindow)
+                break;
+            sHelpId = pChildWindow->GetHelpId();
+        }
+        if (!pChildWindow)
+            return;
+        pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pChildWindow);
+        return;
+    }
+
+    if (!pWidget)
+        return;
+    std::unique_ptr<weld::Widget> xTemp(new GtkInstanceWidget(pWidget, nullptr, false));
+    pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), xTemp.get());
+}
+
 weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile, sal_uInt64)
 {
     // Create a foreign window which we know is a GtkGrid and make the native widgets a child of that, so we can


More information about the Libreoffice-commits mailing list