1 #include "openbox/actions.h"
2 #include "openbox/prop.h"
3 #include "openbox/moveresize.h"
4 #include "openbox/client.h"
5 #include "openbox/frame.h"
8 gboolean corner_specified
;
12 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
);
13 static void free_func(gpointer options
);
14 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
16 static guint32
pick_corner(gint x
, gint y
, gint cx
, gint cy
, gint cw
, gint ch
,
19 void action_resize_startup(void)
21 actions_register("Resize",
28 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
)
33 o
= g_new0(Options
, 1);
35 if ((n
= parse_find_node("edge", node
))) {
36 gchar
*s
= parse_string(doc
, n
);
38 o
->corner_specified
= TRUE
;
39 if (!g_ascii_strcasecmp(s
, "top"))
40 o
->corner
= prop_atoms
.net_wm_moveresize_size_top
;
41 else if (!g_ascii_strcasecmp(s
, "bottom"))
42 o
->corner
= prop_atoms
.net_wm_moveresize_size_bottom
;
43 else if (!g_ascii_strcasecmp(s
, "left"))
44 o
->corner
= prop_atoms
.net_wm_moveresize_size_left
;
45 else if (!g_ascii_strcasecmp(s
, "right"))
46 o
->corner
= prop_atoms
.net_wm_moveresize_size_right
;
47 else if (!g_ascii_strcasecmp(s
, "topleft"))
48 o
->corner
= prop_atoms
.net_wm_moveresize_size_topleft
;
49 else if (!g_ascii_strcasecmp(s
, "topright"))
50 o
->corner
= prop_atoms
.net_wm_moveresize_size_topright
;
51 else if (!g_ascii_strcasecmp(s
, "bottomleft"))
52 o
->corner
= prop_atoms
.net_wm_moveresize_size_bottomleft
;
53 else if (!g_ascii_strcasecmp(s
, "bottomright"))
54 o
->corner
= prop_atoms
.net_wm_moveresize_size_bottomright
;
56 o
->corner_specified
= FALSE
;
63 static void free_func(gpointer options
)
70 /* Always return FALSE because its not interactive */
71 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
76 ObClient
*c
= data
->client
;
80 corner
= prop_atoms
.net_wm_moveresize_size_keyboard
;
81 else if (o
->corner_specified
)
82 corner
= o
->corner
; /* it was specified in the binding */
84 corner
= pick_corner(data
->x
, data
->y
,
85 c
->frame
->area
.x
, c
->frame
->area
.y
,
86 /* use the client size because the frame
87 can be differently sized (shaded
88 windows) and we want this based on the
90 c
->area
.width
+ c
->frame
->size
.left
+
92 c
->area
.height
+ c
->frame
->size
.top
+
93 c
->frame
->size
.bottom
, c
->shaded
);
95 moveresize_start(c
, data
->x
, data
->y
, data
->button
, corner
);
101 static guint32
pick_corner(gint x
, gint y
, gint cx
, gint cy
, gint cw
, gint ch
,
104 /* let's make x and y client relative instead of screen relative */
106 y
= ch
- (y
- cy
); /* y is inverted, 0 is at the bottom of the window */
109 #define A -4*X + 7*ch/3
110 #define B 4*X -15*ch/9
111 #define C -X/4 + 2*ch/3
112 #define D X/4 + 5*ch/12
114 #define F -X/4 + 7*ch/12
115 #define G 4*X - 4*ch/3
116 #define H -4*X + 8*ch/3
117 #define a (y > 5*ch/9)
118 #define b (x < 4*cw/9)
119 #define c (x > 5*cw/9)
120 #define d (y < 4*ch/9)
123 Each of these defines (except X which is just there for fun), represents
124 the equation of a line. The lines they represent are shown in the diagram
125 below. Checking y against these lines, we are able to choose a region
126 of the window as shown.
128 +---------------------A-------|-------|-------B---------------------+
135 | northwest | A north B | northeast |
138 C---------------------+----A--+-------+--B----+---------------------D
139 |CCCCCCC | A B | DDDDDDD|
140 | CCCCCCCC | A | | B | DDDDDDDD |
141 | CCCCCCC A B DDDDDDD |
142 - - - - - - - - - - - +CCCCCCC+aaaaaaa+DDDDDDD+ - - - - - - - - - - - -
144 | west | b move c | east | ad
146 - - - - - - - - - - - +EEEEEEE+ddddddd+FFFFFFF+- - - - - - - - - - - -
147 | EEEEEEE G H FFFFFFF |
148 | EEEEEEEE | G | | H | FFFFFFFF |
149 |EEEEEEE | G H | FFFFFFF|
150 E---------------------+----G--+-------+--H----+---------------------F
153 | southwest | G south H | southeast |
160 +---------------------G-------|-------|-------H---------------------+
164 /* for shaded windows, you can only resize west/east and move */
166 return prop_atoms
.net_wm_moveresize_size_left
;
168 return prop_atoms
.net_wm_moveresize_size_right
;
169 return prop_atoms
.net_wm_moveresize_move
;
173 return prop_atoms
.net_wm_moveresize_size_topleft
;
174 else if (y
>= A
&& y
>= B
&& a
)
175 return prop_atoms
.net_wm_moveresize_size_top
;
176 else if (y
< B
&& y
>= D
)
177 return prop_atoms
.net_wm_moveresize_size_topright
;
178 else if (y
< C
&& y
>= E
&& b
)
179 return prop_atoms
.net_wm_moveresize_size_left
;
180 else if (y
< D
&& y
>= F
&& c
)
181 return prop_atoms
.net_wm_moveresize_size_right
;
182 else if (y
< E
&& y
>= G
)
183 return prop_atoms
.net_wm_moveresize_size_bottomleft
;
184 else if (y
< G
&& y
< H
&& d
)
185 return prop_atoms
.net_wm_moveresize_size_bottom
;
186 else if (y
>= H
&& y
< F
)
187 return prop_atoms
.net_wm_moveresize_size_bottomright
;
189 return prop_atoms
.net_wm_moveresize_move
;