This is an approach for aurorae engine to publish masks for its decorated windows in order to avoid out of window blurring at the decoration corners. Aurorae themes are now able to specify a **mask** element inside **decoration.svg** file like plasma themes already do. Mask is used afterwards to calculate theme's blur region.
| Before | After |
| ------ | ----- |
|![before](/uploads/26014e79c3d5d45ba12fa5cf62294b1c/before.png)|![after](/uploads/923d7021eaaf322be96b611c73558666/after.png)|
Adjusted Aurorae theme for testing: [ROUNDED-DARK.tar.gz](/uploads/082f60ad4311e3e296b7faeeb7c97dac/ROUNDED-DARK.tar.gz)
BUG:395725
Otherwise the connection isn't severed when the layer is destroyed,
leading to crashes when screen resolution changes.
We don't actually need `this` to access `workspace()`, and we have
a guarded `output` as sender in the other case.
Notifications are really only useful in a setting with a full
shell environment where there is a notification center to display them.
Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
This commit expands the QImage-to-GL formatTable to include entries
for RGBX64, RGBA64_Premultiplied, and Grayscale16 image formats.
Uploading 16-bit-per-channel formats is supported by OpenGL and, with
the GL_EXT_texture_norm16 extension, GLES.
This ensures that we get a warning if the config header is not included
instead of compiling the code as if it was disabled. Interestingly, some
checks already used #if KWIN_BUILD_*, so those were generating -Wundef
warnings when the feature is disabled. Commit 886173cab assumed that all
those features were already 01, so this unbreaks the build if any of the
features is disabled.
Fixes: 886173cab ("Reduce ifdefs in Workspace::supportInformation()")
We should use the output area as the margin size as where to position
rather than the panelSize.
This ensures that the keyboard ends up in the right place right above
the panels.
This reverts commit 3d0bdc56a4.
seat->setFocusedPointerSurface() before notifyPointerMotion() is needed
to prevent sending a motion event that's outside the previously focused
surface.
BUG: 449273
It is automatically called (and documented as such) by KCModule
after the constructor is run.
This avoids calling a virtual method from the constructor.
Signed-off-by: Eike Hein <eike.hein@mbition.io>
None of the features it adds ontop of `QComboBox` are used.
Allows to drop the dependency on KCompletion.
Signed-off-by: Eike Hein <eike.hein@mbition.io>
Instead of having the render backends manage layers, have DrmGpu and DrmPipeline
do it. This makes it possible to unify code paths for leased and normal
outputs, remove some redirection and have more freedom with assigning layers
to screens.
It's leftover after the times when widget style was using wayland
connection. Breeze had to destroy all wayland resources before
terminating the internal connection.
Currently, the blur effect will shrink an opaque region even if it
doesn't intersect m_currentBlur.
This ensures that the blur effect won't do a stupid thing such as
clipping the opaque region of the desktop window.
We already try to ensure that the surface damage is within render target
bounds. Avoid clipping surface damage in render backend, which is a bit
excessive task and perhaps it should be done an abstraction level above.
If the main surface is translucent (e.g. it contains only the drop
shadow) but its subsurface is opaque, the "window->isOpaque()" check
will produce a false positive.
It's not guaranteed that there will be current render target in
postPaintScreen() as all painting have been completed. paintScreen() is
a much safer place to pick color.
It's not guaranteed that there will be current render target in
postPaintScreen() as all painting have been completed. Furthermore,
even the docs of the postPaintScreen() function indicate that no
painting should be done there, you can do only cleanup things, e.g.
schedule a repaint, etc. paintScreen() is a much safer place to
capture screenshot.
When casting from integer to pointer, promoting the integer to (u)intptr_t
will ensure that the resulting type can be converted to a pointer without
problems. These two casts changed in this commit trigger a warning when
building for CHERI-enabled architectures such as Arm Morello. This is not
just limited to CHERI, the cast from xcb_pixmap_t (uint32_t) to void*
should also be flagged by -Wint-to-void-pointer-cast when using Clang,
however, it appears that warning only handles C-style casts, and not
reinterpret_cast (https://github.com/llvm/llvm-project/issues/53964).
Software cursor has always been a major source of problems. Hopefully,
porting it to RenderLayer will help us with that.
Note that the cursor layer is currently visible only when using software
cursor, however it will be changed once the Compositor can allocate
a real hardware cursor plane.
Currently, software cursor uses graphics-specific APIs (OpenGL and
QPainter) to paint itself. That will be changed in the future when
rendering parts are extracted from the Scene in a reusable helper.
At this point, it's safe to assume that only X11 has weird rendering
model, which stands in the way of making rendering abstractions nice and
intuitive, so let's check operation mode. If OperationModeX11 is
dropped, this will also simplify finding X11-specific code in kwin.
This is the first tiny step towards the layer-based compositing in kwin.
The RenderLayer represents a layer with some contents. The actual
contents is represented by the RenderLayerDelegate class.
Currently, the RenderLayer is just a simple class responsible for
geometry, and repaints, but it will grow in the future. For example,
render layers need to form a tree.
The next (missing) biggest component in the layer-based compositing are
output layers. When output layers are added, each render layer would
have an output layer assigned to it or have its output layer inherited
from the parent.
The render layer tree wouldn't be affected by changes to the output
layer tree so transition between software and hardware cursors can be
seamless.
The next big milestone will be to try to port some of existing kwin
functionality to the RenderLayer, e.g. software cursor or screen edges.
The responsibilities of the Scene must be reduced to painting only so we
can move forward with the layer-based compositing.
This change moves direct scanout logic from the opengl scene to the base
scene class and the compositor. It makes the opengl scene less
overloaded and allows to share direct scanout logic.
Xcursor loading code has hardcoded search paths, in order to take into
account distros installing app data in a different location,
libwayland-cursor sets the ICONDIR to the icon directory computed based
on the install prefix.
However, that won't work with gitlab CI because it relocates binaries. A
more robust way to find cursors would be to use QStandardPaths to find
all the icon directories on the system.
Another advantage of using own cursor loading code is that it allows us
to reuse cursor images that are symlinks. For example, with
breeze_cursors, almost half of the files in the cursors directory are
symlinks.
The main disadvantage of this approach is that we would have to keep the
search paths up to date. However, on the hand, there are not that many
of them, e.g. ~/.icons, ~/.local/share/icons, /usr/share/icons,
/usr/local/share/icons. The last three are implicitly handled by the
QStandardPaths.
It's specified as a Path in the kcfg file and the KCM will replace the
/home path into $HOME, and I imagine it may do some others likethat.
BUG: 450430
Rather than assuming the input panel to always be less than or equal to
the maximized area, ensure it is. This ensures that the input panel gets
placed correctly when there maximized area is smaller, like when there's
a panel on the side.
Additionally, don't skip the entire positioning code when "m_output" is
empty, to avoid the placement not happening when Kickoff is open.
Whilst global shortcuts are blocked by grabbing the keyboard, user set
up manual scripts can still invoke a global action.
Given we already have code to deactivate when locking it makes sense to
also prevent activation.
BUG: 450331
qApp is defined differently depending on whether QCoreApplication,
QGuiApplication, or QApplication is included.
Use QGuiApplication::instance() to improve code readability.
CCBUG: 450359
qApp is defined differently depending on whether QCoreApplication,
QGuiApplication, or QApplication is included.
Use QGuiApplication::instance() to improve code readability.
CCBUG: 450359
This really should not fail unless we did something seriously wrong
on our end, such as changing GL context during paintScreen.
If we add an invalid `GLSync` to the queue it can lead to very hard
to debug crashes in seemingly unrelated parts of the rendering
process, when the queue is drained, potentially seconds after the
actual failure that occurred here.
Signed-off-by: Eike Hein <eike.hein@mbition.io>
If a window appears on the screen, the highlight window effect will try
to fast-forward animation to the target state by setting the animation
duration to 0. However, TimeLine doesn't like that because it will
eventually lead to division by zero.
This change makes the highlight window effect fast-forward the
transition to highlight or ghost state by using the complete() function.
BUG: 450323
Allows to drop the direct dependency on KDeclarative only used
for `QmlObjectSharedEngine` outside of `KCModuleQML`
Signed-off-by: Eike Hein <eike.hein@mbition.io>
paintScreen() already tries to ensure that the damage region doesn't go
outside the scene geometry. With this change, it will try to clip the
damage region to the render target rect, which saves us an extra region
intersection and simplifies code that calls paintScreen().
Having a render loop in the Platform has always been awkward. Another
way to interpret the platform not supporting per screen rendering would
be that all outputs share the same render loop.
On X11, Scene::painted_screen is going to correspond to the primary
screen, we should not rely on this assumption though!
Neither SceneQPainter nor SceneOpenGL have to compute the projection
matrix by themselves. It can be done by the Scene when setting the
projection matrix. The main benefit behind this change is that it
reduces the amount of custom setup code around paintScreen(), which
makes us one step closer to getting rid of graphics-specific paint()
function and just calling paintScreen().
This allows us to make the GLRenderTarget a bit nicer when using it to
wrap the default fbo as we don't know what the color attachment texture
is besides its size.
This means that the responsibility of ensuring that the color attachment
outlives the fbo is now up to the caller. However, most of kwin code
has been written that way, so it's not an issue.
It's effectively unused and removing it allows us to get rid of
GLTexture field, which is very useful for abstracting the concept of a
"render target" across OpenGL and QPainter backends.
It's currently being used only by the X11 standalone backend. We should
either port the X11 backend to manual dirty state tracking or waiting
until it gets dropped. The main motivation for getting rid of the dirty
state tracking in the GLTexture is that it keeps kwin open for
alternative opengl wrappers, e.g. QOpenGL, and it simplifies GLTexture
code.
Because the GLRenderTarget and the GLVertexBuffer use the global
coordinate system, they are not ergonomic in render layers.
Assigning the device pixel ratio to GLRenderTarget and GLVertexBuffer is
an interesting api design choice too. Scaling is a window system
abstraction, which is absent in OpenGL or Vulkan. For example, it's not
possible to create an OpenGL texture with a scale factor of 2. It only
works with device pixels.
This change makes the GLRenderTarget and the GLVertexBuffer more
ergonomic for usages other than rendering the workspace by removing all
the global coordinate system and scaling stuff. That's the
responsibility of the users of those two classes.
In order to support layered rendering and tiled outputs KWin needs to be
able to split rendering of outputs into multiple surfaces. This commit
prepares the drm backend for that, by moving most of the code in EglGbmBackend
out to a EglGbmSurface class, which will later be used for overlay surfaces
and rendering to multiple connectors side by side.
In doing that, this commit also cleans up the code a bit, removes a lot of
now unnecessary multi-gpu stuff and potentially makes modesets a little
bit more efficient by re-using resources more often.
This allows to track per effect dependencies more precisely. The main
problem with a library and a comment next to it saying who needs it is
that the comment can get easily outdated.
/proc/%/exec always points to the canonical/real path of a binary,
the exec field of a .desktop might contain a symlink and therefore
differ from canonical path.
Explicitely canonicalizing the path in exec prevents this mismatch.
The first move() in X11Client::createDecoration() will alter the client
size, which will result in the subsequent resize() incorrectly resizing
to a smaller window size.
In order to fix that issue, this change makes X11Client adjust the
frame geometry atomically after creating or destroying window decoration.
BUG: 449988
If the window is initially maximized, there won't be any current
decoration when XdgToplevelClient changes the maximize mode, we need to
use m_nextDecoration.
BUG: 450053
With the xdg_toplevel.configure_bounds event, the compositor will be
able to indicate the client the maximum desired surface size.
It can be used to prevent mapping too big application windows, etc.
We're setting this env variable because earlier we used it to force kwin to use its special QPA so we need to change that back to something sensible.
However setting it to Wayland breaks apps that ship their own Qt with missing or broken Wayland support.
Set it to be empty instead. Well-behaved Qt apps will use Wayland regardless because of XDG_SESSION_TYPE.
BUG: 450000
When a window leaves the current virtual desktop, we need to schedule a
workspace repaint so the compositor repaints the old region of the
window on the current desktop.
In hindsight, the scene graph must schedule a repaint, but it's not
doable with the current effects api, it will be changed with future
refactoring changes.
BUG: 444172
Otherwise we get the filename to the library and not the KPackage.
The plugin having this set is most likely a leftover, because KPackage plugins
to not need to define a library.
BUG: 449881
QPlatformScreen::virtualSiblings() must return a list of screens on the
virtual desktop, otherwise QToolTip will use
QGuiApplication::primaryScreen() instead of looking up the screen where
the decoration tooltip must be shown using QDesktopWidget::screenNumber().
BUG: 432860
recordFrame requires an openGL context. This is typically done after a
frame is rendered, but when we send a frame after a cursor move this is
not guaranteed.
BUG: 448162
Despite the argument naming, the input for WindowMotionManager::calculate is supposed to be a
delta, not an absolute time. Giving it a delta fixes the PresentWindows in the DesktopGrid.
BUG: 443971
The quads for the left and right window decorations were broken in
3b4d55837. The problem is only visible for window decorations with more
than one color.
Currently, if kwin_wayland crashes at shutdown, the launcher can
potentially spawn it again. This change addresses that issue by making
the wrapper ignore the QProcess::finished() signal.
Mixing of current and next state can create all sorts of undefined
behavior, e.g. windows not moving to the desired location or
experiencing issues when tiling a maximized window.
BUG: 449541
Currently, the Cursors::currentCursorChanged signal is wired to the
updateCursor() function which calls xcb_xfixes_hide_cursor() or
xcb_xfixes_show_cursor() depending if the cursor is hidden. However, the
currentCursorChanged signal can be emitted if the cursor changed, e.g. a
new pixmap attached, or its visibility status changes.
The zoom effect hides the pointer, but when user hovers ui elements, it
will most likely change and result in more than one xcb_xfixes_hide_cursor()
calls.
It appears like xcb_xfixes_hide_cursor() is implemented as a reference
counter, i.e. if xcb_xfixes_hide_cursor() is called two times, then you
must call xcb_xfixes_show_cursor() two times as well.
This change adds a dedicated signal to indicate whether the cursor is
hidden to avoid calling xcb_xfixes_hide_cursor() multiple times while
the screen is scaled.
BUG: 448537
With connection(), we will look up the x11 connection property on
kwinApp() object, which is less efficient than just calling a method on
the app object.
Since the base Platform::applyOutputChanges() implementation only
applies changes to enabled outputs, it's not possible to re-enable a
previously disabled output.
While there's a fullscreen effect, the fall apart effect should avoid
animating windows as it can corrupt or interfere with the active full
screen effect. This matches behavior of many other animation effects in
kwin.
BUG: 449844
QPainter won't let paint with a device pixel ratio less than 1. There
are used to be workarounds to force a device pixel ratio of 1, but they
were removed with fractional scaling corner fix.
This change makes sure that the decoration renderer forces a device
pixel ratio of 1 if the output's scale factor is less than 1 so
calculated texture coordinates match where window borders are rendered
in the texture atlas.
BUG: 449681
They're error prone and don't really work for changing modes. Having
a current mode in DrmConnector also doesn't work well together with
the transactional style of how DrmPipeline operates
AbstractClient::setQuickTileMode() no longer updates electric border
mode, which can leave AbstractClient::electricBorderMode() with an old
value at the next interactive move and potentially result in quick
tiling not work if the user decides to untile and then tile the window
again while still holding left button.
Quick tiling allows you tile a window so it covers one half or a quarter
of the screen. Electric border is basically interactive flavor of quick
tiling, i.e. it allows you to drag a window to the top screen edge to
maximize it.
Currently, it's confusing that tile geometry is computed based on the
electric border mode.
This change converts electricBorderMaximizeGeometry() in a helper that's
used to compute the tile geometry given the desired mode and output
containing the specified QPoint. With that, setQuickTileMode() won't
need to set electric border anymore, which makes tiling code more
comprehensible, but by not a lot unfortunately.
XdgToplevelClient::setFullScreen() won't change the geometry
immediately, so workspace()->updateFocusMousePosition() can be removed.
Also, input handling code takes care of updating the cached mouse
position in the workspace.
If the user wants to move a tiled window, but changes their mind and
tiles the window back to the previous position, the geometryRestore()
will be corrupted because initialMoveResizeGeometry() is the same as the
geometry of the window in the tiled mode.
This change fixes tracking of the geometry restore by precomputing the
geometry restore when starting interactive move. That way, if the window
is untiled and tiled again without release left pointer button, the
geometry restore will be set to the correct value in setQuickTileMode().
This change also adjusts the test suite so such a subtle case won't be
broken again without noticing it.
There was no handling for the drop being cancelled at all, leading to
leaked WlVisit and XtoWlDrag objects. X clients could also be confused
about the state of the drag and for example not being able to start another
drag.
BUG:449362
Flickable by default allows swiping via click-and-drag or
scrolling with the mousewheel, which is weird when the content
is smaller than the available space.
Inhibit this behavior unless there's a need for scrolling.
The present windows effect can crash because a null (0) EffectScreen can
be passed to EffectsHandler::clientArea(), which is a bug.
Use EffectsHandler::virtualScreenGeometry() to get the bounding geometry
of all outputs.
BUG: 449508
The most recently activated window can be an overlay window that covers
all screens. If its center is not at an output with the fullscreen
window, then the fullscreen window's stack position won't be lowered. In
order to fix that, this change makes isActiveFullscreen() use
Toplevel::isOnOutput(), which uses geometry info, to check if both windows
are on the same output.
Since 4881dd63 replaced the double click timer for OffscreenQuickView
with a time check, we need to make sure the timestamp from
XInput/libinput is passed on to the actual QMouseEvent.
BUG: 448477