summaryrefslogtreecommitdiff
path: root/vcl/unx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-08-21 14:25:03 +0100
committerMichael Stahl <michael.stahl@cib.de>2020-08-27 10:09:32 +0200
commitc4ad7eae4800fe7aa2d8f362d4effa160d5c476f (patch)
treec1742f1359099cf716b77f66633830b37d0620a2 /vcl/unx
parenteee1cf0720e080703da2df0acbe8a87ac3b105cb (diff)
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@cib.de>
Diffstat (limited to 'vcl/unx')
-rw-r--r--vcl/unx/gtk3/gtk3gtkframe.cxx10
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx76
2 files changed, 79 insertions, 7 deletions
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