diff options
Diffstat (limited to 'sway/input_state.c')
-rw-r--r-- | sway/input_state.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/sway/input_state.c b/sway/input_state.c index e2f3c754..3db78167 100644 --- a/sway/input_state.c +++ b/sway/input_state.c @@ -50,6 +50,224 @@ void release_key(keycode key) { struct pointer_state pointer_state; +// Pointer mode values +static struct mode_state { + // Initial view state + struct { + double x, y, w, h; + swayc_t *ptr; + } view; + // Initial pointer state + struct { + int x, y; + } coor; +} initial; + +static struct { + enum { LEFT=1, RIGHT=0 } lr; + enum { TOP=1, BOTTOM=0 } tb; +} lock; + +// Floating set/unset + +static void pointer_mode_set_floating(void) { + initial.view.x = initial.view.ptr->x; + initial.view.y = initial.view.ptr->y; + initial.view.w = initial.view.ptr->width; + initial.view.h = initial.view.ptr->height; + // setup initial cooridinates + initial.coor.x = pointer_state.origin.x; + initial.coor.y = pointer_state.origin.y; +} + +static void pointer_mode_reset_floating(void) { + initial.view.ptr->x = initial.view.x; + initial.view.ptr->y = initial.view.y; + initial.view.ptr->width = initial.view.w; + initial.view.ptr->height = initial.view.h; + arrange_windows(initial.view.ptr, -1, -1); + pointer_state.mode = 0; +} + +// Mode set left/right click + +static void pointer_mode_set_left(void) { + swayc_t *view = pointer_state.view; + initial.view.ptr = view; + if (view->is_floating) { + pointer_state.mode = M_DRAGGING | M_FLOATING; + pointer_mode_set_floating(); + } else { + pointer_state.mode = M_DRAGGING | M_TILING; + } +} + +static void pointer_mode_set_right(void) { + swayc_t *view = pointer_state.view; + initial.view.ptr = view; + // Setup locking information + int midway_x = view->x + view->width/2; + int midway_y = view->y + view->height/2; + + lock.lr = pointer_state.origin.x > midway_x; + lock.tb = pointer_state.origin.y > midway_y; + + if (view->is_floating) { + pointer_state.mode = M_RESIZING | M_FLOATING; + pointer_mode_set_floating(); + } else { + pointer_state.mode = M_RESIZING | M_TILING; + } +} + +// Mode set/update/reset + +void pointer_mode_set(uint32_t button, bool condition) { + // switch on drag/resize mode + switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { + case M_DRAGGING: + // end drag mode when left click is unpressed + if (!pointer_state.l_held) { + pointer_state.mode = 0; + } + break; + + case M_RESIZING: + // end resize mode when right click is unpressed + if (!pointer_state.r_held) { + pointer_state.mode = 0; + } + break; + + // No mode case + default: + // return if failed condition, or no view + if (!condition || !pointer_state.view) { + break; + } + // Set mode depending on current button press + switch (button) { + // Start dragging mode + case M_LEFT_CLICK: + // if button release dont do anything + if (pointer_state.l_held) { + pointer_mode_set_left(); + } + break; + + // Start resize mode + case M_RIGHT_CLICK: + // if button release dont do anyhting + if (pointer_state.r_held) { + pointer_mode_set_right(); + } + break; + + case M_SCROLL_UP: + case M_SCROLL_DOWN: + //TODO add scrolling behavior here + ; + } + } +} + +void pointer_mode_update(void) { + swayc_t *view = initial.view.ptr; + if (view->type != C_VIEW) { + pointer_state.mode = 0; + return; + } + int dx = pointer_state.origin.x - initial.coor.x; + int dy = pointer_state.origin.y - initial.coor.y; + bool changed = false; + + switch (pointer_state.mode) { + case M_FLOATING | M_DRAGGING: + // Update position + if (initial.view.x + dx != view->x) { + view->x = initial.view.x + dx; + changed = true; + } + if (initial.view.y + dy != view->y) { + view->y = initial.view.y + dy; + changed = true; + } + break; + + case M_FLOATING | M_RESIZING: + if (lock.lr) { + if (initial.view.w + dx > min_sane_w) { + if (initial.view.w + dx != view->width) { + view->width = initial.view.w + dx; + changed = true; + } + } + } else { //lock.right + if (initial.view.w - dx > min_sane_w) { + if (initial.view.w - dx != view->width) { + view->width = initial.view.w - dx; + view->x = initial.view.x + dx; + changed = true; + } + } + } + if (lock.tb) { + if (initial.view.h + dy > min_sane_h) { + if (initial.view.y - dy != view->height) { + view->height = initial.view.h + dy; + changed = true; + } + } + } else { //lock.bottom + if (initial.view.h - dy > min_sane_h) { + if (initial.view.h - dy != view->height) { + view->height = initial.view.h - dy; + view->y = initial.view.y + dy; + changed = true; + } + } + } + break; + + case M_TILING | M_DRAGGING: + // swap current view under pointer with dragged view + if (pointer_state.view && pointer_state.view != initial.view.ptr) { + // Swap them around + swap_container(pointer_state.view, initial.view.ptr); + update_geometry(pointer_state.view); + update_geometry(initial.view.ptr); + // Set focus back to initial view + set_focused_container(initial.view.ptr); + } + break; + + case M_TILING | M_RESIZING: + + + + default: + return; + } + if (changed) { + update_geometry(view); + } +} + +void pointer_mode_reset(void) { + switch (pointer_state.mode) { + case M_FLOATING | M_DRAGGING: + case M_FLOATING | M_RESIZING: + pointer_mode_reset_floating(); + break; + + case M_TILING | M_DRAGGING: + case M_TILING | M_RESIZING: + default: + return; + } +} + + static struct wlc_geometry saved_floating; void start_floating(swayc_t *view) { @@ -72,3 +290,4 @@ void reset_floating(swayc_t *view) { pointer_state.floating = (struct pointer_floating){0, 0}; pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; } + |