mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-29 18:45:58 +01:00
renderer/animations: Fix various inaccurate damage tracking issues and offsets (#5297)
This commit is contained in:
parent
1cc9a44318
commit
16a9c16d9f
15 changed files with 229 additions and 147 deletions
|
@ -1165,6 +1165,44 @@ void CWindow::setAnimationsToMove() {
|
||||||
m_bAnimatingIn = false;
|
m_bAnimatingIn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindow::onWorkspaceAnimUpdate() {
|
||||||
|
// clip box for animated offsets
|
||||||
|
if (!m_bIsFloating || m_bPinned || m_bIsFullscreen) {
|
||||||
|
m_vFloatingOffset = Vector2D(0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2D offset;
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID);
|
||||||
|
if (!PWORKSPACE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
|
if (!PWSMON)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto WINBB = getFullWindowBoundingBox();
|
||||||
|
if (PWORKSPACE->m_vRenderOffset.value().x != 0) {
|
||||||
|
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x;
|
||||||
|
|
||||||
|
if (WINBB.x < PWSMON->vecPosition.x)
|
||||||
|
offset.x += (PWSMON->vecPosition.x - WINBB.x) * PROGRESS;
|
||||||
|
|
||||||
|
if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x)
|
||||||
|
offset.x += (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS;
|
||||||
|
} else if (PWORKSPACE->m_vRenderOffset.value().y != 0) {
|
||||||
|
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y;
|
||||||
|
|
||||||
|
if (WINBB.y < PWSMON->vecPosition.y)
|
||||||
|
offset.y += (PWSMON->vecPosition.y - WINBB.y) * PROGRESS;
|
||||||
|
|
||||||
|
if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y)
|
||||||
|
offset.y += (WINBB.y + WINBB.height - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vFloatingOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
int CWindow::popupsCount() {
|
int CWindow::popupsCount() {
|
||||||
if (m_bIsX11)
|
if (m_bIsX11)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -237,6 +237,9 @@ class CWindow {
|
||||||
Vector2D m_vLastFloatingSize;
|
Vector2D m_vLastFloatingSize;
|
||||||
Vector2D m_vLastFloatingPosition;
|
Vector2D m_vLastFloatingPosition;
|
||||||
|
|
||||||
|
// for floating window offset in workspace animations
|
||||||
|
Vector2D m_vFloatingOffset = Vector2D(0, 0);
|
||||||
|
|
||||||
// this is used for pseudotiling
|
// this is used for pseudotiling
|
||||||
bool m_bIsPseudotiled = false;
|
bool m_bIsPseudotiled = false;
|
||||||
Vector2D m_vPseudoSize = Vector2D(0, 0);
|
Vector2D m_vPseudoSize = Vector2D(0, 0);
|
||||||
|
@ -421,6 +424,7 @@ class CWindow {
|
||||||
void updateGroupOutputs();
|
void updateGroupOutputs();
|
||||||
void switchWithWindowInGroup(CWindow* pWindow);
|
void switchWithWindowInGroup(CWindow* pWindow);
|
||||||
void setAnimationsToMove();
|
void setAnimationsToMove();
|
||||||
|
void onWorkspaceAnimUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For hidden windows and stuff
|
// For hidden windows and stuff
|
||||||
|
|
|
@ -49,6 +49,16 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||||
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
||||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||||
|
|
||||||
|
// set floating windows offset callbacks
|
||||||
|
m_vRenderOffset.setUpdateCallback([&](void*) {
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != m_iID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
w->onWorkspaceAnimUpdate();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
if (ANIMSTYLE.starts_with("slidefade")) {
|
if (ANIMSTYLE.starts_with("slidefade")) {
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||||
float movePerc = 100.f;
|
float movePerc = 100.f;
|
||||||
|
|
|
@ -106,6 +106,11 @@ CBox& CBox::expand(const double& value) {
|
||||||
w += value * 2.0;
|
w += value * 2.0;
|
||||||
h += value * 2.0;
|
h += value * 2.0;
|
||||||
|
|
||||||
|
if (w <= 0 || h <= 0) {
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,22 +121,20 @@ CBox& CBox::noNegativeSize() {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBox& CBox::intersection(const CBox other) {
|
CBox CBox::intersection(const CBox other) const {
|
||||||
const float newTop = std::max(y, other.y);
|
const float newX = std::max(x, other.x);
|
||||||
|
const float newY = std::max(y, other.y);
|
||||||
const float newBottom = std::min(y + h, other.y + other.h);
|
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);
|
const float newRight = std::min(x + w, other.x + other.w);
|
||||||
y = newTop;
|
float newW = newRight - newX;
|
||||||
x = newLeft;
|
float newH = newBottom - newY;
|
||||||
w = newRight - newLeft;
|
|
||||||
h = newBottom - newTop;
|
|
||||||
|
|
||||||
if (w <= 0 || h <= 0) {
|
if (newW <= 0 || newH <= 0) {
|
||||||
w = 0;
|
newW = 0;
|
||||||
h = 0;
|
newH = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return {newX, newY, newW, newH};
|
||||||
}
|
}
|
||||||
|
|
||||||
CBox CBox::roundInternal() {
|
CBox CBox::roundInternal() {
|
||||||
|
|
|
@ -52,9 +52,9 @@ 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;
|
||||||
|
CBox intersection(const CBox other) const;
|
||||||
|
|
||||||
SWindowDecorationExtents extentsFrom(const CBox&); // this is the big box
|
SWindowDecorationExtents extentsFrom(const CBox&); // this is the big box
|
||||||
|
|
||||||
|
|
|
@ -87,11 +87,15 @@ void CAnimationManager::tick() {
|
||||||
|
|
||||||
CBox WLRBOXPREV = {0, 0, 0, 0};
|
CBox WLRBOXPREV = {0, 0, 0, 0};
|
||||||
if (PWINDOW) {
|
if (PWINDOW) {
|
||||||
CBox bb = PWINDOW->getFullWindowBoundingBox();
|
if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) {
|
||||||
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||||
if (PWINDOWWORKSPACE)
|
} else if (av->m_eDamagePolicy == AVARDAMAGE_BORDER) {
|
||||||
bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
|
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER);
|
||||||
WLRBOXPREV = bb;
|
PDECO->damageEntire();
|
||||||
|
} else if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW) {
|
||||||
|
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW);
|
||||||
|
PDECO->damageEntire();
|
||||||
|
}
|
||||||
|
|
||||||
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
|
@ -101,25 +105,35 @@ void CAnimationManager::tick() {
|
||||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
if (!PMONITOR)
|
if (!PMONITOR)
|
||||||
continue;
|
continue;
|
||||||
WLRBOXPREV = {PMONITOR->vecPosition, PMONITOR->vecSize};
|
|
||||||
|
// dont damage the whole monitor on workspace change, unless it's a special workspace, because dim/blur etc
|
||||||
|
if (PWORKSPACE->m_bIsSpecialWorkspace)
|
||||||
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||||
|
|
||||||
// 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 (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||||
g_pHyprRenderer->damageWindow(w.get());
|
continue;
|
||||||
|
|
||||||
|
if (w->m_bIsFloating && !w->m_bPinned) {
|
||||||
|
// still doing the full damage hack for floating because sometimes when the window
|
||||||
|
// goes through multiple monitors the last rendered frame is missing damage somehow??
|
||||||
|
const CBox windowBoxNoOffset = w->getFullWindowBoundingBox();
|
||||||
|
const CBox monitorBox = {PMONITOR->vecPosition, PMONITOR->vecSize};
|
||||||
|
if (windowBoxNoOffset.intersection(monitorBox) != windowBoxNoOffset) // on edges between multiple monitors
|
||||||
|
g_pHyprRenderer->damageWindow(w.get(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a special workspace window is on any monitor, damage it
|
if (PWORKSPACE->m_bIsSpecialWorkspace)
|
||||||
|
g_pHyprRenderer->damageWindow(w.get(), true); // hack for special too because it can cross multiple monitors
|
||||||
|
}
|
||||||
|
|
||||||
|
// damage any workspace window that is on any monitor
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
if (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID || w->m_bPinned)
|
||||||
if (w->m_iWorkspaceID == PWORKSPACE->m_iID && PWORKSPACE->m_bIsSpecialWorkspace && g_pCompositor->windowValidMapped(w.get()) &&
|
continue;
|
||||||
g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) {
|
|
||||||
CBox bb = w->getFullWindowBoundingBox();
|
g_pHyprRenderer->damageWindow(w.get());
|
||||||
bb.translate(PWORKSPACE->m_vRenderOffset.value());
|
|
||||||
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()};
|
||||||
|
@ -194,26 +208,13 @@ void CAnimationManager::tick() {
|
||||||
|
|
||||||
if (PWINDOW) {
|
if (PWINDOW) {
|
||||||
PWINDOW->updateWindowDecos();
|
PWINDOW->updateWindowDecos();
|
||||||
auto bb = PWINDOW->getFullWindowBoundingBox();
|
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||||
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
|
||||||
if (PWINDOWWORKSPACE)
|
|
||||||
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 (!g_pCompositor->windowValidMapped(w.get()) || w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||||
continue;
|
|
||||||
|
|
||||||
if (w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
w->updateWindowDecos();
|
w->updateWindowDecos();
|
||||||
|
|
||||||
if (w->m_bIsFloating) {
|
|
||||||
auto bb = w->getFullWindowBoundingBox();
|
|
||||||
bb.translate(PWORKSPACE->m_vRenderOffset.value());
|
|
||||||
g_pHyprRenderer->damageBox(&bb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (PLAYER) {
|
} else if (PLAYER) {
|
||||||
if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
if (PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || PLAYER->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
|
||||||
|
@ -229,31 +230,8 @@ void CAnimationManager::tick() {
|
||||||
case AVARDAMAGE_BORDER: {
|
case AVARDAMAGE_BORDER: {
|
||||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!");
|
||||||
|
|
||||||
// TODO: move this to the border class
|
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER);
|
||||||
|
PDECO->damageEntire();
|
||||||
// damage only the border.
|
|
||||||
const auto ROUNDING = PWINDOW->rounding();
|
|
||||||
const auto ROUNDINGSIZE = ROUNDING + 1;
|
|
||||||
const auto BORDERSIZE = PWINDOW->getRealBorderSize();
|
|
||||||
|
|
||||||
// damage for old box
|
|
||||||
g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top
|
|
||||||
g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height + 2 * BORDERSIZE); // left
|
|
||||||
g_pHyprRenderer->damageBox(WLRBOXPREV.x + WLRBOXPREV.width - ROUNDINGSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE,
|
|
||||||
WLRBOXPREV.height + 2 * BORDERSIZE); // right
|
|
||||||
g_pHyprRenderer->damageBox(WLRBOXPREV.x, WLRBOXPREV.y + WLRBOXPREV.height - ROUNDINGSIZE, WLRBOXPREV.width + 2 * BORDERSIZE,
|
|
||||||
BORDERSIZE + ROUNDINGSIZE); // bottom
|
|
||||||
|
|
||||||
// damage for new box
|
|
||||||
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,
|
|
||||||
WLRBOXNEW.height + 2 * BORDERSIZE); // right
|
|
||||||
g_pHyprRenderer->damageBox(WLRBOXNEW.x, WLRBOXNEW.y + WLRBOXNEW.height - ROUNDINGSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // bottom
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data)
|
||||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET;
|
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWorkspace* pWorkspace) {
|
bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) {
|
||||||
CBox geometry = pWindow->getFullWindowBoundingBox();
|
CBox geometry = pWindow->getFullWindowBoundingBox();
|
||||||
|
|
||||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr()))
|
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr()))
|
||||||
|
@ -234,9 +234,12 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor, CWo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pWindow->m_iWorkspaceID == pWorkspace->m_iID && pWorkspace->m_iMonitorID == pMonitor->ID)
|
if (pWindow->m_iMonitorID == pMonitor->ID)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_iMonitorID != pMonitor->ID)
|
||||||
|
return false;
|
||||||
|
|
||||||
// if not, check if it maybe is active on a different monitor.
|
// if not, check if it maybe is active on a different monitor.
|
||||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
|
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */)
|
||||||
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors
|
||||||
|
@ -244,12 +247,20 @@ 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 window is tiled and it's flying in, don't render on other mons (for slide)
|
||||||
|
if (!pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (pWindow->m_vRealPosition.isBeingAnimated()) {
|
if (pWindow->m_vRealPosition.isBeingAnimated()) {
|
||||||
if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated())
|
if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated())
|
||||||
return false;
|
return false;
|
||||||
// render window if window and monitor intersect
|
// render window if window and monitor intersect
|
||||||
// (when moving out of or through a monitor)
|
// (when moving out of or through a monitor)
|
||||||
CBox windowBox = pWindow->getFullWindowBoundingBox();
|
CBox windowBox = pWindow->getFullWindowBoundingBox();
|
||||||
|
if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated())
|
||||||
|
windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
|
||||||
|
windowBox.translate(pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize};
|
const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize};
|
||||||
if (!windowBox.intersection(monitorBox).empty())
|
if (!windowBox.intersection(monitorBox).empty())
|
||||||
return true;
|
return true;
|
||||||
|
@ -292,7 +303,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp
|
||||||
|
|
||||||
// loop over the tiled windows that are fading out
|
// loop over the tiled windows that are fading out
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w->m_fAlpha.value() == 0.f)
|
if (w->m_fAlpha.value() == 0.f)
|
||||||
|
@ -309,7 +320,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp
|
||||||
|
|
||||||
// and floating ones too
|
// and floating ones too
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (w->m_fAlpha.value() == 0.f)
|
if (w->m_fAlpha.value() == 0.f)
|
||||||
|
@ -345,7 +356,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(CMonitor* pMonitor, CWorksp
|
||||||
if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
if (w->m_iMonitorID == pWorkspace->m_iMonitorID && pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (shouldRenderWindow(w.get(), pMonitor))
|
||||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
|
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
|
||||||
|
|
||||||
if (w->m_iWorkspaceID != pWorkspace->m_iID)
|
if (w->m_iWorkspaceID != pWorkspace->m_iID)
|
||||||
|
@ -388,7 +399,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
|
||||||
if (w->m_bIsFloating)
|
if (w->m_bIsFloating)
|
||||||
continue; // floating are in the second pass
|
continue; // floating are in the second pass
|
||||||
|
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
||||||
|
@ -418,7 +429,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
|
||||||
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// render the bad boy
|
// render the bad boy
|
||||||
|
@ -433,7 +444,7 @@ void CHyprRenderer::renderWorkspaceWindows(CMonitor* pMonitor, CWorkspace* pWork
|
||||||
if (!w->m_bIsFloating || w->m_bPinned)
|
if (!w->m_bIsFloating || w->m_bPinned)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
if (pWorkspace->m_bIsSpecialWorkspace != g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))
|
||||||
|
@ -510,47 +521,16 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||||
g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha));
|
g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip box for animated offsets
|
renderdata.x += pWindow->m_vFloatingOffset.x;
|
||||||
const Vector2D PREOFFSETPOS = {renderdata.x, renderdata.y};
|
renderdata.y += pWindow->m_vFloatingOffset.y;
|
||||||
if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bPinned && !pWindow->m_bIsFullscreen) {
|
|
||||||
Vector2D offset;
|
|
||||||
|
|
||||||
if (PWORKSPACE->m_vRenderOffset.value().x != 0) {
|
|
||||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
|
||||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x;
|
|
||||||
const auto WINBB = pWindow->getFullWindowBoundingBox();
|
|
||||||
|
|
||||||
if (WINBB.x < PWSMON->vecPosition.x) {
|
|
||||||
offset.x = (PWSMON->vecPosition.x - WINBB.x) * PROGRESS;
|
|
||||||
} else if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) {
|
|
||||||
offset.x = (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS;
|
|
||||||
}
|
|
||||||
} else if (PWORKSPACE->m_vRenderOffset.value().y != 0) {
|
|
||||||
const auto PWSMON = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
|
||||||
const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y;
|
|
||||||
const auto WINBB = pWindow->getFullWindowBoundingBox();
|
|
||||||
|
|
||||||
if (WINBB.y < PWSMON->vecPosition.y) {
|
|
||||||
offset.y = (PWSMON->vecPosition.y - WINBB.y) * PROGRESS;
|
|
||||||
} else if (WINBB.y + WINBB.height > PWSMON->vecPosition.y + PWSMON->vecSize.y) {
|
|
||||||
offset.y = (WINBB.y + WINBB.width - PWSMON->vecPosition.y - PWSMON->vecSize.y) * PROGRESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderdata.x += offset.x;
|
|
||||||
renderdata.y += offset.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if window is floating and we have a slide animation, clip it to its full bb
|
// if window is floating and we have a slide animation, clip it to its full bb
|
||||||
if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bIsFullscreen && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) {
|
if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->m_bIsFullscreen && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) {
|
||||||
CRegion rg = pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value()).scale(pMonitor->scale);
|
CRegion rg =
|
||||||
|
pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale);
|
||||||
g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents();
|
g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if window is tiled and it's flying in, don't render on other mons (for slide)
|
|
||||||
if (!ignorePosition && !pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_iMonitorID != pMonitor->ID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// render window decorations first, if not fullscreen full
|
// render window decorations first, if not fullscreen full
|
||||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
|
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
|
||||||
|
|
||||||
|
@ -569,14 +549,14 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||||
if (wd->getDecorationLayer() != DECORATION_LAYER_BOTTOM)
|
if (wd->getDecorationLayer() != DECORATION_LAYER_BOTTOM)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
|
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& wd : pWindow->m_dWindowDecorations) {
|
for (auto& wd : pWindow->m_dWindowDecorations) {
|
||||||
if (wd->getDecorationLayer() != DECORATION_LAYER_UNDER)
|
if (wd->getDecorationLayer() != DECORATION_LAYER_UNDER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
|
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +581,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||||
if (wd->getDecorationLayer() != DECORATION_LAYER_OVER)
|
if (wd->getDecorationLayer() != DECORATION_LAYER_OVER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
|
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +642,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||||
if (wd->getDecorationLayer() != DECORATION_LAYER_OVERLAY)
|
if (wd->getDecorationLayer() != DECORATION_LAYER_OVERLAY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
|
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -861,7 +841,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||||
if (!w->m_bPinned || !w->m_bIsFloating)
|
if (!w->m_bPinned || !w->m_bIsFloating)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!shouldRenderWindow(w.get(), pMonitor, pWorkspace))
|
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// render the bad boy
|
// render the bad boy
|
||||||
|
@ -1739,16 +1719,23 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou
|
||||||
damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1);
|
damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
void CHyprRenderer::damageWindow(CWindow* pWindow, bool forceFull) {
|
||||||
if (g_pCompositor->m_bUnsafeState)
|
if (g_pCompositor->m_bUnsafeState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CBox damageBox = pWindow->getFullWindowBoundingBox();
|
CBox windowBox = pWindow->getFullWindowBoundingBox();
|
||||||
|
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned)
|
||||||
|
windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
|
||||||
|
windowBox.translate(pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
CBox fixedDamageBox = {damageBox.x - m->vecPosition.x, damageBox.y - m->vecPosition.y, damageBox.width, damageBox.height};
|
if (g_pHyprRenderer->shouldRenderWindow(pWindow, m.get()) || forceFull) { // only damage if window is rendered on monitor
|
||||||
|
CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height};
|
||||||
fixedDamageBox.scale(m->scale);
|
fixedDamageBox.scale(m->scale);
|
||||||
m->addDamage(&fixedDamageBox);
|
m->addDamage(&fixedDamageBox);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& wd : pWindow->m_dWindowDecorations)
|
for (auto& wd : pWindow->m_dWindowDecorations)
|
||||||
wd->damageEntire();
|
wd->damageEntire();
|
||||||
|
@ -1756,7 +1743,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||||
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
|
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
|
||||||
|
|
||||||
if (*PLOGDAMAGE)
|
if (*PLOGDAMAGE)
|
||||||
Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
Debug::log(LOG, "Damage: Window ({}): xy: {}, {} wh: {}, {}", pWindow->m_szTitle, windowBox.x, windowBox.y, windowBox.width, windowBox.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
|
||||||
|
|
|
@ -46,14 +46,14 @@ class CHyprRenderer {
|
||||||
void outputMgrApplyTest(wlr_output_configuration_v1*, bool);
|
void outputMgrApplyTest(wlr_output_configuration_v1*, bool);
|
||||||
void arrangeLayersForMonitor(const int&);
|
void arrangeLayersForMonitor(const int&);
|
||||||
void damageSurface(wlr_surface*, double, double, double scale = 1.0);
|
void damageSurface(wlr_surface*, double, double, double scale = 1.0);
|
||||||
void damageWindow(CWindow*);
|
void damageWindow(CWindow*, bool forceFull = false);
|
||||||
void damageBox(CBox*);
|
void damageBox(CBox*);
|
||||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||||
void damageRegion(const CRegion&);
|
void damageRegion(const CRegion&);
|
||||||
void damageMonitor(CMonitor*);
|
void damageMonitor(CMonitor*);
|
||||||
void damageMirrorsWith(CMonitor*, const CRegion&);
|
void damageMirrorsWith(CMonitor*, const CRegion&);
|
||||||
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
|
||||||
bool shouldRenderWindow(CWindow*, CMonitor*, CWorkspace*);
|
bool shouldRenderWindow(CWindow*, CMonitor*);
|
||||||
bool shouldRenderWindow(CWindow*);
|
bool shouldRenderWindow(CWindow*);
|
||||||
void ensureCursorRenderingMode();
|
void ensureCursorRenderingMode();
|
||||||
bool shouldRenderCursor();
|
bool shouldRenderCursor();
|
||||||
|
|
|
@ -45,14 +45,14 @@ CBox CHyprBorderDecoration::assignedBoxGlobal() {
|
||||||
return box.translate(WORKSPACEOFFSET);
|
return box.translate(WORKSPACEOFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprBorderDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
void CHyprBorderDecoration::draw(CMonitor* pMonitor, float a) {
|
||||||
if (doesntWantBorders())
|
if (doesntWantBorders())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_bAssignedGeometry.width < m_seExtents.topLeft.x + 1 || m_bAssignedGeometry.height < m_seExtents.topLeft.y + 1)
|
if (m_bAssignedGeometry.width < m_seExtents.topLeft.x + 1 || m_bAssignedGeometry.height < m_seExtents.topLeft.y + 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CBox windowBox = assignedBoxGlobal().translate(-pMonitor->vecPosition + offset).expand(-m_pWindow->getRealBorderSize()).scale(pMonitor->scale).round();
|
CBox windowBox = assignedBoxGlobal().translate(-pMonitor->vecPosition + m_pWindow->m_vFloatingOffset).expand(-m_pWindow->getRealBorderSize()).scale(pMonitor->scale).round();
|
||||||
|
|
||||||
if (windowBox.width < 1 || windowBox.height < 1)
|
if (windowBox.width < 1 || windowBox.height < 1)
|
||||||
return;
|
return;
|
||||||
|
@ -87,7 +87,35 @@ void CHyprBorderDecoration::updateWindow(CWindow*) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprBorderDecoration::damageEntire() {
|
void CHyprBorderDecoration::damageEntire() {
|
||||||
; // ignored, done in animationManager. todo, move.
|
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto surfaceBox = m_pWindow->getWindowMainSurfaceBox();
|
||||||
|
const auto ROUNDING = m_pWindow->rounding();
|
||||||
|
const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1;
|
||||||
|
const auto BORDERSIZE = m_pWindow->getRealBorderSize();
|
||||||
|
|
||||||
|
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
||||||
|
if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned)
|
||||||
|
surfaceBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
|
||||||
|
surfaceBox.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
|
CBox surfaceBoxExpandedBorder = surfaceBox;
|
||||||
|
surfaceBoxExpandedBorder.expand(BORDERSIZE);
|
||||||
|
CBox surfaceBoxShrunkRounding = surfaceBox;
|
||||||
|
surfaceBoxShrunkRounding.expand(-ROUNDINGSIZE);
|
||||||
|
|
||||||
|
CRegion borderRegion(surfaceBoxExpandedBorder);
|
||||||
|
borderRegion.subtract(surfaceBoxShrunkRounding);
|
||||||
|
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
if (!g_pHyprRenderer->shouldRenderWindow(m_pWindow, m.get())) {
|
||||||
|
const CRegion monitorRegion({m->vecPosition, m->vecSize});
|
||||||
|
borderRegion.subtract(monitorRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pHyprRenderer->damageRegion(borderRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
eDecorationLayer CHyprBorderDecoration::getDecorationLayer() {
|
eDecorationLayer CHyprBorderDecoration::getDecorationLayer() {
|
||||||
|
|
|
@ -11,7 +11,7 @@ class CHyprBorderDecoration : public IHyprWindowDecoration {
|
||||||
|
|
||||||
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
virtual void draw(CMonitor*, float a);
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,37 @@ void CHyprDropShadowDecoration::damageEntire() {
|
||||||
if (*PSHADOWS != 1)
|
if (*PSHADOWS != 1)
|
||||||
return; // disabled
|
return; // disabled
|
||||||
|
|
||||||
CBox dm = {m_vLastWindowPos.x - m_seExtents.topLeft.x, m_vLastWindowPos.y - m_seExtents.topLeft.y, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x,
|
CBox shadowBox = {m_pWindow->m_vRealPosition.value().x - m_seExtents.topLeft.x, m_pWindow->m_vRealPosition.value().y - m_seExtents.topLeft.y,
|
||||||
m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y};
|
m_pWindow->m_vRealSize.value().x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x,
|
||||||
g_pHyprRenderer->damageBox(&dm);
|
m_pWindow->m_vRealSize.value().y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y};
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
||||||
|
if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned)
|
||||||
|
shadowBox.translate(PWORKSPACE->m_vRenderOffset.value());
|
||||||
|
shadowBox.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
|
static auto PSHADOWIGNOREWINDOW = CConfigValue<Hyprlang::INT>("decoration:shadow_ignore_window");
|
||||||
|
const auto ROUNDING = m_pWindow->rounding();
|
||||||
|
const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1;
|
||||||
|
|
||||||
|
CRegion shadowRegion(shadowBox);
|
||||||
|
if (*PSHADOWIGNOREWINDOW) {
|
||||||
|
CBox surfaceBox = m_pWindow->getWindowMainSurfaceBox();
|
||||||
|
if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned)
|
||||||
|
surfaceBox.translate(PWORKSPACE->m_vRenderOffset.value());
|
||||||
|
surfaceBox.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
surfaceBox.expand(-ROUNDINGSIZE);
|
||||||
|
shadowRegion.subtract(CRegion(surfaceBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
if (!g_pHyprRenderer->shouldRenderWindow(m_pWindow, m.get())) {
|
||||||
|
const CRegion monitorRegion({m->vecPosition, m->vecSize});
|
||||||
|
shadowRegion.subtract(monitorRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pHyprRenderer->damageRegion(shadowRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||||
|
@ -54,7 +82,7 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||||
m_bLastWindowBoxWithDecos = g_pDecorationPositioner->getBoxWithIncludedDecos(pWindow);
|
m_bLastWindowBoxWithDecos = g_pDecorationPositioner->getBoxWithIncludedDecos(pWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) {
|
||||||
|
|
||||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||||
return;
|
return;
|
||||||
|
@ -98,12 +126,13 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
||||||
// scale the box in relation to the center of the box
|
// scale the box in relation to the center of the box
|
||||||
fullBox.scaleFromCenter(SHADOWSCALE).translate(*PSHADOWOFFSET);
|
fullBox.scaleFromCenter(SHADOWSCALE).translate(*PSHADOWOFFSET);
|
||||||
|
|
||||||
|
updateWindow(m_pWindow);
|
||||||
m_vLastWindowPos += WORKSPACEOFFSET;
|
m_vLastWindowPos += WORKSPACEOFFSET;
|
||||||
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
||||||
{fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
{fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
||||||
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}};
|
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}};
|
||||||
|
|
||||||
fullBox.translate(offset);
|
fullBox.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
if (fullBox.width < 1 || fullBox.height < 1)
|
if (fullBox.width < 1 || fullBox.height < 1)
|
||||||
return; // don't draw invisible shadows
|
return; // don't draw invisible shadows
|
||||||
|
@ -125,6 +154,9 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
||||||
windowBox.translate(-pMonitor->vecPosition + WORKSPACEOFFSET);
|
windowBox.translate(-pMonitor->vecPosition + WORKSPACEOFFSET);
|
||||||
withDecos.translate(-pMonitor->vecPosition + WORKSPACEOFFSET);
|
withDecos.translate(-pMonitor->vecPosition + WORKSPACEOFFSET);
|
||||||
|
|
||||||
|
windowBox.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
withDecos.translate(m_pWindow->m_vFloatingOffset);
|
||||||
|
|
||||||
auto scaledExtentss = withDecos.extentsFrom(windowBox);
|
auto scaledExtentss = withDecos.extentsFrom(windowBox);
|
||||||
scaledExtentss = scaledExtentss * pMonitor->scale;
|
scaledExtentss = scaledExtentss * pMonitor->scale;
|
||||||
scaledExtentss = scaledExtentss.round();
|
scaledExtentss = scaledExtentss.round();
|
||||||
|
|
|
@ -11,7 +11,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration {
|
||||||
|
|
||||||
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
virtual void draw(CMonitor*, float a);
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
|
|
|
@ -83,10 +83,11 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::damageEntire() {
|
void CHyprGroupBarDecoration::damageEntire() {
|
||||||
auto box = assignedBoxGlobal();
|
auto box = assignedBoxGlobal();
|
||||||
|
box.translate(m_pWindow->m_vFloatingOffset);
|
||||||
g_pHyprRenderer->damageBox(&box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a) {
|
||||||
// get how many bars we will draw
|
// get how many bars we will draw
|
||||||
int barsToDraw = m_dwGroupMembers.size();
|
int barsToDraw = m_dwGroupMembers.size();
|
||||||
|
|
||||||
|
@ -110,8 +111,9 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
||||||
int xoff = 0;
|
int xoff = 0;
|
||||||
|
|
||||||
for (int i = 0; i < barsToDraw; ++i) {
|
for (int i = 0; i < barsToDraw; ++i) {
|
||||||
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x,
|
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x,
|
||||||
ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + offset.y, m_fBarWidth, BAR_INDICATOR_HEIGHT};
|
ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth,
|
||||||
|
BAR_INDICATOR_HEIGHT};
|
||||||
|
|
||||||
if (rect.width <= 0 || rect.height <= 0)
|
if (rect.width <= 0 || rect.height <= 0)
|
||||||
break;
|
break;
|
||||||
|
@ -135,7 +137,8 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
||||||
color.a *= a;
|
color.a *= a;
|
||||||
g_pHyprOpenGL->renderRect(&rect, color);
|
g_pHyprOpenGL->renderRect(&rect, color);
|
||||||
|
|
||||||
rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x, ASSIGNEDBOX.y - pMonitor->vecPosition.y + offset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth,
|
rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x,
|
||||||
|
ASSIGNEDBOX.y - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth,
|
||||||
ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT * 2};
|
ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT * 2};
|
||||||
rect.scale(pMonitor->scale);
|
rect.scale(pMonitor->scale);
|
||||||
|
|
||||||
|
@ -505,9 +508,8 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() {
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
if (!PWORKSPACE)
|
if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned)
|
||||||
return box;
|
box.translate(PWORKSPACE->m_vRenderOffset.value());
|
||||||
|
|
||||||
const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D();
|
return box;
|
||||||
return box.translate(WORKSPACEOFFSET);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
|
||||||
|
|
||||||
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
virtual void draw(CMonitor*, float a);
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class IHyprWindowDecoration {
|
||||||
|
|
||||||
virtual void onPositioningReply(const SDecorationPositioningReply& reply) = 0;
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply) = 0;
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset = Vector2D()) = 0;
|
virtual void draw(CMonitor*, float a) = 0;
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType() = 0;
|
virtual eDecorationType getDecorationType() = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue