summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorthejch <66577496+thejch@users.noreply.github.com>2024-03-16 07:49:34 -0700
committerGitHub <noreply@github.com>2024-03-16 14:49:34 +0000
commitc942ce6dce7f01415f71e5207da69b6989d3818c (patch)
treefcb8064234100b716770877fe61eb8c3851cc83d /src
parent5e5d7e2abcd91c83058ba80ec64ec5054cae5bfa (diff)
renderer: add better multi monitor animations (#5126)
Diffstat (limited to 'src')
-rw-r--r--src/helpers/Box.cpp18
-rw-r--r--src/helpers/Box.hpp1
-rw-r--r--src/managers/AnimationManager.cpp35
-rw-r--r--src/render/Renderer.cpp15
4 files changed, 61 insertions, 8 deletions
diff --git a/src/helpers/Box.cpp b/src/helpers/Box.cpp
index 59578f23..e9e0eeeb 100644
--- a/src/helpers/Box.cpp
+++ b/src/helpers/Box.cpp
@@ -116,6 +116,24 @@ CBox& CBox::noNegativeSize() {
return *this;
}
+CBox& CBox::intersection(const CBox other) {
+ const float newTop = std::max(y, other.y);
+ const float newBottom = std::min(y + h, other.y + other.h);
+ const float newLeft = std::max(x, other.x);
+ const float newRight = std::min(x + w, other.x + other.w);
+ y = newTop;
+ x = newLeft;
+ w = newRight - newLeft;
+ h = newBottom - newTop;
+
+ if (w <= 0 || h <= 0) {
+ w = 0;
+ h = 0;
+ }
+
+ return *this;
+}
+
CBox CBox::roundInternal() {
float newW = x + w - std::floor(x);
float newH = y + h - std::floor(y);
diff --git a/src/helpers/Box.hpp b/src/helpers/Box.hpp
index fd31a7b7..e38d6108 100644
--- a/src/helpers/Box.hpp
+++ b/src/helpers/Box.hpp
@@ -52,6 +52,7 @@ class CBox {
CBox& addExtents(const SWindowDecorationExtents& e);
CBox& expand(const double& value);
CBox& noNegativeSize();
+ CBox& intersection(const CBox other);
CBox copy() const;
diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp
index 072a377e..f9dfa6fa 100644
--- a/src/managers/AnimationManager.cpp
+++ b/src/managers/AnimationManager.cpp
@@ -86,8 +86,13 @@ void CAnimationManager::tick() {
CBox WLRBOXPREV = {0, 0, 0, 0};
if (PWINDOW) {
- WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
- PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
+ CBox bb = PWINDOW->getFullWindowBoundingBox();
+ const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
+ if (PWINDOWWORKSPACE)
+ bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
+ WLRBOXPREV = bb;
+
+ PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR)
continue;
animationsDisabled = animationsDisabled || PWINDOW->m_sAdditionalConfigData.forceNoAnims;
@@ -95,13 +100,27 @@ void CAnimationManager::tick() {
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
if (!PMONITOR)
continue;
- WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
+ WLRBOXPREV = {PMONITOR->vecPosition, PMONITOR->vecSize};
// TODO: just make this into a damn callback already vax...
for (auto& w : g_pCompositor->m_vWindows) {
if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating)
g_pHyprRenderer->damageWindow(w.get());
}
+
+ // if a workspace window is on any monitor, damage it
+ for (auto& w : g_pCompositor->m_vWindows) {
+ for (auto& m : g_pCompositor->m_vMonitors) {
+ if (w->m_iWorkspaceID == PWORKSPACE->m_iID && g_pCompositor->windowValidMapped(w.get()) && g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) {
+ CBox bb = w->getFullWindowBoundingBox();
+ bb.translate(PWORKSPACE->m_vRenderOffset.value());
+ if (PWORKSPACE->m_bIsSpecialWorkspace)
+ bb.scaleFromCenter(1.1); // for some reason special ws windows getting border artifacts if you close it too quickly...
+ bb.intersection({m->vecPosition, m->vecSize});
+ g_pHyprRenderer->damageBox(&bb);
+ }
+ }
+ }
} else if (PLAYER) {
WLRBOXPREV = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()};
PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f);
@@ -175,7 +194,10 @@ void CAnimationManager::tick() {
if (PWINDOW) {
PWINDOW->updateWindowDecos();
- g_pHyprRenderer->damageWindow(PWINDOW);
+ auto bb = PWINDOW->getFullWindowBoundingBox();
+ const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
+ bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
+ g_pHyprRenderer->damageBox(&bb);
} else if (PWORKSPACE) {
for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->isHidden())
@@ -222,7 +244,10 @@ void CAnimationManager::tick() {
BORDERSIZE + ROUNDINGSIZE); // bottom
// damage for new box
- const CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y, PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealSize.value().y};
+ CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value(), PWINDOW->m_vRealSize.value()};
+ const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
+ if (PWINDOWWORKSPACE)
+ WLRBOXNEW.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top
g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left
g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE,
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 309e5742..cb60cd41 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -224,6 +224,15 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo
if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID)
return true;
+ if (pWindow->m_vRealPosition.isBeingAnimated()) {
+ // render window if window and monitor intersect
+ // (when moving out of or through a monitor)
+ CBox windowBox = {pWindow->m_vRealPosition.value(), pWindow->m_vRealSize.value()};
+ const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize};
+ if (!windowBox.intersection(monitorBox).empty())
+ return true;
+ }
+
return false;
}
@@ -363,7 +372,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
continue;
// render active window after all others of this pass
- if (w.get() == g_pCompositor->m_pLastWindow && w->m_iWorkspaceID == pWorkspace->m_iID) {
+ if (w.get() == g_pCompositor->m_pLastWindow) {
lastWindow = w.get();
continue;
}
@@ -404,7 +413,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
continue;
- if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
+ if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
continue;
if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID)
@@ -781,7 +790,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
// special
for (auto& ws : g_pCompositor->m_vWorkspaces) {
- if (ws->m_iMonitorID == pMonitor->ID && ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) {
+ if (ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) {
if (ws->m_bHasFullscreenWindow)
renderWorkspaceWindowsFullscreen(pMonitor, ws.get(), time);
else