aboutsummaryrefslogtreecommitdiff
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 @@
#include <xkbcommon/xkbcommon.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <math.h>
#include <wlc/wlc.h>
#include <ctype.h>
@@ -338,11 +339,14 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
static wlc_handle prev_handle = 0;
mouse_origin = *origin;
bool changed_floating = false;
+ bool changed_tiling = false;
+ int min_sane_w = 100;
+ int min_sane_h = 60;
if (!active_workspace) {
return false;
}
// Do checks to determine if proper keys are being held
- swayc_t *view = get_focused_view(active_workspace);
+ swayc_t *view = container_under_pointer();
uint32_t edge = 0;
if (pointer_state.floating.drag && view) {
if (view->is_floating) {
@@ -356,8 +360,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
if (view->is_floating) {
int dx = mouse_origin.x - prev_pos.x;
int dy = mouse_origin.y - prev_pos.y;
- int min_sane_w = 100;
- int min_sane_h = 60;
// Move and resize the view based on the dx/dy and mouse position
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
}
}
}
+ }
+ } else if (pointer_state.tiling.resize && view) {
+ if (view != pointer_state.tiling.init_view) {
+ // Quit out of the resize
+ pointer_state.tiling.init_view = NULL;
+ }
+ if (!view->is_floating && view == pointer_state.tiling.init_view) {
+ // Handle layout resizes -- Find the biggest parent container then apply resizes to that
+ // and its bordering siblings
+ swayc_t *parent = view;
+ double dx = mouse_origin.x - prev_pos.x;
+ double dy = mouse_origin.y - prev_pos.y;
+ if (pointer_state.lock.top) {
+ while (parent->type != C_WORKSPACE) {
+ // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
+ // way of doing this.
+ if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
+ parent = parent->parent;
+ } else {
+ break;
+ }
+ }
+ if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
+ sway_log(L_DEBUG, "Top is locked, found biggest valid parent at: %p", parent);
+ swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
+ if (sibling) {
+ sway_log(L_DEBUG, "Found sibling at: %p", sibling);
+ if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
+ recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
+ recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
+ changed_tiling = true;
+ }
+ }
+ }
+ } else {
+ while (parent->type != C_WORKSPACE) {
+ if (fabs(parent->parent->y - view->y) <= 1) {
+ parent = parent->parent;
+ } else {
+ break;
+ }
+ }
+ if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
+ sway_log(L_DEBUG, "Bot is locked, found biggest valid parent at: %p", parent);
+ swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
+ if (sibling) {
+ sway_log(L_DEBUG, "Found sibling at: %p", sibling);
+ if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
+ recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
+ recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
+ changed_tiling = true;
+ }
+ }
+ }
+ }
+
+ parent = view;
+ if (pointer_state.lock.left) {
+ while (parent->type != C_WORKSPACE) {
+ if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
+ parent = parent->parent;
+ } else {
+ sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
+ break;
+ }
+ }
+ if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
+ sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent);
+ swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
+ if (sibling) {
+ sway_log(L_DEBUG, "Found sibling at: %p", sibling);
+ if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
+ recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
+ recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
+ changed_tiling = true;
+ }
+ }
+ }
+ } else {
+ while (parent->type != C_WORKSPACE) {
+ if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
+ parent = parent->parent;
+ } else {
+ break;
+ }
+ }
+ if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
+ sway_log(L_DEBUG, "Right is locked, found biggest valid parent at: %p", parent);
+ swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
+ if (sibling) {
+ sway_log(L_DEBUG, "Found sibling at: %p", sibling);
+ if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
+ recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
+ recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
+ changed_tiling = true;
+ }
+ }
+ }
+ }
+ arrange_windows(active_workspace, -1, -1);
}
}
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
wlc_view_set_geometry(view->handle, edge, &geometry);
return true;
}
+ if (changed_tiling) {
+ return true;
+ }
return false;
}
@@ -463,7 +568,16 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
pointer_state.r_held = true;
}
swayc_t *pointer = container_under_pointer();
- set_focused_container(pointer);
+ if (pointer) {
+ set_focused_container(pointer);
+ int midway_x = pointer->x + pointer->width/2;
+ int midway_y = pointer->y + pointer->height/2;
+ pointer_state.lock.bottom = origin->y < midway_y;
+ pointer_state.lock.top = !pointer_state.lock.bottom;
+ pointer_state.lock.right = origin->x < midway_x;
+ pointer_state.lock.left = !pointer_state.lock.right;
+ }
+
if (pointer->is_floating) {
int i;
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
}
arrange_windows(pointer->parent, -1, -1);
if (modifiers->mods & config->floating_mod) {
- int midway_x = pointer->x + pointer->width/2;
- int midway_y = pointer->y + pointer->height/2;
-
pointer_state.floating.drag = pointer_state.l_held;
pointer_state.floating.resize = pointer_state.r_held;
- pointer_state.lock.bottom = origin->y < midway_y;
- pointer_state.lock.top = !pointer_state.lock.bottom;
- pointer_state.lock.right = origin->x < midway_x;
- pointer_state.lock.left = !pointer_state.lock.right;
start_floating(pointer);
}
// Dont want pointer sent to window while dragging or resizing
return (pointer_state.floating.drag || pointer_state.floating.resize);
+ } else {
+ pointer_state.tiling.resize = pointer_state.r_held;
+ pointer_state.tiling.init_view = pointer;
}
return (pointer && pointer != focused);
} else {
@@ -499,6 +609,8 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
if (button == M_RIGHT_CLICK) {
pointer_state.r_held = false;
pointer_state.floating.resize = false;
+ pointer_state.tiling.resize = false;
+ pointer_state.tiling.init_view = NULL;
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
}
}