include/vcl/weld.hxx              |   11 +++++++++++
 sw/source/uibase/inc/navipi.hxx   |    2 ++
 sw/source/uibase/utlui/navipi.cxx |   13 ++++++++-----
 vcl/inc/salvtables.hxx            |    2 ++
 vcl/source/app/salvtables.cxx     |   17 +++++++++++++++++
 vcl/unx/gtk3/gtk3gtkinst.cxx      |   32 ++++++++++++++++++++++++++++++++
 6 files changed, 72 insertions(+), 5 deletions(-)

New commits:
commit 74b5218b68469c29f93436b308e85a20140ce9dd
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Mar 5 15:15:12 2021 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Mar 5 21:25:35 2021 +0100

    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 <caol...@redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 181b35631c97..a42dd09aad5d 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -324,6 +324,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;
@@ -332,6 +337,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 10044d45ed51..bdcd7acde296 100644
--- a/sw/source/uibase/inc/navipi.hxx
+++ b/sw/source/uibase/inc/navipi.hxx
@@ -107,6 +107,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 5a1de153b65c..53fdad3098e3 100644
--- a/sw/source/uibase/utlui/navipi.cxx
+++ b/sw/source/uibase/utlui/navipi.cxx
@@ -534,6 +534,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();
@@ -758,11 +760,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 4322cb242b1b..badc2ff188fd 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -413,6 +413,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 56f297ae8415..81ceba3ccd11 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1146,6 +1146,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 63ebf1885967..7a58dd7d2ead 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -3763,6 +3763,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)
     {
@@ -3772,11 +3774,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; }
@@ -3830,6 +3856,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);
+    }
 };
 
 }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to