summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-20 07:38:04 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-20 07:38:04 -0400
commit14947c92aad2ff72d20fbf875957571cd8f69168 (patch)
treebba3293f642a0d60e48b11574c18b6d03990a5d5
parentMerge pull request #96 from KoffeinFlummi/gap-fix (diff)
parentchanges (diff)
downloadsway-14947c92aad2ff72d20fbf875957571cd8f69168.tar.gz
sway-14947c92aad2ff72d20fbf875957571cd8f69168.tar.zst
sway-14947c92aad2ff72d20fbf875957571cd8f69168.zip
Merge pull request #94 from taiyu-len/master
input_state.ch, and command conflicts resolved
-rw-r--r--include/focus.h4
-rw-r--r--include/input_state.h49
-rw-r--r--include/layout.h2
-rw-r--r--sway.5.txt20
-rw-r--r--sway/commands.c18
-rw-r--r--sway/focus.c74
-rw-r--r--sway/handlers.c130
-rw-r--r--sway/input_state.c68
-rw-r--r--sway/layout.c50
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
5enum movement_direction { 3enum 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
9typedef uint32_t keycode;
10
11// returns true if key has been pressed, otherwise false
12bool check_key(keycode key);
13
14// sets a key as pressed
15void press_key(keycode key);
16
17// unsets a key as pressed
18void release_key(keycode key);
19
20/* Pointer state */
21
22enum 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
30extern 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
45void start_floating(swayc_t *view);
46void 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
8extern swayc_t root_container; 9extern swayc_t root_container;
9 10
@@ -26,5 +27,6 @@ void focus_view_for(swayc_t *ancestor, swayc_t *container);
26 27
27swayc_t *get_focused_container(swayc_t *parent); 28swayc_t *get_focused_container(swayc_t *parent);
28swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); 29swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
30swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
29 31
30#endif 32#endif
diff --git a/sway.5.txt b/sway.5.txt
index 9c40558b..5bccbd12 100644
--- a/sway.5.txt
+++ b/sway.5.txt
@@ -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
79static 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
80static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { 92static 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
7bool locked_container_focus = false; 8bool locked_container_focus = false;
8bool locked_view_focus = false; 9bool locked_view_focus = false;
@@ -53,74 +54,17 @@ static void update_focus(swayc_t *c) {
53} 54}
54 55
55bool move_focus(enum movement_direction direction) { 56bool 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
126swayc_t *get_focused_container(swayc_t *parent) { 70swayc_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
18uint32_t keys_pressed[KEY_CACHE_SIZE];
19 17
20static struct wlc_origin mouse_origin; 18static struct wlc_origin mouse_origin;
21 19
22static bool m1_held = false;
23static bool dragging = false;
24static bool m2_held = false;
25static bool resizing = false;
26static bool lock_left, lock_right, lock_top, lock_bottom = false;
27
28static bool pointer_test(swayc_t *view, void *_origin) { 20static 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
93static struct wlc_geometry saved_floating;
94
95static 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
104static 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
118static bool handle_output_created(wlc_handle output) { 87static 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
407static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { 360static 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
519enum 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
527static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, 474static 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
9static keycode key_state_array[KEY_STATE_MAX_LENGTH];
10
11static 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
21bool check_key(keycode key) {
22 return find_key(key) < KEY_STATE_MAX_LENGTH;
23}
24
25void 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
36void 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
44struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}};
45
46static struct wlc_geometry saved_floating;
47
48void 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
57void 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
301swayc_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}