#include "grab.h"
#include "keyboard.h"
#include "event.h"
+#include "dock.h"
#include "config.h"
#include "mainloop.h"
a time! */
if (uact == OB_USER_ACTION_MENU_SELECTION) {
action_unref(*a);
- a = NULL;
+ *a = NULL;
}
}
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_moveresize,
setup_action_resize
},
+ {
+ "toggledockautohide",
+ action_toggle_dockautohide,
+ NULL
+ },
{
"toggleshowdesktop",
action_toggle_show_desktop,
{
ObAction *a = NULL;
gboolean exist = FALSE;
- int i;
+ gint i;
for (i = 0; actionstrings[i].name; i++)
if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
a = action_new(actionstrings[i].func);
if (actionstrings[i].setup)
actionstrings[i].setup(&a, uact);
- INTERACTIVE_LIMIT(a, uact);
+ if (a)
+ INTERACTIVE_LIMIT(a, uact);
break;
}
if (!exist)
ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
ObUserAction uact)
{
- char *actname;
+ gchar *actname;
ObAction *act = NULL;
xmlNodePtr n;
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);
}
- INTERACTIVE_LIMIT(act, uact);
g_free(actname);
}
return act;
a->data.inter.cancel = cancel;
a->data.inter.final = done;
if (!(cancel || done))
- keyboard_interactive_grab(state, a->data.any.c, a);
+ if (!keyboard_interactive_grab(state, a->data.any.c, a))
+ continue;
}
- ob_main_loop_queue_action(ob_main_loop, a);
+ /* XXX UGLY HACK race with motion event starting a move and the
+ button release gettnig processed first. answer: don't queue
+ moveresize starts. UGLY HACK XXX */
+ if (a->data.any.interactive || a->func == action_moveresize) {
+ /* interactive actions are not queued */
+ a->func(&a->data);
+ } else
+ ob_main_loop_queue_action(ob_main_loop, a);
}
}
}
void action_execute(union ActionData *data)
{
GError *e = NULL;
- char *cmd;
+ gchar *cmd, **argv = 0;
if (data->execute.path) {
cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
if (cmd) {
- if (!g_spawn_command_line_async(cmd, &e)) {
+ if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) {
g_warning("failed to execute '%s': %s",
cmd, e->message);
+ g_error_free(e);
+ } else {
+ if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, NULL, &e)) {
+ g_warning("failed to execute '%s': %s",
+ cmd, e->message);
+ g_error_free(e);
+ }
+ g_strfreev(argv);
}
g_free(cmd);
} else {
void action_focus(union ActionData *data)
{
+ /* if using focus_delay, stop the timer now so that focus doesn't go moving
+ on us */
+ event_halt_focus_delay();
+
client_focus(data->client.any.c);
}
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;
+ }
}
}
}
- action_run_string((raise ? "Raise" : "Lower"), c);
+ if (raise)
+ action_raise(data);
+ else
+ action_lower(data);
}
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_unshaderaise(union ActionData *data)
{
if (data->client.any.c->shaded)
- action_run_string("Unshade", data->client.any.c);
+ action_unshade(data);
else
- action_run_string("Raise", data->client.any.c);
+ action_raise(data);
}
void action_shadelower(union ActionData *data)
{
if (data->client.any.c->shaded)
- action_run_string("Lower", data->client.any.c);
+ action_lower(data);
else
- action_run_string("Shade", data->client.any.c);
+ action_shade(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);
-
- focus_order_to_bottom(data->client.any.c);
}
void action_close(union ActionData *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;
client_action_end(data);
}
-static guint32 pick_corner(int x, int y, int cx, int cy, int cw, int ch)
+static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch)
{
- 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;
+ 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_bottomleft;
- else
- return prop_atoms.net_wm_moveresize_size_topleft;
+ 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;
}
}
void action_cycle_windows(union ActionData *data)
{
- focus_cycle(data->cycle.forward, data->cycle.linear,
+ /* if using focus_delay, stop the timer now so that focus doesn't go moving
+ on us */
+ event_halt_focus_delay();
+
+ focus_cycle(data->cycle.forward, data->cycle.linear, data->any.interactive,
data->cycle.dialog,
data->cycle.inter.final, data->cycle.inter.cancel);
}
void action_directional_focus(union ActionData *data)
{
+ /* if using focus_delay, stop the timer now so that focus doesn't go moving
+ on us */
+ event_halt_focus_delay();
+
focus_directional_cycle(data->interdiraction.direction,
+ data->any.interactive,
data->interdiraction.dialog,
data->interdiraction.inter.final,
data->interdiraction.inter.cancel);
void action_movetoedge(union ActionData *data)
{
- int x, y;
+ gint x, y;
ObClient *c = data->diraction.any.c;
x = c->frame->area.x;
void action_growtoedge(union ActionData *data)
{
- int x, y, width, height, dest;
+ gint x, y, width, height, dest;
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;
client_action_end(data);
}
+void action_toggle_dockautohide(union ActionData *data)
+{
+ config_dock_hide = !config_dock_hide;
+ dock_configure();
+}
+
void action_toggle_show_desktop(union ActionData *data)
{
screen_show_desktop(!screen_showing_desktop);