diff --git a/include/input_state.h b/include/input_state.h index 000996e0c..04fde42d5 100644 --- a/include/input_state.h +++ b/include/input_state.h @@ -37,13 +37,19 @@ extern struct pointer_state { struct pointer_tiling { bool resize; swayc_t *init_view; - struct wlc_origin *lock_pos; + struct wlc_origin lock_pos; } tiling; struct pointer_lock { + // Lock movement for certain edges bool left; bool right; bool top; bool bottom; + // Lock movement in certain directions + bool temp_left; + bool temp_right; + bool temp_up; + bool temp_down; } lock; } pointer_state; diff --git a/sway/handlers.c b/sway/handlers.c index 8dc409e15..07247b1ce 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -419,16 +419,42 @@ 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; + bool valid = true; + double dx = mouse_origin.x - prev_pos.x; + double dy = mouse_origin.y - prev_pos.y; + + if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) { + changed_tiling = true; + valid = false; + } else if (dx > 0 && pointer_state.lock.temp_left) { + pointer_state.lock.temp_left = false; } - if (!view->is_floating && view == pointer_state.tiling.init_view) { + + if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) { + changed_tiling = true; + valid = false; + } else if (dx < 0 && pointer_state.lock.temp_right) { + pointer_state.lock.temp_right = false; + } + + if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) { + changed_tiling = true; + valid = false; + } else if (dy > 0 && pointer_state.lock.temp_up) { + pointer_state.lock.temp_up = false; + } + + if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) { + changed_tiling = true; + valid = false; + } else if (dy < 0 && pointer_state.lock.temp_down) { + pointer_state.lock.temp_down = false; + } + + if (!view->is_floating && valid) { // 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.bottom) { while (parent->type != C_WORKSPACE) { // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better @@ -440,14 +466,19 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } 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 { + pointer_state.tiling.lock_pos.y = mouse_origin.y; + if (parent->height < min_sane_h) { + pointer_state.lock.temp_up = true; + } else if (sibling->height < min_sane_h) { + pointer_state.lock.temp_down = true; + } } } } @@ -460,14 +491,19 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } 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; + } else { + pointer_state.tiling.lock_pos.y = mouse_origin.y; + if (parent->height < min_sane_h) { + pointer_state.lock.temp_down = true; + } else if (sibling->height < min_sane_h) { + pointer_state.lock.temp_up = true; + } } } } @@ -484,14 +520,19 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } 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 { + pointer_state.tiling.lock_pos.x = mouse_origin.x; + if (parent->width < min_sane_w) { + pointer_state.lock.temp_left = true; + } else if (sibling->width < min_sane_w) { + pointer_state.lock.temp_right = true; + } } } } @@ -504,14 +545,19 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } 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; + } else { + pointer_state.tiling.lock_pos.x = mouse_origin.x; + if (parent->width < min_sane_w) { + pointer_state.lock.temp_right = true; + } else if (sibling->width < min_sane_w) { + pointer_state.lock.temp_left = true; + } } } } @@ -609,7 +655,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w 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}; + pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false}; } } return false; diff --git a/sway/input_state.c b/sway/input_state.c index 5119930ad..e2f3c7548 100644 --- a/sway/input_state.c +++ b/sway/input_state.c @@ -48,7 +48,7 @@ void release_key(keycode key) { } } -struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}}; +struct pointer_state pointer_state; static struct wlc_geometry saved_floating; @@ -69,6 +69,6 @@ void reset_floating(swayc_t *view) { view->height = saved_floating.size.h; arrange_windows(view->parent, -1, -1); } - pointer_state.floating = (struct pointer_floating){0,0}; - pointer_state.lock = (struct pointer_lock){0,0,0,0}; + pointer_state.floating = (struct pointer_floating){0, 0}; + pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; }