parent
4a2c33f517
commit
0b97969044
20 changed files with 1542 additions and 0 deletions
@ -0,0 +1,45 @@ |
||||
From 605ebb66085a7f004f7ed6f5851a416d56a790e8 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Wed, 18 Dec 2024 11:59:09 -0500
|
||||
Subject: [PATCH 01/20] Implement moveRelative
|
||||
|
||||
---
|
||||
src/window.cpp | 5 +++++
|
||||
src/window.h | 5 +++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index d70e9bccfe..64ad8d977c 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -3499,6 +3499,11 @@ void Window::setMoveResizeGeometry(const QRectF &geo)
|
||||
setMoveResizeOutput(workspace()->outputAt(geo.center()));
|
||||
}
|
||||
|
||||
+void Window::moveRelative(const QPointF &point)
|
||||
+{
|
||||
+ move(m_frameGeometry.topLeft() + point);
|
||||
+}
|
||||
+
|
||||
Output *Window::moveResizeOutput() const
|
||||
{
|
||||
return m_moveResizeOutput;
|
||||
diff --git a/src/window.h b/src/window.h
|
||||
index 8e15cf8079..2f935e4c19 100644
|
||||
--- a/src/window.h
|
||||
+++ b/src/window.h
|
||||
@@ -718,6 +718,11 @@ public:
|
||||
*/
|
||||
void move(const QPointF &topLeft);
|
||||
|
||||
+ /**
|
||||
+ * Moves the window so that the new topLeft corner of the frame is moved by @p point.
|
||||
+ */
|
||||
+ void moveRelative(const QPointF &point);
|
||||
+
|
||||
/**
|
||||
* Resizes the window to have a new @p size but stay with the top-left corner in the same position.
|
||||
*/
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,55 @@ |
||||
From 56f9b3e2d262e2b4deae68fd62992aada45d2a2e Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Mon, 23 Jun 2025 09:40:54 +0200
|
||||
Subject: [PATCH 02/20] Make output yield tiling constants
|
||||
|
||||
in order to have pixel-perfect placement, the tile gap size and border
|
||||
size must depend on the output size and scaling.
|
||||
---
|
||||
src/core/output.cpp | 10 ++++++++++
|
||||
src/core/output.h | 8 ++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/src/core/output.cpp b/src/core/output.cpp
|
||||
index d884b68fe1..9763561e2c 100644
|
||||
--- a/src/core/output.cpp
|
||||
+++ b/src/core/output.cpp
|
||||
@@ -451,6 +451,16 @@ qreal Output::scale() const
|
||||
return m_state.scale;
|
||||
}
|
||||
|
||||
+qreal Output::defaultPadding() const
|
||||
+{
|
||||
+ return 4. / scale();
|
||||
+}
|
||||
+
|
||||
+qreal Output::defaultBorder() const
|
||||
+{
|
||||
+ return 1. / scale();
|
||||
+}
|
||||
+
|
||||
QRect Output::geometry() const
|
||||
{
|
||||
return QRect(m_state.position, pixelSize() / scale());
|
||||
diff --git a/src/core/output.h b/src/core/output.h
|
||||
index 0122bc34ed..15f03f5630 100644
|
||||
--- a/src/core/output.h
|
||||
+++ b/src/core/output.h
|
||||
@@ -251,6 +251,14 @@ public:
|
||||
*/
|
||||
bool isEnabled() const;
|
||||
|
||||
+ /**
|
||||
+ * Returns default-padding and cutout size of this output in device
|
||||
+ independent pixels.
|
||||
+ */
|
||||
+
|
||||
+ qreal defaultPadding() const;
|
||||
+ qreal defaultBorder() const;
|
||||
+
|
||||
/**
|
||||
* Returns geometry of this output in device independent pixels.
|
||||
*/
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,51 @@ |
||||
From 23374adae557911d1e403c560c1f61aeb0004e44 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Wed, 18 Dec 2024 15:11:22 -0500
|
||||
Subject: [PATCH 03/20] Adjust screen area for tiling + gaps
|
||||
|
||||
---
|
||||
src/workspace.cpp | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/workspace.cpp b/src/workspace.cpp
|
||||
index 0283608c89..bd64f4f248 100644
|
||||
--- a/src/workspace.cpp
|
||||
+++ b/src/workspace.cpp
|
||||
@@ -2271,22 +2271,30 @@ void Workspace::rearrange()
|
||||
*/
|
||||
QRectF Workspace::clientArea(clientAreaOption opt, const Output *output, const VirtualDesktop *desktop) const
|
||||
{
|
||||
+ qreal border = output->defaultBorder() + output->defaultPadding();
|
||||
+
|
||||
switch (opt) {
|
||||
case MaximizeArea:
|
||||
- case PlacementArea:
|
||||
+ case PlacementArea: {
|
||||
if (auto desktopIt = m_screenAreas.constFind(desktop); desktopIt != m_screenAreas.constEnd()) {
|
||||
if (auto outputIt = desktopIt->constFind(output); outputIt != desktopIt->constEnd()) {
|
||||
- return *outputIt;
|
||||
+ auto screenArea = *outputIt;
|
||||
+
|
||||
+ return screenArea - QMarginsF(border, border, border, border);
|
||||
}
|
||||
}
|
||||
return output->geometryF();
|
||||
+ }
|
||||
case MaximizeFullArea:
|
||||
case FullScreenArea:
|
||||
case MovementArea:
|
||||
case ScreenArea:
|
||||
return output->geometryF();
|
||||
- case WorkArea:
|
||||
- return m_workAreas.value(desktop, m_geometry);
|
||||
+ case WorkArea: {
|
||||
+ auto workArea = m_workAreas.value(desktop, m_geometry);
|
||||
+
|
||||
+ return workArea - QMarginsF(border, border, border, border);
|
||||
+ }
|
||||
case FullArea:
|
||||
return m_geometry;
|
||||
default:
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,86 @@ |
||||
From 3b9c72ad9b8b745a823d8a8fd7f11d57ef94b0fb Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Sat, 4 Jan 2025 22:57:57 -0500
|
||||
Subject: [PATCH 04/20] Add user actions for quick third-tiling
|
||||
|
||||
---
|
||||
src/effect/globals.h | 7 +++++++
|
||||
src/scripting/workspace_wrapper.cpp | 5 +++++
|
||||
src/scripting/workspace_wrapper.h | 5 +++++
|
||||
src/useractions.cpp | 10 ++++++++++
|
||||
4 files changed, 27 insertions(+)
|
||||
|
||||
diff --git a/src/effect/globals.h b/src/effect/globals.h
|
||||
index b602c07256..819a097580 100644
|
||||
--- a/src/effect/globals.h
|
||||
+++ b/src/effect/globals.h
|
||||
@@ -198,6 +198,13 @@ enum class QuickTileFlag {
|
||||
Custom = 1 << 4,
|
||||
Horizontal = Left | Right,
|
||||
Vertical = Top | Bottom,
|
||||
+ Third1 = 1 << 5,
|
||||
+ Third2 = 1 << 6,
|
||||
+ Third3 = 1 << 7,
|
||||
+ Third12 = Third1 | Third2,
|
||||
+ Third23 = Third2 | Third3,
|
||||
+ Thirds = Third1 | Third2 | Third3,
|
||||
+ HorizontalComplete = Horizontal | Thirds,
|
||||
};
|
||||
Q_ENUM_NS(QuickTileFlag)
|
||||
Q_DECLARE_FLAGS(QuickTileMode, QuickTileFlag)
|
||||
diff --git a/src/scripting/workspace_wrapper.cpp b/src/scripting/workspace_wrapper.cpp
|
||||
index d1e504b3ac..c9b34876ba 100644
|
||||
--- a/src/scripting/workspace_wrapper.cpp
|
||||
+++ b/src/scripting/workspace_wrapper.cpp
|
||||
@@ -191,6 +191,11 @@ SLOTWRAPPER(slotSwitchToBelowScreen)
|
||||
}
|
||||
|
||||
SLOTWRAPPER(slotWindowQuickTileLeft, QuickTileFlag::Left)
|
||||
+SLOTWRAPPER(slotWindowQuickTileThird1, QuickTileFlag::Third1)
|
||||
+SLOTWRAPPER(slotWindowQuickTileThird12, QuickTileFlag::Third12)
|
||||
+SLOTWRAPPER(slotWindowQuickTileThird2, QuickTileFlag::Third2)
|
||||
+SLOTWRAPPER(slotWindowQuickTileThird23, QuickTileFlag::Third23)
|
||||
+SLOTWRAPPER(slotWindowQuickTileThird3, QuickTileFlag::Third3)
|
||||
SLOTWRAPPER(slotWindowQuickTileRight, QuickTileFlag::Right)
|
||||
SLOTWRAPPER(slotWindowQuickTileTop, QuickTileFlag::Top)
|
||||
SLOTWRAPPER(slotWindowQuickTileBottom, QuickTileFlag::Bottom)
|
||||
diff --git a/src/scripting/workspace_wrapper.h b/src/scripting/workspace_wrapper.h
|
||||
index c1a7db63e7..352208f9e4 100644
|
||||
--- a/src/scripting/workspace_wrapper.h
|
||||
+++ b/src/scripting/workspace_wrapper.h
|
||||
@@ -357,6 +357,11 @@ public Q_SLOTS:
|
||||
void slotWindowShrinkVertical();
|
||||
void slotWindowQuickTileLeft();
|
||||
void slotWindowQuickTileRight();
|
||||
+ void slotWindowQuickTileThird1();
|
||||
+ void slotWindowQuickTileThird12();
|
||||
+ void slotWindowQuickTileThird2();
|
||||
+ void slotWindowQuickTileThird23();
|
||||
+ void slotWindowQuickTileThird3();
|
||||
void slotWindowQuickTileTop();
|
||||
void slotWindowQuickTileBottom();
|
||||
void slotWindowQuickTileTopLeft();
|
||||
diff --git a/src/useractions.cpp b/src/useractions.cpp
|
||||
index 7691e5eb03..6e841d96cd 100644
|
||||
--- a/src/useractions.cpp
|
||||
+++ b/src/useractions.cpp
|
||||
@@ -942,6 +942,16 @@ void Workspace::initShortcuts()
|
||||
Qt::META | Qt::Key_Left, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Left));
|
||||
initShortcut("Window Quick Tile Right", i18n("Quick Tile Window to the Right"),
|
||||
Qt::META | Qt::Key_Right, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Right));
|
||||
+ initShortcut("Window Quick Tile Left Third", i18n("Quick Tile Window to the Left Third"),
|
||||
+ 0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third1));
|
||||
+ initShortcut("Window Quick Tile Left Two-Thirds", i18n("Quick Tile Window to the Left Two-Thirds"),
|
||||
+ 0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third12));
|
||||
+ initShortcut("Window Quick Tile Right Two-Thirds", i18n("Quick Tile Window to the Right Two-Thirds"),
|
||||
+ 0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third23));
|
||||
+ initShortcut("Window Quick Tile Center Third", i18n("Quick Tile Window to the Center Third"),
|
||||
+ 0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third2));
|
||||
+ initShortcut("Window Quick Tile Right Third", i18n("Quick Tile Window to the Right Third"),
|
||||
+ 0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third3));
|
||||
initShortcut("Window Quick Tile Top", i18n("Quick Tile Window to the Top"),
|
||||
Qt::META | Qt::Key_Up, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Top));
|
||||
initShortcut("Window Quick Tile Bottom", i18n("Quick Tile Window to the Bottom"),
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,25 @@ |
||||
From 482eda79d03b7eeb127390bb6d1f91438cc5d053 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Sun, 5 Jan 2025 01:05:09 -0500
|
||||
Subject: [PATCH 05/20] Force maximized windows to cast a shadow
|
||||
|
||||
---
|
||||
src/window.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index 64ad8d977c..4eca4627dd 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -289,7 +289,7 @@ SurfaceItem *Window::surfaceItem() const
|
||||
|
||||
bool Window::wantsShadowToBeRendered() const
|
||||
{
|
||||
- return !isFullScreen() && maximizeMode() != MaximizeFull;
|
||||
+ return !isFullScreen();
|
||||
}
|
||||
|
||||
bool Window::isClient() const
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,134 @@ |
||||
From 4fc4c8b801315a7eb90b8fe8bf7c30b957ec4fcc Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Wed, 1 Oct 2025 20:24:58 -0400
|
||||
Subject: [PATCH 06/20] Add Quicktiles at thirds
|
||||
|
||||
---
|
||||
src/tiles/quicktile.cpp | 53 +++++++++++++++++++++++++++++++++++++++++
|
||||
src/tiles/quicktile.h | 18 ++++++++++++++
|
||||
2 files changed, 71 insertions(+)
|
||||
|
||||
diff --git a/src/tiles/quicktile.cpp b/src/tiles/quicktile.cpp
|
||||
index 8c8dc93952..507df27ed1 100644
|
||||
--- a/src/tiles/quicktile.cpp
|
||||
+++ b/src/tiles/quicktile.cpp
|
||||
@@ -38,6 +38,13 @@ QuickRootTile::QuickRootTile(TileManager *tiling, VirtualDesktop *desktop)
|
||||
|
||||
m_leftVerticalTile = createTile(QRectF(0, 0, 0.5, 1), QuickTileFlag::Left);
|
||||
m_rightVerticalTile = createTile(QRectF(0.5, 0, 0.5, 1), QuickTileFlag::Right);
|
||||
+
|
||||
+ m_third1VerticalTile = createTile(QRectF(0, 0, 1. / 3., 1), QuickTileFlag::Third1);
|
||||
+ m_third12VerticalTile = createTile(QRectF(0, 0, 2. / 3., 1), QuickTileFlag::Third1 | QuickTileFlag::Third2);
|
||||
+ m_third2VerticalTile = createTile(QRectF(1. / 3., 0, 1. / 3., 1), QuickTileFlag::Third2);
|
||||
+ m_third23VerticalTile = createTile(QRectF(1. / 3., 0, 2. / 3., 1), QuickTileFlag::Third2 | QuickTileFlag::Third3);
|
||||
+ m_third3VerticalTile = createTile(QRectF(2. / 3., 0, 1. / 3., 1), QuickTileFlag::Third3);
|
||||
+
|
||||
m_topHorizontalTile = createTile(QRectF(0, 0, 1, 0.5), QuickTileFlag::Top);
|
||||
m_bottomHorizontalTile = createTile(QRectF(0, 0.5, 1, 0.5), QuickTileFlag::Bottom);
|
||||
|
||||
@@ -45,6 +52,18 @@ QuickRootTile::QuickRootTile(TileManager *tiling, VirtualDesktop *desktop)
|
||||
m_topRightTile = createTile(QRectF(0.5, 0, 0.5, 0.5), QuickTileFlag::Top | QuickTileFlag::Right);
|
||||
m_bottomLeftTile = createTile(QRectF(0, 0.5, 0.5, 0.5), QuickTileFlag::Bottom | QuickTileFlag::Left);
|
||||
m_bottomRightTile = createTile(QRectF(0.5, 0.5, 0.5, 0.5), QuickTileFlag::Bottom | QuickTileFlag::Right);
|
||||
+
|
||||
+ m_topThird1Tile = createTile(QRectF(0, 0, 1. / 3., 0.5), QuickTileFlag::Top | QuickTileFlag::Third1);
|
||||
+ m_topThird12Tile = createTile(QRectF(0, 0, 2. / 3., 0.5), QuickTileFlag::Top | QuickTileFlag::Third1 | QuickTileFlag::Third2);
|
||||
+ m_topThird2Tile = createTile(QRectF(1. / 3., 0, 1. / 3., 0.5), QuickTileFlag::Top | QuickTileFlag::Third2);
|
||||
+ m_topThird23Tile = createTile(QRectF(1. / 3., 0, 2. / 3., 0.5), QuickTileFlag::Top | QuickTileFlag::Third2 | QuickTileFlag::Third3);
|
||||
+ m_topThird3Tile = createTile(QRectF(2. / 3., 0, 1. / 3., 0.5), QuickTileFlag::Top | QuickTileFlag::Third3);
|
||||
+
|
||||
+ m_bottomThird1Tile = createTile(QRectF(0, 0.5, 1. / 3., 0.5), QuickTileFlag::Bottom | QuickTileFlag::Third1);
|
||||
+ m_bottomThird12Tile = createTile(QRectF(0, 0.5, 2. / 3., 0.5), QuickTileFlag::Bottom | QuickTileFlag::Third1 | QuickTileFlag::Third2);
|
||||
+ m_bottomThird2Tile = createTile(QRectF(1. / 3., 0.5, 1. / 3., 0.5), QuickTileFlag::Bottom | QuickTileFlag::Third2);
|
||||
+ m_bottomThird23Tile = createTile(QRectF(1. / 3., 0.5, 2. / 3., 0.5), QuickTileFlag::Bottom | QuickTileFlag::Third2 | QuickTileFlag::Third3);
|
||||
+ m_bottomThird3Tile = createTile(QRectF(2. / 3., 0.5, 1. / 3., 0.5), QuickTileFlag::Bottom | QuickTileFlag::Third3);
|
||||
}
|
||||
|
||||
QuickRootTile::~QuickRootTile()
|
||||
@@ -93,6 +112,17 @@ Tile *QuickRootTile::tileForMode(QuickTileMode mode)
|
||||
return m_leftVerticalTile;
|
||||
case QuickTileMode(QuickTileFlag::Right):
|
||||
return m_rightVerticalTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Third1):
|
||||
+ return m_third1VerticalTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Third2):
|
||||
+ return m_third2VerticalTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Third3):
|
||||
+ return m_third3VerticalTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Third1 | QuickTileFlag::Third2):
|
||||
+ return m_third12VerticalTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Third2 | QuickTileFlag::Third3):
|
||||
+ return m_third23VerticalTile;
|
||||
+
|
||||
case QuickTileMode(QuickTileFlag::Top):
|
||||
return m_topHorizontalTile;
|
||||
case QuickTileMode(QuickTileFlag::Bottom):
|
||||
@@ -105,6 +135,29 @@ Tile *QuickRootTile::tileForMode(QuickTileMode mode)
|
||||
return m_bottomLeftTile;
|
||||
case QuickTileMode(QuickTileFlag::Right | QuickTileFlag::Bottom):
|
||||
return m_bottomRightTile;
|
||||
+ case QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Third1):
|
||||
+ return m_topThird1Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Third2):
|
||||
+ return m_topThird2Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Third3):
|
||||
+ return m_topThird3Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Third1 | QuickTileFlag::Third2):
|
||||
+ return m_topThird12Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Third2 | QuickTileFlag::Third3):
|
||||
+ return m_topThird23Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Third1):
|
||||
+ return m_bottomThird1Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Third2):
|
||||
+ return m_bottomThird2Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Third3):
|
||||
+ return m_bottomThird3Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Third1 | QuickTileFlag::Third2):
|
||||
+ return m_bottomThird12Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Third2 | QuickTileFlag::Third3):
|
||||
+ return m_bottomThird23Tile;
|
||||
+ case QuickTileMode(QuickTileFlag::Horizontal):
|
||||
+ case QuickTileMode(QuickTileFlag::Vertical):
|
||||
+ return this;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
diff --git a/src/tiles/quicktile.h b/src/tiles/quicktile.h
|
||||
index 6abb622740..4a75874f6d 100644
|
||||
--- a/src/tiles/quicktile.h
|
||||
+++ b/src/tiles/quicktile.h
|
||||
@@ -45,6 +45,12 @@ private:
|
||||
Tile *m_leftVerticalTile = nullptr;
|
||||
Tile *m_rightVerticalTile = nullptr;
|
||||
|
||||
+ Tile *m_third1VerticalTile = nullptr;
|
||||
+ Tile *m_third12VerticalTile = nullptr;
|
||||
+ Tile *m_third2VerticalTile = nullptr;
|
||||
+ Tile *m_third23VerticalTile = nullptr;
|
||||
+ Tile *m_third3VerticalTile = nullptr;
|
||||
+
|
||||
Tile *m_topHorizontalTile = nullptr;
|
||||
Tile *m_bottomHorizontalTile = nullptr;
|
||||
|
||||
@@ -52,6 +58,18 @@ private:
|
||||
Tile *m_topRightTile = nullptr;
|
||||
Tile *m_bottomLeftTile = nullptr;
|
||||
Tile *m_bottomRightTile = nullptr;
|
||||
+
|
||||
+ Tile *m_topThird1Tile = nullptr;
|
||||
+ Tile *m_topThird12Tile = nullptr;
|
||||
+ Tile *m_topThird2Tile = nullptr;
|
||||
+ Tile *m_topThird23Tile = nullptr;
|
||||
+ Tile *m_topThird3Tile = nullptr;
|
||||
+
|
||||
+ Tile *m_bottomThird1Tile = nullptr;
|
||||
+ Tile *m_bottomThird12Tile = nullptr;
|
||||
+ Tile *m_bottomThird2Tile = nullptr;
|
||||
+ Tile *m_bottomThird23Tile = nullptr;
|
||||
+ Tile *m_bottomThird3Tile = nullptr;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,33 @@ |
||||
From 124e9a52b8b2051cbc37a1d603cfc8a0622feee3 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Wed, 1 Mar 2023 12:36:23 -0500
|
||||
Subject: [PATCH 07/20] Add padding to qulcktiles
|
||||
|
||||
---
|
||||
src/tiles/quicktile.cpp | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tiles/quicktile.cpp b/src/tiles/quicktile.cpp
|
||||
index 507df27ed1..c5c255e648 100644
|
||||
--- a/src/tiles/quicktile.cpp
|
||||
+++ b/src/tiles/quicktile.cpp
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "quicktile.h"
|
||||
#include "tilemanager.h"
|
||||
#include "virtualdesktops.h"
|
||||
+#include "core/output.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
@@ -25,7 +26,7 @@ QuickRootTile::QuickRootTile(TileManager *tiling, VirtualDesktop *desktop)
|
||||
|
||||
auto createTile = [this](const QRectF &geometry, QuickTileMode tileMode) {
|
||||
Tile *tile = createChildAt<Tile>(geometry, childCount());
|
||||
- tile->setPadding(0.0);
|
||||
+ tile->setPadding(m_tiling->output()->defaultPadding());
|
||||
tile->setQuickTileMode(tileMode);
|
||||
|
||||
connect(tile, &Tile::relativeGeometryChanged, this, [this, tile]() {
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,46 @@ |
||||
From 401840537e09859db6811661995cabf0f7fc3fe9 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Tue, 24 Jun 2025 13:19:24 +0200
|
||||
Subject: [PATCH 08/20] Use geometry relative to the cutout
|
||||
|
||||
---
|
||||
src/tiles/tile.cpp | 19 +++++++++----------
|
||||
1 file changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/tiles/tile.cpp b/src/tiles/tile.cpp
|
||||
index d7377d9d18..3c3ba61632 100644
|
||||
--- a/src/tiles/tile.cpp
|
||||
+++ b/src/tiles/tile.cpp
|
||||
@@ -153,20 +153,19 @@ QRectF Tile::relativeGeometry() const
|
||||
|
||||
QRectF Tile::absoluteGeometry() const
|
||||
{
|
||||
- const QRectF geom = m_tiling->output()->geometryF();
|
||||
- return QRectF(std::round(geom.x() + m_relativeGeometry.x() * geom.width()),
|
||||
- std::round(geom.y() + m_relativeGeometry.y() * geom.height()),
|
||||
- std::round(m_relativeGeometry.width() * geom.width()),
|
||||
- std::round(m_relativeGeometry.height() * geom.height()));
|
||||
-}
|
||||
+ qreal cutoutSize = m_tiling->output()->defaultPadding() + m_tiling->output()->defaultBorder();
|
||||
+ const QMarginsF cutout = QMarginsF(cutoutSize, cutoutSize, cutoutSize, cutoutSize);
|
||||
+ const QRectF geom = m_tiling->output()->geometryF() - cutout;
|
||||
+ return QRectF(geom.x() + m_relativeGeometry.x() * geom.width(),
|
||||
+ geom.y() + m_relativeGeometry.y() * geom.height(),
|
||||
+ m_relativeGeometry.width() * geom.width(),
|
||||
+ m_relativeGeometry.height() * geom.height());
|
||||
+} // the code in master is rounding, but why???
|
||||
|
||||
QRectF Tile::absoluteGeometryInScreen() const
|
||||
{
|
||||
const QRectF geom = m_tiling->output()->geometryF();
|
||||
- return QRectF(std::round(m_relativeGeometry.x() * geom.width()),
|
||||
- std::round(m_relativeGeometry.y() * geom.height()),
|
||||
- std::round(m_relativeGeometry.width() * geom.width()),
|
||||
- std::round(m_relativeGeometry.height() * geom.height()));
|
||||
+ return absoluteGeometry().translated(-geom.topLeft());
|
||||
}
|
||||
|
||||
QRectF Tile::windowGeometry() const
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,35 @@ |
||||
From 2b19ce4d9b8a24edd60271e61a6972b08cf28364 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Tue, 20 Jun 2023 18:11:43 -0400
|
||||
Subject: [PATCH 09/20] Make vertical gap twice as big between windows
|
||||
|
||||
---
|
||||
src/tiles/tile.cpp | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tiles/tile.cpp b/src/tiles/tile.cpp
|
||||
index 3c3ba61632..2a3f22a4b4 100644
|
||||
--- a/src/tiles/tile.cpp
|
||||
+++ b/src/tiles/tile.cpp
|
||||
@@ -178,7 +178,17 @@ QRectF Tile::windowGeometry() const
|
||||
effectiveMargins.setBottom(m_relativeGeometry.bottom() < 1.0 ? m_padding / 2.0 : m_padding);
|
||||
|
||||
const auto geom = absoluteGeometry();
|
||||
- return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), m_desktop)) - effectiveMargins;
|
||||
+ // This below is the original return value. Find out if this is actually ok
|
||||
+ // return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), m_desktop)) - effectiveMargins;
|
||||
+
|
||||
+ auto margins = QMarginsF(m_padding, m_padding, m_padding, m_padding);
|
||||
+ if (quickTileMode() & QuickTileFlag::Top) {
|
||||
+ margins += QMarginsF(0,0,0,m_padding);
|
||||
+ } else if (quickTileMode() & QuickTileFlag::Bottom) {
|
||||
+ margins += QMarginsF(0,m_padding,0,0);
|
||||
+ }
|
||||
+ return geom.intersected(workspace()->clientArea(MaximizeArea, m_tiling->output(), m_desktop)) - margins;
|
||||
+
|
||||
}
|
||||
|
||||
QRectF Tile::maximizedWindowGeometry() const
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,200 @@ |
||||
From a782b7db8d28bf67650458356507a09698c0098f Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Mon, 21 Nov 2022 15:31:57 -0500
|
||||
Subject: [PATCH 10/20] Implement core panning methods
|
||||
|
||||
Introduce methods used to pan windows horizontally by a certain pixel
|
||||
amount. Panning applies to all windows which belong to a specified
|
||||
screen:
|
||||
|
||||
- the main method is ~panWindows~, which iterates on all windows and
|
||||
pans those that belong to the specified screen of the required amount.
|
||||
|
||||
- there are 4 slots used to pan all windows on the current screen by
|
||||
1/2 and 1/3 of its size left or right. These slots are accessible via
|
||||
user actions
|
||||
|
||||
- Finally, there is a method to ensure a given window is visible (this
|
||||
slot is called upon client activation)
|
||||
|
||||
Fix compilation
|
||||
|
||||
screen() has been removed and replaced by some method that returns a pointer to a KWin::output; this may lead to some trouble
|
||||
|
||||
Prevent focused panel to move everything
|
||||
|
||||
[hyper-wide] Ensure selected window is visible
|
||||
|
||||
this is weird; it should not be necessary
|
||||
|
||||
stash with definition of panWindows
|
||||
|
||||
[hyper-wide] Fix pan windows with fractional scaling
|
||||
|
||||
Fix ensureVisible
|
||||
---
|
||||
src/effect/effecthandler.cpp | 1 +
|
||||
src/placement.cpp | 75 ++++++++++++++++++++++++++++++++++++
|
||||
src/useractions.cpp | 8 ++++
|
||||
src/workspace.cpp | 1 +
|
||||
src/workspace.h | 7 ++++
|
||||
5 files changed, 92 insertions(+)
|
||||
|
||||
diff --git a/src/effect/effecthandler.cpp b/src/effect/effecthandler.cpp
|
||||
index 84c45f62cf..2492f7ba22 100644
|
||||
--- a/src/effect/effecthandler.cpp
|
||||
+++ b/src/effect/effecthandler.cpp
|
||||
@@ -779,6 +779,7 @@ void EffectsHandler::activateWindow(EffectWindow *effectWindow)
|
||||
auto window = effectWindow->window();
|
||||
if (window->isClient()) {
|
||||
Workspace::self()->activateWindow(window, true);
|
||||
+ Workspace::self()->slotEnsureClientVisible(window);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/placement.cpp b/src/placement.cpp
|
||||
index 6c984282e5..7e68c8e108 100644
|
||||
--- a/src/placement.cpp
|
||||
+++ b/src/placement.cpp
|
||||
@@ -13,7 +13,9 @@
|
||||
#include "placement.h"
|
||||
#include "cursor.h"
|
||||
#include "options.h"
|
||||
+#include "core/outputbackend.h"
|
||||
#include "rules.h"
|
||||
+#include "core/output.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
@@ -741,6 +743,79 @@ void Window::shrinkVertical()
|
||||
}
|
||||
}
|
||||
|
||||
+void Workspace::panWindows(KWin::Output *output, qreal pixels, bool shiftActive)
|
||||
+{ // In case we have problems, here we moved from using indices for
|
||||
+ // screens to using pointers; this may lead to trouble in testing.
|
||||
+
|
||||
+ // shiftActive is UNUSED
|
||||
+ const auto &clients = Workspace::self()->windows();
|
||||
+ for (int i = clients.size() - 1; i >= 0; i--) {
|
||||
+ Window *client = clients.at(i);
|
||||
+ if ((!client->isOnCurrentDesktop()) || (client->isMinimized()) || (client->isOnAllDesktops()) || (!client->isMovable()) || (client->output() != output))
|
||||
+ continue;
|
||||
+ // refactor usind client->isOnOutput
|
||||
+ client->moveRelative(QPointF(pixels, 0 ));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+ // TODO:
|
||||
+ // find current screen with screens()->current()
|
||||
+ // move only clients on current screen
|
||||
+ // refactor this in a generic method and make the slots call it;
|
||||
+ // genericmethod should look like
|
||||
+ //
|
||||
+ // slotPanWindows( int screen, int pixels, bool shiftActive)
|
||||
+
|
||||
+ // The shift amount is given by the size of the window + 2*gapSize
|
||||
+ // The size of the window + 2*gapsize should be the (width of the screen - 2*screenBorder - 2*gapSize)/2
|
||||
+
|
||||
+void Workspace::slotPanWindowsHalfScreenRight()
|
||||
+{
|
||||
+ auto currentOutput = workspace()->activeOutput();
|
||||
+ qreal width = currentOutput->geometryF().width();
|
||||
+ qreal halfWidth = (width - 2. * currentOutput->defaultPadding() - 2. * currentOutput->defaultBorder()) / 2.;
|
||||
+ panWindows(currentOutput, halfWidth, false);
|
||||
+}
|
||||
+
|
||||
+void Workspace::slotPanWindowsHalfScreenLeft()
|
||||
+{
|
||||
+ auto currentOutput = workspace()->activeOutput();
|
||||
+ qreal width = currentOutput->geometryF().width();
|
||||
+ qreal halfWidth = (width - 2. * currentOutput->defaultPadding() - 2. * currentOutput->defaultBorder()) / 2.;
|
||||
+ panWindows(currentOutput, -halfWidth, false);
|
||||
+}
|
||||
+
|
||||
+void Workspace::slotPanWindowsThirdScreenRight()
|
||||
+{
|
||||
+ auto currentOutput = workspace()->activeOutput();
|
||||
+ qreal width = currentOutput->geometryF().width();
|
||||
+ qreal thirdWidth = (width - 2. * currentOutput->defaultPadding() - 2. * currentOutput->defaultBorder()) / 3.;
|
||||
+ panWindows(currentOutput, thirdWidth, false);
|
||||
+}
|
||||
+
|
||||
+void Workspace::slotPanWindowsThirdScreenLeft()
|
||||
+{
|
||||
+ auto currentOutput = workspace()->activeOutput();
|
||||
+ qreal width = currentOutput->geometryF().width();
|
||||
+ qreal thirdWidth = (width - 2. * currentOutput->defaultPadding() - 2. * currentOutput->defaultBorder()) / 3.;
|
||||
+ panWindows(currentOutput, -thirdWidth, false);
|
||||
+}
|
||||
+
|
||||
+void Workspace::slotEnsureClientVisible( KWin::Window* activatedClient )
|
||||
+{
|
||||
+ // This also should be made screen-aware
|
||||
+ if ((!activatedClient) || activatedClient->isDesktop() || activatedClient->isDock())
|
||||
+ return;
|
||||
+ auto activatedOutput = activatedClient->output();
|
||||
+ QRectF screenGeo = activatedClient->output()->geometryF();
|
||||
+ QRectF clientGeo = activatedClient->frameGeometry();
|
||||
+ // activateScreen does not seem to be extremely reliable… Perhaps windows that exist before kwin is started are
|
||||
+ if (clientGeo.left() < screenGeo.left() + activatedOutput->defaultBorder() + activatedOutput->defaultPadding() * 2.)
|
||||
+ panWindows(activatedOutput, screenGeo.left() - clientGeo.left() + activatedOutput->defaultPadding() * 2. + activatedOutput->defaultBorder(), false);
|
||||
+ else if (clientGeo.right() > screenGeo.right() - activatedOutput->defaultBorder() - activatedOutput->defaultPadding() * 2.)
|
||||
+ panWindows(activatedOutput, screenGeo.right() - clientGeo.right() - activatedOutput->defaultPadding() * 2. - activatedOutput->defaultBorder(), false);
|
||||
+}
|
||||
+
|
||||
void Workspace::quickTileWindow(QuickTileMode mode)
|
||||
{
|
||||
if (!m_activeWindow) {
|
||||
diff --git a/src/useractions.cpp b/src/useractions.cpp
|
||||
index 6e841d96cd..f60ec14a0d 100644
|
||||
--- a/src/useractions.cpp
|
||||
+++ b/src/useractions.cpp
|
||||
@@ -952,6 +952,14 @@ void Workspace::initShortcuts()
|
||||
0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third2));
|
||||
initShortcut("Window Quick Tile Right Third", i18n("Quick Tile Window to the Right Third"),
|
||||
0, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Third3));
|
||||
+ initShortcut("Pan Windows Right Half", i18n("Pan Windows to the right by half the screen"),
|
||||
+ 0, &Workspace::slotPanWindowsHalfScreenRight);
|
||||
+ initShortcut("Pan Windows Left Half", i18n("Pan Windows to the left by half the screen"),
|
||||
+ 0, &Workspace::slotPanWindowsHalfScreenLeft);
|
||||
+ initShortcut("Pan Windows Right Third", i18n("Pan Windows to the right by third the screen"),
|
||||
+ 0, &Workspace::slotPanWindowsThirdScreenRight);
|
||||
+ initShortcut("Pan Windows Left Third", i18n("Pan Windows to the left by third the screen"),
|
||||
+ 0, &Workspace::slotPanWindowsThirdScreenLeft);
|
||||
initShortcut("Window Quick Tile Top", i18n("Quick Tile Window to the Top"),
|
||||
Qt::META | Qt::Key_Up, std::bind(&Workspace::quickTileWindow, this, QuickTileFlag::Top));
|
||||
initShortcut("Window Quick Tile Bottom", i18n("Quick Tile Window to the Bottom"),
|
||||
diff --git a/src/workspace.cpp b/src/workspace.cpp
|
||||
index bd64f4f248..6f0d1ff3e8 100644
|
||||
--- a/src/workspace.cpp
|
||||
+++ b/src/workspace.cpp
|
||||
@@ -177,6 +177,7 @@ void Workspace::init()
|
||||
connect(options, &Options::configChanged, m_screenEdges.get(), &ScreenEdges::reconfigure);
|
||||
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::layoutChanged, m_screenEdges.get(), &ScreenEdges::updateLayout);
|
||||
connect(this, &Workspace::windowActivated, m_screenEdges.get(), &ScreenEdges::checkBlocking);
|
||||
+ connect(this, &Workspace::windowActivated, this, &Workspace::slotEnsureClientVisible);
|
||||
|
||||
connect(this, &Workspace::windowRemoved, m_focusChain.get(), &FocusChain::remove);
|
||||
connect(this, &Workspace::windowActivated, m_focusChain.get(), &FocusChain::setActiveWindow);
|
||||
diff --git a/src/workspace.h b/src/workspace.h
|
||||
index 04fe2e0864..2f41dc8302 100644
|
||||
--- a/src/workspace.h
|
||||
+++ b/src/workspace.h
|
||||
@@ -522,6 +522,13 @@ public Q_SLOTS:
|
||||
void slotWindowShrinkHorizontal();
|
||||
void slotWindowShrinkVertical();
|
||||
|
||||
+ void panWindows(KWin::Output *output, qreal pixels, bool shiftActive);
|
||||
+ void slotPanWindowsHalfScreenRight();
|
||||
+ void slotPanWindowsHalfScreenLeft();
|
||||
+ void slotPanWindowsThirdScreenRight();
|
||||
+ void slotPanWindowsThirdScreenLeft();
|
||||
+ void slotEnsureClientVisible( KWin::Window* );
|
||||
+
|
||||
void slotIncreaseWindowOpacity();
|
||||
void slotLowerWindowOpacity();
|
||||
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,68 @@ |
||||
From 243bf425dab979a150e2b18458b2643b4de58178 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Thu, 5 Jun 2025 22:23:24 -0400
|
||||
Subject: [PATCH 11/20] Remove the logic for tiles on different screens
|
||||
|
||||
---
|
||||
src/window.cpp | 38 +-------------------------------------
|
||||
1 file changed, 1 insertion(+), 37 deletions(-)
|
||||
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index 4eca4627dd..5ceea0c812 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -3727,7 +3727,7 @@ void Window::handleQuickTileShortcut(QuickTileMode mode)
|
||||
} else {
|
||||
// If the window is asked to be tiled in a screen corner, don't combine the new mode with the old one.
|
||||
QuickTileMode combined;
|
||||
- switch (mode) {
|
||||
+ switch (mode) { // We should add the thirds here I suppose
|
||||
case QuickTileMode(QuickTileFlag::Left):
|
||||
case QuickTileMode(QuickTileFlag::Top):
|
||||
case QuickTileMode(QuickTileFlag::Right):
|
||||
@@ -3737,42 +3737,6 @@ void Window::handleQuickTileShortcut(QuickTileMode mode)
|
||||
default:
|
||||
combined = mode;
|
||||
}
|
||||
-
|
||||
- // If trying to tile to the side that the window is already tiled to move the window to the next
|
||||
- // screen near the tile if it exists and swap the tile side, otherwise toggle the mode (set QuickTileFlag::None)
|
||||
- if (combined == oldMode) {
|
||||
- Output *currentOutput = moveResizeOutput();
|
||||
- Output *nextOutput = currentOutput;
|
||||
- Output *candidateOutput = currentOutput;
|
||||
- if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Left)) {
|
||||
- candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionWest);
|
||||
- } else if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Right)) {
|
||||
- candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionEast);
|
||||
- }
|
||||
- bool shiftHorizontal = candidateOutput != nextOutput;
|
||||
- nextOutput = candidateOutput;
|
||||
- if ((mode & QuickTileFlag::Vertical) == QuickTileMode(QuickTileFlag::Top)) {
|
||||
- candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionNorth);
|
||||
- } else if ((mode & QuickTileFlag::Vertical) == QuickTileMode(QuickTileFlag::Bottom)) {
|
||||
- candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionSouth);
|
||||
- }
|
||||
- bool shiftVertical = candidateOutput != nextOutput;
|
||||
- nextOutput = candidateOutput;
|
||||
-
|
||||
- if (nextOutput != currentOutput) {
|
||||
- // Move to other screen
|
||||
- tileAtPoint = nextOutput->geometry().center();
|
||||
-
|
||||
- // Swap sides
|
||||
- if (shiftHorizontal) {
|
||||
- combined = (~combined & QuickTileFlag::Horizontal) | (combined & QuickTileFlag::Vertical);
|
||||
- }
|
||||
- if (shiftVertical) {
|
||||
- combined = (~combined & QuickTileFlag::Vertical) | (combined & QuickTileFlag::Horizontal);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
mode = combined;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,290 @@ |
||||
From 0511ab9f21bc31b64a917030fef6c46f5060b971 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <jacopods@gmail.com>
|
||||
Date: Sun, 28 Oct 2018 02:26:37 -0400
|
||||
Subject: [PATCH 12/20] Implement Incremental wide-placement
|
||||
|
||||
[hyper-wide] Fix placement with fractional scaling
|
||||
|
||||
[squashme] Fix compilation
|
||||
---
|
||||
src/placement.cpp | 149 ++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 112 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/src/placement.cpp b/src/placement.cpp
|
||||
index 7e68c8e108..cd480901b5 100644
|
||||
--- a/src/placement.cpp
|
||||
+++ b/src/placement.cpp
|
||||
@@ -162,13 +162,24 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
* with ideas from xfce.
|
||||
*/
|
||||
|
||||
+ // this is messed up when we introduce floats, and I still want
|
||||
+ // pixel perfect placement. Thus, we scale back to ints using the
|
||||
+ // output scale
|
||||
+
|
||||
const QSizeF size = window->size();
|
||||
if (size.isEmpty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
+ auto windowOutput = window->output();
|
||||
+
|
||||
+ const qreal scale = windowOutput->scale();
|
||||
+ int gapSize = std::round(windowOutput->defaultPadding() * scale);
|
||||
+ int screenBorder = std::round(windowOutput->defaultBorder() * scale);
|
||||
+
|
||||
const int none = 0, h_wrong = -1, w_wrong = -2; // overlap types
|
||||
long int overlap, min_overlap = 0;
|
||||
+ int panning, min_panning = 0;
|
||||
int x_optimal, y_optimal;
|
||||
int possible;
|
||||
VirtualDesktop *const desktop = window->isOnCurrentDesktop() ? VirtualDesktopManager::self()->currentDesktop() : window->desktops().front();
|
||||
@@ -178,46 +189,70 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
int basket; // temp holder
|
||||
|
||||
// get the maximum allowed windows space
|
||||
- int x = area.left();
|
||||
- int y = area.top();
|
||||
+
|
||||
+ QRectF preMaxRect = area;
|
||||
+ preMaxRect.setWidth(preMaxRect.width() * 10);
|
||||
+
|
||||
+ const QRectF maxRect = preMaxRect;
|
||||
+ int mrh = maxRect.height() * scale;
|
||||
+
|
||||
+ // Our first guess is the topleft corner
|
||||
+ int x = std::round(maxRect.left() * scale) + gapSize;
|
||||
+ int y = std::round(maxRect.top() * scale) + gapSize;
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
|
||||
// client gabarit
|
||||
- int ch = std::ceil(size.height());
|
||||
- int cw = std::ceil(size.width());
|
||||
+ int ch = std::round(size.height() * scale);
|
||||
+ int cw = std::round(size.width() * scale);
|
||||
|
||||
// Explicitly converts those to int to avoid accidentally
|
||||
// mixing ints and qreal in the calculations below.
|
||||
- int area_xr = std::floor(area.x() + area.width());
|
||||
- int area_yb = std::floor(area.y() + area.height());
|
||||
+ int area_xr = std::round((area.x() + area.width()) * scale);
|
||||
+ int area_yb = std::round((area.y() + area.height()) * scale);
|
||||
+ int maxRect_xr = std::round((maxRect.x() + maxRect.width()) * scale);
|
||||
+ int maxRect_yb = std::round((maxRect.y() + maxRect.height()) * scale);
|
||||
|
||||
+ // This is needed so that we can set the optimal value the first time
|
||||
+ // Could we not set overlap to ∞?
|
||||
bool first_pass = true; // CT lame flag. Don't like it. What else would do?
|
||||
|
||||
// loop over possible positions
|
||||
do {
|
||||
// test if enough room in x and y directions
|
||||
- if (y + ch > area_yb && ch < area.height()) {
|
||||
+ // h_wrong (height wrong) means that the client would overflow
|
||||
+ // from the bottom of the availabe area
|
||||
+ //
|
||||
+ // w_wrong (width wrong) means that the client would overflow
|
||||
+ // from the right of the available area
|
||||
+ if (y + ch > maxRect_yb && ch < mrh) {
|
||||
overlap = h_wrong; // this throws the algorithm to an exit
|
||||
- } else if (x + cw > area_xr) {
|
||||
+ // since we exhausted all possible
|
||||
+ // positions
|
||||
+ } else if (x + cw > maxRect_xr) {
|
||||
overlap = w_wrong;
|
||||
} else {
|
||||
+ // we start computing the overlap with all other windows
|
||||
+ // present on the same desktop.
|
||||
overlap = none; // initialize
|
||||
+ panning = qMax(0, x + cw - area_xr);
|
||||
|
||||
cxl = x;
|
||||
cxr = x + cw;
|
||||
cyt = y;
|
||||
cyb = y + ch;
|
||||
+ // These above are left top right and bottom
|
||||
for (auto l = workspace()->stackingOrder().constBegin(); l != workspace()->stackingOrder().constEnd(); ++l) {
|
||||
auto client = *l;
|
||||
- if (isIrrelevant(client, window, desktop)) {
|
||||
+ if (isIrrelevant(client, window, desktop)
|
||||
+ || client->isDock()) {
|
||||
continue;
|
||||
}
|
||||
- xl = client->x();
|
||||
- yt = client->y();
|
||||
- xr = xl + client->width();
|
||||
- yb = yt + client->height();
|
||||
-
|
||||
+ xl = std::round(client->x() * scale);
|
||||
+ yt = std::round(client->y() * scale);
|
||||
+ xr = std::round((client->x() + client->width()) * scale);
|
||||
+ yb = std::round((client->y() + client->height()) * scale);
|
||||
+ // FIXME: should account for gaps!
|
||||
// if windows overlap, calc the overall overlapping
|
||||
if ((cxl < xr) && (cxr > xl) && (cyt < yb) && (cyb > yt)) {
|
||||
xl = std::max(cxl, xl);
|
||||
@@ -234,9 +269,13 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // JDS: up to here we computed overlap as the sum of the area
|
||||
+ // overlapping with each window already present on the desktop
|
||||
+ // area
|
||||
|
||||
- // CT first time we get no overlap we stop.
|
||||
- if (overlap == none) {
|
||||
+ if ((overlap == none) && (panning == 0)) {
|
||||
+ // Bingo: the spot is free and we do not need to pan; set
|
||||
+ // optimal positions and break from the cycle
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
break;
|
||||
@@ -245,22 +284,40 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
if (first_pass) {
|
||||
first_pass = false;
|
||||
min_overlap = overlap;
|
||||
+ min_panning = maxRect_xr;
|
||||
+ // Why is it not setting x_optimal, y_optimal?
|
||||
}
|
||||
// CT save the best position and the minimum overlap up to now
|
||||
- else if (overlap >= none && overlap < min_overlap) {
|
||||
+ else if ((overlap >= none) && ((overlap < min_overlap) || ((overlap == min_overlap) && (panning < min_panning)))) {
|
||||
min_overlap = overlap;
|
||||
+ min_panning = panning;
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
}
|
||||
|
||||
+ if ((overlap == none) && (panning > 0)) {
|
||||
+ overlap = w_wrong;
|
||||
+ }
|
||||
+
|
||||
+ // JDS now we need to decide whether it makes sense to loop
|
||||
+
|
||||
// really need to loop? test if there's any overlap
|
||||
if (overlap > none) {
|
||||
+ // we are here if overlap is not w_wrong nor h_wrong this
|
||||
+ // means that the client still fits inside the area, but
|
||||
+ // overlaps with some of the other clients. We try to move
|
||||
+ // it around.
|
||||
+
|
||||
+ // Start from the right.
|
||||
+ possible = maxRect_xr;
|
||||
|
||||
- possible = area_xr;
|
||||
if (possible - cw > x) {
|
||||
possible -= cw;
|
||||
}
|
||||
|
||||
+ // JDS now ~possible~ is the last possible x before I get
|
||||
+ // out of the desktop
|
||||
+
|
||||
// compare to the position of each client on the same desk
|
||||
for (auto l = workspace()->stackingOrder().constBegin(); l != workspace()->stackingOrder().constEnd(); ++l) {
|
||||
auto client = *l;
|
||||
@@ -268,32 +325,44 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
continue;
|
||||
}
|
||||
|
||||
- xl = client->x();
|
||||
- yt = client->y();
|
||||
- xr = xl + client->width();
|
||||
- yb = yt + client->height();
|
||||
+ xl = std::round(client->x() * scale);
|
||||
+ yt = std::round(client->y() * scale);
|
||||
+ xr = std::round((client->x() + client->width()) * scale + 2 * gapSize);
|
||||
+ yb = std::round((client->y() + client->height()) * scale);
|
||||
|
||||
// if not enough room above or under the current tested client
|
||||
// determine the first non-overlapped x position
|
||||
- if ((y < yb) && (yt < ch + y)) {
|
||||
+ if ((y < yb) && (y + ch > yt)) {
|
||||
+ // The tested client could be the one getting in
|
||||
+ // our way earlier on
|
||||
|
||||
+ // If this clause succeeds, the tested client was
|
||||
+ // in our way before; if possible, Try and place
|
||||
+ // it either to the right or to the left of it
|
||||
if ((xr > x) && (possible > xr)) {
|
||||
possible = xr;
|
||||
}
|
||||
|
||||
- basket = xl - cw;
|
||||
+ basket = xl - cw - 2*gapSize;
|
||||
if ((basket > x) && (possible > basket)) {
|
||||
possible = basket;
|
||||
}
|
||||
- }
|
||||
+ } // else our client sits completely above or below
|
||||
+ // the tested client and the tested client can be
|
||||
+ // safely ignored. Of course if we got here it means
|
||||
+ // that some overlap existed, so at least one client
|
||||
+ // would test positive to the above if clause
|
||||
}
|
||||
x = possible;
|
||||
}
|
||||
-
|
||||
// ... else ==> not enough x dimension (overlap was wrong on horizontal)
|
||||
else if (overlap == w_wrong) {
|
||||
- x = area.left();
|
||||
- possible = area_yb;
|
||||
+ // if we overflow to the right, reset x to the left side
|
||||
+ // and set possible to be either the bottom of the area or
|
||||
+ // just as low so that the window would touch the bottom
|
||||
+ // of the screen with the bottom side
|
||||
+ x = maxRect.left() * scale;
|
||||
+ possible = maxRect_yb;
|
||||
|
||||
if (possible - ch > y) {
|
||||
possible -= ch;
|
||||
@@ -306,10 +375,10 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
continue;
|
||||
}
|
||||
|
||||
- xl = client->x();
|
||||
- yt = client->y();
|
||||
- xr = xl + client->width();
|
||||
- yb = yt + client->height();
|
||||
+ xl = std::round(client->x() * scale);
|
||||
+ yt = std::round(client->y() * scale);
|
||||
+ xr = std::round((client->x() + client->width()) * scale);
|
||||
+ yb = std::round((client->y() + client->height()) * scale + 4 * gapSize); // this (incorrectly) assumes that the mid vertical gap is twice the gapsize
|
||||
|
||||
// if not enough room to the left or right of the current tested client
|
||||
// determine the first non-overlapped y position
|
||||
@@ -317,20 +386,26 @@ std::optional<PlacementCommand> Placement::placeSmart(const Window *window, cons
|
||||
possible = yb;
|
||||
}
|
||||
|
||||
- basket = yt - ch;
|
||||
+ basket = yt - ch - 4 * gapSize;
|
||||
if ((basket > y) && (possible > basket)) {
|
||||
possible = basket;
|
||||
}
|
||||
}
|
||||
+ if (y == possible) {
|
||||
+ // we exhausted the possible positions
|
||||
+ break;
|
||||
+ }
|
||||
y = possible;
|
||||
}
|
||||
- } while ((overlap != none) && (overlap != h_wrong) && (y < area_yb));
|
||||
+ } while (((overlap != none) || (panning > 0)) && (overlap != h_wrong) && (y < maxRect_yb));
|
||||
|
||||
- if (ch >= area.height()) {
|
||||
- y_optimal = area.top();
|
||||
+ if (ch >= mrh) {
|
||||
+ y_optimal = maxRect.top() * scale;
|
||||
}
|
||||
|
||||
- return QPointF(x_optimal, y_optimal);
|
||||
+ // place the window
|
||||
+
|
||||
+ return QPointF(x_optimal / scale, y_optimal / scale);
|
||||
}
|
||||
|
||||
QPoint Workspace::cascadeOffset(const QRectF &area) const
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,44 @@ |
||||
From 326da58552445f2b267b2a748806dd97e9c6a6aa Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <jacopods@gmail.com>
|
||||
Date: Fri, 5 Apr 2019 22:23:10 -0400
|
||||
Subject: [PATCH 13/20] Remove wrap-around when switching focus horizontally
|
||||
|
||||
Now, this is not a necessity, but more often than not I do not want to
|
||||
wrap around, especially if the desktop is stretched very wide
|
||||
---
|
||||
src/useractions.cpp | 19 +------------------
|
||||
1 file changed, 1 insertion(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/useractions.cpp b/src/useractions.cpp
|
||||
index f60ec14a0d..e92eb95292 100644
|
||||
--- a/src/useractions.cpp
|
||||
+++ b/src/useractions.cpp
|
||||
@@ -1610,24 +1610,7 @@ void Workspace::switchWindow(Direction direction)
|
||||
// Center of the active window
|
||||
QPoint curPos(window->x() + window->width() / 2, window->y() + window->height() / 2);
|
||||
|
||||
- if (!switchWindow(window, direction, curPos, desktop)) {
|
||||
- auto opposite = [&] {
|
||||
- switch (direction) {
|
||||
- case DirectionNorth:
|
||||
- return QPoint(curPos.x(), geometry().height());
|
||||
- case DirectionSouth:
|
||||
- return QPoint(curPos.x(), 0);
|
||||
- case DirectionEast:
|
||||
- return QPoint(0, curPos.y());
|
||||
- case DirectionWest:
|
||||
- return QPoint(geometry().width(), curPos.y());
|
||||
- default:
|
||||
- Q_UNREACHABLE();
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- switchWindow(window, direction, opposite(), desktop);
|
||||
- }
|
||||
+ switchWindow(window, direction, curPos, desktop);
|
||||
}
|
||||
|
||||
bool Workspace::switchWindow(Window *window, Direction direction, QPoint curPos, VirtualDesktop *desktop)
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,28 @@ |
||||
From adccb3d9f6613d12b723ff5bd39cb0fdbbba65b5 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <jacopods@gmail.com>
|
||||
Date: Fri, 24 May 2019 09:33:47 +0200
|
||||
Subject: [PATCH 14/20] Allow windows outside left|right screen boundary
|
||||
|
||||
---
|
||||
src/window.cpp | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index 5ceea0c812..afde7610e6 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -4232,11 +4232,6 @@ void Window::checkWorkspacePosition(QRectF oldGeometry, const VirtualDesktop *ol
|
||||
|
||||
void Window::checkOffscreenPosition(QRectF *geom, const QRectF &screenArea)
|
||||
{
|
||||
- if (geom->left() > screenArea.right()) {
|
||||
- geom->moveLeft(screenArea.right() - screenArea.width() / 4);
|
||||
- } else if (geom->right() < screenArea.left()) {
|
||||
- geom->moveRight(screenArea.left() + screenArea.width() / 4);
|
||||
- }
|
||||
if (geom->top() > screenArea.bottom()) {
|
||||
geom->moveTop(screenArea.bottom() - screenArea.height() / 4);
|
||||
} else if (geom->bottom() < screenArea.top()) {
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,42 @@ |
||||
From d1afa2a57ba8d647559bf44b5cba8b3806b1c5cc Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Sun, 30 Apr 2023 23:09:34 -0400
|
||||
Subject: [PATCH 15/20] Adjust output detection for hyper-wide
|
||||
|
||||
---
|
||||
src/window.cpp | 3 ++-
|
||||
src/workspace.cpp | 4 +++-
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index afde7610e6..6442eb44b1 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -246,7 +246,8 @@ bool Window::isOnActiveOutput() const
|
||||
|
||||
bool Window::isOnOutput(Output *output) const
|
||||
{
|
||||
- return output->geometry().intersects(frameGeometry().toRect());
|
||||
+ return (output->geometry().bottom() >= frameGeometry().top() &&
|
||||
+ output->geometry().top() <= frameGeometry().top());
|
||||
}
|
||||
|
||||
Shadow *Window::shadow() const
|
||||
diff --git a/src/workspace.cpp b/src/workspace.cpp
|
||||
index 6f0d1ff3e8..b58d5b151f 100644
|
||||
--- a/src/workspace.cpp
|
||||
+++ b/src/workspace.cpp
|
||||
@@ -1045,7 +1045,9 @@ Output *Workspace::outputAt(const QPointF &pos) const
|
||||
|
||||
for (Output *output : std::as_const(m_outputs)) {
|
||||
const QRectF geo = output->geometry();
|
||||
-
|
||||
+ if ((geo.bottom() >= pos.y()) && (geo.top() <= pos.y())) {
|
||||
+ return output;
|
||||
+ }
|
||||
const QPointF closestPoint(std::clamp(pos.x(), geo.x(), geo.x() + geo.width() - 1),
|
||||
std::clamp(pos.y(), geo.y(), geo.y() + geo.height() - 1));
|
||||
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,196 @@ |
||||
From ca4cd3cc88680e912752d05ad9863ecbeaf1bf85 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <jacopods@protonmail.com>
|
||||
Date: Thu, 17 Jun 2021 23:00:47 -0400
|
||||
Subject: [PATCH 16/20] Introduce the Pan helper effect
|
||||
|
||||
Fix installation of panhelper effect
|
||||
|
||||
Fix panhelper effect
|
||||
---
|
||||
src/plugins/CMakeLists.txt | 1 +
|
||||
src/plugins/panhelper/CMakeLists.txt | 1 +
|
||||
.../panhelper/package/contents/code/main.js | 122 ++++++++++++++++++
|
||||
src/plugins/panhelper/package/metadata.json | 22 ++++
|
||||
4 files changed, 146 insertions(+)
|
||||
create mode 100644 src/plugins/panhelper/CMakeLists.txt
|
||||
create mode 100644 src/plugins/panhelper/package/contents/code/main.js
|
||||
create mode 100644 src/plugins/panhelper/package/metadata.json
|
||||
|
||||
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
|
||||
index 794522aee2..173705f3f7 100644
|
||||
--- a/src/plugins/CMakeLists.txt
|
||||
+++ b/src/plugins/CMakeLists.txt
|
||||
@@ -84,6 +84,7 @@ add_subdirectory(mousemark)
|
||||
add_subdirectory(nightlight)
|
||||
add_subdirectory(outputlocator)
|
||||
add_subdirectory(overview)
|
||||
+add_subdirectory(panhelper)
|
||||
add_subdirectory(qpa)
|
||||
add_subdirectory(scale)
|
||||
add_subdirectory(screenedge)
|
||||
diff --git a/src/plugins/panhelper/CMakeLists.txt b/src/plugins/panhelper/CMakeLists.txt
|
||||
new file mode 100644
|
||||
index 0000000000..5095de2e67
|
||||
--- /dev/null
|
||||
+++ b/src/plugins/panhelper/CMakeLists.txt
|
||||
@@ -0,0 +1 @@
|
||||
+kwin_add_scripted_effect(panhelper package)
|
||||
diff --git a/src/plugins/panhelper/package/contents/code/main.js b/src/plugins/panhelper/package/contents/code/main.js
|
||||
new file mode 100644
|
||||
index 0000000000..0ca5576c5f
|
||||
--- /dev/null
|
||||
+++ b/src/plugins/panhelper/package/contents/code/main.js
|
||||
@@ -0,0 +1,122 @@
|
||||
+/********************************************************************
|
||||
+ This file is part of the KDE project.
|
||||
+
|
||||
+ Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
+ Copyright (C) 2016 Marco Martin <mart@kde.org>
|
||||
+
|
||||
+This program is free software; you can redistribute it and/or modify
|
||||
+it under the terms of the GNU General Public License as published by
|
||||
+the Free Software Foundation; either version 2 of the License, or
|
||||
+(at your option) any later version.
|
||||
+
|
||||
+This program is distributed in the hope that it will be useful,
|
||||
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+GNU General Public License for more details.
|
||||
+
|
||||
+You should have received a copy of the GNU General Public License
|
||||
+along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+*********************************************************************/
|
||||
+/*global effect, effects, animate, animationTime, Effect*/
|
||||
+class panHelperEffect {
|
||||
+ constructor() {
|
||||
+ effect.configChanged.connect(this.loadConfig.bind(this));
|
||||
+
|
||||
+ effects.windowAdded.connect(this.manage.bind(this));
|
||||
+ for (const window of effects.stackingOrder) {
|
||||
+ this.manage(window);
|
||||
+ }
|
||||
+
|
||||
+ this.loadConfig();
|
||||
+ }
|
||||
+
|
||||
+ loadConfig() {
|
||||
+ "use strict";
|
||||
+ this.duration = animationTime(250);
|
||||
+ }
|
||||
+
|
||||
+ manage(window) {
|
||||
+ window.windowFrameGeometryChanged.connect(this.geometryChange.bind(this));
|
||||
+ }
|
||||
+
|
||||
+ geometryChange(window, oldGeometry) {
|
||||
+ "use strict";
|
||||
+
|
||||
+ var newGeometry = window.geometry;
|
||||
+
|
||||
+ // act only on windows whose width does not change substantially (allow some room for rounding errors)
|
||||
+ if ((Math.abs(newGeometry.width - oldGeometry.width) >4) ||
|
||||
+ (Math.abs(newGeometry.height - oldGeometry.height) >1)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ //only do the transition for far enough windows that are moved horizontally
|
||||
+ var disty = Math.abs(oldGeometry.y - newGeometry.y);
|
||||
+ var distx = Math.abs(oldGeometry.x - newGeometry.x);
|
||||
+ if (!((disty == 0) ^ (distx == 0))) {
|
||||
+ // ignore
|
||||
+ return
|
||||
+ }
|
||||
+ if (((distx != 0 ) && (distx < newGeometry.width / 6)) ||
|
||||
+ ((disty != 0 ) && (disty < newGeometry.height / 6))) {
|
||||
+ if (window.moveAnimation) {
|
||||
+ delete window.moveAnimation;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ var couldRetarget = false;
|
||||
+
|
||||
+ if (window.moveAnimation) {
|
||||
+ if (window.moveAnimation[0]) {
|
||||
+ couldRetarget = retarget(window.moveAnimation[0], {
|
||||
+ value1: newGeometry.width,
|
||||
+ value2: newGeometry.height
|
||||
+ }, this.duration);
|
||||
+ }
|
||||
+ if (couldRetarget && window.moveAnimation[1]) {
|
||||
+ couldRetarget = retarget(window.moveAnimation[1], {
|
||||
+ value1: newGeometry.x + newGeometry.width / 2,
|
||||
+ value2: newGeometry.y + newGeometry.height / 2
|
||||
+ }, this.duration);
|
||||
+ }
|
||||
+ if (!couldRetarget) {
|
||||
+ cancel(window.moveAnimation[0]);
|
||||
+ cancel(window.moveAnimation[1]);
|
||||
+ delete window.moveAnimation;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!couldRetarget) {
|
||||
+ window.moveAnimation = animate({
|
||||
+ window: window,
|
||||
+ duration: this.duration,
|
||||
+ animations: [{
|
||||
+ type: Effect.Size,
|
||||
+ curve: QEasingCurve.OutCubic,
|
||||
+ to: {
|
||||
+ value1: newGeometry.width,
|
||||
+ value2: newGeometry.height
|
||||
+ },
|
||||
+ from: {
|
||||
+ value1: oldGeometry.width,
|
||||
+ value2: oldGeometry.height
|
||||
+ }
|
||||
+ }, {
|
||||
+ type: Effect.Position,
|
||||
+ curve: QEasingCurve.OutCubic,
|
||||
+ to: {
|
||||
+ value1: newGeometry.x + newGeometry.width / 2,
|
||||
+ value2: newGeometry.y + newGeometry.height / 2
|
||||
+ },
|
||||
+ from: {
|
||||
+ value1: oldGeometry.x + oldGeometry.width / 2,
|
||||
+ value2: oldGeometry.y + oldGeometry.height / 2
|
||||
+ }
|
||||
+ }]
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+new panHelperEffect();
|
||||
diff --git a/src/plugins/panhelper/package/metadata.json b/src/plugins/panhelper/package/metadata.json
|
||||
new file mode 100644
|
||||
index 0000000000..14f7d37882
|
||||
--- /dev/null
|
||||
+++ b/src/plugins/panhelper/package/metadata.json
|
||||
@@ -0,0 +1,22 @@
|
||||
+{
|
||||
+ "KPackageStructure": "KWin/Effect",
|
||||
+ "KPlugin": {
|
||||
+ "Authors": [
|
||||
+ {
|
||||
+ "Email": "wilderjds@protonmail.com",
|
||||
+ "Name": "Jacopo De Simoi"
|
||||
+ }
|
||||
+ ],
|
||||
+ "Category": "Window Pan Animation",
|
||||
+ "Description": "Make windows smoothly pan when they are moved (KDE6 version)",
|
||||
+ "EnabledByDefault": true,
|
||||
+ "Icon": "preferences-system-windows-effect-scale",
|
||||
+ "Id": "panhelper",
|
||||
+ "License": "GPL",
|
||||
+ "Name": "Pan Helper",
|
||||
+ "Version": "1"
|
||||
+ },
|
||||
+ "X-KDE-Ordering": "60",
|
||||
+ "X-KWin-Exclusive-Category": "toplevel-pan-animation",
|
||||
+ "X-Plasma-API": "javascript"
|
||||
+}
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,66 @@ |
||||
From 73d06f88f2dd16738574c578aad7a72054fadd8f Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Sat, 22 Oct 2022 22:03:42 -0400
|
||||
Subject: [PATCH 17/20] Remove boundary checking in the position effect
|
||||
|
||||
In order for the pan-helper effect to work, we need to drop the
|
||||
boundary checking in the position effect.
|
||||
|
||||
This seems not to have any adverse effects on my machine; some drivers
|
||||
might not like the fact that windows have negative coordinates.
|
||||
---
|
||||
src/effect/animationeffect.cpp | 29 +++++++++++------------------
|
||||
1 file changed, 11 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/effect/animationeffect.cpp b/src/effect/animationeffect.cpp
|
||||
index 621da89a9b..409d09db51 100644
|
||||
--- a/src/effect/animationeffect.cpp
|
||||
+++ b/src/effect/animationeffect.cpp
|
||||
@@ -570,18 +570,14 @@ void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const Render
|
||||
case Position: {
|
||||
const QRectF geo = w->frameGeometry();
|
||||
const float prgrs = progress(anim);
|
||||
- if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) {
|
||||
- float dest = interpolated(anim, 0);
|
||||
- const qreal x[2] = {xCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||
+ float dest = interpolated(anim, 0);
|
||||
+ const qreal x[2] = {xCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||
xCoord(geo, metaData(TargetAnchor, anim.meta))};
|
||||
- data.translate(dest - (x[0] + prgrs * (x[1] - x[0])));
|
||||
- }
|
||||
- if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) {
|
||||
- float dest = interpolated(anim, 1);
|
||||
- const qreal y[2] = {yCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||
+ data.translate(dest - (x[0] + prgrs * (x[1] - x[0])));
|
||||
+ dest = interpolated(anim, 1);
|
||||
+ const qreal y[2] = {yCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||
yCoord(geo, metaData(TargetAnchor, anim.meta))};
|
||||
- data.translate(0.0, dest - (y[0] + prgrs * (y[1] - y[0])));
|
||||
- }
|
||||
+ data.translate(0.0, dest - (y[0] + prgrs * (y[1] - y[0])));
|
||||
break;
|
||||
}
|
||||
case Rotation: {
|
||||
@@ -858,14 +854,11 @@ void AnimationEffect::updateLayerRepaints()
|
||||
y[0] = anim.from[1];
|
||||
y[1] = anim.to[1];
|
||||
} else {
|
||||
- if (anim.from[0] >= 0.0 && anim.to[0] >= 0.0) {
|
||||
- x[0] = anim.from[0] - xCoord(r, metaData(SourceAnchor, anim.meta));
|
||||
- x[1] = anim.to[0] - xCoord(r, metaData(TargetAnchor, anim.meta));
|
||||
- }
|
||||
- if (anim.from[1] >= 0.0 && anim.to[1] >= 0.0) {
|
||||
- y[0] = anim.from[1] - yCoord(r, metaData(SourceAnchor, anim.meta));
|
||||
- y[1] = anim.to[1] - yCoord(r, metaData(TargetAnchor, anim.meta));
|
||||
- }
|
||||
+ x[0] = anim.from[0] - xCoord(r, metaData(SourceAnchor, anim.meta));
|
||||
+ x[1] = anim.to[0] - xCoord(r, metaData(TargetAnchor, anim.meta));
|
||||
+
|
||||
+ y[0] = anim.from[1] - yCoord(r, metaData(SourceAnchor, anim.meta));
|
||||
+ y[1] = anim.to[1] - yCoord(r, metaData(TargetAnchor, anim.meta));
|
||||
}
|
||||
r = window->expandedGeometry().toRect();
|
||||
rects.push_back(r.translated(x[0], y[0]));
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,40 @@ |
||||
From 24fc0c2cf458e5a9e4b27310862b21758f9a71e6 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <jacopods@protonmail.com>
|
||||
Date: Mon, 28 Jun 2021 23:40:39 -0400
|
||||
Subject: [PATCH 18/20] Add paint_screen flag to prevent artifacts
|
||||
|
||||
As far as I understand I am abusing the Position effect; there are
|
||||
some assumption in the original implementation that do not work with
|
||||
my setting, so I need to add a flag to force full repaints for the
|
||||
duration of the effect.
|
||||
---
|
||||
src/effect/animationeffect.cpp | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/effect/animationeffect.cpp b/src/effect/animationeffect.cpp
|
||||
index 409d09db51..445fc4cd1f 100644
|
||||
--- a/src/effect/animationeffect.cpp
|
||||
+++ b/src/effect/animationeffect.cpp
|
||||
@@ -475,6 +475,10 @@ void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (anim.attribute == Position) {
|
||||
+ data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||
+ }
|
||||
+
|
||||
if (anim.frozenTime < 0) {
|
||||
anim.timeLine.advance(presentTime);
|
||||
}
|
||||
@@ -578,6 +582,8 @@ void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const Render
|
||||
const qreal y[2] = {yCoord(geo, metaData(SourceAnchor, anim.meta)),
|
||||
yCoord(geo, metaData(TargetAnchor, anim.meta))};
|
||||
data.translate(0.0, dest - (y[0] + prgrs * (y[1] - y[0])));
|
||||
+ // modify region if necessary
|
||||
+ w->addRepaintFull();
|
||||
break;
|
||||
}
|
||||
case Rotation: {
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,33 @@ |
||||
From 686789f83acd0bc99e91c1e1dfaf768284556c09 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Tue, 12 Nov 2024 22:41:42 -0500
|
||||
Subject: [PATCH 19/20] Allow loading the keymap from a file
|
||||
|
||||
Make this right
|
||||
---
|
||||
src/xkb.cpp | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/src/xkb.cpp b/src/xkb.cpp
|
||||
index 0cf6ac5816..3e8a6a0d72 100644
|
||||
--- a/src/xkb.cpp
|
||||
+++ b/src/xkb.cpp
|
||||
@@ -580,6 +580,15 @@ xkb_keymap *Xkb::loadKeymapFromConfig()
|
||||
if (!m_configGroup.isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
+
|
||||
+ if (m_configGroup.hasKey("KeymapFile")) {
|
||||
+ auto keymapFile = m_configGroup.readEntry("KeymapFile");
|
||||
+ QFile qf(keymapFile);
|
||||
+ qf.open(QIODevice::ReadOnly);
|
||||
+ QByteArray keymap_data = qf.readAll();
|
||||
+ qCDebug(KWIN_XKB) << "Loading keymap from" << keymapFile;
|
||||
+ return xkb_keymap_new_from_string(m_context, keymap_data, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
+ }
|
||||
const QByteArray model = m_configGroup.readEntry("Model", "pc104").toLatin1();
|
||||
const QByteArray layout = m_configGroup.readEntry("LayoutList").toLatin1();
|
||||
const QByteArray variant = m_configGroup.readEntry("VariantList").toLatin1();
|
||||
--
|
||||
2.49.1
|
||||
|
||||
@ -0,0 +1,25 @@ |
||||
From 4c7870369fc78bd803febe19ee8ee8b95d988d72 Mon Sep 17 00:00:00 2001
|
||||
From: Jacopo De Simoi <wilderjds@protonmail.com>
|
||||
Date: Sat, 31 May 2025 11:30:10 -0400
|
||||
Subject: [PATCH 20/20] temporary build fix
|
||||
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index f31cc8e413..bec737bd27 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -202,7 +202,7 @@ else()
|
||||
set(HAVE_WL_DISPLAY_SET_DEFAULT_MAX_BUFFER_SIZE 0)
|
||||
endif()
|
||||
if (Wayland_VERSION VERSION_GREATER_EQUAL 1.23.90)
|
||||
- set(HAVE_WL_FIXES 1)
|
||||
+ set(HAVE_WL_FIXES 0)
|
||||
else()
|
||||
set(HAVE_WL_FIXES 0)
|
||||
endif()
|
||||
--
|
||||
2.49.1
|
||||
|
||||
Loading…
Reference in new issue