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().
In zxdg_output_v1 version 3, done is deprecated and should be replaced
with wl_output.done. This makes automatically send done upon change not
suitable for the usage. OutputInterface user should now use done()
explicitly to send the update.
CCBUG: 433224
Currently, plasma window model test fails because the null icon is
received after executing the main body of the test.
FAIL! : PlasmaWindowModelTest::testVirtualDesktops() '!dataChangedSpy.wait(100)' returned FALSE. ()
Loc: [/data/projects/src/kwayland-server/autotests/client/test_plasma_window_model.cpp(583)]
We can fix the test by waiting for the iconChanged signal to be emitted,
but we will need to wait in all tests too. Furthermore, it doesn't make a
lot of sense to wait for an icon that was never set.
This change makes the compositor send an icon only if there is one.
It's a behavioral change, but it shouldn't regress anything because kwin
always sets icons via the plasma window management protocol even for apps
that have no valid app id.
It also makes the api of the PlasmaWindowInterface class more intuitive.
Currently, testIcon fails because the actual and the expected pixmaps
have mismatching formats.
The root cause is that images with an alpha channel will loose the alpha
channel if they are converted to QPixmap using QPixmap::fromImage().
The >> stream operator for the QPixmap class will deserialize pixel data
in a temporary QImage and then use QPixmap::fromImage() to get a pixmap
object.
The >> stream operator for the QIcon class will delegate the task of
reading the icon from a QDataStream to QPixmapIconEngine, which uses the
>> stream operator under the hood to deserialize icon data.
In order to fix testIcon, this change constructs a dummy icon from a
pixmap object returned by QPixmap::fromImage().
Currently, we have a mix of Frameworks versions and Plasma versions in
@since tags, which leads to some confusion. Since this is an unstable
library, one cannot rely on since version tags, we are free to add,
change, and remove apis to serve best to kwin requirements. Thus, we can
simply remove all since version tags to fix mixing up different product
versions.
If a Wayland protocol deals with regions, they will be exposed as
QRegion objects in public API. Therefore, it makes sense to make
RegionInterface private as it's an implementation detail and it's
not intended to be used in public api.
The corresponding test was dropped because the CompositorInterface
no longer emits a signal to indicate that a wl_region has been created.
It should be also noted that wl_region stuff is already tested via
other means, e.g. surface damage, etc.
testError expects that the compositor will post a protocol error if the
client tries to create several plasma shell surfaces for the same wayland
surface.
This is a minor regression introduced with the refactor of the
KeyboardInterface. We need to update pressed key status even if there is
no focused surface, otherwise some keys may get stuck in the pressed
state.
This improves the readability of the setFocusedSurface() method in the
KeyboardInterface class. Currently, it's easy to overlook that the
sendEnter() function also sends modifiers.
This change renames methods that are used by the compositor to notify the
seat about input events.
There isn't anything special about the proposed naming scheme, for what
it is worth, it was established in weston. "notify" methods are used to
notify kwaylandserver about something, and "send" methods actually send
relevant events to wayland clients.
PlasmaWindowInterface is a "Server-managed multicasting resources". We
no longer need our wrapper to outlive objects so we can tidy that up.
It's weird to have a method call to an object delete the object, so
memory management is moved to the caller to be consistent.
The protocol spec indicates that the compositor has to accumulate seat
capabilities and post a protocol error if a client requests an input
device and the seat has never had the corresponding capability.
This rewrites the wl_seat protocol implementation to adhere to the new
design principles.
Effectively, we've been supporting wl_seat v7 so the version was also
bumped from 5 to 7.
With this design, a single PointerInterface manages multiple wl_pointer
objects. This makes the API tidier and allows implementing things such as
keyboard grabs more easier.
In addition to that, the PointerInterface doesn't inject its own frame
events anymore. It's up to the compositor to decide when it has to be
sent. However, the PointerInterface may still send a frame event if the
pointer focus changes.
Besides re-writing the pointer interface, this change, unfortunately,
also affects the implementation of pointer-gestures and relative-pointer
protocols because previously they were coupled to individual instances
of PointerInterface.
During a drag the source can disappear at any time. The other client
will be notified, but it may have actions in flight.
Other methods were guarded but not data_offer_finished.
Currently, the compositor is supposed to pass the position of the touch
point to the touchDown() function and in return get its unique global
id. The id can be be passed to subsequent touchMotion() and touchUp().
The compositor is responsible for mapping between libinput slots and
internal touch point ids.
The mapping step is unnecessary and adds in some complexity as the input
code now has to keep the mapping table up to date.
This change makes the touch API more convenient to use by making
relevant functions take touch ids that are assigned by the compositor.
Usually, compositor would use libinput_event_touch_get_seat_slot() to
get touch ids.
It also allows introducing event objects that can be useful later in the
future.
This is a copy of the code from Qt5.15 with some backported patches from
development branch of Qt.
One of the upcoming fixes introduces new API, which is why we can't rely
on distro packaging.
The cmake macro is mostly copied from ECM, but set to rebuild generated
code when the scanner changes.
The following order of events are legal:
Typically order is:
- server announces a new output
- client binds to a new output
- server updates the surface to be on new output
But we can have events occur in the following order:
- server announces a new output
- server updates the surface to be on new output
- client binds to a new output
At which point when we update the surface there is no ID to tell the
client which output the surface is on.
This patch watches for clients binding to output and updates
appropriately.
Be more explicit about the types, prefer passing semantically correct
parents and keep track of the pads from the object rather than relying
on them being initialised properly.
We send modifiers to the active client when they change, and when we
focus an existing client we send the cached state.
For this reason it's important we always update our internal store of
modifiers regardless of whether a surface is currently active.
Unit test is adopted accordingly.
BUG: 429930
The main reason why we have factory methods is that up to some point,
kwayland had its own signal to indicate when globals have to be removed.
Now that all globals add destroy listeners for the wl_display object,
we don't have that signal. Most factory methods are equivalent to doing
new T(display).
Besides adding unnecessary boilerplate code, another reason to get rid
of the factory methods is to reduce the amount of merge conflicts. If
several persons work on implementing wayland protocols at the same time,
sooner or later someone will have to resolve merge conflicts in Display.
libwayland-server allows the wl_display accept client connections on
more than one socket. We currently don't listen on multiple sockets,
but it would be nice if Display supported such operation mode.
And make them public in th keyboard_interface, there's no point in
wrapping this in seat_interface with new approach
See also: plasma/kwayland-server#13
A threshold exists to stop users flooding the server for no reason.
However, there is a usecase for small timeouts.
rsibreak has a "please relax for 20 seconds" interface. Here it makes
perfect sense to know if a user is active in small increments. The plan
is to start a 1s timer and wait for that. Then we wait locally for 20s
without a resume event.
We cannot end a drag after the destroyed() signal for the source data
device is emitted because DataDeviceInterface and its d pointer are gone
by that time.