[Libreoffice-commits] core.git: Branch 'libreoffice-7-1' - include/vcl svtools/source vcl/inc vcl/source vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Wed Dec 9 20:24:56 UTC 2020


 include/vcl/weld.hxx              |   37 ++++++++++++++++++++++++++++++++++---
 svtools/source/control/tabbar.cxx |   13 ++++++++++---
 vcl/inc/salvtables.hxx            |    2 ++
 vcl/source/app/salvtables.cxx     |    7 +++----
 vcl/unx/gtk3/gtk3gtkinst.cxx      |   33 +++++++++++++++++++++++++++++++++
 5 files changed, 82 insertions(+), 10 deletions(-)

New commits:
commit b6c2c72ceeab757fb33f2412afd291c3b21fe2ba
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Dec 9 17:28:00 2020 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Dec 9 21:24:21 2020 +0100

    tdf#138778 add has_child_focus which considers a related popup a 'child'
    
    Change-Id: Iab23e399f2650ece702fb1f62d1387acca472b42
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107480
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 28dd95818293..15236af38c3a 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -89,8 +89,12 @@ protected:
 public:
     virtual void set_sensitive(bool sensitive) = 0;
     virtual bool get_sensitive() const = 0;
+
+    /* visibility */
+
     virtual void show() = 0;
     virtual void hide() = 0;
+
     // This function simply calls show() or hide() but is convenient when the
     // visibility depends on some condition
     virtual void set_visible(bool visible)
@@ -100,17 +104,43 @@ public:
         else
             hide();
     }
-    virtual bool get_visible() const = 0; //if this widget visibility is true
-    virtual bool is_visible() const = 0; //if this widget visibility and all parents is true
+
+    // return if this widget's visibility is true
+    virtual bool get_visible() const = 0;
+
+    // return if this widget's visibility and that of all its parents is true
+    virtual bool is_visible() const = 0;
+
+    /* focus */
+
+    // sets if this widget can own the keyboard focus
     virtual void set_can_focus(bool bCanFocus) = 0;
+
+    // causes this widget to have the keyboard focus
     virtual void grab_focus() = 0;
+
+    // returns if this widget has the keyboard focus
     virtual bool has_focus() const = 0;
-    virtual bool is_active() const = 0; //if this widget has the focus within the active window
+
+    // if the widget that has focus is a child, which includes toplevel popup
+    // children, of this widget. So an Entry with an active popup (or dialog)
+    // has has_child_focus of true, but has_focus of false, while its popup is
+    // shown
+    virtual bool has_child_focus() const = 0;
+
+    // return if this widget has the keyboard focus within the active window
+    // TODO: review if this has any practical difference from has_focus()
+    virtual bool is_active() const = 0;
+
     virtual void set_has_default(bool has_default) = 0;
     virtual bool get_has_default() const = 0;
+
+    /* size */
     virtual void set_size_request(int nWidth, int nHeight) = 0;
     virtual Size get_size_request() const = 0;
     virtual Size get_preferred_size() const = 0;
+
+    /* measure */
     virtual float get_approximate_digit_width() const = 0;
     virtual int get_text_height() const = 0;
     virtual Size get_pixel_size(const OUString& rText) const = 0;
@@ -450,6 +480,7 @@ public:
     // resized, calling set_centered_on_parent with false will turn this
     // off again.
     virtual void set_centered_on_parent(bool bTrackGeometryRequests) = 0;
+    // returns whether the widget that has focus is within this Window
     virtual bool has_toplevel_focus() const = 0;
     virtual void present() = 0;
     virtual void set_window_state(const OString& rStr) = 0;
diff --git a/svtools/source/control/tabbar.cxx b/svtools/source/control/tabbar.cxx
index e41696c0b56d..986041525ade 100644
--- a/svtools/source/control/tabbar.cxx
+++ b/svtools/source/control/tabbar.cxx
@@ -457,8 +457,9 @@ IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel, void )
     ResetPostEvent();
     maLoseFocusIdle.Stop();
 
-    // do it idle in case we quickly regain focus
-    if (!m_xEntry->has_focus())
+    // We need this query, because the edit gets a losefocus event,
+    // when it shows the context menu or the insert symbol dialog
+    if (!m_xEntry->has_focus() && m_xEntry->has_child_focus())
         maLoseFocusIdle.Start();
     else
         GetParent()->EndEditMode( pCancel != nullptr );
@@ -468,7 +469,13 @@ IMPL_LINK_NOARG(TabBarEdit, ImplEndTimerHdl, Timer *, void)
 {
     if (m_xEntry->has_focus())
         return;
-    GetParent()->EndEditMode( true );
+
+    // We need this query, because the edit gets a losefocus event,
+    // when it shows the context menu or the insert symbol dialog
+    if (m_xEntry->has_child_focus())
+        maLoseFocusIdle.Start();
+    else
+        GetParent()->EndEditMode( true );
 }
 
 struct TabBar_Impl
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index f3f4a585cecf..0702cb103a5f 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -210,6 +210,8 @@ public:
 
     virtual bool is_active() const override;
 
+    virtual bool has_child_focus() const override;
+
     virtual void set_has_default(bool has_default) override;
 
     virtual bool get_has_default() const override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 03f68e381163..e8dd4acd4808 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -271,6 +271,8 @@ bool SalInstanceWidget::has_focus() const { return m_xWidget->HasFocus(); }
 
 bool SalInstanceWidget::is_active() const { return m_xWidget->IsActive(); }
 
+bool SalInstanceWidget::has_child_focus() const { return m_xWidget->HasChildPathFocus(true); }
+
 void SalInstanceWidget::set_has_default(bool has_default)
 {
     m_xWidget->set_property("has-default", OUString::boolean(has_default));
@@ -5776,10 +5778,7 @@ public:
         return m_xExpander->get_label_widget()->HasFocus() || SalInstanceContainer::has_focus();
     }
 
-    virtual void grab_focus() override
-    {
-        return m_xExpander->get_label_widget()->GrabFocus();
-    }
+    virtual void grab_focus() override { return m_xExpander->get_label_widget()->GrabFocus(); }
 
     virtual ~SalInstanceExpander() override
     {
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 5af961ed5aeb..c45a66e9edd4 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2546,6 +2546,39 @@ public:
         return pTopLevel && gtk_window_is_active(pTopLevel) && has_focus();
     }
 
+    // is the focus in a child of this widget, where a transient popup attached
+    // to a widget is considered a child of that widget
+    virtual bool has_child_focus() const override
+    {
+        bool bRet = false;
+
+        GList* pList = gtk_window_list_toplevels();
+
+        for (GList* pEntry = pList; pEntry; pEntry = pEntry->next)
+        {
+            if (!gtk_window_has_toplevel_focus(GTK_WINDOW(pEntry->data)))
+                continue;
+            GtkWidget* pFocus = gtk_window_get_focus(GTK_WINDOW(pEntry->data));
+            if (pFocus && gtk_widget_is_ancestor(pFocus, m_pWidget))
+            {
+                bRet = true;
+                break;
+            }
+            GtkWidget* pAttachedTo = gtk_window_get_attached_to(GTK_WINDOW(pEntry->data));
+            if (!pAttachedTo)
+                continue;
+            if (pAttachedTo == m_pWidget || gtk_widget_is_ancestor(pAttachedTo, m_pWidget))
+            {
+                bRet = true;
+                break;
+            }
+        }
+
+        g_list_free(pList);
+
+        return bRet;
+    }
+
     virtual void set_has_default(bool has_default) override
     {
         g_object_set(G_OBJECT(m_pWidget), "has-default", has_default, nullptr);


More information about the Libreoffice-commits mailing list