X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Factions%2Fdesktop.c;h=07416151cb7190b588b2272a0a4ad4ecc2060e69;hb=7f36e21ea9d86df5e6fa62d2888891ed957c4639;hp=7461d8495e4a282c5dfc272df82627c36e787854;hpb=16f2b255cb3e504f7695bc94ec691f949bf6722d;p=chaz%2Fopenbox diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index 7461d849..07416151 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -1,50 +1,156 @@ #include "openbox/actions.h" #include "openbox/screen.h" +#include "openbox/client.h" #include +typedef enum { + LAST, + RELATIVE, + ABSOLUTE +} SwitchType; + typedef struct { - guint desktop; + SwitchType type; + union { + struct { + guint desktop; + } abs; + + struct { + gboolean linear; + gboolean wrap; + ObDirection dir; + } rel; + } u; + gboolean send; + gboolean follow; } Options; -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node); -static void free_func(gpointer options); +static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc, + xmlNodePtr node); +static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc, + xmlNodePtr node); static gboolean run_func(ObActionsData *data, gpointer options); -void action_desktop_startup() +void action_desktop_startup(void) { - actions_register("desktop", - setup_func, - free_func, - run_func, + actions_register("GoToDesktop", setup_go_func, g_free, run_func, + NULL, NULL); + actions_register("SendToDesktop", setup_send_func, g_free, run_func, NULL, NULL); } -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) +static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc, + xmlNodePtr node) { xmlNodePtr n; Options *o; o = g_new0(Options, 1); + /* don't go anywhere if theres no options given */ + o->type = ABSOLUTE; + o->u.abs.desktop = screen_desktop; + /* wrap by default - it's handy! */ + o->u.rel.wrap = TRUE; + + if ((n = parse_find_node("to", node))) { + gchar *s = parse_string(doc, n); + if (!g_ascii_strcasecmp(s, "last")) + o->type = LAST; + else if (!g_ascii_strcasecmp(s, "next")) { + o->type = RELATIVE; + o->u.rel.linear = TRUE; + o->u.rel.dir = OB_DIRECTION_EAST; + } + else if (!g_ascii_strcasecmp(s, "previous")) { + o->type = RELATIVE; + o->u.rel.linear = TRUE; + o->u.rel.dir = OB_DIRECTION_WEST; + } + else if (!g_ascii_strcasecmp(s, "north") || + !g_ascii_strcasecmp(s, "up")) { + o->type = RELATIVE; + o->u.rel.dir = OB_DIRECTION_NORTH; + } + else if (!g_ascii_strcasecmp(s, "south") || + !g_ascii_strcasecmp(s, "down")) { + o->type = RELATIVE; + o->u.rel.dir = OB_DIRECTION_SOUTH; + } + else if (!g_ascii_strcasecmp(s, "west") || + !g_ascii_strcasecmp(s, "left")) { + o->type = RELATIVE; + o->u.rel.dir = OB_DIRECTION_WEST; + } + else if (!g_ascii_strcasecmp(s, "east") || + !g_ascii_strcasecmp(s, "right")) { + o->type = RELATIVE; + o->u.rel.dir = OB_DIRECTION_EAST; + } + else { + o->type = ABSOLUTE; + o->u.abs.desktop = atoi(s) - 1; + } + g_free(s); + } + + if ((n = parse_find_node("wrap", node))) + o->u.rel.wrap = parse_bool(doc, n); - if ((n = parse_find_node("desktop", node))) - o->desktop = parse_int(doc, n) - 1; return o; } -static void free_func(gpointer options) +static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc, + xmlNodePtr node) { - Options *o = options; + xmlNodePtr n; + Options *o; + + o = setup_go_func(i, doc, node); + o->send = TRUE; + o->follow = TRUE; - g_free(o); + if ((n = parse_find_node("follow", node))) + o->follow = parse_bool(doc, n); + + return o; } /* Always return FALSE because its not interactive */ static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; + guint d; + + switch (o->type) { + case LAST: + d = screen_last_desktop; + break; + case ABSOLUTE: + d = o->u.abs.desktop; + break; + case RELATIVE: + d = screen_find_desktop(screen_desktop, + o->u.rel.dir, o->u.rel.wrap, o->u.rel.linear); + break; + } + + if (d < screen_num_desktops && d != screen_desktop) { + gboolean go = TRUE; + + actions_client_move(data, TRUE); + if (o->send && data->client && client_normal(data->client)) { + client_set_desktop(data->client, d, o->follow, FALSE); + go = o->follow; + } - if (o->desktop < screen_num_desktops) - screen_set_desktop(o->desktop, TRUE); + if (go) { + screen_set_desktop(d, TRUE); + if (data->client) + client_bring_helper_windows(data->client); + } + actions_client_move(data, FALSE); + } return FALSE; }