Commit graph

31 commits

Author SHA1 Message Date
Daniel Eklöf
be22fefdc7
selection: add support for different mime-types
Add support for `text/plain`, `text/plain;charset=utf-8` and
`text/uri-list` to regular copy operations (both from clipboard and
primary selection) and drag-and-drop operations.
2020-10-28 19:16:04 +01:00
Daniel Eklöf
7fedf2f801
selection: auto-scroll: selection keeps scrolling while mouse is outside grid
Moving the mouse outside the grid while we have an on-going selection
now starts a timer. The interval of this timer depends on the mouse’s
distance from the grid - the further away the mouse is, the shorter
interval.

On each timer timeout, we scroll one line, and update the
selection. Thus, the shorter the interval, the faster we scroll.

The timer is canceled as soon as the mouse enters the grid again, or
the selection is either canceled or finalized.

The timer FD is created and destroyed on-demand.

Most of the logic is now in selection.c. The exception is the
calculation of the timer interval, which depends on the mouse’s
position. Thus, this is done in input.c.

The scroll+selection update logic needs to know a) which direction
we’re scrolling in, and b) which *column* the selection should be
updated with.

If the mouse is outside the grid’s left or right margins, the stored
mouse column will be -1. I.e. we don’t know whether the mouse is on
the left or right side of the grid. This is why the caller, that
starts the timer, must provide this value.

The same applies to top and bottom margins, but since we already have
the scroll *direction*, which row value to use can be derived from this.
2020-10-11 15:44:20 +02:00
Daniel Eklöf
dec6f963cb
selection: add selection_<type>_has_data()
Returns true when there is data available for paste in the
clipboard/primary selection.
2020-09-09 19:01:21 +02:00
Daniel Eklöf
c3cacb4704
selection: add selection_<type>_unset()
These functions clear the current selection.
2020-09-09 19:01:21 +02:00
Daniel Eklöf
639a61abd8
config: add 'pipe-selected' key binding
This works just like pipe-visible and pipe-scrollback, but pipes the
user-selected text, if any, to the external tool.

Closes #51
2020-07-31 17:04:30 +02:00
Daniel Eklöf
71584aed38
seat: use separate 'enter' serials for keyboard and mouse 2020-07-09 11:20:46 +02:00
Daniel Eklöf
4e48d550ef
multi-seat: improve handling of multiple (mouse) pointers
* xcursor always set for all pointers
* xcursor sometimes not updated when it should be
* mouse grabbed state wasn't per seat, but global (i.e. "does at least
  one seat enable mouse grabbing")
* selection enabled state wasn't per seat
2020-07-09 09:52:11 +02:00
Daniel Eklöf
4c7d29f7eb
multi-seat: re-enable selection support (excluding OSC 52) 2020-07-08 18:41:09 +02:00
Daniel Eklöf
08588cd0fc
selection: handle viewport wrap around correctly
When the viewport wraps around, the selection points may be
"incorrect".
2020-05-19 18:49:42 +02:00
Daniel Eklöf
96a4f1b993
term: scrolling: hopefully fix all selection/scrolling related crashes
When scrolling, there are a couple of cases where an existing
selection must be canceled because we cannot meaningfully represent it
after scrolling.

These are when the selection is (partly) inside:

* The top scrolling region
* The bottom scrolling region
* The new lines scrolled in. I.e. re-used lines

For the scrolling regions, the real problem is when the selection
crosses the scrolling region boundary; a selection that is completely
inside a scrolling regions _might_ be possible to keep, but we would
need to translate the selection coordinates to the new scrolling
region lines.

For simplicity, we cancel the selection if it touches the scrolling
region. Period.

The last item, newly scrolled in lines is when the selection covers
very old lines and we're now wrapping around the scrollback history.

Then there's a fourth problem case: when the user has started a
selection, but hasn't yet moved the cursor. In this case, we have no
end point.

What's more problematic is that when the user (after scrolling) moves
the cursor, we try to create a huge selection that covers mostly
empty (NULL) rows, causing us to crash.

This can happen e.g. when reverse scrolling in such a way that we wrap
around the scrollback history.

The actual viewport in this case is something like `-n - m`. But the
selection we'll end up trying to create will be `m - (rows - n)`. This
range may very well contain NULL rows.

To deal with this, we simply cancel the selection.
2020-05-17 15:34:49 +02:00
Daniel Eklöf
1a8ccb0ffa
selection/render: sync cells' 'selected' bit before rendering
For performance reasons, we track whether a cell is selected or not
using a bit in a cell's attributes.

This makes it easy for the renderer to determine if the cells should
be rendered as selected or not - it just have to look at the
'selected' bit instead of doing a complex range check against the
current selection.

This works nicely in most cases. But, if the cell is updated, the
'selected' bit is cleared. This results in the renderer rendering the
cell normally, i.e. _not_ selected.

Checking for this, and re-setting the 'selected' bit when the cell is
updated (printed to) is way too expensive as it is in the hot path.

Instead, sync the 'selected' bits just before rendering. This isn't so
bad as it may sound; if there is no selection this is a no-op. Even if
there is a selection, only those cells whose 'selected' bit have been
cleared are dirtied (and thus re-rendered) - these cells would have
been re-rendered anyway.
2020-05-16 21:36:08 +02:00
Daniel Eklöf
38c050746d
selection: on_row_in_view() -> on_rows_in_view(), and now takes a range
This allows us to check the selection once when scrolling, instead of
once for each scrolled in line.
2020-05-16 21:16:11 +02:00
Daniel Eklöf
aa01521ff6
selection: add selection_extend()
This function extends an existing selection in the following way:

If the extension point is *before* the upper boundary of the current
selection, extend the selection upwards.

If the extension point is *after* the bottom boundary of the current
selection, extend the selection downwards.

If the extension point is *inside* the current selection, shrink the
selection such that the new size is maximized. This means we move the
*closest* start/end point from in the current selection.
2020-04-04 11:59:15 +02:00
Daniel Eklöf
d706e68280
selection: track selection type; normal or block selection 2020-01-03 23:29:45 +01:00
Daniel Eklöf
fd82caad42
selection: document the asynchronous behavior of text_from_{primary,clipboard} 2019-11-05 09:13:47 +01:00
Daniel Eklöf
b15032d223
selection: text_from_{clipboard,primary}: add 'done' callback
This callback is *always* called, including when there has been an
error.

This is in preparation for making text_from_{clipboard,primary}
asynchronous.
2019-11-05 08:49:32 +01:00
Daniel Eklöf
15afd26716
osc: implement copy/paste to/from primary 2019-08-09 21:27:51 +02:00
Daniel Eklöf
70b6d9d7d2
input: don't paste from primary if client is mouse tracking 2019-08-09 21:26:34 +02:00
Daniel Eklöf
481a1cd678
selection/input: triple click selects an entire row 2019-08-06 19:32:06 +02:00
Daniel Eklöf
c06f141189
term: cancel selection when scrolling wraps
If we scroll enough, we'll eventually end up wrapping around the
entire scrollback buffer. At this point, a selection is no longer
valid, so cancel it.

Note: this was very obvious when scrolling in the alt screen, since
its scrollback buffer is what you see on the screen (i.e. it has no
scrollback).
2019-08-05 20:16:17 +02:00
Daniel Eklöf
c62ce72778
selection: mark-word using spaces only as word separator
When the user double-clicks with ctrl pressed, we now select the word
under the cursor using spaces only as word separator.
2019-08-05 19:02:27 +02:00
Daniel Eklöf
793c37923e
selection: add text_from_clipboard()
This function reads data from the clipboard, and calls a user-provided
callback for each chunk of clipboard data.
2019-07-19 14:20:00 +02:00
Daniel Eklöf
167036ccbe
selection: add text_to_clipboard()
This function takes a string and makes it available to the clipboard.
2019-07-19 11:12:14 +02:00
Daniel Eklöf
8bd969262b
selection: implement double-click-to-select-word 2019-07-17 21:30:57 +02:00
Daniel Eklöf
66e067082b
selection: implement copy *to* primary 2019-07-11 17:38:03 +02:00
Daniel Eklöf
703aeecb95
selection: add support for pasting *from* primary 2019-07-11 17:38:03 +02:00
Daniel Eklöf
e56066feef
selection: add selection_from_primary() API (stub for now) 2019-07-11 17:38:03 +02:00
Daniel Eklöf
482c8f76a9
selection: add support for pasting from clipboard 2019-07-11 17:38:02 +02:00
Daniel Eklöf
b50ec1a850
selection: initial copy-to-clipboard functionality 2019-07-11 17:38:02 +02:00
Daniel Eklöf
e7e199d6b5
selection: spell 'finalize' correctly 2019-07-11 17:38:02 +02:00
Daniel Eklöf
bcf763d417
selection: add a selection API 2019-07-11 17:38:01 +02:00