add the resize action

This commit is contained in:
Dana Jansens 2007-06-22 18:47:30 +00:00
parent 7e6f7fb454
commit 976add5938
5 changed files with 201 additions and 162 deletions

View file

@ -179,6 +179,7 @@ openbox_openbox_SOURCES = \
openbox/actions/raise.c \
openbox/actions/raiselower.c \
openbox/actions/reconfigure.c \
openbox/actions/resize.c \
openbox/actions/restart.c \
openbox/actions/shade.c \
openbox/actions/showdesktop.c \

View file

@ -437,11 +437,6 @@ ActionString actionstrings[] =
action_toggle_decorations,
setup_client_action
},
{
"resize",
action_resize,
setup_action_resize
},
{
"toggledockautohide",
action_toggle_dockautohide,
@ -643,35 +638,6 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.sendtodir.inter.any.interactive =
parse_bool(doc, n);
} else if (act->func == action_resize) {
if ((n = parse_find_node("edge", node->xmlChildrenNode))) {
gchar *s = parse_string(doc, n);
if (!g_ascii_strcasecmp(s, "top"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_top;
else if (!g_ascii_strcasecmp(s, "bottom"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_bottom;
else if (!g_ascii_strcasecmp(s, "left"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_left;
else if (!g_ascii_strcasecmp(s, "right"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_right;
else if (!g_ascii_strcasecmp(s, "topleft"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_topleft;
else if (!g_ascii_strcasecmp(s, "topright"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_topright;
else if (!g_ascii_strcasecmp(s, "bottomleft"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_bottomleft;
else if (!g_ascii_strcasecmp(s, "bottomright"))
act->data.moveresize.corner =
prop_atoms.net_wm_moveresize_size_bottomright;
g_free(s);
}
INTERACTIVE_LIMIT(act, uact);
}
g_free(actname);
@ -933,134 +899,6 @@ void action_toggle_decorations(union ActionData *data)
client_action_end(data, FALSE);
}
static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
gboolean shaded)
{
/* let's make x and y client relative instead of screen relative */
x = x - cx;
y = ch - (y - cy); /* y is inverted, 0 is at the bottom of the window */
#define X x*ch/cw
#define A -4*X + 7*ch/3
#define B 4*X -15*ch/9
#define C -X/4 + 2*ch/3
#define D X/4 + 5*ch/12
#define E X/4 + ch/3
#define F -X/4 + 7*ch/12
#define G 4*X - 4*ch/3
#define H -4*X + 8*ch/3
#define a (y > 5*ch/9)
#define b (x < 4*cw/9)
#define c (x > 5*cw/9)
#define d (y < 4*ch/9)
/*
Each of these defines (except X which is just there for fun), represents
the equation of a line. The lines they represent are shown in the diagram
below. Checking y against these lines, we are able to choose a region
of the window as shown.
+---------------------A-------|-------|-------B---------------------+
| |A B| |
| |A | | B| |
| | A B | |
| | A | | B | |
| | A B | |
| | A | | B | |
| northwest | A north B | northeast |
| | A | | B | |
| | A B | |
C---------------------+----A--+-------+--B----+---------------------D
|CCCCCCC | A B | DDDDDDD|
| CCCCCCCC | A | | B | DDDDDDDD |
| CCCCCCC A B DDDDDDD |
- - - - - - - - - - - +CCCCCCC+aaaaaaa+DDDDDDD+ - - - - - - - - - - - -
| | b c | | sh
| west | b move c | east | ad
| | b c | | ed
- - - - - - - - - - - +EEEEEEE+ddddddd+FFFFFFF+- - - - - - - - - - - -
| EEEEEEE G H FFFFFFF |
| EEEEEEEE | G | | H | FFFFFFFF |
|EEEEEEE | G H | FFFFFFF|
E---------------------+----G--+-------+--H----+---------------------F
| | G H | |
| | G | | H | |
| southwest | G south H | southeast |
| | G | | H | |
| | G H | |
| | G | | H | |
| | G H | |
| |G | | H| |
| |G H| |
+---------------------G-------|-------|-------H---------------------+
*/
if (shaded) {
/* for shaded windows, you can only resize west/east and move */
if (b)
return prop_atoms.net_wm_moveresize_size_left;
if (c)
return prop_atoms.net_wm_moveresize_size_right;
return prop_atoms.net_wm_moveresize_move;
}
if (y < A && y >= C)
return prop_atoms.net_wm_moveresize_size_topleft;
else if (y >= A && y >= B && a)
return prop_atoms.net_wm_moveresize_size_top;
else if (y < B && y >= D)
return prop_atoms.net_wm_moveresize_size_topright;
else if (y < C && y >= E && b)
return prop_atoms.net_wm_moveresize_size_left;
else if (y < D && y >= F && c)
return prop_atoms.net_wm_moveresize_size_right;
else if (y < E && y >= G)
return prop_atoms.net_wm_moveresize_size_bottomleft;
else if (y < G && y < H && d)
return prop_atoms.net_wm_moveresize_size_bottom;
else if (y >= H && y < F)
return prop_atoms.net_wm_moveresize_size_bottomright;
else
return prop_atoms.net_wm_moveresize_move;
#undef X
#undef A
#undef B
#undef C
#undef D
#undef E
#undef F
#undef G
#undef H
#undef a
#undef b
#undef c
#undef d
}
void action_resize(union ActionData *data)
{
ObClient *c = data->moveresize.any.c;
guint32 corner;
if (data->moveresize.keyboard)
corner = prop_atoms.net_wm_moveresize_size_keyboard;
else if (data->moveresize.corner)
corner = data->moveresize.corner; /* it was specified in the binding */
else
corner = pick_corner(data->any.x, data->any.y,
c->frame->area.x, c->frame->area.y,
/* use the client size because the frame
can be differently sized (shaded
windows) and we want this based on the
clients size */
c->area.width + c->frame->size.left +
c->frame->size.right,
c->area.height + c->frame->size.top +
c->frame->size.bottom, c->shaded);
moveresize_start(c, data->any.x, data->any.y, data->any.button, corner);
}
void action_directional_focus(union ActionData *data)
{

View file

@ -30,4 +30,5 @@ void action_all_startup()
action_omnipresent_startup();
action_directionalcyclewindows_startup();
action_directionaltargetwindow_startup();
action_resize_startup();
}

View file

@ -31,5 +31,6 @@ void action_kill_startup();
void action_omnipresent_startup();
void action_directionalcyclewindows_startup();
void action_directionaltargetwindow_startup();
void action_resize_startup();
#endif

198
openbox/actions/resize.c Normal file
View file

@ -0,0 +1,198 @@
#include "openbox/actions.h"
#include "openbox/prop.h"
#include "openbox/moveresize.h"
#include "openbox/client.h"
#include "openbox/frame.h"
typedef struct {
guint32 corner;
} Options;
static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
static void free_func(gpointer options);
static gboolean run_func(ObActionsData *data, gpointer options);
static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
gboolean shaded);
void action_resize_startup()
{
actions_register("Resize",
setup_func,
free_func,
run_func,
NULL, NULL);
}
static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
{
xmlNodePtr n;
Options *o;
o = g_new0(Options, 1);
if ((n = parse_find_node("edge", node))) {
gchar *s = parse_string(doc, n);
if (!g_ascii_strcasecmp(s, "top"))
o->corner = prop_atoms.net_wm_moveresize_size_top;
else if (!g_ascii_strcasecmp(s, "bottom"))
o->corner = prop_atoms.net_wm_moveresize_size_bottom;
else if (!g_ascii_strcasecmp(s, "left"))
o->corner = prop_atoms.net_wm_moveresize_size_left;
else if (!g_ascii_strcasecmp(s, "right"))
o->corner = prop_atoms.net_wm_moveresize_size_right;
else if (!g_ascii_strcasecmp(s, "topleft"))
o->corner = prop_atoms.net_wm_moveresize_size_topleft;
else if (!g_ascii_strcasecmp(s, "topright"))
o->corner = prop_atoms.net_wm_moveresize_size_topright;
else if (!g_ascii_strcasecmp(s, "bottomleft"))
o->corner = prop_atoms.net_wm_moveresize_size_bottomleft;
else if (!g_ascii_strcasecmp(s, "bottomright"))
o->corner = prop_atoms.net_wm_moveresize_size_bottomright;
g_free(s);
}
return o;
}
static void free_func(gpointer options)
{
Options *o = options;
g_free(o);
}
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
Options *o = options;
if (data->client) {
ObClient *c = data->client;
guint32 corner;
if (!data->button)
corner = prop_atoms.net_wm_moveresize_size_keyboard;
else if (o->corner)
corner = o->corner; /* it was specified in the binding */
else
corner = pick_corner(data->x, data->y,
c->frame->area.x, c->frame->area.y,
/* use the client size because the frame
can be differently sized (shaded
windows) and we want this based on the
clients size */
c->area.width + c->frame->size.left +
c->frame->size.right,
c->area.height + c->frame->size.top +
c->frame->size.bottom, c->shaded);
moveresize_start(c, data->x, data->y, data->button, corner);
}
return FALSE;
}
static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
gboolean shaded)
{
/* let's make x and y client relative instead of screen relative */
x = x - cx;
y = ch - (y - cy); /* y is inverted, 0 is at the bottom of the window */
#define X x*ch/cw
#define A -4*X + 7*ch/3
#define B 4*X -15*ch/9
#define C -X/4 + 2*ch/3
#define D X/4 + 5*ch/12
#define E X/4 + ch/3
#define F -X/4 + 7*ch/12
#define G 4*X - 4*ch/3
#define H -4*X + 8*ch/3
#define a (y > 5*ch/9)
#define b (x < 4*cw/9)
#define c (x > 5*cw/9)
#define d (y < 4*ch/9)
/*
Each of these defines (except X which is just there for fun), represents
the equation of a line. The lines they represent are shown in the diagram
below. Checking y against these lines, we are able to choose a region
of the window as shown.
+---------------------A-------|-------|-------B---------------------+
| |A B| |
| |A | | B| |
| | A B | |
| | A | | B | |
| | A B | |
| | A | | B | |
| northwest | A north B | northeast |
| | A | | B | |
| | A B | |
C---------------------+----A--+-------+--B----+---------------------D
|CCCCCCC | A B | DDDDDDD|
| CCCCCCCC | A | | B | DDDDDDDD |
| CCCCCCC A B DDDDDDD |
- - - - - - - - - - - +CCCCCCC+aaaaaaa+DDDDDDD+ - - - - - - - - - - - -
| | b c | | sh
| west | b move c | east | ad
| | b c | | ed
- - - - - - - - - - - +EEEEEEE+ddddddd+FFFFFFF+- - - - - - - - - - - -
| EEEEEEE G H FFFFFFF |
| EEEEEEEE | G | | H | FFFFFFFF |
|EEEEEEE | G H | FFFFFFF|
E---------------------+----G--+-------+--H----+---------------------F
| | G H | |
| | G | | H | |
| southwest | G south H | southeast |
| | G | | H | |
| | G H | |
| | G | | H | |
| | G H | |
| |G | | H| |
| |G H| |
+---------------------G-------|-------|-------H---------------------+
*/
if (shaded) {
/* for shaded windows, you can only resize west/east and move */
if (b)
return prop_atoms.net_wm_moveresize_size_left;
if (c)
return prop_atoms.net_wm_moveresize_size_right;
return prop_atoms.net_wm_moveresize_move;
}
if (y < A && y >= C)
return prop_atoms.net_wm_moveresize_size_topleft;
else if (y >= A && y >= B && a)
return prop_atoms.net_wm_moveresize_size_top;
else if (y < B && y >= D)
return prop_atoms.net_wm_moveresize_size_topright;
else if (y < C && y >= E && b)
return prop_atoms.net_wm_moveresize_size_left;
else if (y < D && y >= F && c)
return prop_atoms.net_wm_moveresize_size_right;
else if (y < E && y >= G)
return prop_atoms.net_wm_moveresize_size_bottomleft;
else if (y < G && y < H && d)
return prop_atoms.net_wm_moveresize_size_bottom;
else if (y >= H && y < F)
return prop_atoms.net_wm_moveresize_size_bottomright;
else
return prop_atoms.net_wm_moveresize_move;
#undef X
#undef A
#undef B
#undef C
#undef D
#undef E
#undef F
#undef G
#undef H
#undef a
#undef b
#undef c
#undef d
}