summaryrefslogtreecommitdiffstats
path: root/sway
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 /sway
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
Diffstat (limited to 'sway')
-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
5 files changed, 180 insertions, 160 deletions
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}