summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-03-05 15:15:12 +0000
committerSzymon Kłos <szymon.klos@collabora.com>2021-05-20 13:22:20 +0200
commitfc03ef816d178f0260c50fa450b6a3e208256043 (patch)
tree9bec66ff2949bd90fcd18349e1c06504f529eca4
parente17107f12860c3da20d4daeac2dcd7bf450adb52 (diff)
add a callback for when a container gains or loses focus
Change-Id: Id8e8e59547280297db9140a840228f62b75593ed Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112021 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--include/vcl/weld.hxx11
-rw-r--r--sw/source/uibase/inc/navipi.hxx2
-rw-r--r--sw/source/uibase/utlui/navipi.cxx13
-rw-r--r--vcl/inc/salvtables.hxx2
-rw-r--r--vcl/source/app/salvtables.cxx17
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx32
6 files changed, 72 insertions, 5 deletions
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index ccf486b1b30c..a1eb697c73f5 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -315,6 +315,11 @@ public:
class VCL_DLLPUBLIC Container : virtual public Widget
{
+protected:
+ Link<Container&, void> m_aContainerFocusChangedHdl;
+
+ void signal_container_focus_changed() { m_aContainerFocusChangedHdl.Call(*this); }
+
public:
// remove and add in one go
virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) = 0;
@@ -323,6 +328,12 @@ public:
// create an XWindow as a child of this container. The XWindow is
// suitable to contain css::awt::XControl items
virtual css::uno::Reference<css::awt::XWindow> CreateChildFrame() = 0;
+ // rLink is called when the focus transitions from a widget outside the container
+ // to a widget inside the container or vice versa
+ virtual void connect_container_focus_changed(const Link<Container&, void>& rLink)
+ {
+ m_aContainerFocusChangedHdl = rLink;
+ }
};
class VCL_DLLPUBLIC Box : virtual public Container
diff --git a/sw/source/uibase/inc/navipi.hxx b/sw/source/uibase/inc/navipi.hxx
index 0b324f3c442b..f0b36d44f0c8 100644
--- a/sw/source/uibase/inc/navipi.hxx
+++ b/sw/source/uibase/inc/navipi.hxx
@@ -109,6 +109,8 @@ class SwNavigationPI : public PanelLayout
DECL_LINK( ChangePageHdl, Timer*, void );
DECL_LINK( PageEditModifyHdl, weld::SpinButton&, void );
DECL_LINK( EditActionHdl, weld::Entry&, bool );
+ DECL_LINK( SetFocusChildHdl, weld::Container&, void );
+
bool EditAction();
void UsePage();
diff --git a/sw/source/uibase/utlui/navipi.cxx b/sw/source/uibase/utlui/navipi.cxx
index 5205b94d485e..21f3a252e642 100644
--- a/sw/source/uibase/utlui/navipi.cxx
+++ b/sw/source/uibase/utlui/navipi.cxx
@@ -514,6 +514,8 @@ SwNavigationPI::SwNavigationPI(vcl::Window* pParent,
, m_bIsZoomedIn(false)
, m_bGlobalMode(false)
{
+ m_xContainer->connect_container_focus_changed(LINK(this, SwNavigationPI, SetFocusChildHdl));
+
set_id("NavigatorPanelParent"); // for uitest/writer_tests5/tdf114724.py
GetCreateView();
@@ -738,11 +740,12 @@ void SwNavigationPI::StateChanged(StateChangedType nStateChange)
m_xContentTree->UpdateTracking();
}
}
- else if (nStateChange == StateChangedType::ControlFocus)
- {
- // update documents listbox
- UpdateListBox();
- }
+}
+
+IMPL_LINK_NOARG(SwNavigationPI, SetFocusChildHdl, weld::Container&, void)
+{
+ // update documents listbox
+ UpdateListBox();
}
// Notification on modified DocInfo
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 26f809483b66..49f98ace6ebc 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -410,6 +410,8 @@ private:
public:
SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder,
bool bTakeOwnership);
+ virtual void HandleEventListener(VclWindowEvent& rEvent) override;
+ virtual void connect_container_focus_changed(const Link<Container&, void>& rLink) override;
virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) override;
virtual void recursively_unset_default_buttons() override;
virtual css::uno::Reference<css::awt::XWindow> CreateChildFrame() override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index aaba618e8d83..24c6f6d09c5d 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1142,6 +1142,23 @@ void SalInstanceContainer::implResetDefault(const vcl::Window* _pWindow)
}
}
+void SalInstanceContainer::connect_container_focus_changed(const Link<Container&, void>& rLink)
+{
+ ensure_event_listener();
+ weld::Container::connect_container_focus_changed(rLink);
+}
+
+void SalInstanceContainer::HandleEventListener(VclWindowEvent& rEvent)
+{
+ if (rEvent.GetId() == VclEventId::WindowActivate
+ || rEvent.GetId() == VclEventId::WindowDeactivate)
+ {
+ signal_container_focus_changed();
+ return;
+ }
+ SalInstanceWidget::HandleEventListener(rEvent);
+}
+
SalInstanceContainer::SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder,
bool bTakeOwnership)
: SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 765a11af62e8..7302eaaa51c7 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -3771,6 +3771,8 @@ class GtkInstanceContainer : public GtkInstanceWidget, public virtual weld::Cont
{
private:
GtkContainer* m_pContainer;
+ gulong m_nSetFocusChildSignalId;
+ bool m_bChildHasFocus;
static void implResetDefault(GtkWidget *pWidget, gpointer user_data)
{
@@ -3780,11 +3782,35 @@ private:
gtk_container_forall(GTK_CONTAINER(pWidget), implResetDefault, user_data);
}
+ void signal_set_focus_child(bool bChildHasFocus)
+ {
+ if (m_bChildHasFocus != bChildHasFocus)
+ {
+ m_bChildHasFocus = bChildHasFocus;
+ signal_container_focus_changed();
+ }
+ }
+
+ static void signalSetFocusChild(GtkContainer*, GtkWidget* pChild, gpointer widget)
+ {
+ GtkInstanceContainer* pThis = static_cast<GtkInstanceContainer*>(widget);
+ pThis->signal_set_focus_child(pChild != nullptr);
+ }
+
public:
GtkInstanceContainer(GtkContainer* pContainer, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
: GtkInstanceWidget(GTK_WIDGET(pContainer), pBuilder, bTakeOwnership)
, m_pContainer(pContainer)
+ , m_nSetFocusChildSignalId(0)
+ , m_bChildHasFocus(false)
+ {
+ }
+
+ virtual void connect_container_focus_changed(const Link<Container&, void>& rLink) override
{
+ if (!m_nSetFocusChildSignalId)
+ m_nSetFocusChildSignalId = g_signal_connect(G_OBJECT(m_pContainer), "set-focus-child", G_CALLBACK(signalSetFocusChild), this);
+ weld::Container::connect_container_focus_changed(rLink);
}
GtkContainer* getContainer() { return m_pContainer; }
@@ -3838,6 +3864,12 @@ public:
css::uno::Reference<css::awt::XWindow> xWindow(xEmbedWindow->GetComponentInterface(), css::uno::UNO_QUERY);
return xWindow;
}
+
+ virtual ~GtkInstanceContainer() override
+ {
+ if (m_nSetFocusChildSignalId)
+ g_signal_handler_disconnect(m_pContainer, m_nSetFocusChildSignalId);
+ }
};
}