1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 action.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
23 #include "focus_cycle.h"
24 #include "moveresize.h"
37 #include "startupnotify.h"
45 void setup_action_movefromedge_north(ObAction
**a
, ObUserAction uact
)
47 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
48 (*a
)->data
.diraction
.direction
= OB_DIRECTION_NORTH
;
49 (*a
)->data
.diraction
.hang
= TRUE
;
52 void setup_action_movefromedge_south(ObAction
**a
, ObUserAction uact
)
54 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
55 (*a
)->data
.diraction
.direction
= OB_DIRECTION_SOUTH
;
56 (*a
)->data
.diraction
.hang
= TRUE
;
59 void setup_action_movefromedge_east(ObAction
**a
, ObUserAction uact
)
61 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
62 (*a
)->data
.diraction
.direction
= OB_DIRECTION_EAST
;
63 (*a
)->data
.diraction
.hang
= TRUE
;
66 void setup_action_movefromedge_west(ObAction
**a
, ObUserAction uact
)
68 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
69 (*a
)->data
.diraction
.direction
= OB_DIRECTION_WEST
;
70 (*a
)->data
.diraction
.hang
= TRUE
;
73 void setup_action_movetoedge_north(ObAction
**a
, ObUserAction uact
)
75 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
76 (*a
)->data
.diraction
.direction
= OB_DIRECTION_NORTH
;
77 (*a
)->data
.diraction
.hang
= FALSE
;
80 void setup_action_movetoedge_south(ObAction
**a
, ObUserAction uact
)
82 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
83 (*a
)->data
.diraction
.direction
= OB_DIRECTION_SOUTH
;
84 (*a
)->data
.diraction
.hang
= FALSE
;
87 void setup_action_movetoedge_east(ObAction
**a
, ObUserAction uact
)
89 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
90 (*a
)->data
.diraction
.direction
= OB_DIRECTION_EAST
;
91 (*a
)->data
.diraction
.hang
= FALSE
;
94 void setup_action_movetoedge_west(ObAction
**a
, ObUserAction uact
)
96 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
97 (*a
)->data
.diraction
.direction
= OB_DIRECTION_WEST
;
98 (*a
)->data
.diraction
.hang
= FALSE
;
101 void setup_action_growtoedge_north(ObAction
**a
, ObUserAction uact
)
103 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
104 (*a
)->data
.diraction
.direction
= OB_DIRECTION_NORTH
;
107 void setup_action_growtoedge_south(ObAction
**a
, ObUserAction uact
)
109 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
110 (*a
)->data
.diraction
.direction
= OB_DIRECTION_SOUTH
;
113 void setup_action_growtoedge_east(ObAction
**a
, ObUserAction uact
)
115 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
116 (*a
)->data
.diraction
.direction
= OB_DIRECTION_EAST
;
119 void setup_action_growtoedge_west(ObAction
**a
, ObUserAction uact
)
121 (*a
)->data
.diraction
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
122 (*a
)->data
.diraction
.direction
= OB_DIRECTION_WEST
;
125 void setup_action_top_layer(ObAction
**a
, ObUserAction uact
)
127 (*a
)->data
.layer
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
128 (*a
)->data
.layer
.layer
= 1;
131 void setup_action_normal_layer(ObAction
**a
, ObUserAction uact
)
133 (*a
)->data
.layer
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
134 (*a
)->data
.layer
.layer
= 0;
137 void setup_action_bottom_layer(ObAction
**a
, ObUserAction uact
)
139 (*a
)->data
.layer
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
140 (*a
)->data
.layer
.layer
= -1;
143 void setup_client_action(ObAction
**a
, ObUserAction uact
)
145 (*a
)->data
.any
.client_action
= OB_CLIENT_ACTION_ALWAYS
;
148 ActionString actionstrings
[] =
162 action_send_to_layer
,
163 setup_action_top_layer
168 setup_action_top_layer
172 action_send_to_layer
,
173 setup_action_normal_layer
177 action_send_to_layer
,
178 setup_action_bottom_layer
181 "togglealwaysonbottom",
183 setup_action_bottom_layer
188 setup_action_movefromedge_north
193 setup_action_movefromedge_south
198 setup_action_movefromedge_west
203 setup_action_movefromedge_east
208 setup_action_movetoedge_north
213 setup_action_movetoedge_south
218 setup_action_movetoedge_west
223 setup_action_movetoedge_east
228 setup_action_growtoedge_north
233 setup_action_growtoedge_south
238 setup_action_growtoedge_west
243 setup_action_growtoedge_east
252 void action_unshaderaise(union ActionData
*data
)
254 if (data
->client
.any
.c
->shaded
)
255 action_unshade(data
);
260 void action_shadelower(union ActionData
*data
)
262 if (data
->client
.any
.c
->shaded
)
268 void action_movetoedge(union ActionData
*data
)
271 ObClient
*c
= data
->diraction
.any
.c
;
273 x
= c
->frame
->area
.x
;
274 y
= c
->frame
->area
.y
;
276 switch(data
->diraction
.direction
) {
277 case OB_DIRECTION_NORTH
:
278 y
= client_directional_edge_search(c
, OB_DIRECTION_NORTH
,
279 data
->diraction
.hang
)
280 - (data
->diraction
.hang
? c
->frame
->area
.height
: 0);
282 case OB_DIRECTION_WEST
:
283 x
= client_directional_edge_search(c
, OB_DIRECTION_WEST
,
284 data
->diraction
.hang
)
285 - (data
->diraction
.hang
? c
->frame
->area
.width
: 0);
287 case OB_DIRECTION_SOUTH
:
288 y
= client_directional_edge_search(c
, OB_DIRECTION_SOUTH
,
289 data
->diraction
.hang
)
290 - (data
->diraction
.hang
? 0 : c
->frame
->area
.height
);
292 case OB_DIRECTION_EAST
:
293 x
= client_directional_edge_search(c
, OB_DIRECTION_EAST
,
294 data
->diraction
.hang
)
295 - (data
->diraction
.hang
? 0 : c
->frame
->area
.width
);
298 g_assert_not_reached();
300 frame_frame_gravity(c
->frame
, &x
, &y
, c
->area
.width
, c
->area
.height
);
301 client_action_start(data
);
302 client_move(c
, x
, y
);
303 client_action_end(data
, FALSE
);
306 void action_growtoedge(union ActionData
*data
)
308 gint x
, y
, width
, height
, dest
;
309 ObClient
*c
= data
->diraction
.any
.c
;
312 a
= screen_area(c
->desktop
, SCREEN_AREA_ALL_MONITORS
, &c
->frame
->area
);
313 x
= c
->frame
->area
.x
;
314 y
= c
->frame
->area
.y
;
315 /* get the unshaded frame's dimensions..if it is shaded */
316 width
= c
->area
.width
+ c
->frame
->size
.left
+ c
->frame
->size
.right
;
317 height
= c
->area
.height
+ c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
319 switch(data
->diraction
.direction
) {
320 case OB_DIRECTION_NORTH
:
321 if (c
->shaded
) break; /* don't allow vertical resize if shaded */
323 dest
= client_directional_edge_search(c
, OB_DIRECTION_NORTH
, FALSE
);
327 height
= c
->frame
->area
.y
+ height
- dest
;
331 case OB_DIRECTION_WEST
:
332 dest
= client_directional_edge_search(c
, OB_DIRECTION_WEST
, FALSE
);
336 width
= c
->frame
->area
.x
+ width
- dest
;
340 case OB_DIRECTION_SOUTH
:
341 if (c
->shaded
) break; /* don't allow vertical resize if shaded */
343 dest
= client_directional_edge_search(c
, OB_DIRECTION_SOUTH
, FALSE
);
344 if (a
->y
+ a
->height
== y
+ c
->frame
->area
.height
) {
345 height
= c
->frame
->area
.height
/ 2;
346 y
= a
->y
+ a
->height
- height
;
348 height
= dest
- c
->frame
->area
.y
;
349 y
+= (height
- c
->frame
->area
.height
) % c
->size_inc
.height
;
350 height
-= (height
- c
->frame
->area
.height
) % c
->size_inc
.height
;
352 case OB_DIRECTION_EAST
:
353 dest
= client_directional_edge_search(c
, OB_DIRECTION_EAST
, FALSE
);
354 if (a
->x
+ a
->width
== x
+ c
->frame
->area
.width
) {
355 width
= c
->frame
->area
.width
/ 2;
356 x
= a
->x
+ a
->width
- width
;
358 width
= dest
- c
->frame
->area
.x
;
359 x
+= (width
- c
->frame
->area
.width
) % c
->size_inc
.width
;
360 width
-= (width
- c
->frame
->area
.width
) % c
->size_inc
.width
;
363 g_assert_not_reached();
365 width
-= c
->frame
->size
.left
+ c
->frame
->size
.right
;
366 height
-= c
->frame
->size
.top
+ c
->frame
->size
.bottom
;
367 frame_frame_gravity(c
->frame
, &x
, &y
, width
, height
);
368 client_action_start(data
);
369 client_move_resize(c
, x
, y
, width
, height
);
370 client_action_end(data
, FALSE
);
374 void action_send_to_layer(union ActionData
*data
)
376 client_set_layer(data
->layer
.any
.c
, data
->layer
.layer
);
379 void action_toggle_layer(union ActionData
*data
)
381 ObClient
*c
= data
->layer
.any
.c
;
383 client_action_start(data
);
384 client_action_end(data
, config_focus_under_mouse
);