/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
action.c for the Openbox window manager
+ Copyright (c) 2006 Mikael Magnusson
Copyright (c) 2003 Ben Jansens
This program is free software; you can redistribute it and/or modify
#include "grab.h"
#include "keyboard.h"
#include "event.h"
+#include "dock.h"
#include "config.h"
#include "mainloop.h"
(*a)->data.cycle.dialog = TRUE;
}
+void setup_action_movefromedge_north(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+ (*a)->data.diraction.direction = OB_DIRECTION_NORTH;
+ (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_south(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+ (*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
+ (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_east(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+ (*a)->data.diraction.direction = OB_DIRECTION_EAST;
+ (*a)->data.diraction.hang = TRUE;
+}
+
+void setup_action_movefromedge_west(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
+ (*a)->data.diraction.direction = OB_DIRECTION_WEST;
+ (*a)->data.diraction.hang = TRUE;
+}
+
void setup_action_movetoedge_north(ObAction **a, ObUserAction uact)
{
(*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.diraction.direction = OB_DIRECTION_NORTH;
+ (*a)->data.diraction.hang = FALSE;
}
void setup_action_movetoedge_south(ObAction **a, ObUserAction uact)
{
(*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
+ (*a)->data.diraction.hang = FALSE;
}
void setup_action_movetoedge_east(ObAction **a, ObUserAction uact)
{
(*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.diraction.direction = OB_DIRECTION_EAST;
+ (*a)->data.diraction.hang = FALSE;
}
void setup_action_movetoedge_west(ObAction **a, ObUserAction uact)
{
(*a)->data.diraction.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.diraction.direction = OB_DIRECTION_WEST;
+ (*a)->data.diraction.hang = FALSE;
}
void setup_action_growtoedge_north(ObAction **a, ObUserAction uact)
action_iconify,
setup_client_action
},
+ {
+ "focustobottom",
+ action_focus_order_to_bottom,
+ setup_client_action
+ },
{
"raiselower",
action_raiselower,
action_move_relative_vert,
setup_client_action
},
+ {
+ "movetocenter",
+ action_move_to_center,
+ setup_client_action
+ },
{
"resizerelativehorz",
action_resize_relative_horz,
action_resize_relative_vert,
setup_client_action
},
+ {
+ "moverelative",
+ action_move_relative,
+ setup_client_action
+ },
+ {
+ "resizerelative",
+ action_resize_relative,
+ setup_client_action
+ },
{
"maximizefull",
action_maximize_full,
action_toggle_maximize_vert,
setup_client_action
},
+ {
+ "togglefullscreen",
+ action_toggle_fullscreen,
+ setup_client_action
+ },
{
"sendtodesktop",
action_send_to_desktop,
action_cycle_windows,
setup_action_cycle_windows_previous
},
+ {
+ "movefromedgenorth",
+ action_movetoedge,
+ setup_action_movefromedge_north
+ },
+ {
+ "movefromedgesouth",
+ action_movetoedge,
+ setup_action_movefromedge_south
+ },
+ {
+ "movefromedgewest",
+ action_movetoedge,
+ setup_action_movefromedge_west
+ },
+ {
+ "movefromedgeeast",
+ action_movetoedge,
+ setup_action_movefromedge_east
+ },
{
"movetoedgenorth",
action_movetoedge,
act->func == action_resize_relative_horz ||
act->func == action_resize_relative_vert) {
if ((n = parse_find_node("delta", node->xmlChildrenNode)))
- act->data.relative.delta = parse_int(doc, n);
+ act->data.relative.deltax = parse_int(doc, n);
+ } else if (act->func == action_move_relative) {
+ if ((n = parse_find_node("x", node->xmlChildrenNode)))
+ act->data.relative.deltax = parse_int(doc, n);
+ if ((n = parse_find_node("y", node->xmlChildrenNode)))
+ act->data.relative.deltay = parse_int(doc, n);
+ } else if (act->func == action_resize_relative) {
+ if ((n = parse_find_node("left", node->xmlChildrenNode)))
+ act->data.relative.deltaxl = parse_int(doc, n);
+ if ((n = parse_find_node("up", node->xmlChildrenNode)))
+ act->data.relative.deltayu = parse_int(doc, n);
+ if ((n = parse_find_node("right", node->xmlChildrenNode)))
+ act->data.relative.deltax = parse_int(doc, n);
+ if ((n = parse_find_node("down", node->xmlChildrenNode)))
+ act->data.relative.deltay = parse_int(doc, n);
} else if (act->func == action_desktop) {
if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
act->data.desktop.desk = parse_int(doc, n);
} else if (act->func == action_directional_focus) {
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.cycle.dialog = parse_bool(doc, n);
+ } else if (act->func == action_raise ||
+ act->func == action_lower ||
+ act->func == action_raiselower ||
+ act->func == action_shadelower ||
+ act->func == action_unshaderaise) {
+ if ((n = parse_find_node("group", node->xmlChildrenNode)))
+ act->data.stacking.group = parse_bool(doc, n);
}
INTERACTIVE_LIMIT(act, uact);
}
void action_unfocus (union ActionData *data)
{
- client_unfocus(data->client.any.c);
+ if (data->client.any.c == focus_client)
+ focus_fallback(OB_FOCUS_FALLBACK_UNFOCUSING);
}
void action_iconify(union ActionData *data)
{
+ client_action_start(data);
client_iconify(data->client.any.c, TRUE, TRUE);
+ client_action_end(data);
+}
+
+void action_focus_order_to_bottom(union ActionData *data)
+{
+ focus_order_to_bottom(data->client.any.c);
}
void action_raiselower(union ActionData *data)
gboolean raise = FALSE;
for (it = stacking_list; it; it = g_list_next(it)) {
- ObClient *cit = it->data;
-
- if (cit == c) break;
- if (client_normal(cit) == client_normal(c) &&
- cit->layer == c->layer &&
- cit->frame->visible &&
- !client_search_transient(c, cit))
- {
- if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
- raise = TRUE;
- break;
+ if (WINDOW_IS_CLIENT(it->data)) {
+ ObClient *cit = it->data;
+
+ if (cit == c) break;
+ if (client_normal(cit) == client_normal(c) &&
+ cit->layer == c->layer &&
+ cit->frame->visible &&
+ !client_search_transient(c, cit))
+ {
+ if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
+ raise = TRUE;
+ break;
+ }
}
}
}
void action_raise(union ActionData *data)
{
client_action_start(data);
- stacking_raise(CLIENT_AS_WINDOW(data->client.any.c));
+ stacking_raise(CLIENT_AS_WINDOW(data->client.any.c), data->stacking.group);
client_action_end(data);
}
void action_lower(union ActionData *data)
{
client_action_start(data);
- stacking_lower(CLIENT_AS_WINDOW(data->client.any.c));
+ stacking_lower(CLIENT_AS_WINDOW(data->client.any.c), data->stacking.group);
client_action_end(data);
}
{
ObClient *c = data->relative.any.c;
client_action_start(data);
- client_move(c, c->area.x + data->relative.delta, c->area.y);
+ client_move(c, c->area.x + data->relative.deltax, c->area.y);
client_action_end(data);
}
{
ObClient *c = data->relative.any.c;
client_action_start(data);
- client_move(c, c->area.x, c->area.y + data->relative.delta);
+ client_move(c, c->area.x, c->area.y + data->relative.deltax);
+ client_action_end(data);
+}
+
+void action_move_to_center(union ActionData *data)
+{
+ ObClient *c = data->client.any.c;
+ Rect *area;
+ area = screen_area_monitor(c->desktop, 0);
+ client_action_start(data);
+ client_move(c, area->width / 2 - c->area.width / 2,
+ area->height / 2 - c->area.height / 2);
client_action_end(data);
}
ObClient *c = data->relative.any.c;
client_action_start(data);
client_resize(c,
- c->area.width + data->relative.delta * c->size_inc.width,
+ c->area.width + data->relative.deltax * c->size_inc.width,
c->area.height);
client_action_end(data);
}
if (!c->shaded) {
client_action_start(data);
client_resize(c, c->area.width, c->area.height +
- data->relative.delta * c->size_inc.height);
+ data->relative.deltax * c->size_inc.height);
client_action_end(data);
}
}
+void action_move_relative(union ActionData *data)
+{
+ ObClient *c = data->relative.any.c;
+ client_action_start(data);
+ client_move(c, c->area.x + data->relative.deltax, c->area.y +
+ data->relative.deltay);
+ client_action_end(data);
+}
+
+void action_resize_relative(union ActionData *data)
+{
+ ObClient *c = data->relative.any.c;
+ client_action_start(data);
+ client_move_resize(c,
+ c->area.x - data->relative.deltaxl * c->size_inc.width,
+ c->area.y - data->relative.deltayu * c->size_inc.height,
+ c->area.width + data->relative.deltax * c->size_inc.width
+ + data->relative.deltaxl * c->size_inc.width,
+ c->area.height + data->relative.deltay * c->size_inc.height
+ + data->relative.deltayu * c->size_inc.height);
+ client_action_end(data);
+}
+
void action_maximize_full(union ActionData *data)
{
client_action_start(data);
client_action_end(data);
}
+void action_toggle_fullscreen(union ActionData *data)
+{
+ client_action_start(data);
+ client_fullscreen(data->client.any.c,
+ !(data->client.any.c->fullscreen), TRUE);
+ client_action_end(data);
+}
+
void action_send_to_desktop(union ActionData *data)
{
ObClient *c = data->sendto.any.c;
static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch)
{
- if ((cw / 3 < 1) || (x - cx > cw / 3 * 2)) {
- if ((ch / 3 < 1) || (y - cy > ch / 3 * 2))
- return prop_atoms.net_wm_moveresize_size_bottomright;
- else if (y - cy < ch / 3)
- return prop_atoms.net_wm_moveresize_size_topright;
- else
- return prop_atoms.net_wm_moveresize_size_right;
- } else if (x - cx < cw / 3) {
- if (y - cy > ch / 3 * 2)
- return prop_atoms.net_wm_moveresize_size_bottomleft;
- else if (y - cy < ch / 3)
- return prop_atoms.net_wm_moveresize_size_topleft;
- else
- return prop_atoms.net_wm_moveresize_size_left;
+ if (config_resize_four_corners) {
+ if (x - cx > cw / 2) {
+ if (y - cy > ch / 2)
+ return prop_atoms.net_wm_moveresize_size_bottomright;
+ else
+ return prop_atoms.net_wm_moveresize_size_topright;
+ } else {
+ if (y - cy > ch / 2)
+ return prop_atoms.net_wm_moveresize_size_bottomleft;
+ else
+ return prop_atoms.net_wm_moveresize_size_topleft;
+ }
} else {
- if (y - cy > ch / 2)
- return prop_atoms.net_wm_moveresize_size_bottom;
- else
- return prop_atoms.net_wm_moveresize_size_top;
+ if (x - cx > cw * 2 / 3) {
+ if (y - cy > ch * 2 / 3)
+ return prop_atoms.net_wm_moveresize_size_bottomright;
+ else if (y - cy < ch / 3)
+ return prop_atoms.net_wm_moveresize_size_topright;
+ else
+ return prop_atoms.net_wm_moveresize_size_right;
+ } else if (x - cx < cw / 3) {
+ if (y - cy > ch * 2 / 3)
+ return prop_atoms.net_wm_moveresize_size_bottomleft;
+ else if (y - cy < ch / 3)
+ return prop_atoms.net_wm_moveresize_size_topleft;
+ else
+ return prop_atoms.net_wm_moveresize_size_left;
+ } else
+ if (y - cy > ch * 2 / 3)
+ return prop_atoms.net_wm_moveresize_size_bottom;
+ else if (y - cy < ch / 3)
+ return prop_atoms.net_wm_moveresize_size_top;
+ else
+ return prop_atoms.net_wm_moveresize_move;
}
}
switch(data->diraction.direction) {
case OB_DIRECTION_NORTH:
- y = client_directional_edge_search(c, OB_DIRECTION_NORTH);
+ y = client_directional_edge_search(c, OB_DIRECTION_NORTH, data->diraction.hang)
+ - (data->diraction.hang ? c->frame->area.height : 0);
break;
case OB_DIRECTION_WEST:
- x = client_directional_edge_search(c, OB_DIRECTION_WEST);
+ x = client_directional_edge_search(c, OB_DIRECTION_WEST, data->diraction.hang)
+ - (data->diraction.hang ? c->frame->area.width : 0);
break;
case OB_DIRECTION_SOUTH:
- y = client_directional_edge_search(c, OB_DIRECTION_SOUTH) -
- c->frame->area.height;
+ y = client_directional_edge_search(c, OB_DIRECTION_SOUTH, data->diraction.hang)
+ - (data->diraction.hang ? 0 : c->frame->area.height);
break;
case OB_DIRECTION_EAST:
- x = client_directional_edge_search(c, OB_DIRECTION_EAST) -
- c->frame->area.width;
+ x = client_directional_edge_search(c, OB_DIRECTION_EAST, data->diraction.hang)
+ - (data->diraction.hang ? 0 : c->frame->area.width);
break;
default:
g_assert_not_reached();
ObClient *c = data->diraction.any.c;
Rect *a;
+ //FIXME growtoedge resizes shaded windows to 0 height
+ if (c->shaded)
+ return;
+
a = screen_area(c->desktop);
x = c->frame->area.x;
y = c->frame->area.y;
switch(data->diraction.direction) {
case OB_DIRECTION_NORTH:
- dest = client_directional_edge_search(c, OB_DIRECTION_NORTH);
+ dest = client_directional_edge_search(c, OB_DIRECTION_NORTH, FALSE);
if (a->y == y)
height = c->frame->area.height / 2;
else {
}
break;
case OB_DIRECTION_WEST:
- dest = client_directional_edge_search(c, OB_DIRECTION_WEST);
+ dest = client_directional_edge_search(c, OB_DIRECTION_WEST, FALSE);
if (a->x == x)
width = c->frame->area.width / 2;
else {
}
break;
case OB_DIRECTION_SOUTH:
- dest = client_directional_edge_search(c, OB_DIRECTION_SOUTH);
+ dest = client_directional_edge_search(c, OB_DIRECTION_SOUTH, FALSE);
if (a->y + a->height == y + c->frame->area.height) {
height = c->frame->area.height / 2;
y = a->y + a->height - height;
height -= (height - c->frame->area.height) % c->size_inc.height;
break;
case OB_DIRECTION_EAST:
- dest = client_directional_edge_search(c, OB_DIRECTION_EAST);
+ dest = client_directional_edge_search(c, OB_DIRECTION_EAST, FALSE);
if (a->x + a->width == x + c->frame->area.width) {
width = c->frame->area.width / 2;
x = a->x + a->width - width;