This fixes an assertion triggered when selecting the upper left cell
and dragging down.
We would end up trying to decrement the pivot end point, hitting an
assertion that only is valid while skipping spacers.
Remove the assertion, and allow pivot points to be moved across line
wraps, but take care not to move outside the visible screen area.
If the initial character is a space, find the next non-space
character.
If the initial character is a delimiter, find the next non-delimiter
character (space, or word character).
If the initial character is neither (i.e, it is a word character),
find the next non-word character.
Extend selection pivoting to allow selections to pivot around a
range.
Use this in word- and row-based selections to pivot around the initial
word/row that was selected.
This mimics the behavior of at least urxvt and xterm.
This removes the selection_mark_word() and selection_mark_row()
functions. To start a word/row-based selection, use selection_start()
with SELECTION_SEMANTIC_{WORD,ROW}
Store a list of currently pressed buttons, and which surface they
belong to (i.e. which surface that received the press).
Then, in motion events (with a button pressed, aka drag operations),
send the event to the “original” surface (that received the press).
Also send release events to the originating surface.
This means a surface receiving a press will always receive a
corresponding release. And no one will receive a release event without
a corresponding press event.
Motion events with a button pressed will *always* use the *first*
button that was pressed. I.e. if you press a button, start dragging,
and then press another button, we keep generating motion events for
the *first* button.
enum selection_scroll_direction is used when extending a selection by
auto-scrolling the terminal content while the mouse is outside the
grid.
What we want is enum selection_direction.
The intention here is to make *all* text_from_clipboard() and
text_from_primary() callers benefit from mime-type base
decoding (e.g. URI list decoding).
Previously, the decoding was done *in* the callback, which meant only
the “default” clipboard/primary selection paste functions, and DnD,
recognized URI lists.
At the end of a drag-and-drop operation, we need to call
`wl_data_offer_finish()`.
We *must* ensure the data offer hasn’t been destroyed before
that. This could previously happen if the compositor decided to send a
regular clipboard offer *after* we had started a drop operation,
but *before* it had finished. The dnd offer was then destroyed when
the clipboard offer was received, causing us to crash in
`wl_data_offer_finish()`.
To handle this, let the receive_offer_context take over ownership of
the data_offer pointer, and “manually” destroy it *after* calling
`wl_data_offer_finish()` in `receive_dnd_done()`.
Note: we should not, and can not, do the same thing for regular
clipboard and primary selection offers; such offers can be used
multiple times and should *not* be destroyed after a single copy
operation.
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.
We accept COPY and MOVE actions, for text/plain;charset=utf-8
mime-types.
To implement DnD, we need to track the current DnD data offer *and*
the terminal instance it is (currently) targeting.
To do this, a seat has a new member, ‘dnd_term’. On a DnD enter event,
we lookup the corresponding terminal instance and point ‘dnd_term’ to
it.
On a DnD leave event, ‘dnd_term’ is reset.
The DnD data offer is tracked in the terminal’s wayland window
instance. It is reset, along with the seat’s ‘dnd_term’ on a DnD leave
event.
On a drop event, we immediately clear the seat’s ‘dnd_term’, to ensure
we don’t reset it, or destroy the offer before the drop has been
completed.
The drop’s ‘done()’ callback takes care of destroying and resetting
the DnD offer in the terminal’s wayland window instance.
Closes#175
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.
Assume it could be a copy-paste typo. We should check PRIMARY, not
CLIPBOARD. Without this fix, we can't use PRIMARY until we copy anything
to CLIPBOARD.
This option lets the user configure which characters act as word
delimiters when selecting text.
This affects both “double clicking”, and ‘ctrl-w’ in scrollback search
mode.
Closes#156