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.
The BO handle table exists to avoid double-closing a BO handle,
which aren't reference-counted by the kernel. But if we can
guarantee that there is only ever a single ref for each BO handle,
then we don't need the BO handle table anymore.
This is possible if we create the handle right before the ADDFB2
IOCTL, and close the handle right after. The handles are very
short-lived and we don't need to track their lifetime.
Because of multi-planar FBs, we need to be a bit careful: some
FB planes might share the same handle. But with a small check, it's
easy to avoid double-closing the same handle (which wouldn't be a
big deal anyways).
There's one gotcha though: drmModeSetCursor2 takes a BO handle as
input. Saving the handles until drmModeSetCursor2 time would require
us to track BO handle lifetimes, so we wouldn't be able to get rid
of the BO handle table. As a workaround, use drmModeGetFB to turn the
FB ID back to a BO handle, call drmModeSetCursor2 and then immediately
close the BO handle. The overhead should be minimal since these IOCTLs
are pretty cheap.
Closes: https://github.com/swaywm/wlroots/issues/3164
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.
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
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.
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.
Previously, we were copying wlr_output_state on the stack and
patching it up to be guaranteed to have a proper drmModeModeInfo
stored in it (and not a custom mode). Also, we had a bunch of
helpers deriving DRM-specific information from the generic
wlr_output_state.
Copying the wlr_output_state worked fine so far, but with output
layers we'll be getting a wl_list in there. An empty wl_list stores
two pointers to itself, copying it on the stack blindly results in
infinite loops in wl_list_for_each.
To fix this, rework our DRM backend to stop copying wlr_output_state,
instead add a new struct wlr_drm_connector_state which holds both
the wlr_output_state and additional DRM-specific information.
This function behaves like allocate_shm_file, except it also
returns a read-only FD. This is useful to share the same segment
of memory with many Wayland clients.
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
Using GBM to import DRM dumb buffers tends to not work well. By
using GBM we're calling some driver-specific functions in Mesa.
These functions check whether Mesa can work with the buffer.
Sometimes Mesa has requirements which differ from DRM dumb buffers
and the GBM import will fail (e.g. on amdgpu).
Instead, drop GBM and use drmPrimeFDToHandle directly. But there's
a twist: BO handles are not ref'counted by the kernel and need to
be ref'counted in user-space [1]. libdrm usually performs this
bookkeeping and is used under-the-hood by Mesa.
We can't re-use libdrm for this task without using driver-specific
APIs. So let's just re-implement the ref'counting logic in wlroots.
The wlroots implementation is inspired from amdgpu's in libdrm [2].
Closes: https://github.com/swaywm/wlroots/issues/2916
[1]: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/110
[2]: 1a4c0ec9ae/amdgpu/handle_table.c
This allows the kernel to access our buffer damage. Some drivers
can take advantage of this, e.g. for PSR2 panels (Panel Self
Refresh) or for transfer over USB.
Closes: https://github.com/swaywm/wlroots/issues/1267
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.
The half-float formats depend on GL_OES_texture_half_float_linear,
not just the GL_OES_texture_half_float extension, because the latter
does not include support for linear magni/minification filters.
The new 2101010 and 16161616F formats are only available on little-
endian builds, since their gl_types are larger than a byte and thus
endianness dependent.
Unless we're dealing with a multi-GPU setup and the backend being
initialized is secondary, we don't need a renderer nor an allocator.
Stop initializing these.
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.
This is the cause of the spurious "drmHandleEvent failed" messages
at exit. restore_drm_outputs calls handle_drm_event in a loop without
checking whether the FD is readable, so drmHandleEvent ends up with a
short read (0 bytes) and returns an error.
The loop's goal is to wait for all queued page-flip events to complete,
to allow drmModeSetCrtc calls to succeed without EBUSY. The
drmModeSetCrtc calls are supposed to restore whatever KMS state we were
started with. But it's not clear from my PoV that restoring the KMS
state on exit is desirable.
KMS clients are supposed to save and restore the (full) KMS state on VT
switch, but not on exit. Leaving our KMS state on exit avoids unnecessary
modesets and allows flicker-free transitions between clients. See [1]
for more details, and note that with Pekka we've concluded that a new
flag to reset some KMS props to their default value on compositor
start-up is the best way forward. As a side note, Weston doesn't restore
the CRTC by does disable the cursor plane on exit (see
drm_output_deinit_planes, I still think disabling the cursor plane
shouldn't be necessary on exit).
Additionally, restore_drm_outputs only a subset of the KMS state.
Gamma and other atomic properties aren't accounted for. If the previous
KMS client had some outputs disabled, restore_drm_outputs would restore
a garbage mode.
[1]: https://blog.ffwll.ch/2016/01/vt-switching-with-atomic-modeset.html
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.
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.
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
Right now callers of drm_crtc_commit need to check whether the
interface is legacy or atomic before passing the TEST_ONLY flag.
Additionally, the fallbacks for legacy are in-place in the common
code.
Add a test_only arg to the crtc_commit hook. This way, there's no
risk to pass atomic-only flags to the legacy function (add an assert
to ensure this) and all of the legacy-specific logic can be put back
into legacy.c (done in next commit).
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.
We never create an EGL context with the platform set to something
other than EGL_PLATFORM_GBM_KHR. Let's simplify wlr_egl_create by
taking a DRM FD instead of a (platform, remote_display) tuple.
This hides the internal details of creating an EGL context for a
specific device. This will allow us to transparently use the device
platform [1] when the time comes.
[1]: https://github.com/swaywm/wlroots/pull/2671
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")
Rely on wlr_output's generic swapchain support instead of creating our
own. The headless output now simply keeps a reference to the front buffer
and does nothing else.
Introduce wlr_shm_client_buffer, which provides a wlr_buffer wrapper
around wl_shm_buffer.
Because the client can destroy the wl_buffer while we still are using
it, we need to do some libwayland tricks to still be able to continue
accessing its underlying storage. We need to reference the wl_shm_pool
and save the data pointer.
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 allows users to know the capabilities of the buffers that
will be allocated. The buffer capability is important to
know when negotiating buffer formats.
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.
When importing a DMA-BUF wlr_buffer as a wlr_texture, the GLES2
renderer caches the result, in case the buffer is used for texturing
again in the future. When the wlr_texture is destroyed by the caller,
the wlr_buffer is unref'ed, but the wlr_gles2_texture is kept around.
This is fine because wlr_gles2_texture listens for wlr_buffer's destroy
event to avoid any use-after-free.
However, with this logic wlr_texture_destroy doesn't "really" destroy
the wlr_gles2_texture. It just decrements the wlr_buffer ref'count.
Each wlr_texture_destroy call must have a matching prior
wlr_texture_create_from_buffer call or the ref'counting will go south.
Wehn destroying the renderer, we don't want to decrement any wlr_buffer
ref'count. Instead, we want to go through any cached wlr_gles2_texture
and destroy our GL state. So instead of calling wlr_texture_destroy, we
need to call our internal gles2_texture_destroy function.
Closes: https://github.com/swaywm/wlroots/issues/2941
Instead of managing our own renderer and allocator, let the common
code do it.
Because wlr_headless_backend_create_with_renderer needs to re-use
the parent renderer, we have to hand-roll some of the renderer
initialization.
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.
Make it so wlr_gles2_texture is ref'counted (via wlr_buffer). This
is similar to wlr_gles2_buffer or wlr_drm_fb work.
When creating a wlr_texture from a wlr_buffer, first check if we
already have a texture for the buffer. If so, increase the
wlr_buffer ref'count and make sure any changes made by an external
process are made visible (by invalidating the texture).
When destroying a wlr_texture created from a wlr_buffer, decrease
the ref'count, but keep the wlr_texture around in case the caller
uses it again. When the wlr_buffer is destroyed, cleanup the
wlr_texture.
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.
Backend-initiated mode changes can use this function instead of
going through drm_connector_set_mode. drm_connector_set_mode becomes
a mere drm_connector_commit_state helper.
Replace it with a new drm_connector_state_is_modeset function that
decides whether a modeset is necessary directly from the
wlr_output_state which is going to be applied.
Stop assuming that the state to be applied is in output->pending in
crtc_commit. This will allow us to remove ephemeral fields in
wlr_drm_crtc, which are used scratch fields to stash temporary
per-commit data.
This function is only required because the DRM backend still needs
to perform multi-GPU magic under-the-hood. Remove the wlr_ prefix
to make it clear it's not a candidate for being made public.
`_NET_WM_PID` is unreliable: it is optional and even if set it may
contain PIDs from sandbox namespaces or remote systems.
Prefer XRes v1.2 QueryClientIds method which returns PIDs as seen by the
Xwayland server.
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.
It allocates in local main memory via shm_open, and provides a FD
to allow sharing with other processes.
This is suitable for software rendering under the Wayland and X11
backends.
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.
This fixes the following warning:
WARNING: Project targeting '>=0.56.0' but tried to use feature deprecated since '0.56.0': Dependency.get_pkgconfig_variable. use Dependency.get_variable(pkgconfig : ...) instead
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.