Commit graph

234 commits

Author SHA1 Message Date
Daniel Eklöf
9209adf6fa
input: don’t use seat->kbd_focus as terminal when processing a key press
When converting mouse scroll events to keyboard input (in alternate
scroll mode), we need to use seat->mouse_focus, not seat->kbd_focus.

To enable this, break out key press/release handling code to a
separate function that takes an explicit term argument. Call this
function from keyboard_key(), input_repeat() and in alternate scroll
mode.

Closes #179
2020-11-03 19:44:51 +01:00
Daniel Eklöf
0d319f8793
input: handle XKB errors
* Don’t de-reference the xkb context/keymap/state if we failed to
  instantiate them.
* Don’t try to send a translated utf8 key sequence if the translation
  failed.
* Handle xkb_compose_state_get_utf8() and xkb_state_key_get_utf8()
  returning more than 64 bytes.

This _may_ fix #171.
2020-10-20 21:01:33 +02:00
Daniel Eklöf
4c3d2cfc7d
input: don’t allow diagonal resize when tiled 2020-10-20 21:00:19 +02:00
Daniel Eklöf
0573c685c7
input: don’t crash if xkbcommon cannot find a compose file
Handle xkb_compose_table_new_from_locale() returning NULL. When this
happens, log a warning that “dead keys” will be disabled, and make
sure to never de-reference the compose table pointer.

Closes #170
2020-10-19 18:30:19 +02:00
Daniel Eklöf
8b06a55cb0
Merge branch 'releases/1.5' into master 2020-10-13 08:06:56 +02:00
Daniel Eklöf
fdb7e40355
input: regression: don’t pass on mouse click to application if we consumed it
When we ‘consume’ a mouse button event (i.e. when we have a shortcut
mapped to it), the event should *not* be passed on to the client
application.

In 5f64c5c335, button handling was
refactored and unfortunately introduced a regression where we once
again started passing consumed button presses to the client
application.

Fixes #168
2020-10-13 08:02:09 +02:00
Daniel Eklöf
8e04b08615
input: trackpad scroll: correctly convert pixel movements to line movements
Trackpad scroll movements are in pixels. Foot previously “translated”
these directly to line movements (i.e. a one pixel scroll event was
translated into a one line scroll).

Now we use the line height of the terminal and correctly convert
pixels to lines.

This makes the trackpad scroll speed in foot consistent with the
scroll speed in e.g. Alacritty and Kitty.
2020-10-11 19:23:25 +02:00
Daniel Eklöf
59ca98f989
input: mouse: match binding if binding’s click count is *less*
Allow a mouse binding to match even if its click count is less than
the actual click count.

If there are multiple bindings that match, use the one with the
highest click count (that less than, or equal to the actual click
count).

Closes #146
2020-10-11 19:22:47 +02:00
Daniel Eklöf
674e565b5a
input: comment: ‘measures’ -> ‘measured’ 2020-10-11 18:23:16 +02:00
Daniel Eklöf
0f67549e04
input: comment: ‘fast’ -> ‘faster’ 2020-10-11 18:22:29 +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
dd14e0b3c3
input: auto-scroll: apply scrollback.multiplier to the interval divisor 2020-10-11 18:09:30 +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
Daniel Eklöf
2303affc87
input: motion: scroll up/down while selecting
If the cursor moves above the grid top, or below the grid bottom,
while selecting text, scroll up/down the scrollback before updating
the selection.

TODO: this only scrolls when the mouse is *moved*. I.e. you can’t move
the cursor outside the grid once and for all, and then let foot
auto-scroll.
2020-10-11 12:03:20 +02:00
Daniel Eklöf
a0ce7e40af
input: trackpad scroll: correctly convert pixel movements to line movements
Trackpad scroll movements are in pixels. Foot previously “translated”
these directly to line movements (i.e. a one pixel scroll event was
translated into a one line scroll).

Now we use the line height of the terminal and correctly convert
pixels to lines.

This makes the trackpad scroll speed in foot consistent with the
scroll speed in e.g. Alacritty and Kitty.
2020-09-29 19:42:31 +02:00
Daniel Eklöf
6a089c92ca
input: mouse: match binding if binding’s click count is *less*
Allow a mouse binding to match even if its click count is less than
the actual click count.

If there are multiple bindings that match, use the one with the
highest click count (that less than, or equal to the actual click
count).

Closes #146
2020-09-27 14:31:39 +02:00
Daniel Eklöf
04c1bab7b0
input: mouse_scroll(): refactor 2020-09-15 18:57:00 +02:00
Daniel Eklöf
cb41db8596
input: don’t use stale keycodes for arrow-up/down
The keycodes will change if the seat’s keymap changes. Make sure we
only do alternate scrolling if the seat has a keyboard, and use
the *current* layout’s keycodes for arrow up/down (instead of
the *first* layout’s).
2020-09-15 18:44:54 +02:00
Daniel Eklöf
028bbd03a3
input: don’t do alternate mode scrolling if application is grabbing mouse 2020-09-15 18:40:51 +02:00
Daniel Eklöf
6ad90e6323
input: don’t do grid scrollback if mouse events are being captured 2020-09-15 18:33:58 +02:00
Daniel Eklöf
4d13429235
key-binding: deprecate scrollback-up/down, add scrollback-up/down-line
This deprecates/renames scrollback-up/down to scrollback-up/down-page.

It also renames scrollback-up/down-half to
scrollback-up/down-half-page, and adds the new bindings
scrollback-up/down-line.
2020-09-10 18:17:47 +02:00
Daniel Eklöf
2e3bd5e23c
config: add scrollback-{up,down}-half key bindings
These new bindings scroll up/down half a page in the
scrollback (instead of the full page scrolled by
‘scrollback-{up,down}’).

Closes #128.
2020-09-09 19:40:48 +02:00
Daniel Eklöf
5f64c5c335
input: fix assertion when pressing first one mouse button, then another 2020-09-07 19:35:25 +02:00
Daniel Eklöf
e32c0d9bf6
Cast printf formatter %p arguments to void* 2020-08-23 10:07:08 +02:00
Daniel Eklöf
dabdffafa5
don't use empty struct initializers 2020-08-23 10:07:00 +02:00
Daniel Eklöf
3ddc17937f
input: inhibit mouse events to client when a binding has consumed it
This introduces a new state to a seat's mouse struct, 'consumed'. It
is set on a mouse *press* event that is claimed by a mouse binding.

It is cleared after a mouse *release* event.

While set, *no* mouse motion or button events are sent to the client
application.
2020-08-22 13:35:36 +02:00
Craig Barnes
104fe2fa55 Fix some spelling mistakes 2020-08-15 19:39:00 +01:00
Daniel Eklöf
d29c4aed8a
input: mouse motion: don't update selection while scrollback searching
When we are doing a scrollback search, the selection *is* ongoing. We
still don't want to update the selection when the mouse moves.
2020-08-14 07:38:56 +02:00
Daniel Eklöf
bb9228dd21
input: bindings: calculate 'cursor_is_on_grid' once only 2020-08-14 07:38:56 +02:00
Daniel Eklöf
364412bfaa
input: mouse-bindings: ignore Shift
Shift is used to enable selection when the client application is
grabbing the mouse.

As such, mouse bindings *never* have Shift as a modifier, but should
still trigger when Shift is being pressed.
2020-08-14 07:38:56 +02:00
Daniel Eklöf
28410f1b99
input: mouse-bindings: check selection is enabled/possible and that pointer is on grid
We shouldn't start or modify a selection if selection isn't
possible (i.e. client application is grabbing the mouse, and user
isn't holding Shift).

We also shouldn't start or modify a selection if the pointer is
outside the grid (updating an ongoing selection on motion events is an
exception to this).
2020-08-14 07:38:56 +02:00
Daniel Eklöf
4d2bc54fa2
config: mouse bindings: add select-begin-block and select-row 2020-08-14 07:38:56 +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
9b65531d6a
Merge branch 'modifiers-in-mouse-bindings' into master 2020-08-14 07:36:34 +02:00
Daniel Eklöf
44557dc7cf
input: don't crash on mouse motion events on the render timer surface 2020-08-14 07:35:01 +02:00
Daniel Eklöf
b97ef5819f
config: key/mouse bindings: refactor: less parsing in keyboard_enter()
This simplifies the handling of mouse and keyboard bindings.

Before, the bindings where parsed *both* when loading the
configuration, and then on every keyboard enter event. This was done
since keys require a keymap to be decoded. Something we don't have at
configuration time. The idea was that at config time, we used a
default keymap just to verify the key combo strings were valid.

The following has changed:

* The bindings in the config struct is now *one* key combo per
  entry. Previously, it was one *action* per entry, and each entry
  had one or more key combos.

  Doing it this way makes it easier when converting the binding in the
  keyboard enter event (which previously had to expand the combos
  anyway).

* The bindings in the config struct no longer contains any unparsed
  strings.

  A key binding contains a decoded 'modifier' struct (which specifies
  whether e.g. ctrl, or shift, or ctrl+shift must be pressed for the
  binding to be used).

  It also contains a decoded XKB keysym.

* A mouse binding in the config struct is similar to a key binding,
  except it contains the button, and click count instead of the XKB
  key sym.

* The modifiers in the user-specified key combo is decoded at config
  time, by using the pre-defined XKB constants
  XKB_MOD_NAME_<modifier>.

  The result is stored in a 'modifiers' struct, which is just a
  collection of booleans; one for each supported modifier.

  The supported modifiers are: shift, ctrl, alt and meta/super.

* The key sym is decoded at config time using
  xkb_keysym_from_name(). This call does *not* depend on a keymap.

* The mouse button is decoded at config time using a hardcoded mapping
  table (just like before).

* The click count is currently hard-coded to 1.

* In the keyboard enter event, all we need to do is pre-compute the
  xkb_mod_mask_t variable for each key/mouse binding, and find all the
  *key codes* that map to the (already decoded) symbol.

  For mouse bindings, the modifiers are the *only* reason we convert
  the mouse bindings at all.

  In fact, on button events, we check if the seat has a keyboard. If
  not, we use the mouse bindings from the configuration directly, and
  simply filter out those with a non-empty set of modifiers.
2020-08-13 18:47:19 +02:00
Daniel Eklöf
375dcf0810
input: pointer-leave: don't reset mouse properties with memset()
Using memset() also clears the mouse bindings. This is both incorrect,
and leaked memory.
2020-08-13 18:47:19 +02:00
Daniel Eklöf
544c1b1976
config: wip: add support for modifiers in mouse bindings
Mouse bindings can now include modifiers. They are specified in pretty
much the same way as in keyboard bindings:

  Control+BTN_LEFT
2020-08-13 18:47:19 +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
e391658d72
Merge branch 'selection-improvements' into master
Closes #70
2020-08-08 10:19:04 +02:00
Daniel Eklöf
4156a64044
input: motion: improve comment 2020-08-08 10:08:47 +02:00
Daniel Eklöf
a3d5626256
input: pointer-enter: add comment describing what we're doing 2020-08-08 10:07:25 +02:00
Daniel Eklöf
7497e44826
input: motion: regression: check for RMB when updating selection
While refactoring this code, the check for LMB or RMB got changed to
LMB or "any button".

This fixes that.

It also adds a boolean 'cursor_is_on_grid', which should make the code
easier to read and understand.
2020-08-08 10:00:18 +02:00
Daniel Eklöf
d49d1fd59d
input: scrolling: don't send events to client if cursor is outside grid 2020-08-07 22:07:16 +02:00
Daniel Eklöf
76c3629cbf
input: mouse: motion/enter: cleanup inside/outside grid handling 2020-08-07 22:04:37 +02:00
Craig Barnes
7eb70a453b Replace GCC "unused" and "format" attributes with portable macros 2020-08-07 20:42:34 +01:00
Daniel Eklöf
4178418010
input: button: button events aren't passed to clients, when cursor is outside grid
Don't send mouse button escapes to a mouse grabbing client when the
cursor is outside the grid (i.e. when it is inside the margins).

Also don't do *any* kind of selection when the cursor is outside the
grid. Previously, we only checked this for selection_start(), but
e.g. double clicking would run selection_extend(), or
selection_mark_word() etc.
2020-08-07 19:59:03 +02:00
Daniel Eklöf
721ca80abe
input: motion: do selection update even if cursor is outside the grid
Previously, the selection was only updated when the mouse cursor was
inside the grid. This makes it difficult to e.g. do large selections
fast, since you often end up moving the cursor outside the grid, or
outside the terminal window even.

Now, we update the selection regardless of *where* the cursor is. This
is done by bounding the row/col we pass to 'selection_update()' to the
grid, while still setting the seat's row/col to -1 when the cursor is
outside the grid, to ensure the xcursor etc are set correctly.

Care must also be taken to *not* pass any motion events to a mouse
grabbing client, when the cursor is outside the grid.

Closes #70.
2020-08-07 19:58:56 +02:00
Daniel Eklöf
158722b642
input: fix col/row calculation when cursor is in the top or left margin
This fixes an issue where the col/row were incorrectly set to 0
instead of -1, when the mouse cursor was inside the grid margins.

This resulted in e.g. the mouse cursor having the wrong shape, and
foot incorrectly handling mouse events as if they were inside the
grid.
2020-08-07 19:51:34 +02:00
Daniel Eklöf
32a155fbf4
input: disable debug loggin 2020-08-04 18:07:41 +02:00