(*a)->data.layer.layer = -1;
}
-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_client_action(ObAction **a, ObUserAction uact)
{
(*a)->data.any.client_action = OB_CLIENT_ACTION_ALWAYS;
action_growtoedge,
setup_action_growtoedge_east
},
- {
- "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,
}
};
-/* only key bindings can be interactive. thus saith the xor.
- because of how the mouse is grabbed, mouse events dont even get
- read during interactive events, so no dice! >:) */
-#define INTERACTIVE_LIMIT(a, uact) \
- if (uact != OB_USER_ACTION_KEYBOARD_KEY) \
- a->data.any.interactive = FALSE;
-
-ObAction *action_from_string(const gchar *name, ObUserAction uact)
-{
- ObAction *a = NULL;
- gboolean exist = FALSE;
- gint i;
-
- for (i = 0; actionstrings[i].name; i++)
- if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
- exist = TRUE;
- a = action_new(actionstrings[i].func);
- if (actionstrings[i].setup)
- actionstrings[i].setup(&a, uact);
- if (a)
- INTERACTIVE_LIMIT(a, uact);
- break;
- }
- if (!exist)
- g_message(_("Invalid action '%s' requested. No such action exists."),
- name);
- if (!a)
- g_message(_("Invalid use of action '%s'. Action will be ignored."),
- name);
- return a;
-}
-
-ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
- ObUserAction uact)
-{
- gchar *actname;
- ObAction *act = NULL;
- xmlNodePtr n;
-
- if (parse_attr_string("name", node, &actname)) {
- if ((act = action_from_string(actname, uact))) {
- } else if (act->func == action_desktop) {
- } else if (act->func == action_send_to_desktop_dir) {
- if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
- act->data.sendtodir.wrap = parse_bool(doc, n);
- if ((n = parse_find_node("follow", node->xmlChildrenNode)))
- act->data.sendtodir.follow = parse_bool(doc, n);
- if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
- act->data.sendtodir.inter.any.interactive =
- parse_bool(doc, n);
- INTERACTIVE_LIMIT(act, uact);
- }
- g_free(actname);
- }
- return act;
-}
-
-
void action_unshaderaise(union ActionData *data)
{
if (data->client.any.c->shaded)
action_shade(data);
}
-void action_send_to_desktop_dir(union ActionData *data)
-{
- ObClient *c = data->sendtodir.inter.any.c;
- guint d;
-
- if (!client_normal(c)) return;
-
- d = screen_cycle_desktop(data->sendtodir.dir, data->sendtodir.wrap,
- data->sendtodir.linear,
- data->sendtodir.inter.any.interactive,
- data->sendtodir.inter.final,
- data->sendtodir.inter.cancel);
- /* only move the desktop when the action is complete. if we switch
- desktops during the interactive action, focus will move but with
- NotifyWhileGrabbed and applications don't like that. */
- if (!data->sendtodir.inter.any.interactive ||
- (data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
- {
- client_set_desktop(c, d, data->sendtodir.follow, FALSE);
- if (data->sendtodir.follow && d != screen_desktop)
- screen_set_desktop(d, TRUE);
- }
-}
-
-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->interdiraction.dock_windows,
- data->interdiraction.desktop_windows,
- data->any.interactive,
- data->interdiraction.dialog,
- data->interdiraction.inter.final,
- data->interdiraction.inter.cancel);
-}
-
void action_movetoedge(union ActionData *data)
{
gint x, y;
dock_configure();
}
-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);
}
--- /dev/null
+#include "openbox/actions.h"
+#include "openbox/screen.h"
+#include "openbox/client.h"
+#include "openbox/debug.h"
+#include <glib.h>
+
+typedef struct {
+ gboolean current;
+ gboolean add;
+} Options;
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_add_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_remove_func(ObParseInst *i,
+ xmlDocPtr doc, xmlNodePtr node);
+static void free_func(gpointer options);
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_addremovedesktop_startup()
+{
+ actions_register("AddDesktop",
+ setup_add_func,
+ free_func,
+ run_func,
+ NULL, NULL);
+ actions_register("RemoveDesktop",
+ setup_remove_func,
+ free_func,
+ run_func,
+ NULL, NULL);
+}
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o;
+
+ o = g_new0(Options, 1);
+
+ if ((n = parse_find_node("where", node))) {
+ gchar *s = parse_string(doc, n);
+ if (!g_ascii_strcasecmp(s, "last"))
+ o->current = FALSE;
+ else if (!g_ascii_strcasecmp(s, "current"))
+ o->current = TRUE;
+ g_free(s);
+ }
+
+ return o;
+}
+
+static gpointer setup_add_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+ Options *o = setup_func(i, doc, node);
+ o->add = TRUE;
+ return o;
+}
+
+static gpointer setup_remove_func(ObParseInst *i,
+ xmlDocPtr doc, xmlNodePtr node)
+{
+ Options *o = setup_func(i, doc, node);
+ o->add = FALSE;
+ return o;
+}
+
+static void free_func(gpointer options)
+{
+ Options *o = options;
+
+ g_free(o);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+ Options *o = options;
+
+ actions_client_move(data, FALSE);
+
+ if (o->add) {
+ screen_set_num_desktops(screen_num_desktops+1);
+
+ /* move all the clients over */
+ if (o->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);
+ }
+ }
+ }
+ else if (screen_num_desktops > 1) {
+ guint rmdesktop, movedesktop;
+ GList *it, *stacking_copy;
+
+ /* what desktop are we removing and moving to? */
+ if (o->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);
+ }
+
+ actions_client_move(data, TRUE);
+
+ return FALSE;
+}