aboutsummaryrefslogtreecommitdiffstats
path: root/sway/handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/handlers.c')
-rw-r--r--sway/handlers.c134
1 files changed, 123 insertions, 11 deletions
diff --git a/sway/handlers.c b/sway/handlers.c
index 79628fe5..53eae439 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -1,6 +1,7 @@
1#include <xkbcommon/xkbcommon.h> 1#include <xkbcommon/xkbcommon.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <math.h>
4#include <wlc/wlc.h> 5#include <wlc/wlc.h>
5#include <ctype.h> 6#include <ctype.h>
6 7
@@ -338,11 +339,14 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
338 static wlc_handle prev_handle = 0; 339 static wlc_handle prev_handle = 0;
339 mouse_origin = *origin; 340 mouse_origin = *origin;
340 bool changed_floating = false; 341 bool changed_floating = false;
342 bool changed_tiling = false;
343 int min_sane_w = 100;
344 int min_sane_h = 60;
341 if (!active_workspace) { 345 if (!active_workspace) {
342 return false; 346 return false;
343 } 347 }
344 // Do checks to determine if proper keys are being held 348 // Do checks to determine if proper keys are being held
345 swayc_t *view = get_focused_view(active_workspace); 349 swayc_t *view = container_under_pointer();
346 uint32_t edge = 0; 350 uint32_t edge = 0;
347 if (pointer_state.floating.drag && view) { 351 if (pointer_state.floating.drag && view) {
348 if (view->is_floating) { 352 if (view->is_floating) {
@@ -356,8 +360,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
356 if (view->is_floating) { 360 if (view->is_floating) {
357 int dx = mouse_origin.x - prev_pos.x; 361 int dx = mouse_origin.x - prev_pos.x;
358 int dy = mouse_origin.y - prev_pos.y; 362 int dy = mouse_origin.y - prev_pos.y;
359 int min_sane_w = 100;
360 int min_sane_h = 60;
361 363
362 // Move and resize the view based on the dx/dy and mouse position 364 // Move and resize the view based on the dx/dy and mouse position
363 int midway_x = view->x + view->width/2; 365 int midway_x = view->x + view->width/2;
@@ -417,6 +419,106 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
417 } 419 }
418 } 420 }
419 } 421 }
422 }
423 } else if (pointer_state.tiling.resize && view) {
424 if (view != pointer_state.tiling.init_view) {
425 // Quit out of the resize
426 pointer_state.tiling.init_view = NULL;
427 }
428 if (!view->is_floating && view == pointer_state.tiling.init_view) {
429 // Handle layout resizes -- Find the biggest parent container then apply resizes to that
430 // and its bordering siblings
431 swayc_t *parent = view;
432 double dx = mouse_origin.x - prev_pos.x;
433 double dy = mouse_origin.y - prev_pos.y;
434 if (pointer_state.lock.top) {
435 while (parent->type != C_WORKSPACE) {
436 // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
437 // way of doing this.
438 if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
439 parent = parent->parent;
440 } else {
441 break;
442 }
443 }
444 if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
445 sway_log(L_DEBUG, "Top is locked, found biggest valid parent at: %p", parent);
446 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
447 if (sibling) {
448 sway_log(L_DEBUG, "Found sibling at: %p", sibling);
449 if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
450 recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
451 recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
452 changed_tiling = true;
453 }
454 }
455 }
456 } else {
457 while (parent->type != C_WORKSPACE) {
458 if (fabs(parent->parent->y - view->y) <= 1) {
459 parent = parent->parent;
460 } else {
461 break;
462 }
463 }
464 if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
465 sway_log(L_DEBUG, "Bot is locked, found biggest valid parent at: %p", parent);
466 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
467 if (sibling) {
468 sway_log(L_DEBUG, "Found sibling at: %p", sibling);
469 if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
470 recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
471 recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
472 changed_tiling = true;
473 }
474 }
475 }
476 }
477
478 parent = view;
479 if (pointer_state.lock.left) {
480 while (parent->type != C_WORKSPACE) {
481 if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
482 parent = parent->parent;
483 } else {
484 sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
485 break;
486 }
487 }
488 if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
489 sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent);
490 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
491 if (sibling) {
492 sway_log(L_DEBUG, "Found sibling at: %p", sibling);
493 if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
494 recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
495 recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
496 changed_tiling = true;
497 }
498 }
499 }
500 } else {
501 while (parent->type != C_WORKSPACE) {
502 if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
503 parent = parent->parent;
504 } else {
505 break;
506 }
507 }
508 if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
509 sway_log(L_DEBUG, "Right is locked, found biggest valid parent at: %p", parent);
510 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
511 if (sibling) {
512 sway_log(L_DEBUG, "Found sibling at: %p", sibling);
513 if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
514 recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
515 recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
516 changed_tiling = true;
517 }
518 }
519 }
520 }
521 arrange_windows(active_workspace, -1, -1);
420 } 522 }
421 } 523 }
422 if (config->focus_follows_mouse && prev_handle != handle) { 524 if (config->focus_follows_mouse && prev_handle != handle) {
@@ -443,6 +545,9 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
443 wlc_view_set_geometry(view->handle, edge, &geometry); 545 wlc_view_set_geometry(view->handle, edge, &geometry);
444 return true; 546 return true;
445 } 547 }
548 if (changed_tiling) {
549 return true;
550 }
446 return false; 551 return false;
447} 552}
448 553
@@ -463,7 +568,16 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
463 pointer_state.r_held = true; 568 pointer_state.r_held = true;
464 } 569 }
465 swayc_t *pointer = container_under_pointer(); 570 swayc_t *pointer = container_under_pointer();
466 set_focused_container(pointer); 571 if (pointer) {
572 set_focused_container(pointer);
573 int midway_x = pointer->x + pointer->width/2;
574 int midway_y = pointer->y + pointer->height/2;
575 pointer_state.lock.bottom = origin->y < midway_y;
576 pointer_state.lock.top = !pointer_state.lock.bottom;
577 pointer_state.lock.right = origin->x < midway_x;
578 pointer_state.lock.left = !pointer_state.lock.right;
579 }
580
467 if (pointer->is_floating) { 581 if (pointer->is_floating) {
468 int i; 582 int i;
469 for (i = 0; i < pointer->parent->floating->length; i++) { 583 for (i = 0; i < pointer->parent->floating->length; i++) {
@@ -475,19 +589,15 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
475 } 589 }
476 arrange_windows(pointer->parent, -1, -1); 590 arrange_windows(pointer->parent, -1, -1);
477 if (modifiers->mods & config->floating_mod) { 591 if (modifiers->mods & config->floating_mod) {
478 int midway_x = pointer->x + pointer->width/2;
479 int midway_y = pointer->y + pointer->height/2;
480
481 pointer_state.floating.drag = pointer_state.l_held; 592 pointer_state.floating.drag = pointer_state.l_held;
482 pointer_state.floating.resize = pointer_state.r_held; 593 pointer_state.floating.resize = pointer_state.r_held;
483 pointer_state.lock.bottom = origin->y < midway_y;
484 pointer_state.lock.top = !pointer_state.lock.bottom;
485 pointer_state.lock.right = origin->x < midway_x;
486 pointer_state.lock.left = !pointer_state.lock.right;
487 start_floating(pointer); 594 start_floating(pointer);
488 } 595 }
489 // Dont want pointer sent to window while dragging or resizing 596 // Dont want pointer sent to window while dragging or resizing
490 return (pointer_state.floating.drag || pointer_state.floating.resize); 597 return (pointer_state.floating.drag || pointer_state.floating.resize);
598 } else {
599 pointer_state.tiling.resize = pointer_state.r_held;
600 pointer_state.tiling.init_view = pointer;
491 } 601 }
492 return (pointer && pointer != focused); 602 return (pointer && pointer != focused);
493 } else { 603 } else {
@@ -499,6 +609,8 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
499 if (button == M_RIGHT_CLICK) { 609 if (button == M_RIGHT_CLICK) {
500 pointer_state.r_held = false; 610 pointer_state.r_held = false;
501 pointer_state.floating.resize = false; 611 pointer_state.floating.resize = false;
612 pointer_state.tiling.resize = false;
613 pointer_state.tiling.init_view = NULL;
502 pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; 614 pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
503 } 615 }
504 } 616 }