KWin does not update activity status when setting `_KDE_NET_WM_ACTIVITIES`
to nullUuid outside of KWin, which causes "All Activities" not working
as expected for KWindowSystem.
`X11Client::activityList` is not kept in sync with
`AbstractClient::m_activityList`. Move `m_activityList` from private to
protected, and use it in `X11Client::readActivities`
BUG: 440496
They are used only by InternalClient. AbstractClient doesn't need to
handle the destruction of DecorationBridge because its lifetime matches
kwin's lifetime.
Currently, if a window switches between SSD and CSD, it is possible to
encounter a "corrupted" state where the server-side decoration is wrapped
around the window while it still has the client-side decoration.
The xdg-decoration protocol fixes this problem by saying that decoration
updates are bound to xdg_surface configure events.
At the moment, kwin sort of applies decoration updates immediately. With
this change, decoration updates will be done according to the spec.
If the compositor wants to create a decoration, it will send a configure
event and apply the decoration when the configure event is acked by the
client. In order to send the configure event with a good window geometry
size, kwin will create the decoration to query the border size but not
assign it to the client yet. As is, KDecoration api doesn't make
querying the border size ahead of time easy. The decoration plugin can
assign arbitrary border sizes to windows as it pleases it. We could change
that, but it effectively means starting KDecoration3 and setting existing
window deco ecosystem around kwin on fire the second time, that's off the
table.
If the compositor wants to remove the decoration, it will send a
configure event. When the configure event is acked and the surface is
committed, the window decoration will be destroyed.
Sync'ing decoration updates to configure events ensures that we cannot
end up with having both client-side and server-side decoration. It also
helps us to fix a bunch of geometry related issues caused by creating
and destroying the decoration without any surface buffer attached yet.
BUG: 445259
Many effects use the stacking order property of the effects handler in
their constructors. This means that windows should have compositing
setup by the time effects are loaded.
After changing how binary effect plugins are loaded, i.e. not queueing
loading effects, but loading them immediately, some effects broke
because the effects handler is created before windows setup compositing.
This change attempts to fix those effects by rearranging compositor
startup code so windows setup compositing first, then create the effects
pointer.
move() and resize() functions are not convenience helpers around the
moveResize() function. They communicate what kwin wants to see after the
corresponding change is applied. It's needed to make asynchronous
geometry updates work.
This change replaces a moveResize() during XdgToplevelClient
initialization with explicit move() and resize() function calls instead,
so it's more clear what the expected end result is.
A few plasma components cache QSGTexture. Those components rely on
texture references going away with QSGNode users. However, with the
current tear down logic, OffscreenQuickView won't destroy any paint
nodes.
Destroy QQuickRenderControl before QQuickWindow to ensure that are no
paint nodes left alive after OffscreenQuickView.
BUG: 444429
BUG: 444381
BUG: 444077
BUG: 444306
For all the task switchers on my system there is no KCM installed:
```bash
rg 'X-KDE-ParentComponents=(PlasmaXLight|org.kde.breeze.desktop|org.kde.breezedark.desktop|org.kde.breezetwilight.desktop|org.kde.breeze.desktop|org.kde.breezedark.desktop|org.kde.breezetwilight.desktop|org.kde.plasma.mycroft.bigscreen|small_icons|big_icons|compact|text|present_windows|thumbnail_grid|thumbnails|informative)'
```
As the docs state, this is only for buildin effects. Which means it is internal API.
Also I consider the choice of displaying a KCM *or* the preview odd, IMHO the preview
is the most important part.
I stumbled upon this when reviewing the metadata files as part of the preparation
for https://phabricator.kde.org/T14564.
Also this way of plugin loading is discouraged for performance reasons, because all the
plugins from the namespace have to be reopened to get their metadata.
Use standard easing curves in animations. OutCubic for the intro
animation and the InCubic for the outro animation.
Hidden opacity options were removed because I don't think they are
needed anymore. I made the starting opacity 0.4 to make the animation
look closer to what it would have been with an ease-out curve without
realizing it.
The output management test checks the implementation of output
management capabilities in the virtual backend, which is not helpful.
This change replaces it with a more useful test that verifies how
windows are placed after an output change.
Currently, if you move the cursor really fast between two outputs, there
may be stuck cursor on the previous output.
We need to query the old cursor visibility status before updating the
cursor position, otherwise the drm backend may not schedule an update to
move the cursor offscreen.
It's fine to have the animation duration hardcoded to 250ms. The main
issue with reading kscreen effect's config is that it adds inter-effect
dependencies, which is simply not worth the trouble.
The intro and the outro animations are very short and they usually
affect all windows on the screen. Windows have to travel a lot and in
very short time, this doesn't look.
Similar to other windows, this change makes the overview effect use the
out cubic curve for window movements (even though the HIG suggests us
using the InOutCubic easing curve). That way, user will look at
flatter parts of the easing curve more, i.e. the windows would move less
chaotically and simply jump to their target position.
Similar to the WindowHeap, this change makes the overview effect use the
out cubic everywhere else so the intro and the outro animations look
coherent.
Another advantage of the OutCubic easing curve is that it makes the
overview effect look more responsive and subtle.
Currently, the wayland server updates the server side decoration mode,
which is counter-intuitive, because it doesn't cache the last preferred mode.
With ServerSideDecorationInterface::preferredMode(), it can be simpler.
This commit does away with the special handling of the legacy cursor and
makes it be applied directly in DrmPipeline, using the same state as the
atomic cursor and without dirty flags.
Effect loading is already tested using integration tests, for example
the maximize test verifies that the maximize effect is loaded _and_ it
actually does something useful when a window is maximized or restored,
testScriptedEffectLoader only verifies that the effect is loaded, which
is less helpful than what integration tests provide us.
But perhaps the main problem with these tests is that they require us
building a mockverse around them. This litters code with ifdef
preprocessor directives and makes changing such code a living nightmare.
Another problem with these two tests is that they cannot use OpenGL
because it means mocking OpenGL, which we obviously not going to do.
With integration tests, it's not a problem.
The bottom line is that unit tests can be useful but they make life
notoriously difficult when it comes to testing components that depend on
other components.
The cursor being set out-of-band with atomic commits creates problems
because it can create false positive for atomic tests, if the cursor
state gets changed in between an atomic test and its matching commit.
This commit also ports the cursor to a swapchain instead of only one
image. This is not strictly required but may prevent artifacts and
will be needed for future optimisations.
Context properties don't work with QML effects. At the moment, no effect
needs to access the options object, but it makes the QML API consistent.
The workspace is already a singleton type.
The natural geometry can live in a different coordinate space than the
target area. Remove the premature optimization so the cell is properly
placed if the two are in different coordinate spaces.
Currently, the ExpoLayout wants the natural geometry to be in the local
coordinate space because of the default layout mode.
With the natural layout, the ExpoLayout will run a simple loop that
repels overlapping cells.
Once no two items overlap, the items will be scaled down based on their
bounding rectangle and the target area.
The problem is that the ExpoLayout includes the area where items will be
eventually placed when computing the bounding rectangle, which can
result in a sort of a bug where almost all windows are shifted to one
side of the screen, which is not at 0,0.
This change removes the target area from the bounding rect math so the
coordinate space where natural geometry is specified is irrelevant.
It fixes the issue where windows can be shifted to one side of the
screen after adding or removing a window. It also makes the ExpoLayout
API more simpler on the QML side and ensures that no relayouting will be
performed if only the position of the WindowHeap changes.
If the decoration is destroyed before the window is mapped, kwin can
respond with a configure event that has 0x0 size. New tests check that
problematic case.
BUG: 444962
Kwin announces a format with alpha when Dma-Bufs are available, even
when the texture doesn't contain any. This results in clients segfault
when trying to access the buffer assuming a maxsize wrt. the announced
format by ways of dimensions and bpp.
This patch moves the format masking to affect the Dma-Buf transport
only.
If eglSwapBuffers() fails, there won't be a buffer and so we need to
mark the frame as failed. Otherwise, the screen can be frozen.
eglSwapBuffers() can fail if some effect calls makeOpenGLContext()
between RenderBackend::beginFrame() and RenderBackend::endFrame(), which
is the case with the zoom effect. It can set wrong draw surface in
ZoomEffect::recreateTexture()
BUG: 445412
This simplifies focus related logic a bit. Instead of differentiating
between wayland and internal window focus, simply maintain window focus
that works both with regular wayland windows as well as the ones created
by kwin.
The thumbnail that represents the "desktop" in the switcher preview
is taken from the default wallpaper, and it will update automatically
as it changes in future versions of Plasma.
The current one is also added along the other thumbnails as a fallback.
BUG: 309401
FIXED-IN: 5.24
Currently, the test doesn't pass due to Xwayland encountering a protocol
error.
That protocol error occurs because the xdg-output is destroyed before
the wl_output.
This change moves the ownership of the xdg-output to wl-output so they
are destroyed together.
dmabuf-feedback allows the compositor to give the clients better feedback on what
formats and modifiers they should use, and for which device they should allocate.
This way they can reallocate for scanout whenever the compositor tells them to,
which makes direct scanout work for a lot more devices and applications.
KWin handles several types of pointing input devices, e.g. mice,
tablets, etc.
As is, enterEvent and leaveEvent are very ambiguous. This change
prepends "pointer" to those methods to make it explicit that they handle
pointer enter/leave events.
While it could be useful with tiled displays, the isFormatSupported and
supportedModifier functions can be called before prepareModeset, so where
m_formats is still empty. Additionally they're neither in a hot path nor
performance critical.
Whether or not we want to use explicit modifiers for our surfaces doesn't
matter for what format+modifiers drm planes support. This way direct scanout
works by default, without having to explicitly enable modifiers
While a stylus is in proximity we want to show its cursor. In this commit
it only gets shown on move because for a still unknown reason the position
is out of date before the first move event.
BUG: 443921
Ever since the effects were changed to static, each test of the
integration tests includes all the effects. The result of this is that
when doing a debug build each test is now 60MiB or more. With the amount
of tests, this results in ~8 GiB of diskspace used just for KWin's
binary output directory, which is rather excessive.
Since the tests all share a common framework library, we can change that
library to a shared library and that way avoid linking all the effects
into each test.
Most of this is shuffling around some link libraries in the integration
test CMakeLists, however, I needed to export the Xwayland class as it is
used by one of the tests but wasn't exported.
Tracking AbstractOutput properties in Toplevel is not extensible. Since
DecorationItem is the only one who needs Toplevel::screenScale(), make
it track the output device pixel ratio.
systemd takes care of setting and dropping master permissions when
sending PauseDevice and ResumeDevice signals.
When the ResumeDevice signal is received, the relevant drm device should
already have master permissions set up.
On the other hand, when the active property changes, there's still a
chance that systemd haven't granted drm master permissions to us.
For some reason, while touch doesn't have a middle button, the
taphandler for middle click close still triggered on tap. So make it
explicitly only support mouse/pen so we exclude touch events.
BUG: 445755
In case a modeset needs to be performed, the drm backend will test all
pipelines to ensure that new mode won't cause any bandwidth issues on
other outputs, etc.
To do that, it may delay presenting frames. If the new configuration
doesn't work, it needs to notify about failed frames.
However, the relevant code that notifies the RenderLoop about failed
atomic commits doesn't check if there's actually a pending modeset
present.
When switching between VTs, systemd can revoke master permissions from
kwin. To make things even more trickier, kwin can try to present a frame
in that short time span.
For many windows it will be invisible, so there's little point for
creating it ahead of time. Another reason for loading the close button
on demand is that Plasma components are typically heavy.
Currently, MouseArea.doubleClicked doesn't work in QtQuick effects.
Luckily, the overview effect doesn't use it, but it's still worth making
sure that it works as expected regardless of whether it's a kwin effect.
With this change, the OffscreenQuickView will keep track of the last
mouse press event. If the second button press occurs within the mouse
double click interval, the OffscreenQuickView will generate a
QEvent::MouseButtonDblClick event, similar to what QGuiApplication would
normally do when processing window system events.
The current code performed two functions:
- metadata was read async
- the event loop is spun between each effect loading
After we merged static and binary plugins this caused a problem for
things like blur and background contrast where loading an effect
influences what we advertise as supported. We don't want plasmashell to
have to reload all it's SVGs.
All KDE provided binary plugins are statically bundled so querying for
plugins is super duper fast anyway. It's not the same kbuildsycococa
path that it used to be.
The C++ plugins tend to be considerably faster in their constructor than
scripted counterparts, and if anything should be loaded lazily it can be
handled inside the effect.
Set the implicit size of the item to the client frameGeometry size.
This is also more convenient for tabbox usage than accessing it through the
client's property, had a proper notify signal and abstracts it from the
implementation.
It also can be mimicked by the preview ThumbnailItem used in the tabbox KCM,
which has no client property.
The TabBox preview uses a mock WindowThumbnailItem mimicking the
real item, but it was missing the `sourceSize` property, preventing
some effects to be previewed if they use it.
This change moves some pieces of the Overview effect in a new
QuickSceneEffect class that can be useful for other QtQuick based
effects.
The QuickSceneEffect class is meant to deal with rendering bits, input
handling, etc.
As the user of the QuickSceneEffect class, you need to override the
createView() method. The createView() method is invoked by the
QuickSceneEffect when it wants to create a QtQuick scene for the given
screen.
The design of the QuickSceneEffect is based on the Overview effect.
EffectQuickScene is not used strictly by effects, aurorae decorations
use it too to render window decorations.
This change renames the EffectQuickView/Scene to
OffscreenQuickView/Scene to clear up the naming scheme.
Add `tabletToolEvent()` to DecorationEventFilter class so it can handle
tablet events.
Add `tabletToolEvent()` to MoveResizeFilter class to avoid incorrect
titlebar highlight after a window is resized by using a stylus.
Add `tabletToolEvent()` to WindowActionInputFilter class so window focus
can be changed by clicking on the window content area when using a stylus.
Add `update()` to `TabletInputRedirection::tabletToolEvent()` to enable
switching window focus by using a stylus.
BUG: 432104
This prevents flickering behind plasma panels after changing compositing
settings.
If the contrast effect is disabled, the destructor of the ContrastEffect will
start the contrast manager remove timer. When it expires, the contrast manager
global will be removed and it will be finally destroyed after 5s (to work
around the wl_global race condition).
If compositing is toggled, the destructor of the ContrastEffect will start
the remove timer and the constructor of the ContrastEffect will stop the
timer, the contrast manager object will be unaffected.
The contrast effect has no options that could affect the shader, so the
reconfigure() method was removed.
This prevents flickering behind plasma panels after changing compositing
settings.
If the blur effect is disabled, the destructor of the BlurEffect will
start the blur manager remove timer. When it expires, the blur manager
global will be removed and it will be finally destroyed after 5s (to work
around the wl_global race condition).
If compositing is toggled, the destructor of the BlurEffect will start
the remove timer and the constructor of the BlurEffect will stop the
timer, the blur manager object will be unaffected.
The blur effect options don't affect the generated shader code, so the
shader status check was removed in reconfigure().
This enables kwin to get notified when a memory has been lost in the
system, allowing the driver to purge all the memory and have kwin create
new contexts.
This matches what we do on GLX.
The current code for creating the root shared context is very naive and
does not take into account aspects like robustness or versions.
It is not always possible to mix attributes, in particular robustness
meaning we are unable to opt into these features in future contexts.
This refactors everything to use a common path to make all contexts.
In the KPluginSelector we don't have the possibility to set the args for
each KCM. Because of that we use the metadata of the KPluginFactory as a
fallback to read the plugin keyword, which specifies the KCM we want to display.
This requires kcmutils 54b196a9bad88732debe0b49111af4755268f09f, which landed in the last release.
BUG: 445667
The person that added krunner search integration uses vim. It seemed
intuitive to that person that the Escape key should quit the search mode
instead of quitting the effect. But it seems like more intuitive thing
is to actually stop the effect.
BUG: 445708
If the opacity property is set to 0, the item will still receive mouse
events. One either needs to set the enabled or the visible property to
false to ensure that the WindowHeap receives no mouse events.
The reason for setting the opacity to 0 instead of the visible property
to false was that I thought later will nuke the paint node, but it seems
like that's not the case.
BUG: 445707
This is needed to ensure that mouse release events go to the view that
received mouse press events; otherwise some views can get stuck in a
state thinking that button xyz is pressed.
Currently, cursor shape set by QtQuick is not sync'ed, which can be seen
as the pointer not changing its shape to i-beam when hovering the search
field.
Currently, every time you launch the overview effect, QtQuick will go
out and parse QML files. With the overview effect gaining more features
and the code size getting bigger, it takes more time for the overview to
present the first frame after it got triggered.
With this change, the overview effect will keep the ScreenView
QQmlComponent object around that can be used to avoid reparsing qml code
every time the overview effect is launched.
It also ports the Overview effect from de-facto deprecated qml context
to initial properties, which yield slightly better startup times.
BUG: 445666
This allows effects to support touch input.
Unfortunately, Qt's TouchEvents require the full touch point state,
whereas KWin's internal touch handling only deals with one point at a
time. So we need to keep track of the touch state in EffectQuickView and
pass that on to Qt. Additionally, we need a QTouchDevice as lots of Qt
code depends on it.
On my Nvidia machine there was a massive lag exitingthe overview effect.
Hotspot showed it as being in QOpenGLVertexArrayObjectPrivate::destroy.
In this method we clean up some shared objects used in the context when
the context closes.
In order to do this we need the context to be current. If it is not
current Qt currently internally creates a temporary offscreen surface.
To fix this we need to have our context current during destruction,
which includes changing order so it is destroyed before the surface.
With this change, user will be able to press Tab and use Enter, Delete,
and F2 keys to activate, remove, and rename virtual desktops, respectively.
Co-authored: Fushan Wen <qydwhotmail@gmail.com>
If a window wants to be initially shown in fullscreen mode, it will
issue an xdg_toplevel.set_fullscreen request before the first surface
commit.
If a window wants to be shown in fullscreen mode and there hasn't been
any first surface commit, kwin will cache the request and apply
fullscreen mode when checking window rules in the initialize() function.
On the other hand, window rules are disabled for plasma surfaces. The
motivation behind that was to forbid user from messing with plasma's
surfaces (this change was suggested during redesign of xdg-shell
implementation).
As it turns out, there are cases where plasma may ask to show a window
in fullscreen mode, which also has a plasma surface installed, e.g.
fullscreen application dashboard.
In order to fix the dashboard, this change allows window rules to be
applied to xdg-toplevel windows that also have plasma surfaces installed.
As is, xdg-toplevel surfaces and plasma surfaces are very different in
nature. Adding more quirks to handle plasma surfaces in
XdgToplevelClient is not worth the effort and there are better
alternatives, e.g. layer-shell.
Based on user feedback, it will be great to have krunner functionality
integrated in the overview/present windows effect.
This change ports the overview effect to Milou for search results. With
it, one can search for existing windows or launch new applications.
BUG: 445207
kwin-strip-effect-metadata needs to run on the host. First, one needs to
build it, e.g.
cmake --build build-native --target kwin-strip-effect-metadata
then when cross-compiling, point cmake to the native build directory, e.g.
cmake -DKWIN_HOST_TOOLING=${path}/build-native
This improves plugin loading times. As is, the main issue is the number
of builtin effects and the fact that each has a lot of translated
strings, which combined adds up to noticeable loading times. KWin itself
will never read those translated strings, it only needs two pieces - the
plugin id and whether the plugin is enabled by default.
This change adds a little helper to strip unnecessary info from metadata
files.
Fixes a crash I have with dpms + suspend, which was caused by the udev
event for updating outputs being called before the output got enabled
again. When DrmGpu::updateOutputs got called it removed the crtc from
the inactive output and then disabled the output afterwards. Instead,
only remove crtcs if an output is really disabled.
This also allows to generalize the logic for lease outputs, and could
in the future allow for faster dpms on/off switching.
This unifies frame hooks for OpenGL and QPainter render backends. There
are a couple of reasons why it's a good idea - it provides one mental
framework to start painting a frame, the Compositor will be able to
start and submit frames. The last one is very cool because it gives the
Compositor more power over compositing.
Besides unifying frame hooks, this cleans up a bit the arg naming mess
in endFrame(). As is, "damage" and "damagedRegion" are very confusing
names. "damage" arg has been renamed to "renderedRegion," because that's
what it is. The renderedRegion arg specifies the region that has been
repainted by the Scene. It's different from the damagedRegion as that
one specifies the surface damage, i.e. the difference between the
current and the next frame, while the renderedRegion may include a
region that had to be repainted to repair the back buffer. The main
reason why we need renderedRegion is the X11 platform. On Wayland, it's
unused.
In the future, we will need to extend this api with output layers.
The lanczos filter checks the screen size before rendering in
LanczosFilter::updateOffscreenSurfaces(), so this is not needed.
This simplifies lifetime handling of the lanczos filter, e.g. we
don't need to bother with opengl context anymore, and makes the
scene use less Screens' features.
On Wayland, a window can have subsurfaces. The spec doesn't require the
main surface and its sub-surfaces to have the same scale factor.
Given that Toplevel::bufferScale() makes no sense with Wayland windows,
this change drops it to make code more reasonable and to prevent people
from using Toplevel::bufferScale().
With a persistent vbo, kwin will allocate one big enough buffer and
allocate memory out of it.
In order to prevent overwriting vertex buffer data that is currently
being accessed by the GPU, fences are inserted at the end of frame.
The signaled fences are destroyed after the buffer swap operation, which
seems a bit odd because the just inserted fence most likely won't be
signaled. Perhaps it's a historical artifact?
This change rearranges fence cleanup so it's performed right before
starting a new frame. With it, kwin will most likely re-use the
previously used memory chunk because there will be plenty of time for
the fence to become signaled.
Another motivation behind this change is to make refactoring SceneOpenGL
code easier. As is, m_backend->endFrame() is wrapped in
GLVertexBuffer::endOfFrame() and GLVertexBuffer::framePosted(). With
that, the Compositor can't call m_backend->endFrame(), which can be
desired for cleaning up render backend abstractions.
Currently, when screencasting a window, kwin may render a window into a
temporary offscreen texture, copy that offscreen texture to the dma-buf
render target, and discard the offscreen texture.
Allocating and deallocating offscreen textures is inefficient. Another
issue is that the screencast plugin uses Scene::Window::windowTexture().
It's a blocker for killing scene windows.
This change introduces a base ScreenCastSource type. It allows us to
move away from Scene::Window::windowTexture() and make the dma-buf code
path efficient with applications such as Firefox that utilize
sub-surfaces.
With the ScreenCastSource, kwin can also provide screen cast frames with
arbitrary device pixel ratio.
Like top level clients, apply plasmashell roles to popups as well (limiting them, don't allow dock or desktop roles in poups as they don't make sense)
This makes possible to recognize plasma tooltips as tooltips, treating them in a way closer to X, and makes morphingpopups work on wayland
After user edits the name of a desktop, the search field is no longer
focused. If the user starts typing text, one could expect that it will
be forwarded to the search field without requiring a click.
This change forwards unhandled key events to the search field to ensure
that searching is intuitive.
Since binary effects are installed in their own directory, checking
service type is redundant. Also, KPluginMetaData::serviceTypes() has
been deprecated.
Task: https://phabricator.kde.org/T14483
The ifdefs for have_gbm obfuscate the code unnecessarily - the drm backend
is not a great experience with qpainter, so in practice noone should ship
it without gbm anyways.
The Compositor contains nothing that can potentially get dirty and need
repainting.
As is, the advantages of this move aren't really noticeable, but it
makes sense with multiple scenes.
Backend parts are far from ideal, they can be improved later on as we
progress with the scene redesign.
The main idea behind the render backend is to decouple low level bits
from scenes. The end goal is to make the render backend provide render
targets where the scene can render.
Design-wise, such a split is more flexible than the current state, for
example we could start experimenting with using qtquick (assuming that
the legacy scene is properly encapsulated) or creating multiple scenes,
for example for each output layer, etc.
So far, the RenderBackend class only contains one getter, more stuff will
be moved from the Scene as it makes sense.
The proprietary NVidia driver now supports gbm, which vastly improves the
user experience. For older devices that will not get gbm support dropping
EglStreams will likely not have a big impact as it has several session breaking
issues anyways.
By removing the backend a lot of logic can be simplified, most notably multi-gpu.
The current "Minimize Overlapping" window placement tends to position
windows in locations that seem completely random, typically in a screen
corner. It is doing this because, true to its name, it is trying to
avoid overlapping other windows as much as possible. However in practice
this is rarely helpful. When the user opens a new window, it's because
they want to use it, and positioning the window far from where the
user is likely to be looking is counter-productive. This is even more
true on today's large and wide displays, where placing the window in a
corner may position it entirely outside the user's current field of
vision. We get bug reports about this exact issue for notifications
(which always appear in a corner by default) by users of such screens.
For notifications, this can be justifiable because notifications are
designed to be ignorable; app windows on the other hand, are not.
As a result, I commonly see Plasma users open windows and then
immediately, reflexively grab the window's titlebar and drag it to the
center of the screen. I have seen my wife do this. I have seen every
YouTube reviewer of Plasma do this. I have even see fellow KDE
developers at sprints do this. It seems like quite a common impulse
to want a newly-opened window to appear in the center of the screen,
which is where the user is likely to already be looking.
Thankfully, KWin already has a window placement mode that does this
automatically: "Centered". Accordingly, this commit changes the default
KWin window placement mode from "Minimize Overlapping" to "Centered".
No kconf migration script is provided because this is a better default
for most people in most cases, and existing users are highly likely to
appreciate this change.
The main motivation behind this change is to move management of drm
blobs out of property wrappers in specialized wrappers to simplify state
management with blobs.
Connector mode blobs are created on demand.
When we switch CRTCs it can happen that a CRTC would stay enabled yet has
no connectors anymore. In this case the kernel may reject our atomic commit,
which would cause the modeset to fail. To counteract that, properly disable
unused drm objects
Currently KWin is combining modesets with presentation, which causes problems
when multiple monitors are used and crtcs need to be switched around, because
taking away a CRTC from another output causes the driver to disable the
other output. In order to avoid such problems, delay presentation until
all pipelines are ready to present and then do a modeset with a single atomic
commit. To process the resulting page flip events properly this commit also
ports KWin to page_flip_handler2 and changes how the pageFlipped and
notifyFrameFailed signals are processed.
Hardware constraints limit the number of crtcs and which connector + crtc
combinations can work together. The current code is searching for working
combinations when a hotplug happens but that's not enough, it also needs
to happen when the user enables or disables outputs and when modesets are
done, and the configuration change needs to be applied with a single atomic
commit.
This commit removes the hard dependency of DrmPipeline on crtcs by moving
the pending state of outputs from the drm objects to DrmPipeline itself,
which ensures that it's independent from the set of drm objects currently
used. It also changes requests from KScreen to be applied truly atomically.
The GlStrictBinding flag indicates whether it's okay not to re-bind the X11
pixmap to the OpenGL surface texture if the corresponding window is damaged.
It doesn't really affect the SceneOpenGL, only low level backend stuff.
This ensures that the window will have correct geometry if a maximized
window changes preferred decoration mode. X11Client does something
similar, see X11Client::updateShape().
In hindsight, perhaps, AbstractClient::{create,destroy}Decoration() must
preserve the old frame geometry, but it's not clear how to do that
because it requires decoration updates to be truly async, otherwise
there will be ugly flickering.
Currently, the scene owns the renderer, which puts more
responsibilities on the scene other than painting windows and it also
puts some limitations on what we can do, for example, there can be only
one scene, etc.
This change decouples the scene and the renderer so the scene is more
swappable.
Scenes are no longer implemented as plugins because opengl backend
and scene creation needs to be wrapped in opengl safety points. We
could still create the render backend and then go through the list
of scene plugins, but accessing concrete scene implementation is
much much simpler. Besides that, having scenes implemented as plugins
is not worthwhile because there are only two scenes and each contributes
very small amount of binary size. On the other hand, we still need to
take into account how many times kwin accesses the hard drive to load
plugins in order to function as expected.
This allows using base opengl backends in libkwin, which can be useful
later on for the purpose of moving the ownership of render backends from
the Scene class to the Compositor class.
It has been disabled with Mesa for almost half a decade due to false
positives and even if it weren't disabled, it contributes to the startup
time.
The commit message that added the self test doesn't explain why it was
added, but if it was added to detect unstable drivers, it's not worth it.
With an opaque fullscreen window we can be sure that items under it don't
actually require us to repaint. This should yield some small efficiency
improvements and resolves stutter with adaptive sync.
BUG: 443872
FIXED-IN: 5.23.3
Windows in workspace.clientList() are sorted in the map order. This
means that the minimize all script will try to activate the last mapped
window when unminimizing windows, which is a bit annoying.
This change ensures that the minimize all script doesn't activate wrong
window by minimizing and unminimizing windows in the stacking order.
It's not a bullet-proof solution though, but it should produce good
enough results.
This improves file organization in kwin by putting backends in a single
directory.
It also makes easier to discover kwin's low level components for new
contributors because the plugins directory may come as the last place to
look for. When one hears "plugin", the first thing that comes to mind is
regular plugins, not low level backends.
This ports the nested wayland platform plugin to the InputDevice
abstractions.
Some global handling logic has been simplified to make porting more
straightforward.
The main motivation behind this change is to prepare input abstractions
for virtual input devices so the wl_seat can properly advertise caps or
the cursor getting properly mapped/unmapped when a fake pointer is
added/removed on a system without a hardware mouse connected.
With this, there are three abstractions - InputDevice, InputBackend, and
InputRedirection.
An InputDevice represents an input device such as a mouse, a keyboard, a
tablet, etc. The InputBackend class notifies the InputRedirection about
(dis-)connected devices. The InputRedirection manages the input devices.
Such design allows to unify the event flow for real and virtual input
devices.
There can be several input backends active. For example, the libinput
backend and an input backend that provides virtual input devices, e.g.
libeis or org_kde_kwin_fake_input.
If an output is disconnected, the Workspace will update the
Toplevel.output property for all windows that are on that output, then
it will call AbstractClient::checkWorkspacePosition() to fix window
position.
That may result in some windows partially sticking outside visible area
because AbstractClient::checkWorkspacePosition() has no idea what output
the window was.
This change addresses that problem by delaying updating the
Toplevel.output property so AbstractClient::checkWorkspacePosition()
could pick better window placement.
The role of enabledByDefaultMethod was misinterpreted. It exists only
for kcms so they can display undetermined state. EnabledByDefault should
still be set to a valid value.
Currently, if an output is hotplugged, all windows will be scrambled,
which is highly annoying.
With this change, windows will stick to their outputs if an output has
been connected or disconnected.
BUG: 296673
BUG: 378896
BUG: 412703
BUG: 443698
Currently, AbstractClient::geometryRestore() is abused to put windows
back on their original screen. It makes window placement more complex
and it breaks restoring initially maximized windows.
After the decoration is destroyed, we need to resize XdgToplevelClient
to ensure that the scheduled configure event will have correct size.
As is, xdg-toplevel configure events are delayed. When it's actually the
time to send a configure event, XdgToplevelClient will compute the
requested client size from the moveResizeGeometry().
If the moveResizeGeometry() still includes window decorations, the
window will get bigger.
BUG: 444119
For optimization purposes, kwin will ignore repaint regions scheduled by
invisible windows, e.g. hidden docks, minimized windows, etc.
The problem is that it sort of breaks w->addRepaintFull(). If a lot of
animation frames are dropped, for example due to heavy cpu load, the
sliding popups animation can jump from the middle of animation right up
to the end. It will schedule a repaint but it will be ignored.
In order to work around that issue, this change makes the sliding popups
effect schedule workspace repaints in postPaintScreen() to ensure that
the Scene will always repaint dirty regions.
Hopefully, this should fix bugs where auto-hide panels sometimes flicker
on Wayland.
BUG: 444502
Without spacing it is not immediately evident where a doc comment
ends and a new declaration begins. Adding a line of whitespace
makes everything more readable and easier to scan quickly.
Currently, input events can flow directly to input device handlers and
sometimes they go through the InputRedirection, which simply forwards
them to the corresponding input device handler.
In case the user has just the one display but they don't want to show it
in their main workspace when sharing video, allow creating a virtual
display.
This also will allow using remote devices as support displays.
The WindowThumbnail item uses the GLTexture class. In order to destroy
the thumbnail texture, the item will schedule a destroy job.
This means that the GLTexture can be alive during or after graphics
reset.
On the other hand, as an implementation detail, GLTexture::clear() may
allocate a framebuffer object, which is going to be destroyed together
with the last texture.
Given that window thumbnail textures can be still alive after a graphics
reset and the fact that GLTexturePrivate::s_fbo gets destroyed when the
last texture is destroyed, kwin can end up trying to clear a decoration
texture with now defunct s_fbo.
Since the old old s_fbo is inert, the glBindFramebuffer() function will
fail and the glClear() operation will affect the default framebuffer,
thus leading to black flickering visual artifacts.
In order to fix that issue, this change makes GLTexture destroy s_fbo
unconditionally in GLTexturePrivate::cleanup() which is called whenever
OpenGL stuff is about to tear down, e.g. due to graphics reset, etc.
BUG: 443951
Without this there can be a mismatch between what clients expect and what
KWin actually uses, causing for example stutter in video players.
BUG: 444303
FIXED-IN: 5.23.2
InputDeviceHandler keeps track of which client has focus, and whether
the decoration or main window has focus.
Should the decoration get destroyed whilst the decoration has focus we
don't update correctly. This can happen when
"BorderlessMaximizedWindows" is set, or if you use key presses whilst
above the decoration.
cleanupDecoration (which is an odd name) is called whenever a decoration
gains or loses focus. Here we can connect for the decoration destruction
and force a focus change.
BUG: 411884
The screen count can be retrieved by checking the number of items in the
EffectHandler.screens property.
The replacement for the numberScreensChanged signal are the screenAdded
and the screenRemoved signals.
The main motivation behind this change is to clean up the screens api
and reduce the number of usages of the Screens class.
This provides a way to create, destroy, and rename virtual desktops in
the overview effect as well as switch between desktops.
The mechanics of switching between virtual desktops can be revisited
later though.
This can be useful for QML scripts that deal with virtual desktops.
The virtual desktop model keeps a copy of virtual desktop objects to
avoid hitting asserts in QAbstractItemModel (it has some asserts to
ensure that indices passed to beginInsertRows() or beginRemoveRows()
make sense).
When we're adding the output to the EglGbmBackend pipelines aren't necessarily
setup yet and are thus missing the modifier list. As creating the gbm surface
immediately is useless anyways, delay that until we need it, where the modifier
list is available.
First we check to see if the color scheme has header colors, and if it
doesn't, we turn around and ask for them anyway, relying on implicit
behavior in kcolorscheme that falls back to Window colors when Header
colors are requested but are not present. Instead, let's just ask for
Window colors to avoid the run-around and stop relying on implicit
behavior.
Currently, idle timers are not restarted on user input which triggers
the lockscreen even though the user is active at computer.
This change fixes that by making sure that idle timers are restarted
whenever SeatInterface's timestamp changes, i.e. user moves the pointer
or presses a key, etc.
Linking builtin effects against KCMs is really awkward. This change
decouples builtin effects from KCMs that use EffectsModel.
In order to discover builtin effects, metadata files are installed in
kwin's data dir, which will be subsequently read by EffectsModel.
The main motivation behind this change is to prepare kwin for importing
kwayland-server code in libkwin.
As is, builtin effects are linked with libkwin. Some builtin effects
have wayland specific code. If we move wayland stuff in libkwin, there's
going to be a circular dependency between kwin4_effect_builtins and
libkwin targets.
This change intends to break that dependency by linking builtin effects
to kwin executable.
The main issue with that is that EffectLoader would need to discover the
effects indirectly. QStaticPlugin is used for that purpose.
Besides breaking the cyclic dependency, it makes builtin effects use the
same plugin infrastructure in libkwineffects that external effects use.
Metadata in src/effects/effect_builtins.cpp was converted in a list of
python dictionaries, which was fed to a python script that generated
main.cpp and metadata.json files.
As is, libkwineffects doesn't use any specific apis in kwayland-server,
it simply "forwards" wayland display and surfaces from libkwin. Given
that, there is no need to link libkwineffects with kwayland-server. If
an effect needs to access wayland specific stuff, it can link explicitly
against kwayland-server.
The main motivation behind this change is to further loosen up
dependencies between various kwin components and kwayland-server so the
latter can be moved back to kwin.
Before attempting to create scenes, kwin will redirect windows but if
the opengl scene can't be created, it won't unredirect windows, which
seems to cause issues on aarch64.
BUG: 443953
API-wise it's odd to require absolute position with relative pointer
moves.
This cleans up some of InputRedirection code by making it simply forward
pointer input events from input devices to the pointer input device
handler, which knows better what to do with the delta value.
The pointer input device handler will compute the absolute position based
on the specified delta value, but it could also do something else, e.g.
not move the pointer at all if it's locked, etc.
When geometry updates are blocked, the output doesn't get updated. This
breaks Workspace::clientArea() overload that takes only the window.
Previously, clientArea() would look up the output where the window is
every time it's called, so the fact that the screen id or AbstractOutput
is unsynchronized with the frame geometry was irrelevant.
This change restores the old behavior as 5.23 is affected by the
output() being out of sync with the frameGeometry(). Specifically, when
kwin starts managing an X11 window, it will block geometry updates,
setup the window, e.g. make it fullscreen, and unblock geometry updates.
Since Workspace::clientArea(clientArea, Toplevel) uses the output(),
X11Client::setFullScreen() will most likely put the X11 window at a
wrong output if it's called inside X11Client::manage().
BUG: 443787
AbstractEglBackend includes option.h, which includes main.h, which
includes QApplication. Since SceneOpenGLBackend doesn't link against
Qt::Widgets, kwin fails to build on Gentoo, but not on other distros
for some reason...
Abstract clients tolerate passing the shaded window geometry to
moveResize().
But the main issue with applyWindowRules() is that it uses the current
frame geometry even though it calls moveResize(). It's not a big deal
but it's error prone.
This change ports applyWindowRules() to the move resize geometry, which
makes code more straightforward and ensures that kwin uses right
geometry type with moveResize().
X11Client tolerates passing shaded geometry to moveResize() and in many
cases kwin already does that.
Another issue is that this doesn't align well with new async geometry
handling abstractions. pos() can't be used because it corresponds to the
current frame position.
We can safely pass the last move resize geometry. It simplifies code a
bit and makes sure that everything works as expected with the move
resize geometry.
Currently, adjustedSize() does two things - it computes and constrains
the natural size of the window.
In many places where adjustedSize() is used, the natural size doesn't
need to be constrained and in some it's actually undesired because
AbstractClient::constrainClientSize() doesn't allow the client size to
be 0x0, which can happen when dealing with a client that has no buffer
committed yet.
This change replaces adjustedSize() with implicitSize(), which simply
calculates the natural frame size based on the current client size.
If the frame size needs to be constrained, for example during
interactive move-resize, use constrainFrameSize() or if you need to
constrain the client size - constrainClientSize().
Trying to reconstrain the geometry after applying rules is unnecessary
because if the geometry is forced using a rule, resizeWithChecks()
should not change it; if the window is maximized or has entered fullscreen
mode, window gravity is irrelevant. If the window is shaded, this
resizeWithChecks() is not needed.
This change simplifies AbstractClient::applyWindowRules(), which allows
to split adjustedSize() to further simplify geometry handling.
Prefer hiding/showing the panel (i.e. the window) when not a touch event
than stopping to make the inputmethod active.
This way we remain compatible with non-virtualkeyboard inputmethods.
The bounding rect of an item is in the item-local coordinate space. If
the item is moved, its bounding rect won't change, but the parent's
bounding rect, may change.
BUG: 443756
AbstractClient::constrainClientSize() forces the minimum client size of
1x1.
If AbstractClient::adjustedSize() is called before the XdgToplevelClient
is mapped, it will return 1x1 rather than 0x0 as expected, which will
confuse
QSize s = adjustedSize();
if (s != size() && s.isValid())
resizeWithChecks(s);
in AbstractClient::applyWindowRules(). Since 1x1 is different from 0x0,
the xdg-toplevel surface is going to be resized to 1x1.
BUG: 443705
Whether relative pointers are supported doesn't depend on the input
backend. This change moves the instantiation of the extension to the
WaylandServer class to make code more consistent.
With the LEDs enum being defined in kwinglobals.h, wayland_server.h
won't need to include keyboard_input.h, which is good for compilation
times and wayland_server.h will drag less stuff, e.g. QtWidgets (input.h
includes QAction)
Currently, cpp source files are included partially in effect sub-folders
and src/effects/CMakeLists.txt, which is really confusing and hard to
follow.
With this change, effect targets will be defined in their own subfolders.
This makes build files more straightforward.
Effect sub-targets are eventually merged into a monolithic
kwin4_effect_builtins target.
Another reason for modularizing builtin effects is that no two effects
can generate moc files with the same name atm even though they are in
different sub-folders. This can be potentially useful in the future, e.g.
making effects static plugins in order to decouple builtin effects from
libkwin (every effect subfolder would need a main.cpp or plugin.cpp file,
which will include the associated moc file).
The GLTexture class is forward declared and the ShowFpsEffect class has
a QScopedPointer<GLTexture> field. We either need to include the
kwinglutils.h header file or add a destructor that does nothing and
define it in the cpp file, where kwinglutils.h is included.
At the moment we'll be setting the YInverted setting, but in practice
that won't have any effect as it only changes the render matrix and
we'll end up streaming inverted textures.
This change addresses it by rendering it into another texture first to
resolve this situation and then download that new texture instead.
The English word "pack" is not really the correct word for these
actions, and does not succeed in communicating what they will do. Since
the actions simply move the active window as far as it will go in the
specified direction, the actions can be renamed to say that instead.
Also rename the action names in the code to match their new UI text for
clarity.
With lv3:ralt_alt ("Right Alt never chooses 3rd level") option set, we
get more layouts from libxkbcommon than it was configured, see:
https://github.com/xkbcommon/libxkbcommon/issues/262
It might be correct lib's behavior, still.
The extra layouts are redundant, so we strip them out from usual usage.
BUG: 440027
This change merges the two OpenGL backends into one making the current
default of GLCore the overall default. It becomes the first context to
try to create. If it fails, it will automatically fall back to the
(previous) OpenGL 2 backend.
Reasoning: the differentiation of OpenGL 2 and 3 is a very technical one
and hard to understand for users. It is not obvious which one is better
or should be used. This results in many user discussions like "Which
backend to use?"
Back when the OpenGL 3 backend was introduced the dedicated feature made
sense. It was a new code base using new driver features. Nowadays the
code base in KWin is robust and mature and so are the drivers. A driver
advertising support for OpenGL 3 will support OpenGL 3. We don't have to
plan for driver breakage in this area any more.
Also our code evolved through the context attribute builder which gives
us the possibility to more easily fall back in case we cannot create the
context. Thus the need to select the backend is not so important as it
used to be when the feature got introduced.
If a user still wants to force OpenGL2, it is still possible by setting
the appropriate environment variables like MESA_GL_VERSION_OVERRIDE.
This change brings the improvement that the backend selection is now
completely removed from the compositing KCM.
Currently, the pointer is moved to the center of the workspace. However,
on a multi-monitor setup, the workspace center may not be the same as
the center of the output it's on. That's the case with my setup -
1920x1080, 1920x1080, 1080x1920 (the monitors are laid out in a row from
left to right).
This change improves the default placement of the pointer by actually
moving it to the center of the screen that contains the workspace center
so the pointer doesn't end up at some "random" position from the user's
point of view.
Edge geometry has width and height, so we need the correction for
approach geometry of bottom and right corners.
The other edges are fixed as well.
BUG: 442973
On X11, there are four input models. With some input models, it's okay
if the window manager calls XSetInputFocus(), with others, the wm has to
ask the client to make a XSetInputFocus() request.
If kwin wants a client to take input focus, kwin will add the client
to the should_get_focus list, which contains all the windows that
are about to get input focus. Clients are popped from the list upon
receiving FOCUS_IN events.
A client will be added to the should_get_focus list even if kwin thinks
that the client already has input focus because communication between
the wm and xorg is async, anything can happen with input focus in meanwhile.
On the other hand, the wm may sometimes focus the null window if no
window should contain the input focus. The issue is that the
should_get_focus list is not cleaned up in that case, which can lead to
Workspace::mostRecentlyActivatedClient() returning wrong client and
possibly other async related issues.
We don't have such madness on Wayland as the compositor is in charge of
handling input focus.
This change makes Workspace::focusToNull() clear the should_get_focus,
which is reasonable. We need to deactivate "in-flight" focus requests.
This also fixes the bug where fullscreen Wayland windows don't go above
docks and panels due to Workspace::mostRecentlyActivatedClient() returning
bad client.
BUG: 439405
BUG: 395919