]> Dogcows Code - chaz/openbox/blob - openbox/actions/cyclewindows.c
Merge branch 'backport' into work
[chaz/openbox] / openbox / actions / cyclewindows.c
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"
7 #include "gettext.h"
8
9 typedef struct {
10 gboolean linear;
11 gboolean dialog;
12 gboolean dock_windows;
13 gboolean desktop_windows;
14 gboolean all_desktops;
15 gboolean forward;
16 gboolean bar;
17 gboolean raise;
18 GSList *actions;
19 } Options;
20
21 static gboolean cycling = FALSE;
22
23 static gpointer setup_func(xmlNodePtr node);
24 static gpointer setup_forward_func(xmlNodePtr node);
25 static gpointer setup_backward_func(xmlNodePtr node);
26 static void free_func(gpointer options);
27 static gboolean run_func(ObActionsData *data, gpointer options);
28 static gboolean i_input_func(guint initial_state,
29 XEvent *e,
30 gpointer options,
31 gboolean *used);
32 static void i_cancel_func(gpointer options);
33
34 static void end_cycle(gboolean cancel, guint state, Options *o);
35
36 void action_cyclewindows_startup(void)
37 {
38 actions_register("NextWindow", setup_forward_func, free_func,
39 run_func, i_input_func, i_cancel_func);
40 actions_register("PreviousWindow", setup_backward_func, free_func,
41 run_func, i_input_func, i_cancel_func);
42 }
43
44 static gpointer setup_func(xmlNodePtr node)
45 {
46 xmlNodePtr n;
47 Options *o;
48
49 o = g_new0(Options, 1);
50 o->dialog = TRUE;
51 o->bar = TRUE;
52
53 if ((n = obt_parse_find_node(node, "linear")))
54 o->linear = obt_parse_node_bool(n);
55 if ((n = obt_parse_find_node(node, "dialog")))
56 o->dialog = obt_parse_node_bool(n);
57 if ((n = obt_parse_find_node(node, "bar")))
58 o->bar = obt_parse_node_bool(n);
59 if ((n = obt_parse_find_node(node, "raise")))
60 o->raise = obt_parse_node_bool(n);
61 if ((n = obt_parse_find_node(node, "panels")))
62 o->dock_windows = obt_parse_node_bool(n);
63 if ((n = obt_parse_find_node(node, "desktop")))
64 o->desktop_windows = obt_parse_node_bool(n);
65 if ((n = obt_parse_find_node(node, "allDesktops")))
66 o->all_desktops = obt_parse_node_bool(n);
67
68 if ((n = obt_parse_find_node(node, "finalactions"))) {
69 xmlNodePtr m;
70
71 m = obt_parse_find_node(n->children, "action");
72 while (m) {
73 ObActionsAct *action = actions_parse(m);
74 if (action) o->actions = g_slist_prepend(o->actions, action);
75 m = obt_parse_find_node(m->next, "action");
76 }
77 }
78 else {
79 o->actions = g_slist_prepend(o->actions,
80 actions_parse_string("Focus"));
81 o->actions = g_slist_prepend(o->actions,
82 actions_parse_string("Raise"));
83 o->actions = g_slist_prepend(o->actions,
84 actions_parse_string("Unshade"));
85 }
86
87 return o;
88 }
89
90 static gpointer setup_forward_func(xmlNodePtr node)
91 {
92 Options *o = setup_func(node);
93 o->forward = TRUE;
94 return o;
95 }
96
97 static gpointer setup_backward_func(xmlNodePtr node)
98 {
99 Options *o = setup_func(node);
100 o->forward = FALSE;
101 return o;
102 }
103
104 static void free_func(gpointer options)
105 {
106 Options *o = options;
107
108 while (o->actions) {
109 actions_act_unref(o->actions->data);
110 o->actions = g_slist_delete_link(o->actions, o->actions);
111 }
112
113 g_free(o);
114 }
115
116 static gboolean run_func(ObActionsData *data, gpointer options)
117 {
118 Options *o = options;
119 struct _ObClient *ft;
120
121 ft = focus_cycle(o->forward,
122 o->all_desktops,
123 o->dock_windows,
124 o->desktop_windows,
125 o->linear,
126 TRUE,
127 o->bar,
128 o->dialog,
129 FALSE, FALSE);
130 cycling = TRUE;
131
132 stacking_restore();
133 if (o->raise && ft) stacking_temp_raise(CLIENT_AS_WINDOW(ft));
134
135 return TRUE;
136 }
137
138 static gboolean i_input_func(guint initial_state,
139 XEvent *e,
140 gpointer options,
141 gboolean *used)
142 {
143 if (e->type == KeyPress) {
144 /* Escape cancels no matter what */
145 if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
146 end_cycle(TRUE, e->xkey.state, options);
147 return FALSE;
148 }
149
150 /* There were no modifiers and they pressed enter */
151 else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
152 !initial_state)
153 {
154 end_cycle(FALSE, e->xkey.state, options);
155 return FALSE;
156 }
157 }
158 /* They released the modifiers */
159 else if (e->type == KeyRelease && initial_state &&
160 (e->xkey.state & initial_state) == 0)
161 {
162 end_cycle(FALSE, e->xkey.state, options);
163 return FALSE;
164 }
165
166 return TRUE;
167 }
168
169 static void i_cancel_func(gpointer options)
170 {
171 /* we get cancelled when we move focus, but we're not cycling anymore, so
172 just ignore that */
173 if (cycling)
174 end_cycle(TRUE, 0, options);
175 }
176
177 static void end_cycle(gboolean cancel, guint state, Options *o)
178 {
179 struct _ObClient *ft;
180
181 ft = focus_cycle(o->forward,
182 o->all_desktops,
183 o->dock_windows,
184 o->desktop_windows,
185 o->linear,
186 TRUE,
187 o->bar,
188 o->dialog,
189 TRUE, cancel);
190 cycling = FALSE;
191
192 if (ft)
193 actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY,
194 state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft);
195
196 stacking_restore();
197 }
This page took 0.043958 seconds and 5 git commands to generate.