summaryrefslogtreecommitdiff
path: root/openbox/actions/desktop.c
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2009-12-16 15:17:08 -0500
committerDana Jansens <danakj@orodu.net>2009-12-17 10:33:06 -0500
commit1a348576400b26dad3a58a81415c4c833fb4915c (patch)
tree39bbdd4efba2b2d7d9e270db837737ad9dab5db3 /openbox/actions/desktop.c
parent1b392b5fbe85c55cda2b0fc9d1e10cbe56216185 (diff)
Make the relative desktop switching actions interactive
The desktop popup can now be shown "permanently" in which case it stays until you tell it to hide.
Diffstat (limited to 'openbox/actions/desktop.c')
-rw-r--r--openbox/actions/desktop.c341
1 files changed, 278 insertions, 63 deletions
diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c
index 27b717b1..14f6ef20 100644
--- a/openbox/actions/desktop.c
+++ b/openbox/actions/desktop.c
@@ -1,6 +1,7 @@
#include "openbox/actions.h"
#include "openbox/screen.h"
#include "openbox/client.h"
+#include "openbox/openbox.h"
#include <glib.h>
typedef enum {
@@ -24,59 +25,130 @@ typedef struct {
} u;
gboolean send;
gboolean follow;
+ gboolean interactive;
} Options;
-static gpointer setup_go_func(xmlNodePtr node);
-static gpointer setup_send_func(xmlNodePtr node);
+static gpointer setup_go_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
static gboolean run_func(ObActionsData *data, gpointer options);
+
+static gboolean i_pre_func(guint state, gpointer options);
+static gboolean i_input_func(guint initial_state,
+ XEvent *e,
+ gpointer options,
+ gboolean *used);
+static void i_post_func(gpointer options);
+
/* 3.4-compatibility */
static gpointer setup_go_last_func(xmlNodePtr node);
static gpointer setup_send_last_func(xmlNodePtr node);
static gpointer setup_go_abs_func(xmlNodePtr node);
static gpointer setup_send_abs_func(xmlNodePtr node);
-static gpointer setup_go_next_func(xmlNodePtr node);
-static gpointer setup_send_next_func(xmlNodePtr node);
-static gpointer setup_go_prev_func(xmlNodePtr node);
-static gpointer setup_send_prev_func(xmlNodePtr node);
-static gpointer setup_go_left_func(xmlNodePtr node);
-static gpointer setup_send_left_func(xmlNodePtr node);
-static gpointer setup_go_right_func(xmlNodePtr node);
-static gpointer setup_send_right_func(xmlNodePtr node);
-static gpointer setup_go_up_func(xmlNodePtr node);
-static gpointer setup_send_up_func(xmlNodePtr node);
-static gpointer setup_go_down_func(xmlNodePtr node);
-static gpointer setup_send_down_func(xmlNodePtr node);
-
+static gpointer setup_go_next_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_next_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_go_prev_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_prev_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_go_left_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_left_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_go_right_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_right_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_go_up_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_up_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_go_down_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+static gpointer setup_send_down_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post);
+
void action_desktop_startup(void)
{
- actions_register("GoToDesktop", setup_go_func, g_free, run_func);
- actions_register("SendToDesktop", setup_send_func, g_free, run_func);
+ actions_register_i("GoToDesktop", setup_go_func, g_free, run_func);
+ actions_register_i("SendToDesktop", setup_send_func, g_free, run_func);
/* 3.4-compatibility */
actions_register("DesktopLast", setup_go_last_func, g_free, run_func);
actions_register("SendToDesktopLast", setup_send_last_func,
g_free, run_func);
actions_register("Desktop", setup_go_abs_func, g_free, run_func);
actions_register("SendToDesktop", setup_send_abs_func, g_free, run_func);
- actions_register("DesktopNext", setup_go_next_func, g_free, run_func);
- actions_register("SendToDesktopNext", setup_send_next_func,
- g_free, run_func);
- actions_register("DesktopPrevious", setup_go_prev_func, g_free, run_func);
- actions_register("SendToDesktopPrevious", setup_send_prev_func,
- g_free, run_func);
- actions_register("DesktopLeft", setup_go_left_func, g_free, run_func);
- actions_register("SendToDesktopLeft", setup_send_left_func,
- g_free, run_func);
- actions_register("DesktopRight", setup_go_right_func, g_free, run_func);
- actions_register("SendToDesktopRight", setup_send_right_func,
- g_free, run_func);
- actions_register("DesktopUp", setup_go_up_func, g_free, run_func);
- actions_register("SendToDesktopUp", setup_send_up_func, g_free, run_func);
- actions_register("DesktopDown", setup_go_down_func, g_free, run_func);
- actions_register("SendToDesktopDown", setup_send_down_func,
- g_free, run_func);
+ actions_register_i("DesktopNext", setup_go_next_func, g_free, run_func);
+ actions_register_i("SendToDesktopNext", setup_send_next_func,
+ g_free, run_func);
+ actions_register_i("DesktopPrevious", setup_go_prev_func,
+ g_free, run_func);
+ actions_register_i("SendToDesktopPrevious", setup_send_prev_func,
+ g_free, run_func);
+ actions_register_i("DesktopLeft", setup_go_left_func, g_free, run_func);
+ actions_register_i("SendToDesktopLeft", setup_send_left_func,
+ g_free, run_func);
+ actions_register_i("DesktopRight", setup_go_right_func, g_free, run_func);
+ actions_register_i("SendToDesktopRight", setup_send_right_func,
+ g_free, run_func);
+ actions_register_i("DesktopUp", setup_go_up_func, g_free, run_func);
+ actions_register_i("SendToDesktopUp", setup_send_up_func,
+ g_free, run_func);
+ actions_register_i("DesktopDown", setup_go_down_func, g_free, run_func);
+ actions_register_i("SendToDesktopDown", setup_send_down_func,
+ g_free, run_func);
}
-static gpointer setup_go_func(xmlNodePtr node)
+static gpointer setup_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
xmlNodePtr n;
Options *o;
@@ -135,18 +207,49 @@ static gpointer setup_go_func(xmlNodePtr node)
return o;
}
-static gpointer setup_send_func(xmlNodePtr node)
+
+static gpointer setup_go_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o;
+
+ o = setup_func(node, pre, input, cancel, post);
+ if (o->type == RELATIVE) {
+ o->interactive = TRUE;
+ *pre = i_pre_func;
+ *input = i_input_func;
+ *post = i_post_func;
+ }
+
+ return o;
+}
+
+static gpointer setup_send_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
xmlNodePtr n;
Options *o;
- o = setup_go_func(node);
+ o = setup_func(node, pre, input, cancel, post);
o->send = TRUE;
o->follow = TRUE;
if ((n = obt_parse_find_node(node, "follow")))
o->follow = obt_parse_node_bool(n);
+ if (o->type == RELATIVE && o->follow) {
+ o->interactive = TRUE;
+ *pre = i_pre_func;
+ *input = i_input_func;
+ *post = i_post_func;
+ }
+
return o;
}
@@ -188,7 +291,54 @@ static gboolean run_func(ObActionsData *data, gpointer options)
actions_client_move(data, FALSE);
}
- return FALSE;
+
+ return o->interactive;
+}
+
+static gboolean i_input_func(guint initial_state,
+ XEvent *e,
+ gpointer options,
+ gboolean *used)
+{
+ if (e->type == KeyPress) {
+ /* Escape cancels no matter what */
+ if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
+ return FALSE;
+ }
+
+ /* There were no modifiers and they pressed enter */
+ else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) &&
+ !initial_state)
+ {
+ return FALSE;
+ }
+ }
+ /* They released the modifiers */
+ else if (e->type == KeyRelease && initial_state &&
+ (e->xkey.state & initial_state) == 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean i_pre_func(guint initial_state, gpointer options)
+{
+ if (!initial_state) {
+ Options *o = options;
+ o->interactive = FALSE;
+ return FALSE;
+ }
+ else {
+ screen_show_desktop_popup(screen_desktop, TRUE);
+ return TRUE;
+ }
+}
+
+static void i_post_func(gpointer options)
+{
+ screen_hide_desktop_popup();
}
/* 3.4-compatilibity */
@@ -241,7 +391,11 @@ static gpointer setup_send_abs_func(xmlNodePtr node)
return o;
}
-static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, ObDirection dir)
+static void setup_rel(Options *o, xmlNodePtr node, gboolean lin,
+ ObDirection dir,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsIPostFunc *post)
{
xmlNodePtr n;
@@ -252,88 +406,149 @@ static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, ObDirection dir
if ((n = obt_parse_find_node(node, "wrap")))
o->u.rel.wrap = obt_parse_node_bool(n);
+
+ if (input) {
+ o->interactive = TRUE;
+ *pre = i_pre_func;
+ *input = i_input_func;
+ *post = i_post_func;
+ }
}
-static gpointer setup_go_next_func(xmlNodePtr node)
+static gpointer setup_go_next_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, TRUE, OB_DIRECTION_EAST);
+ setup_rel(o, node, TRUE, OB_DIRECTION_EAST, pre, input, post);
return o;
}
-static gpointer setup_send_next_func(xmlNodePtr node)
+static gpointer setup_send_next_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, TRUE, OB_DIRECTION_EAST);
+ setup_rel(o, node, TRUE, OB_DIRECTION_EAST,
+ pre, (o->follow ? input : NULL), post);
return o;
}
-static gpointer setup_go_prev_func(xmlNodePtr node)
+static gpointer setup_go_prev_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, TRUE, OB_DIRECTION_WEST);
+ setup_rel(o, node, TRUE, OB_DIRECTION_WEST, pre, input, post);
return o;
}
-static gpointer setup_send_prev_func(xmlNodePtr node)
+static gpointer setup_send_prev_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, TRUE, OB_DIRECTION_WEST);
+ setup_rel(o, node, TRUE, OB_DIRECTION_WEST,
+ pre, (o->follow ? input : NULL), post);
return o;
}
-static gpointer setup_go_left_func(xmlNodePtr node)
+static gpointer setup_go_left_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, FALSE, OB_DIRECTION_WEST);
+ setup_rel(o, node, FALSE, OB_DIRECTION_WEST, pre, input, post);
return o;
}
-static gpointer setup_send_left_func(xmlNodePtr node)
+static gpointer setup_send_left_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, FALSE, OB_DIRECTION_WEST);
+ setup_rel(o, node, FALSE, OB_DIRECTION_WEST,
+ pre, (o->follow ? input : NULL), post);
return o;
}
-static gpointer setup_go_right_func(xmlNodePtr node)
+static gpointer setup_go_right_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, FALSE, OB_DIRECTION_EAST);
+ setup_rel(o, node, FALSE, OB_DIRECTION_EAST, pre, input, post);
return o;
}
-static gpointer setup_send_right_func(xmlNodePtr node)
+static gpointer setup_send_right_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, FALSE, OB_DIRECTION_EAST);
+ setup_rel(o, node, FALSE, OB_DIRECTION_EAST,
+ pre, (o->follow ? input : NULL), post);
return o;
}
-static gpointer setup_go_up_func(xmlNodePtr node)
+static gpointer setup_go_up_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, FALSE, OB_DIRECTION_NORTH);
+ setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, pre, input, post);
return o;
}
-static gpointer setup_send_up_func(xmlNodePtr node)
+static gpointer setup_send_up_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, FALSE, OB_DIRECTION_NORTH);
+ setup_rel(o, node, FALSE, OB_DIRECTION_NORTH,
+ pre, (o->follow ? input : NULL), post);
return o;
}
-static gpointer setup_go_down_func(xmlNodePtr node)
+static gpointer setup_go_down_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = g_new0(Options, 1);
- setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH);
+ setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, pre, input, post);
return o;
}
-static gpointer setup_send_down_func(xmlNodePtr node)
+static gpointer setup_send_down_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
{
Options *o = setup_follow(node);
- setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH);
+ setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH,
+ pre, (o->follow ? input : NULL), post);
return o;
}