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