Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 'once' option to GrowToEdge action. #7

Open
wants to merge 7 commits into
base: work
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions data/rc.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
<xsd:element minOccurs="0" name="here" type="ob:bool"/>
<xsd:element minOccurs="0" name="linear" type="ob:bool"/>
<xsd:element minOccurs="0" name="group" type="ob:bool"/>
<xsd:element minOccurs="0" name="once" type="ob:bool"/>
</xsd:all>
<xsd:attribute name="name" type="ob:actionname" use="required"/>
</xsd:complexType>
Expand Down
166 changes: 146 additions & 20 deletions openbox/actions/growtoedge.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
typedef struct {
ObDirection dir;
gboolean shrink;
gboolean fill;
gboolean once;
} Options;

static gpointer setup_func(xmlNodePtr node);
static gpointer setup_grow_func(xmlNodePtr node);
static gpointer setup_fill_func(xmlNodePtr node);
static gpointer setup_shrink_func(xmlNodePtr node);
static void free_func(gpointer o);
static gboolean run_func(ObActionsData *data, gpointer options);
Expand All @@ -22,7 +25,9 @@ static gpointer setup_west_func(xmlNodePtr node);

void action_growtoedge_startup(void)
{
actions_register("GrowToEdge", setup_func,
actions_register("GrowToEdge", setup_grow_func,
free_func, run_func);
actions_register("GrowToFill", setup_fill_func,
free_func, run_func);
actions_register("ShrinkToEdge", setup_shrink_func,
free_func, run_func);
Expand All @@ -40,7 +45,6 @@ static gpointer setup_func(xmlNodePtr node)

o = g_slice_new0(Options);
o->dir = OB_DIRECTION_NORTH;
o->shrink = FALSE;

if ((n = obt_xml_find_node(node, "direction"))) {
gchar *s = obt_xml_node_string(n);
Expand All @@ -59,6 +63,31 @@ 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;
}

static gpointer setup_grow_func(xmlNodePtr node)
{
Options *o;

o = setup_func(node);
o->shrink = FALSE;
o->fill = FALSE;

return o;
}

static gpointer setup_fill_func(xmlNodePtr node)
{
Options *o;

o = setup_func(node);
o->shrink = FALSE;
o->fill = TRUE;

return o;
}

Expand All @@ -68,6 +97,7 @@ static gpointer setup_shrink_func(xmlNodePtr node)

o = setup_func(node);
o->shrink = TRUE;
o->fill = FALSE;

return o;
}
Expand Down Expand Up @@ -97,6 +127,58 @@ static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h)
return FALSE;
}

static gboolean do_grow_all_edges(ObActionsData* data,
ObClientDirectionalResizeType resize_type)
{
gint x, y, w, h;
gint temp_x, temp_y, temp_w, temp_h;

client_find_resize_directional(data->client,
OB_DIRECTION_NORTH,
resize_type,
&temp_x, &temp_y, &temp_w, &temp_h);
y = temp_y;
h = temp_h;

client_find_resize_directional(data->client,
OB_DIRECTION_SOUTH,
resize_type,
&temp_x, &temp_y, &temp_w, &temp_h);
h += temp_h - data->client->area.height;


client_find_resize_directional(data->client,
OB_DIRECTION_WEST,
resize_type,
&temp_x, &temp_y, &temp_w, &temp_h);
x = temp_x;
w = temp_w;

client_find_resize_directional(data->client,
OB_DIRECTION_EAST,
resize_type,
&temp_x, &temp_y, &temp_w, &temp_h);
w += temp_w - data->client->area.width;

/* When filling, we allow the window to move to an arbitrary x/y
position, since we'll be growing the other edge as well. */
int lw, lh;
client_try_configure(data->client, &x, &y, &w, &h, &lw, &lh, TRUE);

if (x == data->client->area.x &&
y == data->client->area.y &&
w == data->client->area.width &&
h == data->client->area.height)
{
return FALSE;
}

actions_client_move(data, TRUE);
client_move_resize(data->client, x, y, w, h);
actions_client_move(data, FALSE);
return TRUE;
}

static void free_func(gpointer o)
{
g_slice_free(Options, o);
Expand All @@ -106,34 +188,70 @@ static void free_func(gpointer o)
static gboolean run_func(ObActionsData *data, gpointer options)
{
Options *o = options;
gint x, y, w, h;
ObDirection opp;
gint half;

if (!data->client ||
/* don't allow vertical resize if shaded */
((o->dir == OB_DIRECTION_NORTH || o->dir == OB_DIRECTION_SOUTH) &&
data->client->shaded))
{
if (!data->client)
return FALSE;

gboolean doing_verical_resize =
o->dir == OB_DIRECTION_NORTH ||
o->dir == OB_DIRECTION_SOUTH ||
o->fill;
if (data->client->shaded && doing_verical_resize)
return FALSE;

if (o->fill) {
if (o->shrink) {
/* We don't have any implementation of shrinking for the FillToGrow
action. */
return FALSE;
}

if (do_grow_all_edges(data, CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE))
return FALSE;

/* If all the edges are blocked, then allow them to jump past their
current block points. */
if (!o->once)
do_grow_all_edges(data, CLIENT_RESIZE_GROW);

return FALSE;
}

if (!o->shrink) {
/* try grow */
client_find_resize_directional(data->client, o->dir, TRUE,
gint x, y, w, h;

/* Try grow. */
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);

if (do_grow(data, x, y, w, h))
return FALSE;
}

/* we couldn't grow, so try shrink! */
opp = (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH :
(o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH :
(o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST :
OB_DIRECTION_EAST)));
client_find_resize_directional(data->client, opp, FALSE,
/* We couldn't grow, so try shrink! */
ObDirection opposite =
(o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH :
(o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH :
(o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST :
OB_DIRECTION_EAST)));

gint x, y, w, h;
gint half;

client_find_resize_directional(data->client,
opposite,
CLIENT_RESIZE_SHRINK,
&x, &y, &w, &h);
switch (opp) {

switch (opposite) {
case OB_DIRECTION_NORTH:
half = data->client->area.y + data->client->area.height / 2;
if (y > half) {
Expand Down Expand Up @@ -172,6 +290,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;

return o;
}

Expand All @@ -180,6 +300,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;

return o;
}

Expand All @@ -188,6 +310,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;

return o;
}

Expand All @@ -196,5 +320,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;

return o;
}
76 changes: 65 additions & 11 deletions openbox/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -4535,40 +4535,94 @@ void client_find_move_directional(ObClient *self, ObDirection dir,
frame_frame_gravity(self->frame, x, y);
}

void client_find_resize_directional(ObClient *self, ObDirection side,
gboolean grow,
void client_find_resize_directional(ObClient *self,
ObDirection side,
ObClientDirectionalResizeType resize_type,
gint *x, gint *y, gint *w, gint *h)
{
gint head;
gint e, e_start, e_size, delta;
gboolean near;
ObDirection dir;

gboolean grow;
switch (resize_type) {
case CLIENT_RESIZE_GROW:
grow = TRUE;
break;
case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
grow = TRUE;
break;
case CLIENT_RESIZE_SHRINK:
grow = FALSE;
break;
}

switch (side) {
case OB_DIRECTION_EAST:
head = RECT_RIGHT(self->frame->area) +
(self->size_inc.width - 1) * (grow ? 1 : 0);
head = RECT_RIGHT(self->frame->area);
switch (resize_type) {
case CLIENT_RESIZE_GROW:
head += self->size_inc.width - 1;
break;
case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
head -= 1;
break;
case CLIENT_RESIZE_SHRINK:
break;
}

e_start = RECT_TOP(self->frame->area);
e_size = self->frame->area.height;
dir = grow ? OB_DIRECTION_EAST : OB_DIRECTION_WEST;
break;
case OB_DIRECTION_WEST:
head = RECT_LEFT(self->frame->area) -
(self->size_inc.width - 1) * (grow ? 1 : 0);
head = RECT_LEFT(self->frame->area);
switch (resize_type) {
case CLIENT_RESIZE_GROW:
head -= self->size_inc.width - 1;
break;
case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
head += 1;
break;
case CLIENT_RESIZE_SHRINK:
break;
}

e_start = RECT_TOP(self->frame->area);
e_size = self->frame->area.height;
dir = grow ? OB_DIRECTION_WEST : OB_DIRECTION_EAST;
break;
case OB_DIRECTION_NORTH:
head = RECT_TOP(self->frame->area) -
(self->size_inc.height - 1) * (grow ? 1 : 0);
head = RECT_TOP(self->frame->area);
switch (resize_type) {
case CLIENT_RESIZE_GROW:
head -= self->size_inc.height - 1;
break;
case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
head += 1;
break;
case CLIENT_RESIZE_SHRINK:
break;
}

e_start = RECT_LEFT(self->frame->area);
e_size = self->frame->area.width;
dir = grow ? OB_DIRECTION_NORTH : OB_DIRECTION_SOUTH;
break;
case OB_DIRECTION_SOUTH:
head = RECT_BOTTOM(self->frame->area) +
(self->size_inc.height - 1) * (grow ? 1 : 0);
head = RECT_BOTTOM(self->frame->area);
switch (resize_type) {
case CLIENT_RESIZE_GROW:
head += self->size_inc.height - 1;
break;
case CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE:
head -= 1;
break;
case CLIENT_RESIZE_SHRINK:
break;
}

e_start = RECT_LEFT(self->frame->area);
e_size = self->frame->area.width;
dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH;
Expand Down Expand Up @@ -4607,7 +4661,7 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
if (grow == near) --e;
delta = e - RECT_BOTTOM(self->frame->area);
*h += delta;
break;
break;
default:
g_assert_not_reached();
}
Expand Down
13 changes: 11 additions & 2 deletions openbox/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,17 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
gint *dest, gboolean *near_edge);
void client_find_move_directional(ObClient *self, ObDirection dir,
gint *x, gint *y);
void client_find_resize_directional(ObClient *self, ObDirection side,
gboolean grow,

typedef enum {
CLIENT_RESIZE_GROW,
CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE,
CLIENT_RESIZE_SHRINK,
} ObClientDirectionalResizeType;

/*! Moves the client area passed in to grow/shrink the given edge. */
void client_find_resize_directional(ObClient *self,
ObDirection side,
ObClientDirectionalResizeType resize_type,
gint *x, gint *y, gint *w, gint *h);

/*! Fullscreen's or unfullscreen's the client window
Expand Down
Loading