Currently, on X11, when activating a window that is not on the current desktop we allow this
only if focus stealing protection is set to none.
If any focus stealing protection is set then activation is denied. That behavior is
unintiutive to the user. When I e.g. click on a notification from a chat app I expect
something to happen, regardless of focus stealing protection.
Remove the special handling of windows on different desktops and only apply the usual
focus stealing prevention checks (based on timestamps etc). This also matches the behavior
on Wayland.
Window::desktop() is obsolete. On the other hand, X11 doesn't support
having a window on several virtual desktops, so we still need it. As a
compromise, this change moves it to X11Window instead.
Currently, managed and override-redirect windows are split in two types:
X11Window and Unmanaged. While looking at it strictly from type
perspective, this is great. But it creates other problems, e.g. we need
to put shared X11-specific code in the base Window class or mess with
"base" classes.
As an alternative solution, this change merges the Unmanaged class into
the X11Window class and disables some functionality based on the value
of isUnmanaged().
X11Window::manage() is used to create a managed Window. X11Window::track()
is used to create an unmanaged Window.
If a transient parent is removed, X11Window::removeTransient() will try
to upgrade the transient to a group transient.
On the other hand, that code is broken because Window::removeTransient()
will unset transientFor() so we never hit the code path in the if
statement.
While we could fix it, I think it's not worth it because transient
handling code is already mental and making group transients and normal
transients disjoint will help to keep the things simpler.
Currently, X11Window and Unmanaged call finishCompositing(), which tries
to destroy the window item and other associated compositing data.
Usually, it has no any effect on the window item and the effect window
because they are moved to the Deleted. However, it has some effect on
the XDamage handle.
If the X11 window is unmapped, it will destroy the XDamage handle. If
the X11 window is destroyed, it will do nothing. Why does it behave like
that? Because that's how the XDamage spec is written.
This change removes the call to finishCompositing() and refactors how
the XDamage is handled so Window::finishCompositing() is more generic.
If the X11 window is destroyed, SurfaceItemX11::forgetDamage() will be
called and SurfaceItemX11::~SurfaceItemX11() won't attempt to destroy
the damage handle.
If the X11 window is unmapped, SurfaceItemX11::destroyDamage() will be
called and destroyDamage() in SurfaceItemX11::~SurfaceItemX11() will
noop.
If compositing has been restarted, destroyDamage() in
SurfaceItemX11::~SurfaceItemX11() will destroy the damage handle.
The main motivation behind this change is to share rendering code
between windows and the cursor, specifically the Item class which
requires a Scene.
Note that Scene subclasses are responsible for issuing
ItemRenderer::renderItem() calls. The main reason for that is the
current architecture of the effects system, specifically we need to call
some effects hooks before and after painting a window.
This is needed to establish explicit connection between an item and the
scene it belongs to. For now, the scene must be known at the item
construction time. Perhaps it can be improved in the future by items
inheriting their scene from the parent item, but the scene would need to
be refactored more so there's a root item or something like that.
This removes the optimization that sends only one ConfigureNotify event after moving is completed.
However, other windows may depend on ConfigureNotify events to adjust their position in a timely
manner. For example, the shadow window surrounding the main login window of WeChat on Wine.
BUG: 449302
Activities are loaded async. During this time any fetch of activity
information is incorrect as we will treat any settings as invalid.
We need to ignore attempts to set activities during this time, but also
refresh Window's concept of activities once we are loaded.
BUG: 438312
Window::handleInteractiveMoveResize() calls setMoveResizeGeometry(),
which breaks in a way the encapsulation.
This change refactors geometry handling in handleInteractiveMoveResize()
so the next geometry is computed in a temporary variable and the move
resize geometry is updated either using move() or
doInteractiveResizeSync().
There was a geometry change that fixed mixing the next and current
geometries. While it did fix issues on wayland, it broke window shading
on x11 because of an obscure resize() call.
That obscure resize() had a side-effect that ensures m_clientGeometry
has the right value so the next time the window is unshaded,
implicitSize() will return a good value.
In order to make window size computation more robust, this change makes
X11Window compute the natural frame size based on cached size in
m_client, which shouldn't change when the window is shaded.
However, given how buggy window shading is and how difficult it is to
make it work right, I think that it's better to deprecate window shading
and remove it in some future release.
BUG: 450582
With fractional scaling integer based logical geometry may not match
device pixels. Once we have a floating point base we can fix that. This
also is
important for our X11 scale override, with a scale of 2 we could
get logical sizes with halves.
We already have all input being floating point, this doubles down on it
for all remaining geometry.
- Outputs remain integer to ensure that any screen on the right remains
aligned.
- Placement also remains integer based for now.
- Repainting is untouched as we always expand outwards
(QRectF::toAdjustedRect().
- Decoration is untouched for now
- Rules are integer in the config, but floating in the adjusting/API
This should also be fine.
At some point we'll add a method to snap to the device pixel
grid. Effectively `round(value * dpr) / dpr` though right now things
mostly work.
This also gets rid of a lot of hacks for QRect right and bottom which
are very
confusing.
Parts to watch out in the port are:
QRectF::contains now includes edges
QRectF::right and bottom are now sane so previous hacks have to be
removed
QRectF(QPoint, QPoint) behaves differently for the same reason
QRectF::center too
In test results some adjusted values which are the result of
QRect.center because using QRectF's center should behave the same to the
user.
It helps to contextualise the method as it's using several x11-isms,
some of them possible ot abstract.
In any case, the method is only called with X11Window and it's the only
case where it makes sense doing so.