mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 08:46:00 +01:00
renderer: add better multi monitor animations (#5126)
This commit is contained in:
parent
5e5d7e2abc
commit
c942ce6dce
4 changed files with 61 additions and 8 deletions
|
@ -116,6 +116,24 @@ CBox& CBox::noNegativeSize() {
|
||||||
return *this;
|
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() {
|
CBox CBox::roundInternal() {
|
||||||
float newW = x + w - std::floor(x);
|
float newW = x + w - std::floor(x);
|
||||||
float newH = y + h - std::floor(y);
|
float newH = y + h - std::floor(y);
|
||||||
|
|
|
@ -52,6 +52,7 @@ class CBox {
|
||||||
CBox& addExtents(const SWindowDecorationExtents& e);
|
CBox& addExtents(const SWindowDecorationExtents& e);
|
||||||
CBox& expand(const double& value);
|
CBox& expand(const double& value);
|
||||||
CBox& noNegativeSize();
|
CBox& noNegativeSize();
|
||||||
|
CBox& intersection(const CBox other);
|
||||||
|
|
||||||
CBox copy() const;
|
CBox copy() const;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,12 @@ void CAnimationManager::tick() {
|
||||||
|
|
||||||
CBox WLRBOXPREV = {0, 0, 0, 0};
|
CBox WLRBOXPREV = {0, 0, 0, 0};
|
||||||
if (PWINDOW) {
|
if (PWINDOW) {
|
||||||
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
|
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);
|
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
continue;
|
continue;
|
||||||
|
@ -95,13 +100,27 @@ void CAnimationManager::tick() {
|
||||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
continue;
|
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...
|
// TODO: just make this into a damn callback already vax...
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating)
|
if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating)
|
||||||
g_pHyprRenderer->damageWindow(w.get());
|
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) {
|
} else if (PLAYER) {
|
||||||
WLRBOXPREV = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()};
|
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);
|
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) {
|
if (PWINDOW) {
|
||||||
PWINDOW->updateWindowDecos();
|
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) {
|
} else if (PWORKSPACE) {
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (!w->m_bIsMapped || w->isHidden())
|
if (!w->m_bIsMapped || w->isHidden())
|
||||||
|
@ -222,7 +244,10 @@ void CAnimationManager::tick() {
|
||||||
BORDERSIZE + ROUNDINGSIZE); // bottom
|
BORDERSIZE + ROUNDINGSIZE); // bottom
|
||||||
|
|
||||||
// damage for new box
|
// 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, 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 - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left
|
||||||
g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE,
|
g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE,
|
||||||
|
|
|
@ -224,6 +224,15 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo
|
||||||
if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID)
|
if (pMonitor->specialWorkspaceID == pWindow->m_iWorkspaceID)
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +372,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// render active window after all others of this pass
|
// 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();
|
lastWindow = w.get();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +413,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID)
|
if (pWorkspace->m_bIsSpecialWorkspace && w->m_iMonitorID != pWorkspace->m_iMonitorID)
|
||||||
|
@ -781,7 +790,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||||
|
|
||||||
// special
|
// special
|
||||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
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)
|
if (ws->m_bHasFullscreenWindow)
|
||||||
renderWorkspaceWindowsFullscreen(pMonitor, ws.get(), time);
|
renderWorkspaceWindowsFullscreen(pMonitor, ws.get(), time);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue