With the aboutToBeDestroyed signal, the compositor will be able to
perform cleanup before the QObject::destroyed signal is emitted, which
saves us some nullptr checks.
Register WL_SHM_FORMAT_ARGB2101010 and its XRGB,ABGR, and XBGR variants.
These (little-endian) formats are only advertised on little endian
machines, where there exist matching (native-endian) QImage formats.
wl_callback and wl_region are two kinds of objects that are frequently
allocated.
Currently, we make two extra heap allocations per each wl_callback
object. One for the wrapper object (FrameCallback) and the other one is
for its Resource.
With this change, no extra allocations will be made. Also, due to
relying on wl_resource linked lists, the destroy listener implementation
got much simpler.
This won't result in huge memory usage or performance improvements, but
still it's worth reducing the number of memory allocations where possible.
Currently, we store all surfaces in a single list and use linear search
to find the SurfaceInterface by its object id and client connection.
With this, we first search for the wl_resource object by its id. Once we
have a wl_resource, SurfaceInterface::get(wl_resource) can be used.
The main advantage of the proposed solution is that we don't need to
maintain a static list with all SurfaceInterface objects.
Display::outputsIntersecting() is used to compute the list of outputs
where the given surface is. The problem is that it accounts for the dpms
mode.
This means that if an output is turned off, clients will receive a leave
event and they may potentially decide to change the buffer scale and
commit new buffers.
The dpms check was introduced to fix a crash, however since then, output
bits in kwin have changed drastically, in particular how wl_output
objects are destroyed. So, it should be safe to remove the dpms check.
A subsurface should be considered mapped only if it has a buffer
attached and its parent is also mapped.
Currently, mapped status logic in SurfaceInterface is somewhat broken
for sub-surfaces. For example, the mapped() signal will be emitted even
if the sub-surface should be considered unmapped according to the spec.
Currently, if an application is closed, all of its shm buffers will be
destroyed. However, the compositor may want to access them to fade out
the window.
With this change, the underlying shm pool will be referenced when a shm
buffer is destroyed. So, the compositor can access buffer data even if
the buffer is destroyed.
Currently, the BufferInterface encapsulates all the kinds of client
buffers. This has become a somewhat annoying issue as we want to
reference the shm pool if a shm buffer is destroyed, or have custom
buffer readiness logic for linux dma-buf client buffers.
Implementing all of that with the current abstractions will be
challenging as there's no good separation between different client
buffer types.
This change splits the BufferInterface class in three sub-classes -
DrmClientBuffer, LinuxDmaBufV1ClientBuffer, and ShmClientBuffer.
In addition to that, this change fixes the broken buffer ref'ing api.
Currently, the swapStates() function does two things - (a) it merges one
state with another; (b) it applies the next state. This change splits the
swapStates() so it's simpler and the boolean trap can be removed.
If nothing has been committed to the cached state, no changes to the
current state will be done.
If a synchronized sub-surface has been committed, the pending state will
be merged with the cached state. The latter state will be applied when
the parent surface is committed.
Currently, the committed signal is emitted after the client has called
wl_surface.commit. However, this breaks with synchronized subsurfaces.
Notably, Firefox splits a web page in a bunch of smaller layers, which
can be backed by wl_subsurface objects.
All the subsurfaces are in the sync mode. If a layer needs to be
repainted, Firefox will commit the corresponding subsurface with a frame
callback.
Since the committed signal is emitted when the wl_surface.commit request
is invoked, kwin will schedule a new frame immediately. Meaning, that it
is quite likely that firefox will have old contents.
The right thing to do would be to schedule a frame when all the ancestors
of the layer subsurface have been committed.
This change re-jitters the commit logic so the committed signal is
emitted when a new state is applied to the surface. It also slightly
cleans up how SubSurfaceInterface::parentCommit() is called.
It will be nice to cleanup the commit logic further by calling the
surface role's commit hook unconditionally, i.e. not check whether it's
a subsurface. But doing so may result in infinite recursions. How to
clean up that is still TBD.
According to the spec, if the parent surface is specified in the
wl_subsurface.place_below(), the subsurface has to be rendered below the
parent surface.
At the moment, kwaylandserver doesn't handle that case properly. It is
not possible for sub-surfaces to go below the parent surface.
Another issue is that we wrongly assume that the place_above request
will put the subsurface on top of the stack if the parent surface is
specified as sibling. It doesn't seem like that's the case, not
according to the spec.
This change splits the child sub-surface list in two lists - below and
above. The alternative solution is to store the parent surface in the
children list, but it's an error prone solution and it's conceptually
weird.
Until the spec is clear about how the keyboard focus should be
transferred between sub-surfaces, it's better to remove this heuristic
and focus only the main surface.
For example, if an application window has sub-surfaces but user doesn't
press any pointer button, any sub-surface can have focus.
Effectively, this reverts 6fe14f73d2.
This way, the compositor can batch more frame callbacks before flushing
the client connection. We attempted this before, but it broke tests.
Now, it seems like the tests pass, so we can remove the manual flush.
This way, it's less characters to type. In order to support delayed
surface commits, compositor extensions need to piggyback their state on
the state of the wl_surface. In other words, SurfaceState is going to
be used not only by SurfaceInterface, but the viewporter extension, the
xdg-shell extension, etc.
Instead of enabled/disabled. This made it possible for non-focussed
processes to interact with our virtual keyboard. In practice, this meant
that sometimes when switching applications, the disabled from the former
application would arrive after the enabled of the latter, leaving kwin
in a broken state (that the user could address by tapping on the screen
just once).
This signal is useful if the compositor wants to perform some cleanup
before the disconnected signal is emitted or while the connection object
still has valid wl_client native handle.
libwayland-server ensures that the requested version is less than or
equal to the global version.
This change removes the global version check to simplify the generated
code and reduce memory usage footprint, however the latter shouldn't be
that noticeable.
Unfortunately, we cannot just simply unset the wl_global's user data.
The compositor still needs to process client requests after the global
has been removed, for example bind requests or the requests that create
new resources.
CCBUG: 435258
Otherwise we disable it and all events will be disabled (since surface
gets cleared).
This is especially useful since otherwise we lose synchronicity with the
client and weird behaviours happen (like when the client thinks it has a
keyboard but it actually does not).
Fixes the following backtrace:
*0 KWaylandServer::DataDeviceInterface::dragSource() const (this=0x0)
at ./src/server/datadevice_interface.cpp:199
*1 0x00007f10d67b0c71 in
KWaylandServer::DataDeviceInterface::updateDragTarget(KWaylandServer::SurfaceInterface*,
unsigned int) (this=0x55c42e3ee9a0,
surface=surface@entry=0x55c42e4b3170, serial=serial@entry=3104)
at ./src/server/datadevice_interface.cpp:278
*2 0x00007f10d67d8e52 in
KWaylandServer::SeatInterface::setDragTarget(KWaylandServer::SurfaceInterface*,
QPointF const&, QMatrix4x4 const&)
(this=this@entry=0x55c42d422ed0, surface=0x55c42e4b3170,
globalPosition=..., inputTransformation=...) at
/usr/include/c++/9/bits/atomic_base.h:413
*3 0x00007f10d67d9209 in
KWaylandServer::SeatInterface::setDragTarget(KWaylandServer::SurfaceInterface*,
QMatrix4x4 const&) (this=this@entry=0x55c42d422ed0, surface=<optimized
out>, inputTransformation=...)
at ./src/server/seat_interface.cpp:578
*4 0x000055c42cb4563a in KWin::Xwl::XToWlDrag::setDragTarget()
(this=this@entry=0x55c42ea07a00) at ./src/toplevel.h:990
*5 0x000055c42cb47a68 in KWin::Xwl::XToWlDrag::offerCallback(QString
const&) (mime=..., this=0x55c42ea07a00) at ./src/xwl/drag_x.cpp:242
*6 KWin::Xwl::XToWlDrag::offerCallback(QString const&)
(this=0x55c42ea07a00, mime=...) at ./src/xwl/drag_x.cpp:237
*7 0x00007f10d5dc06fe in () at /lib/x86_64-linux-gnu/libQt5Core.so.5
I've been using kwaylandserver without this workaround for a while and
haven't experienced any issues. Also, there were some sub-surface fixes
in QtWayland.
Non-current output modes were deprecated due to various reasons, e.g.
it's not possible to remove some nodes; two modes can have the same
resolution and the refresh rate but different flags, but wl_output.mode
fails to communicate that properly; the usefulness of non-current modes
is questionable. For more details, please refer to [1].
[1] https://gitlab.freedesktop.org/wayland/wayland/-/issues/92
The usage of nested private classes is highly discouraged in
kwaylandserver due to various reasons, e.g. it's easy to forget to put
Q_DECL_HIDDEN, etc.
Currently, the SurfaceInterface class has a signal that is emitted
whenever any sub-surfaces in its sub-tree changes in a way that requires
a repaint. It is emitted when a sub-surface is resized, moved, or
damaged, etc. There is no way for the compositor to track changes in the
stacking order of sub-surfaces efficiently.
This change replaces the subTreeChanged signal with a less noisy signal
that's emitted whenever the list of direct child sub-surfaces changes.
This is needed for keyboard grabs. If the seat is notified about a
keyboard event, it will need to forward the event to the grab object,
which in its turn will decide what should happen to the event.
When hot plugging outputs, we may hit the wl_global race condition.
We need to delay the destruction of output device globals to prevent
hitting that race condition.
Destroying a global leads to a race on the client. If a client binds
at just the wrong moment they will use an invalid ID and cause a
protocol error. The current best thing to do is to announce the removal
then remove the global (and thus the ID) only after a delay. Non-ideal,
but better than nothing.
Pragmatically this affects only:
Blur/Contrast/Slide/Output/OutputDevice
See https://gitlab.freedesktop.org/wayland/wayland/issues/10 for more.
In plasma code, it's more common to see `/** ... */` doxygen comments
rather than `/** ... **/`.
This change fixes up doxygen comment terminators to prevent inconsistency
issues.
An xdg_imported resource must be created no matter whether there is an
exported surface with the specified handle.
This change fixes handling of that case in kwaylandserver by introducing
a dummy imported object.
If there is no exported surface with the given handle, the compositor
should create an xdg_imported resource and immediately send the
destroyed event.
A dummy imported object is needed because generated code sets resource
implementation; otherwise we would set an implementation without any
user data to mark the resource as inert.
XdgImportedV2Interface already knows what the associated resource is, so
we can call send_destroyed() method that takes no resource to let auto
generated code figure out what resource must be used. It simplifies code.
There's no point for using the d-pointer pattern because the importer
and the exporter classes are private already, they are not exposed in
public api.
Currently, testXdgForeign fails because imported and exported resources
are destroyed immediately from destructor request handlers and code that
performs cleanup in the exported-imported mapping tables accesses the
dangling pointers.
Previously, it wasn't an issue because the destruction of exported and
imported resources was delayed using QObject::deleteLater().