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.
As long as the mouse button was *pressed* while the pointer was inside
the grid, we want to keep reporting motion events until the button is
released.
Even when the pointer moves outside the grid (but in this case, the
reported coordinates are bounded by the grid size).
This patch also tries to improve multi-button handling (i.e. multiple
buttons pressed at the same time), and the events we report to the
client for these, in the following ways:
* Motion events now report the *initial* button. That is, if you start
a drag operation with the LEFT button, then press RIGHT (before
releasing LEFT), keep reporting LEFT in the motion events.
* Mouse release events are reported for *any* button, as long as the
pointer is *inside* the grid, *or*, the button released was the
button used to start a drag operation.
The last point is important; if we have reported a button press
followed by motion events (i.e. a drag operation), we need to report
the button release, *even* if the pointer is outside the grid.
Note that the client may receive unbalanced button press/release
events in the following ways if the user pressed one, and then a
second button *inside* the grid, then releases the *first*
button (possibly outside the grid), and finally releases the *second*
button *outside* the grid.
In this case, both buttons will report press events. The first button
will report a release event since it is the initial button in the drag
operation.
However, we don’t track the fact that the second button is being
pressed, and thus if it is released outside the grid, it wont generate
a release event.
This is done by allocating cells for the pre-edit text when receiving
the text-input::done() call, and populating them by converting the
utf-8 formatted pre-edit text to wchars.
We also convert the pre-edit cursor position to cell positions (it can
cover multiple cells).
When rendering, we simply render the pre-edit cells on-top off the
regular grid. While doing so, we also mark the underlying, “real”,
cells as dirty, to ensure they are re-rendered when the pre-edit text
is modified or removed.
Don’t require NumLock to be locked. Foot has no idea _which_ modifier
the user has mapped NumLock to, meaning we really cannot require it to
be locked.
wl_output_release, the use of which was recently introduced, is not
available until wl_output interface version 3.
However, only wl_output version 2 was bound. This lead to protocol
errors when a display was disconnected, causing foot to terminate.
Instead, only use wl_output_release if wl_output version 3 is provided
and bound. Otherwise, just use wl_output_destroy.
Closes: https://codeberg.org/dnkl/foot/issues/219
These bindings copy from the clipboard or primary selection into the
search buffer.
Default bindings:
* clipboard-paste: ctrl+v, ctrl+y
* primary-paste: shift+insert
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
Bind to xdg-shell version 2 if available, as this enables us to
track our window’s ‘tiled’ state in the ‘configure’ events.
This in turn allows us to stash the ‘old’ window size when being
tiled, to be used again when restoring the window size when un-tiled.
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).
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.
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.
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.
This can be set to 'none' (the default), 'osd', 'log' or 'both'.
When 'osd' is enabled, we'll render the frame rendering time to a
sub-surface after each frame.
When 'log' is enabled, the frame rendering time is logged on stderr.
When enabled, the mouse cursor is hidden when the user types in the
terminal. It is un-hidden when the user moves the mouse, or when the
window loses keyboard focus.
This allows us to detect syntax errors early on, and is also more
efficient since we don't have to re-tokenize the command line every
time the binding is executed.
Previously, we calculated the monitors horizontal and vertical PPI
values.
For font sizing, we used the vertical PPI value. It seems however,
that using the diagonal PPI value, i.e. diagonal_px / diagonal_inch,
gives more consistent results.
This is still a PPI value, but since it is intended to be used as a
FontConfig DPI value, name it 'dpi'.
* xcursor always set for all pointers
* xcursor sometimes not updated when it should be
* mouse grabbed state wasn't per seat, but global (i.e. "does at least
one seat enable mouse grabbing")
* selection enabled state wasn't per seat
Previously, we triggered a theme reload on output changes. This is
completely wrong. We may get a new output with a scale different from
the output the pointer is actually on.
Now, we store the current scale along with the theme. We then trigger
a call to reload the xcursor theme *every* time the pointer enters a
surface. When it does, we use the current scale factor of the terminal
that owns that surface.
If the terminal covers multiple outputs, with different scale factors,
we'll use the largest scale factor. This may not be 100% correct. But
to fix that, we'd need to track which regions of a surface are mapped
on which outputs. Too complicated I say.
That is, deal with monitors being unplugged.
At least on Sway 1.4, surfaces are not unmapped before the output is
removed. Thus, in addition to free:ing the monitor resources, we also
need to update all terminals that are mapped on this output - remove
the output from their "mapped on" list.
Before, we converted each axis event's scroll amount to an integer and
scrolled that many lines.
However, axis events are speed sensitive - very slow scrolling will
result in events with a scroll amount that is < 1.0.
For us, this meant we never scrolled a single line. You could slow
scroll all day if you wanted, and still we would never scroll a single
line.
Fix this by aggregating the scroll amount from axis events until the
scroll amount is > 1.0, and then scroll.
They aren't really user configurable. At least not yet.
However, with this, we now handle raw key codes just like the normal
key bindings. Meaning, e.g. ctrl+g, ctrl+a, ctrl+e etc now works while
searching with e.g. a russian layout.
Before, when looking for a matching user key binding, we only
matched *symbols*.
This means that the physical keys that generate a specific key binding
is layout dependent. What's worse, it may not even be possible to
generate the key binding at all.
Russian is one such layout, where all the "normal" (us) symbols are
replaced.
By using raw key codes, we can get around this - the key code has a
direct mapping to the physical key.
However, matching raw key codes **only** doesn't always make sense
either. For now, match **both** symbols _and_ key codes. Symbols take
precedence.
TODO: we might have to make this configurable _per binding_.
Note: 'search' mode still uses mostly hardcoded shortcuts that still
have this problem (i.e. ctrl+g doesn't work with a russian layout).
This way we:
* Don't have to call wl_display_get_fd() all the time
* No longer call fdm_del_no_close() even though the FD hasn't been
added to the FDM.