When the surface is destroyed clear it's reference but wait for the up
event to destroy the touch point via wlr_seat_touch_notify_up().
If the surface is destroyed before the up event we end up with
incomplete sequences sent to the client like
[915821.276] wl_touch@3.down(146, 2475027, wl_surface@38, 0, 236.000000, 515.000000)
[915821.608] wl_touch@3.frame()
[915821.637] wl_touch@3.motion(2475027, 0, 236.000000, 515.000000)
[915821.779] wl_touch@3.frame()
so there's never an up event. While it should be something like
[2461229.051] wl_touch@3.down(81, 3236959, wl_surface@34, 0, 218.000000, 478.000000)
[2461229.435] wl_touch@3.frame()
[2461229.484] wl_touch@3.motion(3236959, 0, 218.000000, 478.000000)
[2461229.636] wl_touch@3.frame()
[2461277.520] wl_touch@3.up(82, 3237007, 0)
[2461277.681] wl_touch@3.frame()
this confuses toolkits intepreting the next down event incorrectly. So
don't destroy the touch point too early.
This change tracks, for each wlr_seat_client, the most recent serial
numbers which were sent to the client. When the client makes a
selection request, wlroots now verifies that the serial number
associated with the selection request was actually provided to that
specific client. This ensures that the client that was most
recently interacted with always has priority for its copy selection
requests, and that no other clients can incorrectly use a larger serial
value and "steal" the role of having the copy selection.
Also, the code used to determine when a given selection is superseded
by a newer request uses < instead of <= to allow clients to make
multiple selection requests with the same serial number and have the
last one hold.
To limit memory use, a ring buffer is used to store runs of sequential
serial numbers, and all serial numbers earlier than the start of the
ring buffer are assumed to be valid. Faking very old serials is
unlikely to be disruptive.
Assuming all clients are correctly written, the only additional
constraint which this patch should impose is that serial numbers
are now bound to seats: clients may not receive a serial number
from an input event on one seat and then use that to request
copy-selection on another seat.
atomic and legacy now both pass the backend as the user data for the
pageflip event. We than retrieve the correct connector by matching on
the crtc_id passed to the page_flip_handler2.
Wlroots also requires the DRM_CRTC_IN_VBLANK_EVENT capability now.
Fixes#1297
The backend doesn't need to handle transform changes, since everything is done
in software. In fact, all of the implementations were all identical and just
set the transform.
We could add support for hardware transforms, but:
- This would require a different field (something like hardware_transform)
- Not all combinations are possible because there often are hardware
limitations
- The Wayland protocol isn't ready for this (in particular xdg-output, see [1])
This belongs to a different patch series anyway.
[1]: https://patchwork.freedesktop.org/series/52324/
It can be surprising for callers to stash pending changes, commit, get a
failure, then set some other pending changes, commit again, and get another
failure because of the previously-pending changes.
Instead, make commit reset the pending state on failure.
In addition to `button_count`, we keep track of the current buttons
pressed just as in `wlr_keyboard`.
Add `set_add` and `set_remove` to assist with this. These functions can
only be used with values greater than 0 (such as the button/key masks
for keyboards and pointers).
Partially addresses:
- https://github.com/swaywm/wlroots/issues/1716
- https://github.com/swaywm/wlroots/issues/1593
The DRM subsystem needs a NULL modeset for connectors which disappear
from the system to disable the hardware pipes, otherwise the pixels get
rendered but are sent nowhere.
The atomic backend does the equivalent by removing the properties and
issuing a commit.
Fixes#1706
If mmap fails, it will return MAP_FAILED not NULL. Since the error
handling was incorrectly checking for NULL, MAP_FAILED was being passed
to xkb_keymap_new_from_string, on mmap failure, causing a segfault.
This just fixes the error checking.
If an output is destroyed while an idle_done event is scheduled, it
results in the following Address Sanitizer Output:
==1469==ERROR: AddressSanitizer: heap-use-after-free on address 0x6170000bb668 at pc 0x7f49aaa0c348 bp 0x7ffed5da35b0 sp 0x7ffed5da35a0
WRITE of size 8 at 0x6170000bb668 thread T0
#0 0x7f49aaa0c347 in schedule_done_handle_idle_timer ../subprojects/wlroots/types/wlr_output.c:265
#1 0x7f49aa2f875b in wl_event_loop_dispatch_idle (/usr/lib/libwayland-server.so.0+0xa75b)
#2 0x7f49aa2f8815 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa815)
#3 0x7f49aa2f739b in wl_display_run (/usr/lib/libwayland-server.so.0+0x939b)
#4 0x556622dadd51 in server_run ../sway/server.c:216
#5 0x556622dac25d in main ../sway/main.c:397
#6 0x7f49aa0d0ce2 in __libc_start_main (/usr/lib/libc.so.6+0x23ce2)
#7 0x556622d8d09d in _start (/usr/local/bin/sway+0x3909d)
0x6170000bb668 is located 488 bytes inside of 672-byte region [0x6170000bb480,0x6170000bb720)
freed by thread T0 here:
#0 0x7f49aabc8f89 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:66
#1 0x7f49aa968fc2 in drm_connector_destroy ../subprojects/wlroots/backend/drm/drm.c:829
#2 0x7f49aaa0cc52 in wlr_output_destroy ../subprojects/wlroots/types/wlr_output.c:357
#3 0x7f49aa96d2e9 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1265
#4 0x7f49aa961a59 in drm_invalidated ../subprojects/wlroots/backend/drm/backend.c:135
#5 0x7f49aaa2e1e9 in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#6 0x7f49aa98319f in udev_event ../subprojects/wlroots/backend/session/session.c:52
#7 0x7f49aa2f87f1 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa7f1)
previously allocated by thread T0 here:
#0 0x7f49aabc95a1 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:95
#1 0x7f49aa96b7a2 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1114
#2 0x7f49aa961a59 in drm_invalidated ../subprojects/wlroots/backend/drm/backend.c:135
#3 0x7f49aaa2e1e9 in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#4 0x7f49aa98319f in udev_event ../subprojects/wlroots/backend/session/session.c:52
#5 0x7f49aa2f87f1 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa7f1)
SUMMARY: AddressSanitizer: heap-use-after-free ../subprojects/wlroots/types/wlr_output.c:265 in schedule_done_handle_idle_timer
Shadow bytes around the buggy address:
0x0c2e8000f670: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e8000f680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e8000f690: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e8000f6a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e8000f6b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c2e8000f6c0: fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd
0x0c2e8000f6d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2e8000f6e0: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e8000f6f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e8000f700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2e8000f710: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Remove the idle_done idle timer when the output is destroyed
In order to support compositors running as systemd user units without display manager,
a mechanism for specifying session ID exactly must exist.
Checking for `XDG_SESSION_ID` mimics loginctl behaviour e95be7def2/src/login/loginctl.c (L856).
"/org/freedesktop/login1/seat/self" path triggers seat-finding code path in logind,
which currently relies on getting the session based on caller's PID.
This behaviour is deprecated in logind as it doesn't work eg. with systemd user units,
which run outside of user session.
We check for "seat0" in logind_change_vt() already as introduced in 47985d2dc5,
so hard-coding it here is not a problem, otherwise sd_session_get_seat() could be used.