+ else {
+ screen_show_desktop_popup(screen_desktop, TRUE);
+ return TRUE;
+ }
+}
+
+static void i_post_func(gpointer options)
+{
+ screen_hide_desktop_popup();
+}
+
+/* 3.4-compatilibity */
+static gpointer setup_follow(xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o = g_slice_new0(Options);
+ o->send = TRUE;
+ o->follow = TRUE;
+ if ((n = obt_xml_find_node(node, "follow")))
+ o->follow = obt_xml_node_bool(n);
+ return o;
+}
+
+static gpointer setup_go_last_func(xmlNodePtr node)
+{
+ Options *o = g_slice_new0(Options);
+ o->type = LAST;
+ return o;
+}
+
+static gpointer setup_send_last_func(xmlNodePtr node)
+{
+ Options *o = setup_follow(node);
+ o->type = LAST;
+ return o;
+}
+
+static gpointer setup_go_abs_func(xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o = g_slice_new0(Options);
+ o->type = ABSOLUTE;
+ if ((n = obt_xml_find_node(node, "desktop")))
+ o->u.abs.desktop = obt_xml_node_int(n) - 1;
+ else
+ o->u.abs.desktop = screen_desktop;
+ return o;
+}
+
+static void setup_rel(Options *o, xmlNodePtr node, gboolean lin,
+ ObDirection dir,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsIPostFunc *post)
+{
+ xmlNodePtr n;
+
+ o->type = RELATIVE;
+ o->u.rel.linear = lin;
+ o->u.rel.dir = dir;
+ o->u.rel.wrap = TRUE;
+
+ if ((n = obt_xml_find_node(node, "wrap")))
+ o->u.rel.wrap = obt_xml_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,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, TRUE, OB_DIRECTION_EAST, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;
+}
+
+static gpointer setup_go_prev_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, TRUE, OB_DIRECTION_WEST, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;
+}
+
+static gpointer setup_go_left_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, FALSE, OB_DIRECTION_WEST, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;
+}
+
+static gpointer setup_go_right_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, FALSE, OB_DIRECTION_EAST, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;
+}
+
+static gpointer setup_go_up_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;
+}
+
+static gpointer setup_go_down_func(xmlNodePtr node,
+ ObActionsIPreFunc *pre,
+ ObActionsIInputFunc *input,
+ ObActionsICancelFunc *cancel,
+ ObActionsIPostFunc *post)
+{
+ Options *o = g_slice_new0(Options);
+ setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, pre, input, post);
+ return o;
+}
+
+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,
+ pre, (o->follow ? input : NULL), post);
+ return o;