A new AreaBasedEdge is introduced which supports the Edge functionality
by just connecting to the globalPointerChanged signal of
InputRedirection.
The AreaBasedEdges are used if KWin's operation mode is not X11 only.
This unfortunately required to change the datatype of the list of edges
in ScreenEdges. It used to be specific on the inheriting class.
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
The define KWIN_SINGLETON adds to a class definition:
public:
static Foo *create(QObject *parent = 0);
static Foo *self() { return s_self; }
protected:
explicit Foo(QObject *parent = 0);
private:
static Foo *s_self;
There is an additional define KWIN_SINGLETON_VARIABLE to set a different
name than s_self.
The define KWIN_SINGLETON_FACTORY can be used to generate the create
method. It expands to:
Foo *Foo::s_self = 0;
Foo *Foo::create(QObject *parent)
{
Q_ASSERT(!s_self);
s_self = new Foo(parent);
return s_self;
}
In addition there are defines to again set a different variable name and
to create an object of another inheriting class.
All the classes currently using this pattern are adjusted to use these
new defines. In a few places the name was adjusted. E.g. in Compositor
the factory method was called createCompositor instead of create.
REVIEW: 109865
With Qt5 QCursor does no longer provide ::handle() which was used to
set a cursor on a native XWindow for which we do not have a QWidget.
Also KWin has had for quite some time an optimized version to get the
cursor position without doing XQueryPointer each time ::pos() is called.
These two features are merged into a new class Cursor providing more or
less the same API as QCursor.
In addition the new class provides a facility to perform mouse polling
replacing the implementations in Compositor and ScreenEdges.
For more information about the new class see the documentation for the
new class in cursor.h.
but drop screenedges below the supportWindow instead
that's why it exists, that's deterministic, that's faster
includes adaption to new screenedge and xcb invocation (compared to 4.10)
BUG: 314625
FIXED-IN: 4.10.1
REVIEW: 108867
Corners are still ours (it's a valid use case to still be able to switch
window through e.g. Present Windows even when running a fullscreen app).
How is it done? An Edge can be blocked and does no longer trigger if it
is blocked. For WindowBasedEdges the edge windows get unmapped in the
blocking case and mapped again when the blocking condition is no longer
valid.
The blocking is so far connected to:
* changes of active window
* changes of fullscreen windows
Whenever one of the events occurs it is checked whether there is:
1. an active client
2. it is fullscreen
3. on the same screen as the edge
If this is the case the edge will be blocked, otherwise unblocked.
BUG: 271607
FIXED-IN: 4.11
For each edge an additional "approach" area window is created. When the
mouse enters this approach window, it gets unmapped and a mouse polling
interval is started. If the mouse leaves the approach area again, the
window gets mapped again and the mouse polling is stopped.
During the approaching a signal is emitted with a factor in [0.0,1.0] to
describe how close the mouse is to the edge. 0.0 means far away, 1.0
means triggering the edge. This signal is passed to the effects to allow
using this information. E.g. to provide a glow corner effect or to make
use of it in the cube animation effect to start the animation on desktop
switch.
In fact it already used to be a Singleton as there is just one object
hold by the Singleton Workspace. So let's make it a proper Singleton
following our kind of standard approach of having a ::create factory
method called from Workspace ctor and a ::self to get to the singleton
instance.
The main difference is that the activation of an edge is no longer
broadcasted to all effects and scripts, but instead a passed in slot of
the Effect/Script is invoked.
For this the EffectsHandler API is changed to take the Effect as an
argument to (un)reserveElectricBorder. As callback slot the existing
borderActivated is used.
In addition the ScreenEdge monitors the object for beeing destroyed and
unregisters the the edge automatically. This removes the need from the
Effect to call unregister in the dtor.
BUG: 309695
FIXED-IN: 4.11
This rewrite is mostly motivated by the need to handle multi screen
setups correctly. That is have edges per screen and not for the combined
geometry. Also porting from XLib to XCB has been a motivation for the
rewrite.
The design of the new ScreenEdge handling is described in the
documentation of ScreenEdges in screenedge.h.
In addition the following changes have been performed:
* move configuration from Options to ScreenEdge
* add screen edge information to Workspace::supportInformation (obviously
replaces what had been read from Options)
* have Workspace hold a pointer to ScreenEdges instead of an object
* forward declaration of ScreenEdges in workspaces.h, this explains the
seemingly unrelated changes of just another include in some files
BUG: 290887
FIXED-IN: 4.11
Main motivation for this change except the fact that it doesn't belong
into Workspace is that the screen edges got updated from within setting
the desktop layout which got removed with the introduction of the
VirtualDesktopManager.
The ScreenEdge now keeps some state to be able to correctly unreserve the
electric borders when changes in the configuration are performed. There
is still room for improvement as there are still some deep function calls
from within reconfiguring in Workspace.
REVIEW: 107493
ScreenEdge is changed to emit a signal whenever a screen edge
got activated without an action or effect taking care of it.
A Script can reserve one to many callbacks for an edge and the
callback get's triggered whenever the signal is emitted. On
deconstruction of the Script the edge is unreserved again.
FEATURE: 299275
FIXED-IN: 4.9.0
REVIEW: 104904
Since the method destroy() was called only from one location in the code
followed by update(), the funtionality has been moved to the method update()
which now takes an boolean argument 'force'. This argument is false by default
and set to true only at that location where destroy() was called formerly.
The code was updated to use a QVector for the screen edge windows instead of
an ordinary Window array. The getter method windows() was updated to return
now this QVector.
In the method propagateClients() in layers.cpp the newWindowStack QVector is
filled by iteration through the screen edge windows and only adding Windows that
are not None.
Since the functions were moved from Workspace to its own class ScreenEdge
and the functionality was formerly called ElectricWindows, the functions still
had the old names. They are now consistenly renamed without redundand naming.
The function calls were updated as well in all classes where ScreenEdge is used.
The initialization was done in class Workspace before but is now
moved to class ScreenEdge in its own init() method. Is is called from
Workspace at the same position where the initialization took place before.
Since the functionality of screen edge handling was moved to its own class,
the screen edge windows are now provided by the getter method screenEdgeWindows().
The new getter method screenEdgeWindows() returns a reference to a QVector,
which includes the screen edge windows.
The Workspace method propagateClients() implemented in layers.cpp needs these
screen edge windows to restack the windows. The code was also modified to use
QVector instead of a Window array.
A new getter method screenEdgeWindows() is provided by class ScreenEdge
since the screen edge windows are needed in class Workspace in the function
propagateClients() which is implemented in layers.cpp
This commit change the screen edge function calls to be called in the
new class ScreenEdge. The old methods are still in Workspace and will
be removed in a further commit.
This initial commit introduces a two new files screenedge.h and screenedge.cpp which cover a new
class ScreenEdge. The code for screen edge handling was copied from Workspace to this class.
Workspace had to be extended by a getter for movingWindow. CMakeList was updated to build the
new class.