From: padraigo Date: Fri, 5 Sep 2003 15:13:26 +0000 (+0000) Subject: 2003-09-05 Padraig O'Briain X-Git-Tag: AT_SPI2_ATK_2_12_0~1145 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=99f0f510b665fb2298bc8cdd6613e384e445406b 2003-09-05 Padraig O'Briain * registryd/registry.[ch}: Add queue_handler_id and focus_object to SpiRegistry data structure. (registry_flush_event_queue): If event being discarded is "state-change:focused" store object as focus_object. (registry_start_queue): Remove queue handler and focus object if present. (registry_discard_event): New function which discards a focus event if we had stored focus object in the registry. (registry_queue_event): Add new check that is_queueing is set as this function is reentrant. (registry_filer_event): Add call to registry_discard_event. This resolves issues raised in bug #108664. git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@544 e2bd861d-eb25-0410-b326-f6ed22b6b98c --- diff --git a/ChangeLog b/ChangeLog index 80eb8d9..2ef6b39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2003-09-05 Padraig O'Briain + + * registryd/registry.[ch}: + Add queue_handler_id and focus_object to SpiRegistry data structure. + (registry_flush_event_queue): If event being discarded is + "state-change:focused" store object as focus_object. + (registry_start_queue): Remove queue handler and focus object + if present. + (registry_discard_event): New function which discards a focus event + if we had stored focus object in the registry. + (registry_queue_event): Add new check that is_queueing is set as this + function is reentrant. + (registry_filer_event): Add call to registry_discard_event. + + This resolves issues raised in bug #108664. + 2003-09-05 Taneem Ahmed * configure.in: Added "bn" to ALL_LINGUAS. diff --git a/registryd/registry.c b/registryd/registry.c index 70bb7f5..31dbb81 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; @@ -679,7 +680,18 @@ 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); g_free (q_ctx); @@ -696,6 +708,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 +734,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 @@ -749,7 +805,7 @@ registry_defer_on_event (SpiRegistry *registry, NotifyContext *ctx) return defer; } -static void +static gboolean registry_queue_event (SpiRegistry *registry, NotifyContext *ctx) { NotifyContext *q_ctx = registry_clone_notify_context (ctx); @@ -757,7 +813,20 @@ registry_queue_event (SpiRegistry *registry, NotifyContext *ctx) if (q_ctx->etype.type_cat != ETYPE_MOUSE) fprintf (stderr, "push! %s %p\n", q_ctx->etype.event_name, q_ctx); #endif - g_queue_push_head (registry->deferred_event_queue, q_ctx); + if (registry->is_queueing) + { + g_queue_push_head (registry->deferred_event_queue, q_ctx); + + return FALSE; + } + 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); + g_free (q_ctx); + return TRUE; + } } /** @@ -775,11 +844,12 @@ registry_filter_event (SpiRegistry *registry, NotifyContext *ctx, { 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 +860,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); @@ -817,13 +892,14 @@ impl_registry_notify_event (PortableServer_Servant servant, ctx.e_out = *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 %x\n", ctx.e_out, ctx.e_out.type); -} #endif registry_emit_event (registry, &ctx); } @@ -854,6 +930,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 +948,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), diff --git a/registryd/registry.h b/registryd/registry.h index 9254543..166a0d0 100644 --- a/registryd/registry.h +++ b/registryd/registry.h @@ -50,6 +50,8 @@ struct _SpiRegistry { GQueue *deferred_event_queue; gboolean is_queueing; guint exit_notify_timeout; + guint queue_handler_id; + Bonobo_Unknown focus_object; SpiDEController *de_controller; SpiDesktop *desktop; };