include/svx/fontworkgallery.hxx         |    4 +++
 svx/source/tbxctrls/fontworkgallery.cxx |   14 ++++++++++++
 vcl/unx/gtk3/gtkinst.cxx                |   35 ++++++++++++++++++++++++--------
 3 files changed, 45 insertions(+), 8 deletions(-)

New commits:
commit 1255e9b3c0ed82014a8c0832c40e4c7d8f9c5756
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Mar 9 12:24:00 2023 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Mar 10 10:48:36 2023 +0000

    tdf#140659 gtk a11y: Don't unset model when freezing icon view
    
    As described in Change-Id I10249bbd8c684e89174ba91ce4690d37c24b5d5c
    ("tdf#153657 gtk3 a11y: Use IconView item tooltip as a11y desc"),
    freezing the gtk3 icon view previously resulted in the accessible
    child objects not being created at the time of insertion,
    so setting the accessible description on them doesn't work.
    
    As a result, e.g. the Orca screen reader would not properly
    announce the focused item in Math's elements dock window when using
    the gtk3 VCL plugin.
    
    This was caused by clearing the model in
    `GtkInstanceIconView::freeze` (and resetting it in
    `GtkInstanceIconView::thaw`).
    
    Stop doing that to fix the problem.
    
    Thanks to Caolán for this suggestion!
    
    This also allows to revert
    
        commit 4e8331b77a2dcad2b10d3ca5b788711ea4e83a1b
        Date:   Wed Dec 7 13:20:03 2022 +0000
    
            Resolves: tdf#152411 clear before freeze to let gtk a11y drop 
reference
    
    in a follow-up commit since the problem described in
    tdf#152411 also no longer happens with this in place.
    
    Also switch the previous check + SAL_WARN to an assert
    now that the underlying cause has been addressed.
    
    Change-Id: Id0c241d68ec4fbf933312008f7d0ee86bd3eab0c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148535
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index fd1124e6cb00..6be688f06b93 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -16837,16 +16837,8 @@ private:
         assert(gtk_tree_path_get_depth(pPath) == 1);
         int* indices = gtk_tree_path_get_indices(pPath);
         const int nIndex = indices[0];
-        const int nChildCount = 
atk_object_get_n_accessible_children(pAtkObject);
-        if (nIndex >= nChildCount)
-        {
-            SAL_WARN("vcl.gtk",
-                     "item index "
-                         << nIndex << " greater than ItemView's accessible 
child count "
-                         << nChildCount
-                         << ". Is the IconView frozen, preventing creation of 
a11y children?");
-            return;
-        }
+        assert(nIndex < atk_object_get_n_accessible_children(pAtkObject)
+               && "item index too high for ItemView's accessible child count");
 
         const OUString sTooltipText = 
signal_query_tooltip(GtkInstanceTreeIter(iter));
         AtkObject* pChild = atk_object_ref_accessible_child(pAtkObject, 
nIndex);
@@ -17013,11 +17005,7 @@ public:
         bool bIsFirstFreeze = IsFirstFreeze();
         GtkInstanceWidget::freeze();
         if (bIsFirstFreeze)
-        {
-            g_object_ref(m_pTreeStore);
-            gtk_icon_view_set_model(m_pIconView, nullptr);
             g_object_freeze_notify(G_OBJECT(m_pTreeStore));
-        }
         enable_notify_events();
     }
 
@@ -17025,11 +17013,7 @@ public:
     {
         disable_notify_events();
         if (IsLastThaw())
-        {
             g_object_thaw_notify(G_OBJECT(m_pTreeStore));
-            gtk_icon_view_set_model(m_pIconView, GTK_TREE_MODEL(m_pTreeStore));
-            g_object_unref(m_pTreeStore);
-        }
         GtkInstanceWidget::thaw();
         enable_notify_events();
     }
commit ba0e36e607d1c380fd09b6725a4ebcb69ff399de
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Mar 9 11:38:36 2023 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Mar 10 10:48:29 2023 +0000

    tdf#153657 tdf#140659 gtk3 a11y: Use IconView item tooltip as a11y desc
    
    Similar to how the non-gtk SalInstanceIconView does since
    
            commit 2a28ebeef5ea3e2b01d836a7233d2316b765bf38
            Date:   Wed Jun 1 11:18:26 2022 +0300
    
                Accessibility for IconView
    
    , use the tooltip as accessible description for
    the gtk3's IconView implementation as well.
    
    (Another alternative might be to always require passing
    a text/name in weld::IconView::insert, e.g. by turning the
    `const OUString* pStr` param into a `const OUString&`
    and adding a bool param to indicate whether the text
    should be shown on screen or only used for the accessible
    *name*. Might make sense to reconsider that when looking into
    the remaining aspects from the IconView a11y discussions in [1]
    and [2].)
    
    Together with Change-Id Ic77cf485ed4b2b413d3d3368c15b788d693111cd
    "tdf#153657 a11y: Set tooltip/a11y desc for fontwork styles",
    this makes Orca announce the items in the fontwork
    gallery by their title when using the gtk3 VCL plugin as well.
    
    Setting the accessible description for the items in Math's
    elements side bar still doesn't work with this change by
    itself, since the fact that the IconView is frozen
    (s. the call to `freeze()` in `SmElementsControl::addElements`)
    apparently prevents the creation of the accessible child objects
    on insertion (s. upcoming Change-Id 
Id0c241d68ec4fbf933312008f7d0ee86bd3eab0c,
    "tdf#140659 gtk a11y: Don't unset model when freezing icon view").
    
    [1] https://gerrit.libreoffice.org/c/core/+/135226
    [2] https://gerrit.libreoffice.org/c/core/+/135593
    
    Change-Id: I10249bbd8c684e89174ba91ce4690d37c24b5d5c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148534
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 501521e82491..fd1124e6cb00 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -16825,6 +16825,37 @@ private:
         return !aTooltip.isEmpty();
     }
 
+    /* Set the item's tooltip text as its accessible description as well. */
+    void set_item_accessible_description_from_tooltip(GtkTreeIter& iter)
+    {
+#if GTK_CHECK_VERSION(4, 0, 0)
+        (void)iter;
+#else
+        AtkObject* pAtkObject = 
gtk_widget_get_accessible(GTK_WIDGET(m_pIconView));
+        assert(pAtkObject);
+        GtkTreePath* pPath = 
gtk_tree_model_get_path(GTK_TREE_MODEL(m_pTreeStore), &iter);
+        assert(gtk_tree_path_get_depth(pPath) == 1);
+        int* indices = gtk_tree_path_get_indices(pPath);
+        const int nIndex = indices[0];
+        const int nChildCount = 
atk_object_get_n_accessible_children(pAtkObject);
+        if (nIndex >= nChildCount)
+        {
+            SAL_WARN("vcl.gtk",
+                     "item index "
+                         << nIndex << " greater than ItemView's accessible 
child count "
+                         << nChildCount
+                         << ". Is the IconView frozen, preventing creation of 
a11y children?");
+            return;
+        }
+
+        const OUString sTooltipText = 
signal_query_tooltip(GtkInstanceTreeIter(iter));
+        AtkObject* pChild = atk_object_ref_accessible_child(pAtkObject, 
nIndex);
+        atk_object_set_description(pChild,
+                                   OUStringToOString(sTooltipText, 
RTL_TEXTENCODING_UTF8).getStr());
+        g_object_unref(pChild);
+#endif
+    }
+
     void insert_item(GtkTreeIter& iter, int pos, const OUString* pId, const 
OUString* pText, const OUString* pIconName)
     {
         // m_nTextCol may be -1, so pass it last, to not terminate the 
sequence before the Id value
@@ -16839,6 +16870,8 @@ private:
             if (pixbuf)
                 g_object_unref(pixbuf);
         }
+
+        set_item_accessible_description_from_tooltip(iter);
     }
 
     void insert_item(GtkTreeIter& iter, int pos, const OUString* pId, const 
OUString* pText, const VirtualDevice* pIcon)
@@ -16855,6 +16888,8 @@ private:
             if (pixbuf)
                 g_object_unref(pixbuf);
         }
+
+        set_item_accessible_description_from_tooltip(iter);
     }
 
     OUString get(const GtkTreeIter& iter, int col) const
commit 1fbf95190ea0b3f14060193c51ff31ae178a992a
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Mar 9 08:58:44 2023 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Mar 10 10:48:23 2023 +0000

    tdf#153657 a11y: Set tooltip/a11y desc for fontwork styles
    
    Add a map between ID and title and use that in a newly
    introduced tooltip query handler to return the item's title
    so it is shown as a tooltip.
    
    This also implies that the title is used as the accessible
    description for the items for the non-gtk case, see
    `SalInstanceIconView::EntryAccessibleDescriptionHdl`,
    introduced in
    
        commit 2a28ebeef5ea3e2b01d836a7233d2316b765bf38
        Date:   Wed Jun 1 11:18:26 2022 +0300
    
            Accessibility for IconView
    
    Therefore, the NVDA screen reader on Windows now
    announces the items using their title when they
    receive focus.
    
    Change-Id: Ic77cf485ed4b2b413d3d3368c15b788d693111cd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148523
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/svx/fontworkgallery.hxx b/include/svx/fontworkgallery.hxx
index 1eb90f6476e0..8e5eceb8f033 100644
--- a/include/svx/fontworkgallery.hxx
+++ b/include/svx/fontworkgallery.hxx
@@ -23,6 +23,7 @@
 
 #include <svx/svxdllapi.h>
 #include <vcl/weld.hxx>
+#include <map>
 #include <vector>
 
 class SdrView;
@@ -53,6 +54,8 @@ class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC FontWorkGalleryDialog 
final : public wel
     SdrModel*           mpDestModel;
 
     std::vector<VclPtr< VirtualDevice >> maFavoritesHorizontal;
+    // mapping between item ID and item title
+    std::map<OUString, OUString> maIdToTitleMap;
 
     std::unique_ptr<weld::IconView> maCtlFavorites;
     std::unique_ptr<weld::Button> mxOKButton;
@@ -63,6 +66,7 @@ class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC FontWorkGalleryDialog 
final : public wel
 
     DECL_DLLPRIVATE_LINK(DoubleClickFavoriteHdl, weld::IconView&, bool);
     DECL_DLLPRIVATE_LINK(ClickOKHdl, weld::Button&, void );
+    DECL_DLLPRIVATE_LINK(QueryTooltipHandler, const weld::TreeIter&, OUString);
 
 public:
     FontWorkGalleryDialog(weld::Window* pParent, SdrView& rView);
diff --git a/svx/source/tbxctrls/fontworkgallery.cxx 
b/svx/source/tbxctrls/fontworkgallery.cxx
index cd7d4158cef9..da1df7a8fd96 100644
--- a/svx/source/tbxctrls/fontworkgallery.cxx
+++ b/svx/source/tbxctrls/fontworkgallery.cxx
@@ -66,6 +66,7 @@ FontWorkGalleryDialog::FontWorkGalleryDialog(weld::Window* 
pParent, SdrView& rSd
     maCtlFavorites->set_size_request(aSize.Width(), aSize.Height());
 
     maCtlFavorites->connect_item_activated( LINK( this, FontWorkGalleryDialog, 
DoubleClickFavoriteHdl ) );
+    maCtlFavorites->connect_query_tooltip(LINK(this, FontWorkGalleryDialog, 
QueryTooltipHandler));
     mxOKButton->connect_clicked(LINK(this, FontWorkGalleryDialog, ClickOKHdl));
 
     initFavorites( GALLERY_THEME_FONTWORK );
@@ -125,10 +126,16 @@ void FontWorkGalleryDialog::fillFavorites(sal_uInt16 
nThemeId)
     auto nFavCount = maFavoritesHorizontal.size();
 
     maCtlFavorites->clear();
+    maIdToTitleMap.clear();
+
+    std::vector<OUString> aTitles;
+    GalleryExplorer::FillObjListTitle(nThemeId, aTitles);
+    assert(aTitles.size() == nFavCount);
 
     for( size_t nFavorite = 1; nFavorite <= nFavCount; nFavorite++ )
     {
         OUString sId = OUString::number(static_cast<sal_uInt16>(nFavorite));
+        maIdToTitleMap.emplace(sId, aTitles.at(nFavorite - 1));
         maCtlFavorites->insert(-1, nullptr, &sId, 
maFavoritesHorizontal[nFavorite - 1], nullptr);
     }
 
@@ -262,6 +269,13 @@ IMPL_LINK_NOARG(FontWorkGalleryDialog, 
DoubleClickFavoriteHdl, weld::IconView&,
     return true;
 }
 
+IMPL_LINK(FontWorkGalleryDialog, QueryTooltipHandler, const weld::TreeIter&, 
iter, OUString)
+{
+    const OUString id = maCtlFavorites->get_id(iter);
+    auto it = maIdToTitleMap.find(id);
+    return it != maIdToTitleMap.end() ? it->second : OUString();
+}
+
 namespace {
 
 class FontworkAlignmentWindow final : public WeldToolbarPopup

Reply via email to