diff options
author | Caolán McNamara <caolanm@redhat.com> | 2021-03-05 15:15:12 +0000 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2021-05-20 13:22:20 +0200 |
commit | fc03ef816d178f0260c50fa450b6a3e208256043 (patch) | |
tree | 9bec66ff2949bd90fcd18349e1c06504f529eca4 | |
parent | e17107f12860c3da20d4daeac2dcd7bf450adb52 (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.hxx | 11 | ||||
-rw-r--r-- | sw/source/uibase/inc/navipi.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/utlui/navipi.cxx | 13 | ||||
-rw-r--r-- | vcl/inc/salvtables.hxx | 2 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 17 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 32 |
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); + } }; } |