Commit graph

306 commits

Author SHA1 Message Date
Daniel Eklöf
2d85dbec6b
input: enable repeat while COMPOSING 2021-11-28 15:14:52 +01:00
Daniel Eklöf
9f3dba683e
input: refactor: new function: legacy_kbd_protocol()
This breaks out all handling of key escapes to-be-sent to the client,
to a separate function, legacy_kbd_protocol().

That is, the key press/release handler first handles key generic
handling, such as starting and stopping the repeat timer.

Then it checks for foot keyboard bindings. If not bindings match, we
need to pass the keyboard event to the client. This code has now been
separated out into a new function.
2021-11-28 15:14:52 +01:00
Daniel Eklöf
325ad6dd4e
input: finalize mouse selection on a pointer-leave event on the GRID surface
If a mouse selection was ongoing, and the user switched
workspace (probably using the keyboard...), and then back, the
selection was still treated as ongoing, while all other mouse state
has been reset.

This meant the user had to tap at least once to stop the selection.
2021-11-25 15:21:53 +01:00
Daniel Eklöf
4a74050999
input: add support for modifyOtherKeys=2
Similar to modifyOtherKeys=1 (foot’s default, and only, mode), except
that:

* All modifiers (and not just Ctrl) generate \E[27;m;n~ escapes
* Regular keys (with modifiers) also generate \E[27;m;n~ escapes (for
  example, C-h no longer generates ^H, but \E[27;5;104~)

For our keymap based lookups, this is handled by adding
MOD_MODIFY_OTHER_KEYS_STATE<N> variants.

For “generic” keys, we simply adjust the conditions for when to emit a
\E[27;m;n~ escape - the only requirement is that at least one modifier
is active.
2021-11-13 11:09:07 +01:00
Daniel Eklöf
ebcf5a4b4f
input: don’t apply [scrollback].multiplier when alt screen is in use
Closes #787
2021-11-13 11:05:36 +01:00
Daniel Eklöf
0900d01ec9
input: clean up mouse scroll handling
* Allow scrolling on the normal (non-alt) screen, when application is
  grabbing the mouse (when user presses Shift).
* Use term_mouse_grabbed() instead of explicitly checking for
  MOUSE_NONE tracking.
* Remove mouse tracking check from cmd_scrollback_{up,down}. Caller is
  expected to have done the check.
* Don’t scroll down on mouse wheel tilt events.
2021-10-27 17:09:26 +02:00
Daniel Eklöf
bcea929c94
config: add [key-bindings].noop action
Key combinations assigned to this action will not be sent to the
application.

Closes #765
2021-10-27 17:07:26 +02:00
Daniel Eklöf
8691ad8b2e
input: update serial on each key press/release and mouse button
The serial is used when copying/pasting data from the clipboard. Up
until now, we’ve used the serial from the keyboard/mouse enter
events.

This works in most cases, but breaks in the following example:

  $ wl-copy  WLCOPY
  /* Ctrl+Shift+v works fine (pastes "WLCOPY") */

  $ printf "\033]52;c;eHl6\a"
  /* Ctrl+Shift+v pastes "WLCOPY" instead of "xyz" */

Shifting focus away and then back to the foot window, and re-executing
the printf works, suggesting the “enter” serial is no longer valid
after another process(?) has copied something to the clipboard.

Updating the serial on key press/release (and the corresponding mouse
serial on mouse button events) seems to fix this.

I’ve also tested that “normal” copy/paste operations, within the same
foot instance, and between foot and other applications, are still
working. In at least river (wlroots based), and GNOME/mutter.

Closes #753
2021-10-20 19:59:57 +02:00
Daniel Eklöf
dbc01459e7
input: filter out non-significant modifiers when matching mouse bindings
Closes #736
2021-10-06 20:12:17 +02:00
Daniel Eklöf
8e4d020a41
input: check for ‘effective’ modifiers, not ‘depressed’
When reading XKB modifier state, use XKB_STATE_MODS_EFFECTIVE, not
XKB_STATE_MODS_DEPRESSED.

This fixes handling of ‘sticky’ modifier keys.
2021-10-02 17:33:01 +02:00
Daniel Eklöf
e553e1076c
input: workaround GNOME issue with pointer button events
Under certain circumstances, GNOME will send multiple pointer button
press events, without any release or leave events in between.

This trips up our button tracking.

Workaround, by replacing the existing state for the pressed button
with the new state.

Previously, debug builds would assert (and thus crash), while release
builds would have multiple states for the same button,
causing (probably) issues like the title bar not being usable (as in,
cannot be dragged, buttons not working etc).

Hopefully closes #709
2021-09-12 10:32:22 +02:00
Daniel Eklöf
c2cc964116
input: implement support for mouse wheel left/right
We now emit button 6/7 events (when the client application grabs the
mouse). This buttons map to mouse wheel horizontal scroll events. Or, left/right
tilting, if you like.

Wayland report these as ‘axis’ events (just like regular scroll wheel events),
and thus we need to translate those scroll events to button events.

libinput does not define any mouse buttons for wheel tilts, so we add our own
defitions. These are added last in the BTN_* range, just before the BTN_JOYSTICK
events.
2021-08-07 12:27:44 +02:00
Daniel Eklöf
460e3b5c57
input: codespell: follwing -> following 2021-08-06 23:08:09 +02:00
Daniel Eklöf
a21bf1b4d9
input: workaround GNOME messing up pointer leave/enter after moving window
GNOME doesn’t send pointer enter after finishing a window move.

In subsequent move operations, it is also possible to make it skip sending
pointer leave when starting the move operations.

This caused foot to assert in debug builds, and add the same button multiple
times to the list of buttons currently being pressed.
2021-08-06 22:35:29 +02:00
Daniel Eklöf
03f952cf4d
term: consolidate shutdown related state into an anonymous struct 2021-07-31 19:08:51 +02:00
Daniel Eklöf
149c52bd44
config: remove replaced/removed key bindings, instead of marking as ‘unused’
Instead of keeping removed/replaced key bindings in the key binding
array (marked as ‘unused’), remove them, by compacting the array.

The invariant is thus that there should be *no* entries in the key
binding list with the `BIND_ACTION_NONE` for action.

Add code to debug builds that verifies this, plus a unit test.

Closes #614
2021-06-30 18:05:07 +02:00
Daniel Eklöf
a09f928175
input: ignore ‘unused’ URL key bindings when mapping bindings to current keymap
This is a temporary fix for #614. Long term fix is to remove the
‘replaced’ bindings from the array at config time.
2021-06-28 22:34:52 +02:00
Daniel Eklöf
f7860aec76
config: add new function config_clone() 2021-06-23 10:39:14 +02:00
Daniel Eklöf
495c730487
config: don’t use tllist where it isn’t necessary
tllists are great when dealing with dynamically changing lists. They
are also very easy to use when building lists/arrays where the final
size is unknown.

However, this ease of use comes at a price: code size. tll-macros
expand to a lot of code.

Since things in the config are static, once the config has been
loaded, using tllists for configuration data structures doesn’t make
much sense.

This patch replaces nearly all tllists used by the configuration, with
dynamically allocated arrays.
2021-06-18 15:35:57 +02:00
Daniel Eklöf
a7e2e4bfa9
input: pass through scrollback-* key bindings when alt screen is activw
Since the alt screen have no scrollback, all scrollback-* actions are
effectively no-ops when the alt screen is active.

Make them available to the client application instead.

Closes #573
2021-06-04 23:25:45 +02:00
Craig Barnes
3d9302b6f9
macros: add UNITTEST macro and use to replace test_keymap_lookup() 2021-05-26 09:13:58 +02:00
Daniel Eklöf
360946917c
input: regression test for escape sequence generated for ctrl+shift+tab 2021-05-26 09:13:58 +02:00
Daniel Eklöf
51f7599e91
input: keymap_lookup: remove unused argument ‘seat’ 2021-05-26 09:13:58 +02:00
Daniel Eklöf
058eba33ec
revert: input: do not include consumed modifiers in the set sent to the client
There were two issues with it:

* Not all applications decode the sequence into a set of modifiers +
  key, but use a fixed sequence -> combo mapping, that we broke.

* There were unforeseen issues with e.g. F1-12, where the modifier
  were removed from combos like Ctrl+F12, or Alt+F12. The reason is
  simple; XKB tells us that Ctrl, or Alt, is a consumed modifier. Now,
  _why_ it thinks that is a different story.

This reverts 6cd72bdee6

Closes #425
2021-03-29 20:11:32 +02:00
Daniel Eklöf
0c85905972
input: must have all required modifiers to un-shift a symbol
When detecting, and repairing, “broken” key bindings (where the key
binding itself explicitly lists a modifier that is consumed by the
final symbol - e.g “Shift+W”), don’t just look for an intersection
between the set of modifiers needed to produce the final symbol, and
the modifiers listed in the key combo. Instead, check if the key combo
has *all* the required modifiers.

Example: Shift+AltGr+w produces Page_Down. I.e. Page_Down is the
_shifted_ symbol, ‘w’ is the un-shifted symbol, and Shift+AltGr are
the modifiers required to shift ‘w’ to Page_Down.

If we have the key combo Shift+Page_Down, foot would, correctly,
determine that Page_Down is a shifted symbol. It would find the
Shift+AltGr modifier set, and since the intersection of “Shift+AltGr”
and “Shift” (from our key combo) is non-empty, foot
would (incorrectly) determine that we can, and should, replace
Page_Down with its un-shifted symbol ‘w’.

This is completely wrong, since Shift+w does _not_ produce Page_Down.

Closes #407
2021-03-21 16:22:08 +01:00
Daniel Eklöf
e4f164d958
keymap: handle shift+tab combos correctly, after consuming modifiers
Shift+Tab is an odd bird in XKB; it produces a shifted variant of tab,
ISO_Left_Tab, with Shift being a consumed modifier.

From a terminal perspective, Tab and ISO_Left_Tab are the same key,
with Shift+Tab generating ‘CSI Z’, and all other combos generating a
‘CSI 27;mods;9~’ escape.

Before, when we didn’t filter out consumed modifiers, we could simply
re-use the keymap for Tab when translating ISO_Left_Tab.

This is no longer possible, since shift has been filtered out. As a
result, Shift+Tab no longer generated ‘CSI Z’, but ‘\t’. I.e as if
shift wasn’t being pressed.

This patch adds a separate keymap table for ISO_Left_Tab. It’s MOD_ANY
entry corresponds to Shift+Tab, and emits ‘CSI Z’. All its other
entries *exclude* shift (since it has been consumed), *but*, the
encoded modifier (in the escape sequences) *include* shift.
2021-03-08 20:30:25 +01:00
Daniel Eklöf
6cd72bdee6
input: do not include consumed modifiers in the set sent to the client
When sending a key escape sequence to the client application, do not
include consumed modifiers.

Fixes part of #376
2021-03-08 20:30:23 +01:00
Daniel Eklöf
a5b554761a
input: repair key combos containing both explicit modifier and shifted symbol
If a user-provided key combo contains both an explicit modifier, and
the shifted symbol it produces, replace the symbol with its un-shifted
version.

Example: Control+Shift+U contains both ‘Shift’, and ‘U’, where ‘Shift’
is the modifier that shifts ‘u’ to ‘U’.

Such modifiers are “consumed”, i.e. filtered out, when matching key
combos. As such, Control+Shift+U will never trigger since we’ll never
be able to match the consumed modifier ‘Shift’.

The above combo can be written in two ways:

- Control+U
- Control+Shift+u

To be able to detect that Control+Shift+U is an invalid combination,
we need to check all *shifted* symbols for all key *codes*.

Once we’ve detected a shifted symbol (and where it differs from the
un-shifted symbol), we loop all modifier sets that produce the shift
level where our shifted symbol is. For each such set, check if it
intersects with the user-provided key combo’s modifier set.

If there is an intersection, it means the user provided a key combo
containing a modifier and symbol, such that the modifier is consumed
when the symbol is produced.

In this case, we replace the symbol with its un-shifted version.
2021-03-04 09:43:44 +01:00
Daniel Eklöf
5e64e06a55
input: rewrite of how we match foot’s own key bindings
Bindings are matched in one out of three ways:

* By translated (by XKB) symbols
* By untranslated symbols
* By raw key codes

A translated symbol is affected by pressed modifiers, some of which
can be “consumed”. Consumed modifiers to not partake in the comparison
with the binding’s modifiers. In this mode, ctrl+shift+2 maps to
ctrl+@ on a US layout.

Untranslated symbols, or un-shifted symbols refer to the “base” symbol
of the pressed key, i.e. it’s unaffected by modifiers. In this mode,
consumed modifiers *do* partake in the comparison with the binding’s
modifiers, and ctrl+shift+2 maps to ctrl+shift+2 on a US layout.

More examples: ctrl+shift+u maps to ctrl+U in the translated lookup,
while ctrl+shift+u maps to ctrl+shift+u in the untranslated lookup.

Finally, we also match raw key codes. This allows our bindings to work
using the same physical keys when the user switches between latin and
non-latin layouts.

This means key bindings in foot.ini *must* not include both +shift+
and a *shifted* key. I.e. ctrl+shift+U is not a valid combo as it
cannot be triggered. Unfortunately, this was how you were supposed to
write bindings up until now... so, we try to detect such bindings, log
a deprecation warning and then “fix” the binding for the user.

When specifying bindings in foot.ini, both ctrl+U and ctrl+shift+u are
valid, and will work. The latter is preferred though, since we cannot
detect the raw key code for the former variant. Personally, I also
prefer the latter one because it is more explicit; it’s more obvious
which keys are involved.

However, in some cases it makes more sense to use the other
variant. Typically for non-letter combos.
2021-03-04 09:43:43 +01:00
Daniel Eklöf
decc655d48
input: ask XKB for consumed modifiers, but don’t actually use them just yet 2021-03-04 09:42:36 +01:00
Daniel Eklöf
e9d8ade5cc
input: mutter has been seen sending NULL surfaces in pointer enter 2021-03-04 08:57:31 +01:00
Daniel Eklöf
81b5d476a9
input: exit URLs mode on mouse button events
This makes URLs mode behave like scrollback search mode.
2021-03-04 08:57:03 +01:00
Daniel Eklöf
c7006661f5
url-mode: use ‘jump-label-letters’ as the alphabet for key sequences
Instead of hard coding the alphabet to “sadfjklewcmpgh”, use the
letters from ‘jump-label-letters’.

Closes #355
2021-02-13 11:43:28 +01:00
Craig Barnes
3c86af52c2 Convert all but 2 remaining uses of xassert(false) to BUG("...") 2021-02-10 09:01:51 +00:00
Craig Barnes
2f81a1d07c Convert some more uses of xassert(false) to BUG("...") 2021-02-09 15:16:19 +00:00
Craig Barnes
1ec5684438 Convert some uses of xassert(false) to BUG("some error message") 2021-02-09 13:52:33 +00:00
Daniel Eklöf
03bac9dada
key-bindings: refactor: use a single type for all key bindings
Up until now, the various key binding modes (“normal”, “search” and
“url”) have used their own struct definitions for their key bindings.

The only reason for this was to have a properly typed “action” (using
the appropriate “action” enum).

This caused lots of duplicated code. This patch refactors this to use
a single struct definition for the “unparsed” key bindings handled by
the configuration, and another single definition for “parsed” bindings
used while handling input.

This allows us to implement configuration parsing, keymap translation
and so on using one set of functions, regardless of key binding mode.
2021-02-08 10:09:14 +01:00
Daniel Eklöf
a988138492
url-mode: urls_collect(): URL list pointer as an argument 2021-02-07 16:33:34 +01:00
Daniel Eklöf
2c10a147ea
url-mode: underline URLs using the color from colors.urls
This is implemented by allocating one of the (few!) remaining bits in
the cells’ attribute struct to indicate the cell should be “URL
highlighted”.

render_cell() looks at this bit and draws an underline using the color
from colors.urls (defaults to regular3 - i.e. yellow).

A new function, url_tag_cells(), iterates the currently detected URLs
and sets the new ‘url’ attribute flag on the affected cells.

Note: this is done in a separate function to keep urls_collect() free
from as many dependencies as possible.

urls_reset() is updated to *clear* the ‘url’ flag (and thus implicitly
also results in a grid refresh, _if_ there were any URLs).

We now exit URL mode on *any* client application input. This needs to
be so since we can’t know if the URLs we previously detected are still
valid.
2021-02-07 16:33:34 +01:00
Daniel Eklöf
d6ea2a4bdc
input: mouse events on jump label surfaces do nothing 2021-02-07 16:33:33 +01:00
Daniel Eklöf
93181649b3
config: add show-urls-copy action
This works just like show-urls-launch, except that instead of opening
the URL (typically using xdg-open), it is placed in the clipboard when
activated.
2021-02-07 16:33:32 +01:00
Daniel Eklöf
0a1c5e44c4
config: rename ‘show-urls’ to ‘show-urls-launch’ 2021-02-07 16:33:32 +01:00
Daniel Eklöf
2cc84db979
urls: initial support for detecting URLs and rendering jump-labels
The jump labels work, but is currently hardcoded to use xdg-open
2021-02-07 16:33:31 +01:00
Daniel Eklöf
ee39966ded
config: add infrastructure to handle URL mode specific key bindings
* Add “show-urls” action to regular key bindings
* Add url-bindings section to foot.ini
* Add “cancel” action to URL mode key bindings
2021-02-07 16:33:31 +01:00
Daniel Eklöf
d6b1dbf8d9
input: don’t execute mouse bindings when the application is grabbing the mouse
When the application is grabbing the mouse, we require ‘shift’ to be
pressed to be able to use foot’s mouse bindings. Otherwise the mouse
event is sent to the application.

This wasn’t being enforced consistently; each and every mouse **only**
action was checking the mouse grab state, but e.g. *primary
paste* (which can be used as both a key binding and a mouse binding)
was not.

The fix is actually quite simple: don’t even try to execute *any*
mouse bindings when the application is grabbing the mouse (unless
shift is pressed).

This fixes an issue where e.g. middle mouse button events (using the
default mouse bindings) were never seen by any mouse grabbing client
applications.
2021-02-02 09:52:05 +01:00
Craig Barnes
e56136ce11 debug: rename assert() to xassert(), to avoid clashing with <assert.h> 2021-01-16 20:16:00 +00:00
Daniel Eklöf
67ac09ab2e
input: don’t enable keyboard repeat timer when repeat rate is zero
wayland-client-protocol.h:

  Negative values for either rate or delay are illegal. A rate of
  zero will disable any repeating (regardless of the value of
  delay).

This fixes a division-by-zero crash.
2021-01-16 12:33:59 +01:00
Craig Barnes
3f4cfa338b Add xsnprintf() and remove some unnecessary strlen(3) calls 2021-01-14 21:30:06 +00:00
Daniel Eklöf
767bd4f1db
config: add ‘select-extend-character-wise’ bind action
This forces the (new) selection mode to be character-wise when
extending a word- or line-wise selection.

Default key binding is ctrl+RMB.
2021-01-14 16:29:29 +01:00
Daniel Eklöf
3a9172342f
selection: combine enum selection_kind with selection_semantic 2021-01-06 10:53:27 +01:00