]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
set the defaults for typed windows in client_get_all:
[chaz/openbox] / openbox / client.c
index 5cd6339f4620ba962f3273cb1f43da0f9e4bed8e..5677f62779f729eee35c505064ac94fc56f1dfa0 100644 (file)
@@ -359,7 +359,17 @@ void client_manage(Window window)
        a window maps since its not based on an action from the user like
        clicking a window to activate is. so keep the new window out of the way
        but do focus it. */
-    if (activate) client_focus(self);
+    if (activate) {
+        /* if using focus_delay, stop the timer now so that focus doesn't go
+           moving on us */
+        event_halt_focus_delay();
+
+        client_focus(self);
+        /* since focus can change the stacking orders, if we focus the window
+           then the standard raise it gets is not enough, we need to queue one
+           for after the focus change takes place */
+        client_raise(self);
+    }
 
     /* client_activate does this but we aret using it so we have to do it
        here as well */
@@ -526,8 +536,9 @@ static void client_restore_session_state(ObClient *self)
     RECT_SET(self->area, self->session->x, self->session->y,
              self->session->w, self->session->h);
     self->positioned = TRUE;
-    XResizeWindow(ob_display, self->window,
-                  self->session->w, self->session->h);
+    if (self->session->w > 0 && self->session->h > 0)
+        XResizeWindow(ob_display, self->window,
+                      self->session->w, self->session->h);
 
     self->desktop = (self->session->desktop == DESKTOP_ALL ?
                      self->session->desktop :
@@ -704,6 +715,18 @@ static void client_get_all(ObClient *self)
     client_get_mwm_hints(self);
     client_get_type(self);/* this can change the mwmhints for special cases */
 
+    {
+        /* a couple type-based defaults for new windows */
+
+        /* this makes sure that these windows appear on all desktops */
+        if (self->type == OB_CLIENT_TYPE_DESKTOP)
+            self->desktop = DESKTOP_ALL;
+
+        /* dock windows default to ABOVE */
+        if (self->type == OB_CLIENT_TYPE_DOCK && !self->below)
+            self->above = TRUE;
+    }
+
     client_update_protocols(self);
 
     client_get_gravity(self); /* get the attribute gravity */
@@ -945,36 +968,36 @@ void client_get_type(ObClient *self)
     self->type = -1;
   
     if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
-       /* use the first value that we know about in the array */
-       for (i = 0; i < num; ++i) {
-           if (val[i] == prop_atoms.net_wm_window_type_desktop)
-               self->type = OB_CLIENT_TYPE_DESKTOP;
-           else if (val[i] == prop_atoms.net_wm_window_type_dock)
-               self->type = OB_CLIENT_TYPE_DOCK;
-           else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
-               self->type = OB_CLIENT_TYPE_TOOLBAR;
-           else if (val[i] == prop_atoms.net_wm_window_type_menu)
-               self->type = OB_CLIENT_TYPE_MENU;
-           else if (val[i] == prop_atoms.net_wm_window_type_utility)
-               self->type = OB_CLIENT_TYPE_UTILITY;
-           else if (val[i] == prop_atoms.net_wm_window_type_splash)
-               self->type = OB_CLIENT_TYPE_SPLASH;
-           else if (val[i] == prop_atoms.net_wm_window_type_dialog)
-               self->type = OB_CLIENT_TYPE_DIALOG;
-           else if (val[i] == prop_atoms.net_wm_window_type_normal)
-               self->type = OB_CLIENT_TYPE_NORMAL;
-           else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
-               /* prevent this window from getting any decor or
-                  functionality */
-               self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
-                                        OB_MWM_FLAG_DECORATIONS);
-               self->mwmhints.decorations = 0;
-               self->mwmhints.functions = 0;
-           }
-           if (self->type != (ObClientType) -1)
-               break; /* grab the first legit type */
-       }
-       g_free(val);
+        /* use the first value that we know about in the array */
+        for (i = 0; i < num; ++i) {
+            if (val[i] == prop_atoms.net_wm_window_type_desktop)
+                self->type = OB_CLIENT_TYPE_DESKTOP;
+            else if (val[i] == prop_atoms.net_wm_window_type_dock)
+                self->type = OB_CLIENT_TYPE_DOCK;
+            else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
+                self->type = OB_CLIENT_TYPE_TOOLBAR;
+            else if (val[i] == prop_atoms.net_wm_window_type_menu)
+                self->type = OB_CLIENT_TYPE_MENU;
+            else if (val[i] == prop_atoms.net_wm_window_type_utility)
+                self->type = OB_CLIENT_TYPE_UTILITY;
+            else if (val[i] == prop_atoms.net_wm_window_type_splash)
+                self->type = OB_CLIENT_TYPE_SPLASH;
+            else if (val[i] == prop_atoms.net_wm_window_type_dialog)
+                self->type = OB_CLIENT_TYPE_DIALOG;
+            else if (val[i] == prop_atoms.net_wm_window_type_normal)
+                self->type = OB_CLIENT_TYPE_NORMAL;
+            else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
+                /* prevent this window from getting any decor or
+                   functionality */
+                self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
+                                         OB_MWM_FLAG_DECORATIONS);
+                self->mwmhints.decorations = 0;
+                self->mwmhints.functions = 0;
+            }
+            if (self->type != (ObClientType) -1)
+                break; /* grab the first legit type */
+        }
+        g_free(val);
     }
     
     if (self->type == (ObClientType) -1) {
@@ -1085,78 +1108,76 @@ void client_setup_decor_and_functions(ObClient *self)
          OB_FRAME_DECOR_ALLDESKTOPS |
          OB_FRAME_DECOR_ICONIFY |
          OB_FRAME_DECOR_MAXIMIZE |
-         OB_FRAME_DECOR_SHADE);
+         OB_FRAME_DECOR_SHADE |
+         OB_FRAME_DECOR_CLOSE);
     self->functions =
         (OB_CLIENT_FUNC_RESIZE |
          OB_CLIENT_FUNC_MOVE |
          OB_CLIENT_FUNC_ICONIFY |
          OB_CLIENT_FUNC_MAXIMIZE |
-         OB_CLIENT_FUNC_SHADE);
-    if (self->delete_window) {
-       self->functions |= OB_CLIENT_FUNC_CLOSE;
-        self->decorations |= OB_FRAME_DECOR_CLOSE;
-    }
+         OB_CLIENT_FUNC_SHADE |
+         OB_CLIENT_FUNC_CLOSE);
 
     if (!(self->min_size.width < self->max_size.width ||
-         self->min_size.height < self->max_size.height))
-       self->functions &= ~OB_CLIENT_FUNC_RESIZE;
+          self->min_size.height < self->max_size.height))
+        self->functions &= ~OB_CLIENT_FUNC_RESIZE;
 
     switch (self->type) {
     case OB_CLIENT_TYPE_NORMAL:
-       /* normal windows retain all of the possible decorations and
-          functionality, and are the only windows that you can fullscreen */
-       self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
-       break;
+        /* normal windows retain all of the possible decorations and
+           functionality, and are the only windows that you can fullscreen */
+        self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
+        break;
 
     case OB_CLIENT_TYPE_DIALOG:
     case OB_CLIENT_TYPE_UTILITY:
-       /* these windows cannot be maximized */
-       self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
-       break;
+        /* these windows cannot be maximized */
+        self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
+        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);
-       break;
+        /* these windows get less functionality */
+        self->functions &= ~(OB_CLIENT_FUNC_ICONIFY | OB_CLIENT_FUNC_RESIZE);
+        break;
 
     case OB_CLIENT_TYPE_DESKTOP:
     case OB_CLIENT_TYPE_DOCK:
     case OB_CLIENT_TYPE_SPLASH:
-       /* none of these windows are manipulated by the window manager */
-       self->decorations = 0;
-       self->functions = 0;
-       break;
+        /* none of these windows are manipulated by the window manager */
+        self->decorations = 0;
+        self->functions = 0;
+        break;
     }
 
     /* Mwm Hints are applied subtractively to what has already been chosen for
        decor and functionality */
     if (self->mwmhints.flags & OB_MWM_FLAG_DECORATIONS) {
-       if (! (self->mwmhints.decorations & OB_MWM_DECOR_ALL)) {
-           if (! ((self->mwmhints.decorations & OB_MWM_DECOR_HANDLE) ||
+        if (! (self->mwmhints.decorations & OB_MWM_DECOR_ALL)) {
+            if (! ((self->mwmhints.decorations & OB_MWM_DECOR_HANDLE) ||
                    (self->mwmhints.decorations & OB_MWM_DECOR_TITLE)))
                 /* if the mwm hints request no handle or title, then all
                    decorations are disabled */
-               self->decorations = 0;
-       }
+                self->decorations = 0;
+        }
     }
 
     if (self->mwmhints.flags & OB_MWM_FLAG_FUNCTIONS) {
-       if (! (self->mwmhints.functions & OB_MWM_FUNC_ALL)) {
-           if (! (self->mwmhints.functions & OB_MWM_FUNC_RESIZE))
-               self->functions &= ~OB_CLIENT_FUNC_RESIZE;
-           if (! (self->mwmhints.functions & OB_MWM_FUNC_MOVE))
-               self->functions &= ~OB_CLIENT_FUNC_MOVE;
+        if (! (self->mwmhints.functions & OB_MWM_FUNC_ALL)) {
+            if (! (self->mwmhints.functions & OB_MWM_FUNC_RESIZE))
+                self->functions &= ~OB_CLIENT_FUNC_RESIZE;
+            if (! (self->mwmhints.functions & OB_MWM_FUNC_MOVE))
+                self->functions &= ~OB_CLIENT_FUNC_MOVE;
             /* dont let mwm hints kill any buttons
-           if (! (self->mwmhints.functions & OB_MWM_FUNC_ICONIFY))
-               self->functions &= ~OB_CLIENT_FUNC_ICONIFY;
-           if (! (self->mwmhints.functions & OB_MWM_FUNC_MAXIMIZE))
-               self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
+               if (! (self->mwmhints.functions & OB_MWM_FUNC_ICONIFY))
+               self->functions &= ~OB_CLIENT_FUNC_ICONIFY;
+               if (! (self->mwmhints.functions & OB_MWM_FUNC_MAXIMIZE))
+               self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
             */
-           /* dont let mwm hints kill the close button
-              if (! (self->mwmhints.functions & MwmFunc_Close))
-              self->functions &= ~OB_CLIENT_FUNC_CLOSE; */
-       }
+            /* dont let mwm hints kill the close button
+               if (! (self->mwmhints.functions & MwmFunc_Close))
+               self->functions &= ~OB_CLIENT_FUNC_CLOSE; */
+           }
     }
 
     if (!(self->functions & OB_CLIENT_FUNC_SHADE))
@@ -1179,20 +1200,20 @@ void client_setup_decor_and_functions(ObClient *self)
         self->decorations &= ~OB_FRAME_DECOR_HANDLE;
 
     /* finally, the user can have requested no decorations, which overrides
-       everything */
+       everything (but doesnt give it a border if it doesnt have one) */
     if (self->undecorated)
-        self->decorations = OB_FRAME_DECOR_BORDER;
+        self->decorations &= OB_FRAME_DECOR_BORDER;
 
     /* if we don't have a titlebar, then we cannot shade! */
     if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR))
-       self->functions &= ~OB_CLIENT_FUNC_SHADE;
+        self->functions &= ~OB_CLIENT_FUNC_SHADE;
 
     /* now we need to check against rules for the client's current state */
     if (self->fullscreen) {
-       self->functions &= (OB_CLIENT_FUNC_CLOSE |
+        self->functions &= (OB_CLIENT_FUNC_CLOSE |
                             OB_CLIENT_FUNC_FULLSCREEN |
                             OB_CLIENT_FUNC_ICONIFY);
-       self->decorations = 0;
+        self->decorations = 0;
     }
 
     client_change_allowed_actions(self);
@@ -1200,13 +1221,6 @@ void client_setup_decor_and_functions(ObClient *self)
     if (self->frame) {
         /* adjust the client's decorations, etc. */
         client_reconfigure(self);
-    } else {
-        /* this makes sure that these windows appear on all desktops */
-        if (self->type == OB_CLIENT_TYPE_DESKTOP &&
-            self->desktop != DESKTOP_ALL)
-        {
-            self->desktop = DESKTOP_ALL;
-        }
     }
 }
 
@@ -1220,20 +1234,20 @@ static void client_change_allowed_actions(ObClient *self)
         actions[num++] = prop_atoms.net_wm_action_change_desktop;
 
     if (self->functions & OB_CLIENT_FUNC_SHADE)
-       actions[num++] = prop_atoms.net_wm_action_shade;
+        actions[num++] = prop_atoms.net_wm_action_shade;
     if (self->functions & OB_CLIENT_FUNC_CLOSE)
-       actions[num++] = prop_atoms.net_wm_action_close;
+        actions[num++] = prop_atoms.net_wm_action_close;
     if (self->functions & OB_CLIENT_FUNC_MOVE)
-       actions[num++] = prop_atoms.net_wm_action_move;
+        actions[num++] = prop_atoms.net_wm_action_move;
     if (self->functions & OB_CLIENT_FUNC_ICONIFY)
-       actions[num++] = prop_atoms.net_wm_action_minimize;
+        actions[num++] = prop_atoms.net_wm_action_minimize;
     if (self->functions & OB_CLIENT_FUNC_RESIZE)
-       actions[num++] = prop_atoms.net_wm_action_resize;
+        actions[num++] = prop_atoms.net_wm_action_resize;
     if (self->functions & OB_CLIENT_FUNC_FULLSCREEN)
-       actions[num++] = prop_atoms.net_wm_action_fullscreen;
+        actions[num++] = prop_atoms.net_wm_action_fullscreen;
     if (self->functions & OB_CLIENT_FUNC_MAXIMIZE) {
-       actions[num++] = prop_atoms.net_wm_action_maximize_horz;
-       actions[num++] = prop_atoms.net_wm_action_maximize_vert;
+        actions[num++] = prop_atoms.net_wm_action_maximize_horz;
+        actions[num++] = prop_atoms.net_wm_action_maximize_vert;
     }
 
     PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
@@ -1241,21 +1255,21 @@ static void client_change_allowed_actions(ObClient *self)
     /* make sure the window isn't breaking any rules now */
 
     if (!(self->functions & OB_CLIENT_FUNC_SHADE) && self->shaded) {
-       if (self->frame) client_shade(self, FALSE);
-       else self->shaded = FALSE;
+        if (self->frame) client_shade(self, FALSE);
+        else self->shaded = FALSE;
     }
     if (!(self->functions & OB_CLIENT_FUNC_ICONIFY) && self->iconic) {
-       if (self->frame) client_iconify(self, FALSE, TRUE);
-       else self->iconic = FALSE;
+        if (self->frame) client_iconify(self, FALSE, TRUE);
+        else self->iconic = FALSE;
     }
     if (!(self->functions & OB_CLIENT_FUNC_FULLSCREEN) && self->fullscreen) {
-       if (self->frame) client_fullscreen(self, FALSE, TRUE);
-       else self->fullscreen = FALSE;
+        if (self->frame) client_fullscreen(self, FALSE, TRUE);
+        else self->fullscreen = FALSE;
     }
     if (!(self->functions & OB_CLIENT_FUNC_MAXIMIZE) && (self->max_horz ||
                                                          self->max_vert)) {
-       if (self->frame) client_maximize(self, FALSE, 0, TRUE);
-       else self->max_vert = self->max_horz = FALSE;
+        if (self->frame) client_maximize(self, FALSE, 0, TRUE);
+        else self->max_vert = self->max_horz = FALSE;
     }
 }
 
@@ -1369,9 +1383,9 @@ void client_update_title(ObClient *self)
      
     /* try netwm */
     if (!PROP_GETS(self->window, net_wm_name, utf8, &data))
-       /* try old x stuff */
-       if (!PROP_GETS(self->window, wm_name, locale, &data))
-           data = g_strdup("Unnamed Window");
+        /* try old x stuff */
+        if (!PROP_GETS(self->window, wm_name, locale, &data))
+            data = g_strdup("Unnamed Window");
 
     /* did the title change? then reset the title_count */
     if (old_title && 0 != strncmp(old_title, data, strlen(data)))
@@ -1405,7 +1419,7 @@ void client_update_title(ObClient *self)
     self->title = data;
 
     if (self->frame)
-       frame_adjust_title(self->frame);
+        frame_adjust_title(self->frame);
 
     g_free(old_title);
 
@@ -1696,7 +1710,8 @@ static ObStackingLayer calc_layer(ObClient *self)
     else if (self->type == OB_CLIENT_TYPE_DESKTOP)
         l = OB_STACKING_LAYER_DESKTOP;
     else if (self->type == OB_CLIENT_TYPE_DOCK) {
-        if (!self->below) l = OB_STACKING_LAYER_TOP;
+        if (self->above) l = OB_STACKING_LAYER_DOCK_ABOVE;
+        else if (self->below) l = OB_STACKING_LAYER_DOCK_BELOW;
         else l = OB_STACKING_LAYER_NORMAL;
     }
     else if (self->above) l = OB_STACKING_LAYER_ABOVE;
@@ -1747,7 +1762,7 @@ gboolean client_should_show(ObClient *self)
 {
     if (self->iconic) return FALSE;
     else if (!(self->desktop == screen_desktop ||
-              self->desktop == DESKTOP_ALL)) return FALSE;
+               self->desktop == DESKTOP_ALL)) return FALSE;
     else if (client_normal(self) && screen_showing_desktop) return FALSE;
     
     return TRUE;
@@ -1765,7 +1780,7 @@ static void client_showhide(ObClient *self)
 gboolean client_normal(ObClient *self) {
     return ! (self->type == OB_CLIENT_TYPE_DESKTOP ||
               self->type == OB_CLIENT_TYPE_DOCK ||
-             self->type == OB_CLIENT_TYPE_SPLASH);
+              self->type == OB_CLIENT_TYPE_SPLASH);
 }
 
 static void client_apply_startup_state(ObClient *self)
@@ -1953,27 +1968,46 @@ void client_configure_full(ObClient *self, ObCorner anchor,
         h -= self->base_size.height;
 
         if (self->min_ratio)
-            if (h * self->min_ratio > w) h = (int)(w / self->min_ratio);
+            if (h * self->min_ratio > w) {
+                h = (int)(w / self->min_ratio);
+
+                /* you cannot resize to nothing */
+                if (h < 1) {
+                    h = 1;
+                    w = (int)(h * self->min_ratio);
+                }
+            }
         if (self->max_ratio)
-            if (h * self->max_ratio < w) h = (int)(w / self->max_ratio);
+            if (h * self->max_ratio < w) {
+                h = (int)(w / self->max_ratio);
+
+                /* you cannot resize to nothing */
+                if (h < 1) {
+                    h = 1;
+                    w = (int)(h * self->min_ratio);
+                }
+            }
 
         w += self->base_size.width;
         h += self->base_size.height;
     }
 
+    g_assert(w > 0);
+    g_assert(h > 0);
+
     switch (anchor) {
     case OB_CORNER_TOPLEFT:
-       break;
+        break;
     case OB_CORNER_TOPRIGHT:
-       x -= w - self->area.width;
-       break;
+        x -= w - self->area.width;
+        break;
     case OB_CORNER_BOTTOMLEFT:
-       y -= h - self->area.height;
-       break;
+        y -= h - self->area.height;
+        break;
     case OB_CORNER_BOTTOMRIGHT:
-       x -= w - self->area.width;
-       y -= h - self->area.height;
-       break;
+        x -= w - self->area.width;
+        y -= h - self->area.height;
+        break;
     }
 
     moved = x != self->area.x || y != self->area.y;
@@ -2189,8 +2223,18 @@ void client_maximize(ObClient *self, gboolean max, int dir, gboolean savearea)
     h = self->area.height;
 
     if (max) {
-        if (savearea)
-            self->pre_max_area = self->area;
+        if (savearea) {
+            if ((dir == 0 || dir == 1) && !self->max_horz) { /* horz */
+                RECT_SET(self->pre_max_area,
+                         self->area.x, self->pre_max_area.y,
+                         self->area.width, self->pre_max_area.height);
+            }
+            if ((dir == 0 || dir == 2) && !self->max_vert) { /* vert */
+                RECT_SET(self->pre_max_area,
+                         self->pre_max_area.x, self->area.y,
+                         self->pre_max_area.width, self->area.height);
+            }
+        }
     } else {
         Rect *a;
 
@@ -2264,6 +2308,11 @@ void client_close(ObClient *self)
 
     if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return;
 
+    /* in the case that the client provides no means to requesting that it
+       close, we just kill it */
+    if (!self->delete_window)
+        client_kill(self);
+    
     /*
       XXX: itd be cool to do timeouts and shit here for killing the client's
       process off
@@ -2533,10 +2582,7 @@ gboolean client_can_focus(ObClient *self)
     if (!self->frame->visible)
         return FALSE;
 
-    if (!((self->can_focus || self->focus_notify) &&
-          (self->desktop == screen_desktop ||
-           self->desktop == DESKTOP_ALL) &&
-          !self->iconic))
+    if (!(self->can_focus || self->focus_notify))
         return FALSE;
 
     /* do a check to see if the window has already been unmapped or destroyed
@@ -3156,7 +3202,7 @@ ObClient* client_under_pointer()
         for (it = stacking_list; it != NULL; it = it->next) {
             if (WINDOW_IS_CLIENT(it->data)) {
                 ObClient *c = WINDOW_AS_CLIENT(it->data);
-                if (c->desktop == screen_desktop &&
+                if (c->frame->visible &&
                     RECT_CONTAINS(c->frame->area, x, y)) {
                     ret = c;
                     break;
@@ -3166,3 +3212,8 @@ ObClient* client_under_pointer()
     }
     return ret;
 }
+
+gboolean client_has_group_siblings(ObClient *self)
+{
+    return self->group && self->group->members->next;
+}
This page took 0.04146 seconds and 4 git commands to generate.