1 #include "openbox/actions.h"
2 #include "openbox/stacking.h"
3 #include "openbox/window.h"
4 #include "openbox/event.h"
5 #include "openbox/focus_cycle.h"
6 #include "openbox/openbox.h"
8 #include "obt/keyboard.h"
12 gboolean dock_windows
;
13 gboolean desktop_windows
;
14 gboolean only_hilite_windows
;
15 gboolean all_desktops
;
20 ObFocusCyclePopupMode dialog_mode
;
24 /* options for after we're done */
25 gboolean cancel
; /* did the user cancel or not */
26 guint state
; /* keyboard state when finished */
29 static gpointer
setup_func(xmlNodePtr node
,
30 ObActionsIPreFunc
*pre
,
31 ObActionsIInputFunc
*in
,
32 ObActionsICancelFunc
*c
,
33 ObActionsIPostFunc
*post
);
34 static gpointer
setup_forward_func(xmlNodePtr node
,
35 ObActionsIPreFunc
*pre
,
36 ObActionsIInputFunc
*in
,
37 ObActionsICancelFunc
*c
,
38 ObActionsIPostFunc
*post
);
39 static gpointer
setup_backward_func(xmlNodePtr node
,
40 ObActionsIPreFunc
*pre
,
41 ObActionsIInputFunc
*in
,
42 ObActionsICancelFunc
*c
,
43 ObActionsIPostFunc
*post
);
44 static void free_func(gpointer options
);
45 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
46 static gboolean
i_input_func(guint initial_state
,
51 static void i_cancel_func(gpointer options
);
52 static void i_post_func(gpointer options
);
54 void action_cyclewindows_startup(void)
56 actions_register_i("NextWindow", setup_forward_func
, free_func
, run_func
);
57 actions_register_i("PreviousWindow", setup_backward_func
, free_func
,
61 static gpointer
setup_func(xmlNodePtr node
,
62 ObActionsIPreFunc
*pre
,
63 ObActionsIInputFunc
*input
,
64 ObActionsICancelFunc
*cancel
,
65 ObActionsIPostFunc
*post
)
70 o
= g_slice_new0(Options
);
72 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_LIST
;
73 o
->interactive
= TRUE
;
75 if ((n
= obt_xml_find_node(node
, "linear")))
76 o
->linear
= obt_xml_node_bool(n
);
77 if ((n
= obt_xml_find_node(node
, "dialog"))) {
78 if (obt_xml_node_contains(n
, "none"))
79 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_NONE
;
80 else if (obt_xml_node_contains(n
, "no"))
81 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_NONE
;
82 else if (obt_xml_node_contains(n
, "icons"))
83 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_ICONS
;
85 if ((n
= obt_xml_find_node(node
, "interactive")))
86 o
->interactive
= obt_xml_node_bool(n
);
87 if ((n
= obt_xml_find_node(node
, "bar")))
88 o
->bar
= obt_xml_node_bool(n
);
89 if ((n
= obt_xml_find_node(node
, "raise")))
90 o
->raise
= obt_xml_node_bool(n
);
91 if ((n
= obt_xml_find_node(node
, "panels")))
92 o
->dock_windows
= obt_xml_node_bool(n
);
93 if ((n
= obt_xml_find_node(node
, "hilite")))
94 o
->only_hilite_windows
= obt_xml_node_bool(n
);
95 if ((n
= obt_xml_find_node(node
, "desktop")))
96 o
->desktop_windows
= obt_xml_node_bool(n
);
97 if ((n
= obt_xml_find_node(node
, "allDesktops")))
98 o
->all_desktops
= obt_xml_node_bool(n
);
100 if ((n
= obt_xml_find_node(node
, "finalactions"))) {
103 m
= obt_xml_find_node(n
->children
, "action");
105 ObActionsAct
*action
= actions_parse(m
);
106 if (action
) o
->actions
= g_slist_append(o
->actions
, action
);
107 m
= obt_xml_find_node(m
->next
, "action");
111 o
->actions
= g_slist_prepend(o
->actions
,
112 actions_parse_string("Focus"));
113 o
->actions
= g_slist_prepend(o
->actions
,
114 actions_parse_string("Raise"));
115 o
->actions
= g_slist_prepend(o
->actions
,
116 actions_parse_string("Unshade"));
119 *input
= i_input_func
;
120 *cancel
= i_cancel_func
;
125 static gpointer
setup_forward_func(xmlNodePtr node
,
126 ObActionsIPreFunc
*pre
,
127 ObActionsIInputFunc
*input
,
128 ObActionsICancelFunc
*cancel
,
129 ObActionsIPostFunc
*post
)
131 Options
*o
= setup_func(node
, pre
, input
, cancel
, post
);
136 static gpointer
setup_backward_func(xmlNodePtr node
,
137 ObActionsIPreFunc
*pre
,
138 ObActionsIInputFunc
*input
,
139 ObActionsICancelFunc
*cancel
,
140 ObActionsIPostFunc
*post
)
142 Options
*o
= setup_func(node
, pre
, input
, cancel
, post
);
147 static void free_func(gpointer options
)
149 Options
*o
= options
;
152 actions_act_unref(o
->actions
->data
);
153 o
->actions
= g_slist_delete_link(o
->actions
, o
->actions
);
156 g_slice_free(Options
, o
);
159 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
161 Options
*o
= options
;
162 struct _ObClient
*ft
;
164 gboolean done
= FALSE
;
165 gboolean cancel
= FALSE
;
170 !o
->only_hilite_windows
,
174 (o
->interactive
? o
->bar
: FALSE
),
175 (o
->interactive
? o
->dialog_mode
: OB_FOCUS_CYCLE_POPUP_MODE_NONE
),
179 if (o
->raise
&& ft
) stacking_temp_raise(CLIENT_AS_WINDOW(ft
));
181 return o
->interactive
;
184 static gboolean
i_input_func(guint initial_state
,
190 Options
*o
= options
;
191 guint mods
, initial_mods
;
193 initial_mods
= obt_keyboard_only_modmasks(initial_state
);
194 mods
= obt_keyboard_only_modmasks(e
->xkey
.state
);
195 if (e
->type
== KeyRelease
) {
196 /* remove from the state the mask of the modifier key being
197 released, if it is a modifier key being released that is */
198 mods
&= ~obt_keyboard_keyevent_to_modmask(e
);
201 if (e
->type
== KeyPress
) {
202 KeySym sym
= obt_keyboard_keypress_to_keysym(e
);
204 /* Escape cancels no matter what */
205 if (sym
== XK_Escape
) {
207 o
->state
= e
->xkey
.state
;
211 /* There were no modifiers and they pressed enter */
212 else if ((sym
== XK_Return
|| sym
== XK_KP_Enter
) && !initial_mods
) {
214 o
->state
= e
->xkey
.state
;
218 /* They released the modifiers */
219 else if (e
->type
== KeyRelease
&& initial_mods
&& !(mods
& initial_mods
))
222 o
->state
= e
->xkey
.state
;
229 static void i_cancel_func(gpointer options
)
231 Options
*o
= options
;
236 static void i_post_func(gpointer options
)
238 Options
*o
= options
;
239 struct _ObClient
*ft
;
241 gboolean done
= TRUE
;
243 ft
= focus_cycle(o
->forward
,
245 !o
->only_hilite_windows
,
254 actions_run_acts(o
->actions
, OB_USER_ACTION_KEYBOARD_KEY
,
255 o
->state
, -1, -1, 0, OB_FRAME_CONTEXT_NONE
, ft
);