Re: Custom widgets in ATK



On 14/08/17 23:11, Eric Williams wrote:
Hello,

Hi,

a quick answer for your email below. Sorry for not answering before, I
have just came back from holidays.


I am an Eclipse SWT developer, working to improve accessibility
support for SWT on Linux.

Some background: SWT is a cross-platform Java UI toolkit which runs
using GTK on Linux. Most SWT widgets match up to GTK widgets -- these
are accessible by default via GTK. However we implement a custom GTK
container, called SwtFixed, for custom widgets. These custom widgets
do not map up to native GTK widgets and are drawn manually. The role
of these widgets vary: from text editing to custom combos, etc. The
main text editor in Eclipse is a custom widget, which means that
accessibility for these widgets is important.

The issue: at present time, Orca is unable to read these custom
widgets. It works on GTK2 semi-reliably, but GTK3 is unusable. Orca
either hangs, crashes, or fails to read events/information from the
custom widgets.

We currently have an accessibility implementation in SWT that was
created long before GTK3 was around. From what I gather, it has not
been regularly maintained since ~2012. The existing implementation
uses ATK to enable accessibility in areas that GTK cannot (i.e., for
custom widgets). I am virtually certain that the problem lies in the
accessibility implementation, as the custom container implementation
is accessible by default through GTK. I have confirmed this via testing.

Here is some of the code to register a custom widget with ATK:

(I've removed some of the Java typing to make it easier to read)

widgetType = G_OBJECT_TYPE (widget);
registry = atk_get_default_registry ();
factory = atk_registry_get_factory (registry, widgetType);
if (ATK_IS_NO_OP_OBJECT_FACTORY(factory)) return;

factoryName = FACTORY_TYPENAME + getTypeName(widgetType);

if (g_type_from_name (factoryName) == 0) {
    /* register the factory */
    GTypeInfo typeInfo = new GTypeInfo ();
    typeInfo.base_init = GTypeInfo_base_init_factory.getAddress ();
    typeInfo.class_size = (short)AtkObjectFactoryClass_sizeof ();
    typeInfo.instance_size = (short)AtkObjectFactory_sizeof ();
    
    info = g_malloc (GTypeInfo.sizeof);
    memmove (info, typeInfo, GTypeInfo.sizeof);
    swtFactoryType = g_type_register_static
        (ATK_TYPE_OBJECT_FACTORY(), factoryName, info, 0);
    parentType = atk_object_factory_get_accessible_type(factory);
    atk_registry_set_factory_type (registry, widgetType,
        swtFactoryType);
}

ATK Factories are not the way to go anymore to extend already existing
accessible objects/containers, now that most moder ATK implementations
are not modules anymore. In fact, now I then I'm tempted to mark them as
deprecated on ATK itself. The only reason I didn't do that is that there
are still plenty of implementations using them, without no plans to port
that code (AFAIK).



Another thing: I tried investigating with Accerciser, but it hangs and
gives me the following error message:

WARNING **: AT-SPI: Error in GetItems, sender=(null), error=Did not
receive a reply. Possible causes include: the remote application did
not send a reply, the message bus security policy blocked the reply,
the reply timeout expired, or the network connection was broken.

I would appreciate it if someone could point me in the right
direction. Is the code provided correct? Is there something additional
we need to be doing to register with ATK?

On GTK3, the accessible implementation is public. We needed to ask that
when they stopped to use factories, so apps/toolkits providing custom
widgets could extend them. The poster boy at that moment was Evince. You
mention that you have a custom container, so I hope that you are just
extending GtkContainer. If that is the case this code could be used as
an example:

https://git.gnome.org/browse/evince/tree/libview/ev-view-accessible.c#n71

I hope this helps.

BR




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]