Commit graph

60 commits

Author SHA1 Message Date
Fushan Wen
1d0e75bc5c x11client: Replace activityList with m_activityList
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
2021-12-16 09:59:23 +00:00
Vlad Zahorodnii
acb0683e0d wayland: Properly handle async xdg-decoration updates
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
2021-12-15 12:47:27 +00:00
Vlad Zahorodnii
70f46970da Invalidate decoration explicitly
Lets us to remove AbstractClient::updateDecoration().
2021-12-15 12:47:27 +00:00
Vlad Zahorodnii
01a46ff389 Reduce code duplication between X11Client::createDecoration() and AbstractClient::createDecoration() 2021-12-15 12:47:27 +00:00
Vlad Zahorodnii
f1e96676ef Remove boolean trap in AbstractClient::isShown()
Check shaded state where needed.
2021-11-24 08:11:35 +00:00
Vlad Zahorodnii
d755e74c29 Remove some manual repaints in X11Client
Let the scene schedule a repaint instead.
2021-11-16 07:26:44 +00:00
Xaver Hugl
6ff4de2e05 port everything away from Q_FOREACH 2021-11-08 14:19:05 +00:00
Xaver Hugl
c01c15f241 AbstractClient: split up hideClient into hide and show
This makes the purpose of the method call more clear
2021-11-08 14:19:05 +00:00
Vlad Zahorodnii
bb687ff6f1 Stop abusing AbstractClient::geometryRestore()
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.
2021-10-30 14:02:32 +00:00
Vlad Zahorodnii
09952e1dc7 wayland: Fix wayland windows growing after toggling decorations
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
2021-10-29 14:40:17 +00:00
Vlad Zahorodnii
b90975b7a2 Replace AbstractClient::adjustedSize() with a simpler alternative
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().
2021-10-15 17:16:11 +00:00
Rodney Dawes
886a86ab2b Pass correct argument to Q_UNUSED for disabled features 2021-10-08 13:19:35 -04:00
Vlad Zahorodnii
afcb9fd037 x11: Fix "Move window to next screen" shortcut for maximized windows
With the recent AbstractOutput changes, Workspace::clientArea() overload
that takes only the window and no additional output was changed to

    return clientArea(opt, window, window->output());

prior to that, it had been looking up the output at the center of the
frame geometry.

As it turns out, AbstractOutput::sendToOutput() blocks geometry updates,
which in its turn means that Toplevel::output() will be updated only
after geometry updates are unblocked. For the most part, it's not a big
deal until you need to use Workspace::clientArea(opt, const Toplevel*)

Since the output won't be updated until geometry updates are unblocked,
clientArea(opt, const Toplevel *) may return outdated info.

One could argue that we just simply need to update m_output similar to
m_frameGeometry when geometry updates are blocked, but... it's not going
to work on wayland! On Wayland, GeometryUpdatesBlocker is totally
unnecessary. Even if a window is resized, m_frameGeometry will be left
unchanged until the client repaints the window.

Instead, one need to pass the AbstractOutput to clientArea() if it's
important.

This change makes X11Client::changeMaximize() query the MaximizeArea of
the output containing the center of the move resize geometry, similar to
what the XdgToplevelClient does.

BUG: 442534
2021-09-17 14:02:01 +00:00
Vlad Zahorodnii
748004d81e x11: Avoid discarding the window pixmap for no reason
If the buffer size changes after creating or destroying the decoration,
the surface item will discard the pixmap.

If the buffer size remains the same, we can continue using old pixmap.
2021-09-09 16:55:39 +00:00
Alex Richardson
af3602b48c Fix out-of-bounds copy in xcb_send_event() calls
xcb_send_event always copies 32 bytes, so we have to pad all xcb_*_event_t
to 32 bytes to avoid leaking uninitialized stack memory. I found this
problem while running kwin_x11 on a CHERI-RISC-V system (which has bounded
pointers). The xcb_send_event() implementation has a memcpy() that was
copying 32 bytes but the event passed was a bounded to 28 bytes, so this
resulted in a run-time exception in X11Client::sendClientMessage().
The same problem exists in Selection::sendSelectionNotify(), but this time
we could end up copying up to 8 bytes since xcb_selection_notify_event_t
is only 24 bytes.

This disclosure of uninitialized data could in theory have a security
impact if it leaks a pointer value (e.g. a return address) as part of an
exploit chain that needs to bypass ASLR. However, the selection notify
events go directly to the XServer and you most likely already have a
serious problem if an attacker has full control over the XServer. It is
possible that the configure notify events go directly to an untrusted
client, but even if they do this leak is not directly exploitable.

See also https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/18
2021-09-09 15:03:44 +01:00
Kai Uwe Broulik
8bebf5cee1 Port to function-pointer based QMetaObject::invokeMethod
It's more efficient and compile-time checked
2021-09-07 06:30:39 +00:00
Ismael Asensio
436011e0ec X11Client: emit isCloseableChanged when updated
This allows the decoration buttons to be updated accordingly
when the status changes.

We also need to explicitely update allowed actions when rules
are applied, as `isCloseable` is not a settable property, but
an allowed action

BUG: 424370
FIXED-IN: 5.22.90
2021-09-04 15:51:38 +02:00
Vlad Zahorodnii
cdd3f96fe1 Port X11Client::fullscreenMonitorsArea() to AbstractOutput 2021-09-01 10:10:24 +00:00
Vlad Zahorodnii
7016da39c8 Move active output tracking to workspace
Active output is a window management concept. It indicates what output
new windows have to be placed on if they have no output hint. So
Workspace seems to be a better place for it than the Screens class, which
is obsolete.
2021-08-30 13:28:23 +00:00
Vlad Zahorodnii
9dfccfc95c Port some of kwin to Workspace::geometry() 2021-08-30 12:26:16 +03:00
Vlad Zahorodnii
b80fbe6fb0 Merge WindowRules::checkScreen() and WindowRules::checkOutput() 2021-08-29 21:55:07 +00:00
Vlad Zahorodnii
6ca411a84a Port AbstractClient::sendToScreen() to AbstractOutput 2021-08-29 21:55:07 +00:00
Vlad Zahorodnii
fddbd57d09 Port Workspace::clientArea() to VirtualDesktop
This makes Workspace APIs that take virtual desktops more consistent.
2021-08-25 14:31:30 +00:00
Vlad Zahorodnii
d5c2518973 Add Workspace::clientArea() that take no desktop
The new overloads take the client (as context) and the desired screen id
or a point and return the client area.

The main motivation behind this change is to make the transition to the
new virtual desktop model where a window can be on several desktops less
painful.
2021-08-19 10:49:40 +00:00
Vlad Zahorodnii
bc7b28bb65 Fix a typo
At this point, desktop() is -1 since the client hasn't been moved to any
virtual desktop yet.

It seems like checking desktop() is a typo. It makes more sense to check
desktopId.
2021-08-16 06:32:43 +00:00
Vlad Zahorodnii
7f04d730e6 Make WindowRules::checkDesktop take a list of desktops
This ports relevant apis in WindowRules to the VirtualDesktop class.

If the client has no desktop rule, the desktop list that has been passed
to the checkDesktops() function will be returned.

If the client has a desktop window rule, the checkDesktop() function
will return a list with a single VirtualDesktop object or none if the
window is forced to be on all virtual desktops.
2021-08-16 06:32:43 +00:00
Vlad Zahorodnii
a13fd02ea8 Remove virtualdesktops.h include in toplevel.h
toplevel.h is included in many places. Changing virtualdesktops.h may
trigger rebuild of all kwin.

With this change, only cpp files that use virtualdesktops.h will need to
be recompiled.
2021-08-12 17:23:15 +00:00
Vlad Zahorodnii
ad4f183a76 x11: Drop support for _NET_WM_FRAME_OVERLAP
The main idea behind _NET_WM_FRAME_OVERLAP is to extend the borders of
the server-side decoration so the application can draw on top of it. It
was inspired by similar feature in Windows.

However, _NET_WM_FRAME_OVERLAP is basically unused. Neither GTK nor Qt
support it and I have never seen any application that uses it.

At the moment, kwin is the only compositing window manager that supports
_NET_WM_FRAME_OVERLAP. Neither mutter nor compiz nor compton and so on
support it.

Since _NET_WM_FRAME_OVERLAP is practically unused, there's no point for
keeping supporting it.

This change shouldn't affect any existing app as _NET_WM_FRAME_OVERLAP
atom is not listed in _NET_SUPPORTED.
2021-08-12 11:44:40 +00:00
Vlad Zahorodnii
c61085dc2e Remove Toplevel::compositing() and Workspace::compositing()
It is error-prone to have multiple sources for the same data. If the
base implementation (Compositor::compositing()) changes, other helpers
can get out of sync.
2021-06-22 08:32:35 +00:00
Vlad Zahorodnii
1b2c7b248b Run clazy with qt-keywords fixit
In C++20, there will be emit() class member, which can conflict with the
emit keyword. Given that, there are plans to enable QT_NO_KEYWORDS by
default in the future.

See also
https://lists.qt-project.org/pipermail/development/2020-February/038812.html
2021-06-08 10:49:42 +03:00
Vlad Zahorodnii
8c8098a61c Move X11Client::wantsShadowToBeRendered to AbstractClient
Otherwise only X11 windows will lose server-side drop-shadows when the
maximized mode changes.

BUG: 434213
2021-06-04 17:57:21 +03:00
Vlad Zahorodnii
b0042a30c1 x11: Pick better names for geometries before blocking
The new names express better what "geometries before update blocking" are.
2021-05-31 05:20:57 +00:00
Vlad Zahorodnii
c3978f197b x11: Properly detect the case where client window moves inside frame window
If the window borders change in such a way that the buffer geometry
doesn't change, but the client geometry does change, we need to configure
the wrapper window and maybe the client window so there are no black
borders, etc.
2021-05-31 05:20:57 +00:00
Vlad Zahorodnii
ce0edde906 x11: Remove irrelevant comments
The relevant code the comment talks about was removed long time ago.
2021-05-31 05:20:57 +00:00
Vlad Zahorodnii
308cbcc47f x11: Add missing geometry checks in moveResizeInternal()
Currently, there is an assumption in the moveResizeInternal() method
that if the buffer geometry changes, then the client geometry will also
change. However, as it turns out, it's not completely true. For example,
if the window is maximized while its geometry already matches the
maximize area, the buffer geometry won't change, but the client geometry
will change.

This change adds missing geometry checks. *geometryBeforeBlocking
corresponds to the old geometry. We can use it to decide if the geometry
has changed.
2021-05-31 05:20:57 +00:00
Vlad Zahorodnii
eaca921e01 x11: Remove window rule geometry mismatch debug message
If the geometry window rule must be forced, the move resize method has
to force it, but similar to size constraints, we assume that the caller
of the move resize function will do the right thing. So, remove the
debug message to be consistent with other client types.
2021-05-31 05:20:57 +00:00
Vlad Zahorodnii
f46c7bae8d Move decoration renderer to decoration item
Currently, the implementation of the DecoratedClient and the decoration
renderer are strongly coupled. This poses a problem with the item based
design as the ultimate goal is to have scene items construct paint nodes
which are then fed to the renderer. The DecorationItem has to have
control over the decoration texture. Another issue is that the scene
cannot smoothly cross-fade between two window states if the decoration
is removed, e.g. from fullscreen mode to normal and vice versa.

This change moves the decoration renderer to the decoration item. With
the introduction of a generic scene texture atlas, we hope to get rid of
the decoration renderer altogether.
2021-05-26 06:35:03 +00:00
Vlad Zahorodnii
93d95ffbc4 Replace AbstractClient::doPerformInteractiveMoveResize() with a simpler solution
AbstractClient::doPerformInteractiveMoveResize() is only used by the
X11Client to reset a boolean flag when the client doesn't support sync
counters.

X11Client can call performInteractiveMoveResize() only in two cases: the
sync request timer expires or the client increments the sync counter.

This change removes the AbstractClient::doPerformInteractiveMoveResize()
function and adds a function to handle the case where the sync timer
expires explicitly. This removes a virtual function in the AbstractClient
and makes code more readable.
2021-05-25 09:32:55 +03:00
Vlad Zahorodnii
c929d977a7 Move geometry before blocking to X11Client
It's only used by X11Client. Neither InternalClient nor WaylandClient
need buffer/frame/client geometry before blocking.
2021-05-25 06:17:41 +00:00
Vlad Zahorodnii
9a7ab8a62e Rework async geometry updates
Window management features were written with synchronous geometry
updates in mind. Currently, this poses a big problem on Wayland because
geometry updates are done in asynchronous fashion there.

At the moment, geometry is updated in a so called pseudo-asynchronous
fashion, meaning that the frame geometry will be reset to the old value
once geometry updates are unblocked. The main drawback of this approach
is that it is too error prone, the data flow is hard to comprehend, etc.

It is worth noting that there is already a machinery to perform async
geometry which is used during interactive move/resize operations.

This change extends the move/resize geometry usage beyond interactive
move/resize to make asynchronous geometry updates less error prone and
easier to comprehend.

With the proposed solution, all geometry updates must be done on the
move/resize geometry first. After that, the new geometry is passed on to
the Client-specific implementation of moveResizeInternal().

To be more specific, the frameGeometry() returns the current frame
geometry, it is primarily useful only to the scene. If you want to move
or resize a window, you need to use moveResizeGeometry() because it
corresponds to the last requested frame geometry.

It is worth noting that the moveResizeGeometry() returns the desired
bounding geometry. The client may commit the xdg_toplevel surface with a
slightly smaller window geometry, for example to enforce a specific
aspect ratio. The client is not allowed to resize beyond the size as
indicated in moveResizeGeometry().

The data flow is very simple: moveResize() updates the move/resize
geometry and calls the client-specific implementation of the
moveResizeInternal() method. Based on whether a configure event is
needed, moveResizeInternal() will update the frameGeometry() either
immediately or after the client commits a new buffer.

Unfortunately, both the compositor and xdg-shell clients try to update
the window geometry. It means that it's possible to have conflicts
between the two. With this change, the compositor's move resize geometry
will be synced only if there are no pending configure events, meaning
that the user doesn't try to resize the window.
2021-05-25 06:17:41 +00:00
Aleix Pol
ae01ed219c workspace: Unify client removal code
We have 2 equivalent code paths for x11 and wayland unnecessarily, unify
them under the same method.
Rename m_clients to m_x11Clients so that it's clear what the difference
is between m_clients and m_allClients.
2021-05-24 23:16:41 +00:00
Vlad Zahorodnii
6f39d79d72 Remove Scene::Window::{discard,update}Pixmap
They are used only by X11Client, so make X11Client call relevants
methods on the surface item directly instead. In hindsight, it will be a
really good idea to make SurfaceItemX11 and SurfaceItemXwayland(?)
automatically manage the window pixmap. However, it can be done once
an item freezing api is added and we fix the cross-fade animation.
2021-05-19 11:10:50 +00:00
Vlad Zahorodnii
edb7867ee9 Prepend "Interactive" to interactive move resize methods
This is to improve code readability and make it easier to differentiate
between methods that are used during interactive move-resize and normal
move-resize methods in the future.
2021-05-16 13:50:25 +03:00
Vlad Zahorodnii
3c2e1a71c4 Unvirtualize Toplevel::bufferGeometry()
This makes the implementation of the buffer geometry consistent with the
frame geometry and the client geometry and removes a virtual method call
from a few hot paths.
2021-05-16 10:48:41 +00:00
Vlad Zahorodnii
7c0bb4180a Remove Workspace::updateClientLayer()
It's the same as calling AbstactClient::updateLayer()
2021-05-16 10:48:06 +00:00
Vlad Zahorodnii
03445424e9 x11: Don't initialize X11Client's geometries to 0,0 100x100
It is actually okay to start with an empty frame geometry because
manage() will compute the frame geometry from the client's window size.
2021-05-14 07:00:20 +00:00
Vlad Zahorodnii
e5799a2131 Remove force geometry flags
With the client-side decoration changes, kwin will properly determine
whether the window needs to be configured even if the frame geometry has
not changed.

This change slightly changes the semantics of the setFrameGeometry()
method. Prior to this, it was possible to force a geometry, i.e. block
other geometry updates, however such a behavior is counter-intuitive and
it exponentially increases the complexity of code.

As far as I know, the force flag was needed to propagate geometry
changes if the frame geometry doesn't change, but the client geometry
does. With the client-side decoration changes, the force flag is not
needed, as kwin now takes into account the client geometry and the frame
geometry when determining whether to send a configure event.
2021-05-14 07:00:20 +00:00
Vlad Zahorodnii
aeca1af4ac Propagate correct maximize mode to decorations
When the maximize mode changes from MaximizeFull to either
MaximizeHorizontal or MaximizeVertical, (max_mode & MaximizeFull) will
evaluate to true because MaximizeFull is defined as bitwise OR between
MaximizeHorizontal and MaximizeVertical.
2021-05-07 14:18:04 +00:00
Vlad Zahorodnii
36b55261da Drop AbstractClient::addRepaintDuringGeometryUpdates()
It's not needed since the scene keeps track of repaints.
2021-03-31 13:56:55 +00:00
Vlad Zahorodnii
a9d5b84596 scene: Refactor damage teardown in X11SurfaceItem
This introduces the markedAsZombie signal, which is emitted when the
window is about to become deleted. The X11SurfaceItem uses this signal
to determine when the damage must be destroyed.
2021-03-31 13:56:55 +00:00