X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Faction.c;h=db49f56cd8f09e01727f25142caaa57f043daaff;hb=66c350763fa85cfda0b6561ace9c032d3aa03b71;hp=8ad60931f9f40b2f709b00dcba7eb27455a17664;hpb=78af5d15e9dd94959786811e9eddfa1e5024067c;p=chaz%2Fopenbox diff --git a/openbox/action.c b/openbox/action.c index 8ad60931..db49f56c 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -33,6 +33,7 @@ #include "dock.h" #include "config.h" #include "mainloop.h" +#include "startupnotify.h" #include @@ -40,7 +41,7 @@ inline 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, OB_CURSOR_NONE); + grab_pointer(TRUE, FALSE, OB_CURSOR_NONE); } inline void client_action_end(union ActionData *data) @@ -48,7 +49,7 @@ 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; @@ -433,6 +434,11 @@ void setup_action_showmenu(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; @@ -493,7 +499,7 @@ ActionString actionstrings[] = { "focus", action_focus, - setup_client_action + setup_action_focus }, { "unfocus", @@ -928,6 +934,15 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, 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); @@ -994,8 +1009,6 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, 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); } @@ -1005,7 +1018,7 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, } void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, - guint state, guint button, gint x, gint y, + guint state, guint button, gint x, gint y, Time time, gboolean cancel, gboolean done) { GSList *it; @@ -1034,7 +1047,7 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, 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)) { @@ -1048,6 +1061,8 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, a->data.any.button = button; + a->data.any.time = time; + if (a->data.any.interactive) { a->data.inter.cancel = cancel; a->data.inter.final = done; @@ -1068,7 +1083,7 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, } } -void action_run_string(const gchar *name, struct _ObClient *c) +void action_run_string(const gchar *name, struct _ObClient *c, Time time) { ObAction *a; GSList *l; @@ -1078,7 +1093,7 @@ void action_run_string(const gchar *name, struct _ObClient *c) l = g_slist_append(NULL, a); - action_run(l, c, 0); + action_run(l, c, 0, time); } void action_execute(union ActionData *data) @@ -1092,13 +1107,37 @@ void action_execute(union ActionData *data) g_warning("failed to execute '%s': %s", cmd, e->message); g_error_free(e); - } else { + } 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_warning("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_warning("failed to execute '%s': %s", + cmd, e->message); + g_error_free(e); } g_strfreev(argv); } @@ -1125,22 +1164,29 @@ void action_activate(union ActionData *data) 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) @@ -1188,7 +1234,7 @@ void action_raiselower(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); } @@ -1211,7 +1257,7 @@ void action_shadelower(union ActionData *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); } @@ -1313,28 +1359,35 @@ void action_move_relative(union ActionData *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); } @@ -1344,21 +1397,21 @@ void action_toggle_maximize_full(union ActionData *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); } @@ -1366,21 +1419,21 @@ 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, 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); } @@ -1388,15 +1441,14 @@ 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, 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); }