]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
change in how things are ungrabbed to avoid grabwhilenotify. don't ungrab every key...
[chaz/openbox] / openbox / client.c
index ed005ee79d02c1a7fd52ad6b171ffab2f71146d3..bf7723365fdde511c1fa1e39ccbd68ba951f191c 100644 (file)
@@ -241,6 +241,7 @@ void client_manage(Window window)
     XWMHints *wmhint;
     gboolean activate = FALSE;
     ObAppSettings *settings;
+    gint placex, placey;
 
     grab_server(TRUE);
 
@@ -347,7 +348,7 @@ void client_manage(Window window)
         !self->iconic &&
         /* this means focus=true for window is same as config_focus_new=true */
         ((config_focus_new || (settings && settings->focus == 1)) ||
-         client_search_focus_parent(self)) &&
+         client_search_focus_tree_full(self)) &&
         /* this checks for focus=false for the window */
         (!settings || settings->focus != 0) &&
         /* note the check against Type_Normal/Dialog, not client_normal(self),
@@ -359,7 +360,16 @@ void client_manage(Window window)
         activate = TRUE;
     }
 
-    /* figure out placement for the window */
+    /* adjust the frame to the client's size before showing or placing
+       the window */
+    frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
+    frame_adjust_client_area(self->frame);
+
+    /* where the frame was placed is where the window was originally */
+    placex = self->area.x;
+    placey = self->area.y;
+
+    /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
         gboolean transient;
 
@@ -367,12 +377,46 @@ void client_manage(Window window)
                  (!self->positioned ? "no" :
                   (self->positioned == PPosition ? "program specified" :
                    (self->positioned == USPosition ? "user specified" :
-                    "BADNESS !?"))), self->area.x, self->area.y);
+                    (self->positioned == PPosition | USPosition ?
+                     "program + user specified" :
+                     "BADNESS !?")))), self->area.x, self->area.y);
+
+        ob_debug("Sized: %s @ %d %d\n",
+                 (!self->sized ? "no" :
+                  (self->sized == PSize ? "program specified" :
+                   (self->sized == USSize ? "user specified" :
+                    (self->sized == PSize | USSize ?
+                     "program + user specified" :
+                     "BADNESS !?")))), self->area.width, self->area.height);
+
+        transient = place_client(self, &placex, &placey, settings);
+
+        /* if the window isn't user-positioned, then make it fit inside
+           the visible screen area on its monitor.
 
-        transient = place_client(self, &self->area.x, &self->area.y, settings);
+           the monitor is chosen by place_client! */
+        if (!(self->sized & USSize)) {
+            /* make a copy to modify */
+            Rect a = *screen_area_monitor(self->desktop, client_monitor(self));
+
+            /* shrink by the frame's area */
+            a.width -= self->frame->size.left + self->frame->size.right;
+            a.height -= self->frame->size.top + self->frame->size.bottom;
+
+            /* fit the window inside the area */
+            self->area.width = MIN(self->area.width, a.width);
+            self->area.height = MIN(self->area.height, a.height);
+
+            ob_debug("setting window size to %dx%d\n",
+                     self->area.width, self->area.height);
+
+            /* adjust the frame to the client's new size */
+            frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
+            frame_adjust_client_area(self->frame);
+        }
 
         /* make sure the window is visible. */
-        client_find_onscreen(self, &self->area.x, &self->area.y,
+        client_find_onscreen(self, &placex, &placey,
                              self->area.width, self->area.height,
                              /* non-normal clients has less rules, and
                                 windows that are being restored from a
@@ -392,31 +436,32 @@ void client_manage(Window window)
     }
 
     ob_debug("placing window 0x%x at %d, %d with size %d x %d\n",
-             self->window, self->area.x, self->area.y,
+             self->window, placex, placey,
              self->area.width, self->area.height);
     if (self->session)
         ob_debug("  but session requested %d %d instead, overriding\n",
                  self->session->x, self->session->y);
 
-    /* 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);
-
+    /* 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);
 
     /* 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(self, self->area.x, self->area.y,
+       clients don't work right
+
+       also do this after applying the startup state so maximize and fullscreen
+       will get the right sizes and positions if the client is starting with
+       those states
+    */
+    client_configure(self, placex, placey,
                      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);
 
     if (activate) {
         guint32 last_time = focus_client ?
@@ -439,8 +484,8 @@ void client_manage(Window window)
                           "Not focusing the window because its on another "
                           "desktop\n");
         }
-        /* If something is focused, and it's not our parent... */
-        else if (focus_client && client_search_focus_parent(self) == NULL)
+        /* If something is focused, and it's not our relative... */
+        else if (focus_client && client_search_focus_tree_full(self) == NULL)
         {
             /* If time stamp is old, don't steal focus */
             if (self->user_time && last_time &&
@@ -451,15 +496,37 @@ void client_manage(Window window)
                               "Not focusing the window because the time is "
                               "too old\n");
             }
+            /* If its a transient (and parents aren't focused) and the time
+               is ambiguous (either the current focus target doesn't have
+               a timestamp, or they are the same (we probably inherited it
+               from them) */
+            else if (self->transient_for != NULL &&
+                     (!last_time || self->user_time == last_time))
+            {
+                activate = FALSE;
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "Not focusing the window because it is a "
+                              "transient, and the time is very ambiguous\n");
+            }
             /* Don't steal focus from globally active clients.
                I stole this idea from KWin. It seems nice.
              */
-            if (!(focus_client->can_focus || focus_client->focus_notify)) {
+            else if (!(focus_client->can_focus ||
+                       focus_client->focus_notify))
+            {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because a globally "
                               "active client has focus\n");
             }
+            /* Don't move focus if it's not going to go to this window
+               anyway */
+            else if (client_focus_target(self) != self) {
+                activate = FALSE;
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "Not focusing the window because another window "
+                              "would get the focus anyway\n");
+            }
         }
 
         if (!activate) {
@@ -540,6 +607,10 @@ ObClient *client_fake_manage(Window window)
     self->frame = frame_new(self);
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
+    ob_debug("gave extents left %d right %d top %d bottom %d\n",
+             self->frame->size.left, self->frame->size.right, 
+             self->frame->size.top, self->frame->size.bottom);
+
     /* free the ObAppSettings shallow copy */
     g_free(settings);
 
@@ -649,6 +720,8 @@ void client_unmanage(ObClient *self)
         }
 
         self->fullscreen = self->max_horz = self->max_vert = FALSE;
+        /* let it be moved and resized no matter what */
+        self->functions = OB_CLIENT_FUNC_MOVE | OB_CLIENT_FUNC_RESIZE;
         self->decorations = 0; /* unmanaged windows have no decor */
 
         client_move_resize(self, a.x, a.y, a.width, a.height);
@@ -722,11 +795,13 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
         if (app->name &&
             !g_pattern_match(app->name, strlen(self->name), self->name, NULL))
             match = FALSE;
-        if (app->class &&
-            !g_pattern_match(app->class, strlen(self->class),self->class,NULL))
+        else if (app->class &&
+                !g_pattern_match(app->class,
+                                 strlen(self->class), self->class, NULL))
             match = FALSE;
-        if (app->role &&
-            !g_pattern_match(app->role, strlen(self->role), self->role, NULL))
+        else if (app->role &&
+                 !g_pattern_match(app->role,
+                                  strlen(self->role), self->role, NULL))
             match = FALSE;
 
         if (match) {
@@ -738,46 +813,44 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
         }
     }
 
-    if (settings) {
-        if (settings->shade != -1)
-            self->shaded = !!settings->shade;
-        if (settings->decor != -1)
-            self->undecorated = !settings->decor;
-        if (settings->iconic != -1)
-            self->iconic = !!settings->iconic;
-        if (settings->skip_pager != -1)
-            self->skip_pager = !!settings->skip_pager;
-        if (settings->skip_taskbar != -1)
-            self->skip_taskbar = !!settings->skip_taskbar;
+    if (settings->shade != -1)
+        self->shaded = !!settings->shade;
+    if (settings->decor != -1)
+        self->undecorated = !settings->decor;
+    if (settings->iconic != -1)
+        self->iconic = !!settings->iconic;
+    if (settings->skip_pager != -1)
+        self->skip_pager = !!settings->skip_pager;
+    if (settings->skip_taskbar != -1)
+        self->skip_taskbar = !!settings->skip_taskbar;
 
-        if (settings->max_vert != -1)
-            self->max_vert = !!settings->max_vert;
-        if (settings->max_horz != -1)
-            self->max_horz = !!settings->max_horz;
+    if (settings->max_vert != -1)
+        self->max_vert = !!settings->max_vert;
+    if (settings->max_horz != -1)
+        self->max_horz = !!settings->max_horz;
 
-        if (settings->fullscreen != -1)
-            self->fullscreen = !!settings->fullscreen;
+    if (settings->fullscreen != -1)
+        self->fullscreen = !!settings->fullscreen;
 
-        if (settings->desktop) {
-            if (settings->desktop == DESKTOP_ALL)
-                self->desktop = settings->desktop;
-            else if (settings->desktop > 0 &&
-                     settings->desktop <= screen_num_desktops)
-                self->desktop = settings->desktop - 1;
-        }
+    if (settings->desktop) {
+        if (settings->desktop == DESKTOP_ALL)
+            self->desktop = settings->desktop;
+        else if (settings->desktop > 0 &&
+                 settings->desktop <= screen_num_desktops)
+            self->desktop = settings->desktop - 1;
+    }
 
-        if (settings->layer == -1) {
-            self->below = TRUE;
-            self->above = FALSE;
-        }
-        else if (settings->layer == 0) {
-            self->below = FALSE;
-            self->above = FALSE;
-        }
-        else if (settings->layer == 1) {
-            self->below = FALSE;
-            self->above = TRUE;
-        }
+    if (settings->layer == -1) {
+        self->below = TRUE;
+        self->above = FALSE;
+    }
+    else if (settings->layer == 0) {
+        self->below = FALSE;
+        self->above = FALSE;
+    }
+    else if (settings->layer == 1) {
+        self->below = FALSE;
+        self->above = TRUE;
     }
     return settings;
 }
@@ -802,6 +875,7 @@ static void client_restore_session_state(ObClient *self)
 
     RECT_SET_POINT(self->area, self->session->x, self->session->y);
     self->positioned = USPosition;
+    self->sized = USSize;
     if (self->session->w > 0)
         self->area.width = self->session->w;
     if (self->session->h > 0)
@@ -924,10 +998,10 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
         POINT_SET(newbl, newtl.x, newbr.y);
 
         /* is it moving or just resizing from some corner? */
-        stationary_l = oldtl.x == oldtl.x;
-        stationary_r = oldtr.x == oldtr.x;
-        stationary_t = oldtl.y == oldtl.y;
-        stationary_b = oldbl.y == oldbl.y;
+        stationary_l = oldtl.x == newtl.x;
+        stationary_r = oldtr.x == newtr.x;
+        stationary_t = oldtl.y == newtl.y;
+        stationary_b = oldbl.y == newbl.y;
 
         /* if left edge is growing and didnt move right edge */
         if (stationary_r && newtl.x < oldtl.x)
@@ -949,16 +1023,13 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
      * xterm -geometry resolution-width/2 will work fine. Trying to
      * place it completely offscreen will be handled in the above code.
      * Sorry for this confused comment, i am tired. */
-    if (fw <= mon_a->width) {
-        if (rudel && !self->strut.left && *x < mon_a->x) *x = mon_a->x;
-        if (ruder && !self->strut.right && *x + fw > mon_a->x + mon_a->width)
-            *x = mon_a->x + mon_a->width - fw;
-    }
-    if (fh <= mon_a->height) {
-        if (rudet && !self->strut.top && *y < mon_a->y) *y = mon_a->y;
-        if (rudeb && !self->strut.bottom && *y + fh > mon_a->y + mon_a->height)
-            *y = mon_a->y + mon_a->height - fh;
-    }
+    if (rudel && !self->strut.left && *x < mon_a->x) *x = mon_a->x;
+    if (ruder && !self->strut.right && *x + fw > mon_a->x + mon_a->width)
+        *x = mon_a->x + MAX(0, mon_a->width - fw);
+
+    if (rudet && !self->strut.top && *y < mon_a->y) *y = mon_a->y;
+    if (rudeb && !self->strut.bottom && *y + fh > mon_a->y + mon_a->height)
+        *y = mon_a->y + MAX(0, mon_a->height - fh);
 
     /* get where the client should be */
     frame_frame_gravity(self->frame, x, y, w, h);
@@ -1129,15 +1200,27 @@ static void client_get_desktop(ObClient *self)
                 self->desktop = self->transient_for->desktop;
                 trdesk = TRUE;
             } else {
+                /* if all the group is on one desktop, then open it on the
+                   same desktop */
                 GSList *it;
+                gboolean first = TRUE;
+                guint all = screen_num_desktops; /* not a valid value */
 
-                for (it = self->group->members; it; it = g_slist_next(it))
-                    if (it->data != self &&
-                        !((ObClient*)it->data)->transient_for) {
-                        self->desktop = ((ObClient*)it->data)->desktop;
-                        trdesk = TRUE;
-                        break;
+                for (it = self->group->members; it; it = g_slist_next(it)) {
+                    ObClient *c = it->data;
+                    if (c != self) {
+                        if (first) {
+                            all = c->desktop;
+                            first = FALSE;
+                        }
+                        else if (all != c->desktop)
+                            all = screen_num_desktops; /* make it invalid */
                     }
+                }
+                if (all != screen_num_desktops) {
+                    self->desktop = all;
+                    trdesk = TRUE;
+                }
             }
         }
         if (!trdesk) {
@@ -1528,7 +1611,6 @@ void client_update_normal_hints(ObClient *self)
 {
     XSizeHints size;
     glong ret;
-    gint oldgravity = self->gravity;
 
     /* defaults */
     self->min_ratio = 0.0f;
@@ -1544,20 +1626,10 @@ void client_update_normal_hints(ObClient *self)
         if (!client_normal(self))
         */
         self->positioned = (size.flags & (PPosition|USPosition));
+        self->sized = (size.flags & (PSize|USSize));
 
-        if (size.flags & PWinGravity) {
+        if (size.flags & PWinGravity)
             self->gravity = size.win_gravity;
-      
-            /* if the client has a frame, i.e. has already been mapped and
-               is changing its gravity */
-            if (self->frame && self->gravity != oldgravity) {
-                /* move our idea of the client's position based on its new
-                   gravity */
-                client_convert_gravity(self, oldgravity,
-                                       &self->area.x, &self->area.y,
-                                       self->area.width, self->area.height);
-            }
-        }
 
         if (size.flags & PAspect) {
             if (size.min_aspect.y)
@@ -1582,6 +1654,8 @@ void client_update_normal_hints(ObClient *self)
     }
 }
 
+/*! This needs to be followed by a call to client_configure to make
+  the changes show */
 void client_setup_decor_and_functions(ObClient *self)
 {
     /* start with everything (cept fullscreen) */
@@ -1620,14 +1694,16 @@ void client_setup_decor_and_functions(ObClient *self)
 
     case OB_CLIENT_TYPE_DIALOG:
     case OB_CLIENT_TYPE_UTILITY:
-        /* these windows cannot be maximized */
-        self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
+        /* these windows don't have anything added or removed by default */
         break;
 
     case OB_CLIENT_TYPE_MENU:
     case OB_CLIENT_TYPE_TOOLBAR:
-        /* these windows get less functionality */
-        self->functions &= ~(OB_CLIENT_FUNC_ICONIFY | OB_CLIENT_FUNC_RESIZE);
+        /* these windows can't iconify or maximize */
+        self->decorations &= ~(OB_FRAME_DECOR_ICONIFY |
+                               OB_FRAME_DECOR_MAXIMIZE);
+        self->functions &= ~(OB_CLIENT_FUNC_ICONIFY |
+                             OB_CLIENT_FUNC_MAXIMIZE);
         break;
 
     case OB_CLIENT_TYPE_SPLASH:
@@ -1703,10 +1779,8 @@ void client_setup_decor_and_functions(ObClient *self)
     }
 
     if (self->max_horz && self->max_vert) {
-        /* also can't resize maximized windows.
-           do this after checking for resize to let you maximize */
-        self->functions &=~ OB_CLIENT_FUNC_RESIZE;
-
+        /* you can't resize fully maximized windows */
+        self->functions &= ~OB_CLIENT_FUNC_RESIZE;
         /* kill the handle on fully maxed windows */
         self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
     }
@@ -1738,11 +1812,6 @@ void client_setup_decor_and_functions(ObClient *self)
     }
 
     client_change_allowed_actions(self);
-
-    if (self->frame) {
-        /* adjust the client's decorations, etc. */
-        client_reconfigure(self);
-    }
 }
 
 static void client_change_allowed_actions(ObClient *self)
@@ -1887,7 +1956,8 @@ void client_update_wmhints(ObClient *self)
         }
 
         /* the WM_HINTS can contain an icon */
-        client_update_icons(self);
+        if (hints->flags & IconPixmapHint)
+            client_update_icons(self);
 
         XFree(hints);
     }
@@ -1939,8 +2009,14 @@ void client_update_title(ObClient *self)
               PROP_GETS(self->window, wm_icon_name, utf8, &data)))
             data = g_strdup(self->title);
 
-    PROP_SETS(self->window, net_wm_visible_icon_name, data);
-    self->icon_title = data;
+    if (self->client_machine) {
+        visible = g_strdup_printf("%s (%s)", data, self->client_machine);
+        g_free(data);
+    } else
+        visible = data;
+
+    PROP_SETS(self->window, net_wm_visible_icon_name, visible);
+    self->icon_title = visible;
 }
 
 void client_update_strut(ObClient *self)
@@ -2372,10 +2448,10 @@ static ObStackingLayer calc_layer(ObClient *self)
     }
     else if ((self->fullscreen ||
               /* No decorations and fills the monitor = oldskool fullscreen.
-                 But not for undecorated windows, because the user can do that
+                 But not for maximized windows.
               */
               (self->decorations == 0 &&
-               !self->undecorated &&
+               !(self->max_horz && self->max_vert) &&
                RECT_EQUAL(self->area,
                           *screen_physical_area_monitor
                           (client_monitor(self))))) &&
@@ -2441,13 +2517,13 @@ gboolean client_show(ObClient *self)
     if (client_should_show(self)) {
         frame_show(self->frame);
         show = TRUE;
-    }
 
-    /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
-       needs to be in IconicState. This includes when it is on another
-       desktop!
-    */
-    client_change_wm_state(self);
+        /* According to the ICCCM (sec 4.1.3.1) when a window is not visible,
+           it needs to be in IconicState. This includes when it is on another
+           desktop!
+        */
+        client_change_wm_state(self);
+    }
     return show;
 }
 
@@ -2464,19 +2540,18 @@ gboolean client_hide(ObClient *self)
                actions should not rely on being able to move focus during an
                interactive grab.
             */
-            if (keyboard_interactively_grabbed())
-                keyboard_interactive_cancel();
+            event_cancel_all_key_grabs();
         }
 
         frame_hide(self->frame);
         hide = TRUE;
-    }
 
-    /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
-       needs to be in IconicState. This includes when it is on another
-       desktop!
-    */
-    client_change_wm_state(self);
+        /* According to the ICCCM (sec 4.1.3.1) when a window is not visible,
+           it needs to be in IconicState. This includes when it is on another
+           desktop!
+        */
+        client_change_wm_state(self);
+    }
     return hide;
 }
 
@@ -2484,12 +2559,6 @@ void client_showhide(ObClient *self)
 {
     if (!client_show(self))
         client_hide(self);
-
-    /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it
-       needs to be in IconicState. This includes when it is on another
-       desktop!
-    */
-    client_change_wm_state(self);
 }
 
 gboolean client_normal(ObClient *self) {
@@ -2569,18 +2638,62 @@ static void client_apply_startup_state(ObClient *self)
     */
 }
 
-void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y,
-                            gint w, gint h)
+void client_gravity_resize_w(ObClient *self, gint *x, gint oldw, gint neww)
 {
-    gint oldg = self->gravity;
+    /* these should be the current values. this is for when you're not moving,
+       just resizing */
+    g_assert(*x == self->area.x);
+    g_assert(oldw == self->area.width);
 
-    /* get the frame's position from the requested stuff */
-    self->gravity = gravity;
-    frame_client_gravity(self->frame, x, y, w, h);
-    self->gravity = oldg;
+    /* horizontal */
+    switch (self->gravity) {
+    default:
+    case NorthWestGravity:
+    case WestGravity:
+    case SouthWestGravity:
+    case StaticGravity:
+    case ForgetGravity:
+        break;
+    case NorthGravity:
+    case CenterGravity:
+    case SouthGravity:
+        *x -= (neww - oldw) / 2;
+        break;
+    case NorthEastGravity:
+    case EastGravity:
+    case SouthEastGravity:
+        *x -= neww - oldw;
+        break;
+    }
+}
 
-    /* get the client's position in its true gravity from that */
-    frame_frame_gravity(self->frame, x, y, w, h);
+void client_gravity_resize_h(ObClient *self, gint *y, gint oldh, gint newh)
+{
+    /* these should be the current values. this is for when you're not moving,
+       just resizing */
+    g_assert(*y == self->area.y);
+    g_assert(oldh == self->area.height);
+
+    /* vertical */
+    switch (self->gravity) {
+    default:
+    case NorthWestGravity:
+    case NorthGravity:
+    case NorthEastGravity:
+    case StaticGravity:
+    case ForgetGravity:
+        break;
+    case WestGravity:
+    case CenterGravity:
+    case EastGravity:
+        *y -= (newh - oldh) / 2;
+        break;
+    case SouthWestGravity:
+    case SouthGravity:
+    case SouthEastGravity:
+        *y -= newh - oldh;
+        break;
+    }
 }
 
 void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
@@ -2592,7 +2705,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
     /* make the frame recalculate its dimentions n shit without changing
        anything visible for real, this way the constraints below can work with
        the updated frame dimensions. */
-    frame_adjust_area(self->frame, TRUE, TRUE, TRUE);
+    frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
     /* work within the prefered sizes given by the window */
     if (!(*w == self->area.width && *h == self->area.height)) {
@@ -2696,7 +2809,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
         *h = a->height;
 
         user = FALSE; /* ignore if the client can't be moved/resized when it
-                         is entering fullscreen */
+                         is fullscreening */
     } else if (self->max_horz || self->max_vert) {
         Rect *a;
         guint i;
@@ -2714,8 +2827,8 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
             *h = a->height - self->frame->size.top - self->frame->size.bottom;
         }
 
-        /* maximizing is not allowed if the user can't move+resize the window
-         */
+        user = FALSE; /* ignore if the client can't be moved/resized when it
+                         is maximizing */
     }
 
     /* gets the client's position */
@@ -2783,11 +2896,15 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
     /* find the frame's dimensions and move/resize it */
     fmoved = moved;
     fresized = resized;
+
+    /* if decorations changed, then readjust everything for the frame */
     if (self->decorations != fdecor ||
         self->max_horz != fhorz || self->max_vert != fvert)
     {
         fmoved = fresized = TRUE;
     }
+
+    /* adjust the frame */
     if (fmoved || fresized)
         frame_adjust_area(self->frame, fmoved, fresized, FALSE);
 
@@ -2907,9 +3024,8 @@ static void client_iconify_recursive(ObClient *self,
                 self->iconic = iconic;
 
                 /* update the focus lists.. iconic windows go to the bottom of
-                   the list, put the new iconic window at the 'top of the
-                   bottom'. */
-                focus_order_to_top(self);
+                   the list */
+                focus_order_to_bottom(self);
 
                 changed = TRUE;
             }
@@ -3097,7 +3213,7 @@ void client_set_desktop_recursive(ObClient *self,
     guint old;
     GSList *it;
 
-    if (target != self->desktop) {
+    if (target != self->desktop && self->type != OB_CLIENT_TYPE_DESKTOP) {
 
         ob_debug("Setting desktop %u\n", target+1);
 
@@ -3409,8 +3525,7 @@ gboolean client_focus(ObClient *self)
        actions should not rely on being able to move focus during an
        interactive grab.
     */
-    if (keyboard_interactively_grabbed())
-        keyboard_interactive_cancel();
+    event_cancel_all_key_grabs();
 
     xerror_set_ignore(TRUE);
     xerror_occured = FALSE;
@@ -3567,7 +3682,7 @@ static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h)
     for (i = 1; i < self->nicons; ++i) {
         gulong diff;
 
-        diff = ABS(self->icons[0].width - w) + ABS(self->icons[0].height - h);
+        diff = ABS(self->icons[i].width - w) + ABS(self->icons[i].height - h);
         if (diff < min_diff) {
             min_diff = diff;
             min_i = i;
@@ -3613,6 +3728,7 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
     {
         self->undecorated = undecorated;
         client_setup_decor_and_functions(self);
+        client_reconfigure(self); /* show the lack of decorations */
         client_change_state(self); /* reflect this in the state hints */
     }
 }
This page took 0.039171 seconds and 4 git commands to generate.