Add MoveFromEdge* actions, shorten client_directional_edge_search with some handy #defines
This commit is contained in:
parent
efa508a2a2
commit
b18846db69
6 changed files with 123 additions and 103 deletions
|
@ -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.
|
||||
|
|
|
@ -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/"
|
||||
|
@ -284,6 +286,10 @@
|
|||
<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"/>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -65,6 +65,7 @@ struct InterDirectionalAction{
|
|||
struct DirectionalAction{
|
||||
struct AnyAction any;
|
||||
ObDirection direction;
|
||||
gboolean hang;
|
||||
};
|
||||
|
||||
struct Execute {
|
||||
|
|
138
openbox/client.c
138
openbox/client.c
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue