Accessibility problem with custom GtkWidget
- From: Gabor Karsay <gabor karsay gmx at>
- To: gnome-accessibility-list gnome org
- Subject: Accessibility problem with custom GtkWidget
- Date: Sun, 13 Jan 2019 15:46:30 +0100
Hello,
I'm an accessibility newbie asking for some help (a hint would be
enough) with a custom GtkWidget. As I planned to add some Atspi
functionality I found out that my widget is "disturbing"
AtspiEventListener. When there is an AtspiEventListener and I open a
window with my widget and close it again, the listener emits a couple of
"g_object_unref: assertion 'G_IS_OBJECT (object)' failed" messages.
So obviously my widget is doing something wrong or probably doesn't do
something it should do. It's a composite widget: a GtkScrolledWindow
that is showing a couple of GtkDrawingAreas over each other in a
GtkOverlay. It looks like this:
https://gkarsay.github.io/parlatype/reference/PtWaveviewer.html
I'm not asking you to have a look at the widget code itself, just some
general advice what a custom widget should do. Have you seen something
like this before?
Just to clarify, I didn't do anything yet to improve accessibility. I
thought if the subwidgets are accessible, then the whole custom widget
is accessible.
I wrote a test case with a listener. It's just listening as long as the
window is open:
--------- test.c -----------
/* Compile:
gcc -g -o test test.c `pkg-config --libs --cflags gtk+-3.0 atspi-2`
*/
#include <gtk/gtk.h>
#include <atspi/atspi.h>
static void
on_event_cb (AtspiEvent *event,
void *user_data)
{
/* nothing */
}
static void
app_activate (GApplication *app,
gpointer user_data)
{
AtspiEventListener *listener;
GtkWidget *window;
listener = atspi_event_listener_new ((AtspiEventListenerCB)
on_event_cb, NULL, NULL);
atspi_event_listener_register (listener,
"object:state-changed:focused", NULL);
window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_present (GTK_WINDOW (window));
}
int main(int argc, gchar **argv)
{
GtkApplication *app;
gint status;
app = gtk_application_new ("org.example.test", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
----- test.c end ---------------
When I run the test (in Debian stable and unstable), open my widget
(Parlatype) and close it again, I get this from the test program:
(gdb) bt full
#0 0x00007ffff56de261 in _g_log_abort (breakpoint=breakpoint@entry=1)
at ././glib/gmessages.c:509
debugger_present = 1
#1 0x00007ffff56df66d in g_logv (log_domain=0x7ffff5e5e9b6
"GLib-GObject", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>,
args=args@entry=0x7fffffffdba0) at ././glib/gmessages.c:1318
domain = 0x0
data = 0x0
depth = 1
log_func = 0x7ffff56df1f0 <g_log_default_handler>
domain_fatal_mask = <optimized out>
masquerade_fatal = 0
test_level = 10
was_fatal = <optimized out>
was_recursion = <optimized out>
msg = 0x555555a4bdb0 "g_object_unref: assertion 'G_IS_OBJECT
(object)' failed"
msg_alloc = 0x555555a4bdb0 "g_object_unref: assertion
'G_IS_OBJECT (object)' failed"
i = 3
#2 0x00007ffff56df7cf in g_log (log_domain=<optimized out>,
log_level=<optimized out>, format=<optimized out>) at
././glib/gmessages.c:1359
args = {{gp_offset = 40, fp_offset = 48, overflow_arg_area =
0x7fffffffdc80, reg_save_area = 0x7fffffffdbc0}}
#3 0x00007ffff56aca9b in g_ptr_array_foreach (array=0x5555558f8100,
func=0x7ffff5e37ae0 <g_object_unref>, user_data=0x0) at
././glib/garray.c:1502
i = 2
#4 0x00007ffff56acb30 in ptr_array_free (array=0x5555558f8100,
flags=FREE_SEGMENT) at ././glib/garray.c:1088
rarray = 0x5555558f8100
segment = <optimized out>
#5 0x00007ffff56acba9 in g_ptr_array_free (array=<optimized out>,
free_segment=free_segment@entry=1) at ././glib/garray.c:1075
rarray = <optimized out>
flags = <optimized out>
__func__ = "g_ptr_array_free"
#6 0x00007ffff5c02395 in atspi_accessible_dispose
(object=0x5555558201a0 [AtspiAccessible]) at atspi-accessible.c:164
accessible = 0x5555558201a0 [AtspiAccessible]
e = {type = 0x7ffff5c14aa2 "object:state-changed:defunct",
source = 0x5555558201a0 [AtspiAccessible], detail1 = 1, detail2 = 0,
any_data = {g_type = 24, data = {{v_int = 0, v_uint = 0, v_long = 0,
v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0,
v_pointer = 0x0}, {v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0,
v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}}}}
parent = <optimized out>
i = -1
#7 0x00007ffff5e39648 in g_object_run_dispose (object=0x5555558201a0
[AtspiAccessible]) at ././gobject/gobject.c:1084
__func__ = "g_object_run_dispose"
#8 0x00007ffff5c0b3bc in handle_remove_accessible (bus=<optimized out>,
user_data=<optimized out>, message=<optimized out>) at atspi-misc.c:357
app = 0x555555a2a250 [AtspiApplication]
iter = {dummy1 = 0x5555558dd840, dummy2 = 0x7fff00600000,
dummy3 = 108, dummy4 = 0, dummy5 = 1435359304, dummy6 = 21845, dummy7 =
117, dummy8 = 0, dummy9 = 1435359376, dummy10 = 21845, dummy11 = 0, pad1
= 0, pad2 = 0x7ffff5befea0, pad3 = 0x0}
a = 0x5555558201a0 [AtspiAccessible]
sender = 0x55555585d934 ":1.31"
path = 0x55555585d940 "/org/a11y/atspi/accessible/5"
iter_struct = {dummy1 = 0x5555558dd840, dummy2 =
0x7fff00600000, dummy3 = 108, dummy4 = 0, dummy5 = 1435359304, dummy6 =
21845, dummy7 = 119, dummy8 = 0, dummy9 = 1435359376, dummy10 = 21845,
dummy11 = 10, pad1 = 0, pad2 = 0x7ffff5befe20, pad3 = 0x0}
signature = <optimized out>
type = <optimized out>
interface = <optimized out>
closure = 0x555555964330
in_process_deferred_messages = 1
#9 0x00007ffff5c0b3bc in process_deferred_message
(closure=0x555555964330) at atspi-misc.c:753
type = <optimized out>
interface = <optimized out>
closure = 0x555555964330
in_process_deferred_messages = 1
#10 0x00007ffff5c0b3bc in process_deferred_messages () at atspi-misc.c:774
closure = 0x555555964330
in_process_deferred_messages = 1
#11 0x00007ffff5c0b599 in process_deferred_messages () at atspi-misc.c:785
in_process_deferred_messages = 1
in_process_deferred_messages = 1
#12 0x00007ffff5c0b599 in process_deferred_messages_callback
(data=<optimized out>) at atspi-misc.c:786
#13 0x00007ffff56d86aa in g_main_dispatch (context=0x55555576e070) at
././glib/gmain.c:3203
dispatch = 0x7ffff56d50d0 <g_idle_dispatch>
prev_source = 0x0
was_in_call = 0
user_data = 0x0
callback = 0x7ffff5c0b580 <process_deferred_messages_callback>
cb_funcs = <optimized out>
cb_data = 0x555555903080
need_destroy = <optimized out>
source = 0x555555879730
current = 0x555555780320
i = 0
#14 0x00007ffff56d86aa in g_main_context_dispatch
(context=context@entry=0x55555576e070) at ././glib/gmain.c:3856
#15 0x00007ffff56d8a60 in g_main_context_iterate
(context=context@entry=0x55555576e070, block=block@entry=1,
dispatch=dispatch@entry=1, self=<optimized out>) at ././glib/gmain.c:3929
max_priority = 200
timeout = 0
some_ready = 1
nfds = 4
allocated_nfds = 4
fds = <optimized out>
#16 0x00007ffff56d8b0c in g_main_context_iteration
(context=context@entry=0x55555576e070, may_block=may_block@entry=1) at
././glib/gmain.c:3990
retval = <optimized out>
#17 0x00007ffff611572d in g_application_run (application=0x55555576c1a0
[GtkApplication], argc=1, argv=0x7fffffffe0d8) at
././gio/gapplication.c:2381
arguments = 0x555555762420
status = 0
context = 0x55555576e070
acquired_context = <optimized out>
__func__ = "g_application_run"
#18 0x0000555555554d50 in main (argc=1, argv=0x7fffffffe0d8) at test.c:52
app = 0x55555576c1a0 [GtkApplication]
status = 32767
--- backtrace end ----
Any advice is welcome. Is there some online How-do-I for improving
accessibility? I found only the API reference. It tells me how to do
something, but first I have to know what to do.
Thank you!
Gabor
[
Date Prev][
Date Next] [
Thread Prev][Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]