Index: Test/AtkTest/EventCollection.cs
===================================================================
--- Test/AtkTest/EventCollection.cs	(revision 126759)
+++ Test/AtkTest/EventCollection.cs	(working copy)
@@ -74,6 +74,11 @@
 			return new EventCollection (this.FindAll (delegate (AtSpiEvent ev) { return ev.Type == type; }), originalRepr);
 		}
 		
+		public EventCollection FindByName (string name)
+		{
+			return new EventCollection (this.FindAll (delegate (AtSpiEvent ev) { return ev.SourceName == name; }), originalRepr);
+		}
+		
 		public EventCollection FindByRole (Atk.Role role)
 		{
 			return new EventCollection (this.FindAll (delegate (AtSpiEvent ev) { return ev.SourceRole == role; }), originalRepr);
Index: Test/AtkTest/AtkTests.cs
===================================================================
--- Test/AtkTest/AtkTests.cs	(revision 126759)
+++ Test/AtkTest/AtkTests.cs	(working copy)
@@ -1367,6 +1367,18 @@
 				Atk.StateType.Visible);
 		}
 		
+		[Test]
+		public void Bug445210 ()
+		{
+				StartEventMonitor ();
+			object f = ActivateAdditionalForm ("445210");
+			ExpectEvents (1, Atk.Role.Frame, "window:activate", "445210");
+			ExpectEvents (0, Atk.Role.Frame, "window:activate", "UiaAtkBridge test");
+			StartEventMonitor ();
+			RemoveAdditionalForm (f);
+			ExpectEvents (1, Atk.Role.Frame, "window:activate", "MainWindow");
+			ExpectEvents (0, Atk.Role.Frame, "window:activate", "445210");
+		}
 		public void HSplitter (Atk.Object accessible)
 		{
 			BasicWidgetType type = BasicWidgetType.HSplitContainer;
Index: Test/AtkTest/ChangeLog
===================================================================
--- Test/AtkTest/ChangeLog	(revision 126759)
+++ Test/AtkTest/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2009-02-13  Mike Gorse <mgorse@novell.com>
+
+	* AtkTester.cs, EventCollection.cs: Allow fetching events by name.
+
+	* AtkTester.cs, AtkTests.cs: Add test for bug 445210.
+
 2009-02-11  Mike Gorse <mgorse@novell.com>
 
 	* AtkTester.cs: Expect TreeTable for a ListBox.
Index: Test/AtkTest/AtkTester.cs
===================================================================
--- Test/AtkTest/AtkTester.cs	(revision 126759)
+++ Test/AtkTest/AtkTester.cs	(working copy)
@@ -71,6 +71,8 @@
 
 		public abstract void ExpandTreeView (BasicWidgetType type);
 		public abstract void CollapseTreeView (BasicWidgetType type);
+		public abstract object ActivateAdditionalForm (string name);
+		public abstract void RemoveAdditionalForm (object obj);
 
 		public abstract Atk.Object GetTopLevelRootItem ();
 
@@ -2118,6 +2120,15 @@
 			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
 		}
 
+		protected void ExpectEvents (int count, Atk.Role role, string evType, string name)
+		{
+			if (events == null)
+				events = EventMonitor.Pause ();
+			EventCollection evs = events.FindByRole (role).FindByType (evType).FindByName (name);
+			string eventsInXml = String.Format (" events in XML: {0}", Environment.NewLine + events.OriginalGrossXml);
+			Assert.AreEqual (count, evs.Count, "bad number of " + evType + " events: " + eventsInXml);
+		}
+
 		protected void ExpectEvents (int min, int max, Atk.Role role, string evType)
 		{
 			if (events == null)
Index: Test/UiaAtkBridgeTest/BridgeTester.cs
===================================================================
--- Test/UiaAtkBridgeTest/BridgeTester.cs	(revision 126759)
+++ Test/UiaAtkBridgeTest/BridgeTester.cs	(working copy)
@@ -231,7 +231,7 @@
 			form.Controls.Add (flp);
 			form.Controls.Add (tlp);
 			form.Controls.Add (containerControl);
-			form.Text = "UiaAtkBridge test";
+			form.Text = "MainWindow";
 			SWF.Application.EnableVisualStyles ();
 		}
 		
@@ -355,6 +355,23 @@
 			treeView.CollapseAll ();
 		}
 
+		public override object ActivateAdditionalForm (string name)
+		{
+			SWF.Form f = new SWF.Form ();
+			f.Text = name;
+			SWF.Button button = new SWF.Button ();
+			f.Controls.Add (button);
+			f.Show ();
+			button.Focus ();
+			return f;
+		}
+
+		public override void RemoveAdditionalForm (object obj)
+		{
+			SWF.Form f = (SWF.Form)obj;
+			f.Close ();
+			butWithImage.Focus ();
+		}
 		public override object CastToAtkInterface (Type t, Atk.Object accessible)
 		{
 			if (t == typeof (Atk.Action)) {
Index: Test/UiaAtkBridgeTest/ChangeLog
===================================================================
--- Test/UiaAtkBridgeTest/ChangeLog	(revision 126759)
+++ Test/UiaAtkBridgeTest/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2009-02-12  Mike Gorse  <mgorse@novell.com>
+
+	* BridgeTester.cs: Add test for bug 445210.
+
+	* BridgeTester.cs: Change window name to match gail test app.
+
 2009-02-11  Mike Gorse  <mgorse@novell.com>
 
 	* BridgeTests.cs: Separate Items.Clear tests for StatusStrip and
Index: Test/GailTest/ChangeLog
===================================================================
--- Test/GailTest/ChangeLog	(revision 126759)
+++ Test/GailTest/ChangeLog	(working copy)
@@ -1,3 +1,7 @@
+2009-02-13  Mike Gorse  <mgorse@novell.com>
+
+	* gailtester.cs: Add test for bug 445210.
+
 2009-02-09  Andrés G. Aragoneses  <aaragoneses@novell.com>
 
 	* GailTester.cs: New tests prepared for the event of the menu
Index: Test/GailTest/GailTester.cs
===================================================================
--- Test/GailTest/GailTester.cs	(revision 126759)
+++ Test/GailTest/GailTester.cs	(working copy)
@@ -125,6 +125,25 @@
 			});
 		}
 
+		public override object ActivateAdditionalForm (string name)
+		{
+			Gtk.Window win = new Gtk.Window (name);
+			Gtk.Button button = new Gtk.Button ("test");
+			win.Add (button);
+			RunInGuiThread (delegate () {
+				win.Show ();
+				button.GrabFocus ();
+			});
+			return win;
+		}
+
+		public override void RemoveAdditionalForm (object obj)
+		{
+			Gtk.Window win = (Gtk.Window)obj;
+			win.Hide ();
+			GailTestApp.MainClass.GiveMeARealButton (true).GrabFocus ();
+		}
+
 		public override void EnableWidget (Atk.Object accessible)
 		{
 			RunInGuiThread (delegate () {
Index: UiaAtkBridge/TopLevelRootItem.cs
===================================================================
--- UiaAtkBridge/TopLevelRootItem.cs	(revision 126759)
+++ UiaAtkBridge/TopLevelRootItem.cs	(working copy)
@@ -53,12 +53,6 @@
 			}
 		}
 
-		public void SendWindowActivate ()
-		{
-			if (currentActiveWindow != null)
-				GLib.Signal.Emit (currentActiveWindow, "activate");
-		}
-
 		private UiaAtkBridge.Window currentActiveWindow = null;
 		
 		internal override void AddOneChild (Atk.Object child)
@@ -75,9 +69,16 @@
 			if (currentActiveWindow != null)
 				currentActiveWindow.LoseActiveState ();
 			currentActiveWindow = newWin;
-			currentActiveWindow.GainActiveState ();
+			if (currentActiveWindow != null)
+				currentActiveWindow.GainActiveState ();
 		}
 		
+		internal void WindowDeactivated (Window win)
+		{
+			if (object.ReferenceEquals (currentActiveWindow, win))
+				currentActiveWindow = null;
+		}
+
 		public override void RaiseStructureChangedEvent (object provider, StructureChangedEventArgs e)
 		{
 			// TODO
Index: UiaAtkBridge/ChangeLog
===================================================================
--- UiaAtkBridge/ChangeLog	(revision 126759)
+++ UiaAtkBridge/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+	2009-02-13  Mike Gorse  <mgorse@novell.com>
+
+	* Adapter.cs, AutomationBridge.cs, TopLevelRootItem.cs, Window.cs:
+	  Rework emission of activate signals [bug 445210].
+
 	2009-02-11  Mike Gorse  <mgorse@novell.com>
 
 	* AutomationBridge.cs, Tree.cs: Use TreeTable code for ListBox.
Index: UiaAtkBridge/Window.cs
===================================================================
--- UiaAtkBridge/Window.cs	(revision 126759)
+++ UiaAtkBridge/Window.cs	(working copy)
@@ -222,13 +222,18 @@
 
 		private void NewActiveState (bool active)
 		{
+			if (this.active == active)
+				return;
 			this.active = active;
 			NotifyStateChange (Atk.StateType.Active, active);
+			if (active)
+				GLib.Signal.Emit (this, "activate");
 		}
 		
 		internal void LoseActiveState ()
 		{
 			NewActiveState (false);
+			TopLevelRootItem.Instance.WindowDeactivated (this);
 		}
 
 		internal void GainActiveState ()
Index: UiaAtkBridge/Adapter.cs
===================================================================
--- UiaAtkBridge/Adapter.cs	(revision 126759)
+++ UiaAtkBridge/Adapter.cs	(working copy)
@@ -48,8 +48,6 @@
 
 #region Adapter Methods
 	
-		static long lastFocusLossTime = System.DateTime.Now.Ticks;
-
 		protected void NotifyStateChange (Atk.StateType state) {
 			NotifyStateChange (state, RefStateSet ().ContainsState (state));
 		}
@@ -81,7 +79,6 @@
 		
 		public virtual void RaiseAutomationPropertyChangedEvent (AutomationPropertyChangedEventArgs e)
 		{
-			long curTime = System.DateTime.Now.Ticks;
 			if (e.Property == AutomationElementIdentifiers.HasKeyboardFocusProperty) {
 				bool canFocus = (bool) Provider.GetPropertyValue (
 				     AutomationElementIdentifiers.IsKeyboardFocusableProperty.Id);
@@ -93,14 +90,22 @@
 				// Hack -- we get the window activate event
 				// event after a focus event, which isn't the
 				// order we want.
-				if (focused && (curTime - lastFocusLossTime > 1000000))
-					TopLevelRootItem.Instance.SendWindowActivate ();
+				if (focused) {
+					Atk.Object container = Parent;
+					while (container != null) {
+						if (container is Window) {
+							Window window = (Window)container;
+							TopLevelRootItem.Instance.CheckAndHandleNewActiveWindow (window);
+							//window.GainActiveState ();
+							break;
+						}
+						container = container.Parent;
+					}
+				}
 
 				NotifyStateChange (Atk.StateType.Focused, focused);
 				if (focused)
 					Atk.Focus.TrackerNotify (this);
-				else
-					lastFocusLossTime = curTime;
 			} else if (e.Property == AutomationElementIdentifiers.IsOffscreenProperty) { 
 				bool offscreen = (bool)e.NewValue;
 				NotifyStateChange (Atk.StateType.Visible, !offscreen);
Index: UiaAtkBridge/AutomationBridge.cs
===================================================================
--- UiaAtkBridge/AutomationBridge.cs	(revision 126759)
+++ UiaAtkBridge/AutomationBridge.cs	(working copy)
@@ -809,7 +809,6 @@
 			pointerProviderMapping [providerHandle] = provider;
 
 			GLib.Signal.Emit (newWindow, "create");
-			GLib.Signal.Emit (newWindow, "activate");
 			
 			windowProviders++;
 		}
