action.c for the Openbox window manager
Copyright (c) 2006 Mikael Magnusson
- Copyright (c) 2003 Ben Jansens
+ Copyright (c) 2003-2007 Dana Jansens
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "config.h"
#include "mainloop.h"
#include "startupnotify.h"
+#include "gettext.h"
#include <glib.h>
{
if (config_focus_follow)
if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(TRUE, OB_CURSOR_NONE);
+ grab_pointer(TRUE, FALSE, OB_CURSOR_NONE);
}
inline void client_action_end(union ActionData *data)
if (config_focus_follow)
if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
if (!data->any.button) {
- grab_pointer(FALSE, OB_CURSOR_NONE);
+ grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
} else {
ObClient *c;
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTH;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_east(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_EAST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_south(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTH;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_west(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_WEST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_northeast(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTHEAST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_southeast(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_southwest(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_directional_focus_northwest(ObAction **a, ObUserAction uact)
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.interdiraction.direction = OB_DIRECTION_NORTHWEST;
(*a)->data.interdiraction.dialog = TRUE;
+ (*a)->data.interdiraction.dock_windows = FALSE;
}
void setup_action_send_to_desktop(ObAction **a, ObUserAction uact)
(*a)->data.cycle.linear = FALSE;
(*a)->data.cycle.forward = TRUE;
(*a)->data.cycle.dialog = TRUE;
+ (*a)->data.cycle.dock_windows = FALSE;
}
void setup_action_cycle_windows_previous(ObAction **a, ObUserAction uact)
(*a)->data.cycle.linear = FALSE;
(*a)->data.cycle.forward = FALSE;
(*a)->data.cycle.dialog = TRUE;
+ (*a)->data.cycle.dock_windows = FALSE;
}
void setup_action_movefromedge_north(ObAction **a, ObUserAction uact)
}
}
+void setup_action_focus(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.any.client_action = OB_CLIENT_ACTION_OPTIONAL;
+}
+
void setup_client_action(ObAction **a, ObUserAction uact)
{
(*a)->data.any.client_action = OB_CLIENT_ACTION_ALWAYS;
{
"focus",
action_focus,
- setup_client_action
+ setup_action_focus
},
{
"unfocus",
break;
}
if (!exist)
- g_warning("Invalid action '%s' requested. No such action exists.",
+ g_message(_("Invalid action '%s' requested. No such action exists."),
name);
if (!a)
- g_warning("Invalid use of action '%s'. Action will be ignored.", name);
+ g_message(_("Invalid use of action '%s'. Action will be ignored."),
+ name);
return a;
}
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);
act->data.cycle.linear = parse_bool(doc, n);
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
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);
} else if (act->func == action_directional_focus) {
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
- act->data.cycle.dialog = 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);
} 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);
}
it won't work right unless we XUngrabKeyboard first,
even though we grabbed the key/button Asychronously.
e.g. "gnome-panel-control --main-menu" */
- XUngrabKeyboard(ob_display, event_curtime);
+ grab_keyboard(FALSE);
}
for (it = acts; it; it = g_slist_next(it)) {
cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
if (cmd) {
if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) {
- g_warning("failed to execute '%s': %s",
+ g_message(_("Failed to execute '%s': %s"),
cmd, e->message);
g_error_free(e);
- } else {
- gchar **env, *program;
+ } else if (data->execute.startupnotify) {
+ gchar *program;
program = g_path_get_basename(argv[0]);
- env = sn_get_spawn_environment(program,
- data->execute.any.time);
- if (!g_spawn_async(NULL, argv, env, G_SPAWN_SEARCH_PATH |
+ /* 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_warning("failed to execute '%s': %s",
+ g_message(_("Failed to execute '%s': %s"),
cmd, e->message);
g_error_free(e);
sn_spawn_cancel();
}
- g_strfreev(env);
+ 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_warning("failed to convert '%s' from utf8", data->execute.path);
+ g_message(_("Failed to convert the path '%s' from utf8"),
+ data->execute.path);
}
}
}
moving on us */
event_halt_focus_delay();
- client_activate(data->activate.any.c, data->activate.here, TRUE,
- data->activate.any.time);
+ client_activate(data->activate.any.c, data->activate.here, TRUE);
}
}
void action_focus(union ActionData *data)
{
- /* similar to the openbox dock for dockapps, don't let user actions give
- focus to 3rd-party docks (panels) either (unless they ask for it
- themselves). */
- if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
- /* if using focus_delay, stop the timer now so that focus doesn't go
- moving on us */
- event_halt_focus_delay();
+ if (data->client.any.c) {
+ /* similar to the openbox dock for dockapps, don't let user actions
+ give focus to 3rd-party docks (panels) either (unless they ask for
+ it themselves). */
+ if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
+ /* 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);
+ client_focus(data->client.any.c);
+ }
+ } else {
+ /* focus action on something other than a client, make keybindings
+ work for this openbox instance, but don't focus any specific client
+ */
+ focus_nothing();
}
}
void action_unfocus (union ActionData *data)
{
if (data->client.any.c == focus_client)
- focus_fallback(OB_FOCUS_FALLBACK_UNFOCUSING);
+ focus_fallback(FALSE);
}
void action_iconify(union ActionData *data)
void action_raise(union ActionData *data)
{
client_action_start(data);
- stacking_raise(CLIENT_AS_WINDOW(data->client.any.c), data->stacking.group);
+ stacking_raise(CLIENT_AS_WINDOW(data->client.any.c));
client_action_end(data);
}
void action_lower(union ActionData *data)
{
client_action_start(data);
- stacking_lower(CLIENT_AS_WINDOW(data->client.any.c), data->stacking.group);
+ stacking_lower(CLIENT_AS_WINDOW(data->client.any.c));
client_action_end(data);
}
void action_resize_relative(union ActionData *data)
{
ObClient *c = data->relative.any.c;
+ gint x, y, ow, w, oh, h, lw, lh;
+
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);
+
+ x = c->area.x;
+ y = c->area.y;
+ ow = c->area.width;
+ w = 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
+ + data->relative.deltayu * c->size_inc.height;
+
+ client_try_configure(c, OB_CORNER_TOPLEFT, &x, &y, &w, &h, &lw, &lh, TRUE);
+ client_move_resize(c, x + (ow - w), y + (oh - h), w, h);
client_action_end(data);
}
void action_maximize_full(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, TRUE, 0, TRUE);
+ client_maximize(data->client.any.c, TRUE, 0);
client_action_end(data);
}
void action_unmaximize_full(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, FALSE, 0, TRUE);
+ client_maximize(data->client.any.c, FALSE, 0);
client_action_end(data);
}
client_maximize(data->client.any.c,
!(data->client.any.c->max_horz ||
data->client.any.c->max_vert),
- 0, TRUE);
+ 0);
client_action_end(data);
}
void action_maximize_horz(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, TRUE, 1, TRUE);
+ client_maximize(data->client.any.c, TRUE, 1);
client_action_end(data);
}
void action_unmaximize_horz(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, FALSE, 1, TRUE);
+ client_maximize(data->client.any.c, FALSE, 1);
client_action_end(data);
}
{
client_action_start(data);
client_maximize(data->client.any.c,
- !data->client.any.c->max_horz, 1, TRUE);
+ !data->client.any.c->max_horz, 1);
client_action_end(data);
}
void action_maximize_vert(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, TRUE, 2, TRUE);
+ client_maximize(data->client.any.c, TRUE, 2);
client_action_end(data);
}
void action_unmaximize_vert(union ActionData *data)
{
client_action_start(data);
- client_maximize(data->client.any.c, FALSE, 2, TRUE);
+ client_maximize(data->client.any.c, FALSE, 2);
client_action_end(data);
}
{
client_action_start(data);
client_maximize(data->client.any.c,
- !data->client.any.c->max_vert, 2, TRUE);
+ !data->client.any.c->max_vert, 2);
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_fullscreen(data->client.any.c, !(data->client.any.c->fullscreen));
client_action_end(data);
}
on us */
event_halt_focus_delay();
- focus_cycle(data->cycle.forward, data->cycle.linear, data->any.interactive,
+ focus_cycle(data->cycle.forward,
+ data->cycle.dock_windows,
+ data->cycle.linear, data->any.interactive,
data->cycle.dialog,
- data->cycle.inter.final, data->cycle.inter.cancel,
- data->cycle.inter.any.time);
+ data->cycle.inter.final, data->cycle.inter.cancel);
}
void action_directional_focus(union ActionData *data)
event_halt_focus_delay();
focus_directional_cycle(data->interdiraction.direction,
+ data->interdiraction.dock_windows,
data->any.interactive,
data->interdiraction.dialog,
data->interdiraction.inter.final,
- data->interdiraction.inter.cancel,
- data->interdiraction.inter.any.time);
+ data->interdiraction.inter.cancel);
}
void action_movetoedge(union ActionData *data)