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
;
19 ObFocusCyclePopupMode dialog_mode
;
23 /* options for after we're done */
24 gboolean cancel
; /* did the user cancel or not */
25 guint state
; /* keyboard state when finished */
28 static gpointer
setup_func(xmlNodePtr node
,
29 ObActionsIPreFunc
*pre
,
30 ObActionsIInputFunc
*in
,
31 ObActionsICancelFunc
*c
,
32 ObActionsIPostFunc
*post
);
33 static gpointer
setup_forward_func(xmlNodePtr node
,
34 ObActionsIPreFunc
*pre
,
35 ObActionsIInputFunc
*in
,
36 ObActionsICancelFunc
*c
,
37 ObActionsIPostFunc
*post
);
38 static gpointer
setup_backward_func(xmlNodePtr node
,
39 ObActionsIPreFunc
*pre
,
40 ObActionsIInputFunc
*in
,
41 ObActionsICancelFunc
*c
,
42 ObActionsIPostFunc
*post
);
43 static void free_func(gpointer options
);
44 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
45 static gboolean
i_input_func(guint initial_state
,
50 static void i_cancel_func(gpointer options
);
51 static void i_post_func(gpointer options
);
53 void action_cyclewindows_startup(void)
55 actions_register_i("NextWindow", setup_forward_func
, free_func
, run_func
);
56 actions_register_i("PreviousWindow", setup_backward_func
, free_func
,
60 static gpointer
setup_func(xmlNodePtr node
,
61 ObActionsIPreFunc
*pre
,
62 ObActionsIInputFunc
*input
,
63 ObActionsICancelFunc
*cancel
,
64 ObActionsIPostFunc
*post
)
69 o
= g_slice_new0(Options
);
71 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_LIST
;
73 if ((n
= obt_xml_find_node(node
, "linear")))
74 o
->linear
= obt_xml_node_bool(n
);
75 if ((n
= obt_xml_find_node(node
, "dialog"))) {
76 if (obt_xml_node_contains(n
, "none"))
77 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_NONE
;
78 else if (obt_xml_node_contains(n
, "no"))
79 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_NONE
;
80 else if (obt_xml_node_contains(n
, "icons"))
81 o
->dialog_mode
= OB_FOCUS_CYCLE_POPUP_MODE_ICONS
;
83 if ((n
= obt_xml_find_node(node
, "bar")))
84 o
->bar
= obt_xml_node_bool(n
);
85 if ((n
= obt_xml_find_node(node
, "raise")))
86 o
->raise
= obt_xml_node_bool(n
);
87 if ((n
= obt_xml_find_node(node
, "panels")))
88 o
->dock_windows
= obt_xml_node_bool(n
);
89 if ((n
= obt_xml_find_node(node
, "hilite")))
90 o
->only_hilite_windows
= obt_xml_node_bool(n
);
91 if ((n
= obt_xml_find_node(node
, "desktop")))
92 o
->desktop_windows
= obt_xml_node_bool(n
);
93 if ((n
= obt_xml_find_node(node
, "allDesktops")))
94 o
->all_desktops
= obt_xml_node_bool(n
);
96 if ((n
= obt_xml_find_node(node
, "finalactions"))) {
99 m
= obt_xml_find_node(n
->children
, "action");
101 ObActionsAct
*action
= actions_parse(m
);
102 if (action
) o
->actions
= g_slist_append(o
->actions
, action
);
103 m
= obt_xml_find_node(m
->next
, "action");
107 o
->actions
= g_slist_prepend(o
->actions
,
108 actions_parse_string("Focus"));
109 o
->actions
= g_slist_prepend(o
->actions
,
110 actions_parse_string("Raise"));
111 o
->actions
= g_slist_prepend(o
->actions
,
112 actions_parse_string("Unshade"));
115 *input
= i_input_func
;
116 *cancel
= i_cancel_func
;
121 static gpointer
setup_forward_func(xmlNodePtr node
,
122 ObActionsIPreFunc
*pre
,
123 ObActionsIInputFunc
*input
,
124 ObActionsICancelFunc
*cancel
,
125 ObActionsIPostFunc
*post
)
127 Options
*o
= setup_func(node
, pre
, input
, cancel
, post
);
132 static gpointer
setup_backward_func(xmlNodePtr node
,
133 ObActionsIPreFunc
*pre
,
134 ObActionsIInputFunc
*input
,
135 ObActionsICancelFunc
*cancel
,
136 ObActionsIPostFunc
*post
)
138 Options
*o
= setup_func(node
, pre
, input
, cancel
, post
);
143 static void free_func(gpointer options
)
145 Options
*o
= options
;
148 actions_act_unref(o
->actions
->data
);
149 o
->actions
= g_slist_delete_link(o
->actions
, o
->actions
);
152 g_slice_free(Options
, o
);
155 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
157 Options
*o
= options
;
158 struct _ObClient
*ft
;
160 ft
= focus_cycle(o
->forward
,
162 !o
->only_hilite_windows
,
172 if (o
->raise
&& ft
) stacking_temp_raise(CLIENT_AS_WINDOW(ft
));
177 static gboolean
i_input_func(guint initial_state
,
183 Options
*o
= options
;
184 guint mods
, initial_mods
;
186 initial_mods
= obt_keyboard_only_modmasks(initial_state
);
187 mods
= obt_keyboard_only_modmasks(e
->xkey
.state
);
188 if (e
->type
== KeyRelease
) {
189 /* remove from the state the mask of the modifier key being
190 released, if it is a modifier key being released that is */
191 mods
&= ~obt_keyboard_keyevent_to_modmask(e
);
194 if (e
->type
== KeyPress
) {
195 KeySym sym
= obt_keyboard_keypress_to_keysym(e
);
197 /* Escape cancels no matter what */
198 if (sym
== XK_Escape
) {
200 o
->state
= e
->xkey
.state
;
204 /* There were no modifiers and they pressed enter */
205 else if ((sym
== XK_Return
|| sym
== XK_KP_Enter
) && !initial_mods
) {
207 o
->state
= e
->xkey
.state
;
211 /* They released the modifiers */
212 else if (e
->type
== KeyRelease
&& initial_mods
&& !(mods
& initial_mods
))
215 o
->state
= e
->xkey
.state
;
222 static void i_cancel_func(gpointer options
)
224 Options
*o
= options
;
229 static void i_post_func(gpointer options
)
231 Options
*o
= options
;
232 struct _ObClient
*ft
;
234 ft
= focus_cycle(o
->forward
,
236 !o
->only_hilite_windows
,
246 actions_run_acts(o
->actions
, OB_USER_ACTION_KEYBOARD_KEY
,
247 o
->state
, -1, -1, 0, OB_FRAME_CONTEXT_NONE
, ft
);