This change allows the tablet tool button to be used for floating mod
resize. In addition, it attempts to ensure that tablet tool events are
consistent such that tablet v2 events and pointer events will never be
interleaved, and such that the tool buttons count will never fall out of
sync and cause tool button emulation to break.
Some of this logic is similar to what is done for tablet tool tip, but
not quite identical, because of the complication that we have to deal
with multiple inputs that can overlap eachother.
Fixes#7036.
This might be the wrong fix, but the crash is happening because the ->data
field on an xwayland surface is NULL. A NULL data field is normal for
unmanaged surfaces, however it seems clients can do weird things: They can
create a cursor lock on a regular xwayland surface then make it unmanaged
by calling override_redirect. In this case, the xwayland server should
destroy the cursor lock, which is does, but does so in the wrong order
making it try to dereference a NULL pointer after sway has acknowledged
its new unmanaged status.
```
(gdb) bt full
0 0x000055fd91934861 in warp_to_constraint_cursor_hint (cursor=0x55fd93486c00)
at ../sway/input/cursor.c:1243
sy = 605
lx = 6.9527431433545762e-310
sx = 1272
view = 0x0
con = 0x7ffd1cdfe400
ly = -6.949595189996421e+59
constraint = 0x55fd93e7faa0
1 0x000055fd91934976 in handle_constraint_destroy (listener=0x55fd93f0fd58, data=0x55fd93e7faa0)
at ../sway/input/cursor.c:1266
sway_constraint = 0x55fd93f0fd30
constraint = 0x55fd93e7faa0
cursor = 0x55fd93486c00
2 0x00007fda8275bf6e in wl_signal_emit_mutable () at /usr/lib/libwayland-server.so.0
3 0x00007fda82e57016 in pointer_constraint_destroy (constraint=0x55fd93e7faa0)
at ../subprojects/wlroots/types/wlr_pointer_constraints_v1.c:49
4 0x00007fda82e570dc in pointer_constraint_destroy_resource (resource=0x55fd933cf8f0)
at ../subprojects/wlroots/types/wlr_pointer_constraints_v1.c:66
constraint = 0x55fd93e7faa0
5 0x00007fda8275d8ba in () at /usr/lib/libwayland-server.so.0
6 0x00007fda8275f6a9 in wl_resource_destroy () at /usr/lib/libwayland-server.so.0
7 0x00007fda82e56fb3 in resource_destroy (client=0x55fd93ea52e0, resource=0x55fd933cf8f0)
at ../subprojects/wlroots/types/wlr_pointer_constraints_v1.c:39
8 0x00007fda81d8f4f6 in () at /usr/lib/libffi.so.8
9 0x00007fda81d8bf5e in () at /usr/lib/libffi.so.8
10 0x00007fda81d8eb73 in ffi_call () at /usr/lib/libffi.so.8
11 0x00007fda8275aada in () at /usr/lib/libwayland-server.so.0
12 0x00007fda8275f01c in () at /usr/lib/libwayland-server.so.0
13 0x00007fda8275d9e2 in wl_event_loop_dispatch () at /usr/lib/libwayland-server.so.0
14 0x00007fda8275e197 in wl_display_run () at /usr/lib/libwayland-server.so.0
15 0x000055fd919264d3 in server_run (server=0x55fd919a3a80 <server>) at ../sway/server.c:320
16 0x000055fd91925457 in main (argc=1, argv=0x7ffd1cdfed98) at ../sway/main.c:411
verbose = false
debug = false
validate = false
allow_unsupported_gpu = false
config_path = 0x0
c = -1
```
sway sends wl_keyboard.enter on seat focus change and when a keyboard
active on a seat is configured. If all keyboards are removed and a
keyboard is added back without changing the focused client, no new
notify event would be sent despite having keyboard focus. This could
lead to key events without notify, which is a protocol violation.
As a quick fix, when configuring a keyboard on a seat where no keyboard
is currently active, activate the keyboard so that a focused surface
will receive a notify event.
Regressed by: e1b268af98
Closes: https://github.com/swaywm/sway/issues/7330
When we reload the config, we reset every input device and re-apply
configuration from the config file. This means that the keyboard keymap
is updated at least once during config reload, more if the config file
contains keyboard configuration.
When they keyboard keymap changes and is updated through wlr_seat, the
keymap ends up sent to every keyboard bound in every client, seemingly
multiple times. On an x230 of mine with a keyboard layout set in the
config file, I see 42 keymap events sent to foot on config reload.
Reduce events from keyboard configurations by skipping all but the
currently active keyboard for the seat, and by clearing the active
keyboard during input manager device reset. After this change, I only
see a single just-in-time keymap event.
Fixes: https://github.com/swaywm/sway/issues/6654
Support the new dwtp (disable while trackpointing) option introduced in
libinput 1.21, allowing users to control whether the trackpoint (like
those in Thinkpads, but not only) should be disabled while using the
keyboard/touchpad.
See: https://gitlab.freedesktop.org/libinput/libinput/-/issues/731
Remove the incorrect attempt to block focus changes when an input grab
is present and replace it with the same logic used for layer_shell-based
screen lockers: restore the focus after changing it.
This fixes a use-after-free of seat->workspace if outputs are destroyed
while a screen lock is enabled.
When removing outputs, it is possible to end up in a situation where
none of the session lock client's surfaces have keyboard focus,
resulting in it not receiving keyboard events. Track the focused
surface and update it as needed on surface destroy.
Sway focuses the inactive child when focusing split containers. However,
there is currently no way to focus the parent container itself by mouse.
A user must use the keyboard to do so.
This commit maintains the current behavior, but makes it such that a
second click on the split container titlebar (i.e., after its children
are visible) focuses the split container itself.
active_keyboard may be NULL, in which case an invalid pointer could be
passed to wlr_input_method_keyboard_grab_v2_send_modifiers. This
procedure call is unnecessary since wlroots commit 372a52ec "input
method: send modifiers in set_keyboard", so the call can simply be
removed.
Fixes#6836.
We currently track the focus of a seat in two ways: we use a list called
focus_stack to track the order in which nodes have been focused, with
the first node representing what's currently focused, and we use a
variable called has_focus to indicate whether anything has focus--i.e.
whether we should actually treat that first node as focused at any given
time.
In a number of places, we treat has_focus as implying that a focused
node exists. If it's true, we attempt to dereference the return value of
seat_get_focus(), our helper function for getting the first node in
focus_list, with no further checks. But this isn't quite correct with
the current implementation of seat_get_focus(): not only does it return
NULL when has_focus is false, it also returns NULL when focus_stack
contains no items.
In most cases, focus_stack never becomes empty and so this doesn't
matter at all. Since focus_stack stores a history of focused nodes, we
rarely remove nodes from it. The exception to this is when a node itself
goes away. In that case, we call seat_node_destroy() to remove it from
focus_stack and free it. But we don't unset has_focus if we've removed
the final node! This lets us get into a state where has_focus is true
but seat_get_focus() returns NULL, leading to a segfault when we try to
dereference it.
Fix the issue both by updating has_focus in seat_node_destroy() and by
adding an assertion in seat_get_focus() that ensures focus_stack and
has_focus are in sync, which will make it easier to track down similar
issues in the future.
Fixes#6395.
[1] There's some discussion in #1585 from when this was implemented
about whether has_focus is actually necessary; it's possible we could
remove it entirely, but for the moment this is the architecture we have.
previously, fullscreen global containers would grab cursor input
even if a shell-layer surface was on top of it
related issue: https://github.com/swaywm/sway/issues/6501
Adds detection code to handle pci-*-platform-* strings
in ID_PATH
References: https://github.com/swaywm/sway/issues/6590
Signed-off-by: Jari Ronkainen <ronchaine@gmail.com>
If the surface the pointer started to interact with is destroyed we also
want the seatop_down to end. In case a drag is initiated we receive a
call to handle_end.
This solves an issue where layer-shell items would not receive a button
release event when the pointer left them while being pressed. The
default seatop changes focus immediately while seatop_down defers any
focus changes until the pointer is released or seatop_down is destroyed.
Losing the precision resulted in wlr_cursor and wlr_seat::pointer_state
getting out of sync during pointer motion in seatop_down.
Since the difference was always under 1 px, it was practically
impossible to notice in normal use.
But because of being out of sync, cursor_rebase would always end up
incorrectly calling wlr_seat_pointer_notify_motion from
seatop_default_begin (on releasing mouse button) which broke cursor
locking.
See #5405Closes#4632
When emulating touch, the simulating_pointer_from_touch field is
set to true. It's switched back to false when a touch_up event is
received. However we need to ensure we always send a wl_pointer.frame
event following a group of other wl_pointer events.
Since a touch_frame event is always guaranteed to come after a group
of touch events, unset simulating_pointer_from_touch in the touch_frame
handler instead of the touch_up handler. Add a new field to know whether
the touch_frame handler should stop emulation.
get_current_time_msec is only used in cursor.c, so we can move it in and
make it static. This is primarily intended to avoid a symbol collision
with wlroots, which we unfortunately do not have a good solution for
yet.
Implements functionality described in [1]. Please see the issue for a
video with a demonstration of the new behavior.
An issue is that titlebars cover up a significant portion of the top
edge drop area. The solution is simply to change the edge drop area
hitbox to start at the contents instead of the container.
[1] https://github.com/swaywm/sway/issues/6218
When issuing a focus command on a specific container, users expect to
proceed it even if is hidden by a fullscreen window.
This matches the behavior of i3.
Pending state is currently inlined directly in the container struct,
while the current state is in a state struct. A side-effect of this is
that it is not immediately obvious that pending double-buffered state is
accessed, nor is it obvious what state is double-buffered.
Instead, use the state struct for both current and pending.
Every seat_set_focus* should be followed by a transaction_commit_dirty.
In cases where the focus change is followed by a seatop_begin* this is
not needed, as transaction_commit_dirty is then called by the
seatop_begin* function.
Fixes#6034
Before this commit, there would be cases where focus changes from one
window to another, the new window activates text_input, then the old
window sends a deactivate request, making text_input unfocused
completely.
There is no need to check for transactions at the end of every user
input, as the vast majority of input will not issue transactions. This
implementation can also hide where changes are made without an
appropriate transaction commit, as a future unrelated input would issue
the commit instead.
Instead, commit transactions in places where changes are made or are
likely to be made.
In i3, the workspace_layout command does not affect the
workspace layout. Instead, new workspace level containers
are wrapped in the desired layout and the workspace layout
always defaults to the output orientation.
The keyboard group's effective keyboard layout was never being changed
due to a condition that incorrectly preventing it from being performed.
The IPC event that follows the change was correctly being prevented.
To query whether a container is sticky, checking `con->is_sticky` is
insufficient. `container_is_floating_or_child` must also return true;
this led to a lot of repetition.
This commit introduces `container_is_sticky[_or_child]` functions, and
switches all stickiness checks to use them. (Including ones where the
container is already known to be floating, for consistency.)
Previously, `find_edge` on a single fullscreen view would occasionally
return an edge rather than `WLR_EDGE_NONE`. This would trigger entry
into `seatop_resize_tiling`, which doesn't have meaning for a fullscreen
view.
The result was that the fullscreen container hitbox was considered to be
that of where it'd be if it were tiling, so most clicks would not go
through.
Fixes#5792.
When scrolling on a tabbed/stacked container, i3 focuses its
inactive-focused focused child. Sway does the same, but then resets the
focus to whatever was focused previously.
Ref e5992eed16/src/click.c (L207-L219)
We can't arm the timer during cursor creation since the config may not
be ready yet. Instead arm the timer while applying the input
configuration, by this time the configuration has been parsed and we can
arm the hide timer.
Fixes#5686
According to the wayland docs, wayland timers are disarmed on creation.
This leads to the cursor not being hidden if there is no activity after
creation, since the timer is armed on activity, but not at creation.
Arm the timer after creation to ensure the cursor is hidden even if
there is no cursor activity after creation.
Fixes#5684
Reset the event source after unhiding the cursor, to ensure that the
timeout starts after showing the cursor. Also remove the open coded
variant in seat_consider_warp_to_focus().
Fixes#5679
This changes it so all libinput config options are set on any device
that supports it. Previously, only a subset of libinput config options
were being considered depending on the input type. Instead of trying to
guess which properties the device may support, attempt to set any
configured property regardless of the device type. All of the functions
already have early returns in them for when the device does not actually
support the property. This brings the configuration side inline with
describe_libinput_device for the IPC side. This change was prompted
by a tablet tool showing the calibration matrix property in the IPC
message, but not being able to actually change it since that property
was only being considered for the touch input type.
On warping to a cursor hint, update the pointer position we track as
well, so that on the next pointer rebase we don't send an unexpected
synthetic motion event to clients.
Fixes#5405.
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.
An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.
We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).
Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.
[1]: https://github.com/swaywm/sway/pull/5521
Closes: https://github.com/swaywm/sway/issues/5483
As per the Wayland spec [1]:
> The icon surface is an optional (can be NULL) surface that provides an
> icon to be moved around with the cursor.
However, as of now Sway "start_drag" signal handler does not starts the
DND session unless a non-NULL drag icons is provided. This patch fixes
it by skipping handling of the drag icon if it is null.
Fixes#5509
[1] https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_data_device
Signed-off-by: Nick Diego Yamane <nickdiego@igalia.com>
wlr_drag installs grabs for the full duration of the drag, leading to
the drag target not being focused when the drag ends. This leads to
unexpected focus behavior, especially for the keyboard which requires
toggling focus away and back to set.
We can only fix the focus once the grabs are released, so refocus the
seat when the wlr_drag destroy event is received.
Closes: https://github.com/swaywm/sway/issues/5116