From 7503be79f36a8383cc4140f123d0046f470ffb31 Mon Sep 17 00:00:00 2001 From: Arthur Grillo Date: Sun, 29 Oct 2023 18:20:24 -0300 Subject: [PATCH] Add a no-drag option Clicking and dragging to create a selection could be bit cumbersome when using a touch-pad. Add an option to switch to a mode that you click to start a selection, and click again to end it. Fixes: #76 --- include/slurp.h | 4 ++++ main.c | 55 ++++++++++++++++++++++++++++++++++++++++++++----- slurp.1.scd | 4 ++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/slurp.h b/include/slurp.h index 5fe2ced..f14fa67 100644 --- a/include/slurp.h +++ b/include/slurp.h @@ -30,6 +30,9 @@ struct slurp_selection { struct slurp_state { bool running; bool edit_anchor; + bool is_selecting; + bool just_pressed; + struct wl_display *display; struct wl_registry *registry; @@ -59,6 +62,7 @@ struct slurp_state { struct wl_list boxes; // slurp_box::link bool fixed_aspect_ratio; double aspect_ratio; // h / w + bool no_drag; struct slurp_box result; }; diff --git a/main.c b/main.c index f772541..2776729 100644 --- a/main.c +++ b/main.c @@ -172,6 +172,11 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, output->cursor_image->hotspot_y / output->scale); wl_surface_commit(seat->cursor_surface); } + + if (seat->state->no_drag) { + seat->state->just_pressed = false; + seat->state->is_selecting = false; + } } static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, @@ -185,6 +190,7 @@ static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct slurp_seat *seat = data; + struct slurp_state *state = seat->state; // the places the cursor moved away from are also dirty if (seat->pointer_selection.has_selection) { seat_set_outputs_dirty(seat); @@ -194,13 +200,30 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, switch (seat->button_state) { case WL_POINTER_BUTTON_STATE_RELEASED: - seat_update_selection(seat); + if (state->no_drag) { + state->just_pressed = false; + } else { + state->is_selecting = false; + } break; case WL_POINTER_BUTTON_STATE_PRESSED:; - handle_active_selection_motion(seat, &seat->pointer_selection); + if (state->no_drag) { + if (!state->just_pressed) { + state->is_selecting = !state->is_selecting; + state->just_pressed = true; + } + } else { + state->is_selecting = true; + } break; } + if (state->is_selecting) { + handle_active_selection_motion(seat, &seat->pointer_selection); + } else { + seat_update_selection(seat); + } + if (seat->pointer_selection.has_selection) { seat_set_outputs_dirty(seat); } @@ -242,6 +265,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) { struct slurp_seat *seat = data; + struct slurp_state *state = seat->state; if (seat->touch_selection.has_selection) { return; } @@ -250,12 +274,29 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, switch (button_state) { case WL_POINTER_BUTTON_STATE_PRESSED: - handle_selection_start(seat, &seat->pointer_selection); + if (state->no_drag) { + if (!state->just_pressed) { + state->is_selecting = !state->is_selecting; + state->just_pressed = true; + } + } else { + state->is_selecting = true; + } break; case WL_POINTER_BUTTON_STATE_RELEASED: - handle_selection_end(seat, &seat->pointer_selection); + if (state->no_drag) { + state->just_pressed = false; + } else { + state->is_selecting = false; + } break; } + + if (state->is_selecting) { + handle_selection_start(seat, &seat->pointer_selection); + } else { + handle_selection_end(seat, &seat->pointer_selection); + } } static const struct wl_pointer_listener pointer_listener = { @@ -884,6 +925,7 @@ int main(int argc, char *argv[]) { .display_dimensions = false, .restrict_selection = false, .fixed_aspect_ratio = false, + .no_drag = false, .aspect_ratio = 0, .font_family = FONT_FAMILY }; @@ -892,7 +934,7 @@ int main(int argc, char *argv[]) { char *format = "%x,%y %wx%h\n"; bool output_boxes = false; int w, h; - while ((opt = getopt(argc, argv, "hdb:c:s:B:w:proa:f:F:")) != -1) { + while ((opt = getopt(argc, argv, "hdDb:c:s:B:w:proa:f:F:")) != -1) { switch (opt) { case 'h': printf("%s", usage); @@ -900,6 +942,9 @@ int main(int argc, char *argv[]) { case 'd': state.display_dimensions = true; break; + case 'D': + state.no_drag = true; + break; case 'b': state.colors.background = parse_color(optarg); break; diff --git a/slurp.1.scd b/slurp.1.scd index 6a93475..656a3b5 100644 --- a/slurp.1.scd +++ b/slurp.1.scd @@ -73,6 +73,10 @@ held, the selection is moved instead of being resized. Force selections to have the given aspect ratio. This constraint is not applied to the predefined rectangles specified using *-o*. +*-D* + Allow to click twice to select a rectangle, instead of the usual + click-and-drag method. + # COLORS Colors may be specified in #RRGGBB or #RRGGBBAA format. The # is optional.