diff --git a/data/rc.xsd b/data/rc.xsd index 75dd660e8..c15043ca2 100644 --- a/data/rc.xsd +++ b/data/rc.xsd @@ -176,6 +176,8 @@ + + diff --git a/openbox/actions/growtoedge.c b/openbox/actions/growtoedge.c index fa1b2c7ed..b4a2b927b 100644 --- a/openbox/actions/growtoedge.c +++ b/openbox/actions/growtoedge.c @@ -9,6 +9,8 @@ typedef struct { ObDirection dir; gboolean shrink; gboolean fill; + gboolean once; + gboolean strict; } Options; static gpointer setup_grow_func(xmlNodePtr node); @@ -62,6 +64,12 @@ static gpointer setup_func(xmlNodePtr node) g_free(s); } + if ((n = obt_xml_find_node(node, "once"))) + o->once = obt_xml_node_bool(n); + + if ((n = obt_xml_find_node(node, "strict"))) + o->strict = obt_xml_node_bool(n); + return o; } @@ -207,7 +215,9 @@ static gboolean run_func(ObActionsData *data, gpointer options) /* If all the edges are blocked, then allow them to jump past their current block points. */ - do_grow_all_edges(data, CLIENT_RESIZE_GROW); + if (!o->once) + do_grow_all_edges(data, CLIENT_RESIZE_GROW); + return FALSE; } @@ -215,7 +225,13 @@ static gboolean run_func(ObActionsData *data, gpointer options) gint x, y, w, h; /* Try grow. */ - client_find_resize_directional(data->client, + if (o->once) + client_find_resize_directional(data->client, + o->dir, + CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE, + &x, &y, &w, &h); + else + client_find_resize_directional(data->client, o->dir, CLIENT_RESIZE_GROW, &x, &y, &w, &h); @@ -224,7 +240,11 @@ static gboolean run_func(ObActionsData *data, gpointer options) return FALSE; } - /* We couldn't grow, so try shrink! */ + /* We couldn't grow, so try shrink! + Except when on strict mode. */ + if (o->strict) + return FALSE; + ObDirection opposite = (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH : (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH : @@ -278,6 +298,8 @@ static gpointer setup_north_func(xmlNodePtr node) Options *o = g_slice_new0(Options); o->shrink = FALSE; o->dir = OB_DIRECTION_NORTH; + o->once = FALSE; + o->strict = FALSE; return o; } @@ -286,6 +308,8 @@ static gpointer setup_south_func(xmlNodePtr node) Options *o = g_slice_new0(Options); o->shrink = FALSE; o->dir = OB_DIRECTION_SOUTH; + o->once = FALSE; + o->strict = FALSE; return o; } @@ -294,6 +318,8 @@ static gpointer setup_east_func(xmlNodePtr node) Options *o = g_slice_new0(Options); o->shrink = FALSE; o->dir = OB_DIRECTION_EAST; + o->once = FALSE; + o->strict = FALSE; return o; } @@ -302,5 +328,7 @@ static gpointer setup_west_func(xmlNodePtr node) Options *o = g_slice_new0(Options); o->shrink = FALSE; o->dir = OB_DIRECTION_WEST; + o->once = FALSE; + o->strict = FALSE; return o; } diff --git a/openbox/actions/movetoedge.c b/openbox/actions/movetoedge.c index ef5b69201..e3d668597 100644 --- a/openbox/actions/movetoedge.c +++ b/openbox/actions/movetoedge.c @@ -7,6 +7,7 @@ typedef struct { ObDirection dir; + gboolean once; } Options; static gpointer setup_func(xmlNodePtr node); @@ -53,6 +54,9 @@ static gpointer setup_func(xmlNodePtr node) g_free(s); } + if ((n = obt_xml_find_node(node, "once"))) + o->once = obt_xml_node_bool(n); + return o; } @@ -69,7 +73,11 @@ static gboolean run_func(ObActionsData *data, gpointer options) if (data->client) { gint x, y; - client_find_move_directional(data->client, o->dir, &x, &y); + if (o->once) + client_find_move_directional(data->client, o->dir, CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE, &x, &y); + else + client_find_move_directional(data->client, o->dir, CLIENT_MOVE_MOVE, &x, &y); + if (x != data->client->area.x || y != data->client->area.y) { actions_client_move(data, TRUE); client_move(data->client, x, y); @@ -85,6 +93,7 @@ static gpointer setup_north_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); o->dir = OB_DIRECTION_NORTH; + o->once = FALSE; return o; } @@ -92,6 +101,7 @@ static gpointer setup_south_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); o->dir = OB_DIRECTION_SOUTH; + o->once = FALSE; return o; } @@ -99,6 +109,7 @@ static gpointer setup_east_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); o->dir = OB_DIRECTION_EAST; + o->once = FALSE; return o; } @@ -106,6 +117,7 @@ static gpointer setup_west_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); o->dir = OB_DIRECTION_WEST; + o->once = FALSE; return o; } diff --git a/openbox/client.c b/openbox/client.c index 5e6569e0e..ddc5afbc7 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -4468,7 +4468,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, g_slice_free(Rect, a); } -void client_find_move_directional(ObClient *self, ObDirection dir, +void client_find_move_directional(ObClient *self, ObDirection dir, ObClientDirectionalMoveType move_type, gint *x, gint *y) { gint head, size; @@ -4478,24 +4478,52 @@ void client_find_move_directional(ObClient *self, ObDirection dir, switch (dir) { case OB_DIRECTION_EAST: head = RECT_RIGHT(self->frame->area); + switch (move_type) { + case CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE: + head -= 1; + break; + case CLIENT_MOVE_MOVE: + break; + } size = self->frame->area.width; e_start = RECT_TOP(self->frame->area); e_size = self->frame->area.height; break; case OB_DIRECTION_WEST: head = RECT_LEFT(self->frame->area); + switch (move_type) { + case CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE: + head += 1; + break; + case CLIENT_MOVE_MOVE: + break; + } size = self->frame->area.width; e_start = RECT_TOP(self->frame->area); e_size = self->frame->area.height; break; case OB_DIRECTION_NORTH: head = RECT_TOP(self->frame->area); + switch (move_type) { + case CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE: + head += 1; + break; + case CLIENT_MOVE_MOVE: + break; + } size = self->frame->area.height; e_start = RECT_LEFT(self->frame->area); e_size = self->frame->area.width; break; case OB_DIRECTION_SOUTH: head = RECT_BOTTOM(self->frame->area); + switch (move_type) { + case CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE: + head -= 1; + break; + case CLIENT_MOVE_MOVE: + break; + } size = self->frame->area.height; e_start = RECT_LEFT(self->frame->area); e_size = self->frame->area.width; @@ -4506,6 +4534,7 @@ void client_find_move_directional(ObClient *self, ObDirection dir, client_find_edge_directional(self, dir, head, size, e_start, e_size, &e, &near); + *x = self->frame->area.x; *y = self->frame->area.y; switch (dir) { diff --git a/openbox/client.h b/openbox/client.h index 11a014000..1568aa0a1 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -487,7 +487,13 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, gint my_head, gint my_tail, gint my_edge_start, gint my_edge_size, gint *dest, gboolean *near_edge); -void client_find_move_directional(ObClient *self, ObDirection dir, + +typedef enum { + CLIENT_MOVE_MOVE, + CLIENT_MOVE_MOVE_IF_NOT_ON_EDGE, +} ObClientDirectionalMoveType; + +void client_find_move_directional(ObClient *self, ObDirection dir, ObClientDirectionalMoveType move_type, gint *x, gint *y); typedef enum { diff --git a/openbox/moveresize.c b/openbox/moveresize.c index d12a64de5..3f20c5d68 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -694,7 +694,7 @@ static void move_with_keys(KeySym sym, guint state) else /* sym == XK_Up */ dir = OB_DIRECTION_NORTH; - client_find_move_directional(moveresize_client, dir, &x, &y); + client_find_move_directional(moveresize_client, dir, CLIENT_MOVE_MOVE, &x, &y); dx = x - moveresize_client->area.x; dy = y - moveresize_client->area.y; } else {