]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
fix fullscreen windows being stuck in the wrong layer when they come out of
[chaz/openbox] / openbox / client.c
index 1c029841e8b5cb583a08d46e258366773124c685..16c249378c3ec85de487e72b5b1c8b64e817bb25 100644 (file)
@@ -386,6 +386,12 @@ void client_manage(Window window)
     if (ob_state() == OB_STATE_RUNNING) {
         gboolean transient;
 
+        ob_debug("Positioned: %s @ %d %d\n",
+                 (!self->positioned ? "no" :
+                  (self->positioned == PPosition ? "program specified" :
+                   (self->positioned == USPosition ? "user specified" :
+                    "BADNESS !?"))), self->area.x, self->area.y);
+
         transient = place_client(self, &self->area.x, &self->area.y, settings);
 
         /* make sure the window is visible. */
@@ -408,10 +414,6 @@ void client_manage(Window window)
                               !self->session));
     }
 
-    /* do this after the window is placed, so the premax/prefullscreen numbers
-       won't be all wacko!!
-       also, this moves the window to the position where it has been placed
-    */
     ob_debug("placing window 0x%x at %d, %d with size %d x %d\n",
              self->window, self->area.x, self->area.y,
              self->area.width, self->area.height);
@@ -419,15 +421,26 @@ void client_manage(Window window)
         ob_debug("  but session requested %d %d instead, overriding\n",
                  self->session->x, self->session->y);
 
-    /* generate a ConfigureNotify telling the client where it is */
+    /* adjust the frame to the client's size before showing the window */
+    frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
+    frame_adjust_client_area(self->frame);
+
+
+    /* move the client to its placed position, or it it's already there,
+       generate a ConfigureNotify telling the client where it is.
+
+       do this after adjusting the frame. otherwise it gets all weird and
+       clients don't work right */
     client_configure_full(self, self->area.x, self->area.y,
                           self->area.width, self->area.height,
                           FALSE, TRUE);
 
+    /* do this after the window is placed, so the premax/prefullscreen numbers
+       won't be all wacko!!
+       also, this moves the window to the position where it has been placed
+    */
     client_apply_startup_state(self);
 
-    mouse_grab_for_client(self, TRUE);
-
     if (activate) {
         guint32 last_time = focus_client ?
             focus_client->user_time : CurrentTime;
@@ -494,9 +507,7 @@ void client_manage(Window window)
             stacking_raise(CLIENT_AS_WINDOW(self));
     }
 
-    /* adjust the frame to the client's size before showing the window */
-    frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
-    frame_adjust_client_area(self->frame);
+    mouse_grab_for_client(self, TRUE);
 
     /* this has to happen before we try focus the window, but we want it to
        happen after the client's stacking has been determined or it looks bad
@@ -519,7 +530,8 @@ void client_manage(Window window)
     /* update the list hints */
     client_set_list();
 
-    ob_debug("Managed window 0x%lx (%s)\n", window, self->class);
+    ob_debug("Managed window 0x%lx plate 0x%x (%s)\n",
+             window, self->frame->plate, self->class);
 
     return;
 }
@@ -561,7 +573,8 @@ void client_unmanage(ObClient *self)
     guint j;
     GSList *it;
 
-    ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window,
+    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)\n",
+             self->window, self->frame->plate,
              self->class, self->title ? self->title : "");
 
     g_assert(self != NULL);
@@ -1175,7 +1188,7 @@ static void client_get_state(ObClient *self)
                 self->below = TRUE;
             else if (state[i] == prop_atoms.net_wm_state_demands_attention)
                 self->demands_attention = TRUE;
-            else if (state[i] == prop_atoms.openbox_wm_state_undecorated)
+            else if (state[i] == prop_atoms.ob_wm_state_undecorated)
                 self->undecorated = TRUE;
         }
 
@@ -1594,7 +1607,9 @@ void client_setup_decor_and_functions(ObClient *self)
          OB_CLIENT_FUNC_ICONIFY |
          OB_CLIENT_FUNC_MAXIMIZE |
          OB_CLIENT_FUNC_SHADE |
-         OB_CLIENT_FUNC_CLOSE);
+         OB_CLIENT_FUNC_CLOSE |
+         OB_CLIENT_FUNC_BELOW |
+         OB_CLIENT_FUNC_ABOVE);
 
     if (!(self->min_size.width < self->max_size.width ||
           self->min_size.height < self->max_size.height))
@@ -1626,10 +1641,15 @@ void client_setup_decor_and_functions(ObClient *self)
         self->functions = OB_CLIENT_FUNC_MOVE;
 
     case OB_CLIENT_TYPE_DESKTOP:
-    case OB_CLIENT_TYPE_DOCK:
         /* these windows are not manipulated by the window manager */
         self->decorations = 0;
         self->functions = 0;
+
+    case OB_CLIENT_TYPE_DOCK:
+        /* these windows are not manipulated by the window manager, but they
+           can set below layer which has a special meaning */
+        self->decorations = 0;
+        self->functions = OB_CLIENT_FUNC_BELOW;
         break;
     }
 
@@ -1719,7 +1739,7 @@ void client_setup_decor_and_functions(ObClient *self)
 
 static void client_change_allowed_actions(ObClient *self)
 {
-    gulong actions[9];
+    gulong actions[11];
     gint num = 0;
 
     /* desktop windows are kept on all desktops */
@@ -1742,6 +1762,10 @@ static void client_change_allowed_actions(ObClient *self)
         actions[num++] = prop_atoms.net_wm_action_maximize_horz;
         actions[num++] = prop_atoms.net_wm_action_maximize_vert;
     }
+    if (self->functions & OB_CLIENT_FUNC_ABOVE)
+        actions[num++] = prop_atoms.net_wm_action_above;
+    if (self->functions & OB_CLIENT_FUNC_BELOW)
+        actions[num++] = prop_atoms.net_wm_action_below;
 
     PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 
@@ -2279,7 +2303,7 @@ static void client_change_state(ObClient *self)
     if (self->demands_attention)
         netstate[num++] = prop_atoms.net_wm_state_demands_attention;
     if (self->undecorated)
-        netstate[num++] = prop_atoms.openbox_wm_state_undecorated;
+        netstate[num++] = prop_atoms.ob_wm_state_undecorated;
     PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 
     if (self->frame)
@@ -2343,9 +2367,12 @@ static ObStackingLayer calc_layer(ObClient *self)
                 self->frame->size.bottom == 0 && self->frame->size.top == 0 &&
                 RECT_EQUAL(self->area,
                            *screen_physical_area_monitor
-                           (client_monitor(self)))))) &&
-             (client_focused(self) || client_search_focus_tree(self)))
-        l = OB_STACKING_LAYER_FULLSCREEN;
+                           (client_monitor(self))))))) {
+        if (client_focused(self) || client_search_focus_tree(self))
+            l = OB_STACKING_LAYER_FULLSCREEN;
+        else
+            l = OB_STACKING_LAYER_FULLSCREEN_BELOW;
+    }
     else if (self->above) l = OB_STACKING_LAYER_ABOVE;
     else if (self->below) l = OB_STACKING_LAYER_BELOW;
     else l = OB_STACKING_LAYER_NORMAL;
@@ -2722,8 +2749,8 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
        for user-requested ones, only resize if final is true, or when
        resizing in redraw mode */
     send_resize_client = ((!user && resized) ||
-                          (user && resized &&
-                           (final || config_resize_redraw)));
+                          (user && (final ||
+                                    (resized && config_resize_redraw))));
 
     /* if the client is enlarging, then resize the client before the frame */
     if (send_resize_client && (w > oldw || h > oldh)) {
@@ -2790,7 +2817,6 @@ void client_fullscreen(ObClient *self, gboolean fs)
 
     self->fullscreen = fs;
     client_change_state(self); /* change the state hints on the client */
-    client_calc_layer(self);   /* and adjust out layer/stacking */
 
     if (fs) {
         self->pre_fullscreen_area = self->area;
@@ -2805,36 +2831,36 @@ void client_fullscreen(ObClient *self, gboolean fs)
             self->pre_fullscreen_area.height = self->pre_max_area.height;
         }
 
-        /* these are not actually used cuz client_configure will set them
-           as appropriate when the window is fullscreened */
-        x = y = w = h = 0;
+        /* these will help configure_full figure out where to fullscreen
+           the window */
+        x = self->area.x;
+        y = self->area.y;
+        w = self->area.width;
+        h = self->area.height;
     } else {
-        Rect *a;
+        g_assert(self->pre_fullscreen_area.width > 0 &&
+                 self->pre_fullscreen_area.height > 0);
 
-        if (self->pre_fullscreen_area.width > 0 &&
-            self->pre_fullscreen_area.height > 0)
-        {
-            x = self->pre_fullscreen_area.x;
-            y = self->pre_fullscreen_area.y;
-            w = self->pre_fullscreen_area.width;
-            h = self->pre_fullscreen_area.height;
-            RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
-        } else {
-            /* pick some fallbacks... */
-            a = screen_area_monitor(self->desktop, 0);
-            x = a->x + a->width / 4;
-            y = a->y + a->height / 4;
-            w = a->width / 2;
-            h = a->height / 2;
-        }
+        x = self->pre_fullscreen_area.x;
+        y = self->pre_fullscreen_area.y;
+        w = self->pre_fullscreen_area.width;
+        h = self->pre_fullscreen_area.height;
+        RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
     }
 
     client_setup_decor_and_functions(self);
 
     client_move_resize(self, x, y, w, h);
 
-    /* try focus us when we go into fullscreen mode */
-    client_focus(self);
+    /* and adjust our layer/stacking. do this after resizing the window,
+       and applying decorations, because windows which fill the screen are
+       considered "fullscreen" and it affects their layer */
+    client_calc_layer(self);
+
+    if (fs) {
+        /* try focus us when we go into fullscreen mode */
+        client_focus(self);
+    }
 }
 
 static void client_iconify_recursive(ObClient *self,
@@ -2922,8 +2948,8 @@ void client_maximize(ObClient *self, gboolean max, gint dir)
         if (dir == 2 && !self->max_vert) return;
     }
 
-    /* we just tell it to configure in the same place and client_configure
-       worries about filling the screen with the window */
+    /* these will help configure_full figure out which screen to fill with
+       the window */
     x = self->area.x;
     y = self->area.y;
     w = self->area.width;
@@ -2941,34 +2967,23 @@ void client_maximize(ObClient *self, gboolean max, gint dir)
                      self->pre_max_area.width, self->area.height);
         }
     } else {
-        Rect *a;
-
-        a = screen_area_monitor(self->desktop, 0);
         if ((dir == 0 || dir == 1) && self->max_horz) { /* horz */
-            if (self->pre_max_area.width > 0) {
-                x = self->pre_max_area.x;
-                w = self->pre_max_area.width;
+            g_assert(self->pre_max_area.width > 0);
 
-                RECT_SET(self->pre_max_area, 0, self->pre_max_area.y,
-                         0, self->pre_max_area.height);
-            } else {
-                /* pick some fallbacks... */
-                x = a->x + a->width / 4;
-                w = a->width / 2;
-            }
+            x = self->pre_max_area.x;
+            w = self->pre_max_area.width;
+
+            RECT_SET(self->pre_max_area, 0, self->pre_max_area.y,
+                     0, self->pre_max_area.height);
         }
         if ((dir == 0 || dir == 2) && self->max_vert) { /* vert */
-            if (self->pre_max_area.height > 0) {
-                y = self->pre_max_area.y;
-                h = self->pre_max_area.height;
+            g_assert(self->pre_max_area.height > 0);
 
-                RECT_SET(self->pre_max_area, self->pre_max_area.x, 0,
-                         self->pre_max_area.width, 0);
-            } else {
-                /* pick some fallbacks... */
-                y = a->y + a->height / 4;
-                h = a->height / 2;
-            }
+            y = self->pre_max_area.y;
+            h = self->pre_max_area.height;
+
+            RECT_SET(self->pre_max_area, self->pre_max_area.x, 0,
+                     self->pre_max_area.width, 0);
         }
     }
 
@@ -3207,7 +3222,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 action = self->demands_attention ?
                     prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
-            else if (state == prop_atoms.openbox_wm_state_undecorated)
+            else if (state == prop_atoms.ob_wm_state_undecorated)
                 action = undecorated ? prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
         }
@@ -3237,7 +3252,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 below = TRUE;
             } else if (state == prop_atoms.net_wm_state_demands_attention) {
                 demands_attention = TRUE;
-            } else if (state == prop_atoms.openbox_wm_state_undecorated) {
+            } else if (state == prop_atoms.ob_wm_state_undecorated) {
                 undecorated = TRUE;
             }
 
@@ -3264,7 +3279,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 below = FALSE;
             } else if (state == prop_atoms.net_wm_state_demands_attention) {
                 demands_attention = FALSE;
-            } else if (state == prop_atoms.openbox_wm_state_undecorated) {
+            } else if (state == prop_atoms.ob_wm_state_undecorated) {
                 undecorated = FALSE;
             }
         }
@@ -3326,8 +3341,6 @@ ObClient *client_focus_target(ObClient *self)
 
 gboolean client_can_focus(ObClient *self)
 {
-    XEvent ev;
-
     /* choose the correct target */
     self = client_focus_target(self);
 
@@ -3337,24 +3350,6 @@ gboolean client_can_focus(ObClient *self)
     if (!(self->can_focus || self->focus_notify))
         return FALSE;
 
-    /* do a check to see if the window has already been unmapped or destroyed
-       do this intelligently while watching out for unmaps we've generated
-       (ignore_unmaps > 0) */
-    if (XCheckTypedWindowEvent(ob_display, self->window,
-                               DestroyNotify, &ev)) {
-        XPutBackEvent(ob_display, &ev);
-        return FALSE;
-    }
-    while (XCheckTypedWindowEvent(ob_display, self->window,
-                                  UnmapNotify, &ev)) {
-        if (self->ignore_unmaps) {
-            self->ignore_unmaps--;
-        } else {
-            XPutBackEvent(ob_display, &ev);
-            return FALSE;
-        }
-    }
-
     return TRUE;
 }
 
@@ -3729,8 +3724,6 @@ ObClient *client_search_transient(ObClient *self, ObClient *search)
             if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \
                 continue;                                                     \
             if(cur->iconic)                                                   \
-                continue;                                                     \
-            if(cur->layer == c->layer)                                        \
                 continue;
 
 #define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \
This page took 0.029082 seconds and 4 git commands to generate.