provide a route to weld accessibility
Change-Id: I92e88a4356cb8e4bd958fd86d33c52f5be82be54
Reviewed-on: https://gerrit.libreoffice.org/51787
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index d623427..4a8340e 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -17,6 +17,8 @@
#include <vcl/field.hxx>
#include <vcl/virdev.hxx>
typedef css::uno::Reference<css::accessibility::XAccessible> a11yref;
namespace weld
{
class Container;
@@ -595,7 +597,9 @@ public:
virtual TextView* weld_text_view(const OString& id, bool bTakeOwnership = false) = 0;
virtual Expander* weld_expander(const OString& id, bool bTakeOwnership = false) = 0;
virtual Entry* weld_entry(const OString& id, bool bTakeOwnership = false) = 0;
virtual DrawingArea* weld_drawing_area(const OString& id, bool bTakeOwnership = false) = 0;
virtual DrawingArea* weld_drawing_area(const OString& id, const a11yref& rA11yImpl = nullptr,
bool bTakeOwnership = false)
= 0;
virtual ~Builder() {}
};
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 9cfe42e..9e0b4eb 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1224,10 +1224,11 @@ private:
DECL_LINK(MouseReleaseHdl, const Point&, void);
public:
SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, bool bTakeOwnership)
SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, const a11yref& rAlly, bool bTakeOwnership)
: SalInstanceWidget(pDrawingArea, bTakeOwnership)
, m_xDrawingArea(pDrawingArea)
{
m_xDrawingArea->SetAccessible(rAlly);
m_xDrawingArea->SetPaintHdl(LINK(this, SalInstanceDrawingArea, PaintHdl));
m_xDrawingArea->SetResizeHdl(LINK(this, SalInstanceDrawingArea, ResizeHdl));
m_xDrawingArea->SetMousePressHdl(LINK(this, SalInstanceDrawingArea, MousePressHdl));
@@ -1601,10 +1602,10 @@ public:
return pExpander ? new SalInstanceExpander(pExpander, bTakeOwnership) : nullptr;
}
virtual weld::DrawingArea* weld_drawing_area(const OString &id, bool bTakeOwnership) override
virtual weld::DrawingArea* weld_drawing_area(const OString &id, const a11yref& rA11yImpl, bool bTakeOwnership) override
{
VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
return pDrawingArea ? new SalInstanceDrawingArea(pDrawingArea, bTakeOwnership) : nullptr;
return pDrawingArea ? new SalInstanceDrawingArea(pDrawingArea, rA11yImpl, bTakeOwnership) : nullptr;
}
virtual ~SalInstanceBuilder() override
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 947d1cc..c5ba7be 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -8,7 +8,7 @@
*/
#include "../gtk/gtkinst.cxx"
#include "../gtk/a11y/atkwrapper.hxx"
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -2615,6 +2615,8 @@ class GtkInstanceDrawingArea : public GtkInstanceWidget, public virtual weld::Dr
{
private:
GtkDrawingArea* m_pDrawingArea;
a11yref m_xAccessible;
AtkObject *m_pAccessible;
ScopedVclPtrInstance<VirtualDevice> m_xDevice;
std::vector<unsigned char> m_aBuffer;
cairo_surface_t* m_pSurface;
@@ -2699,9 +2701,11 @@ private:
}
public:
GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, bool bTakeOwnership)
GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, const a11yref& rA11y, bool bTakeOwnership)
: GtkInstanceWidget(GTK_WIDGET(pDrawingArea), bTakeOwnership)
, m_pDrawingArea(pDrawingArea)
, m_xAccessible(rA11y)
, m_pAccessible(nullptr)
, m_xDevice(nullptr, Size(1, 1), DeviceFormat::DEFAULT)
, m_pSurface(nullptr)
, m_nDrawSignalId(g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(signalDraw), this))
@@ -2710,6 +2714,14 @@ public:
, m_nMotionSignalId(g_signal_connect(m_pDrawingArea, "motion-notify-event", G_CALLBACK(signalMotion), this))
, m_nButtonReleaseSignalId(g_signal_connect(m_pDrawingArea, "button-release-event", G_CALLBACK(signalButton), this))
{
g_object_set_data(G_OBJECT(m_pDrawingArea), "g-lo-GtkInstanceDrawingArea", this);
}
AtkObject* GetAtkObject()
{
if (!m_pAccessible && m_xAccessible.is())
m_pAccessible = atk_object_wrapper_new(m_xAccessible);
return m_pAccessible;
}
virtual void queue_draw() override
@@ -2724,6 +2736,9 @@ public:
virtual ~GtkInstanceDrawingArea() override
{
g_object_steal_data(G_OBJECT(m_pDrawingArea), "g-lo-GtkInstanceDrawingArea");
if (m_pAccessible)
g_object_unref(m_pAccessible);
if (m_pSurface)
cairo_surface_destroy(m_pSurface);
g_signal_handler_disconnect(m_pDrawingArea, m_nButtonPressSignalId);
@@ -3107,6 +3122,37 @@ namespace
}
}
namespace
{
AtkObject* (*default_drawing_area_get_accessible)(GtkWidget *widget);
AtkObject* drawing_area_get_accessibity(GtkWidget *pWidget)
{
void* pData = g_object_get_data(G_OBJECT(pWidget), "g-lo-GtkInstanceDrawingArea");
GtkInstanceDrawingArea* pDrawingArea = static_cast<GtkInstanceDrawingArea*>(pData);
AtkObject *pAtkObj = pDrawingArea ? pDrawingArea->GetAtkObject() : nullptr;
if (pAtkObj)
return pAtkObj;
return default_drawing_area_get_accessible(pWidget);
}
void ensure_intercept_drawing_area_accessibility()
{
static bool bDone;
if (!bDone)
{
gpointer pClass = g_type_class_ref(GTK_TYPE_DRAWING_AREA);
GtkWidgetClass* pWidgetClass = GTK_WIDGET_CLASS(pClass);
default_drawing_area_get_accessible = pWidgetClass->get_accessible;
pWidgetClass->get_accessible = drawing_area_get_accessibity;
g_type_class_unref(pClass);
bDone = true;
}
}
}
class GtkInstanceBuilder : public weld::Builder
{
private:
@@ -3120,6 +3166,8 @@ public:
, m_sHelpRoot(rUIFile)
, m_pParentWidget(pParent)
{
ensure_intercept_drawing_area_accessibility();
OUString aUri(rUIRoot + rUIFile);
OUString aPath;
osl::FileBase::getSystemPathFromFileURL(aUri, aPath);
@@ -3301,13 +3349,13 @@ public:
return new GtkInstanceExpander(pExpander, bTakeOwnership);
}
virtual weld::DrawingArea* weld_drawing_area(const OString &id, bool bTakeOwnership) override
virtual weld::DrawingArea* weld_drawing_area(const OString &id, const a11yref& rA11y, bool bTakeOwnership) override
{
GtkDrawingArea* pDrawingArea = GTK_DRAWING_AREA(gtk_builder_get_object(m_pBuilder, id.getStr()));
if (!pDrawingArea)
return nullptr;
auto_add_parentless_widgets_to_container(GTK_WIDGET(pDrawingArea));
return new GtkInstanceDrawingArea(pDrawingArea, bTakeOwnership);
return new GtkInstanceDrawingArea(pDrawingArea, rA11y, bTakeOwnership);
}
};