This commit renames map/unmap listeners to clarify that they handle
subsurface events, and ensures the node is always destroyed before
the subsurface.
Without this patch, wl_list_remove() would operate on listener links in
already freed memory. glibc is usually lenient to bugs like this, but
musl isn't.
Allows the compositor to submit tokens to the pool of
currently active tokens. This can be useful when the
launcher doesn't use or support xdg-activation-v1 by
itself - e.g. when it is X11 based or use gtk_shell1.
This doesn't work if scene outputs are not used as the primary output of
scene surfaces will always be NULL.
Therefore, take a wlr_scene_output instead of separate wlr_scene and
wlr_output arguments and rename the function to
wlr_scene_output_send_frame_done().
The actual behavior of the function is unchanged.
This allows compositors to avoid sending multiple frame done events
to a surface that is rendered on multiple outputs at once. This may
also be used in the same way for presentation feedback.
wlroots picks names for all outputs, but it might be desirable for
compositor to override it.
For instance, Sway will use a headless output as a fallback in
case no outputs are connected. Sway wants to clearly label the
fallback output as such and label "real" headless outputs starting
from HEADLESS-1.
Implement a basic version of linux-dmabuf-unstable-v1 version 4.
Only default hints are implemented.
The new wlr_linux_dmabuf_feedback_v1 data structure will allow
compositors to define their own custom hints in the future. This
data structure makes it easy to describe feedback metadata.
It's converted to a "compiled" form suitable for marshalling over
the Wayland socket via feedback_compile.
This allows output commit listeners to access the newly committed
buffer. Currently wlr_output.front_buffer is used but it'll get
removed in the next commit.
DRM formats with an empty modifier list are invalid. Instead of
emptying the list, reduce it to { INVALID }.
Add a check to make sure the renderer and backend support implicit
modifiers, so that we don't fallback on e.g. Vulkan.
Closes: https://github.com/swaywm/sway/issues/6692
This allows getting a wlr_scene_output from a wlr_output. Since an
output can only be added once to a scene-graph there's no ambiguity.
This is useful for compositors using wlr_scene_attach_output_layout:
the output layout integration automatically creates a scene-graph
output for each wlr_output added to the layout.
This allows compositors to get primary formats without manually
calling wlr_output_impl.get_primary_formats.
For example, the Sway patch for linux-dmabuf feedback [1] needs
this.
[1]: https://github.com/swaywm/sway/pull/6313
Sometimes we were calling wlr_output_impl.set_cursor with a NULL
buffer, but we weren't clearing wlr_output.cursor_front_buffer.
Avoid leaving a dangling buffer behind.
Introduce a helper function output_set_hardware_cursor which calls
wlr_output_impl.set_cursor and keeps cursor_front_buffer in sync.
The implicit check to filter out LINEAR for dmabuf checked for INVALID
twice instead of checking for INVALID & LINEAR. Fix this.
Fixes: d37eb5c2ea ("linux-dmabuf-v1: filter out LINEAR if implicit")
Reported-by: Dawid Czeluśniak <czelusniakdawid@gmail.com>
If only INVALID and LINEAR are valid modifiers, we need to filter out
LINEAR since Xwayland won't be able to allocate a BO with the explicit
linear modifier on hardware that does not support explicit modifiers.
The addition of LINEAR is an internal implementation detail which
simplifies the wlroots architecture for now.
Evntually Xwayland should be fixed to filter out modifiers that are not
supported by the GBM implementation, see [1]. This could be done by
querying EGL for the supported modifiers.
[1]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1166
This allows compositors to easily add an xdg_surface to the
scene-graph while retaining the ability to unconstraint popups
and decide their final position.
Compositors can handle new popups with the wlr_xdg_shell.new_surface
event, get the parent scene-graph node via wlr_xdg_popup.parent.data,
create a new scene-graph node via wlr_scene_xdg_surface_tree_create,
and unconstraint the popup if they want to.
The parameters are used when the client is in the process of
building a buffer. There's no reason why this internal
implementation detail should be exposed in our public header.
All graphics drivers supporting cursor planes support ARGB8888,
the default cursor format, so this fallback is almost certainly
unused.
Essentially all cursor themes use alpha transparency to make it
clearer where relative to the screen content the cursor hotspot is.
It is better to fall back to a slightly slower software cursor than
it is to fall back to the opaque square that is a hardware cursor
without an alpha channel.
This change introduces new double buffered state to the wlr_output,
corresponding to the buffer format to render to.
The format being rendered to does not control the bit depth of colors
being sent to the display; it does generally determine the format with
which screenshot data is provided. The DRM backend _may_ sent higher
bit depths if the render format depth is increased, but hardware and
other limitations may apply.
Most (and possibly all) compositors using wlroots only ever render
fully opaque content. To provide better performance, this change
switches the default format used by wlr_output buffers from
ARGB8888 to the opaque XRGB8888.
Compositors like mutter, kwin, and weston already default to
XRGB8888, so this change is unlikely to expose any new bugs in
underlying drivers and hardware.
This does not affect the hardware cursor's buffer format, which is
still ARGB8888 by default.
As part of this change, the X11 backend (which does not support
changing format at runtime) now picks a true color, 24 bit depth
visual (i.e. XRGB8888) instead of a 32 bit depth (ARGB8888) one.
This makes it possible for the two functions using output_pick_format
(output_pick_cursor_format and output_create_swapchain) to select
different buffer formats.
The backend and renderer don't directly interact together, so there's
no point in checking that their buffer caps intersect. What we want to
check is that:
- The backend and allocator buffer caps are compatible, because the
backend consumes buffers to display them.
- The renderer and allocator buffer caps are compatible, because the
renderer imports buffers to sample them or render to them.
For instance, when running with the DRM backend and the Pixman renderer,
the (backend & renderer) check will fail because backend = DMABUF and
renderer = DATA_PTR.
They are never used in practice, which makes all of our flag
handling effectively dead code. Also, APIs such as KMS don't
provide a good way to deal with the flags. Let's just fail the
DMA-BUF import when clients provide flags.
We were send a protocol error if INTERLACED or BOTTOM_FIRST was
set. This is incorrect for the zwp_linux_dmabuf_params.create
code-path because this kills the client without allowing it to
gracefully handle the error.
We should only send a protocol error if the client provides a bit
not listed in the protocol definition.
The protocol uses a signed integer here, which is also what the
wlr_input_method_v2_preedit_string struct provides to compositors from
the input method protocol. Sway currently just passes those int32_t
values directly to this function leading to an implicit conversion.
The data field is useful to track metadata about a token. The destroy
events are useful for compositors that track application startup to
let them know they can stop doing that.
These new functions allow a compositor to request new managed tokens
without participating in the xdg-activation procedure as a wayland
client.
This enables the compositor itself to behave as a launcher
application.
Variables on the stack are released when the parent block is closed.
Here, `now` is used outside of the `if` block, causing the following
crash when starting Sway with the headless backend:
==49606==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fff94645f90 at pc 0x5558aeae9e29 bp 0x7fff94645df0 sp 0x7fff94645de0
READ of size 16 at 0x7fff94645f90 thread T0
#0 0x5558aeae9e28 in handle_present ../sway/desktop/output.c:834
#1 0x7fdc8d6792fb in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#2 0x7fdc8d54f77f in wlr_output_send_present ../subprojects/wlroots/types/output/output.c:766
#3 0x7fdc8d524a28 in output_commit ../subprojects/wlroots/backend/headless/output.c:71
#4 0x7fdc8d54d2db in wlr_output_commit ../subprojects/wlroots/types/output/output.c:629
#5 0x5558aeb013cb in output_render ../sway/desktop/render.c:1157
#6 0x5558aeae549e in output_repaint_timer_handler ../sway/desktop/output.c:544
#7 0x5558aeae5f8a in damage_handle_frame ../sway/desktop/output.c:606
#8 0x7fdc8d6792fb in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#9 0x7fdc8d6007d5 in output_handle_frame ../subprojects/wlroots/types/wlr_output_damage.c:44
#10 0x7fdc8d6792fb in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#11 0x7fdc8d54ee84 in wlr_output_send_frame ../subprojects/wlroots/types/output/output.c:720
#12 0x7fdc8d54efc3 in schedule_frame_handle_idle_timer ../subprojects/wlroots/types/output/output.c:728
#13 0x7fdc8c9dcf5a in wl_event_loop_dispatch_idle (/usr/lib/libwayland-server.so.0+0xaf5a)
#14 0x7fdc8c9dcfb4 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xafb4)
#15 0x7fdc8c9dabc6 in wl_display_run (/usr/lib/libwayland-server.so.0+0x8bc6)
#16 0x5558aeac8e30 in server_run ../sway/server.c:285
#17 0x5558aeac3c7d in main ../sway/main.c:396
#18 0x7fdc8be35b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#19 0x5558aea8686d in _start (/home/simon/src/sway/build/sway/sway+0x33f86d)
If the output is destroyed after capture_output but before
frame_handle_copy, it'll have a dangling output pointer. Add the
output destroy listener in capture_output.
Closes: https://github.com/swaywm/wlroots/issues/3284
This is only called from one function.
To destroy the wlr_scene_subsurface_tree from elsewhere, callers
can destroy the scene-graph node returned by
wlr_scene_subsurface_tree_create instead (just like a compositor
would do). subsurface_tree_handle_surface_destroy does exactly this.
Inlining avoids calling subsurface_tree_destroy by mistake.
This organizes the wlr_output implementation into separate files.
This avoids having a single mega-file with lots of unrelated parts
and makes it more obvious what the interactions between all the
parts are.
No functional changes, just moving code around.
Currently these functions remove the node from the scene if the sibling
argument is the same node as the node. To prevent confusion when
misusing this API, assert that the nodes are distinct and document this.
These functions are used mostly for rendering, where including unmapped
surfaces is undesired.
This is a breaking change. However, few to no usages will have to be
updated.
struct wlr_xdg_surface_state is introduced to hold the geometry
and configure serial to be applied on next wl_surface.commit.
This commit fixes our handling for ack_configure: instead of making
the request mutate our current state, it mutates the pending state
only.
Co-authored-by: Simon Ser <contact@emersion.fr>
As touchpad touches are generally fully abstracted, a client cannot
currently know when a user is interacting with the touchpad without
moving. This is solved by hold gestures.
Hold gestures are notifications about one or more fingers being held
down on the touchpad without significant movement.
Hold gestures are primarily designed for two interactions:
- Hold to interact: where a hold gesture is active for some time a
menu could pop up, some object could be selected, etc.
- Hold to cancel: where e.g. kinetic scrolling is currently active,
the start of a hold gesture can be used to stop the scroll.
Unlike swipe and pinch, hold gestures, by definition, do not have
movement, so there is no need for an "update" stage in the gesture.
Create two structs, wlr_event_pointer_hold_begin and
wlr_event_pointer_hold_end, to represent hold gesture events and the
signals to emit them: wlr_pointer->pointer.hold_begin/hold_end.
This allows the compiler to error out if we haven't enumerated all
of the cases. This is useful to avoid a missing implementation when
adding a new node type.
This commit removes any checks whether a configure will change anything
and makes configures be sent unconditionally. Additionally, configures
are scheduled on xdg_toplevel.{un,}set_{maximized,fullscreen} events.
Previously, `wlr_xdg_toplevel` didn't follow the usual "current state +
pending state" pattern and instead had confusingly named
`client_pending` and `server_pending`. This commit removes them, and
instead introduces `wlr_xdg_toplevel.scheduled` to store the properties
that are yet to be sent to a client, and `wlr_xdg_toplevel.requested`
to store the properties that a client has requested. They have different
types to emphasize that they aren't actual states.
This allows callers to specify the operations they'll perform on
the returned data pointer. The motivations for this are:
- The upcoming Linux MAP_NOSIGBUS flag may only be usable on
read-only mappings.
- gbm_bo_map with GBM_BO_TRANSFER_READ hurts performance.
This will allow more scene-graph extensions to be added without
cluttering wlr_scene.c, for instance for sub-surface handling and
wlr_output_layout integration.
When providing non-zero layout-local coordinates to
wlr_scene_render_output, the viewport should be translated by the
given values. However the viewport was translated by the opposite
values: when giving 42,42 the viewport's position would be set to
-42,-42.
On modeset wlr_output will internally allocate a buffer. The
backend will emit a "mode" output event, then wlr_output will
emit a "commit" event.
wlr_output_damage handles the "mode" event by damaging the whole
output, and then handles the "commit" event. However the commit
event has a buffer, so wlr_output_damage rotates the damage in its
ring buffer, thinking the compositor has rendered a frame. The
compositor hasn't rendered a frame, what wlr_output_damage sees is
the internal wlr_output black buffer used for the modeset.
Let's fix this by damaging the whole output in the "commit" event
handler if the mode has changed. Additionally, damage the whole
output after rotating the damage ring buffer.
Caching frame callback lists is actually the correct behavior, because
if a surface is locked because of e.g. subsurface synchronization,
clients would expect to receive frame done events only after the
pending state is actually committed.
With the addition of a non-surface node type, it was unclear how such
nodes should interact with scene_node_surface_at(). For example, if the
topmost node at the given point is a RECT, should the function treat
that node as transparent and continue searching, or as opaque and return
(probably) NULL?
Instead, replace the function with one returning a scene_node, which
will allow for more consistent behavior across different node types.
Compositors can downcast scene_surface nodes via the now-public
wlr_scene_surface_from_node() if they need access to the surface itself.
RECT is a solid-colored rectangle, useful for simple borders or other
decoration. This can be rendered directly using the wlr_renderer,
without needing to create a surface.
For consistency with the rest of the scene-graph API, prevent detaching
a subtree by giving NULL for the new parent, and don't allow ROOT nodes
to be grafted into another tree.
If nodes are arranged in a tree rather than at a single level, then it
makes sense that there should be a way to move them to a completely
different parent in addition to moving up or down among siblings.
This allows compositors to easily enable or disable a scene-graph node.
This can be used to show/hide a surface when the xdg_surface is
mapped/unmapped.
A new wlr_scene API has been added, following the design ideas from [1].
The new API contains the minimal set of features required to make the
API useful. The goal is to design a solid fundation and add more
features in the future.
[1]: https://github.com/swaywm/wlroots/issues/1826#issuecomment-564601757
If a subsurface is being placed below a subsurface right above it, this
should be a noop. However, `node` pointed to the subsurface that was
moved, which resulted in `subsurface->parent_pending_link` being
inserted into itself, breaking parent's pending subsurface list.
This commit separates finding the requested node and getting it's `prev`
field, fixing the issue.
Similar to commit 85757665e6 ("backend/drm: Check if output is enabled
before sending frame event"), check if the output is still enabled
before sending the frame event. This fixes the bug not only for the DRM
backend, but for wayland and X11 as well.
The protocol specifies that all requests (aside from destroy) are
ignored after the compositor sends the closed event. Therefore,
destroying the wlroots object and rendering the resource inert
when sending the closed event keeps things simpler for wlroots and
compositors.
This wlr_surface_state field was a special case because we don't
want to save the whole current state: for instance, the wlr_buffer
must not be saved or else wouldn't get released soon enough.
Let's just inline the state fields we need instead.
wl_fixed_t is a 32-bit data type, but our doubles are 64-bit. This meant
that two doubles that would map to the same wl_fixed_t could compare
unequal, and send a duplicate motion event.
Refs swaywm/sway#4632.
The protocol allows compositors to not send any keymap to Wayland
clients. Handle a keymap-less keyboard correctly by sending
WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP instead of erroring out in the
mmap call.
When enabling an output, skip the empty buffer allocation if the
backend accepts modesets without a buffer.
This fixes mode-setting with the noop backend.
According to the viewport protocol, upon wp_viewport::destroy():
> The associated wl_surface's crop and scale state is removed.
> The change is applied on the next wl_surface.commit.
Therefore, wp_viewport_destroy(viewport) should remove all viewport state.
Currently, wlroots does not remove the crop and scale state. Instead, a
client must do:
wl_fixed_t clear = wl_fixed_from_int(-1);
wp_viewport_set_source(viewport, clear, clear, clear, clear);
wp_viewport_set_destination(viewport, -1, -1);
wp_viewport_destroy(viewport);
This commit adds the necessary logic into viewport_destroy and makes
wlroots comply with the protocol.
Sometimes we allocate a buffer with modifiers but then fail to
perform a modeset with it. This can happen on Intel because of
bandwidth limitations. To mitigate this issue, it's possible to
re-allocate the buffer with modifiers.
Add the logic to do so in wlr_output.
Adds `wlr_buffer_resource_interface` and `wlr_buffer_register_resource_interface`,
which allows a user to register a way to create a wlr_buffer from a specific
wl_resource.
The first time wlr_buffer_from_resource is called with a wl_buffer
resource that originates from wl_shm, create a new
wlr_shm_client_buffer as usual. If wlr_buffer_from_resource is called
multiple times, re-use the existing wlr_shm_client_buffer.
This commit changes how the wlr_shm_client_buffer lifetime is managed:
previously it was destroyed as soon as the wlr_buffer was released.
With this commit it's destroyed when the wl_buffer resource is.
Apart from de-duplicating wlr_shm_client_buffer creations, this allows
to easily track when a wlr_shm_client_buffer is re-used. This is useful
for the renderer and the backends, e.g. the Pixman renderer can keep
using the same Pixman image if the buffer is re-used. In the future,
this will also allow to re-use resources in the Wayland and X11 backends
(remote wl_buffer objects for Wayland, pixmaps for X11).
When wlr_output manages its own swap-chain, there's no need to
hook into the backend to grab DMA-BUFs. Instead, maintain a
wlr_output.front_buffer field with the latest committed buffer.
This function doesn't need the wl_resource anymore.
In the failure paths, wlr_buffer_unlock in surface_apply_damage
will take care of sending wl_buffer.release.
We often juggle between wlr_buffer and wlr_client_buffer variables.
Use a consistent naming: "buffer" for wlr_buffer and "client_buffer"
for wlr_client_buffer.
`wlr_client_buffer_import` is splitted in two distincts function:
- wlr_buffer_from_resource, which transforms a wl_resource into
a wlr_buffer
- wlr_client_buffer_create, which creates a wlr_client_buffer
from a wlr_buffer by creating a texture from it and copying its
wl_resource
[1] and [2] have introduced new wl_array usage in wlroots, but
contains a mistake: wl_array_for_each iterates over pointers to
the wl_array entries, not over entries themselves.
Fix all wl_array_for_each call sites. Name the variables "ptr"
to avoid confusion.
Found via ASan:
==148752==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x602000214111 in thread T0
#0 0x7f6ff2235f19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x7f6ff1c04004 in wlr_tablet_destroy ../subprojects/wlroots/types/wlr_tablet_tool.c:24
#2 0x7f6ff1b8463c in wlr_input_device_destroy ../subprojects/wlroots/types/wlr_input_device.c:51
#3 0x7f6ff1ab9941 in backend_destroy ../subprojects/wlroots/backend/wayland/backend.c:306
#4 0x7f6ff1a68323 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:57
#5 0x7f6ff1ab36b4 in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:57
#6 0x7f6ff1ab417c in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:124
#7 0x7f6ff106184e in wl_display_destroy (/usr/lib/libwayland-server.so.0+0x884e)
#8 0x55cd1a77c9e5 in server_fini ../sway/server.c:218
#9 0x55cd1a77893f in main ../sway/main.c:400
#10 0x7f6ff04bdb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#11 0x55cd1a73a7ad in _start (/home/simon/src/sway/build/sway/sway+0x33a7ad)
0x602000214111 is located 1 bytes inside of 16-byte region [0x602000214110,0x602000214120)
freed by thread T0 here:
#0 0x7f6ff2235f19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x7f6ff1c04004 in wlr_tablet_destroy ../subprojects/wlroots/types/wlr_tablet_tool.c:24
#2 0x7f6ff1b8463c in wlr_input_device_destroy ../subprojects/wlroots/types/wlr_input_device.c:51
#3 0x7f6ff1ab9941 in backend_destroy ../subprojects/wlroots/backend/wayland/backend.c:306
#4 0x7f6ff1a68323 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:57
#5 0x7f6ff1ab36b4 in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:57
#6 0x7f6ff1ab417c in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:124
#7 0x7f6ff106184e in wl_display_destroy (/usr/lib/libwayland-server.so.0+0x884e)
previously allocated by thread T0 here:
#0 0x7f6ff2236279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6ff1066d03 in wl_array_add (/usr/lib/libwayland-server.so.0+0xdd03)
[1]: https://github.com/swaywm/wlroots/pull/3002
[2]: https://github.com/swaywm/wlroots/pull/3004
The wl_touch.frame event is used to group multiple touch events
together. Instead of sending it immediately after each touch event,
rely on the backend to send it (and on the compositor to relay it).
This is a breaking change because compositors now need to manually
send touch frame events instead of relying on wlr_seat to do it.