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:
parent
dc447860be
commit
eaf41cb6c5
4 changed files with 143 additions and 35 deletions
|
@ -3254,7 +3254,7 @@ void AbstractClient::setElectricBorderMaximizing(bool maximizing)
|
||||||
{
|
{
|
||||||
m_electricMaximizing = maximizing;
|
m_electricMaximizing = maximizing;
|
||||||
if (maximizing)
|
if (maximizing)
|
||||||
outline()->show(electricBorderMaximizeGeometry(Cursor::pos(), desktop()));
|
outline()->show(electricBorderMaximizeGeometry(Cursor::pos(), desktop()), moveResizeGeometry());
|
||||||
else
|
else
|
||||||
outline()->hide();
|
outline()->hide();
|
||||||
elevate(maximizing);
|
elevate(maximizing);
|
||||||
|
|
26
outline.cpp
26
outline.cpp
|
@ -55,8 +55,6 @@ Outline::~Outline()
|
||||||
|
|
||||||
void Outline::show()
|
void Outline::show()
|
||||||
{
|
{
|
||||||
m_active = true;
|
|
||||||
emit activeChanged();
|
|
||||||
if (m_visual.isNull()) {
|
if (m_visual.isNull()) {
|
||||||
createHelper();
|
createHelper();
|
||||||
}
|
}
|
||||||
|
@ -65,6 +63,8 @@ void Outline::show()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_visual->show();
|
m_visual->show();
|
||||||
|
m_active = true;
|
||||||
|
emit activeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Outline::hide()
|
void Outline::hide()
|
||||||
|
@ -81,8 +81,14 @@ void Outline::hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
void Outline::show(const QRect& outlineGeometry)
|
void Outline::show(const QRect& outlineGeometry)
|
||||||
|
{
|
||||||
|
show(outlineGeometry, QRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Outline::show(const QRect &outlineGeometry, const QRect &visualParentGeometry)
|
||||||
{
|
{
|
||||||
setGeometry(outlineGeometry);
|
setGeometry(outlineGeometry);
|
||||||
|
setVisualParentGeometry(visualParentGeometry);
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +99,22 @@ void Outline::setGeometry(const QRect& outlineGeometry)
|
||||||
}
|
}
|
||||||
m_outlineGeometry = outlineGeometry;
|
m_outlineGeometry = outlineGeometry;
|
||||||
emit geometryChanged();
|
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()
|
void Outline::createHelper()
|
||||||
|
|
33
outline.h
33
outline.h
|
@ -45,6 +45,8 @@ class OutlineVisual;
|
||||||
class Outline : public QObject {
|
class Outline : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
|
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)
|
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
|
||||||
public:
|
public:
|
||||||
~Outline();
|
~Outline();
|
||||||
|
@ -57,6 +59,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void setGeometry(const QRect &outlineGeometry);
|
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.
|
* Shows the outline of a window using either an effect or the X implementation.
|
||||||
* To stop the outline process use @link hideOutline.
|
* To stop the outline process use @link hideOutline.
|
||||||
|
@ -73,6 +83,18 @@ public:
|
||||||
*/
|
*/
|
||||||
void show(const QRect &outlineGeometry);
|
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.
|
* Hides shown outline.
|
||||||
* @see showOutline
|
* @see showOutline
|
||||||
|
@ -80,6 +102,8 @@ public:
|
||||||
void hide();
|
void hide();
|
||||||
|
|
||||||
const QRect &geometry() const;
|
const QRect &geometry() const;
|
||||||
|
const QRect &visualParentGeometry() const;
|
||||||
|
QRect unifiedGeometry() const;
|
||||||
|
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
|
|
||||||
|
@ -89,11 +113,14 @@ private Q_SLOTS:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void activeChanged();
|
void activeChanged();
|
||||||
void geometryChanged();
|
void geometryChanged();
|
||||||
|
void unifiedGeometryChanged();
|
||||||
|
void visualParentGeometryChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createHelper();
|
void createHelper();
|
||||||
QScopedPointer<OutlineVisual> m_visual;
|
QScopedPointer<OutlineVisual> m_visual;
|
||||||
QRect m_outlineGeometry;
|
QRect m_outlineGeometry;
|
||||||
|
QRect m_visualParentGeometry;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
KWIN_SINGLETON(Outline)
|
KWIN_SINGLETON(Outline)
|
||||||
};
|
};
|
||||||
|
@ -156,6 +183,12 @@ const QRect &Outline::geometry() const
|
||||||
return m_outlineGeometry;
|
return m_outlineGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const QRect &Outline::visualParentGeometry() const
|
||||||
|
{
|
||||||
|
return m_visualParentGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Outline *OutlineVisual::outline()
|
Outline *OutlineVisual::outline()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.1;
|
import QtQuick 2.1
|
||||||
import QtQuick.Window 2.1;
|
import QtQuick.Window 2.1
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore;
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
Window {
|
Window {
|
||||||
id: window
|
id: window
|
||||||
|
|
||||||
|
readonly property int animationDuration: units.longDuration
|
||||||
|
property bool animationEnabled: false
|
||||||
|
|
||||||
flags: Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
|
flags: Qt.BypassWindowManagerHint | Qt.FramelessWindowHint
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
// outline is a context property
|
// outline is a context property
|
||||||
x: outline.geometry.x
|
x: outline.unifiedGeometry.x
|
||||||
y: outline.geometry.y
|
y: outline.unifiedGeometry.y
|
||||||
width: outline.geometry.width
|
width: outline.unifiedGeometry.width
|
||||||
height: outline.geometry.height
|
height: outline.unifiedGeometry.height
|
||||||
|
|
||||||
visible: outline.active
|
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 {
|
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 maximizedArea = workspace.clientArea(workspace.MaximizeArea, Qt.point(outline.geometry.x, outline.geometry.y), workspace.currentDesktop);
|
||||||
var left = false;
|
|
||||||
var right = false;
|
var left = outline.geometry.x === maximizedArea.x;
|
||||||
var top = false;
|
var right = outline.geometry.x + outline.geometry.width === maximizedArea.x + maximizedArea.width;
|
||||||
var bottom = false;
|
var top = outline.geometry.y === maximizedArea.y;
|
||||||
if (outline.geometry.x == maximizedArea.x) {
|
var bottom = outline.geometry.y + outline.geometry.height === maximizedArea.y + maximizedArea.height;
|
||||||
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 borders = PlasmaCore.FrameSvgItem.AllBorders;
|
var borders = PlasmaCore.FrameSvgItem.AllBorders;
|
||||||
if (left) {
|
if (left) {
|
||||||
borders = borders & ~PlasmaCore.FrameSvgItem.LeftBorder;
|
borders = borders & ~PlasmaCore.FrameSvgItem.LeftBorder;
|
||||||
|
@ -68,15 +112,24 @@ Window {
|
||||||
if (left && right && bottom && top) {
|
if (left && right && bottom && top) {
|
||||||
borders = PlasmaCore.FrameSvgItem.AllBorders;
|
borders = PlasmaCore.FrameSvgItem.AllBorders;
|
||||||
}
|
}
|
||||||
svg.enabledBorders = borders;
|
return borders;
|
||||||
}
|
}
|
||||||
id: svg
|
|
||||||
imagePath: "widgets/translucentbackground"
|
Behavior on x {
|
||||||
anchors.fill: parent
|
NumberAnimation { duration: window.animationDuration; easing.type: Easing.InOutQuad; }
|
||||||
Connections {
|
enabled: window.animationEnabled
|
||||||
target: outline
|
}
|
||||||
onGeometryChanged: svg.updateBorders()
|
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue