1 #include "openbox/actions.h"
2 #include "openbox/event.h"
3 #include "openbox/focus_cycle.h"
4 #include "openbox/openbox.h"
5 #include "openbox/misc.h"
11 gboolean dock_windows
;
12 gboolean desktop_windows
;
13 ObDirection direction
;
17 static gboolean cycling
= FALSE
;
19 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
);
20 static gpointer
setup_cycle_func(ObParseInst
*i
, xmlDocPtr doc
,
22 static gpointer
setup_target_func(ObParseInst
*i
, xmlDocPtr doc
,
24 static void free_func(gpointer options
);
25 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
26 static gboolean
i_input_func(guint initial_state
,
30 static void i_cancel_func(gpointer options
);
32 static void end_cycle(gboolean cancel
, guint state
, Options
*o
);
34 void action_directionalwindows_startup()
36 actions_register("DirectionalCycleWindows", setup_cycle_func
, free_func
,
37 run_func
, i_input_func
, i_cancel_func
);
38 actions_register("DirectionalTargetWindow", setup_target_func
, free_func
,
39 run_func
, NULL
, NULL
);
42 static gpointer
setup_func(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
)
47 o
= g_new0(Options
, 1);
50 if ((n
= parse_find_node("dialog", node
)))
51 o
->dialog
= parse_bool(doc
, n
);
52 if ((n
= parse_find_node("panels", node
)))
53 o
->dock_windows
= parse_bool(doc
, n
);
54 if ((n
= parse_find_node("desktop", node
)))
55 o
->desktop_windows
= parse_bool(doc
, n
);
56 if ((n
= parse_find_node("direction", node
))) {
57 gchar
*s
= parse_string(doc
, n
);
58 if (!g_ascii_strcasecmp(s
, "north") ||
59 !g_ascii_strcasecmp(s
, "up"))
60 o
->direction
= OB_DIRECTION_NORTH
;
61 else if (!g_ascii_strcasecmp(s
, "northwest"))
62 o
->direction
= OB_DIRECTION_NORTHWEST
;
63 else if (!g_ascii_strcasecmp(s
, "northeast"))
64 o
->direction
= OB_DIRECTION_NORTHEAST
;
65 else if (!g_ascii_strcasecmp(s
, "west") ||
66 !g_ascii_strcasecmp(s
, "left"))
67 o
->direction
= OB_DIRECTION_WEST
;
68 else if (!g_ascii_strcasecmp(s
, "east") ||
69 !g_ascii_strcasecmp(s
, "right"))
70 o
->direction
= OB_DIRECTION_EAST
;
71 else if (!g_ascii_strcasecmp(s
, "south") ||
72 !g_ascii_strcasecmp(s
, "down"))
73 o
->direction
= OB_DIRECTION_SOUTH
;
74 else if (!g_ascii_strcasecmp(s
, "southwest"))
75 o
->direction
= OB_DIRECTION_SOUTHWEST
;
76 else if (!g_ascii_strcasecmp(s
, "southeast"))
77 o
->direction
= OB_DIRECTION_SOUTHEAST
;
81 if ((n
= parse_find_node("finalactions", node
))) {
84 m
= parse_find_node("action", n
->xmlChildrenNode
);
86 ObActionsAct
*action
= actions_parse(i
, doc
, m
);
87 if (action
) o
->actions
= g_slist_prepend(o
->actions
, action
);
88 m
= parse_find_node("action", m
->next
);
92 o
->actions
= g_slist_prepend(o
->actions
,
93 actions_parse_string("Focus"));
94 o
->actions
= g_slist_prepend(o
->actions
,
95 actions_parse_string("Raise"));
96 o
->actions
= g_slist_prepend(o
->actions
,
97 actions_parse_string("Unshade"));
103 static gpointer
setup_cycle_func(ObParseInst
*i
, xmlDocPtr doc
,
106 Options
*o
= setup_func(i
, doc
, node
);
107 o
->interactive
= TRUE
;
111 static gpointer
setup_target_func(ObParseInst
*i
, xmlDocPtr doc
,
114 Options
*o
= setup_func(i
, doc
, node
);
115 o
->interactive
= FALSE
;
119 static void free_func(gpointer options
)
121 Options
*o
= options
;
124 actions_act_unref(o
->actions
->data
);
125 o
->actions
= g_slist_delete_link(o
->actions
, o
->actions
);
131 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
133 Options
*o
= options
;
136 end_cycle(FALSE
, data
->state
, o
);
138 focus_directional_cycle(o
->direction
,
147 return o
->interactive
;
150 static gboolean
i_input_func(guint initial_state
,
155 if (e
->type
== KeyPress
) {
156 /* Escape cancels no matter what */
157 if (e
->xkey
.keycode
== ob_keycode(OB_KEY_ESCAPE
)) {
158 end_cycle(TRUE
, e
->xkey
.state
, options
);
162 /* There were no modifiers and they pressed enter */
163 else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RETURN
) &&
166 end_cycle(FALSE
, e
->xkey
.state
, options
);
170 /* They released the modifiers */
171 else if (e
->type
== KeyRelease
&& initial_state
&&
172 (e
->xkey
.state
& initial_state
) == 0)
174 end_cycle(FALSE
, e
->xkey
.state
, options
);
181 static void i_cancel_func(gpointer options
)
183 /* we get cancelled when we move focus, but we're not cycling anymore, so
186 end_cycle(TRUE
, 0, options
);
189 static void end_cycle(gboolean cancel
, guint state
, Options
*o
)
191 struct _ObClient
*ft
;
193 ft
= focus_directional_cycle(o
->direction
,
202 actions_run_acts(o
->actions
, OB_USER_ACTION_KEYBOARD_KEY
,
203 state
, -1, -1, 0, OB_FRAME_CONTEXT_NONE
, ft
);