X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=registryd%2Fregistry.c;h=d3f1c6d578b82f88ce55769fe5794b283307f055;hb=9ef50cd056dcbc74caacca587f99b7892024dd42;hp=621c0d0d691a525d6fb88ebcb0e60dbc94182db7;hpb=1a4c66f1bdc9221df14ac9cb7545472ac3224506;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/registryd/registry.c b/registryd/registry.c index 621c0d0..d3f1c6d 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -45,6 +45,7 @@ static SpiListenerClass *spi_registry_parent_class; static GQuark _deactivate_quark = 0; static GQuark _activate_quark = 0; static GQuark _state_quark = 0; +static GQuark _state_changed_focused_quark = 0; int _dbg = 0; @@ -115,7 +116,11 @@ desktop_add_application (SpiDesktop *desktop, /* FIXME spi_init_any_object (&e.any_data, a); */ - spi_init_any_nil (&e.any_data); + spi_init_any_nil (&e.any_data, + e.source, + Accessibility_ROLE_DESKTOP_FRAME, + ""); + Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry), &e, &ev); bonobo_object_release_unref (a, &ev); @@ -130,7 +135,7 @@ desktop_remove_application (SpiDesktop *desktop, { BonoboObject *registry = BONOBO_OBJECT (data); Accessibility_Event e; - Accessibility_Accessible a; + /* Accessibility_Accessible a; FIXME */ CORBA_Environment ev; CORBA_exception_init (&ev); @@ -139,13 +144,16 @@ desktop_remove_application (SpiDesktop *desktop, e.source = BONOBO_OBJREF (desktop); e.detail1 = index; e.detail2 = 0; + /* FIXME a = Accessibility_Accessible_getChildAtIndex (BONOBO_OBJREF (desktop), index, &ev); - /* FIXME spi_init_any_object (&e.any_data, a); */ - spi_init_any_nil (&e.any_data); - Accessibility_Accessible_unref (a, &ev); + spi_init_any_nil (&e.any_data, + e.source, + Accessibility_ROLE_DESKTOP_FRAME, + ""); + /* Accessibility_Accessible_unref (a, &ev); */ Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry), &e, &ev); Accessibility_Desktop_unref (e.source, &ev); @@ -317,7 +325,7 @@ parse_event_type (EventTypeStruct *etype, const char *event_name) else { etype->minor = etype->major; - etype->detail = g_quark_from_static_string (""); //etype->major; + etype->detail = g_quark_from_static_string (""); /*etype->major;*/ } } else @@ -422,20 +430,31 @@ impl_accessibility_registry_register_global_event_listener ( } } +typedef struct { + gboolean remove_all; + Accessibility_EventListener listener; + EventTypeStruct etype; +} RemoveListenerClosure; + static SpiReEntrantContinue remove_listener_cb (GList * const *list, gpointer user_data) { SpiListenerStruct *ls = (SpiListenerStruct *) (*list)->data; CORBA_Environment ev; - Accessibility_EventListener listener = user_data; + RemoveListenerClosure *cl = user_data; CORBA_exception_init (&ev); - - if (CORBA_Object_is_equivalent (ls->listener, listener, &ev)) - { - spi_re_entrant_list_delete_link (list); - spi_listener_struct_free (ls, &ev); - } + + if (cl->remove_all || (((cl->etype.minor == ls->event_type_quark) || + (cl->etype.major == ls->event_type_quark)) && + cl->etype.type_cat == ls->event_type_cat ) ) + { + if (CORBA_Object_is_equivalent (ls->listener, cl->listener, &ev)) + { + spi_re_entrant_list_delete_link (list); + spi_listener_struct_free (ls, &ev); + } + } CORBA_exception_free (&ev); @@ -454,14 +473,18 @@ impl_accessibility_registry_deregister_global_event_listener_all ( int i; GList **lists[3]; SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + RemoveListenerClosure cl = { 0, }; lists[0] = ®istry->object_listeners; lists[1] = ®istry->window_listeners; lists[2] = ®istry->toolkit_listeners; + cl.remove_all = TRUE; + cl.listener = listener; + for (i = 0; i < sizeof (lists) / sizeof (lists[0]); i++) { - spi_re_entrant_list_foreach (lists [i], remove_listener_cb, listener); + spi_re_entrant_list_foreach (lists [i], remove_listener_cb, &cl); } } @@ -477,14 +500,16 @@ impl_accessibility_registry_deregister_global_event_listener ( CORBA_Environment *ev) { SpiRegistry *registry; - EventTypeStruct etype; + RemoveListenerClosure cl = { 0, }; registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - parse_event_type (&etype, (char *) event_name); + cl.remove_all = FALSE; + parse_event_type (&cl.etype, (char *) event_name); + cl.listener = listener; - spi_re_entrant_list_foreach (get_listener_list (registry, etype.type_cat), - remove_listener_cb, listener); + spi_re_entrant_list_foreach (get_listener_list (registry, cl.etype.type_cat), + remove_listener_cb, &cl); } @@ -577,7 +602,7 @@ typedef struct { CORBA_Environment *ev; Bonobo_Unknown source; EventTypeStruct etype; - Accessibility_Event e_out; + Accessibility_Event *e_out; } NotifyContext; static SpiReEntrantContinue @@ -609,12 +634,12 @@ notify_listeners_cb (GList * const *list, gpointer user_data) } #endif - ctx->e_out.source = ctx->source; + ctx->e_out->source = ctx->source; if ((*list) && (*list)->data == ls) { Accessibility_EventListener_notifyEvent ( - (Accessibility_EventListener) ls->listener, &ctx->e_out, ctx->ev); + (Accessibility_EventListener) ls->listener, ctx->e_out, ctx->ev); if (ctx->ev->_major != CORBA_NO_EXCEPTION) { DBG (1, g_warning ("Accessibility app error: exception during " @@ -654,11 +679,7 @@ registry_clone_notify_context (NotifyContext *ctx) new_ctx->etype.major = ctx->etype.major; new_ctx->etype.minor = ctx->etype.minor; new_ctx->etype.detail = ctx->etype.detail; - new_ctx->e_out.type = CORBA_string_dup (ctx->e_out.type); - new_ctx->e_out.source = ctx->e_out.source; - new_ctx->e_out.detail1 = ctx->e_out.detail1; - new_ctx->e_out.detail2 = ctx->e_out.detail2; - CORBA_any__copy (&(new_ctx->e_out.any_data), &(ctx->e_out.any_data)); + new_ctx->e_out = ORBit_copy_value (ctx->e_out, TC_Accessibility_Event); return new_ctx; } @@ -679,9 +700,20 @@ registry_flush_event_queue (SpiRegistry *registry, q_ctx->ev = ev; registry_emit_event (registry, q_ctx); } - bonobo_object_release_unref (q_ctx->source, NULL); + if (discard && + (q_ctx->etype.type_cat == ETYPE_OBJECT) && + (q_ctx->etype.major == _state_quark) && + (q_ctx->etype.minor == _state_changed_focused_quark)) { + registry->focus_object = q_ctx->source; +#ifdef SPI_QUEUE_DEBUG + fprintf (stderr, "discard!: set focus_object %p\n", registry->focus_object); +#endif + } + else { + bonobo_object_release_unref (q_ctx->source, NULL); + } CORBA_free ((void *)q_ctx->etype.event_name); - CORBA_free ((void *)q_ctx->e_out.type); + CORBA_free (q_ctx->e_out); g_free (q_ctx); } registry->is_queueing = FALSE; @@ -696,6 +728,7 @@ registry_timeout_flush_queue (gpointer data) fprintf (stderr, "timeout! flushing queue...\n"); #endif CORBA_exception_init (&ev); + registry->queue_handler_id = 0; registry_flush_event_queue (registry, FALSE, &ev); return FALSE; } @@ -721,14 +754,57 @@ registry_reset_on_event (SpiRegistry *registry, NotifyContext *ctx) return (ctx->etype.type_cat == ETYPE_WINDOW) ? TRUE : FALSE; } +#ifdef SPI_QUEUE_DEBUG +#include +#endif + static void registry_start_queue (SpiRegistry *registry) { - g_timeout_add_full (G_PRIORITY_HIGH_IDLE, - registry->exit_notify_timeout, - registry_timeout_flush_queue, registry, - NULL); - registry->is_queueing = 1; +#ifdef SPI_QUEUE_DEBUG + struct timeval tp; + gettimeofday (&tp, NULL); + fprintf (stderr, "start queueing at %i.%.6i\n", tp.tv_sec, tp.tv_usec); +#endif + if (registry->queue_handler_id != 0) + g_source_remove (registry->queue_handler_id); + + if (registry->focus_object) + { +#ifdef SPI_QUEUE_DEBUG + fprintf (stderr, "registry_start_queue: release focus_object %p\n", registry->focus_object); +#endif + bonobo_object_release_unref (registry->focus_object, NULL); + registry->focus_object = NULL; + } + registry->queue_handler_id = g_timeout_add_full (G_PRIORITY_HIGH_IDLE, + registry->exit_notify_timeout, + registry_timeout_flush_queue, registry, + NULL); + registry->is_queueing = TRUE; +} + +static gboolean +registry_discard_event (SpiRegistry *registry, NotifyContext *ctx) +{ + gboolean ret = FALSE; + + if (ctx->etype.type_cat == ETYPE_FOCUS) + { + if (registry->focus_object) + { + if (CORBA_Object_is_equivalent (registry->focus_object, ctx->source, NULL)) + { + ret = TRUE; + } +#ifdef SPI_QUEUE_DEBUG + fprintf (stderr, "registry_discard_event: release focus_object %p\n", registry->focus_object); +#endif + bonobo_object_release_unref (registry->focus_object, NULL); + registry->focus_object = NULL; + } + } + return ret; } static gboolean @@ -741,22 +817,33 @@ registry_defer_on_event (SpiRegistry *registry, NotifyContext *ctx) registry_start_queue (registry); } /* defer all object:state-change events after a window:deactivate */ - else if ((ctx->etype.type_cat == ETYPE_OBJECT) && - (ctx->etype.major == _state_quark)) { + else if ((ctx->etype.type_cat == ETYPE_FOCUS) || + ((ctx->etype.type_cat == ETYPE_OBJECT) && + (ctx->etype.major == _state_quark))) { defer = TRUE; } return defer; } -static void +static gboolean registry_queue_event (SpiRegistry *registry, NotifyContext *ctx) { - NotifyContext *q_ctx = registry_clone_notify_context (ctx); #ifdef SPI_QUEUE_DEBUG - if (q_ctx->etype.type_cat != ETYPE_MOUSE) - fprintf (stderr, "push! %s %p\n", q_ctx->etype.event_name, q_ctx); + if (ctx->etype.type_cat != ETYPE_MOUSE) + fprintf (stderr, "push! %s %p\n", ctx->etype.event_name, ctx); #endif - g_queue_push_head (registry->deferred_event_queue, q_ctx); + if (registry->is_queueing) + { + NotifyContext *q_ctx = registry_clone_notify_context (ctx); + + g_queue_push_head (registry->deferred_event_queue, q_ctx); + + return FALSE; + } + else + { + return TRUE; + } } /** @@ -772,14 +859,14 @@ static gboolean registry_filter_event (SpiRegistry *registry, NotifyContext *ctx, CORBA_Environment *ev) { - gboolean queue_is_empty = FALSE; g_assert (ctx != NULL); - /* case #1 is not yet used */ + if (registry_discard_event (registry, ctx)) + return FALSE; + if (registry_defer_on_event (registry, ctx)) { /* #2, #3 */ if (registry->is_queueing) { - registry_queue_event (registry, ctx); - return FALSE; + return registry_queue_event (registry, ctx); } else { /* #4a */ return TRUE; @@ -790,6 +877,11 @@ registry_filter_event (SpiRegistry *registry, NotifyContext *ctx, #ifdef SPI_QUEUE_DEBUG fprintf (stderr, "event %s caused reset, discard=%d\n", ctx->etype.event_name, (int) discard); + { + struct timeval tp; + gettimeofday (&tp, NULL); + fprintf (stderr, "event at %i.%.6i\n", tp.tv_sec, tp.tv_usec); + } #endif registry_flush_event_queue (registry, discard, ev); return (discard ? FALSE : TRUE); @@ -814,16 +906,17 @@ impl_registry_notify_event (PortableServer_Servant servant, parse_event_type (&ctx.etype, e->type); ctx.ev = ev; - ctx.e_out = *e; + ctx.e_out = (Accessibility_Event *)e; ctx.source = e->source; +#ifdef SPI_QUEUE_DEBUG + if (ctx.etype.type_cat != ETYPE_MOUSE) + fprintf (stderr, "filter! %s level: %d\n", ctx.etype.event_name, level); +#endif if (registry_filter_event (registry, &ctx, ev)) { #ifdef SPI_QUEUE_DEBUG if (ctx.etype.type_cat != ETYPE_MOUSE) -{ fprintf (stderr, "emit! %s level: %d\n", ctx.etype.event_name, level); - fprintf (stderr, "emit! %p %p\n", ctx.e_out, ctx.e_out.type); -} #endif registry_emit_event (registry, &ctx); } @@ -854,6 +947,7 @@ spi_registry_class_init (SpiRegistryClass *klass) _deactivate_quark = g_quark_from_static_string ("deactivate"); _activate_quark = g_quark_from_static_string ("activate"); _state_quark = g_quark_from_static_string ("state-changed"); + _state_changed_focused_quark = g_quark_from_static_string ("state-changedfocused"); } static void @@ -871,7 +965,16 @@ spi_registry_init (SpiRegistry *registry) registry->window_listeners = NULL; registry->toolkit_listeners = NULL; registry->deferred_event_queue = g_queue_new (); - registry->exit_notify_timeout = 100; + registry->exit_notify_timeout = 200; + registry->queue_handler_id = 0; + /* + * The focus_object is set when a state-change:focused event is discarded + * after a window:deactivate event is received because a window:activate + * event has been received for the same window within the timeout period. + * The focus object is used to suppress a focus event for that object. + * It is released when a window:deactivate event is received. + */ + registry->focus_object = NULL; registry->desktop = spi_desktop_new (); /* Register callback notification for application addition and removal */ g_signal_connect (G_OBJECT (registry->desktop),