Commit graph

154 commits

Author SHA1 Message Date
Daniel Eklöf
ff96ce1e91
input: rework mouse button/motion handling
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.
2020-12-12 19:05:24 +01:00
Daniel Eklöf
9e1746cc29
selection: do not try to paste un-handled mime types
Closes #230
2020-11-30 20:04:17 +01:00
Daniel Eklöf
043b741008
selection: offer clipboard content in more mime types 2020-11-30 20:02:47 +01:00
Daniel Eklöf
2281ee852a
selection: fix enum type
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.
2020-11-06 20:12:15 +01:00
Daniel Eklöf
a8fb51a34c
selection: explicitly set direction when right-click extending
Fixes an issue where right-click-and-dragging to extend a selection
caused one cell being removed from the selection.

Closes #180
2020-11-04 19:01:59 +01:00
Daniel Eklöf
43f293f22e
selection: do mime-type based decoding before passing data to callback
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.
2020-11-01 11:52:11 +01:00
Daniel Eklöf
102d4975a1
selection: dnd: fix wl_data_offer_destroy() race
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.
2020-10-31 10:36:11 +01:00
Daniel Eklöf
bb43695426
codespell: fix misspelled words 2020-10-28 19:34:49 +01:00
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
9580c04dd3
selection: debug log of data offer mime-types and actions 2020-10-26 21:19:07 +01:00
Daniel Eklöf
8e23b5b70d
selection: implement support for drag-and-drop
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
2020-10-26 21:02:53 +01:00
Daniel Eklöf
033ff180af
selection: re-factor: break out code shared between clipboard/primary send
The send functions are called by the compositor when another
application wants to paste data *from* foot.
2020-10-13 18:38:49 +02:00
Daniel Eklöf
0d8344d3b9
selection: auto-scroll: call cmd_scrollback_{up,down}() with number of rows
No need to loop and call cmd_scrollback_{up,down}() with ‘1’ each loop
iteration; just call it with the total number of lines to scroll.
2020-10-11 18:26:24 +02:00
Daniel Eklöf
0cff7c7c4f
selection: cancel: call selection_stop_scroll_timer()
Instead of re-implementing the same logic, simply call
selection_stop_scroll_timer().
2020-10-11 18:24:47 +02:00
Daniel Eklöf
4ad7fdc19c
selection: auto-scroll: add SELECTION_SCROLL_NOT as a scroll ‘direction’ 2020-10-11 18:18:18 +02: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
Sergey Nazaryev
d95dd062aa selection: use appropriate check for PRIMARY paste
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.
2020-10-10 21:13:58 +03:00
Daniel Eklöf
49f4b3da64
config: add ‘[default].word-delimiters’
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
2020-10-09 19:44:23 +02:00
Daniel Eklöf
fcb2beebda
selection: reset clipboard/primary->text after free:ing it 2020-09-17 20:05:22 +02:00
Daniel Eklöf
dd18710bb7
selection: primary unset: don’t free text twice 2020-09-17 20:02:38 +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
44e7943fef
codespell: selection: faild -> failed 2020-08-27 19:55:27 +02:00
Daniel Eklöf
1707db1678
selection: don't initiate a paste when we're already pasting 2020-08-25 18:56:15 +02:00
Daniel Eklöf
9ec4c3fd94
selection: must use term_paste_data_to_slave() for paste data 2020-08-25 18:56:15 +02:00
Daniel Eklöf
efbc3431ed
selection: clipboard callback: assert we're in sending-paste-data mode 2020-08-25 18:56:15 +02:00
Daniel Eklöf
e570146c07
selection: block non-paste data from being sent to client while pasting
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.
2020-08-25 18:56:15 +02:00
Daniel Eklöf
81222dac57
selection: add a 2 second timeout when receiving clipboard 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.
2020-08-25 18:56:13 +02:00
Daniel Eklöf
74cf8e0206
selection: don't do "return function_returning_void()" in functions returning void 2020-08-23 10:07:09 +02:00
Daniel Eklöf
dabdffafa5
don't use empty struct initializers 2020-08-23 10:07:00 +02:00
Daniel Eklöf
cb9626741a
selection: don't highlight trailing empty cells in a selection
This makes it clear which cells contain spaces (that will be copied)
or are empty (will *not* be copied).
2020-08-18 18:03:07 +02:00
Daniel Eklöf
f14b49068a
selection: extend: set ongoing to true 2020-08-14 07:38:56 +02:00
Daniel Eklöf
9517c6443c
selection: finalize: clear ongoing selection
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.
2020-08-14 07:38:55 +02:00
Daniel Eklöf
cddeaa2c1c
selection: update: don't update if there's no ongoing selection 2020-08-14 07:38:55 +02:00
Daniel Eklöf
20f0334e13
config: add mouse specific bind actions
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.
2020-08-14 07:38:55 +02:00
Daniel Eklöf
1decd8e9de
selection: improve handling of multi-column characters
* Don't assume multi-column characters are exactly *two* columns
* Check for CELL_MULT_COL_SPACER values instead of using wcwidth()
2020-08-13 18:33:22 +02:00
Daniel Eklöf
3816a3b460
selection: handle multi-column characters when reversing selection direction 2020-08-13 18:32:56 +02:00
Daniel Eklöf
8808dd28f2
selection: adjust start point when the selection changes direction
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.
2020-08-12 19:42:21 +02:00
Craig Barnes
7a77958ba2 Convert most dynamic allocations to use functions from xmalloc.h 2020-08-08 20:37:57 +01: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
5c20069588
Merge branch 'master' into scrollback-position-indicator 2020-07-27 16:51:39 +02:00
Daniel Eklöf
7127a0a6c3
selection: extending a selection is now interactive
That is, a selection extension can be resized just like an ordinary
extension.
2020-07-27 16:44:41 +02:00
Daniel Eklöf
c1f35731e0
input: margins are not selectable
* 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.
2020-07-26 12:37:02 +02:00
Daniel Eklöf
ffaa19ee22
selection: provide a const-wrapper for extract_one()
extract_one() takes const pointers, while the callback argument to
foreach() expects non-const.
2020-07-15 11:31:57 +02:00
Daniel Eklöf
aafa120f92
selection: refactor: break out text extraction to a separate file 2020-07-15 11:19:18 +02:00
Daniel Eklöf
bead6f36d6
selection: don't skip SPACER cells in the generic foreach()
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.
2020-07-15 09:22:06 +02:00
Daniel Eklöf
540864521e
selection: row->dirty is a boolean 2020-07-15 09:21:39 +02:00
Daniel Eklöf
a2af13a126
selection: no need to try to detect multi-column chars at the end of the line
This is handled by the generic foreach() functions, which now simply
skips spacer cells.
2020-07-14 17:06:04 +02:00
Daniel Eklöf
df2927e088
term: print: write special value CELL_MULT_COL_SPACER to extra cells
When printing a multi-column character, write CELL_MULT_COL_SPACER
instead of '0' to both padding cells (when character doesn't fit at
the end of the line), and to the cells following the actual character.
2020-07-14 16:49:11 +02:00
Daniel Eklöf
5c99e8013b
term: rename COMB_CHARS_LO,HI -> CELL_COMB_CHARS_LO,HI 2020-07-14 16:41:57 +02:00