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 if (data->layer.layer < 0)
385 client_set_layer(c, c->below ? 0 : -1);
386 else if (data->layer.layer > 0)
387 client_set_layer(c, c->above ? 0 : 1);
388 client_action_end(data, config_focus_under_mouse);
391 void action_toggle_dockautohide(union ActionData *data)
395 void action_remove_desktop(union ActionData *data)