Skip to content

add drag mode for click-and-drag / text selection #96

Open
kristijanribaric wants to merge 6 commits into
moverest:mainfrom
kristijanribaric:add-drag-mode
Open

add drag mode for click-and-drag / text selection #96
kristijanribaric wants to merge 6 commits into
moverest:mainfrom
kristijanribaric:add-drag-mode

Conversation

@kristijanribaric

@kristijanribaric kristijanribaric commented Jun 10, 2026

Copy link
Copy Markdown

Adds a --drag flag (-d) that performs a left-button click-and-drag between two selected positions, enabling text selection and UI element dragging via the keyboard.

How it works

--drag is a flag that can be combined with any mode chain. It requires two selections:

  1. Start selection: the mode chain runs as normal; once a target is confirmed, its position is stored as the drag start and a caret marker is drawn on screen. The selection then resets so the user can pick again.
  2. End selection: once the second target is confirmed, the pointer presses and holds the left button at the start position, moves to the end position, and releases.

It works with any mode or chain of modes:

wl-kbptr -o modes=tile,click --drag
wl-kbptr -o modes=floating,click --drag
wl-kbptr -o modes=bisect,click --drag
wl-kbptr -o modes=split,click --drag
wl-kbptr -o modes=tile,bisect,click --drag

Demo

recording_20260610_121438.mp4

Configuration ([mode_drag])

Option Default Description
start_marker_color #f50d Color of the start position marker
start_marker_size 8 Size of the marker in pixels
start_marker_shape caret Shape: caret (I-beam), rectangle or circle

Implementation notes

  • Added a restart callback to mode_interface so the mode chain can be reset for the second selection without re-doing setup (e.g. floating keeps its loaded/detected areas, tile/bisect/split reset their label selection or history)
  • drag_phase is tracked on struct state; drag intercept logic lives in enter_next_mode at the terminal point
  • The start marker is rendered as an overlay in mode_render, on top of whatever mode is currently active

@moverest

Copy link
Copy Markdown
Owner

Thanks for your PR. I like the idea and it's something that was suggested as well (#31).

I am wondering however if implementing it as a mode makes the most sense. It doesn't really do anything and most of the logic is already outside. I feel like just being an option, e.g. --drag, would make more sense. Or maybe it's a case where the mode abstraction is showing its limit. I'm not sure. I'll try to have a think this weekend and come back to the review.

@moverest

Copy link
Copy Markdown
Owner

After some thought, I realise that the "mode" abstraction is starting to show its limits. What we're really doing is running through modes until we get a selection and then rerun them from the start to get the second selection which then enables us to do the mouse drag so it's not really a "mode". It should make the code simpler then not implementing it as a mode but just as an option, e.g. --drag. What do you think?

@kristijanribaric

Copy link
Copy Markdown
Author

If you have it an option as --drag, how would you use it exactly? Would you use it like wl-kbptr -o modes=floating --drag?
What if you call wl-kbptr -o modes=floating,click --drag? Should then a click also not be a mode but an option like --click?

@kristijanribaric

kristijanribaric commented Jun 19, 2026

Copy link
Copy Markdown
Author

I think it might make more sense to keep modes only for selecting modes and make the click additional parameter, so with drag you'd use it as wl-kbptr -o modes=floating --click --drag and then maybe add additional params later like --right-click, --double-click, etc.

What do you think is the best approach here?

@moverest

Copy link
Copy Markdown
Owner

You make a great point.

The only thing the click mode does is set the a global state to tell the program what to do when we're done carving the selection area. It "worked" because it didn't change the flow but now that you're adding the dragging which basically goes through all the modes all again, the abstraction is wacky.

I like your suggestion with the --drag and --click. I think it makes sense.

Now, for this PR, I think it makes sense to just add the --drag and keep the rest as to not increase the scope.

Once it's merged, the --click options can be added. I'm thinking of keeping the click mode for compatibility reasons (as to not break people's configs) but remove it from the documentation.

@kristijanribaric

Copy link
Copy Markdown
Author

I refactored the code so that drag more is triggered using --drag parameter, please have a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants