Animate quick tiling outline

When quick tiling animate the outline from the window geometry to the position it would have afterwards.
This provides a visual hint to from where to where the window will go.

Differential Revision: https://phabricator.kde.org/D5262
This commit is contained in:
Kai Uwe Broulik 2017-04-25 16:38:52 +02:00
parent dc447860be
commit eaf41cb6c5
4 changed files with 143 additions and 35 deletions

View file

@ -3254,7 +3254,7 @@ void AbstractClient::setElectricBorderMaximizing(bool maximizing)
{
m_electricMaximizing = maximizing;
if (maximizing)
outline()->show(electricBorderMaximizeGeometry(Cursor::pos(), desktop()));
outline()->show(electricBorderMaximizeGeometry(Cursor::pos(), desktop()), moveResizeGeometry());
else
outline()->hide();
elevate(maximizing);

View file

@ -55,8 +55,6 @@ Outline::~Outline()
void Outline::show()
{
m_active = true;
emit activeChanged();
if (m_visual.isNull()) {
createHelper();
}
@ -65,6 +63,8 @@ void Outline::show()
return;
}
m_visual->show();
m_active = true;
emit activeChanged();
}
void Outline::hide()
@ -81,8 +81,14 @@ void Outline::hide()
}
void Outline::show(const QRect& outlineGeometry)
{
show(outlineGeometry, QRect());
}
void Outline::show(const QRect &outlineGeometry, const QRect &visualParentGeometry)
{
setGeometry(outlineGeometry);
setVisualParentGeometry(visualParentGeometry);
show();
}
@ -93,6 +99,22 @@ void Outline::setGeometry(const QRect& outlineGeometry)
}
m_outlineGeometry = outlineGeometry;
emit geometryChanged();
emit unifiedGeometryChanged();
}
void Outline::setVisualParentGeometry(const QRect &visualParentGeometry)
{
if (m_visualParentGeometry == visualParentGeometry) {
return;
}
m_visualParentGeometry = visualParentGeometry;
emit visualParentGeometryChanged();
emit unifiedGeometryChanged();
}
QRect Outline::unifiedGeometry() const
{
return m_outlineGeometry | m_visualParentGeometry;
}
void Outline::createHelper()

View file

@ -45,6 +45,8 @@ class OutlineVisual;
class Outline : public QObject {
Q_OBJECT
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
Q_PROPERTY(QRect visualParentGeometry READ visualParentGeometry NOTIFY visualParentGeometryChanged)
Q_PROPERTY(QRect unifiedGeometry READ unifiedGeometry NOTIFY unifiedGeometryChanged)
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
public:
~Outline();
@ -57,6 +59,14 @@ public:
*/
void setGeometry(const QRect &outlineGeometry);
/**
* Set the visual parent geometry.
* This is the geometry from which the will emerge.
* @param visualParentGeometry The visual geometry of the visual parent
* @see showOutline
*/
void setVisualParentGeometry(const QRect &visualParentGeometry);
/**
* Shows the outline of a window using either an effect or the X implementation.
* To stop the outline process use @link hideOutline.
@ -73,6 +83,18 @@ public:
*/
void show(const QRect &outlineGeometry);
/**
* Shows the outline for the given @p outlineGeometry animated from @p visualParentGeometry.
* This is the same as setOutlineGeometry followed by setVisualParentGeometry
* and then showOutline.
* To stop the outline process use @link hideOutline.
* @param outlineGeometry The geometry of the outline to be shown
* @param visualParentGeometry The geometry from where the outline should emerge
* @see hideOutline
* @since 5.10
*/
void show(const QRect &outlineGeometry, const QRect &visualParentGeometry);
/**
* Hides shown outline.
* @see showOutline
@ -80,6 +102,8 @@ public:
void hide();
const QRect &geometry() const;
const QRect &visualParentGeometry() const;
QRect unifiedGeometry() const;
bool isActive() const;
@ -89,11 +113,14 @@ private Q_SLOTS:
Q_SIGNALS:
void activeChanged();
void geometryChanged();
void unifiedGeometryChanged();
void visualParentGeometryChanged();
private:
void createHelper();
QScopedPointer<OutlineVisual> m_visual;
QRect m_outlineGeometry;
QRect m_visualParentGeometry;
bool m_active;
KWIN_SINGLETON(Outline)
};
@ -156,6 +183,12 @@ const QRect &Outline::geometry() const
return m_outlineGeometry;
}
inline
const QRect &Outline::visualParentGeometry() const
{
return m_visualParentGeometry;
}
inline
Outline *OutlineVisual::outline()
{

View file

@ -1,5 +1,6 @@
/*
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
* Copyright 2017 Kai Uwe Broulik <kde@privat.broulik.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -17,41 +18,84 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.1;
import QtQuick.Window 2.1;
import org.kde.plasma.core 2.0 as PlasmaCore;
import QtQuick 2.1
import QtQuick.Window 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
Window {
id: window
readonly property int animationDuration: units.longDuration
property bool animationEnabled: false
flags: Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
color: "transparent"
// outline is a context property
x: outline.geometry.x
y: outline.geometry.y
width: outline.geometry.width
height: outline.geometry.height
x: outline.unifiedGeometry.x
y: outline.unifiedGeometry.y
width: outline.unifiedGeometry.width
height: outline.unifiedGeometry.height
visible: outline.active
onVisibleChanged: {
if (visible) {
if (outline.visualParentGeometry.width > 0 && outline.visualParentGeometry.height > 0) {
window.animationEnabled = false
// move our frame to the visual parent geometry
svg.setGeometry(outline.visualParentGeometry)
window.animationEnabled = true
// and then animate it nicely to its destination
svg.setGeometry(outline.geometry)
} else {
// no visual parent? just move it to its destination right away
window.animationEnabled = false
svg.setGeometry(outline.geometry)
window.animationEnabled = true
}
}
}
Connections {
target: outline
// when unified geometry changes, this means our window position changed and any
// animation will potentially be offset and/or cut off, skip the animation in this case
onUnifiedGeometryChanged: {
if (window.visible) {
window.animationEnabled = false
svg.setGeometry(outline.geometry)
window.animationEnabled = true
}
}
}
PlasmaCore.FrameSvgItem {
function updateBorders() {
id: svg
// takes into account the offset inside unified geometry
function setGeometry(geometry) {
x = geometry.x - outline.unifiedGeometry.x
y = geometry.y - outline.unifiedGeometry.y
width = geometry.width
height = geometry.height
}
imagePath: "widgets/translucentbackground"
x: 0
y: 0
width: 0
height: 0
enabledBorders: {
var maximizedArea = workspace.clientArea(workspace.MaximizeArea, Qt.point(outline.geometry.x, outline.geometry.y), workspace.currentDesktop);
var left = false;
var right = false;
var top = false;
var bottom = false;
if (outline.geometry.x == maximizedArea.x) {
left = true;
}
if (outline.geometry.y == maximizedArea.y) {
top = true;
}
if (outline.geometry.x + outline.geometry.width == maximizedArea.x + maximizedArea.width) {
right = true;
}
if (outline.geometry.y + outline.geometry.height == maximizedArea.y + maximizedArea.height) {
bottom = true;
}
var left = outline.geometry.x === maximizedArea.x;
var right = outline.geometry.x + outline.geometry.width === maximizedArea.x + maximizedArea.width;
var top = outline.geometry.y === maximizedArea.y;
var bottom = outline.geometry.y + outline.geometry.height === maximizedArea.y + maximizedArea.height;
var borders = PlasmaCore.FrameSvgItem.AllBorders;
if (left) {
borders = borders & ~PlasmaCore.FrameSvgItem.LeftBorder;
@ -68,15 +112,24 @@ Window {
if (left && right && bottom && top) {
borders = PlasmaCore.FrameSvgItem.AllBorders;
}
svg.enabledBorders = borders;
return borders;
}
id: svg
imagePath: "widgets/translucentbackground"
anchors.fill: parent
Connections {
target: outline
onGeometryChanged: svg.updateBorders()
Behavior on x {
NumberAnimation { duration: window.animationDuration; easing.type: Easing.InOutQuad; }
enabled: window.animationEnabled
}
Behavior on y {
NumberAnimation { duration: window.animationDuration; easing.type: Easing.InOutQuad; }
enabled: window.animationEnabled
}
Behavior on width {
NumberAnimation { duration: window.animationDuration; easing.type: Easing.InOutQuad; }
enabled: window.animationEnabled
}
Behavior on height {
NumberAnimation { duration: window.animationDuration; easing.type: Easing.InOutQuad; }
enabled: window.animationEnabled
}
Component.onCompleted: svg.updateBorders()
}
}