#include "debug.h"
#include "client.h"
#include "focus.h"
+#include "focus_cycle.h"
#include "moveresize.h"
#include "menu.h"
#include "prop.h"
#include <glib.h>
-inline void client_action_start(union ActionData *data)
+static gulong ignore_start = 0;
+
+static void client_action_start(union ActionData *data)
{
- if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(TRUE, FALSE, OB_CURSOR_NONE);
+ ignore_start = event_start_ignore_all_enters();
}
-inline void client_action_end(union ActionData *data)
+static void client_action_end(union ActionData *data, gboolean allow_enters)
{
if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
+ if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
+ if (!data->any.button && data->any.c && !allow_enters) {
+ event_end_ignore_all_enters(ignore_start);
+ } else {
+ ObClient *c;
+
+ /* usually this is sorta redundant, but with a press action
+ that moves windows our from under the cursor, the enter
+ event will come as a GrabNotify which is ignored, so this
+ makes a fake enter event
+ */
+ if ((c = client_under_pointer()) && c != data->any.c) {
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Generating fake enter because we did a "
+ "mouse-event action");
+ event_enter_client(c);
+ }
+ }
+ }
}
typedef struct
/* deal with pointers */
if (a->func == action_execute || a->func == action_restart)
g_free(a->data.execute.path);
+ else if (a->func == action_debug)
+ g_free(a->data.debug.string);
else if (a->func == action_showmenu)
g_free(a->data.showmenu.name);
/* deal with pointers */
if (a->func == action_execute || a->func == action_restart)
a->data.execute.path = g_strdup(a->data.execute.path);
+ else if (a->func == action_debug)
+ a->data.debug.string = g_strdup(a->data.debug.string);
else if (a->func == action_showmenu)
a->data.showmenu.name = g_strdup(a->data.showmenu.name);
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTH;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_east(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_EAST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_south(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTH;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_west(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_WEST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_northeast(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTHEAST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_southeast(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_southwest(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_directional_focus_northwest(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTHWEST;
(*a)->data.interdiraction.dialog = TRUE;
(*a)->data.interdiraction.dock_windows = FALSE;
+ (*a)->data.interdiraction.desktop_windows = FALSE;
}
void setup_action_send_to_desktop(ObAction **a, ObUserAction uact)
void setup_action_desktop(ObAction **a, ObUserAction uact)
{
+/*
(*a)->data.desktop.inter.any.interactive = FALSE;
+*/
}
void setup_action_desktop_prev(ObAction **a, ObUserAction uact)
(*a)->data.cycle.forward = TRUE;
(*a)->data.cycle.dialog = TRUE;
(*a)->data.cycle.dock_windows = FALSE;
+ (*a)->data.cycle.desktop_windows = FALSE;
(*a)->data.cycle.all_desktops = FALSE;
}
(*a)->data.cycle.forward = FALSE;
(*a)->data.cycle.dialog = TRUE;
(*a)->data.cycle.dock_windows = FALSE;
+ (*a)->data.cycle.desktop_windows = FALSE;
(*a)->data.cycle.all_desktops = FALSE;
}
void setup_action_move(ObAction **a, ObUserAction uact)
{
(*a)->data.moveresize.any.client_action = OB_CLIENT_ACTION_ALWAYS;
- (*a)->data.moveresize.move = TRUE;
(*a)->data.moveresize.keyboard =
(uact == OB_USER_ACTION_NONE ||
uact == OB_USER_ACTION_KEYBOARD_KEY ||
uact == OB_USER_ACTION_MENU_SELECTION);
+ (*a)->data.moveresize.corner = 0;
}
void setup_action_resize(ObAction **a, ObUserAction uact)
{
(*a)->data.moveresize.any.client_action = OB_CLIENT_ACTION_ALWAYS;
- (*a)->data.moveresize.move = FALSE;
(*a)->data.moveresize.keyboard =
(uact == OB_USER_ACTION_NONE ||
uact == OB_USER_ACTION_KEYBOARD_KEY ||
uact == OB_USER_ACTION_MENU_SELECTION);
+ (*a)->data.moveresize.corner = 0;
}
void setup_action_showmenu(ObAction **a, ObUserAction uact)
}
}
+void setup_action_addremove_desktop_current(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.addremovedesktop.current = TRUE;
+}
+
+void setup_action_addremove_desktop_last(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.addremovedesktop.current = FALSE;
+}
+
void setup_action_focus(ObAction **a, ObUserAction uact)
{
(*a)->data.any.client_action = OB_CLIENT_ACTION_OPTIONAL;
ActionString actionstrings[] =
{
+ {
+ "debug",
+ action_debug,
+ NULL
+ },
{
"execute",
- action_execute,
+ action_execute,
NULL
},
{
},
{
"move",
- action_moveresize,
+ action_move,
setup_action_move
},
{
"resize",
- action_moveresize,
+ action_resize,
setup_action_resize
},
{
action_break_chroot,
NULL
},
+ {
+ "adddesktoplast",
+ action_add_desktop,
+ setup_action_addremove_desktop_last
+ },
+ {
+ "removedesktoplast",
+ action_remove_desktop,
+ setup_action_addremove_desktop_last
+ },
+ {
+ "adddesktopcurrent",
+ action_add_desktop,
+ setup_action_addremove_desktop_current
+ },
+ {
+ "removedesktopcurrent",
+ action_remove_desktop,
+ setup_action_addremove_desktop_current
+ },
{
NULL,
NULL,
if (parse_attr_string("name", node, &actname)) {
if ((act = action_from_string(actname, uact))) {
- if (act->func == action_execute || act->func == action_restart) {
- if ((n = parse_find_node("execute", node->xmlChildrenNode))) {
- gchar *s = parse_string(doc, n);
- act->data.execute.path = parse_expand_tilde(s);
- g_free(s);
- }
- if ((n = parse_find_node("startupnotify", node->xmlChildrenNode))) {
- xmlNodePtr m;
- if ((m = parse_find_node("enabled", n->xmlChildrenNode)))
- act->data.execute.startupnotify = parse_bool(doc, m);
- if ((m = parse_find_node("name", n->xmlChildrenNode)))
- act->data.execute.name = parse_string(doc, m);
- if ((m = parse_find_node("icon", n->xmlChildrenNode)))
- act->data.execute.icon_name = parse_string(doc, m);
- }
} else if (act->func == action_showmenu) {
if ((n = parse_find_node("menu", node->xmlChildrenNode)))
act->data.showmenu.name = parse_string(doc, n);
if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
act->data.desktop.desk = parse_int(doc, n);
if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+/*
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.desktop.inter.any.interactive =
parse_bool(doc, n);
+*/
} else if (act->func == action_send_to_desktop) {
if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
act->data.sendto.desk = parse_int(doc, n);
act->data.cycle.dialog = parse_bool(doc, n);
if ((n = parse_find_node("panels", node->xmlChildrenNode)))
act->data.cycle.dock_windows = parse_bool(doc, n);
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.cycle.desktop_windows = parse_bool(doc, n);
if ((n = parse_find_node("allDesktops",
node->xmlChildrenNode)))
act->data.cycle.all_desktops = parse_bool(doc, n);
act->data.interdiraction.dialog = parse_bool(doc, n);
if ((n = parse_find_node("panels", node->xmlChildrenNode)))
act->data.interdiraction.dock_windows = parse_bool(doc, n);
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.interdiraction.desktop_windows =
+ parse_bool(doc, n);
+ } else if (act->func == action_resize) {
+ if ((n = parse_find_node("edge", node->xmlChildrenNode))) {
+ gchar *s = parse_string(doc, n);
+ if (!g_ascii_strcasecmp(s, "top"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_top;
+ else if (!g_ascii_strcasecmp(s, "bottom"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_bottom;
+ else if (!g_ascii_strcasecmp(s, "left"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_left;
+ else if (!g_ascii_strcasecmp(s, "right"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_right;
+ else if (!g_ascii_strcasecmp(s, "topleft"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_topleft;
+ else if (!g_ascii_strcasecmp(s, "topright"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_topright;
+ else if (!g_ascii_strcasecmp(s, "bottomleft"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_bottomleft;
+ else if (!g_ascii_strcasecmp(s, "bottomright"))
+ act->data.moveresize.corner =
+ prop_atoms.net_wm_moveresize_size_bottomright;
+ g_free(s);
+ }
} else if (act->func == action_raise ||
act->func == action_lower ||
act->func == action_raiselower ||
{
GSList *it;
ObAction *a;
- gboolean inter = FALSE;
if (!acts)
return;
if (x < 0 && y < 0)
screen_pointer_pos(&x, &y);
- if (grab_on_keyboard())
- inter = TRUE;
- else
- for (it = acts; it; it = g_slist_next(it)) {
- a = it->data;
- if (a->data.any.interactive) {
- inter = TRUE;
- break;
- }
- }
-
- if (!inter) {
- /* sometimes when we execute another app as an action,
- it won't work right unless we XUngrabKeyboard first,
- even though we grabbed the key/button Asychronously.
- e.g. "gnome-panel-control --main-menu" */
- grab_keyboard(FALSE);
- }
-
for (it = acts; it; it = g_slist_next(it)) {
a = it->data;
/* 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) {
+ moveresize starts. UGLY HACK XXX
+
+ XXX ALSO don't queue showmenu events, because on button press
+ events we need to know if a mouse grab is going to take place,
+ and set the button to 0, so that later motion events don't think
+ that a drag is going on. since showmenu grabs the pointer..
+ */
+ if (a->data.any.interactive || a->func == action_move ||
+ a->func == action_resize || a->func == action_showmenu)
+ {
/* interactive actions are not queued */
a->func(&a->data);
- } else if ((context == OB_FRAME_CONTEXT_CLIENT ||
- (c && c->type == OB_CLIENT_TYPE_DESKTOP &&
- context == OB_FRAME_CONTEXT_DESKTOP)) &&
- (a->func == action_focus ||
- a->func == action_activate ||
- a->func == action_showmenu))
+ } else if (a->func == action_focus ||
+ a->func == action_activate ||
+ a->func == action_showmenu)
{
/* XXX MORE UGLY HACK
actions from clicks on client windows are NOT queued.
pointer. ugh.
also with the menus, there is a race going on. if the
- desktop wants to pop up a menu, and we do to, we send them
+ desktop wants to pop up a menu, and we do too, we send them
the button before we pop up the menu, so they pop up their
menu first. but not always. if we pop up our menu before
sending them the button press, then the result is
deterministic. yay.
+
+ XXX further more. focus actions are not queued at all,
+ because if you bind focus->showmenu, the menu will get
+ hidden to do the focusing
*/
a->func(&a->data);
} else
action_run(l, c, 0, time);
}
+void action_debug(union ActionData *data)
+{
+ if (data->debug.string)
+ g_print("%s\n", data->debug.string);
+}
+
void action_execute(union ActionData *data)
{
- GError *e = NULL;
- gchar *cmd, **argv = 0;
- if (data->execute.path) {
- cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
- if (cmd) {
- if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) {
- g_message(_("Failed to execute '%s': %s"),
- cmd, e->message);
- g_error_free(e);
- } else if (data->execute.startupnotify) {
- gchar *program;
-
- program = g_path_get_basename(argv[0]);
- /* sets up the environment */
- sn_setup_spawn_environment(program,
- data->execute.name,
- data->execute.icon_name,
- /* launch it on the current
- desktop */
- screen_desktop,
- data->execute.any.time);
- if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
- G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, NULL, &e)) {
- g_message(_("Failed to execute '%s': %s"),
- cmd, e->message);
- g_error_free(e);
- sn_spawn_cancel();
- }
- unsetenv("DESKTOP_STARTUP_ID");
- g_free(program);
- g_strfreev(argv);
- } else {
- if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
- G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, NULL, &e))
- {
- g_message(_("Failed to execute '%s': %s"),
- cmd, e->message);
- g_error_free(e);
- }
- g_strfreev(argv);
- }
- g_free(cmd);
- } else {
- g_message(_("Failed to convert the path '%s' from utf8"),
- data->execute.path);
- }
- }
}
void action_activate(union ActionData *data)
{
if (data->client.any.c) {
if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
- data->any.context != OB_FRAME_CONTEXT_CLIENT)
+ (data->any.context != OB_FRAME_CONTEXT_CLIENT &&
+ data->any.context != OB_FRAME_CONTEXT_FRAME))
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
{
if (data->client.any.c) {
if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
- data->any.context != OB_FRAME_CONTEXT_CLIENT)
+ (data->any.context != OB_FRAME_CONTEXT_CLIENT &&
+ data->any.context != OB_FRAME_CONTEXT_FRAME))
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
void action_unfocus (union ActionData *data)
{
if (data->client.any.c == focus_client)
- focus_fallback(FALSE);
+ focus_fallback(FALSE, FALSE, TRUE);
}
void action_iconify(union ActionData *data)
{
client_action_start(data);
- client_iconify(data->client.any.c, TRUE, TRUE);
- client_action_end(data);
+ client_iconify(data->client.any.c, TRUE, TRUE, FALSE);
+ client_action_end(data, config_focus_under_mouse);
}
void action_focus_order_to_bottom(union ActionData *data)
void action_raiselower(union ActionData *data)
{
ObClient *c = data->client.any.c;
- GList *it;
- gboolean raise = FALSE;
-
- for (it = stacking_list; it; it = g_list_next(it)) {
- 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;
- }
- }
- }
- }
-
- if (raise)
- action_raise(data);
- else
- action_lower(data);
+ client_action_start(data);
+ stacking_restack_request(c, NULL, Opposite);
+ client_action_end(data, config_focus_under_mouse);
}
void action_raise(union ActionData *data)
{
client_action_start(data);
stacking_raise(CLIENT_AS_WINDOW(data->client.any.c));
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_unshaderaise(union ActionData *data)
{
client_action_start(data);
stacking_lower(CLIENT_AS_WINDOW(data->client.any.c));
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_close(union ActionData *data)
{
client_action_start(data);
client_shade(data->client.any.c, TRUE);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_unshade(union ActionData *data)
{
client_action_start(data);
client_shade(data->client.any.c, FALSE);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_shade(union ActionData *data)
{
client_action_start(data);
client_shade(data->client.any.c, !data->client.any.c->shaded);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_omnipresent(union ActionData *data)
{
client_set_desktop(data->client.any.c,
data->client.any.c->desktop == DESKTOP_ALL ?
- screen_desktop : DESKTOP_ALL, FALSE);
+ screen_desktop : DESKTOP_ALL, FALSE, TRUE);
}
void action_move_relative_horz(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);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
void action_move_relative_vert(union ActionData *data)
ObClient *c = data->relative.any.c;
client_action_start(data);
client_move(c, c->area.x, c->area.y + data->relative.deltax);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
void action_move_to_center(union ActionData *data)
{
ObClient *c = data->client.any.c;
Rect *area;
- area = screen_area_monitor(c->desktop, 0);
+ area = screen_area(c->desktop, client_monitor(c), NULL);
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);
+ client_move(c, area->x + area->width / 2 - c->area.width / 2,
+ area->y + area->height / 2 - c->area.height / 2);
+ client_action_end(data, FALSE);
+ g_free(area);
}
void action_resize_relative_horz(union ActionData *data)
client_resize(c,
c->area.width + data->relative.deltax * c->size_inc.width,
c->area.height);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
void action_resize_relative_vert(union ActionData *data)
client_action_start(data);
client_resize(c, c->area.width, c->area.height +
data->relative.deltax * c->size_inc.height);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
}
client_action_start(data);
client_move(c, c->area.x + data->relative.deltax, c->area.y +
data->relative.deltay);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
void action_resize_relative(union ActionData *data)
{
ObClient *c = data->relative.any.c;
- gint x, y, ow, w, oh, h, lw, lh;
+ gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh;
client_action_start(data);
x = c->area.x;
y = c->area.y;
ow = c->area.width;
- w = ow + data->relative.deltax * c->size_inc.width
+ xoff = -data->relative.deltaxl * c->size_inc.width;
+ nw = ow + data->relative.deltax * c->size_inc.width
+ data->relative.deltaxl * c->size_inc.width;
oh = c->area.height;
- h = oh + data->relative.deltay * c->size_inc.height
+ yoff = -data->relative.deltayu * c->size_inc.height;
+ nh = oh + data->relative.deltay * c->size_inc.height
+ data->relative.deltayu * c->size_inc.height;
+
+ g_print("deltax %d %d x %d ow %d xoff %d nw %d\n",
+ data->relative.deltax,
+ data->relative.deltaxl,
+ x, ow, xoff, nw);
- client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
- client_move_resize(c, x + (ow - w), y + (oh - h), w, h);
- client_action_end(data);
+ client_try_configure(c, &x, &y, &nw, &nh, &lw, &lh, TRUE);
+ xoff = xoff == 0 ? 0 : (xoff < 0 ? MAX(xoff, ow-nw) : MIN(xoff, ow-nw));
+ yoff = yoff == 0 ? 0 : (yoff < 0 ? MAX(yoff, oh-nh) : MIN(yoff, oh-nh));
+ client_move_resize(c, x + xoff, y + yoff, nw, nh);
+ client_action_end(data, FALSE);
}
void action_maximize_full(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, TRUE, 0);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_unmaximize_full(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, FALSE, 0);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_maximize_full(union ActionData *data)
!(data->client.any.c->max_horz ||
data->client.any.c->max_vert),
0);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_maximize_horz(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, TRUE, 1);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_unmaximize_horz(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, FALSE, 1);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_maximize_horz(union ActionData *data)
client_action_start(data);
client_maximize(data->client.any.c,
!data->client.any.c->max_horz, 1);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_maximize_vert(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, TRUE, 2);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_unmaximize_vert(union ActionData *data)
{
client_action_start(data);
client_maximize(data->client.any.c, FALSE, 2);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_maximize_vert(union ActionData *data)
client_action_start(data);
client_maximize(data->client.any.c,
!data->client.any.c->max_vert, 2);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_fullscreen(union ActionData *data)
{
client_action_start(data);
client_fullscreen(data->client.any.c, !(data->client.any.c->fullscreen));
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_send_to_desktop(union ActionData *data)
if (data->sendto.desk < screen_num_desktops ||
data->sendto.desk == DESKTOP_ALL) {
- client_set_desktop(c, data->sendto.desk, data->sendto.follow);
- if (data->sendto.follow)
+ client_set_desktop(c, data->sendto.desk, data->sendto.follow, FALSE);
+ if (data->sendto.follow && data->sendto.desk != screen_desktop)
screen_set_desktop(data->sendto.desk, TRUE);
}
}
void action_desktop(union ActionData *data)
{
- if (!data->inter.any.interactive ||
- (!data->inter.cancel && !data->inter.final))
+ /* XXX add the interactive/dialog option back again once the dialog
+ has been made to not use grabs */
+ if (data->desktop.desk < screen_num_desktops ||
+ data->desktop.desk == DESKTOP_ALL)
{
- if (data->desktop.desk < screen_num_desktops ||
- data->desktop.desk == DESKTOP_ALL)
- {
- screen_set_desktop(data->desktop.desk, TRUE);
- if (data->inter.any.interactive)
- screen_desktop_popup(data->desktop.desk, TRUE);
- }
- } else
- screen_desktop_popup(0, FALSE);
+ screen_set_desktop(data->desktop.desk, TRUE);
+ if (data->inter.any.interactive)
+ screen_desktop_popup(data->desktop.desk, TRUE);
+ }
}
void action_desktop_dir(union ActionData *data)
if (!data->sendtodir.inter.any.interactive ||
(data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
{
- if (d != screen_desktop) screen_set_desktop(d, TRUE);
+ if (d != screen_desktop)
+ screen_set_desktop(d, TRUE);
}
}
if (!data->sendtodir.inter.any.interactive ||
(data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
{
- client_set_desktop(c, d, data->sendtodir.follow);
+ client_set_desktop(c, d, data->sendtodir.follow, FALSE);
if (data->sendtodir.follow && d != screen_desktop)
screen_set_desktop(d, TRUE);
}
void action_desktop_last(union ActionData *data)
{
- screen_set_desktop(screen_last_desktop, TRUE);
+ if (screen_last_desktop < screen_num_desktops)
+ screen_set_desktop(screen_last_desktop, TRUE);
}
void action_toggle_decorations(union ActionData *data)
client_action_start(data);
client_set_undecorated(c, !c->undecorated);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
#undef d
}
-void action_moveresize(union ActionData *data)
+void action_move(union ActionData *data)
{
ObClient *c = data->moveresize.any.c;
guint32 corner;
- if (data->moveresize.keyboard) {
- corner = (data->moveresize.move ?
- prop_atoms.net_wm_moveresize_move_keyboard :
- prop_atoms.net_wm_moveresize_size_keyboard);
- } else {
- corner = (data->moveresize.move ?
- prop_atoms.net_wm_moveresize_move :
- pick_corner(data->any.x, data->any.y,
- c->frame->area.x, c->frame->area.y,
- /* use the client size because the frame
- can be differently sized (shaded
- windows) and we want this based on the
- clients size */
- c->area.width + c->frame->size.left +
- c->frame->size.right,
- c->area.height + c->frame->size.top +
- c->frame->size.bottom, c->shaded));
- }
+ if (data->moveresize.keyboard)
+ corner = prop_atoms.net_wm_moveresize_move_keyboard;
+ else
+ corner = prop_atoms.net_wm_moveresize_move;
+
+ moveresize_start(c, data->any.x, data->any.y, data->any.button, corner);
+}
+
+void action_resize(union ActionData *data)
+{
+ ObClient *c = data->moveresize.any.c;
+ guint32 corner;
+
+ if (data->moveresize.keyboard)
+ corner = prop_atoms.net_wm_moveresize_size_keyboard;
+ else if (data->moveresize.corner)
+ corner = data->moveresize.corner; /* it was specified in the binding */
+ else
+ corner = pick_corner(data->any.x, data->any.y,
+ c->frame->area.x, c->frame->area.y,
+ /* use the client size because the frame
+ can be differently sized (shaded
+ windows) and we want this based on the
+ clients size */
+ c->area.width + c->frame->size.left +
+ c->frame->size.right,
+ c->area.height + c->frame->size.top +
+ c->frame->size.bottom, c->shaded);
moveresize_start(c, data->any.x, data->any.y, data->any.button, corner);
}
focus_cycle(data->cycle.forward,
data->cycle.all_desktops,
data->cycle.dock_windows,
+ data->cycle.desktop_windows,
data->cycle.linear, data->any.interactive,
data->cycle.dialog,
data->cycle.inter.final, data->cycle.inter.cancel);
focus_directional_cycle(data->interdiraction.direction,
data->interdiraction.dock_windows,
+ data->interdiraction.desktop_windows,
data->any.interactive,
data->interdiraction.dialog,
data->interdiraction.inter.final,
frame_frame_gravity(c->frame, &x, &y, c->area.width, c->area.height);
client_action_start(data);
client_move(c, x, y);
- client_action_end(data);
+ client_action_end(data, FALSE);
}
void action_growtoedge(union ActionData *data)
ObClient *c = data->diraction.any.c;
Rect *a;
- a = screen_area(c->desktop);
+ a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area);
x = c->frame->area.x;
y = c->frame->area.y;
/* get the unshaded frame's dimensions..if it is shaded */
frame_frame_gravity(c->frame, &x, &y, width, height);
client_action_start(data);
client_move_resize(c, x, y, width, height);
- client_action_end(data);
+ client_action_end(data, FALSE);
+ g_free(a);
}
void action_send_to_layer(union ActionData *data)
client_set_layer(c, c->below ? 0 : -1);
else if (data->layer.layer > 0)
client_set_layer(c, c->above ? 0 : 1);
- client_action_end(data);
+ client_action_end(data, config_focus_under_mouse);
}
void action_toggle_dockautohide(union ActionData *data)
void action_toggle_show_desktop(union ActionData *data)
{
- screen_show_desktop(!screen_showing_desktop, TRUE);
+ screen_show_desktop(!screen_showing_desktop, NULL);
}
void action_show_desktop(union ActionData *data)
{
- screen_show_desktop(TRUE, TRUE);
+ screen_show_desktop(TRUE, NULL);
}
void action_unshow_desktop(union ActionData *data)
{
- screen_show_desktop(FALSE, TRUE);
+ screen_show_desktop(FALSE, NULL);
}
void action_break_chroot(union ActionData *data)
/* break out of one chroot */
keyboard_reset_chains(1);
}
+
+void action_add_desktop(union ActionData *data)
+{
+ client_action_start(data);
+ screen_set_num_desktops(screen_num_desktops+1);
+
+ /* move all the clients over */
+ if (data->addremovedesktop.current) {
+ GList *it;
+
+ for (it = client_list; it; it = g_list_next(it)) {
+ ObClient *c = it->data;
+ if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop)
+ client_set_desktop(c, c->desktop+1, FALSE, TRUE);
+ }
+ }
+
+ client_action_end(data, config_focus_under_mouse);
+}
+
+void action_remove_desktop(union ActionData *data)
+{
+ guint rmdesktop, movedesktop;
+ GList *it, *stacking_copy;
+
+ if (screen_num_desktops < 2) return;
+
+ client_action_start(data);
+
+ /* what desktop are we removing and moving to? */
+ if (data->addremovedesktop.current)
+ rmdesktop = screen_desktop;
+ else
+ rmdesktop = screen_num_desktops - 1;
+ if (rmdesktop < screen_num_desktops - 1)
+ movedesktop = rmdesktop + 1;
+ else
+ movedesktop = rmdesktop;
+
+ /* make a copy of the list cuz we're changing it */
+ stacking_copy = g_list_copy(stacking_list);
+ for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
+ if (WINDOW_IS_CLIENT(it->data)) {
+ ObClient *c = it->data;
+ guint d = c->desktop;
+ if (d != DESKTOP_ALL && d >= movedesktop) {
+ client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
+ ob_debug("moving window %s\n", c->title);
+ }
+ /* raise all the windows that are on the current desktop which
+ is being merged */
+ if ((screen_desktop == rmdesktop - 1 ||
+ screen_desktop == rmdesktop) &&
+ (d == DESKTOP_ALL || d == screen_desktop))
+ {
+ stacking_raise(CLIENT_AS_WINDOW(c));
+ ob_debug("raising window %s\n", c->title);
+ }
+ }
+ }
+
+ /* act like we're changing desktops */
+ if (screen_desktop < screen_num_desktops - 1) {
+ gint d = screen_desktop;
+ screen_desktop = screen_last_desktop;
+ screen_set_desktop(d, TRUE);
+ ob_debug("fake desktop change\n");
+ }
+
+ screen_set_num_desktops(screen_num_desktops-1);
+
+ client_action_end(data, config_focus_under_mouse);
+}