diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/window.h | 3 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 24 | ||||
-rw-r--r-- | vcl/source/window/window2.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/gtk/a11y/atkwrapper.cxx | 45 | ||||
-rw-r--r-- | vcl/unx/gtk/a11y/atkwrapper.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 77 |
6 files changed, 147 insertions, 20 deletions
diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 1f61f2b1d4a7..f1f990716db1 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -273,7 +273,8 @@ public: css::uno::Reference< css::awt::XWindowPeer > mxWindowPeer; css::uno::Reference< css::accessibility::XAccessible > mxAccessible; std::shared_ptr< VclSizeGroup > m_xSizeGroup; - std::vector< VclPtr<FixedText> > m_aMnemonicLabels; + std::vector<VclPtr<FixedText>> m_aMnemonicLabels; + std::vector<css::accessibility::AccessibleRelation> m_aExtraAccessibleRelations; std::unique_ptr<ImplAccessibleInfos> mpAccessibleInfos; VCLXWindow* mpVCLXWindow; vcl::Region maWinRegion; //< region to 'shape' the VCL window (frame coordinates) diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 2d49a95c2b7a..c47d46422b53 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -390,6 +390,30 @@ bool SalInstanceWidget::get_hexpand() const return m_xWidget->get_hexpand(); } +void SalInstanceWidget::set_accessible_relation_labeled_by(weld::Widget* pLabel) +{ + vcl::Window* pAtkLabel + = pLabel ? dynamic_cast<SalInstanceWidget&>(*pLabel).getWidget() : nullptr; + m_xWidget->SetAccessibleRelationLabeledBy(pAtkLabel); +} + +void SalInstanceWidget::set_accessible_relation_label_for(weld::Widget* pLabeled) +{ + vcl::Window* pAtkLabeled + = pLabeled ? dynamic_cast<SalInstanceWidget&>(*pLabeled).getWidget() : nullptr; + m_xWidget->SetAccessibleRelationLabelFor(pAtkLabeled); +} + +void SalInstanceWidget::add_extra_accessible_relation(const css::accessibility::AccessibleRelation &rRelation) +{ + m_xWidget->AddExtraAccessibleRelation(rRelation); +} + +void SalInstanceWidget::clear_extra_accessible_relations() +{ + m_xWidget->ClearExtraAccessibleRelations(); +} + void SalInstanceWidget::set_vexpand(bool bExpand) { m_xWidget->set_vexpand(bExpand); diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 5539fb3b8463..92d62792feb5 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -45,6 +45,7 @@ #include <salframe.hxx> #include <scrwnd.hxx> +#include <com/sun/star/accessibility/AccessibleRelation.hpp> #include <com/sun/star/accessibility/AccessibleRole.hpp> using namespace com::sun::star; @@ -1979,6 +1980,21 @@ const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const return mpWindowImpl->m_aMnemonicLabels; } +void Window::AddExtraAccessibleRelation(const css::accessibility::AccessibleRelation &rRelation) +{ + mpWindowImpl->m_aExtraAccessibleRelations.push_back(rRelation); +} + +const std::vector<css::accessibility::AccessibleRelation>& Window::GetExtraAccessibleRelations() const +{ + return mpWindowImpl->m_aExtraAccessibleRelations; +} + +void Window::ClearExtraAccessibleRelations() +{ + mpWindowImpl->m_aExtraAccessibleRelations.clear(); +} + } /* namespace vcl */ void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx index 875d5a26fb9f..a6382c8b2ef6 100644 --- a/vcl/unx/gtk/a11y/atkwrapper.cxx +++ b/vcl/unx/gtk/a11y/atkwrapper.cxx @@ -496,6 +496,29 @@ wrapper_get_index_in_parent( AtkObject *atk_obj ) /*****************************************************************************/ +AtkRelation* +atk_object_wrapper_relation_new(const accessibility::AccessibleRelation& rRelation) +{ + sal_uInt32 nTargetCount = rRelation.TargetSet.getLength(); + + std::vector<AtkObject*> aTargets; + + for (sal_uInt32 i = 0; i < nTargetCount; ++i) + { + uno::Reference< accessibility::XAccessible > xAccessible( + rRelation.TargetSet[i], uno::UNO_QUERY ); + aTargets.push_back(atk_object_wrapper_ref(xAccessible)); + } + + AtkRelation *pRel = + atk_relation_new( + aTargets.data(), nTargetCount, + mapRelationType( rRelation.RelationType ) + ); + + return pRel; +} + static AtkRelationSet * wrapper_ref_relation_set( AtkObject *atk_obj ) { @@ -517,25 +540,9 @@ wrapper_ref_relation_set( AtkObject *atk_obj ) sal_Int32 nRelations = xRelationSet.is() ? xRelationSet->getRelationCount() : 0; for( sal_Int32 n = 0; n < nRelations; n++ ) { - accessibility::AccessibleRelation aRelation = xRelationSet->getRelation( n ); - sal_uInt32 nTargetCount = aRelation.TargetSet.getLength(); - - std::vector<AtkObject*> aTargets; - - for (sal_uInt32 i = 0; i < nTargetCount; ++i) - { - uno::Reference< accessibility::XAccessible > xAccessible( - aRelation.TargetSet[i], uno::UNO_QUERY ); - aTargets.push_back(atk_object_wrapper_ref(xAccessible)); - } - - AtkRelation *pRel = - atk_relation_new( - aTargets.data(), nTargetCount, - mapRelationType( aRelation.RelationType ) - ); - atk_relation_set_add( pSet, pRel ); - g_object_unref( G_OBJECT( pRel ) ); + AtkRelation *pRel = atk_object_wrapper_relation_new(xRelationSet->getRelation(n)); + atk_relation_set_add(pSet, pRel); + g_object_unref(pRel); } } catch(const uno::Exception &) { diff --git a/vcl/unx/gtk/a11y/atkwrapper.hxx b/vcl/unx/gtk/a11y/atkwrapper.hxx index ef33397fa48c..8725e54ccf5b 100644 --- a/vcl/unx/gtk/a11y/atkwrapper.hxx +++ b/vcl/unx/gtk/a11y/atkwrapper.hxx @@ -98,6 +98,8 @@ void atk_object_wrapper_dispose(AtkObjectWrapper* wrapper); AtkStateType mapAtkState( sal_Int16 nState ); +AtkRelation* atk_object_wrapper_relation_new(const css::accessibility::AccessibleRelation& rRelation); + void actionIfaceInit(AtkActionIface *iface); void componentIfaceInit(AtkComponentIface *iface); void editableTextIfaceInit(AtkEditableTextIface *iface); diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index dfb20768282e..e2cc74647add 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -1258,6 +1258,16 @@ private: gulong m_nKeyPressSignalId; gulong m_nKeyReleaseSignalId; gulong m_nSizeAllocateSignalId; + gulong m_nButtonPressSignalId; + gulong m_nMotionSignalId; + gulong m_nButtonReleaseSignalId; + gulong m_nDragMotionSignalId; + gulong m_nDragDropSignalId; + gulong m_nDragDropReceivedSignalId; + gulong m_nDragLeaveSignalId; + + rtl::Reference<GtkDropTarget> m_xDropTarget; + std::vector<AtkRelation*> m_aExtraAtkRelations; static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget) { @@ -1508,6 +1518,73 @@ public: return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8); } + virtual void set_accessible_relation_labeled_by(weld::Widget* pLabel) override + { + AtkObject* pAtkObject = gtk_widget_get_accessible(m_pWidget); + if (!pAtkObject) + return; + AtkObject *pAtkLabel = pLabel ? gtk_widget_get_accessible(dynamic_cast<GtkInstanceWidget&>(*pLabel).getWidget()) : nullptr; + AtkRelationSet *pRelationSet = atk_object_ref_relation_set(pAtkObject); + AtkRelation *pRelation = atk_relation_set_get_relation_by_type(pRelationSet, ATK_RELATION_LABELLED_BY); + if (pRelation) + atk_relation_set_remove(pRelationSet, pRelation); + if (pAtkLabel) + { + AtkObject *obj_array[1]; + obj_array[0] = pAtkLabel; + pRelation = atk_relation_new(obj_array, 1, ATK_RELATION_LABELLED_BY); + atk_relation_set_add(pRelationSet, pRelation); + } + g_object_unref(pRelationSet); + } + + virtual void set_accessible_relation_label_for(weld::Widget* pLabeled) override + { + AtkObject* pAtkObject = gtk_widget_get_accessible(m_pWidget); + if (!pAtkObject) + return; + AtkObject *pAtkLabeled = pLabeled ? gtk_widget_get_accessible(dynamic_cast<GtkInstanceWidget&>(*pLabeled).getWidget()) : nullptr; + AtkRelationSet *pRelationSet = atk_object_ref_relation_set(pAtkObject); + AtkRelation *pRelation = atk_relation_set_get_relation_by_type(pRelationSet, ATK_RELATION_LABEL_FOR); + if (pRelation) + atk_relation_set_remove(pRelationSet, pRelation); + if (pAtkLabeled) + { + AtkObject *obj_array[1]; + obj_array[0] = pAtkLabeled; + pRelation = atk_relation_new(obj_array, 1, ATK_RELATION_LABEL_FOR); + atk_relation_set_add(pRelationSet, pRelation); + } + g_object_unref(pRelationSet); + } + + virtual void add_extra_accessible_relation(const css::accessibility::AccessibleRelation &rRelation) override + { + AtkObject* pAtkObject = gtk_widget_get_accessible(m_pWidget); + if (!pAtkObject) + return; + + AtkRelationSet *pRelationSet = atk_object_ref_relation_set(pAtkObject); + AtkRelation *pRel = atk_object_wrapper_relation_new(rRelation); + m_aExtraAtkRelations.push_back(pRel); + atk_relation_set_add(pRelationSet, pRel); + g_object_unref(pRel); + g_object_unref(pRelationSet); + } + + virtual void clear_extra_accessible_relations() override + { + AtkObject* pAtkObject = gtk_widget_get_accessible(m_pWidget); + if (!pAtkObject) + return; + + AtkRelationSet *pRelationSet = atk_object_ref_relation_set(pAtkObject); + for (AtkRelation* pRel : m_aExtraAtkRelations) + atk_relation_set_remove(pRelationSet, pRel); + m_aExtraAtkRelations.clear(); + g_object_unref(pRelationSet); + } + virtual bool get_extents_relative_to(weld::Widget& rRelative, int& x, int &y, int& width, int &height) override { //for toplevel windows this is sadly futile under wayland, so we can't tell where a dialog is in order to allow |