diff options
Diffstat (limited to 'sway/handlers.c')
-rw-r--r-- | sway/handlers.c | 134 |
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 | } |