]> Dogcows Code - chaz/openbox/commitdiff
Add MoveFromEdge* actions, shorten client_directional_edge_search with some handy...
authorMikael Magnusson <mikachu@comhem.se>
Tue, 31 Oct 2006 03:33:21 +0000 (03:33 +0000)
committerMikael Magnusson <mikachu@comhem.se>
Tue, 31 Oct 2006 03:33:21 +0000 (03:33 +0000)
CHANGELOG
data/rc.xsd
openbox/action.c
openbox/action.h
openbox/client.c
openbox/client.h

index b50f427580eafd47f8328ce5a2380dc0d75f8fe5..121c72f8df53391a682982182877725ed6f36db6 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+3.4:
+  * Add MoveFromEdge* actions corresponding to MoveToEdge* but aligns far
+    edges instead of near edges, so if you have two overlapping windows you
+    can easily put them side by side.
+
 3.3.1:
   * Fix panels getting a border with keepBorder turned on.
   * Fix a crash in mirrorhorizontal when drawing a surface with width 1.
index c5cf79ee6298a592b9b8fc3135effabd4ea796c9..b841512f71897e90343e0ec0494b1a60dbad1e7d 100644 (file)
@@ -39,6 +39,8 @@
          Add showDelay for the dock
      Tue Jul 18 23:43:15 CEST 2006 - jonaskoelker(a)gnu.org
          hack code for great justice
+     Tue Oct 31 03:30:26 UTC 2006 - mikachu(a)openbox.org
+         Add movefromedge* actions
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
     targetNamespace="http://openbox.org/"
             <xs:enumeration value="MoveRelativeHorz"/>
             <xs:enumeration value="MoveRelativeVert"/>
             <xs:enumeration value="MoveToCenter"/>
+            <xs:enumeration value="MoveFromEdgeEast"/>
+            <xs:enumeration value="MoveFromEdgeNorth"/>
+            <xs:enumeration value="MoveFromEdgeSouth"/>
+            <xs:enumeration value="MoveFromEdgeWest"/>
             <xs:enumeration value="MoveToEdgeEast"/>
             <xs:enumeration value="MoveToEdgeNorth"/>
             <xs:enumeration value="MoveToEdgeSouth"/>
index 7f9d113f1595661057019d5b1b931b91bd3adcb8..24a0c6346396d39c45de365b372b106e008af1c6 100644 (file)
@@ -303,28 +303,60 @@ void setup_action_cycle_windows_previous(ObAction **a, ObUserAction uact)
     (*a)->data.cycle.dialog = TRUE;
 }
 
+void setup_action_movefromedge_north(ObAction **a, ObUserAction uact)
+{
+    (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+    (*a)->data.diraction.direction = OB_DIRECTION_NORTH;
+    (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_south(ObAction **a, ObUserAction uact)
+{
+    (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+    (*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
+    (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_east(ObAction **a, ObUserAction uact)
+{
+    (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+    (*a)->data.diraction.direction = OB_DIRECTION_EAST;
+    (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_west(ObAction **a, ObUserAction uact)
+{
+    (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+    (*a)->data.diraction.direction = OB_DIRECTION_WEST;
+    (*a)->data.diraction.hang = TRUE;
+}
+
 void setup_action_movetoedge_north(ObAction **a, ObUserAction uact)
 {
     (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
     (*a)->data.diraction.direction = OB_DIRECTION_NORTH;
+    (*a)->data.diraction.hang = FALSE;
 }
 
 void setup_action_movetoedge_south(ObAction **a, ObUserAction uact)
 {
     (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
     (*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
+    (*a)->data.diraction.hang = FALSE;
 }
 
 void setup_action_movetoedge_east(ObAction **a, ObUserAction uact)
 {
     (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
     (*a)->data.diraction.direction = OB_DIRECTION_EAST;
+    (*a)->data.diraction.hang = FALSE;
 }
 
 void setup_action_movetoedge_west(ObAction **a, ObUserAction uact)
 {
     (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
     (*a)->data.diraction.direction = OB_DIRECTION_WEST;
+    (*a)->data.diraction.hang = FALSE;
 }
 
 void setup_action_growtoedge_north(ObAction **a, ObUserAction uact)
@@ -783,6 +815,26 @@ ActionString actionstrings[] =
         action_cycle_windows,
         setup_action_cycle_windows_previous
     },
+    {
+        "movefromedgenorth",
+        action_movetoedge,
+        setup_action_movefromedge_north
+    },
+    {
+        "movefromedgesouth",
+        action_movetoedge,
+        setup_action_movefromedge_south
+    },
+    {
+        "movefromedgewest",
+        action_movetoedge,
+        setup_action_movefromedge_west
+    },
+    {
+        "movefromedgeeast",
+        action_movetoedge,
+        setup_action_movefromedge_east
+    },
     {
         "movetoedgenorth",
         action_movetoedge,
@@ -1554,18 +1606,20 @@ void action_movetoedge(union ActionData *data)
     
     switch(data->diraction.direction) {
     case OB_DIRECTION_NORTH:
-        y = client_directional_edge_search(c, OB_DIRECTION_NORTH);
+        y = client_directional_edge_search(c, OB_DIRECTION_NORTH, data->diraction.hang)
+            - (data->diraction.hang ? c->frame->area.height : 0);
         break;
     case OB_DIRECTION_WEST:
-        x = client_directional_edge_search(c, OB_DIRECTION_WEST);
+        x = client_directional_edge_search(c, OB_DIRECTION_WEST, data->diraction.hang)
+            - (data->diraction.hang ? c->frame->area.width : 0);
         break;
     case OB_DIRECTION_SOUTH:
-        y = client_directional_edge_search(c, OB_DIRECTION_SOUTH) -
-            c->frame->area.height;
+        y = client_directional_edge_search(c, OB_DIRECTION_SOUTH, data->diraction.hang)
+            - (data->diraction.hang ? 0 : c->frame->area.height);
         break;
     case OB_DIRECTION_EAST:
-        x = client_directional_edge_search(c, OB_DIRECTION_EAST) -
-            c->frame->area.width;
+        x = client_directional_edge_search(c, OB_DIRECTION_EAST, data->diraction.hang)
+            - (data->diraction.hang ? 0 : c->frame->area.width);
         break;
     default:
         g_assert_not_reached();
@@ -1594,7 +1648,7 @@ void action_growtoedge(union ActionData *data)
 
     switch(data->diraction.direction) {
     case OB_DIRECTION_NORTH:
-        dest = client_directional_edge_search(c, OB_DIRECTION_NORTH);
+        dest = client_directional_edge_search(c, OB_DIRECTION_NORTH, FALSE);
         if (a->y == y)
             height = c->frame->area.height / 2;
         else {
@@ -1603,7 +1657,7 @@ void action_growtoedge(union ActionData *data)
         }
         break;
     case OB_DIRECTION_WEST:
-        dest = client_directional_edge_search(c, OB_DIRECTION_WEST);
+        dest = client_directional_edge_search(c, OB_DIRECTION_WEST, FALSE);
         if (a->x == x)
             width = c->frame->area.width / 2;
         else {
@@ -1612,7 +1666,7 @@ void action_growtoedge(union ActionData *data)
         }
         break;
     case OB_DIRECTION_SOUTH:
-        dest = client_directional_edge_search(c, OB_DIRECTION_SOUTH);
+        dest = client_directional_edge_search(c, OB_DIRECTION_SOUTH, FALSE);
         if (a->y + a->height == y + c->frame->area.height) {
             height = c->frame->area.height / 2;
             y = a->y + a->height - height;
@@ -1622,7 +1676,7 @@ void action_growtoedge(union ActionData *data)
         height -= (height - c->frame->area.height) % c->size_inc.height;
         break;
     case OB_DIRECTION_EAST:
-        dest = client_directional_edge_search(c, OB_DIRECTION_EAST);
+        dest = client_directional_edge_search(c, OB_DIRECTION_EAST, FALSE);
         if (a->x + a->width == x + c->frame->area.width) {
             width = c->frame->area.width / 2;
             x = a->x + a->width - width;
index 7aab7bd65b7767e1b5d56ed6fac8a8ee1b0be5cd..4c749fee0932eaf921d322cad578c8c36cdb4f95 100644 (file)
@@ -65,6 +65,7 @@ struct InterDirectionalAction{
 struct DirectionalAction{
     struct AnyAction any;
     ObDirection direction;
+    gboolean hang;
 };
 
 struct Execute {
index 474176888b784f03aeda80c88ad3ffaa884b3417..2fa7728ac35bf549fc4b456b94e3a183082a1b53 100644 (file)
@@ -3216,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;
@@ -3237,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)
@@ -3251,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)
@@ -3299,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)
@@ -3320,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)
@@ -3348,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)
@@ -3397,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:
index 41531979ddf34a1bee854763dd9c17cae1aafa36..9702bb198bec38544fbb25937ca9e5fe8e9b62a4 100644 (file)
@@ -575,7 +575,7 @@ ObClient *client_search_transient(ObClient *self, ObClient *search);
 ObClient *client_find_directional(ObClient *c, ObDirection dir);
 
 /*! Return the closest edge in the given direction */
-gint client_directional_edge_search(ObClient *c, ObDirection dir);
+gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang);
 
 /*! Set a client window to be above/below other clients.
   @layer < 0 indicates the client should be placed below other clients.<br>
This page took 0.038696 seconds and 4 git commands to generate.