[metacity] display: clean up focus_window vs expected_focus_window



commit a2b02f69b56d622e08cf1aac29616d5f6c567930
Author: Dan Winship <danw gnome org>
Date:   Tue Apr 26 08:12:04 2011 -0400

    display: clean up focus_window vs expected_focus_window
    
    Mutter previously defined display->focus_window as the window that the
    server says is focused, but kept display->expected_focus_window to
    indicate the window that we have requested to be focused. But it turns
    out that "expected_focus_window" was almost always what we wanted.
    
    Make MetaDisplay do a better job of tracking focus-related requests
    and events, and change display->focus_window to be our best guess of
    the "currently" focused window (ie, the window that will be focused at
    the time when the server processes the next request we send it).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=647706

 src/core/display-private.h |   23 ++--
 src/core/display.c         |  261 +++++++++++++++++++++++++++++++++++++-------
 src/core/stack.c           |   10 +-
 src/core/window-private.h  |    7 +-
 src/core/window.c          |  167 ++--------------------------
 src/ui/select-workspace.c  |    4 +-
 6 files changed, 252 insertions(+), 220 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 018b251..a94f59c 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -95,19 +95,18 @@ struct _MetaDisplay
 #include "atomnames.h"
 #undef item
 
-  /* This is the actual window from focus events,
-   * not the one we last set
+  /* The window and serial of the most recent FocusIn event. */
+  Window server_focus_window;
+  gulong server_focus_serial;
+
+  /* Our best guess as to the "currently" focused window (that is, the
+   * window that we expect will be focused at the point when the X
+   * server processes our next request), and the serial of the request
+   * or event that caused this.
    */
   MetaWindow *focus_window;
 
-  /* window we are expecting a FocusIn event for or the current focus
-   * window if we are not expecting any FocusIn/FocusOut events; not
-   * perfect because applications can call XSetInputFocus directly.
-   * (It could also be messed up if a timestamp later than current
-   * time is sent to meta_display_set_input_focus_window, though that
-   * would be a programming error).  See bug 154598 for more info.
-   */
-  MetaWindow *expected_focus_window;
+  gulong focus_serial;
 
   /* last timestamp passed to XSetInputFocus */
   guint32 last_focus_time;
@@ -470,6 +469,10 @@ void meta_display_set_input_focus_window   (MetaDisplay *display,
                                             gboolean     focus_frame,
                                             guint32      timestamp);
 
+void meta_display_request_take_focus       (MetaDisplay *display,
+                                            MetaWindow  *window,
+                                            guint32      timestamp);
+
 /* meta_display_focus_the_no_focus_window is called when the
  * designated no_focus_window should be focused, but is otherwise the
  * same as meta_display_set_input_focus_window
diff --git a/src/core/display.c b/src/core/display.c
index 94b469d..9c0bbde 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -331,7 +331,9 @@ meta_display_open (void)
   the_display->autoraise_timeout_id = 0;
   the_display->autoraise_window = NULL;
   the_display->focus_window = NULL;
-  the_display->expected_focus_window = NULL;
+  the_display->focus_serial = 0;
+  the_display->server_focus_window = None;
+  the_display->server_focus_serial = 0;
   the_display->grab_old_window_stacking = NULL;
 
   the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
@@ -1436,6 +1438,162 @@ button_press_event_new (XEvent *xevent)
   return event;
 }
 
+static void
+set_focus_window (MetaDisplay *display,
+                  MetaWindow  *window,
+                  gulong       serial)
+{
+  display->focus_serial = serial;
+
+  if (window == display->focus_window)
+    return;
+
+  if (display->focus_window)
+    {
+      MetaWindow *previous;
+
+      meta_topic (META_DEBUG_FOCUS,
+                  "%s is now the previous focus window due to being focused out or unmapped\n",
+                  display->focus_window->desc);
+
+      /* Make sure that signals handlers invoked by
+       * meta_window_set_focused_internal() don't see
+       * display->focus_window->has_focus == FALSE
+       */
+      previous = display->focus_window;
+      display->focus_window = NULL;
+
+      meta_window_set_focused_internal (previous, FALSE);
+    }
+
+  display->focus_window = window;
+
+  if (display->focus_window)
+    {
+      meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n",
+                  display->focus_window->desc, serial);
+      meta_window_set_focused_internal (display->focus_window, TRUE);
+    }
+  else
+    meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial);
+
+  meta_compositor_set_active_window (display->compositor, window);
+  meta_display_update_active_window_hint (display);
+}
+
+static void
+handle_window_focus_event (MetaDisplay *display,
+                           MetaWindow  *window,
+                           XEvent      *event)
+{
+  MetaWindow *focus_window;
+#ifdef WITH_VERBOSE_MODE
+  const char *window_type;
+
+  /* Note the event can be on either the window or the frame,
+   * we focus the frame for shaded windows
+   */
+  if (window)
+    {
+      if (event->xany.window == window->xwindow)
+        window_type = "client window";
+      else if (window->frame && event->xany.window == window->frame->xwindow)
+        window_type = "frame window";
+      else
+        window_type = "unknown client window";
+    }
+  else if (meta_display_xwindow_is_a_no_focus_window (display, event->xany.window))
+    window_type = "no_focus_window";
+  else if (meta_display_screen_for_root (display, event->xany.window))
+    window_type = "root window";
+  else
+    window_type = "unknown window";
+
+  meta_topic (META_DEBUG_FOCUS,
+              "Focus %s event received on %s 0x%lx (%s) "
+              "mode %s detail %s serial %lu\n",
+              event->type == FocusIn ? "in" :
+              event->type == FocusOut ? "out" :
+              "???",
+              window ? window->desc : "",
+              event->xany.window, window_type,
+              meta_event_mode_to_string (event->xfocus.mode),
+              meta_event_detail_to_string (event->xfocus.detail),
+              event->xfocus.serial);
+#endif
+
+  /* FIXME our pointer tracking is broken; see how
+   * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c
+   * handle it for the correct way.  In brief you need to track
+   * pointer focus and regular focus, and handle EnterNotify in
+   * PointerRoot mode with no window manager.  However as noted above,
+   * accurate focus tracking will break things because we want to keep
+   * windows "focused" when using keybindings on them, and also we
+   * sometimes "focus" a window by focusing its frame or
+   * no_focus_window; so this all needs rethinking massively.
+   *
+   * My suggestion is to change it so that we clearly separate
+   * actual keyboard focus tracking using the xterm algorithm,
+   * and metacity's "pretend" focus window, and go through all
+   * the code and decide which one should be used in each place;
+   * a hard bit is deciding on a policy for that.
+   *
+   * http://bugzilla.gnome.org/show_bug.cgi?id=90382
+   */
+
+  /* We ignore grabs, though this is questionable. It may be better to
+   * increase the intelligence of the focus window tracking.
+   *
+   * The problem is that keybindings for windows are done with
+   * XGrabKey, which means focus_window disappears and the front of
+   * the MRU list gets confused from what the user expects once a
+   * keybinding is used.
+   */
+
+  if (event->xfocus.mode == NotifyGrab ||
+      event->xfocus.mode == NotifyUngrab ||
+      /* From WindowMaker, ignore all funky pointer root events */
+      event->xfocus.detail > NotifyNonlinearVirtual)
+    {
+      meta_topic (META_DEBUG_FOCUS,
+                  "Ignoring focus event generated by a grab or other weirdness\n");
+      return;
+    }
+
+  if (event->type == FocusIn)
+    {
+      display->server_focus_window = event->xany.window;
+      display->server_focus_serial = event->xfocus.serial;
+
+      if (window && window->override_redirect)
+        focus_window = NULL;
+      else
+        focus_window = window;
+    }
+  else if (event->type == FocusOut)
+    {
+      if (event->xfocus.detail == NotifyInferior)
+        {
+          /* This event means the client moved focus to a subwindow */
+          meta_topic (META_DEBUG_FOCUS,
+                      "Ignoring focus outwith NotifyInferior\n");
+          return;
+        }
+
+      display->server_focus_window = None;
+      display->server_focus_serial = event->xfocus.serial;
+      focus_window = NULL;
+    }
+  else
+    g_return_if_reached ();
+
+  if (display->server_focus_serial >= display->focus_serial)
+    {
+      set_focus_window (display, focus_window,
+                        display->server_focus_serial);
+    }
+}
+
 /**
  * This is the most important function in the whole program. It is the heart,
  * it is the nexus, it is the Grand Central Station of Metacity's world.
@@ -1479,6 +1637,17 @@ event_callback (XEvent   *event,
   display->current_time = event_get_time (display, event);
   display->xinerama_cache_invalidated = TRUE;
 
+  if (event->xany.serial > display->focus_serial &&
+      display->focus_window &&
+      display->focus_window->xwindow != display->server_focus_window)
+    {
+      meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
+                  display->focus_window->desc);
+      set_focus_window (display,
+                        meta_display_lookup_x_window (display, display->server_focus_window),
+                        display->server_focus_serial);
+    }
+
   modified = event_get_modified_window (display, event);
 
   if (event->type == ButtonPress)
@@ -1872,12 +2041,12 @@ event_callback (XEvent   *event,
                */
               if (window->type == META_WINDOW_DESKTOP &&
                   meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
-                  display->expected_focus_window != NULL)
+                  display->focus_window != NULL)
                 {
                   meta_topic (META_DEBUG_FOCUS,
                               "Unsetting focus from %s due to mouse entering "
                               "the DESKTOP window\n",
-                              display->expected_focus_window->desc);
+                              display->focus_window->desc);
                   meta_display_focus_the_no_focus_window (display,
                                                           window->screen,
                                                           event->xcrossing.time);
@@ -1908,38 +2077,14 @@ event_callback (XEvent   *event,
       break;
     case FocusIn:
     case FocusOut:
-      if (window)
-        {
-          meta_window_notify_focus (window, event);
-        }
-      else if (meta_display_xwindow_is_a_no_focus_window (display,
-                                                          event->xany.window))
-        {
-          meta_topic (META_DEBUG_FOCUS,
-                      "Focus %s event received on no_focus_window 0x%lx "
-                      "mode %s detail %s\n",
-                      event->type == FocusIn ? "in" :
-                      event->type == FocusOut ? "out" :
-                      "???",
-                      event->xany.window,
-                      meta_event_mode_to_string (event->xfocus.mode),
-                      meta_event_detail_to_string (event->xfocus.detail));
-        }
-      else
+      handle_window_focus_event (display, window, event);
+
+      if (!window)
         {
+          /* Check if the window is a root window. */
           if (event->xany.window != screen->xroot)
             break;
 
-          meta_topic (META_DEBUG_FOCUS,
-                      "Focus %s event received on root window 0x%lx "
-                      "mode %s detail %s\n",
-                      event->type == FocusIn ? "in" :
-                      event->type == FocusOut ? "out" :
-                      "???",
-                      event->xany.window,
-                      meta_event_mode_to_string (event->xfocus.mode),
-                      meta_event_detail_to_string (event->xfocus.detail));
-
           if (event->type == FocusIn &&
               event->xfocus.detail == NotifyDetailNone)
             {
@@ -2056,13 +2201,6 @@ event_callback (XEvent   *event,
                               window->unmaps_pending);
                 }
             }
-
-          /* Unfocus on UnmapNotify, do this after the possible
-           * window_free above so that window_free can see if window->has_focus
-           * and move focus to another window
-           */
-          if (window)
-            meta_window_lost_focus (window);
         }
       break;
     case MapNotify:
@@ -5182,17 +5320,56 @@ meta_display_set_input_focus_window (MetaDisplay *display,
     return;
 
   meta_error_trap_push (display);
+  display->focus_serial = XNextRequest (display->xdisplay);
+  meta_topic (META_DEBUG_FOCUS, "XSetInputFocus(%s, %u) with serial %lu\n",
+              window->desc, timestamp, display->focus_serial);
   XSetInputFocus (display->xdisplay,
                   focus_frame ? window->frame->xwindow : window->xwindow,
                   RevertToPointerRoot,
                   timestamp);
   meta_error_trap_pop (display);
 
-  display->expected_focus_window = window;
   display->last_focus_time = timestamp;
 
   if (window != display->autoraise_window)
     meta_display_remove_autoraise_callback (window->display);
+
+  set_focus_window (display, window, display->focus_serial);
+}
+
+void
+meta_display_request_take_focus (MetaDisplay *display,
+                                 MetaWindow  *window,
+                                 guint32      timestamp)
+{
+  if (timestamp_too_old (display, window, &timestamp))
+    return;
+
+  meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n",
+              window->desc, timestamp);
+
+  if (window != display->focus_window)
+    {
+      /* The "Globally Active Input" window case, where the window
+       * doesn't want us to call XSetInputFocus on it, but does
+       * want us to send a WM_TAKE_FOCUS.
+       *
+       * We can't just set display->focus_window to @window, since we
+       * we don't know when (or even if) the window will actually take
+       * focus, so we could end up being wrong for arbitrarily long.
+       * But we also can't leave it set to the current window, or else
+       * bug #597352 would come back. So we focus the no_focus_window
+       * now (and set display->focus_window to that), send the
+       * WM_TAKE_FOCUS, and then just forget about @window
+       * until/unless we get a FocusIn.
+       */
+      meta_display_focus_the_no_focus_window (display,
+                                              window->screen,
+                                              timestamp);
+    }
+  meta_window_send_icccm_message (window,
+                                  display->atom_WM_TAKE_FOCUS,
+                                  timestamp);
 }
 
 void
@@ -5203,14 +5380,18 @@ meta_display_focus_the_no_focus_window (MetaDisplay *display,
   if (timestamp_too_old (display, NULL, &timestamp))
     return;
 
+  display->focus_serial = XNextRequest (display->xdisplay);
+  meta_topic (META_DEBUG_FOCUS, "Focusing no_focus_window at %u with serial %lu\n",
+              timestamp, display->focus_serial);
   XSetInputFocus (display->xdisplay,
                   screen->no_focus_window,
                   RevertToPointerRoot,
                   timestamp);
-  display->expected_focus_window = NULL;
   display->last_focus_time = timestamp;
 
   meta_display_remove_autoraise_callback (display);
+
+  set_focus_window (display, NULL, display->focus_serial);
 }
 
 void
diff --git a/src/core/stack.c b/src/core/stack.c
index a3b6bdc..271e7b3 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -250,7 +250,7 @@ static gboolean
 is_focused_foreach (MetaWindow *window,
                     void       *data)
 {
-  if (window == window->display->expected_focus_window)
+  if (window->has_focus)
     {
       *((gboolean*) data) = TRUE;
       return FALSE;
@@ -308,11 +308,11 @@ get_standalone_layer (MetaWindow *window)
         layer = META_LAYER_BOTTOM;
       else if (window->fullscreen &&
                (focused_transient ||
-                window == window->display->expected_focus_window ||
-                window->display->expected_focus_window == NULL ||
-                (window->display->expected_focus_window != NULL &&
+                window == window->display->focus_window ||
+                window->display->focus_window == NULL ||
+                (window->display->focus_window != NULL &&
                  windows_on_different_xinerama (window,
-                                                window->display->expected_focus_window))))
+                                                window->display->focus_window))))
         layer = META_LAYER_FULLSCREEN;
       else if (window->wm_state_above)
         layer = META_LAYER_TOP;
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 36ba47b..bad9176 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -262,7 +262,7 @@ struct _MetaWindow
   /* EWHH demands attention flag */
   guint wm_state_demands_attention : 1;
 
-  /* this flag tracks receipt of focus_in focus_out */
+  /* TRUE if window == window->display->focus_window */
   guint has_focus : 1;
 
   /* Have we placed this window? */
@@ -577,10 +577,9 @@ gboolean meta_window_property_notify   (MetaWindow *window,
                                         XEvent     *event);
 gboolean meta_window_client_message    (MetaWindow *window,
                                         XEvent     *event);
-gboolean meta_window_notify_focus      (MetaWindow *window,
-                                        XEvent     *event);
 
-void     meta_window_lost_focus        (MetaWindow *window);
+void     meta_window_set_focused_internal (MetaWindow *window,
+                                           gboolean    focused);
 
 void     meta_window_set_current_workspace_hint (MetaWindow *window);
 
diff --git a/src/core/window.c b/src/core/window.c
index c9130ad..20cf474 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1112,16 +1112,6 @@ meta_window_free (MetaWindow  *window,
       meta_workspace_focus_default_window (window->screen->active_workspace,
                                            NULL, timestamp);
     }
-  else if (window->display->expected_focus_window == window)
-    {
-      meta_topic (META_DEBUG_FOCUS,
-                  "Focusing default window since expected focus window freed %s\n",
-                  window->desc);
-      window->display->expected_focus_window = NULL;
-      meta_workspace_focus_default_window (window->screen->active_workspace,
-                                           window,
-                                           timestamp);
-    }
   else
     {
       meta_topic (META_DEBUG_FOCUS,
@@ -1129,6 +1119,8 @@ meta_window_free (MetaWindow  *window,
                   window->desc);
     }
 
+  g_assert (window->display->focus_window != window);
+
   if (window->struts)
     {
       meta_free_gslist_and_elements (window->struts);
@@ -1145,12 +1137,6 @@ meta_window_free (MetaWindow  *window,
 
   g_assert (window->display->grab_window != window);
 
-  if (window->display->focus_window == window)
-    {
-      window->display->focus_window = NULL;
-      meta_compositor_set_active_window (window->display->compositor, NULL);
-    }
-
   if (window->maximized_horizontally || window->maximized_vertically)
     unmaximize_window_before_freeing (window);
 
@@ -4522,10 +4508,10 @@ meta_window_focus (MetaWindow  *window,
           meta_topic (META_DEBUG_FOCUS,
                       "Sending WM_TAKE_FOCUS to %s since take_focus = true\n",
                       window->desc);
-          meta_window_send_icccm_message (window,
-                                          window->display->atom_WM_TAKE_FOCUS,
-                                          timestamp);
-          window->display->expected_focus_window = window;
+
+          meta_display_request_take_focus (window->display,
+                                           window,
+                                           timestamp);
         }
     }
 
@@ -5103,7 +5089,7 @@ meta_window_configure_request (MetaWindow *window,
   if (event->xconfigurerequest.value_mask & CWStackMode)
     {
       MetaWindow *active_window;
-      active_window = window->display->expected_focus_window;
+      active_window = window->display->focus_window;
       if (meta_prefs_get_disable_workarounds ())
         {
           meta_topic (META_DEBUG_STACK,
@@ -5746,8 +5732,7 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
           parent->attached_focus_window = NULL;
         }
 
-      if (child_focus_state_changed && !parent->has_focus &&
-          parent != window->display->expected_focus_window)
+      if (child_focus_state_changed && !parent->has_focus)
         {
           meta_window_appears_focused_changed (parent);
         }
@@ -5757,22 +5742,14 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
     }
 }
 
-static void
+void
 meta_window_set_focused_internal (MetaWindow *window,
                                   gboolean    focused)
 {
   if (focused)
     {
-      if (window == window->display->focus_window)
-        return;
-
-      meta_topic (META_DEBUG_FOCUS,
-                  "* Focus --> %s\n", window->desc);
-      window->display->focus_window = window;
       window->has_focus = TRUE;
 
-      meta_compositor_set_active_window (window->display->compositor, window);
-
       /* Move to the front of the focusing workspace's MRU list.
        * We should only be "removing" it from the MRU list if it's
        * not already there.  Note that it's possible that we might
@@ -5833,23 +5810,10 @@ meta_window_set_focused_internal (MetaWindow *window,
     }
   else
     {
-      if (window != window->display->focus_window)
-        return;
-
-      meta_topic (META_DEBUG_FOCUS,
-                  "%s is now the previous focus window due to being focused out or unmapped\n",
-                  window->desc);
-
-      meta_topic (META_DEBUG_FOCUS,
-                  "* Focus --> NULL (was %s)\n", window->desc);
-
       meta_window_propagate_focus_appearance (window, FALSE);
 
-      window->display->focus_window = NULL;
       window->has_focus = FALSE;
 
-      meta_compositor_set_active_window (window->display->compositor, NULL);
-
       if (!window->attached_focus_window)
         meta_window_appears_focused_changed (window);
 
@@ -5867,119 +5831,6 @@ meta_window_set_focused_internal (MetaWindow *window,
     }
 }
 
-void
-meta_window_lost_focus (MetaWindow *window)
-{
-  meta_window_set_focused_internal (window, FALSE);
-}
-
-gboolean
-meta_window_notify_focus (MetaWindow *window,
-                          XEvent     *event)
-{
-  /* note the event can be on either the window or the frame,
-   * we focus the frame for shaded windows
-   */
-
-  /* The event can be FocusIn, FocusOut, or UnmapNotify.
-   * On UnmapNotify we have to pretend it's focus out,
-   * because we won't get a focus out if it occurs, apparently.
-   */
-
-  /* We ignore grabs, though this is questionable.
-   * It may be better to increase the intelligence of
-   * the focus window tracking.
-   *
-   * The problem is that keybindings for windows are done with
-   * XGrabKey, which means focus_window disappears and the front of
-   * the MRU list gets confused from what the user expects once a
-   * keybinding is used.
-   */
-  meta_topic (META_DEBUG_FOCUS,
-              "Focus %s event received on %s 0x%lx (%s) "
-              "mode %s detail %s\n",
-              event->type == FocusIn ? "in" :
-              event->type == FocusOut ? "out" :
-              event->type == UnmapNotify ? "unmap" :
-              "???",
-              window->desc, event->xany.window,
-              event->xany.window == window->xwindow ?
-              "client window" :
-              (window->frame && event->xany.window == window->frame->xwindow) ?
-              "frame window" :
-              "unknown window",
-              event->type != UnmapNotify ?
-              meta_event_mode_to_string (event->xfocus.mode) : "n/a",
-              event->type != UnmapNotify ?
-              meta_event_detail_to_string (event->xfocus.detail) : "n/a");
-
-  /* FIXME our pointer tracking is broken; see how
-   * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c
-   * handle it for the correct way.  In brief you need to track
-   * pointer focus and regular focus, and handle EnterNotify in
-   * PointerRoot mode with no window manager.  However as noted above,
-   * accurate focus tracking will break things because we want to keep
-   * windows "focused" when using keybindings on them, and also we
-   * sometimes "focus" a window by focusing its frame or
-   * no_focus_window; so this all needs rethinking massively.
-   *
-   * My suggestion is to change it so that we clearly separate
-   * actual keyboard focus tracking using the xterm algorithm,
-   * and metacity's "pretend" focus window, and go through all
-   * the code and decide which one should be used in each place;
-   * a hard bit is deciding on a policy for that.
-   *
-   * http://bugzilla.gnome.org/show_bug.cgi?id=90382
-   */
-
-  if ((event->type == FocusIn ||
-       event->type == FocusOut) &&
-      (event->xfocus.mode == NotifyGrab ||
-       event->xfocus.mode == NotifyUngrab ||
-       /* From WindowMaker, ignore all funky pointer root events */
-       event->xfocus.detail > NotifyNonlinearVirtual))
-    {
-      meta_topic (META_DEBUG_FOCUS,
-                  "Ignoring focus event generated by a grab or other weirdness\n");
-      return TRUE;
-    }
-
-  if (event->type == FocusIn)
-    {
-      if (window->override_redirect)
-        {
-          window->display->focus_window = NULL;
-          meta_compositor_set_active_window (window->display->compositor, NULL);
-
-          return FALSE;
-        }
-      else
-        {
-          meta_window_set_focused_internal (window, TRUE);
-        }
-    }
-  else if (event->type == FocusOut)
-    {
-      if (event->xfocus.detail == NotifyInferior)
-        {
-          /* This event means the client moved focus to a subwindow */
-          meta_topic (META_DEBUG_FOCUS,
-                      "Ignoring focus out on %s with NotifyInferior\n",
-                      window->desc);
-          return TRUE;
-        }
-      else
-        {
-          meta_window_set_focused_internal (window, FALSE);
-        }
-    }
-
-  /* Now set _NET_ACTIVE_WINDOW hint */
-  meta_display_update_active_window_hint (window->display);
-
-  return FALSE;
-}
-
 static gboolean
 process_property_notify (MetaWindow     *window,
                          XPropertyEvent *event)
diff --git a/src/ui/select-workspace.c b/src/ui/select-workspace.c
index 76e6356..20390fc 100644
--- a/src/ui/select-workspace.c
+++ b/src/ui/select-workspace.c
@@ -49,9 +49,7 @@ meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
   wnck_window.icon = window->icon;
   wnck_window.mini_icon = window->mini_icon;
 
-  wnck_window.is_active = FALSE;
-  if (window == window->display->expected_focus_window)
-    wnck_window.is_active = TRUE;
+  wnck_window.is_active = window->has_focus;
 
   if (window->frame)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]