aboutsummaryrefslogtreecommitdiffstats
path: root/sway/old/input_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/old/input_state.c')
-rw-r--r--sway/old/input_state.c490
1 files changed, 0 insertions, 490 deletions
diff --git a/sway/old/input_state.c b/sway/old/input_state.c
deleted file mode 100644
index 04aafd37..00000000
--- a/sway/old/input_state.c
+++ /dev/null
@@ -1,490 +0,0 @@
1#include <string.h>
2#include <stdbool.h>
3#include <ctype.h>
4#include "sway/input_state.h"
5#include "sway/config.h"
6#include "log.h"
7
8#define KEY_STATE_MAX_LENGTH 64
9
10struct key_state {
11 /*
12 * Aims to store state regardless of modifiers.
13 * If you press a key, then hold shift, then release the key, we'll
14 * get two different key syms, but the same key code. This handles
15 * that scenario and makes sure we can use the right bindings.
16 */
17 uint32_t key_sym;
18 uint32_t alt_sym;
19 uint32_t key_code;
20};
21
22static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
23
24static struct key_state last_released;
25
26static uint32_t modifiers_state;
27
28void input_init(void) {
29 int i;
30 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
31 struct key_state none = { 0, 0, 0 };
32 key_state_array[i] = none;
33 }
34
35 struct key_state none = { 0, 0, 0 };
36 last_released = none;
37
38 modifiers_state = 0;
39}
40
41uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod) {
42 if ((new_state & mod) != 0) { // pressed
43 if ((modifiers_state & mod) != 0) { // already pressed
44 return MOD_STATE_UNCHANGED;
45 } else { // pressed
46 return MOD_STATE_PRESSED;
47 }
48 } else { // not pressed
49 if ((modifiers_state & mod) != 0) { // released
50 return MOD_STATE_RELEASED;
51 } else { // already released
52 return MOD_STATE_UNCHANGED;
53 }
54 }
55}
56
57void modifiers_state_update(uint32_t new_state) {
58 modifiers_state = new_state;
59}
60
61static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
62 int i;
63 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
64 if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) {
65 break;
66 }
67 if (key_sym != 0 && (key_state_array[i].key_sym == key_sym
68 || key_state_array[i].alt_sym == key_sym)) {
69 break;
70 }
71 if (update && key_state_array[i].key_code == key_code) {
72 key_state_array[i].alt_sym = key_sym;
73 break;
74 }
75 if (key_sym == 0 && key_code != 0 && key_state_array[i].key_code == key_code) {
76 break;
77 }
78 }
79 return i;
80}
81
82bool check_key(uint32_t key_sym, uint32_t key_code) {
83 return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
84}
85
86bool check_released_key(uint32_t key_sym) {
87 return (key_sym != 0
88 && (last_released.key_sym == key_sym
89 || last_released.alt_sym == key_sym));
90}
91
92void press_key(uint32_t key_sym, uint32_t key_code) {
93 if (key_code == 0) {
94 return;
95 }
96 // Check if key exists
97 if (!check_key(key_sym, key_code)) {
98 // Check that we don't exceed buffer length
99 int insert = find_key(0, 0, true);
100 if (insert < KEY_STATE_MAX_LENGTH) {
101 key_state_array[insert].key_sym = key_sym;
102 key_state_array[insert].key_code = key_code;
103 }
104 }
105}
106
107void release_key(uint32_t key_sym, uint32_t key_code) {
108 uint8_t index = find_key(key_sym, key_code, true);
109 if (index < KEY_STATE_MAX_LENGTH) {
110 last_released.key_sym = key_state_array[index].key_sym;
111 last_released.alt_sym = key_state_array[index].alt_sym;
112 last_released.key_code = key_state_array[index].key_code;
113 struct key_state none = { 0, 0, 0 };
114 key_state_array[index] = none;
115 }
116}
117
118// Pointer state and mode
119
120struct pointer_state pointer_state;
121
122static struct mode_state {
123 // initial view state
124 double x, y, w, h;
125 swayc_t *ptr;
126 // Containers used for resizing horizontally
127 struct {
128 double w;
129 swayc_t *ptr;
130 struct {
131 double w;
132 swayc_t *ptr;
133 } parent;
134 } horiz;
135 // Containers used for resizing vertically
136 struct {
137 double h;
138 swayc_t *ptr;
139 struct {
140 double h;
141 swayc_t *ptr;
142 } parent;
143 } vert;
144} initial;
145
146static struct {
147 bool left;
148 bool top;
149} lock;
150
151// initial set/unset
152
153static void set_initial_view(swayc_t *view) {
154 initial.ptr = view;
155 initial.x = view->x;
156 initial.y = view->y;
157 initial.w = view->width;
158 initial.h = view->height;
159}
160
161static void set_initial_sibling(void) {
162 bool reset = true;
163 swayc_t *ws = swayc_active_workspace_for(initial.ptr);
164 if ((initial.horiz.ptr = get_swayc_in_direction_under(initial.ptr,
165 lock.left ? MOVE_RIGHT: MOVE_LEFT, ws))) {
166 initial.horiz.w = initial.horiz.ptr->width;
167 initial.horiz.parent.ptr = get_swayc_in_direction_under(initial.horiz.ptr,
168 lock.left ? MOVE_LEFT : MOVE_RIGHT, ws);
169 initial.horiz.parent.w = initial.horiz.parent.ptr->width;
170 reset = false;
171 }
172 if ((initial.vert.ptr = get_swayc_in_direction_under(initial.ptr,
173 lock.top ? MOVE_DOWN: MOVE_UP, ws))) {
174 initial.vert.h = initial.vert.ptr->height;
175 initial.vert.parent.ptr = get_swayc_in_direction_under(initial.vert.ptr,
176 lock.top ? MOVE_UP : MOVE_DOWN, ws);
177 initial.vert.parent.h = initial.vert.parent.ptr->height;
178 reset = false;
179 }
180 // If nothing will change just undo the mode
181 if (reset) {
182 pointer_state.mode = 0;
183 }
184}
185
186static void reset_initial_view(void) {
187 initial.ptr->x = initial.x;
188 initial.ptr->y = initial.y;
189 initial.ptr->width = initial.w;
190 initial.ptr->height = initial.h;
191 arrange_windows(initial.ptr, -1, -1);
192 pointer_state.mode = 0;
193}
194
195static void reset_initial_sibling(void) {
196 initial.horiz.ptr->width = initial.horiz.w;
197 initial.horiz.parent.ptr->width = initial.horiz.parent.w;
198 initial.vert.ptr->height = initial.vert.h;
199 initial.vert.parent.ptr->height = initial.vert.parent.h;
200 arrange_windows(initial.horiz.ptr->parent, -1, -1);
201 arrange_windows(initial.vert.ptr->parent, -1, -1);
202 pointer_state.mode = 0;
203}
204
205void pointer_position_set(double new_x, double new_y, bool force_focus) {
206 double x, y;
207 wlc_pointer_get_position_v2(&x, &y);
208 pointer_state.delta.x = new_x - x;
209 pointer_state.delta.y = new_y - y;
210
211 wlc_pointer_set_position_v2(new_x, new_y);
212
213 // Update view under pointer
214 swayc_t *prev_view = pointer_state.view;
215 pointer_state.view = container_under_pointer();
216
217 // If pointer is in a mode, update it
218 if (pointer_state.mode) {
219 pointer_mode_update();
220 // Otherwise change focus if config is set
221 } else if (force_focus || (prev_view != pointer_state.view && config->focus_follows_mouse)) {
222 if (pointer_state.view && pointer_state.view->type == C_VIEW) {
223 set_focused_container(pointer_state.view);
224 }
225 }
226}
227
228void center_pointer_on(swayc_t *view) {
229 pointer_position_set(view->x + view->width/2, view->y + view->height/2, true);
230}
231
232// Mode set left/right click
233
234static void pointer_mode_set_dragging(void) {
235 switch (config->dragging_key) {
236 case M_LEFT_CLICK:
237 set_initial_view(pointer_state.left.view);
238 break;
239 case M_RIGHT_CLICK:
240 set_initial_view(pointer_state.right.view);
241 break;
242 }
243
244 if (initial.ptr->is_floating) {
245 pointer_state.mode = M_DRAGGING | M_FLOATING;
246 } else {
247 pointer_state.mode = M_DRAGGING | M_TILING;
248 // unset mode if we can't drag tile
249 if (initial.ptr->parent->type == C_WORKSPACE &&
250 initial.ptr->parent->children->length == 1) {
251 pointer_state.mode = 0;
252 }
253 }
254}
255
256static void pointer_mode_set_resizing(void) {
257 switch (config->resizing_key) {
258 case M_LEFT_CLICK:
259 set_initial_view(pointer_state.left.view);
260 break;
261 case M_RIGHT_CLICK:
262 set_initial_view(pointer_state.right.view);
263 break;
264 }
265 // Setup locking information
266 int midway_x = initial.ptr->x + initial.ptr->width/2;
267 int midway_y = initial.ptr->y + initial.ptr->height/2;
268
269 double x, y;
270 wlc_pointer_get_position_v2(&x, &y);
271 lock.left = x > midway_x;
272 lock.top = y > midway_y;
273
274 if (initial.ptr->is_floating) {
275 pointer_state.mode = M_RESIZING | M_FLOATING;
276 } else {
277 pointer_state.mode = M_RESIZING | M_TILING;
278 set_initial_sibling();
279 }
280}
281
282// Mode set/update/reset
283
284void pointer_mode_set(uint32_t button, bool condition) {
285 // switch on drag/resize mode
286 switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
287 case M_DRAGGING:
288 // end drag mode when 'dragging' click is unpressed
289 if (config->dragging_key == M_LEFT_CLICK && !pointer_state.left.held) {
290 pointer_state.mode = 0;
291 } else if (config->dragging_key == M_RIGHT_CLICK && !pointer_state.right.held) {
292 pointer_state.mode = 0;
293 }
294 break;
295
296 case M_RESIZING:
297 // end resize mode when 'resizing' click is unpressed
298 if (config->resizing_key == M_LEFT_CLICK && !pointer_state.left.held) {
299 pointer_state.mode = 0;
300 } else if (config->resizing_key == M_RIGHT_CLICK && !pointer_state.right.held) {
301 pointer_state.mode = 0;
302 }
303 break;
304
305 // No mode case
306 default:
307 // return if failed condition, or no view
308 if (!condition || !pointer_state.view) {
309 break;
310 }
311
312 // Set mode depending on current button press
313 switch (button) {
314 // Start left-click mode
315 case M_LEFT_CLICK:
316 // if button release don't do anything
317 if (pointer_state.left.held) {
318 if (config->dragging_key == M_LEFT_CLICK) {
319 pointer_mode_set_dragging();
320 } else if (config->resizing_key == M_LEFT_CLICK) {
321 pointer_mode_set_resizing();
322 }
323 }
324 break;
325
326 // Start right-click mode
327 case M_RIGHT_CLICK:
328 // if button release don't do anyhting
329 if (pointer_state.right.held) {
330 if (config->dragging_key == M_RIGHT_CLICK) {
331 pointer_mode_set_dragging();
332 } else if (config->resizing_key == M_RIGHT_CLICK) {
333 pointer_mode_set_resizing();
334 }
335 }
336 break;
337 }
338 }
339}
340
341void pointer_mode_update(void) {
342 if (initial.ptr->type != C_VIEW) {
343 pointer_state.mode = 0;
344 return;
345 }
346 double x, y;
347 wlc_pointer_get_position_v2(&x, &y);
348 int dx = x;
349 int dy = y;
350
351 switch (pointer_state.mode) {
352 case M_FLOATING | M_DRAGGING:
353 // Update position
354 switch (config->dragging_key) {
355 case M_LEFT_CLICK:
356 dx -= pointer_state.left.x;
357 dy -= pointer_state.left.y;
358 break;
359 case M_RIGHT_CLICK:
360 dx -= pointer_state.right.x;
361 dy -= pointer_state.right.y;
362 break;
363 }
364
365 if (initial.x + dx != initial.ptr->x) {
366 initial.ptr->x = initial.x + dx;
367 }
368 if (initial.y + dy != initial.ptr->y) {
369 initial.ptr->y = initial.y + dy;
370 }
371 update_geometry(initial.ptr);
372 break;
373
374 case M_FLOATING | M_RESIZING:
375 switch (config->resizing_key) {
376 case M_LEFT_CLICK:
377 dx -= pointer_state.left.x;
378 dy -= pointer_state.left.y;
379 initial.ptr = pointer_state.left.view;
380 break;
381 case M_RIGHT_CLICK:
382 dx -= pointer_state.right.x;
383 dy -= pointer_state.right.y;
384 initial.ptr = pointer_state.right.view;
385 break;
386 }
387
388 if (lock.left) {
389 if (initial.w + dx > min_sane_w) {
390 initial.ptr->width = initial.w + dx;
391 }
392 } else { // lock.right
393 if (initial.w - dx > min_sane_w) {
394 initial.ptr->width = initial.w - dx;
395 initial.ptr->x = initial.x + dx;
396 }
397 }
398 if (lock.top) {
399 if (initial.h + dy > min_sane_h) {
400 initial.ptr->height = initial.h + dy;
401 }
402 } else { // lock.bottom
403 if (initial.h - dy > min_sane_h) {
404 initial.ptr->height = initial.h - dy;
405 initial.ptr->y = initial.y + dy;
406 }
407 }
408 update_geometry(initial.ptr);
409 break;
410
411 case M_TILING | M_DRAGGING:
412 // swap current view under pointer with dragged view
413 if (pointer_state.view && pointer_state.view->type == C_VIEW
414 && pointer_state.view != initial.ptr
415 && !pointer_state.view->is_floating) {
416 // Swap them around
417 swap_container(pointer_state.view, initial.ptr);
418 swap_geometry(pointer_state.view, initial.ptr);
419 update_geometry(pointer_state.view);
420 update_geometry(initial.ptr);
421 // Set focus back to initial view
422 set_focused_container(initial.ptr);
423 // Arrange the windows
424 arrange_windows(&root_container, -1, -1);
425 }
426 break;
427
428 case M_TILING | M_RESIZING:
429 switch (config->resizing_key) {
430 case M_LEFT_CLICK:
431 dx -= pointer_state.left.x;
432 dy -= pointer_state.left.y;
433 break;
434 case M_RIGHT_CLICK:
435 dx -= pointer_state.right.x;
436 dy -= pointer_state.right.y;
437 break;
438 }
439
440 // resize if we can
441 if (initial.horiz.ptr) {
442 if (lock.left) {
443 // Check whether its fine to resize
444 if (initial.w + dx > min_sane_w && initial.horiz.w - dx > min_sane_w) {
445 initial.horiz.ptr->width = initial.horiz.w - dx;
446 initial.horiz.parent.ptr->width = initial.horiz.parent.w + dx;
447 }
448 } else { // lock.right
449 if (initial.w - dx > min_sane_w && initial.horiz.w + dx > min_sane_w) {
450 initial.horiz.ptr->width = initial.horiz.w + dx;
451 initial.horiz.parent.ptr->width = initial.horiz.parent.w - dx;
452 }
453 }
454 arrange_windows(initial.horiz.ptr->parent, -1, -1);
455 }
456 if (initial.vert.ptr) {
457 if (lock.top) {
458 if (initial.h + dy > min_sane_h && initial.vert.h - dy > min_sane_h) {
459 initial.vert.ptr->height = initial.vert.h - dy;
460 initial.vert.parent.ptr->height = initial.vert.parent.h + dy;
461 }
462 } else { // lock.bottom
463 if (initial.h - dy > min_sane_h && initial.vert.h + dy > min_sane_h) {
464 initial.vert.ptr->height = initial.vert.h + dy;
465 initial.vert.parent.ptr->height = initial.vert.parent.h - dy;
466 }
467 }
468 arrange_windows(initial.vert.ptr->parent, -1, -1);
469 }
470 default:
471 return;
472 }
473}
474
475void pointer_mode_reset(void) {
476 switch (pointer_state.mode) {
477 case M_FLOATING | M_RESIZING:
478 case M_FLOATING | M_DRAGGING:
479 reset_initial_view();
480 break;
481
482 case M_TILING | M_RESIZING:
483 (void) reset_initial_sibling;
484 break;
485
486 case M_TILING | M_DRAGGING:
487 default:
488 break;
489 }
490}