This commit ensures that outputs that weren't created by the output
layout helper aren't destroyed on the output layout change.
Consider the following piece of logic:
// struct wlr_output *o1, *o2;
// struct wlr_scene *scene;
// struct wlr_output_layout *layout;
wlr_scene_attach_output_layout(scene, layout);
wlr_output_layout_add_auto(layout, o1);
struct wlr_scene_output *so2 = wlr_scene_output_create(scene, o2);
wlr_output_layout_move(layout, o1, 100, 200);
// so2 is invalid now
Now that the DRM backend no longer depends on GBM, we can make it
optional. The GLES2 renderer still depends on it because of our EGL
device selection.
This is useful for compositors with their own renderers, and for
compositors using the Vulkan renderer.
This allows the make/model/serial to be NULL when unset, and allows
them to be longer than the hardcoded array length.
This is a breaking change: compositors need to handle the new NULL
case, and we stop setting make/model to useless "headless" or
"wayland" strings.
These are trivial wrappers around eglMakeCurrent and
eglGetCurrentContext. Compositors which need to call these
functions will also call other EGL or GL functions anyways. Let's
reduce our API surface a bit by making them private.
This will display red translucent rectangles on the screen regions that
have been damaged. These rectangles will fade out over the span of 250
msecs. If the area is damaged again while the region is fading out,
the timer is reset.
Let's also disable direct scan out when this option is enabled, or else
we won't be able to render the highlight damage regions.
After cancelation we destroy the touch points associated with this
surface as the Wayland spec says:
No further events are sent to the clients from that particular gesture.
Touch cancellation applies to all touch points currently active on this
client's surface. The client is responsible for finalizing the touch
points, future touch points on this surface may re-use the touch point
ID.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/2999
This function sidesteps damage tracking and output awareness on
buffers/surfaces. This function isn't a great fit for the API.
Let's also inline the function and simplify it.
There were a couple places this was missing
- on mode change of an output. If the resolution changes for example
nodes may fall out of the view.
- on commits on an output for scale or transform changes
- when the transform of a buffer is changed. If the dest size is not
set, the buffer may have been rotated potentially changing its size
if the buffer width != height
With protocol additions such as [1], compositors currently have no
way to opt out of the version upgrade. The protocol upgrade will
always be backwards-compatible but may require new compositor
features.
The status quo doesn't make it possible to ship a protocol addition
without breaking the wlroots API. This will be an issue for API
stabilization [2].
To address this, let compositors provide a maximum version in the
function creating the global. We need to support all previous versions
of the interface anyways because of older clients.
This mechanism works the same way as Wayland clients passing a version
in wl_global.bind.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3514
[2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1008
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3397
The original commit introduced a bug by transposing the order of
some of the fields in xcb_size_hints_t. Since XCB ICCCM support is
required now, we can just eliminate the duplicate structs.
With minor changes:
- Remove #ifdef HAS_XCB_ICCCM guards
- Fix #includes
- Fix references to local size_hints struct
This reverts commit 12b9b1a4bd.
This was originally added in 810c7b7 for use in rootston's input config
handling. It has never actually been part of the wlroots API and
shouldn't exist.
The destroy callback in wlr_touch_impl has been removed. The function
`wlr_touch_finish` has been introduced to clean up the resources owned by a
wlr_touch.
`wlr_input_device_destroy` no longer destroys the wlr_touch, attempting to
destroy a wlr_touch will result in a no-op.
The field `name` has been added to the wlr_touch_impl to be able to identify
a given wlr_touch device.
The destroy callback in wlr_tablet_tool_impl has been removed. The function
`wlr_tablet_tool_finish` has been introduced to clean up the resources owned by
a wlr_tablet_tool.
`wlr_input_device_destroy` no longer destroys the wlr_tablet_tool, attempting to
destroy a wlr_tablet_tool will result in a no-op.
The field `name` has been added to the wlr_tablet_tool_impl to be able to
identify a given wlr_tablet_tool device.
The destroy callback in wlr_tablet_pad_impl has been removed. The function
`wlr_tablet_pad_finish` has been introduced to clean up the resources owned by a
wlr_tablet_pad.
`wlr_input_device_destroy` no longer destroys the wlr_tablet_pad, attempting to
destroy a wlr_tablet_pad will result in a no-op.
The field `name` has been added to the wlr_tablet_pad_impl to be able to identify
a given wlr_tablet_pad device.
The destroy callback in wlr_switch_impl has been removed. The function
`wlr_switch_finish` has been introduced to clean up the resources owned by a
wlr_switch.
`wlr_input_device_destroy` no longer destroys the wlr_switch, attempting to
destroy a wlr_switch will result in a no-op.
The field `name` has been added to the wlr_switch_impl to be able to identify
a given wlr_switch device.
The destroy callback in wlr_pointer_impl has been removed. The function
`wlr_pointer_finish` has been introduced to clean up the resources owned by a
wlr_pointer.
`wlr_input_device_destroy` no longer destroys the wlr_pointer, attempting to
destroy a wlr_pointer will result in a no-op.
The field `name` has been added to the wlr_pointer_impl to be able to identify
a given wlr_pointer device.
The destroy member in wlr_keyboard_impl has been removed. The function
`wlr_keyboard_finish` has been introduce to clean up the resources owned by a
wlr_keyboard.
`wlr_input_device_destroy` no longer destroys the wlr_keyboard, attempting to
destroy a wlr_keyboard will result in a no-op.
The field `name` has been added to the wlr_keyboard_impl to be able to identify
a given wlr_keyboard device.
This removes an artificial limitation in form of an assert that disallowed the
creation of textures while the renderer is rendering.
A consumer might run its own rendering pipeline and after start of the renderer
still want to create textures for internal usage.
To be consistent with other wlr_xdg_* structs,
wlr_xdg_positioner_resource is renamed to wlr_xdg_positioner and made
public, and wlr_xdg_positioner is renamed to wlr_xdg_positioner_rules.
Functions which operated on wlr_xdg_positioner were renamed and updated
accordingly.
In case the `wlr_input_device` is not owned by a specialized input device, the
function will finish the wlr_input_device and call it's implementation destroy
function if an implementation has been supplied, or simply free it.
The wlroots APIs currently don't allow importing/uploading a buffer
during rendering operations. Scene-graph buffer nodes need to turn
their wlr_buffer into a wlr_texture at some point. It's not always
possible to do so at wlr_scene_buffer creation time because the
scene-graph may have zero outputs at this point, thus no way to
grab a wlr_renderer.
Instead, add scene-graph buffers to a pending list and try to import
them in wlr_scene_output_commit.
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3354
Currently the output enter event is never sent if the client has not
yet bound the output, which happens every time the compositor creates a
new output.
To fix this, listen for the output bind event and inform clients as
if needed.
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.
This intersects two DRM format sets. This is useful for implementing
DMA-BUF feedback in compositors, see e.g. the Sway PR [1].
[1]: https://github.com/swaywm/sway/pull/6313
Support for EXT_image_dma_buf_import_modifiers doesn't necessarily
indicate support for modifiers. For instance, Mesa will advertise
EXT_image_dma_buf_import_modifiers for all drivers. This is a trick
to allow EGL clients to enumerate supported formats (something
EXT_image_dma_buf_import is missing). For more information, see [1].
Add a new wlr_egl.has_modifiers flag which indicates whether
modifiers are supported. It's set to true if any
eglQueryDmaBufModifiersEXT query returned a non-empty list.
Use that flag to figure out whether the buffer modifier should be
passed to the EGL implementation on import.
[1]: https://github.com/KhronosGroup/EGL-Registry/issues/142
This allows creating a wlr_egl from an already-existing EGL display
and context. This is useful to allow compositors to choose the exact
EGL initialization parameters.
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
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 headless backend no longer needs a parent renderer: it no longer
needs to return it in wlr_backend_impl.get_renderer, nor does it
need to return its DRM FD in wlr_backend_impl.get_drm_fd. Drop this
function altogether since it now behaves exactly like
wlr_headless_backend_create.
This field's ownership is unclear: it's in wlr_input_device, but
it's not managed by the common code, it's up to each individual
backend to use it and clean it up.
Since this is a backend implementation detail, move it to the
backend-specific structs.
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.
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.
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.
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.
This new renderer is implemented with the existing wlr_renderer API
(which is known to be sub-optimal for some operations). It's not
used by default, but users can opt-in by setting WLR_RENDERER=vulkan.
The renderer depends on VK_EXT_image_drm_format_modifier and
VK_EXT_physical_device_drm.
Co-authored-by: Simon Ser <contact@emersion.fr>
Co-authored-by: Jan Beich <jbeich@FreeBSD.org>
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.
Expose the panel orientation with wlr_drm_connector_get_panel_orientation.
Leave it to the compositor to consume this information and configure the
output accordingly.
Closes: https://github.com/swaywm/wlroots/issues/1581
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.
A launchee notifies with a "remove"¹ message when done starting up.
Catch these and forward to the compositor. This allows the compositor to
end the startup sequence that might have been started by another
protocol like xdg-activation.
We don't handle other messages since we expect the launcher to use a
wayland protocol like xdg-activation.
While `_NET_STARTUP_ID` helps to associate toplevels with startup-ids
this signals the end of the startup sequence.
1) https://specifications.freedesktop.org/startup-notification-spec/startup-notification-latest.txt
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.
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.
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
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.
Uses the EXT_device_query extension to get the EGL device matching the
requested DRM file descriptor. If the extension is not supported or no device
is found, the EGL device will be retrieved using GBM.
Depends on the EGL_EXT_device_enumeration to get the list of EGL devices.
As more options are added, more fields will be duplicated. Let's
just embed the struct in wlr_xwayland_server so that we don't need
to keep both in sync.
This EGL extension has been added in [1]. The upsides are:
- We directly get a render node, instead of having to convert the
primary node name to a render node name.
- If EGL_DRM_RENDER_NODE_FILE_EXT returns NULL, that means there is
no render node being used by the driver.
[1]: https://github.com/KhronosGroup/EGL-Registry/pull/127
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.
Now that we have our own wl_drm implementation, there's no reason
to provide custom renderer hooks to init a wl_display in the
interface. We can just initialize the wl_display generically,
depending on the renderer capabilities.
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.
Khronos refers to extensions with their namespace as a prefix in
uppercase. Change our naming to align with Khronos conventions.
This also makes grepping easier.
`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
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.
Everything needs to go through the unified wlr_buffer interface
now.
If necessary, there are two ways support for
EGL_WL_bind_wayland_display could be restored by compositors:
- Either by using GBM to convert back EGL Wayland buffers to
DMA-BUFs, then wrap the DMA-BUF into a wlr_buffer.
- Or by wrapping the EGL Wayland buffer into a special wlr_buffer
that doesn't implement any wlr_buffer_impl hook, and special-case
that buffer type in the renderer.
This will allow us to remove all of our EGL wl_drm support code
and remove some weird stuff we need just for wl_drm support. In
particular, wl_drm buffers coming from the EGL implementation
can't easily be wrapped into a wlr_buffer properly.
The mailing list has never been used.
I think listing the deprecated functions in the release notes is
enough. I'd rather not add the burden of maintaining a separate
communication medium.
Custom backends and renderers need to implement
wlr_backend_impl.get_buffer_caps and
wlr_renderer_impl.get_render_buffer_caps. They can't if enum
wlr_buffer_cap isn't made public.
The wlr_egl functions are mostly used internally by the GLES2
renderer. Let's reduce our API surface a bit by hiding them. If
there are good use-cases for one of these, we can always make them
public again.
The functions mutating the current EGL context are not made private
because e.g. Wayfire uses them.
Right now, when a new output state field is added, all backends by
default won't reject it. This means we need to add new checks to
each and every backend when we introduce a new state field.
Instead, introduce a bitmask of supported output state fields in
each backend, and error out if the user has submitted an unknown
field.
Some fields don't need any backend involvment to work. These are
listed in WLR_OUTPUT_STATE_BACKEND_OPTIONAL as a convenience.
Add wlr_pixman_buffer_get_current_image for wlr_pixman_renderer.
Add wlr_gles2_buffer_get_current_fbo for wlr_gles2_renderer.
Allow get the FBO/pixman_image_t, the compositor can be add some
action for FBO(for eg, attach a depth buffer), or without pixman
render to pixman_image_t(for eg, use QPainter of Qt instead of pixman).
The types of buffers supported by the renderer might depend on the
renderer's instance. For instance, a renderer might only support
DMA-BUFs if the necessary EGL extensions are available.
Pass the wlr_renderer to get_buffer_caps so that the renderer can
perform such checks.
Fixes: 982498fab3 ("render: introduce renderer_get_render_buffer_caps")
This new API allows buffer implementations to know when a user is
actively accessing the buffer's underlying storage. This is
important for the upcoming client-backed wlr_buffer implementation.
Prior to this commit, subsurfaces could only be placed above their
parent. Any place_{above,below} request involving the parent would
fail with a protocol error.
However the Wayland protocol allows using the parent surface in the
place_{above,below} requests, and allows subsurfaces to be placed
below their parent.
Weston's implementation adds a dummy wl_list node in the subsurface
list. However this is potentially dangerous: iterating the list
requires making sure the dummy wl_list node is checked for, otherwise
memory corruption will happen.
Instead, split the list in two: one for subsurfaces above the parent,
the other for subsurfaces below.
Tested with wleird's subsurfaces demo client.
Closes: https://github.com/swaywm/wlroots/issues/1865
There isn't always a good time to prune old tokens. Compositors
which only implement a "give focus on activation" logic can prune
tokens on focus change. However other compositors might want to
implement other semantics, e.g. "mark urgent on activation". In this
case a focus change shouldn't invalidate other tokens.
Additionally, some tokens aren't necessarily tied to a seat.
To avoid ending up with an ever-growing list of tokens, add a timeout.
Instead of passing a wlr_texture to the backend, directly pass a
wlr_buffer. Use get_cursor_size and get_cursor_formats to create
a wlr_buffer that can be used as a cursor.
We don't want to pass a wlr_texture because we want to remove as
many rendering bits from the backend as possible.
This allows compositors to choose a wlr_buffer to render to. This
is a less awkward interface than having to call bind_buffer() before
and after begin() and end().
Closes: https://github.com/swaywm/wlroots/issues/2618
This property is present on all modern X11 instances. The nonpresence of
it requires applications to fall back to XQueryTree-based logic to
determine stacking logic (e.g., to determine what surface should get
Xdnd events).
These code paths are effectively untested nowadays, so this makes it
more likely for wlroots to "break" applications. For instance, the
XQueryTree fallback path has been broken in Chromium for the last 10
years.
It's easy enough to maintain this property, so let's just do it.
Fixes#2889.
This new functions cleans up the common backend state. While this
currently only emits the destroy signal, this will also clean up
the renderer and allocator in upcoming patches.
This adds a a function to create a wlr_texture from a wlr_buffer.
The main motivation for this is to allow the renderer to create a
single wlr_texture per wlr_buffer. This can avoid needless imports
by re-using existing textures.
Previously, the same struct was used for linux-dmabuf-v1 params
and buffer. This made the whole logic a little bit awkward, because
a wlr_dmabuf_v1_buffer could either be still being constructed, or
be a complete buffer.
Introduce a separate wlr_linux_buffer_params_v1 struct for buffer
params still being constructed. Once the params are complete (ie.
once the create request is sent), the params struct is destroyed
and the buffer struct is created.
This will help with [1] as well.
[1]: https://github.com/swaywm/wlroots/issues/2664
Drop wlr_dmabuf_v1_buffer_from_params_resource and
wlr_linux_dmabuf_v1_from_resource. Contrary to wl_buffer, these
resources are internal linux-dmabuf-v1 implementation details and
should not be shared with other interfaces.
libseat provides all session functionality, so there is no longer need
for a session backend abstraction. The libseat device ID, seat handle
and event loop handle are moved to the main wlr_session and wlr_device
structs.
The get_drm_fd was made available in an internal header with a53ab146f. Move it
now to the public header so consumers opting in to the unstable interfaces can
make use of it.
Use 128-bit hexadecimal string tokens generated with /dev/urandom
instead of UUIDs for xdg-foreign handles, removing the libuuid
dependency. Update readme and CI. Closes#2830.
build: remove xdg-foreign feature
With no external dependencies required, there's no reason not to always
build it. Remove WLR_HAS_XDG_FOREIGN as well.
wlroots' dependency on this library doesn't change the features
exposed to compositors. It's purely a wlroots implementation detail.
Thus downstream compositors shouldn't really care about it.
Introduce an "internal_features" dictionary to store the status of
such internal dependencies.
To unify the code style of the project, absolute paths have been used in
some places, such as '#include "render/allocator.h"' in
"render/gbm_allocator.h". Except for include the wayland protocol
headers should be consistent.
This dependency is already required by many other widely used X11
programs, such as i3, Qt, and other XWMs. So it should be available
on most systems.
X11 support can be pretty broken without xcb-icccm, with focus issues
for instance. Let's just remove this --please-break-my-desktop footgun
option.