Track the sibling that unmanaged windows are above
authorDana Jansens <danakj@orodu.net>
Sun, 27 Jun 2010 12:38:02 +0000 (14:38 +0200)
committerDana Jansens <danakj@orodu.net>
Sun, 27 Jun 2010 12:38:02 +0000 (14:38 +0200)
so we don't do the work of reordering them in the stacking lists for
 ConfigureNotify events where their stacking order didn't change

openbox/event.c
openbox/stacking.c
openbox/stacking.h
openbox/window.h

index 2dcdb6caf496dcc034a9415cd2d52198331c9c70..bf404d37d532dd73d69acd3113801d6a5dbe1179 100644 (file)
@@ -521,6 +521,16 @@ static void event_process(const XEvent *ec, gpointer data)
 
     /* deal with it in the kernel */
 
+    /* deal with it in the ObWindow superclass first */
+    if (!obwin) {
+        Window p; /* parent window (it's never None in these events) */
+        if (((e->type == CreateNotify && (p = e->xcreatewindow.parent)) ||
+             (e->type == ReparentNotify && (p = e->xreparent.parent))) &&
+            p == obt_root(ob_screen))
+        {
+            obwin = UNMANAGED_AS_WINDOW(unmanaged_new(window));
+        }
+    }
     if (obwin) event_handle_window(obwin, e);
 
     if (e->type == FocusIn) {
@@ -648,16 +658,6 @@ static void event_process(const XEvent *ec, gpointer data)
         if (client && client != focus_client)
             frame_adjust_focus(client->frame, FALSE);
     }
-    else if (e->type == CreateNotify &&
-             !obwin && e->xcreatewindow.parent == obt_root(ob_screen))
-    {
-        obwin = UNMANAGED_AS_WINDOW(unmanaged_new(e->xcreatewindow.window));
-    }
-    else if (e->type == ReparentNotify &&
-             !obwin && e->xreparent.parent == obt_root(ob_screen))
-    {
-        obwin = UNMANAGED_AS_WINDOW(unmanaged_new(e->xreparent.window));
-    }
     else if (client)
         event_handle_client(client, e);
     else if (um)
@@ -1817,7 +1817,22 @@ static void event_handle_window(ObWindow *wi, XEvent *e)
         }
 
         break;
-
+    case CreateNotify:
+        if (e->xcreatewindow.parent == obt_root(ob_screen))
+            /* we actually only care about tracking above for unmanaged
+               windows, and they are only created by create or reparent
+               events, at which time they become the top-most, so we don't
+               bother tracking above for all windows in this function */
+            wi->above = window_top(stacking_topmost_window());
+        break;
+    case ReparentNotify:
+        if (e->xreparent.parent == obt_root(ob_screen))
+            /* we actually only care about tracking above for unmanaged
+               windows, and they are only created by create or reparent
+               events, at which time they become the top-most, so we don't
+               bother tracking above for all windows in this function */
+            wi->above = window_top(stacking_topmost_window());
+        break;
     case MapNotify:
         if (e->xmap.window == window_redir(wi)) {
             composite_dirty();
@@ -1900,8 +1915,12 @@ static void event_handle_unmanaged(ObUnmanaged *um, XEvent *e)
         obt_display_ignore_errors(FALSE);
         break;
     case ConfigureNotify:
-        /* XXX check if above changed */
-        stacking_unmanaged_above_notify(um, e->xconfigure.above);
+        if (e->xconfigure.above != UNMANAGED_AS_WINDOW(um)->above) {
+            ob_debug("ConfigureNotify changed stacking order for "
+                     "unmanaged 0x%lx", window_top(um));
+            stacking_unmanaged_above_notify(um, e->xconfigure.above);
+            UNMANAGED_AS_WINDOW(um)->above = e->xconfigure.above;
+        }
     }
 }
 
index a8dac99885f2cffead4f718c43f736b98b204955..6e9e8e8142a9ee2395b6ecfd73306061f9639c78 100644 (file)
@@ -964,3 +964,19 @@ void stacking_iter_free(ObStackingIter *it)
 {
     g_slice_free(ObStackingIter, it);
 }
+
+ObWindow* stacking_topmost_window(void)
+{
+    ObUNode *un = stacking_ulist ? stacking_ulist->data : NULL;
+    if (un && un->belowme == stacking_list)
+        /* the topmost unmanaged window is higher than the topmost
+           managed window, return it */
+        return UNMANAGED_AS_WINDOW(un->um);
+    else if (stacking_list)
+        /* the topmost managed window exists so it must be the highest */
+        return stacking_list->data;
+    else
+        /* there is no topmost managed window, and there must not be an
+           unmanaged window either, as it would be above NULL */
+        return NULL;
+}
index 1577d944a9119514fbe159c115f12f6c642de04a..6058786d9eed5b82eb313776df9dcbe2a3c74fdb 100644 (file)
@@ -99,4 +99,7 @@ void stacking_iter_prev(ObStackingIter *it);
 struct _ObWindow* stacking_iter_win(ObStackingIter *it);
 void stacking_iter_free(ObStackingIter *it);
 
+/*! Return the topmost window on the screen */
+struct _ObWindow* stacking_topmost_window(void);
+
 #endif
index 1e2883337552bc6726b45be918b51ec02be4236a..9afcdcd256bb43d604999365e2c801f03dff0a42 100644 (file)
@@ -77,6 +77,7 @@ struct _ObWindow {
     gint n_rects; /* number of objects in @rects */
     gboolean mapped;
     gboolean is_redir;
+    Window above; /* the sibling window last reported that this is above */
 #endif
 };