1 #include "openbox/actions.h"
2 #include "openbox/event.h"
3 #include "openbox/stacking.h"
4 #include "openbox/window.h"
5 #include "openbox/focus_cycle.h"
6 #include "openbox/openbox.h"
7 #include "openbox/misc.h"
13 gboolean dock_windows
;
14 gboolean desktop_windows
;
15 ObDirection direction
;
21 static gboolean cycling
= FALSE
;
23 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
);
24 static gpointer
setup_cycle_func(ObParseInst
*i
, xmlDocPtr doc
,
26 static gpointer
setup_target_func(ObParseInst
*i
, xmlDocPtr doc
,
28 static void free_func(gpointer options
);
29 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
30 static gboolean
i_input_func(guint initial_state
,
34 static void i_cancel_func(gpointer options
);
36 static void end_cycle(gboolean cancel
, guint state
, Options
*o
);
38 void action_directionalwindows_startup(void)
40 actions_register("DirectionalCycleWindows", setup_cycle_func
, free_func
,
41 run_func
, i_input_func
, i_cancel_func
);
42 actions_register("DirectionalTargetWindow", setup_target_func
, free_func
,
43 run_func
, NULL
, NULL
);
46 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
)
51 o
= g_new0(Options
, 1);
55 if ((n
= parse_find_node("dialog", node
)))
56 o
->dialog
= parse_bool(doc
, n
);
57 if ((n
= parse_find_node("bar", node
)))
58 o
->bar
= parse_bool(doc
, n
);
59 if ((n
= parse_find_node("raise", node
)))
60 o
->raise
= parse_bool(doc
, n
);
61 if ((n
= parse_find_node("panels", node
)))
62 o
->dock_windows
= parse_bool(doc
, n
);
63 if ((n
= parse_find_node("desktop", node
)))
64 o
->desktop_windows
= parse_bool(doc
, n
);
65 if ((n
= parse_find_node("direction", node
))) {
66 gchar
*s
= parse_string(doc
, n
);
67 if (!g_ascii_strcasecmp(s
, "north") ||
68 !g_ascii_strcasecmp(s
, "up"))
69 o
->direction
= OB_DIRECTION_NORTH
;
70 else if (!g_ascii_strcasecmp(s
, "northwest"))
71 o
->direction
= OB_DIRECTION_NORTHWEST
;
72 else if (!g_ascii_strcasecmp(s
, "northeast"))
73 o
->direction
= OB_DIRECTION_NORTHEAST
;
74 else if (!g_ascii_strcasecmp(s
, "west") ||
75 !g_ascii_strcasecmp(s
, "left"))
76 o
->direction
= OB_DIRECTION_WEST
;
77 else if (!g_ascii_strcasecmp(s
, "east") ||
78 !g_ascii_strcasecmp(s
, "right"))
79 o
->direction
= OB_DIRECTION_EAST
;
80 else if (!g_ascii_strcasecmp(s
, "south") ||
81 !g_ascii_strcasecmp(s
, "down"))
82 o
->direction
= OB_DIRECTION_SOUTH
;
83 else if (!g_ascii_strcasecmp(s
, "southwest"))
84 o
->direction
= OB_DIRECTION_SOUTHWEST
;
85 else if (!g_ascii_strcasecmp(s
, "southeast"))
86 o
->direction
= OB_DIRECTION_SOUTHEAST
;
90 if ((n
= parse_find_node("finalactions", node
))) {
93 m
= parse_find_node("action", n
->xmlChildrenNode
);
95 ObActionsAct
*action
= actions_parse(i
, doc
, m
);
96 if (action
) o
->actions
= g_slist_prepend(o
->actions
, action
);
97 m
= parse_find_node("action", m
->next
);
101 o
->actions
= g_slist_prepend(o
->actions
,
102 actions_parse_string("Focus"));
103 o
->actions
= g_slist_prepend(o
->actions
,
104 actions_parse_string("Raise"));
105 o
->actions
= g_slist_prepend(o
->actions
,
106 actions_parse_string("Unshade"));
112 static gpointer
setup_cycle_func(ObParseInst
*i
, xmlDocPtr doc
,
115 Options
*o
= setup_func(i
, doc
, node
);
116 o
->interactive
= TRUE
;
120 static gpointer
setup_target_func(ObParseInst
*i
, xmlDocPtr doc
,
123 Options
*o
= setup_func(i
, doc
, node
);
124 o
->interactive
= FALSE
;
128 static void free_func(gpointer options
)
130 Options
*o
= options
;
133 actions_act_unref(o
->actions
->data
);
134 o
->actions
= g_slist_delete_link(o
->actions
, o
->actions
);
140 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
142 Options
*o
= options
;
145 end_cycle(FALSE
, data
->state
, o
);
147 struct _ObClient
*ft
;
149 ft
= focus_directional_cycle(o
->direction
,
159 if (o
->raise
) stacking_temp_raise(CLIENT_AS_WINDOW(ft
));
162 return o
->interactive
;
165 static gboolean
i_input_func(guint initial_state
,
170 if (e
->type
== KeyPress
) {
171 /* Escape cancels no matter what */
172 if (e
->xkey
.keycode
== ob_keycode(OB_KEY_ESCAPE
)) {
173 end_cycle(TRUE
, e
->xkey
.state
, options
);
177 /* There were no modifiers and they pressed enter */
178 else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RETURN
) &&
181 end_cycle(FALSE
, e
->xkey
.state
, options
);
185 /* They released the modifiers */
186 else if (e
->type
== KeyRelease
&& initial_state
&&
187 (e
->xkey
.state
& initial_state
) == 0)
189 end_cycle(FALSE
, e
->xkey
.state
, options
);
196 static void i_cancel_func(gpointer options
)
198 /* we get cancelled when we move focus, but we're not cycling anymore, so
201 end_cycle(TRUE
, 0, options
);
204 static void end_cycle(gboolean cancel
, guint state
, Options
*o
)
206 struct _ObClient
*ft
;
208 ft
= focus_directional_cycle(o
->direction
,
218 actions_run_acts(o
->actions
, OB_USER_ACTION_KEYBOARD_KEY
,
219 state
, -1, -1, 0, OB_FRAME_CONTEXT_NONE
, ft
);