add the adddesktop and removedesktop actions

This commit is contained in:
Dana Jansens 2007-06-23 14:42:06 +00:00
parent 74aa6fe7cc
commit b963ed3a92
5 changed files with 148 additions and 196 deletions

View file

@ -156,6 +156,7 @@ openbox_openbox_SOURCES = \
gettext.h \
openbox/actions/all.c \
openbox/actions/all.h \
openbox/actions/addremovedesktop.c \
openbox/actions/breakchroot.c \
openbox/actions/close.c \
openbox/actions/cyclewindows.c \

View file

@ -302,16 +302,6 @@ void setup_action_bottom_layer(ObAction **a, ObUserAction uact)
(*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;
@ -449,26 +439,6 @@ ActionString actionstrings[] =
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,
@ -476,64 +446,6 @@ ActionString actionstrings[] =
}
};
/* 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)
@ -550,45 +462,6 @@ void action_shadelower(union ActionData *data)
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;
@ -718,75 +591,6 @@ void action_toggle_dockautohide(union ActionData *data)
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);
}

View file

@ -0,0 +1,145 @@
#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;
}

View file

@ -35,4 +35,5 @@ void action_all_startup()
action_desktop_startup();
action_directionaldesktop_startup();
action_resizerelative_startup();
action_addremovedesktop_startup();
}

View file

@ -36,5 +36,6 @@ void action_decorations_startup();
void action_desktop_startup();
void action_directionaldesktop_startup();
void action_resizerelative_startup();
void action_addremovedesktop_startup();
#endif