It was completely wrong: according to the protocol, the effective
geometry is only updated on commit time if there pending state has
new state from xdg_surface.set_window_geometry or
xdg_surface.set_window_geometry has never been sent at all.
This commit adds wlr_xdg_surface.geometry which correctly matches the
effective window geometry and removes now-useless
wlr_xdg_surface_get_geometry().
When pressing the keybinding to shut down the compositor, the following
use-after-free is triggered:
==1165966==ERROR: AddressSanitizer: heap-use-after-free on address 0x51800000ade0 at pc 0x7fa6728b4531 bp 0x7ffe540a6aa0 sp 0x7ffe540a6a90
READ of size 8 at 0x51800000ade0 thread T0
#0 0x7fa6728b4530 in wlr_seat_set_keyboard ../types/seat/wlr_seat_keyboard.c:124
#1 0x58a83fa7fd4e in keyboard_handle_key ../tinywl/tinywl.c:228
#2 0x7fa673a1901d in wl_signal_emit_mutable (/usr/lib/libwayland-server.so.0+0xa01d) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19)
#3 0x7fa67295b4be in wlr_keyboard_notify_key ../types/wlr_keyboard.c:102
#4 0x7fa67295c791 in wlr_keyboard_finish ../types/wlr_keyboard.c:165
#5 0x7fa672848cb1 in destroy_wl_seat ../backend/wayland/seat.c:293
#6 0x7fa672833dca in backend_destroy ../backend/wayland/backend.c:493
#7 0x7fa6727b49e8 in wlr_backend_destroy ../backend/backend.c:67
#8 0x7fa67282d334 in multi_backend_destroy ../backend/multi/backend.c:59
#9 0x7fa67282da5a in handle_event_loop_destroy ../backend/multi/backend.c:110
#10 0x7fa673a18b98 in wl_event_loop_destroy (/usr/lib/libwayland-server.so.0+0x9b98) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19)
#11 0x7fa673a1b43c in wl_display_destroy (/usr/lib/libwayland-server.so.0+0xc43c) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19)
#12 0x58a83fa8ada1 in main ../tinywl/tinywl.c:1068
#13 0x7fa672043ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#14 0x7fa672043d89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#15 0x58a83fa7e7c4 in _start (/home/simon/src/wlroots/build/tinywl/tinywl+0x167c4) (BuildId: 1febf2a5a18bda0f6b67377a132484061875e248)
0x51800000ade0 is located 352 bytes inside of 880-byte region [0x51800000ac80,0x51800000aff0)
freed by thread T0 here:
#0 0x7fa6732dfdb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7fa6728c6a1e in wlr_seat_destroy ../types/seat/wlr_seat.c:245
#2 0x7fa6728c6a7a in handle_display_destroy ../types/seat/wlr_seat.c:251
#3 0x7fa673a1b3c6 in wl_display_destroy (/usr/lib/libwayland-server.so.0+0xc3c6) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19)
previously allocated by thread T0 here:
#0 0x7fa6732e0cc1 in __interceptor_calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7fa6728c6a9d in wlr_seat_create ../types/seat/wlr_seat.c:255
#2 0x58a83fa8a8d3 in main ../tinywl/tinywl.c:1024
#3 0x7fa672043ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
This happens because the wlr_seat is destroyed before the
wlr_keyboard. Destroying the wlr_keyboard has the side effect of
implicitly releasing keys currently held down.
Explicitly destroying the wlr_backend before the wl_display fixes
this.
Suggested-by: Isaac Freund <ifreund@ifreund.xyz>
Stop trying to maintain a per-file _POSIX_C_SOURCE. Instead,
require POSIX.1-2008 globally. A lot of core source files depend
on that already.
Some care must be taken on a few select files where we need a bit
more than POSIX. Some files need XSI extensions (_XOPEN_SOURCE) and
some files need BSD extensions (_DEFAULT_SOURCE). In both cases,
these feature test macros imply _POSIX_C_SOURCE. Make sure to not
define both these macros and _POSIX_C_SOURCE explicitly to avoid
POSIX requirement conflicts (e.g. _POSIX_C_SOURCE says POSIX.1-2001
but _XOPEN_SOURCE says POSIX.1-2008).
Additionally, there is one special case in render/vulkan/vulkan.c.
That file needs major()/minor(), and these are system-specific.
On FreeBSD, _POSIX_C_SOURCE hides system-specific symbols so we need
to make sure it's not defined for this file. On Linux, we can
explicitly include <sys/sysmacros.h> and ensure that apart from
symbols defined there the file only uses POSIX toys.
Compositors now are expected to wait for an initial commit by checking
wlr_xdg_surface.initial_commit on every surface commit and send
(schedule) configure events manually.
This commit changes the behavior of `new_*` signals to better match
their names (see https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3608).
wlr_xdg_shell.events.new_surface is now emitted when an xdg_surface is
created, and wlr_xdg_shell.events.new_{toplevel,popup} events are
introduced to get notified when an xdg_{toplevel,popup} is created.
Same applies to
`wlr_xdg_decoration_manager_v1.events.new_toplevel_decoration`. As a
result, wlr_xdg_surface.added and wlr_xdg_toplevel_decoration_v1.added
are removed, as we no longer need to track whether the corresponding
event was emitted.
Additionally, this commit changes the behavior of
wlr_xdg_surface.events.destroy: it is now emitted when the xdg_surface
is destroyed, as the name suggests.
wlr_xdg_{toplevel,popup}.events.destroy events are added to get
notified when an xdg_{toplevel,popup} is destroyed.
"View" has been cargo-culted from Weston. In Weston, a view is not
even necessarily a toplevel -- it's just a way to draw an arbitrary
somewhere (a surface may be painted at multiple locations
simultaneously). The Weston concept has been misunderstood and then
was carried over to rootston, Sway, and tinywl.
Let's just use the official Wayland wording instead.
This changes the semantics of wlr_output_state. Instead of having
fields with uninitialized memory when missing from the committed
bitflag, all fields are always initialized (and maybe NULL/empty),
just like we do in wlr_surface_state. This reduces the chances of
footguns when reading a field, and removes the need to check for
the committed bitfield everywhere.
A new wlr_output_state_init() function takes care of initializing
the Pixman region.
Up until now, wlr_backend_autocreate() created the wlr_session and
then stuffed it into struct wlr_multi_backend so that compositors
can grab it later.
This is an abuse of wlr_multi_backend and the wlr_backend API:
wlr_backend_get_session() and wlr_multi_backend.session only exist
to accomodate the needs of wlr_backend_autocreate(). What's more,
the DRM and libinput backends don't implement
wlr_backend_impl.get_session.
Instead, return the struct wlr_session to the compositor in the
wlr_backend_autocreate() call. wlr_backend_get_session() will be
removed in the next commit.