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

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 27 08:10:09 UTC 2020


 framework/source/uielement/edittoolbarcontroller.cxx |    4 +
 vcl/inc/unx/gtk/gtkframe.hxx                         |    2 
 vcl/unx/gtk3/gtk3gtkframe.cxx                        |   10 ++
 vcl/unx/gtk3/gtk3gtkinst.cxx                         |   76 +++++++++++++++++--
 4 files changed, 85 insertions(+), 7 deletions(-)

New commits:
commit c4ad7eae4800fe7aa2d8f362d4effa160d5c476f
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Aug 21 14:25:03 2020 +0100
Commit:     Michael Stahl <michael.stahl at cib.de>
CommitDate: Thu Aug 27 10:09:32 2020 +0200

    tdf#135965 let F1 in gtk widgets embedded in a GtkSalFrame call help
    
    and...
    
    Resolves: tdf#135965 blank helpids for EditControl children
    
    so the helpid of the EditControl itself is chosen and LibreLogo's
    help can be shown with F1
    
    and...
    
    Resolves: tdf#135965 distinguish between press and release
    
    and...
    
    Related: tdf#135965 return true to show event was handled
    
    and ...
    
    Related: tdf#135965 don't install accel group on adapter
    
    it already has a suitable one in this case
    
    Change-Id: I6eed15a54769a1a1dcc0a8a6ddb226bd9d7a4fcd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101315
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>

diff --git a/framework/source/uielement/edittoolbarcontroller.cxx b/framework/source/uielement/edittoolbarcontroller.cxx
index 76988f88f7a9..392943bdd8e0 100644
--- a/framework/source/uielement/edittoolbarcontroller.cxx
+++ b/framework/source/uielement/edittoolbarcontroller.cxx
@@ -65,6 +65,10 @@ EditControl::EditControl(vcl::Window* pParent, EditToolbarController* pEditToolb
     , m_xWidget(m_xBuilder->weld_entry("entry"))
     , m_pEditToolbarController(pEditToolbarController)
 {
+    OString sEmpty;
+    m_xWidget->set_help_id(sEmpty);
+    m_xContainer->set_help_id(sEmpty);
+
     m_xWidget->connect_focus_in(LINK(this, EditControl, FocusInHdl));
     m_xWidget->connect_focus_out(LINK(this, EditControl, FocusOutHdl));
     m_xWidget->connect_changed(LINK(this, EditControl, ModifyHdl));
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 3d4c803ff5be..fa08c1e64617 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 gboolean             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 5d773bbeeb8a..8ca684ca53b7 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 );
@@ -3179,7 +3185,9 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
             GtkWidgetClass* pWindowClass = GTK_WIDGET_CLASS(pClass);
             // if the focus is not in our main widget, see if there is a handler
             // for this key stroke in GtkWindow first
-            bool bHandled = pWindowClass->key_press_event(pThis->m_pWindow, pEvent);
+            bool bHandled = pEvent->type == GDK_KEY_PRESS
+                ? pWindowClass->key_press_event(pThis->m_pWindow, pEvent)
+                : pWindowClass->key_release_event(pThis->m_pWindow, pEvent);
             g_type_class_unref(pClass);
             if (bHandled)
                 return true;
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 986cf4d23bc1..a6a1481c1620 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -3865,10 +3865,11 @@ private:
     rtl::Reference<SalGtkXWindow> m_xWindow; //uno api
     gulong m_nToplevelFocusChangedSignalId;
 
-    static void help_pressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer widget)
+    static gboolean help_pressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer widget)
     {
         GtkInstanceWindow* pThis = static_cast<GtkInstanceWindow*>(widget);
         pThis->help();
+        return true;
     }
 
     static void signalToplevelFocusChanged(GtkWindow*, GParamSpec*, gpointer widget)
@@ -3885,11 +3886,15 @@ public:
         , m_pWindow(pWindow)
         , m_nToplevelFocusChangedSignalId(0)
     {
-        //hook up F1 to show help
-        GtkAccelGroup *pGroup = gtk_accel_group_new();
-        GClosure* closure = g_cclosure_new(G_CALLBACK(help_pressed), this, nullptr);
-        gtk_accel_group_connect(pGroup, GDK_KEY_F1, static_cast<GdkModifierType>(0), GTK_ACCEL_LOCKED, closure);
-        gtk_window_add_accel_group(pWindow, pGroup);
+        const bool bIsFrameWeld = pBuilder == nullptr;
+        if (!bIsFrameWeld)
+        {
+            //hook up F1 to show help
+            GtkAccelGroup *pGroup = gtk_accel_group_new();
+            GClosure* closure = g_cclosure_new(G_CALLBACK(help_pressed), this, nullptr);
+            gtk_accel_group_connect(pGroup, GDK_KEY_F1, static_cast<GdkModifierType>(0), GTK_ACCEL_LOCKED, closure);
+            gtk_window_add_accel_group(pWindow, pGroup);
+        }
     }
 
     virtual void set_title(const OUString& rTitle) override
@@ -15244,6 +15249,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()
@@ -15801,6 +15812,59 @@ 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
+gboolean GtkSalFrame::NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer pFrame)
+{
+    Help* pHelp = Application::GetHelp();
+    if (!pHelp)
+        return true;
+
+    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 true;
+        pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pChildWindow);
+        return true;
+    }
+
+    if (!pWidget)
+        return true;
+    std::unique_ptr<weld::Widget> xTemp(new GtkInstanceWidget(pWidget, nullptr, false));
+    pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), xTemp.get());
+    return true;
+}
+
 weld::Builder* GtkInstance::CreateInterimBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
 {
     // 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