]> Dogcows Code - chaz/openbox/blob - openbox/actions/cyclewindows.c
make cyclewindows action into nextwindow and previouswindow again
[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()
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 /* if using focus_delay, stop the timer now so that focus doesn't go moving
116 on us */
117 event_halt_focus_delay();
118
119 focus_cycle(o->forward,
120 o->all_desktops,
121 o->dock_windows,
122 o->desktop_windows,
123 o->linear,
124 TRUE,
125 o->dialog,
126 FALSE, FALSE);
127 cycling = TRUE;
128
129 return TRUE;
130 }
131
132 static gboolean i_input_func(guint initial_state,
133 XEvent *e,
134 gpointer options,
135 gboolean *used)
136 {
137 if (e->type == KeyPress) {
138 /* Escape cancels no matter what */
139 if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
140 end_cycle(TRUE, e->xkey.state, options);
141 return FALSE;
142 }
143
144 /* There were no modifiers and they pressed enter */
145 else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
146 !initial_state)
147 {
148 end_cycle(FALSE, e->xkey.state, options);
149 return FALSE;
150 }
151 }
152 /* They released the modifiers */
153 else if (e->type == KeyRelease && initial_state &&
154 (e->xkey.state & initial_state) == 0)
155 {
156 end_cycle(FALSE, e->xkey.state, options);
157 return FALSE;
158 }
159
160 return TRUE;
161 }
162
163 static void i_cancel_func(gpointer options)
164 {
165 /* we get cancelled when we move focus, but we're not cycling anymore, so
166 just ignore that */
167 if (cycling)
168 end_cycle(TRUE, 0, options);
169 }
170
171 static void end_cycle(gboolean cancel, guint state, Options *o)
172 {
173 struct _ObClient *ft;
174
175 ft = focus_cycle(o->forward,
176 o->all_desktops,
177 o->dock_windows,
178 o->desktop_windows,
179 o->linear,
180 TRUE,
181 o->dialog,
182 TRUE, cancel);
183
184 if (ft) {
185 actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY,
186 state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft);
187 }
188 cycling = FALSE;
189 }
This page took 0.042237 seconds and 5 git commands to generate.