Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.241
diff -p -u -r1.241 display.c
--- src/display.c	23 Dec 2004 06:44:56 -0000	1.241
+++ src/display.c	23 Dec 2004 22:19:16 -0000
@@ -1821,10 +1821,31 @@ event_callback (XEvent   *event,
     case FocusOut:
       if (window)
         {
-          meta_window_notify_focus (window, event);
+          if (!serial_is_ignored (display, event->xany.serial))
+            meta_window_notify_focus (window, event);
         }
       else if (event->xany.window == display->no_focus_window)
         {
+          /* In mouse focus mode, if the double-click-on-titlebar
+	   * action is set to shade/unshade, then double-clicking on a
+	   * window followed by moving the mouse outside the frame
+	   * will /sometimes/ NOT generate a FocusOut event for that
+	   * window, yet a FocusIn is generated for the
+	   * no_focus_window.  This isn't just because of an
+	   * accidentally ignored serial either--there really is a
+	   * missing FocusOut.  (I've observed the missing FocusOut
+	   * with emacs, but not with gnome-terminal, so perhaps the
+	   * braindead toolkit emacs is using is somehow causing
+	   * issues) Anyway, in this case, we manually unfocus the
+	   * window.  See bug 90290.
+           */
+          if (display->focus_window != NULL && event->type == FocusIn)
+            {
+              XEvent fake_xevent;
+              fake_xevent = *event;
+              fake_xevent.type = FocusOut;
+              meta_window_notify_focus (display->focus_window, &fake_xevent);
+            }
           meta_topic (META_DEBUG_FOCUS,
                       "Focus %s event received on no_focus_window 0x%lx "
                       "mode %s detail %s\n",
@@ -1908,10 +1929,14 @@ event_callback (XEvent   *event,
     case UnmapNotify:
       if (window)
         {
-          if (display->grab_op != META_GRAB_OP_NONE &&
-              display->grab_window == window)
-            meta_display_end_grab_op (display, CurrentTime);      
+          if (window->shaded)
+            add_ignored_serial (display, event->xany.serial);
       
+          if (display->grab_op != META_GRAB_OP_NONE &&
+              display->grab_window == window &&
+              !window->shaded)
+            meta_display_end_grab_op (display, CurrentTime);
+
           if (!frame_was_receiver)
             {
               if (window->unmaps_pending == 0)
@@ -1936,7 +1961,7 @@ event_callback (XEvent   *event,
            * window_free above so that window_free can see if window->has_focus
            * and move focus to another window
            */
-          if (window)
+          if (window && !window->shaded)
             meta_window_notify_focus (window, event);
         }
       break;
