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
While pasting data from the clipboard, block *all* other data from
being sent to the client. This includes keyboard and mouse events, but
also replies for VT queries.
This is particularly important when bracketed paste has been enabled,
since then the client will interpret *everything* between the
bracketed paste start and end as paste data.
When reading clipboard data, a malicious clipboard provider could
stall us forever, by not sending any data, and not closing the pipe.
This commit adds a timer_fd based timeout of 2 seconds. If the timer
triggers, we abort the clipboard receive.
Check for ongoing selection, and *clear* it before bailing out due to
the selection not having an end-point.
This fixes an issue where a selection was kept as ongoing, even though
the button had been released. Typically triggered by clicking without
moving the mouse; this started a new selection, then (tried to)
finalize it, but failed since the selection didn't have an end-point.
This extends the "normal" bind action enum with mouse specific
actions.
When parsing key bindings, we only check up to the last valid keyboard
binding, while mouse bindings support *both* key actions and mouse
actions.
The new actions are:
* select-begin: starts an interactive selection
* select-extend: interactively extend an existing selection
* select-word: select word under cursor
* select-word-whitespace: select word under cursor, where the only
word separating characters are whitespace characters.
The old hard-coded selection "bindings" have been converted to instead
use these actions, via default bindings added to the configuration.
Without this, the initial cell will always be selected, regardless of
how the selection is moved to the left or right.
With this patch, the initial cell will only be selected while the
selection is being made in the original direction. Changing direction
of the selection moves the start point to next/previous character.
* Fix col/row calculation in pointer-enter event; we did not take the
margins into account.
* seat->mouse.col,row are now set to -1 if the cursor is inside the
margins. That is, col/row are only ever valid when the mouse is
actually over the grid, and not in the margins.
* Use regular 'left-ptr' mouse cursor when mouse is inside the
margins, to not make the user think he/she can start a selection.
Besides making things clearer, this also fixes a crash that occurred
if you started a selection in e.g. the right margin.
As that breaks e.g. selection marking (SPACER cells didn't get
inverted when rendered).
Instead, skip them in extract_one() only. I.e. when copying text from
the grid.