]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
move stuff around some more
[chaz/openbox] / openbox / client.c
index 0386d23dc0a49f0953dba39997759ce749d90c39..ce1c417fd0f8f73303f4b243de8cb8c93123901b 100644 (file)
@@ -126,7 +126,7 @@ void client_set_list()
         windows = NULL;
 
     PROP_SETA32(RootWindow(ob_display, ob_screen),
-                net_client_list, window, (guint32*)windows, size);
+                net_client_list, window, (gulong*)windows, size);
 
     if (windows)
         g_free(windows);
@@ -204,6 +204,26 @@ void client_manage_all()
     XFree(children);
 }
 
+/* This should possibly do something more interesting than just match
+ * against WM_CLASS literally. */
+static ObAppSetting *get_settings(ObClient *client)
+{
+    GSList *a = config_per_app_settings;
+
+    while (a) {
+        ObAppSetting *app = (ObAppSetting *) a->data;
+        
+        if (!strcmp(app->name, client->name)) {
+            ob_debug("Window matching: %s\n", app->name);
+
+            return (ObAppSetting *) a->data;
+        }
+
+        a = a->next;
+    }
+    return NULL;
+}
+
 void client_manage(Window window)
 {
     ObClient *self;
@@ -212,6 +232,7 @@ void client_manage(Window window)
     XSetWindowAttributes attrib_set;
     XWMHints *wmhint;
     gboolean activate = FALSE;
+    ObAppSetting *settings;
 
     grab_server(TRUE);
 
@@ -292,12 +313,29 @@ void client_manage(Window window)
 
     client_apply_startup_state(self);
 
+    /* get and set application level settings */
+    settings = get_settings(self);
+
+    if (settings) {
+        if (settings->shade && !settings->decor)
+            settings->decor = TRUE;
+        
+        client_shade(self, settings->shade);
+        client_set_undecorated(self, !settings->decor);
+        
+        if (settings->desktop != -1)
+            client_set_desktop(self, settings->desktop, FALSE);
+
+        client_set_layer(self, settings->layer);
+    }
+
     stacking_add(CLIENT_AS_WINDOW(self));
     client_restore_session_stacking(self);
 
     /* focus the new window? */
     if (ob_state() != OB_STATE_STARTING &&
-        (config_focus_new || client_search_focus_parent(self)) &&
+        (config_focus_new || client_search_focus_parent(self)) ||
+        (settings && settings->focus) &&
         /* note the check against Type_Normal/Dialog, not client_normal(self),
            which would also include other types. in this case we want more
            strict rules for focus */
@@ -342,8 +380,26 @@ void client_manage(Window window)
         gint x = self->area.x, ox = x;
         gint y = self->area.y, oy = y;
 
-        place_client(self, &x, &y);
+        place_client(self, &x, &y, settings);
 
+        /* make sure the window is visible. */
+        client_find_onscreen(self, &x, &y,
+                             self->frame->area.width,
+                             self->frame->area.height,
+                             /* non-normal clients has less rules, and
+                                windows that are being restored from a
+                                session do also. we can assume you want
+                                it back where you saved it. Clients saying
+                                they placed themselves are subjected to
+                                harder rules, ones that are placed by
+                                place.c or by the user are allowed partially
+                                off-screen and on xinerama divides (ie,
+                                it is up to the placement routines to avoid
+                                the xinerama divides) */
+                             ((self->positioned & PPosition) &&
+                              !(self->positioned & USPosition)) &&
+                             client_normal(self) &&
+                             !self->session);
         if (x != ox || y != oy)         
             client_move(self, x, y);
     }
@@ -534,7 +590,7 @@ static void client_restore_session_state(ObClient *self)
     self->session = it->data;
 
     RECT_SET_POINT(self->area, self->session->x, self->session->y);
-    self->positioned = TRUE;
+    self->positioned = PPosition;
     if (self->session->w > 0)
         self->area.width = self->session->w;
     if (self->session->h > 0)
@@ -603,9 +659,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
     /* XXX watch for xinerama dead areas */
     /* This makes sure windows aren't entirely outside of the screen so you
      * can't see them at all */
-    //a = screen_area(self->desktop);
-    a = screen_physical_area_monitor(client_monitor(self));
     if (client_normal(self)) {
+        a = screen_area(self->desktop);
         if (!self->strut.right && *x >= a->x + a->width - 1)
             *x = a->x + a->width - self->frame->area.width;
         if (!self->strut.bottom && *y >= a->y + a->height - 1)
@@ -617,12 +672,16 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
     }
 
     /* This here doesn't let windows even a pixel outside the screen,
-     * not applied to all windows. Not sure if it's going to stay at all.
-     * I wonder if disabling this will break struts somehow? Let's find out. */
+     * when called from client_manage, programs placing themselves are
+     * forced completely onscreen, while things like
+     * 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 (rude) {
-        /* this is ben's MOZILLA BITCHSLAP. "oh ya it fucking feels good.
-           Java can suck it too." */
-
+        /* avoid the xinerama monitor divide while we're at it,
+         * remember to fix the placement stuff to avoid it also and
+         * then remove this XXX */
+        a = screen_physical_area_monitor(client_monitor(self));
         /* dont let windows map/move into the strut unless they
            are bigger than the available area */
         if (w <= a->width) {
@@ -1106,7 +1165,7 @@ void client_update_normal_hints(ObClient *self)
         /* normal windows can't request placement! har har
         if (!client_normal(self))
         */
-        self->positioned = !!(size.flags & (PPosition|USPosition));
+        self->positioned = (size.flags & (PPosition|USPosition));
 
         if (size.flags & PWinGravity) {
             self->gravity = size.win_gravity;
@@ -1207,7 +1266,7 @@ void client_setup_decor_and_functions(ObClient *self)
                    (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 = config_theme_keepborder ? OB_FRAME_DECOR_BORDER : 0;
         }
     }
 
@@ -1279,7 +1338,7 @@ void client_setup_decor_and_functions(ObClient *self)
 
 static void client_change_allowed_actions(ObClient *self)
 {
-    guint32 actions[9];
+    gulong actions[9];
     gint num = 0;
 
     /* desktop windows are kept on all desktops */
@@ -1694,8 +1753,8 @@ void client_update_icons(ObClient *self)
 
 static void client_change_state(ObClient *self)
 {
-    guint32 state[2];
-    guint32 netstate[11];
+    gulong state[2];
+    gulong netstate[11];
     guint num;
 
     state[0] = self->wmstate;
@@ -1783,9 +1842,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->above) l = OB_STACKING_LAYER_DOCK_ABOVE;
-        else if (self->below) l = OB_STACKING_LAYER_DOCK_BELOW;
-        else l = OB_STACKING_LAYER_DOCK_NORMAL;
+        if (self->below) l = OB_STACKING_LAYER_NORMAL;
+        else l = OB_STACKING_LAYER_ABOVE;
     }
     else if (self->above) l = OB_STACKING_LAYER_ABOVE;
     else if (self->below) l = OB_STACKING_LAYER_BELOW;
@@ -2777,6 +2835,9 @@ void client_unfocus(ObClient *self)
 
 void client_activate(ObClient *self, gboolean here)
 {
+    /* This check is for the client_list_menu trying to activate
+     * a closed client. */
+    if (!g_list_find(client_list, self)) return;
     if (client_normal(self) && screen_showing_desktop)
         screen_show_desktop(FALSE);
     if (self->iconic)
@@ -2997,6 +3058,13 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
     if (self->undecorated != undecorated) {
         self->undecorated = undecorated;
         client_setup_decor_and_functions(self);
+        /* Make sure the client knows it might have moved. Maybe there is a
+         * better way of doing this so only one client_configure is sent, but
+         * since 125 of these are sent per second when moving the window (with
+         * user = FALSE) i doubt it matters much.
+         */
+        client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y,
+                         self->area.width, self->area.height, TRUE, TRUE);
         client_change_state(self); /* reflect this in the state hints */
     }
 }
This page took 0.025892 seconds and 4 git commands to generate.