]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
Add MoveFromEdge* actions, shorten client_directional_edge_search with some handy...
[chaz/openbox] / openbox / client.c
index 08b09c93f68d4eddf26603187a6d2bba79894ec6..2fa7728ac35bf549fc4b456b94e3a183082a1b53 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
    
    client.c for the Openbox window manager
-   Copyright (c) 2004        Mikael Magnusson
+   Copyright (c) 2006        Mikael Magnusson
    Copyright (c) 2003        Ben Jansens
 
    This program is free software; you can redistribute it and/or modify
@@ -361,7 +361,7 @@ void client_manage(Window window)
 
         if (settings->desktop < screen_num_desktops
             || settings->desktop == DESKTOP_ALL)
-            client_set_desktop(self, settings->desktop, FALSE);
+            client_set_desktop(self, settings->desktop, TRUE);
 
         if (settings->layer > -2 && settings->layer < 2)
             client_set_layer(self, settings->layer);
@@ -415,8 +415,9 @@ void client_manage(Window window)
     if (ob_state() == OB_STATE_RUNNING) {
         gint x = self->area.x, ox = x;
         gint y = self->area.y, oy = y;
+        gboolean transient;
 
-        place_client(self, &x, &y, settings);
+        transient = place_client(self, &x, &y, settings);
 
         /* make sure the window is visible. */
         client_find_onscreen(self, &x, &y,
@@ -432,10 +433,11 @@ void client_manage(Window window)
                                 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);
+                             transient ||
+                             (((self->positioned & PPosition) &&
+                               !(self->positioned & USPosition)) &&
+                              client_normal(self) &&
+                              !self->session));
         if (x != ox || y != oy)         
             client_move(self, x, y);
     }
@@ -1301,8 +1303,12 @@ void client_setup_decor_and_functions(ObClient *self)
             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 = config_theme_keepborder ? OB_FRAME_DECOR_BORDER : 0;
+                   decorations are disabled, but keep the border if that's
+                   specified */
+                if (self->mwmhints.decorations & OB_MWM_DECOR_BORDER)
+                    self->decorations = OB_FRAME_DECOR_BORDER;
+                else
+                    self->decorations = 0;
         }
     }
 
@@ -2856,9 +2862,6 @@ 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)
@@ -3213,11 +3216,30 @@ void client_update_sm_client_id(ObClient *self)
                   &self->sm_client_id);
 }
 
+#define WANT_EDGE(cur, c) \
+            if(cur == c)                                                      \
+                continue;                                                     \
+            if(!client_normal_or_dock(cur))                                   \
+                continue;                                                     \
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \
+                continue;                                                     \
+            if(cur->iconic)                                                   \
+                continue;                                                     \
+            if(cur->layer < c->layer && !config_resist_layers_below)          \
+                continue;
+
+#define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \
+            if ((his_edge_start >= my_edge_start && \
+                 his_edge_start <= my_edge_end) ||  \
+                (my_edge_start >= his_edge_start && \
+                 my_edge_start <= his_edge_end))    \
+                dest = his_offset;
+
 /* finds the nearest edge in the given direction from the current client
  * note to self: the edge is the -frame- edge (the actual one), not the
  * client edge.
  */
-gint client_directional_edge_search(ObClient *c, ObDirection dir)
+gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
 {
     gint dest, monitor_dest;
     gint my_edge_start, my_edge_end, my_offset;
@@ -3234,11 +3256,11 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
     case OB_DIRECTION_NORTH:
         my_edge_start = c->frame->area.x;
         my_edge_end = c->frame->area.x + c->frame->area.width;
-        my_offset = c->frame->area.y;
+        my_offset = c->frame->area.y + (hang ? c->frame->area.height : 0);
         
         /* default: top of screen */
-        dest = a->y;
-        monitor_dest = monitor->y;
+        dest = a->y + (hang ? c->frame->area.height : 0);
+        monitor_dest = monitor->y + (hang ? c->frame->area.height : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset > monitor_dest)
@@ -3248,45 +3270,29 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
-            his_offset = cur->frame->area.y + cur->frame->area.height;
+            his_offset = cur->frame->area.y + (hang ? 0 : cur->frame->area.height);
 
             if(his_offset + 1 > my_offset)
                 continue;
 
             if(his_offset < dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_SOUTH:
         my_edge_start = c->frame->area.x;
         my_edge_end = c->frame->area.x + c->frame->area.width;
-        my_offset = c->frame->area.y + c->frame->area.height;
+        my_offset = c->frame->area.y + (hang ? 0 : c->frame->area.height);
 
         /* default: bottom of screen */
-        dest = a->y + a->height;
-        monitor_dest = monitor->y + monitor->height;
+        dest = a->y + a->height - (hang ? c->frame->area.height : 0);
+        monitor_dest = monitor->y + monitor->height - (hang ? c->frame->area.height : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset < monitor_dest)
@@ -3296,20 +3302,11 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
-            his_offset = cur->frame->area.y;
+            his_offset = cur->frame->area.y + (hang ? cur->frame->area.height : 0);
 
 
             if(his_offset - 1 < my_offset)
@@ -3317,25 +3314,18 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             
             if(his_offset > dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_WEST:
         my_edge_start = c->frame->area.y;
         my_edge_end = c->frame->area.y + c->frame->area.height;
-        my_offset = c->frame->area.x;
+        my_offset = c->frame->area.x + (hang ? c->frame->area.width : 0);
 
         /* default: leftmost egde of screen */
-        dest = a->x;
-        monitor_dest = monitor->x;
+        dest = a->x + (hang ? c->frame->area.width : 0);
+        monitor_dest = monitor->x + (hang ? c->frame->area.width : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset > monitor_dest)
@@ -3345,46 +3335,29 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
-            his_offset = cur->frame->area.x + cur->frame->area.width;
+            his_offset = cur->frame->area.x + (hang ? 0 : cur->frame->area.width);
 
             if(his_offset + 1 > my_offset)
                 continue;
-            
+
             if(his_offset < dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
-                
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
-        break;
+       break;
     case OB_DIRECTION_EAST:
         my_edge_start = c->frame->area.y;
         my_edge_end = c->frame->area.y + c->frame->area.height;
-        my_offset = c->frame->area.x + c->frame->area.width;
+        my_offset = c->frame->area.x + (hang ? 0 : c->frame->area.width);
         
         /* default: rightmost edge of screen */
-        dest = a->x + a->width;
-        monitor_dest = monitor->x + monitor->width;
+        dest = a->x + a->width - (hang ? c->frame->area.width : 0);
+        monitor_dest = monitor->x + monitor->width - (hang ? c->frame->area.width : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset < monitor_dest)
@@ -3394,35 +3367,19 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
-            his_offset = cur->frame->area.x;
+            his_offset = cur->frame->area.x + (hang ? cur->frame->area.width : 0);
 
             if(his_offset - 1 < my_offset)
                 continue;
             
             if(his_offset > dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_NORTHEAST:
This page took 0.034193 seconds and 4 git commands to generate.