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 <caol...@redhat.com> AuthorDate: Fri Aug 21 14:25:03 2020 +0100 Commit: Michael Stahl <michael.st...@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.st...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits