add the adddesktop and removedesktop actions
This commit is contained in:
parent
74aa6fe7cc
commit
b963ed3a92
5 changed files with 148 additions and 196 deletions
|
@ -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 \
|
||||
|
|
196
openbox/action.c
196
openbox/action.c
|
@ -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);
|
||||
}
|
||||
|
|
145
openbox/actions/addremovedesktop.c
Normal file
145
openbox/actions/addremovedesktop.c
Normal 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;
|
||||
}
|
|
@ -35,4 +35,5 @@ void action_all_startup()
|
|||
action_desktop_startup();
|
||||
action_directionaldesktop_startup();
|
||||
action_resizerelative_startup();
|
||||
action_addremovedesktop_startup();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue