1 #include "openbox/action.h"
2 #include "openbox/action_list.h"
3 #include "openbox/action_parser.h"
4 #include "openbox/action_value.h"
5 #include "openbox/stacking.h"
6 #include "openbox/window.h"
7 #include "openbox/event.h"
8 #include "openbox/focus_cycle.h"
9 #include "openbox/openbox.h"
11 #include "obt/keyboard.h"
15 gboolean dock_windows;
16 gboolean desktop_windows;
17 gboolean only_hilite_windows;
18 gboolean all_desktops;
22 ObFocusCyclePopupMode dialog_mode;
23 ObActionList *actions;
26 /* options for after we're done */
27 gboolean cancel; /* did the user cancel or not */
28 guint state; /* keyboard state when finished */
31 static gpointer setup_func(GHashTable *config,
32 ObActionIPreFunc *pre,
33 ObActionIInputFunc *in,
34 ObActionICancelFunc *c,
35 ObActionIPostFunc *post);
36 static gpointer setup_forward_func(GHashTable *config,
37 ObActionIPreFunc *pre,
38 ObActionIInputFunc *in,
39 ObActionICancelFunc *c,
40 ObActionIPostFunc *post);
41 static gpointer setup_backward_func(GHashTable *config,
42 ObActionIPreFunc *pre,
43 ObActionIInputFunc *in,
44 ObActionICancelFunc *c,
45 ObActionIPostFunc *post);
46 static void free_func(gpointer options);
47 static gboolean run_func(ObActionData *data, gpointer options);
48 static gboolean i_input_func(guint initial_state,
53 static void i_cancel_func(gpointer options);
54 static void i_post_func(gpointer options);
56 void action_cyclewindows_startup(void)
58 action_register_i("NextWindow", setup_forward_func, free_func, run_func);
59 action_register_i("PreviousWindow", setup_backward_func, free_func,
63 static gpointer setup_func(GHashTable *config,
64 ObActionIPreFunc *pre,
65 ObActionIInputFunc *input,
66 ObActionICancelFunc *cancel,
67 ObActionIPostFunc *post)
72 o = g_slice_new0(Options);
74 o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_LIST;
76 v = g_hash_table_lookup(config, "linear");
77 if (v && action_value_is_string(v))
78 o->linear = action_value_bool(v);
79 v = g_hash_table_lookup(config, "dialog");
80 if (v && action_value_is_string(v)) {
81 const gchar *s = action_value_string(v);
82 if (g_strcasecmp(s, "none") == 0)
83 o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
84 else if (g_strcasecmp(s, "no") == 0)
85 o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
86 else if (g_strcasecmp(s, "icons") == 0)
87 o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_ICONS;
89 v = g_hash_table_lookup(config, "bar");
90 if (v && action_value_is_string(v))
91 o->bar = action_value_bool(v);
92 v = g_hash_table_lookup(config, "raise");
93 if (v && action_value_is_string(v))
94 o->raise = action_value_bool(v);
95 v = g_hash_table_lookup(config, "panels");
96 if (v && action_value_is_string(v))
97 o->dock_windows = action_value_bool(v);
98 v = g_hash_table_lookup(config, "hilite");
99 if (v && action_value_is_string(v))
100 o->only_hilite_windows = action_value_bool(v);
101 v = g_hash_table_lookup(config, "desktop");
102 if (v && action_value_is_string(v))
103 o->desktop_windows = action_value_bool(v);
104 v = g_hash_table_lookup(config, "allDesktops");
105 if (v && action_value_is_string(v))
106 o->all_desktops = action_value_bool(v);
108 v = g_hash_table_lookup(config, "finalactions");
109 if (v && action_value_is_action_list(v)) {
110 o->actions = action_value_action_list(v);
111 action_list_ref(o->actions);
114 ObActionParser *p = action_parser_new();
115 o->actions = action_parser_read_string(p,
119 action_parser_unref(p);
122 *input = i_input_func;
123 *cancel = i_cancel_func;
128 static gpointer setup_forward_func(GHashTable *config,
129 ObActionIPreFunc *pre,
130 ObActionIInputFunc *input,
131 ObActionICancelFunc *cancel,
132 ObActionIPostFunc *post)
134 Options *o = setup_func(config, pre, input, cancel, post);
139 static gpointer setup_backward_func(GHashTable *config,
140 ObActionIPreFunc *pre,
141 ObActionIInputFunc *input,
142 ObActionICancelFunc *cancel,
143 ObActionIPostFunc *post)
145 Options *o = setup_func(config, pre, input, cancel, post);
150 static void free_func(gpointer options)
152 Options *o = options;
154 action_list_unref(o->actions);
155 g_slice_free(Options, o);
158 static gboolean run_func(ObActionData *data, gpointer options)
160 Options *o = options;
161 struct _ObClient *ft;
163 ft = focus_cycle(o->forward,
165 !o->only_hilite_windows,
175 if (o->raise && ft) stacking_temp_raise(CLIENT_AS_WINDOW(ft));
180 static gboolean i_input_func(guint initial_state,
186 Options *o = options;
187 guint mods, initial_mods;
189 initial_mods = obt_keyboard_only_modmasks(initial_state);
190 mods = obt_keyboard_only_modmasks(e->xkey.state);
191 if (e->type == KeyRelease) {
192 /* remove from the state the mask of the modifier key being
193 released, if it is a modifier key being released that is */
194 mods &= ~obt_keyboard_keyevent_to_modmask(e);
197 if (e->type == KeyPress) {
198 KeySym sym = obt_keyboard_keypress_to_keysym(e);
200 /* Escape cancels no matter what */
201 if (sym == XK_Escape) {
203 o->state = e->xkey.state;
207 /* There were no modifiers and they pressed enter */
208 else if ((sym == XK_Return || sym == XK_KP_Enter) && !initial_mods) {
210 o->state = e->xkey.state;
214 /* They released the modifiers */
215 else if (e->type == KeyRelease && initial_mods && !(mods & initial_mods))
218 o->state = e->xkey.state;
225 static void i_cancel_func(gpointer options)
227 Options *o = options;
232 static void i_post_func(gpointer options)
234 Options *o = options;
235 struct _ObClient *ft;
237 ft = focus_cycle(o->forward,
239 !o->only_hilite_windows,
249 action_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY,
250 o->state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft);