Index: gnopernicus/srcore/default.xml.in
===================================================================
RCS file: /cvs/gnome/gnopernicus/srcore/default.xml.in,v
retrieving revision 1.19
diff -u -r1.19 default.xml.in
--- gnopernicus/srcore/default.xml.in	29 Jul 2004 13:12:17 -0000	1.19
+++ gnopernicus/srcore/default.xml.in	3 Aug 2004 11:02:13 -0000
@@ -630,6 +630,9 @@
           <_literal voice="system">titleize window</_literal>
           <attribute type="string" voice="name">name</attribute>
         </event>
+        <event name="object:context-switched">
+          <attribute type="string" voice="name">name</attribute>
+        </event>
       </role>
       <role name="label">
         <event name="generic">
Index: gnopernicus/srcore/verbose.xml.in
===================================================================
RCS file: /cvs/gnome/gnopernicus/srcore/verbose.xml.in,v
retrieving revision 1.19
diff -u -r1.19 verbose.xml.in
--- gnopernicus/srcore/verbose.xml.in	29 Jul 2004 13:12:17 -0000	1.19
+++ gnopernicus/srcore/verbose.xml.in	3 Aug 2004 11:02:18 -0000
@@ -635,6 +635,9 @@
           <_literal voice="system">titleize window</_literal>
           <attribute type="string" voice="name">name</attribute>
         </event>
+        <event name="object:context-switched">
+          <attribute type="string" voice="name">name</attribute>
+        </event>
       </role>
       <role name="label">
         <event name="generic">
Index: gnopernicus/srlow/libsrlow/SRLow.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srlow/libsrlow/SRLow.c,v
retrieving revision 1.98
diff -u -r1.98 SRLow.c
--- gnopernicus/srlow/libsrlow/SRLow.c	2 Aug 2004 10:50:48 -0000	1.98
+++ gnopernicus/srlow/libsrlow/SRLow.c	3 Aug 2004 11:02:29 -0000
@@ -74,6 +74,7 @@
 #define SRL_EVENT_NAME_CHILDREN_REMOVED         "object:children-changed:remove"
 #define SRL_EVENT_NAME_TAB_ADDED                "object:tab-added"
 #define SRL_EVENT_NAME_TAB_REMOVED              "object:tab-removed"
+#define SRL_EVENT_NAME_CONTEXT_SWITCHED         "object:context-switched"
 
 #define SRL_TOOLKIT_MOZILLA			"mozilla"
 #define SRL_APP_METACITY			"metacity"
@@ -116,8 +117,7 @@
     SRL_EVENT_CHILDREN_REMOVED,
     SRL_EVENT_TAB_ADDED,
     SRL_EVENT_TAB_REMOVED,
-    
-
+    SRL_EVENT_CONTEXT_SWITCHED,
     SRL_EVENT_WINDOW_RENAME
 }SRLEventType;
 
@@ -195,6 +195,7 @@
 static Accessible		*srl_last_focus		= NULL;
 static Accessible		*srl_watched_acc	= NULL;
 static Accessible 		*srl_last_table 	= NULL;
+static Accessible 		*srl_last_context 	= NULL;
 /*FIXME:next varaible should be in SRObject.c file */
 Accessible 			*srl_last_edit		= NULL;
 
@@ -510,7 +511,8 @@
 
     if (event->acc)
 	Accessible_unref (event->acc);
-    AccessibleEvent_unref (event->acc_ev);
+    if (event->acc_ev)
+	AccessibleEvent_unref (event->acc_ev);
     g_free (event);
 }
 
@@ -711,6 +713,8 @@
 	return SRL_EVENT_NAME_FOCUS;
     if (srle_has_type (event, SRL_EVENT_FOCUS2))
 	return SRL_EVENT_NAME_FOCUS;
+    if (srle_has_type (event, SRL_EVENT_CONTEXT_SWITCHED))
+	return SRL_EVENT_NAME_CONTEXT_SWITCHED;
 
     srl_assert_not_reached ();
     return SRL_EVENT_NAME_UNKNOWN;
@@ -734,6 +738,7 @@
 	    event->type == SRL_EVENT_WINDOW_DEACTIVATE ||
 	    event->type == SRL_EVENT_WINDOW_RENAME ||
 	    event->type == SRL_EVENT_TAB_ADDED ||
+	    event->type == SRL_EVENT_CONTEXT_SWITCHED ||
 	    event->type == SRL_EVENT_TAB_REMOVED;
 }
 static gboolean
@@ -995,7 +1000,7 @@
 		sro_set_difference (obj, diff);
 	    SPI_freeString (diff);
 	}
-	if (srl_is_window_event (event))
+	if (srl_is_window_event (event) && event->type != SRL_EVENT_CONTEXT_SWITCHED)
 	{
 	    gchar *name = AccessibleWindowEvent_getTitleString (event->acc_ev);
 	    if (name)
@@ -1681,6 +1686,67 @@
     return TRUE;
 }
 
+#define SRL_MAX_LEVELS_UP 5
+static gboolean
+srl_check_context_changed (SRLEvent *event)
+{
+    Accessible *acc, *context;
+    gint i;
+
+    srl_assert (event);
+
+    acc = event->acc_ev->source;
+    Accessible_ref (acc);
+    context = NULL;
+    for (i = 0; i < SRL_MAX_LEVELS_UP; i++)
+    {
+	Accessible *parent = Accessible_getParent (acc);
+	if (parent)
+	{
+	    Accessible_unref (acc);
+	    acc = parent;
+	    if (Accessible_getRole (acc) == SPI_ROLE_EMBEDDED)
+	    {
+		context = acc;
+		Accessible_ref (context);
+		break;
+	    }
+	}
+	else
+	    break;
+    }
+    if (acc)
+	Accessible_unref (acc);
+    if (context)
+    {
+	if (context != srl_last_context)
+	{
+	    SRLEvent *ev;
+	    if (srl_last_context)
+		Accessible_unref (srl_last_context);
+	    srl_last_context = context;
+	    ev = srle_new ();
+	    ev->acc = srl_last_context;
+	    Accessible_ref (srl_last_context);
+	    ev->type = SRL_EVENT_CONTEXT_SWITCHED;
+	    srl_notify_clients_obj (ev, SR_EVENT_WINDOW);
+	    srle_free (ev);
+	}
+	else
+	{
+	    Accessible_unref (context);
+	}
+    }
+    else
+    {
+	if (srl_last_context)
+	    Accessible_unref (srl_last_context);
+	srl_last_context = NULL;    
+    }
+    return TRUE;
+}
+
+
 static gboolean
 srl_process_event (SRLEvent *event)
 {
@@ -1693,6 +1759,9 @@
     srle_change_type (event);
     process = srl_event_is_reported (event);
 
+    if (srle_has_type (event, SRL_EVENT_FOCUS))
+	srl_check_context_changed (event);
+
     if (srle_has_type (event, SRL_EVENT_FOCUS) ||
 	srle_has_type (event, SRL_EVENT_FOCUS2))
 	    srl_set_last_focus ((Accessible*)srle_get_acc (event));
@@ -1776,6 +1845,7 @@
     srl_idle_installed	= FALSE;
     srl_watched_acc	= NULL;
     srl_last_table	= NULL;
+    srl_last_context 	= NULL;
     
     srl_log_init ();
     srl_timing_init ();
@@ -1838,6 +1908,8 @@
 	Accessible_unref (srl_watched_acc);
     if (srl_last_table)
 	Accessible_unref (srl_last_table);
+    if (srl_last_context)
+	Accessible_unref (srl_last_context);
     srl_log_terminate ();
     srl_timing_terminate ();
     srl_set_uninitialized ();
