diff options
-rw-r--r-- | include/focus.h | 4 | ||||
-rw-r--r-- | include/input_state.h | 49 | ||||
-rw-r--r-- | include/layout.h | 2 | ||||
-rw-r--r-- | sway.5.txt | 20 | ||||
-rw-r--r-- | sway/commands.c | 18 | ||||
-rw-r--r-- | sway/focus.c | 74 | ||||
-rw-r--r-- | sway/handlers.c | 130 | ||||
-rw-r--r-- | sway/input_state.c | 68 | ||||
-rw-r--r-- | sway/layout.c | 50 |
9 files changed, 243 insertions, 172 deletions
diff --git a/include/focus.h b/include/focus.h index 410ed134..383993fa 100644 --- a/include/focus.h +++ b/include/focus.h | |||
@@ -1,7 +1,5 @@ | |||
1 | #ifndef _SWAY_FOCUS_H | 1 | #ifndef _SWAY_FOCUS_H |
2 | #define _SWAY_FOCUS_H | 2 | #define _SWAY_FOCUS_H |
3 | #include "container.h" | ||
4 | |||
5 | enum movement_direction { | 3 | enum movement_direction { |
6 | MOVE_LEFT, | 4 | MOVE_LEFT, |
7 | MOVE_RIGHT, | 5 | MOVE_RIGHT, |
@@ -10,6 +8,8 @@ enum movement_direction { | |||
10 | MOVE_PARENT | 8 | MOVE_PARENT |
11 | }; | 9 | }; |
12 | 10 | ||
11 | #include "container.h" | ||
12 | |||
13 | // focused_container - the container found by following the `focused` pointer | 13 | // focused_container - the container found by following the `focused` pointer |
14 | // from a given container to a container with `is_focused` boolean set | 14 | // from a given container to a container with `is_focused` boolean set |
15 | // --- | 15 | // --- |
diff --git a/include/input_state.h b/include/input_state.h new file mode 100644 index 00000000..782b4b19 --- /dev/null +++ b/include/input_state.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef _SWAY_KEY_STATE_H | ||
2 | #define _SWAY_KEY_STATE_H | ||
3 | #include <stdbool.h> | ||
4 | #include <stdint.h> | ||
5 | #include "container.h" | ||
6 | |||
7 | /* Keyboard state */ | ||
8 | |||
9 | typedef uint32_t keycode; | ||
10 | |||
11 | // returns true if key has been pressed, otherwise false | ||
12 | bool check_key(keycode key); | ||
13 | |||
14 | // sets a key as pressed | ||
15 | void press_key(keycode key); | ||
16 | |||
17 | // unsets a key as pressed | ||
18 | void release_key(keycode key); | ||
19 | |||
20 | /* Pointer state */ | ||
21 | |||
22 | enum pointer_values { | ||
23 | M_LEFT_CLICK = 272, | ||
24 | M_RIGHT_CLICK = 273, | ||
25 | M_SCROLL_CLICK = 274, | ||
26 | M_SCROLL_UP = 275, | ||
27 | M_SCROLL_DOWN = 276, | ||
28 | }; | ||
29 | |||
30 | extern struct pointer_state { | ||
31 | bool l_held; | ||
32 | bool r_held; | ||
33 | struct pointer_floating { | ||
34 | bool drag; | ||
35 | bool resize; | ||
36 | } floating; | ||
37 | struct pointer_lock { | ||
38 | bool left; | ||
39 | bool right; | ||
40 | bool top; | ||
41 | bool bottom; | ||
42 | } lock; | ||
43 | } pointer_state; | ||
44 | |||
45 | void start_floating(swayc_t *view); | ||
46 | void reset_floating(swayc_t *view); | ||
47 | |||
48 | #endif | ||
49 | |||
diff --git a/include/layout.h b/include/layout.h index 98fdb531..75e72d2f 100644 --- a/include/layout.h +++ b/include/layout.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <wlc/wlc.h> | 4 | #include <wlc/wlc.h> |
5 | #include "list.h" | 5 | #include "list.h" |
6 | #include "container.h" | 6 | #include "container.h" |
7 | #include "focus.h" | ||
7 | 8 | ||
8 | extern swayc_t root_container; | 9 | extern swayc_t root_container; |
9 | 10 | ||
@@ -26,5 +27,6 @@ void focus_view_for(swayc_t *ancestor, swayc_t *container); | |||
26 | 27 | ||
27 | swayc_t *get_focused_container(swayc_t *parent); | 28 | swayc_t *get_focused_container(swayc_t *parent); |
28 | swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); | 29 | swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); |
30 | swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); | ||
29 | 31 | ||
30 | #endif | 32 | #endif |
@@ -22,11 +22,11 @@ Commands | |||
22 | -------- | 22 | -------- |
23 | 23 | ||
24 | **bindsym** <key combo> <command>:: | 24 | **bindsym** <key combo> <command>:: |
25 | Binds _key combo_ to execute _command_ when pressed. You may use XKB key names | 25 | Binds _key combo_ to execute _command_ when pressed. You may use XKB key |
26 | here (**xev**(1) is a good tool for discovering them). An example bindsym | 26 | names here (**xev**(1) is a good tool for discovering them). An example |
27 | command would be _bindsym Mod1+Shift+f exec firefox_, which would execute | 27 | bindsym command would be _bindsym Mod1+Shift+f exec firefox_, which would |
28 | Firefox if the alt, shift, and F keys are pressed together. Any valid sway | 28 | execute Firefox if the alt, shift, and F keys are pressed together. Any |
29 | command is eligible to be bound to a key combo. | 29 | valid sway command is eligible to be bound to a key combo. |
30 | 30 | ||
31 | **exec** <shell command>:: | 31 | **exec** <shell command>:: |
32 | Executes _shell command_ with sh. | 32 | Executes _shell command_ with sh. |
@@ -41,9 +41,6 @@ Commands | |||
41 | **floating** toggle:: | 41 | **floating** toggle:: |
42 | Toggles the "floating" status of the focused view. | 42 | Toggles the "floating" status of the focused view. |
43 | 43 | ||
44 | **floating** mode_toggle:: | ||
45 | Toggles focus between floating view and tiled view. | ||
46 | |||
47 | **focus** <direction>:: | 44 | **focus** <direction>:: |
48 | Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The | 45 | Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The |
49 | directional focus commands will move the focus in that direction. The parent | 46 | directional focus commands will move the focus in that direction. The parent |
@@ -51,6 +48,9 @@ Commands | |||
51 | container, which is useful, for example, to open a sibling of the parent | 48 | container, which is useful, for example, to open a sibling of the parent |
52 | container, or to move the entire container around. | 49 | container, or to move the entire container around. |
53 | 50 | ||
51 | **focus** mode_toggle:: | ||
52 | Toggles focus between floating view and tiled view. | ||
53 | |||
54 | **focus_follows_mouse** <yes|no>:: | 54 | **focus_follows_mouse** <yes|no>:: |
55 | If set to _yes_, the currently focused view will change as you move your | 55 | If set to _yes_, the currently focused view will change as you move your |
56 | mouse around the screen to the view that ends up underneath your mouse. | 56 | mouse around the screen to the view that ends up underneath your mouse. |
@@ -86,10 +86,10 @@ Commands | |||
86 | **fullscreen**:: | 86 | **fullscreen**:: |
87 | Toggles fullscreen status for the focused view. | 87 | Toggles fullscreen status for the focused view. |
88 | 88 | ||
89 | **gaps** <amount>**:: | 89 | **gaps** <amount>:: |
90 | Adds _amount_ pixels between each view, and around each output. | 90 | Adds _amount_ pixels between each view, and around each output. |
91 | 91 | ||
92 | **gaps** <inner|outer> <amount>**:: | 92 | **gaps** <inner|outer> <amount>:: |
93 | Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects | 93 | Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects |
94 | spacing between views and the latter affects the space around each output. | 94 | spacing between views and the latter affects the space around each output. |
95 | 95 | ||
diff --git a/sway/commands.c b/sway/commands.c index f3553b03..c4cf96a2 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -76,6 +76,18 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) { | |||
76 | return false; | 76 | return false; |
77 | } | 77 | } |
78 | 78 | ||
79 | static int bindsym_sort(const void *_lbind, const void *_rbind) { | ||
80 | const struct sway_binding *lbind = *(void **)_lbind; | ||
81 | const struct sway_binding *rbind = *(void **)_rbind; | ||
82 | unsigned int lmod = 0, rmod = 0, i; | ||
83 | |||
84 | //Count how any modifiers are pressed | ||
85 | for (i = 0; i < 8 * sizeof(lbind->modifiers); ++i) { | ||
86 | lmod += lbind->modifiers & 1 << i; | ||
87 | rmod += rbind->modifiers & 1 << i; | ||
88 | } | ||
89 | return (rbind->keys->length + rmod) - (lbind->keys->length + lmod); | ||
90 | } | ||
79 | 91 | ||
80 | static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { | 92 | static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { |
81 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { | 93 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { |
@@ -118,7 +130,10 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
118 | list_free(split); | 130 | list_free(split); |
119 | 131 | ||
120 | // TODO: Check if there are other commands with this key binding | 132 | // TODO: Check if there are other commands with this key binding |
121 | list_add(config->current_mode->bindings, binding); | 133 | struct sway_mode *mode = config->current_mode; |
134 | list_add(mode->bindings, binding); | ||
135 | qsort(mode->bindings->items, mode->bindings->length, | ||
136 | sizeof(mode->bindings->items[0]), bindsym_sort); | ||
122 | 137 | ||
123 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); | 138 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); |
124 | return true; | 139 | return true; |
@@ -228,7 +243,6 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) { | |||
228 | } | 243 | } |
229 | // Refocus on the view once its been put back into the layout | 244 | // Refocus on the view once its been put back into the layout |
230 | arrange_windows(active_workspace, -1, -1); | 245 | arrange_windows(active_workspace, -1, -1); |
231 | return true; | ||
232 | } | 246 | } |
233 | set_focused_container(view); | 247 | set_focused_container(view); |
234 | } | 248 | } |
diff --git a/sway/focus.c b/sway/focus.c index f76b2d9a..a6ffe73f 100644 --- a/sway/focus.c +++ b/sway/focus.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include "focus.h" | 3 | #include "focus.h" |
4 | #include "log.h" | 4 | #include "log.h" |
5 | #include "workspace.h" | 5 | #include "workspace.h" |
6 | #include "layout.h" | ||
6 | 7 | ||
7 | bool locked_container_focus = false; | 8 | bool locked_container_focus = false; |
8 | bool locked_view_focus = false; | 9 | bool locked_view_focus = false; |
@@ -53,74 +54,17 @@ static void update_focus(swayc_t *c) { | |||
53 | } | 54 | } |
54 | 55 | ||
55 | bool move_focus(enum movement_direction direction) { | 56 | bool move_focus(enum movement_direction direction) { |
56 | if (locked_container_focus) { | 57 | swayc_t *view = get_swayc_in_direction( |
57 | return false; | 58 | get_focused_container(&root_container), direction); |
58 | } | 59 | if (view) { |
59 | swayc_t *current = get_focused_container(&root_container); | 60 | if (direction == MOVE_PARENT) { |
60 | if (current->type == C_VIEW | 61 | set_focused_container(view); |
61 | && wlc_view_get_state(current->handle) & WLC_BIT_FULLSCREEN) { | ||
62 | return false; | ||
63 | } | ||
64 | swayc_t *parent = current->parent; | ||
65 | |||
66 | if (direction == MOVE_PARENT) { | ||
67 | if (parent->type == C_OUTPUT) { | ||
68 | sway_log(L_DEBUG, "Focus cannot move to parent"); | ||
69 | return false; | ||
70 | } else { | 62 | } else { |
71 | sway_log(L_DEBUG, "Moving focus from %p:%ld to %p:%ld", | 63 | set_focused_container(get_focused_view(view)); |
72 | current, current->handle, parent, parent->handle); | ||
73 | set_focused_container(parent); | ||
74 | return true; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | while (true) { | ||
79 | sway_log(L_DEBUG, "Moving focus away from %p", current); | ||
80 | |||
81 | // Test if we can even make a difference here | ||
82 | bool can_move = false; | ||
83 | int diff = 0; | ||
84 | if (direction == MOVE_LEFT || direction == MOVE_RIGHT) { | ||
85 | if (parent->layout == L_HORIZ || parent->type == C_ROOT) { | ||
86 | can_move = true; | ||
87 | diff = direction == MOVE_LEFT ? -1 : 1; | ||
88 | } | ||
89 | } else { | ||
90 | if (parent->layout == L_VERT) { | ||
91 | can_move = true; | ||
92 | diff = direction == MOVE_UP ? -1 : 1; | ||
93 | } | ||
94 | } | ||
95 | sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no"); | ||
96 | if (can_move) { | ||
97 | int i; | ||
98 | for (i = 0; i < parent->children->length; ++i) { | ||
99 | swayc_t *child = parent->children->items[i]; | ||
100 | if (child == current) { | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | int desired = i + diff; | ||
105 | sway_log(L_DEBUG, "Moving from %d to %d", i, desired); | ||
106 | if (desired < 0 || desired >= parent->children->length) { | ||
107 | can_move = false; | ||
108 | } else { | ||
109 | swayc_t *newview = parent->children->items[desired]; | ||
110 | set_focused_container(get_focused_view(newview)); | ||
111 | return true; | ||
112 | } | ||
113 | } | ||
114 | if (!can_move) { | ||
115 | sway_log(L_DEBUG, "Can't move at current level, moving up tree"); | ||
116 | current = parent; | ||
117 | parent = parent->parent; | ||
118 | if (!parent) { | ||
119 | // Nothing we can do | ||
120 | return false; | ||
121 | } | ||
122 | } | 64 | } |
65 | return true; | ||
123 | } | 66 | } |
67 | return false; | ||
124 | } | 68 | } |
125 | 69 | ||
126 | swayc_t *get_focused_container(swayc_t *parent) { | 70 | swayc_t *get_focused_container(swayc_t *parent) { |
diff --git a/sway/handlers.c b/sway/handlers.c index 63db972e..03a32835 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -13,18 +13,10 @@ | |||
13 | #include "workspace.h" | 13 | #include "workspace.h" |
14 | #include "container.h" | 14 | #include "container.h" |
15 | #include "focus.h" | 15 | #include "focus.h" |
16 | 16 | #include "input_state.h" | |
17 | #define KEY_CACHE_SIZE 32 | ||
18 | uint32_t keys_pressed[KEY_CACHE_SIZE]; | ||
19 | 17 | ||
20 | static struct wlc_origin mouse_origin; | 18 | static struct wlc_origin mouse_origin; |
21 | 19 | ||
22 | static bool m1_held = false; | ||
23 | static bool dragging = false; | ||
24 | static bool m2_held = false; | ||
25 | static bool resizing = false; | ||
26 | static bool lock_left, lock_right, lock_top, lock_bottom = false; | ||
27 | |||
28 | static bool pointer_test(swayc_t *view, void *_origin) { | 20 | static bool pointer_test(swayc_t *view, void *_origin) { |
29 | const struct wlc_origin *origin = _origin; | 21 | const struct wlc_origin *origin = _origin; |
30 | // Determine the output that the view is under | 22 | // Determine the output that the view is under |
@@ -90,29 +82,6 @@ swayc_t *container_under_pointer(void) { | |||
90 | return lookup; | 82 | return lookup; |
91 | } | 83 | } |
92 | 84 | ||
93 | static struct wlc_geometry saved_floating; | ||
94 | |||
95 | static void start_floating(swayc_t *view) { | ||
96 | if (view->is_floating) { | ||
97 | saved_floating.origin.x = view->x; | ||
98 | saved_floating.origin.y = view->y; | ||
99 | saved_floating.size.w = view->width; | ||
100 | saved_floating.size.h = view->height; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static void reset_floating(swayc_t *view) { | ||
105 | if (view->is_floating) { | ||
106 | view->x = saved_floating.origin.x; | ||
107 | view->y = saved_floating.origin.y; | ||
108 | view->width = saved_floating.size.w; | ||
109 | view->height = saved_floating.size.h; | ||
110 | arrange_windows(view->parent, -1, -1); | ||
111 | } | ||
112 | dragging = resizing = false; | ||
113 | lock_left = lock_right = lock_top = lock_bottom = false; | ||
114 | } | ||
115 | |||
116 | /* Handles */ | 85 | /* Handles */ |
117 | 86 | ||
118 | static bool handle_output_created(wlc_handle output) { | 87 | static bool handle_output_created(wlc_handle output) { |
@@ -327,10 +296,10 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
327 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | 296 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { |
328 | return false; | 297 | return false; |
329 | } | 298 | } |
330 | bool cmd_success = false; | ||
331 | 299 | ||
332 | // Revert floating container back to original position on keypress | 300 | // Revert floating container back to original position on keypress |
333 | if (state == WLC_KEY_STATE_PRESSED && (dragging || resizing)) { | 301 | if (state == WLC_KEY_STATE_PRESSED && |
302 | (pointer_state.floating.drag || pointer_state.floating.resize)) { | ||
334 | reset_floating(get_focused_view(&root_container)); | 303 | reset_floating(get_focused_view(&root_container)); |
335 | } | 304 | } |
336 | 305 | ||
@@ -356,16 +325,10 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
356 | } | 325 | } |
357 | } | 326 | } |
358 | 327 | ||
359 | int total = 0; | 328 | if (state == WLC_KEY_STATE_PRESSED) { |
360 | for (i = 0; i < KEY_CACHE_SIZE && !mod; ++i) { | 329 | press_key(sym); |
361 | total += keys_pressed[i] != 0; | 330 | } else { // WLC_KEY_STATE_RELEASED |
362 | if (state == WLC_KEY_STATE_PRESSED && keys_pressed[i] == 0) { | 331 | release_key(sym); |
363 | keys_pressed[i] = sym; | ||
364 | break; | ||
365 | } else if (state == WLC_KEY_STATE_RELEASED && keys_pressed[i] == sym) { | ||
366 | keys_pressed[i] = 0; | ||
367 | break; | ||
368 | } | ||
369 | } | 332 | } |
370 | 333 | ||
371 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | 334 | // TODO: reminder to check conflicts with mod+q+a versus mod+q |
@@ -376,32 +339,22 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
376 | bool match; | 339 | bool match; |
377 | int j; | 340 | int j; |
378 | for (j = 0; j < binding->keys->length; ++j) { | 341 | for (j = 0; j < binding->keys->length; ++j) { |
379 | match = false; | ||
380 | xkb_keysym_t *key = binding->keys->items[j]; | 342 | xkb_keysym_t *key = binding->keys->items[j]; |
381 | int k; | 343 | if ((match = check_key(*key)) == false) { |
382 | for (k = 0; k < KEY_CACHE_SIZE; ++k) { | ||
383 | if (keys_pressed[k] == *key) { | ||
384 | match = true; | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | if (match == false) { | ||
389 | break; | 344 | break; |
390 | } | 345 | } |
391 | } | 346 | } |
392 | |||
393 | if (match) { | 347 | if (match) { |
394 | // Remove matched keys from keys_pressed | ||
395 | if (state == WLC_KEY_STATE_PRESSED) { | 348 | if (state == WLC_KEY_STATE_PRESSED) { |
396 | handle_command(config, binding->command); | 349 | handle_command(config, binding->command); |
397 | cmd_success = true; | 350 | return true; |
398 | } else if (state == WLC_KEY_STATE_RELEASED) { | 351 | } else if (state == WLC_KEY_STATE_RELEASED) { |
399 | // TODO: --released | 352 | // TODO: --released |
400 | } | 353 | } |
401 | } | 354 | } |
402 | } | 355 | } |
403 | } | 356 | } |
404 | return cmd_success; | 357 | return false; |
405 | } | 358 | } |
406 | 359 | ||
407 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { | 360 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
@@ -415,7 +368,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
415 | // Do checks to determine if proper keys are being held | 368 | // Do checks to determine if proper keys are being held |
416 | swayc_t *view = get_focused_view(active_workspace); | 369 | swayc_t *view = get_focused_view(active_workspace); |
417 | uint32_t edge = 0; | 370 | uint32_t edge = 0; |
418 | if (dragging && view) { | 371 | if (pointer_state.floating.drag && view) { |
419 | if (view->is_floating) { | 372 | if (view->is_floating) { |
420 | int dx = mouse_origin.x - prev_pos.x; | 373 | int dx = mouse_origin.x - prev_pos.x; |
421 | int dy = mouse_origin.y - prev_pos.y; | 374 | int dy = mouse_origin.y - prev_pos.y; |
@@ -423,7 +376,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
423 | view->y += dy; | 376 | view->y += dy; |
424 | changed_floating = true; | 377 | changed_floating = true; |
425 | } | 378 | } |
426 | } else if (resizing && view) { | 379 | } else if (pointer_state.floating.resize && view) { |
427 | if (view->is_floating) { | 380 | if (view->is_floating) { |
428 | int dx = mouse_origin.x - prev_pos.x; | 381 | int dx = mouse_origin.x - prev_pos.x; |
429 | int dy = mouse_origin.y - prev_pos.y; | 382 | int dy = mouse_origin.y - prev_pos.y; |
@@ -434,24 +387,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
434 | int midway_x = view->x + view->width/2; | 387 | int midway_x = view->x + view->width/2; |
435 | int midway_y = view->y + view->height/2; | 388 | int midway_y = view->y + view->height/2; |
436 | if (dx < 0) { | 389 | if (dx < 0) { |
437 | if (!lock_right) { | 390 | if (!pointer_state.lock.right) { |
438 | if (view->width > min_sane_w) { | 391 | if (view->width > min_sane_w) { |
439 | changed_floating = true; | 392 | changed_floating = true; |
440 | view->width += dx; | 393 | view->width += dx; |
441 | edge += WLC_RESIZE_EDGE_RIGHT; | 394 | edge += WLC_RESIZE_EDGE_RIGHT; |
442 | } | 395 | } |
443 | } else if (mouse_origin.x < midway_x && !lock_left) { | 396 | } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { |
444 | changed_floating = true; | 397 | changed_floating = true; |
445 | view->x += dx; | 398 | view->x += dx; |
446 | view->width -= dx; | 399 | view->width -= dx; |
447 | edge += WLC_RESIZE_EDGE_LEFT; | 400 | edge += WLC_RESIZE_EDGE_LEFT; |
448 | } | 401 | } |
449 | } else if (dx > 0) { | 402 | } else if (dx > 0) { |
450 | if (mouse_origin.x > midway_x && !lock_right) { | 403 | if (mouse_origin.x > midway_x && !pointer_state.lock.right) { |
451 | changed_floating = true; | 404 | changed_floating = true; |
452 | view->width += dx; | 405 | view->width += dx; |
453 | edge += WLC_RESIZE_EDGE_RIGHT; | 406 | edge += WLC_RESIZE_EDGE_RIGHT; |
454 | } else if (!lock_left) { | 407 | } else if (!pointer_state.lock.left) { |
455 | if (view->width > min_sane_w) { | 408 | if (view->width > min_sane_w) { |
456 | changed_floating = true; | 409 | changed_floating = true; |
457 | view->x += dx; | 410 | view->x += dx; |
@@ -462,24 +415,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
462 | } | 415 | } |
463 | 416 | ||
464 | if (dy < 0) { | 417 | if (dy < 0) { |
465 | if (!lock_bottom) { | 418 | if (!pointer_state.lock.bottom) { |
466 | if (view->height > min_sane_h) { | 419 | if (view->height > min_sane_h) { |
467 | changed_floating = true; | 420 | changed_floating = true; |
468 | view->height += dy; | 421 | view->height += dy; |
469 | edge += WLC_RESIZE_EDGE_BOTTOM; | 422 | edge += WLC_RESIZE_EDGE_BOTTOM; |
470 | } | 423 | } |
471 | } else if (mouse_origin.y < midway_y && !lock_top) { | 424 | } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { |
472 | changed_floating = true; | 425 | changed_floating = true; |
473 | view->y += dy; | 426 | view->y += dy; |
474 | view->height -= dy; | 427 | view->height -= dy; |
475 | edge += WLC_RESIZE_EDGE_TOP; | 428 | edge += WLC_RESIZE_EDGE_TOP; |
476 | } | 429 | } |
477 | } else if (dy > 0) { | 430 | } else if (dy > 0) { |
478 | if (mouse_origin.y > midway_y && !lock_bottom) { | 431 | if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { |
479 | changed_floating = true; | 432 | changed_floating = true; |
480 | view->height += dy; | 433 | view->height += dy; |
481 | edge += WLC_RESIZE_EDGE_BOTTOM; | 434 | edge += WLC_RESIZE_EDGE_BOTTOM; |
482 | } else if (!lock_top) { | 435 | } else if (!pointer_state.lock.top) { |
483 | if (view->height > min_sane_h) { | 436 | if (view->height > min_sane_h) { |
484 | changed_floating = true; | 437 | changed_floating = true; |
485 | view->y += dy; | 438 | view->y += dy; |
@@ -493,7 +446,8 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
493 | if (config->focus_follows_mouse && prev_handle != handle) { | 446 | if (config->focus_follows_mouse && prev_handle != handle) { |
494 | //Dont change focus if fullscreen | 447 | //Dont change focus if fullscreen |
495 | swayc_t *focused = get_focused_view(view); | 448 | swayc_t *focused = get_focused_view(view); |
496 | if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) && !(m1_held || m2_held)) { | 449 | if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) |
450 | && !(pointer_state.l_held || pointer_state.r_held)) { | ||
497 | set_focused_container(container_under_pointer()); | 451 | set_focused_container(container_under_pointer()); |
498 | } | 452 | } |
499 | } | 453 | } |
@@ -516,13 +470,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
516 | return false; | 470 | return false; |
517 | } | 471 | } |
518 | 472 | ||
519 | enum pointer_values { | ||
520 | M_LEFT_CLICK = 272, | ||
521 | M_RIGHT_CLICK = 273, | ||
522 | M_SCROLL_CLICK = 274, | ||
523 | M_SCROLL_UP = 275, | ||
524 | M_SCROLL_DOWN = 276, | ||
525 | }; | ||
526 | 473 | ||
527 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, | 474 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, |
528 | uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { | 475 | uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { |
@@ -534,10 +481,10 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
534 | if (state == WLC_BUTTON_STATE_PRESSED) { | 481 | if (state == WLC_BUTTON_STATE_PRESSED) { |
535 | sway_log(L_DEBUG, "Mouse button %u pressed", button); | 482 | sway_log(L_DEBUG, "Mouse button %u pressed", button); |
536 | if (button == M_LEFT_CLICK) { | 483 | if (button == M_LEFT_CLICK) { |
537 | m1_held = true; | 484 | pointer_state.l_held = true; |
538 | } | 485 | } |
539 | if (button == M_RIGHT_CLICK) { | 486 | if (button == M_RIGHT_CLICK) { |
540 | m2_held = true; | 487 | pointer_state.r_held = true; |
541 | } | 488 | } |
542 | swayc_t *pointer = container_under_pointer(); | 489 | swayc_t *pointer = container_under_pointer(); |
543 | set_focused_container(pointer); | 490 | set_focused_container(pointer); |
@@ -552,30 +499,31 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
552 | } | 499 | } |
553 | arrange_windows(pointer->parent, -1, -1); | 500 | arrange_windows(pointer->parent, -1, -1); |
554 | if (modifiers->mods & config->floating_mod) { | 501 | if (modifiers->mods & config->floating_mod) { |
555 | dragging = m1_held; | ||
556 | resizing = m2_held; | ||
557 | int midway_x = pointer->x + pointer->width/2; | 502 | int midway_x = pointer->x + pointer->width/2; |
558 | int midway_y = pointer->y + pointer->height/2; | 503 | int midway_y = pointer->y + pointer->height/2; |
559 | lock_bottom = origin->y < midway_y; | 504 | |
560 | lock_top = !lock_bottom; | 505 | pointer_state.floating.drag = pointer_state.l_held; |
561 | lock_right = origin->x < midway_x; | 506 | pointer_state.floating.resize = pointer_state.r_held; |
562 | lock_left = !lock_right; | 507 | pointer_state.lock.bottom = origin->y < midway_y; |
508 | pointer_state.lock.top = !pointer_state.lock.bottom; | ||
509 | pointer_state.lock.right = origin->x < midway_x; | ||
510 | pointer_state.lock.left = !pointer_state.lock.right; | ||
563 | start_floating(pointer); | 511 | start_floating(pointer); |
564 | } | 512 | } |
565 | //Dont want pointer sent to window while dragging or resizing | 513 | //Dont want pointer sent to window while dragging or resizing |
566 | return (dragging || resizing); | 514 | return (pointer_state.floating.drag || pointer_state.floating.resize); |
567 | } | 515 | } |
568 | return (pointer && pointer != focused); | 516 | return (pointer && pointer != focused); |
569 | } else { | 517 | } else { |
570 | sway_log(L_DEBUG, "Mouse button %u released", button); | 518 | sway_log(L_DEBUG, "Mouse button %u released", button); |
571 | if (button == M_LEFT_CLICK) { | 519 | if (button == M_LEFT_CLICK) { |
572 | m1_held = false; | 520 | pointer_state.l_held = false; |
573 | dragging = false; | 521 | pointer_state.floating.drag = false; |
574 | } | 522 | } |
575 | if (button == M_RIGHT_CLICK) { | 523 | if (button == M_RIGHT_CLICK) { |
576 | m2_held = false; | 524 | pointer_state.r_held = false; |
577 | resizing = false; | 525 | pointer_state.floating.resize = false; |
578 | lock_top = lock_bottom = lock_left = lock_right = false; | 526 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; |
579 | } | 527 | } |
580 | } | 528 | } |
581 | return false; | 529 | return false; |
@@ -590,10 +538,6 @@ static void handle_wlc_ready(void) { | |||
590 | } | 538 | } |
591 | free_flat_list(config->cmd_queue); | 539 | free_flat_list(config->cmd_queue); |
592 | config->active = true; | 540 | config->active = true; |
593 | |||
594 | for (i = 0; i < KEY_CACHE_SIZE; ++i) { | ||
595 | keys_pressed[i] = 0; | ||
596 | } | ||
597 | } | 541 | } |
598 | 542 | ||
599 | 543 | ||
diff --git a/sway/input_state.c b/sway/input_state.c new file mode 100644 index 00000000..51213b19 --- /dev/null +++ b/sway/input_state.c | |||
@@ -0,0 +1,68 @@ | |||
1 | #include <string.h> | ||
2 | #include <stdbool.h> | ||
3 | #include <ctype.h> | ||
4 | |||
5 | #include "input_state.h" | ||
6 | |||
7 | #define KEY_STATE_MAX_LENGTH 64 | ||
8 | |||
9 | static keycode key_state_array[KEY_STATE_MAX_LENGTH]; | ||
10 | |||
11 | static uint8_t find_key(keycode key) { | ||
12 | int i; | ||
13 | for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { | ||
14 | if (key_state_array[i] == key) { | ||
15 | break; | ||
16 | } | ||
17 | } | ||
18 | return i; | ||
19 | } | ||
20 | |||
21 | bool check_key(keycode key) { | ||
22 | return find_key(key) < KEY_STATE_MAX_LENGTH; | ||
23 | } | ||
24 | |||
25 | void press_key(keycode key) { | ||
26 | // Check if key exists | ||
27 | if (!check_key(key)) { | ||
28 | // Check that we dont exceed buffer length | ||
29 | int insert = find_key(0); | ||
30 | if (insert < KEY_STATE_MAX_LENGTH) { | ||
31 | key_state_array[insert] = key; | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | void release_key(keycode key) { | ||
37 | uint8_t index = find_key(key); | ||
38 | if (index < KEY_STATE_MAX_LENGTH) { | ||
39 | //shift it over and remove key | ||
40 | key_state_array[index] = 0; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}}; | ||
45 | |||
46 | static struct wlc_geometry saved_floating; | ||
47 | |||
48 | void start_floating(swayc_t *view) { | ||
49 | if (view->is_floating) { | ||
50 | saved_floating.origin.x = view->x; | ||
51 | saved_floating.origin.y = view->y; | ||
52 | saved_floating.size.w = view->width; | ||
53 | saved_floating.size.h = view->height; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | void reset_floating(swayc_t *view) { | ||
58 | if (view->is_floating) { | ||
59 | view->x = saved_floating.origin.x; | ||
60 | view->y = saved_floating.origin.y; | ||
61 | view->width = saved_floating.size.w; | ||
62 | view->height = saved_floating.size.h; | ||
63 | arrange_windows(view->parent, -1, -1); | ||
64 | } | ||
65 | pointer_state.floating = (struct pointer_floating){0,0}; | ||
66 | pointer_state.lock = (struct pointer_lock){0,0,0,0}; | ||
67 | } | ||
68 | |||
diff --git a/sway/layout.c b/sway/layout.c index e628c5ed..37db2e52 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -298,3 +298,53 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) { | |||
298 | return NULL; | 298 | return NULL; |
299 | } | 299 | } |
300 | 300 | ||
301 | swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) { | ||
302 | swayc_t *parent = container->parent; | ||
303 | |||
304 | if (dir == MOVE_PARENT) { | ||
305 | if (parent->type == C_OUTPUT) { | ||
306 | return NULL; | ||
307 | } else { | ||
308 | return parent; | ||
309 | } | ||
310 | } | ||
311 | while (true) { | ||
312 | // Test if we can even make a difference here | ||
313 | bool can_move = false; | ||
314 | int diff = 0; | ||
315 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | ||
316 | if (parent->layout == L_HORIZ || parent->type == C_ROOT) { | ||
317 | can_move = true; | ||
318 | diff = dir == MOVE_LEFT ? -1 : 1; | ||
319 | } | ||
320 | } else { | ||
321 | if (parent->layout == L_VERT) { | ||
322 | can_move = true; | ||
323 | diff = dir == MOVE_UP ? -1 : 1; | ||
324 | } | ||
325 | } | ||
326 | if (can_move) { | ||
327 | int i; | ||
328 | for (i = 0; i < parent->children->length; ++i) { | ||
329 | swayc_t *child = parent->children->items[i]; | ||
330 | if (child == container) { | ||
331 | break; | ||
332 | } | ||
333 | } | ||
334 | int desired = i + diff; | ||
335 | if (desired < 0 || desired >= parent->children->length) { | ||
336 | can_move = false; | ||
337 | } else { | ||
338 | return parent->children->items[desired]; | ||
339 | } | ||
340 | } | ||
341 | if (!can_move) { | ||
342 | container = parent; | ||
343 | parent = parent->parent; | ||
344 | if (!parent) { | ||
345 | // Nothing we can do | ||
346 | return NULL; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | } | ||