diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-08-21 14:25:03 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-08-21 19:32:37 +0200 |
commit | c2f03b1f5d2579b33140cd910115fffff76c4f9e (patch) | |
tree | 6d74ef59d47c753ae7ba58b29d0e34e39156eb32 /vcl | |
parent | d2e57b17af2fb5719009c290db3fd9ef81e78c67 (diff) |
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@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 6 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 66 |
3 files changed, 73 insertions, 1 deletions
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 |