So far input events were sent through Xwayland which is not needed as
we have all information available. Even more it had the pointer surface
on the wrong window when interacting with decorations as it was on the
window and not on the decoration.
... not them becoming visible.
Latter doesn't work for most cases (unminimizing)
for obvious reasons (they're not minimized) and
when a new window is mapped, the focus stealing
prevention seems a good filter
(if it's not good enough to gain the focus,
it's not good enough to break the state either)
REVIEW: 123783
CCBUG: 346837
CCBUG: 346933
CCBUG: 347212
* properties defined in AbstractClient
* implementation of isShade moved to AbstractClient
* implementation of setShade(bool) moved to AbstractClient
* default implementation for isShadeable added to AbstractClient
* default implementation for shadeMode returning ShadeNone
* default implementation fo setShade which does nothing
Moves the properties and the base implementation into AbstractClient.
Methods invoke a new protected virtual method which is implemented in
Client to update the TabGroup.
Moves the implmentation to AbstractClient. Methods are no longer virtual,
setActive calls a virtual protected method which is implemented in Client
for Client specific activation code.
A virtual base implementation is provided which does nothing. Needed
in AbstractClient to get Workspace::slotWindowGrow* to work with
active_client becoming an AbstractCliet.
The change is mostly straight forward. Effects are straight forward
adjusted. Client::findModal is moved up, this causes still a few
dynamic_casts to Client. Mostly because Workspace::activateClient still
operates on Client.
The idea for this base class is to provide access to all elements which
make up a managed "Client" being it X11 or Wayland. They share a lot,
like they have a caption, they can be minimized, etc. etc.
Of course it would have also been possible to derive a new class from
Client, but that looks like the more difficult task as Client is very
X11 specific.
So far only a very small interface is extracted with pure-virtual
methods. This is going to change by moving the functionality up into
the AbstractClient.
The interface extracted so far is inspired by the usage of FocusChain
and users of FocusChain.
This is an alternative approach suggested by the
NETWM spec.
The advantage is, that windows are not minimized
at all what apparently lead to some confusion
about the nature of the mode (which was abused
to tidy up) and a secret config key to allow for
that unrelated behavior.
Instead the ShowDesktopIsMinimizeAll key is removed
and replaced by a dedicated script + shortcut.
Bonus: less code to remember "minimized" windows =)
Adapt to API changes introduced by b62e8888cd39301e00ad98dfe791fa66676408fb.
It adds DecoratedClient::color(group, role) for getting colors that are
not included in QPalette. Breeze used to read these colors from
kdeglobals, breaking per window color schemes. KWin now handles reading
these colors along with QPalette loading with DecorationPalette.
REVIEW: 122883
We released three versions with it being disabled and it doesn't look
like it will come back any time soon. Also the build was broken at least
since the repo splitting due to incorrect path to dbus xml.
In addition the connection to decorations got dropped already with the
change to kdecoration2. Which means it anyway needs large adjustements
to get the code working again.
Overall it doesn't look like it makes lots of sense to keep the code
around for someone working on it in future. If that happens this change
can be reverted.
On Wayland we get the damage from the SurfaceInterface instead of
using a damage handle. This change ensures that the damage handle
interaction is only used on platform X11, while on Wayland we get
the damage from the SurfaceInterface directly.
When XWayland associates a Wayland surface with an X window it
sends a WL_SURFACE_ID client message to the window manager.
KWin listens for this client message in Toplevel and provides it
as a member in Toplevel.
This requires KWin to actually start a Wayland server (and XWayland)
to make proper use of the information.
A wrapper class for MotifHints is added to xcbutils. This class manages
the information about the read Motif hints, so that Client doesn't need
to have a copy of the read states.
The class is designed in a way that during Client::manage we get rid of
another roundtrip.
REVIEW: 122378
Xcb::GeometryHints is a convenient wrapper around the size hints
as described in ICCCM combined with the sanity checks so far applied
by KWin after reading the property.
Instead of accessing the members of the property structure, we are
now using the convenience methods.
During ::manage no further actions are triggered when reading the
size hints. Only when they are read later on the previous checks
are applied. During ::manage they can be ignored as it had a dedicated
isManaged check.
The method ::resizeWithCheck got a new argument of type xcb_gravity_t
which defaults to 0. This is needed from ::configureRequest which so
far temporarily changed the xSizeHints structure. By passing as an
argument this is no longer needed.
REVIEW: 122185
We are only using the UrgencyHint, InputHint and GroupLeader from
WMHints. Those are provided by NETWinInfo, so we can use the
functionality provided by NETWinInfo instead of calling XGetWMHints.
REVIEW: 120162
NOTE: this is not working completely yet, lots of code is still ifdefed
other parts are still broken.
The main difference for the new decoration API is that it is neither
QWidget nor QWindow based. It's just a QObject which processes input
events and has a paint method to render the decoration. This means all
the workarounds for the QWidget interception are removed. Also the paint
redirector is removed. Instead each compositor has now its own renderer
which can be optimized for the specific case. E.g. the OpenGL compositor
renders to a scratch image which gets copied into the combined texture,
the XRender compositor copies into the XPixmaps.
Input events are also changed. The events are composed into QMouseEvents
and passed through the decoration, which might accept them. If they are
not accpted we assume that it's a press on the decoration area allowing
us to resize/move the window. Input events are not completely working
yet, e.g. wheel events are not yet processed and double click on deco
is not yet working.
Overall KDecoration2 is way more stateful and KWin core needs more
adjustments for it. E.g. borders are allowed to be disabled at any time.
This is going to be a controversal change. It enforces KWin decorations
on all client side decorated windows from GTK+. Unfortunately we are
caught between a rock and a hard place. Keeping the status quo means
having broken windows and a more or less broken window manager due to
GTK+ including the shadow in the windows. This is no solution.
Enforcing server side decorations visually breaks the windows. This is
also no solution. So why do it?
It's our task to provide the best possible user experience and KWin is
a window manager which has always done great efforts to fix misbehaving
windows. One can think of the focus stealing prevention, the window rules
and lately the scripts. The best possible window management experience is
our aim. This means we cannot leave the users with the broken windows
from GTK.
The issues we noticed were reported to GTK+ about 2 months ago and we are
working on improving the situation. Unfortunately several issues are not
yet addressed and others will only be addressed in the next GTK+ release.
We are working on improving the NETWM spec (see [1]) to ensure that the
client side decorated windows are not in a broken state. This means the
enforcment is a temporary solution and will be re-evaluated with the next
GTK release. I would prefer to not have to do such a change, if some of
the bugs were fixed or GTK+ would not use client-side-decos on wms not
yet supporting those all of this would be a no issue.
For a complete list of the problems caused by GTK's decos see bug [2] and
the linked bug reports from there.
The change is done in a least inversive way in KWin. We just check for
the property _GTK_FRAME_EXTENTS and create a Q_PROPERTY in Client for it.
If we add support for the frame extents in future we would also need
this. So it's not a change just for enforcing the decoration.
The actual enforcing is done through a KWin script so users can still
disable it.
REVIEW: 119062
[1] https://mail.gnome.org/archives/wm-spec-list/2014-June/msg00002.html
[2] https://bugzilla.gnome.org/show_bug.cgi?id=729721
Use the timestamp from the xcb event which triggers the update whenever
possible. If we don't have access to the latest event, let's at least
update our own xTime prior to using it.
Slightly unrelated change included: Group switches the userTime from
XLib datatype to xcb datatype.
BUG: 335637
REVIEW: 118456
Qt doesn't like that we reparent the decoration using low level xcb
calls. So let's use a QWindow wrapper for the frame and let Qt do
the reparenting itself.
BUG: 334768
REVIEW: 118159
Only used for the delayedMoveResizeTimer as timeout slot. Code is small
so a lambda makes more sense. At the same time the code is slightly
improved to ensure that startDelayedMoveResize is never called while
the timer is already active.
This means that mousePressEvents are now required to come from the
decoration.
REVIEW: 117843
The sync protocol with e.g. Qt 4 windows is broken if our app time is
older than the one of the last sync alarm event. Thus we keep a timestamp
in the syncRequest struct of the last sent sync request. If the timestamp
is newer than our xTime when sending the next request, we update the
xTime to ensure that we have a new timestamp again.
BUG: 333512
REVIEW: 117734
So far the Unmanaged got released after an XCB_UNMAP_NOTIFY. This event
gets created after xcb_unmap_window or after xcb_destroy_window. In the
latter case the window is already distroyed and any of KWin's cleanup
calls will cause a BadWindow (or similar) error.
The idea to circumvent these errors is to try to wait for the
DESTROY_NOTIFY event. To do so the processing of the release is slightly
delayed. If KWin gets the destroy notify before the delay times out the
Unamanged gets released immediately but with a Destroy flag. For this a
new enum ReleaseToplevel is introduced and Unmanage::release takes this
as an argument instead of the bool which indicated OnShutdown. Also this
enum is added to Toplevel::finishCompositing so that it can ignore the
destroyed case and not generate an error.
REVIEW: 117422
Adds NET::WM2BlockCompositing to the Client's properties which allows to
read the state from the NETWinInfo object and get updates without having
to resolve the atom ourselve.
REVIEW: 117561
Excluded are the signals to Appmenu as that's currently excluded from
build.
Private slots with only one connection are turned into lambdas.
REVIEW: 117355
Instead of passing the macro based Predicate to findClient it now
expects a function which can be passed to std::find_if.
Existing code like:
xcb_window_t window; // our test window
Client *c = findClient(WindowMatchPredicated(window));
becomes:
Client *c = findClient([window](const Client *c) {
return c->window() == window;
});
The advantage is that it is way more flexible and has the logic what
to check for directly with the code and not hidden in the macro
definition.
In addition there is a simplified overload for the very common case of
matching a window id against one of Client's windows. This overloaded
method takes a Predicate and the window id.
Above example becomes:
Client *c = findClient(Predicate::WindowMatch, w);
Existing code is migrated to use the simplified method taking
MatchPredicate and window id. The very few cases where a more complex
condition is tested the lambda function is used. As these are very
local tests only used in one function it's not worthwhile to add further
overloads to the findClient method in Workspace.
With this change all the Predicate macro definitions are removed from
utils.h as they are now completely unused.
REVIEW: 116916
As can be seen in [1] the patches to KWin were in CVS HEAD before the
protocol got standardized and it never got any adoption. It's neither in
the NETWM spec, nor implemented in Qt4 nor in Qt5. KWin did not even add
the protocol to the NET::Supported property.
Thus it doesn't make much sense to keep a protocol which nobody speaks.
Still the code around the protocol is kept and also the names are kept.
Only difference is that Client::takeActivity got removed and the code
moved to the only calling place in Workspace. Motivated by that change
the enum defined in utils.h is moved into Workspace, it's turned into
a proper QFlags class and used as a type in the method argument instead
of a generic long.
[1] https://mail.gnome.org/archives/wm-spec-list/2004-April/msg00013.html
REVIEW: 116922
Major new functionality is xkbcommon support. InputRedirection holds an
instance to a small wrapper class which has the xkb context, keymap and
state. The keymap is initialied from the file descriptor we get from the
Wayland backend.
InputRedirection uses this to translate the keycodes into keysymbols and
to QString and to track the modifiers as provided by the
Qt::KeybordModifiers flags.
This provides us enough information for internal usage (e.g. pass through
effects if they have "grabbed" the keyboard).
If KWin doesn't filter out the key events, it passes them on to the
currently active Client respectively an unmanaged on top of the stack.
This needs still some improvement (not each unmanaged should get the
event). The Client/Unmnaged still uses xtest extension to send the key
events to the window. So keylogging is still possible.
InputRedirection keeps track of the Toplevel which is currently the one
which should get pointer events. This is determined by checking whether
there is an Unmanaged or a Client at the pointer position. At the moment
this is still slightly incorrect, e.g. pointer grabs are ignored,
unmanaged are not checked whether they are output only and input shapes
are not yet tracked.
The pointer events are delivered to the Toplevel as:
* enter
* leave
* move
* button press
* axis event
Nevertheless move events are still generated in InputRedirection through
xcb test for simplicity. They are still send to the root window, so all
windows get mouse move.
Button press and axis are generated only in the implementations of the
event handlers and delivered directly to the window, so other windows
won't see it.
In KCommonDecoration the OnAllDesktops button gets hidden or shown
depending on the number of desktops. For that KDecoration is extended
by a new property which delegates to the bridge to return whether
onAllDesktops is available. In KWin Core this is implemented using
the number of desktops.
FEATURE: 321611
FIXED-IN: 5.0.0
REVIEW: 116076
This provides a new protocol intended to be used by auto-hiding panels
to make use of the centralized screen edges. To use it a Client can
set an X11 property of type _KDE_NET_WM_SCREEN_EDGE_SHOW to KWin.
As value it takes:
* 0: top edge
* 1: right edge
* 2: bottom edge
* 3: left edge
KWin will hide the Client (hide because unmap or minimize would break
it) and create an Edge. If that Edge gets triggered the Client is shown
again and the property gets deleted. If the Client doesn't border the
specified screen edge the Client gets shown immediately so that we
never end in a situation that we cannot unhide the auto-hidden panel
again. The exact process is described in the documentation of
ScreenEdges. The Client can request to be shown again by deleting the
property.
If KWin gets restarted the state is read from the property and it is
tried to create the edge as described.
As this is a KWin specific extension we need to discuss what it means
for Clients using this feature with other WMs: it does nothing. As
the Client gets hidden by KWin and not by the Client, it just doesn't
get hidden if the WM doesn't provide the feature. In case of an
auto-hiding panel this seems like a good solution given that we don't
want to hide it if we cannot unhide it. Of course there's the option
for the Client to provide that feature itself and if that's wanted we
would need to announce the feature in the _NET_SUPPORTED atom. At the
moment that doesn't sound like being needed as Plasma doesn't want to
provide an own implementation.
The implementation comes with a small test application showing how
the feature is intended to be used.
REVIEW: 115910
Client used to have dedicated methods for different icon sizes instead
of combining all pixmaps into one QIcon. This resulted in various parts
of KWin having different access to the icons:
* effects only got one pixmap of size 32x32
* decorations only got the 16x16 and 32x32 pixmaps combined into a QIcon
* tabbox could request all icon sizes, but only as pixmap
Now all sizes are available in one QIcon allowing to easily access the
best fitting icon in a given UI.
The X property _KDE_NET_WM_COLOR_SCHEME can be set on a window and
specifies the absolute path to a .color file describing the color
scheme of the managed client.
The Client reads this property and creates a QPalette from it. If
the property is not set or the value is incorrect, the Client uses
KWin's default palette.
The idea behind this property is to allow an application with a
custom color scheme to tell KWin which color scheme the window
decoration should use. So that the window looks as a solid pattern
again.
KWin core can access the QWindow of the decoration instead of the
QWidget. This is a preparation step to allow QWidget based window
decorations without any QWidgets at all.
KWin core makes already use of this new accessor to get the window Id
which is also on QWidgets provided through the QWindow.
The frameId only makes sense for a Client, in case of Unmanaged the
same window id is used as for the window() handle. Client creates the
frame and destroys it.
Given that it makes sense to let Client manage the frame properly.
The ::frameId() is therefore virtual and as base implementation it
returns the client id. Client reimplements it and returns the proper
frame id.
Method is also implemented in Deleted as it used to be passed to
deleted.
Instead of inspecting the XEvent queue we create a Timer with a
singleshot of 0 msec to move the setActive(false) call to the end of the
event handling. In case there is a matching FocusIn event this will be
handled before the timer fired and can cancel the timer.
Focus out handling used to check the event queue for a matching focus in
event to prevent short flickers when no window is active. This is not
possible with XCB and needs a replacement. Maybe a short timer event.
Interestingly the attribute send_event from XUnmapEvent does not exist in
xcb_unmap_notify_event_t and also the X protocol doesn't know anything
about send event.
At same time also renaming variable to follow naming scheme and have a
sensible name. Also moved default value initialization into initializer
list.
REVIEW: 110283
The type of the transient_for related variables are changed to
xcb_window_t. They cannot be Xcb::Window as we don't take ownership over
the transient for window.
Variables are renamed to m_camelCase to follow naming scheme.
A wrapper for retrieving the TransientFor hint is added to the Xcb
Wrappers.
Using Xcb::Window to wrap this helper window and port all the used XLib
calls to XCB.
Also renaming the variable to m_ and camel case to follow general naming
scheme.
Unfortunately the Xcb::Window wrapper cannot be used for the client
window as the client should not be destroyed by KWin.
All the API calls except XSelectInput are changed to xcb and the name is
adjusted to m_client to follow the naming scheme.
The Xcb::Window nicely encapsulates the created wrapper window. As
almost all code is adjusted, the variable is also renamed to
m_wrapper to follow the normal naming scheme.