internal: Window storage rework - part 1 (#5762)

* Window storage rework - part 1

* format

* remove useless include

* fix pch

* format

* fix crash in dwindle

* fix vram leak

* prefer .expired() for bool checks
This commit is contained in:
Vaxry 2024-04-27 12:43:12 +01:00 committed by GitHub
parent 25aec3ac8c
commit bca7804bb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 1416 additions and 1346 deletions

View file

@ -2,7 +2,7 @@
#include "../config/ConfigValue.hpp"
#include "../Compositor.hpp"
CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) {
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
initAllSignals();
}
@ -69,8 +69,8 @@ static void onRepositionPopup(void* owner, void* data) {
void CPopup::initAllSignals() {
if (!m_pWLR) {
if (m_pWindowOwner)
hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
if (!m_pWindowOwner.expired())
hyprListener_newPopup.initCallback(&m_pWindowOwner.lock()->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
else if (m_pLayerOwner)
hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head");
else
@ -146,12 +146,12 @@ void CPopup::onCommit(bool ignoreSiblings) {
return;
}
if (m_pWindowOwner && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) {
if (!m_pWindowOwner.expired() && (!m_pWindowOwner.lock()->m_bIsMapped || !m_pWindowOwner.lock()->m_pWorkspace->m_bVisible)) {
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
if (*PLOGDAMAGE)
Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner);
Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowOwner.lock());
return;
}
@ -230,8 +230,8 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
}
Vector2D CPopup::t1ParentCoords() {
if (m_pWindowOwner)
return m_pWindowOwner->m_vRealPosition.value();
if (!m_pWindowOwner.expired())
return m_pWindowOwner.lock()->m_vRealPosition.value();
if (m_pLayerOwner)
return m_pLayerOwner->realPosition.value();
@ -260,8 +260,8 @@ Vector2D CPopup::size() {
}
void CPopup::sendScale() {
if (m_pWindowOwner)
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale);
if (!m_pWindowOwner.expired())
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner.lock()->m_pWLSurface.m_fLastScale);
else if (m_pLayerOwner)
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale);
else

View file

@ -9,7 +9,7 @@ struct SLayerSurface;
class CPopup {
public:
// dummy head nodes
CPopup(CWindow* pOwner);
CPopup(PHLWINDOW pOwner);
CPopup(SLayerSurface* pOwner);
// real nodes
@ -35,8 +35,8 @@ class CPopup {
private:
// T1 owners, each popup has to have one of these
CWindow* m_pWindowOwner = nullptr;
SLayerSurface* m_pLayerOwner = nullptr;
PHLWINDOWREF m_pWindowOwner;
SLayerSurface* m_pLayerOwner = nullptr;
// T2 owners
CPopup* m_pParent = nullptr;

View file

@ -5,7 +5,7 @@
static void onNewSubsurface(void* owner, void* data);
CSubsurface::CSubsurface(CWindow* pOwner) : m_pWindowParent(pOwner) {
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
initSignals();
initExistingSubsurfaces(pOwner->m_pWLSurface.wlr());
}
@ -15,7 +15,7 @@ CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
initExistingSubsurfaces(pOwner->m_sWLSurface.wlr());
}
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface, this);
initSignals();
initExistingSubsurfaces(pSubsurface->surface);
@ -73,8 +73,8 @@ void CSubsurface::initSignals() {
hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface");
hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
} else {
if (m_pWindowParent)
hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
if (!m_pWindowParent.expired())
hyprListener_newSubsurface.initCallback(&m_pWindowParent.lock()->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
else if (m_pPopupParent)
hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
else
@ -86,7 +86,7 @@ void CSubsurface::checkSiblingDamage() {
if (!m_pParent)
return; // ??????????
const double SCALE = m_pWindowParent && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
const double SCALE = m_pWindowParent.lock() && m_pWindowParent.lock()->m_bIsX11 ? 1.0 / m_pWindowParent.lock()->m_fX11SurfaceScaledBy : 1.0;
for (auto& n : m_pParent->m_vChildren) {
if (n.get() == this)
@ -106,12 +106,12 @@ void CSubsurface::recheckDamageForSubsurfaces() {
void CSubsurface::onCommit() {
// no damaging if it's not visible
if (m_pWindowParent && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) {
if (!m_pWindowParent.expired() && (!m_pWindowParent.lock()->m_bIsMapped || !m_pWindowParent.lock()->m_pWorkspace->m_bVisible)) {
m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
if (*PLOGDAMAGE)
Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowParent);
Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowParent.lock());
return;
}
@ -121,8 +121,8 @@ void CSubsurface::onCommit() {
if (m_pPopupParent)
m_pPopupParent->recheckTree();
if (m_pWindowParent) // I hate you firefox why are you doing this
m_pWindowParent->m_pPopupHead->recheckTree();
if (!m_pWindowParent.expired()) // I hate you firefox why are you doing this
m_pWindowParent.lock()->m_pPopupHead->recheckTree();
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage();
@ -152,8 +152,8 @@ void CSubsurface::onDestroy() {
void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) {
CSubsurface* PSUBSURFACE = nullptr;
if (m_pWindowParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent)).get();
if (!m_pWindowParent.expired())
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
else if (m_pPopupParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
PSUBSURFACE->m_pParent = this;
@ -169,8 +169,8 @@ void CSubsurface::onMap() {
box.expand(4);
g_pHyprRenderer->damageBox(&box);
if (m_pWindowParent)
m_pWindowParent->updateSurfaceScaleTransformDetails();
if (!m_pWindowParent.expired())
m_pWindowParent.lock()->updateSurfaceScaleTransformDetails();
}
void CSubsurface::onUnmap() {
@ -206,8 +206,8 @@ Vector2D CSubsurface::coordsRelativeToParent() {
Vector2D CSubsurface::coordsGlobal() {
Vector2D coords = coordsRelativeToParent();
if (m_pWindowParent)
coords += m_pWindowParent->m_vRealPosition.value();
if (!m_pWindowParent.expired())
coords += m_pWindowParent.lock()->m_vRealPosition.value();
else if (m_pPopupParent)
coords += m_pPopupParent->coordsGlobal();

View file

@ -4,17 +4,16 @@
#include <vector>
#include "WLSurface.hpp"
class CWindow;
class CPopup;
class CSubsurface {
public:
// root dummy nodes
CSubsurface(CWindow* pOwner);
CSubsurface(PHLWINDOW pOwner);
CSubsurface(CPopup* pOwner);
// real nodes
CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner);
CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner);
CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner);
~CSubsurface();
@ -46,8 +45,8 @@ class CSubsurface {
// if nullptr, means it's a dummy node
CSubsurface* m_pParent = nullptr;
CWindow* m_pWindowParent = nullptr;
CPopup* m_pPopupParent = nullptr;
PHLWINDOWREF m_pWindowParent;
CPopup* m_pPopupParent = nullptr;
std::vector<std::unique_ptr<CSubsurface>> m_vChildren;

View file

@ -7,7 +7,7 @@ void CWLSurface::assign(wlr_surface* pSurface) {
m_bInert = false;
}
void CWLSurface::assign(wlr_surface* pSurface, CWindow* pOwner) {
void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) {
m_pWindowOwner = pOwner;
m_pWLRSurface = pSurface;
init();
@ -52,20 +52,22 @@ wlr_surface* CWLSurface::wlr() const {
}
bool CWLSurface::small() const {
if (!m_pWindowOwner || !exists())
if (!validMapped(m_pWindowOwner) || !exists())
return false;
return m_pWindowOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pWindowOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1;
const auto O = m_pWindowOwner.lock();
return O->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || O->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1;
}
Vector2D CWLSurface::correctSmallVec() const {
if (!m_pWindowOwner || !exists() || !small() || m_bFillIgnoreSmall)
if (!validMapped(m_pWindowOwner) || !exists() || !small() || m_bFillIgnoreSmall)
return {};
const auto SIZE = getViewporterCorrectedSize();
const auto O = m_pWindowOwner.lock();
return Vector2D{(m_pWindowOwner->m_vReportedSize.x - SIZE.x) / 2, (m_pWindowOwner->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) *
(m_pWindowOwner->m_vRealSize.value() / m_pWindowOwner->m_vReportedSize);
return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize.value() / O->m_vReportedSize);
}
Vector2D CWLSurface::getViewporterCorrectedSize() const {
@ -110,11 +112,11 @@ void CWLSurface::destroy() {
hyprListener_destroy.removeCallback();
hyprListener_commit.removeCallback();
m_pWLRSurface->data = nullptr;
m_pWindowOwner = nullptr;
m_pLayerOwner = nullptr;
m_pPopupOwner = nullptr;
m_pSubsurfaceOwner = nullptr;
m_bInert = true;
m_pWindowOwner.reset();
m_pLayerOwner = nullptr;
m_pPopupOwner = nullptr;
m_pSubsurfaceOwner = nullptr;
m_bInert = true;
if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface)
g_pCompositor->m_pLastFocus = nullptr;
@ -148,8 +150,8 @@ void CWLSurface::init() {
Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this);
}
CWindow* CWLSurface::getWindow() {
return m_pWindowOwner;
PHLWINDOW CWLSurface::getWindow() {
return m_pWindowOwner.lock();
}
SLayerSurface* CWLSurface::getLayer() {
@ -165,15 +167,15 @@ CSubsurface* CWLSurface::getSubsurface() {
}
bool CWLSurface::desktopComponent() {
return m_pLayerOwner || m_pWindowOwner || m_pSubsurfaceOwner || m_pPopupOwner;
return m_pLayerOwner || !m_pWindowOwner.expired() || m_pSubsurfaceOwner || m_pPopupOwner;
}
std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() {
if (!desktopComponent())
return {};
if (m_pWindowOwner)
return m_pWindowOwner->getWindowMainSurfaceBox();
if (!m_pWindowOwner.expired())
return m_pWindowOwner.lock()->getWindowMainSurfaceBox();
if (m_pLayerOwner)
return m_pLayerOwner->geometry;
if (m_pPopupOwner)

View file

@ -17,7 +17,7 @@ class CWLSurface {
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
void assign(wlr_surface* pSurface);
void assign(wlr_surface* pSurface, CWindow* pOwner);
void assign(wlr_surface* pSurface, PHLWINDOW pOwner);
void assign(wlr_surface* pSurface, SLayerSurface* pOwner);
void assign(wlr_surface* pSurface, CSubsurface* pOwner);
void assign(wlr_surface* pSurface, CPopup* pOwner);
@ -37,7 +37,7 @@ class CWLSurface {
void onCommit();
// getters for owners.
CWindow* getWindow();
PHLWINDOW getWindow();
SLayerSurface* getLayer();
CPopup* getPopup();
CSubsurface* getSubsurface();
@ -94,7 +94,7 @@ class CWLSurface {
wlr_surface* m_pWLRSurface = nullptr;
CWindow* m_pWindowOwner = nullptr;
PHLWINDOWREF m_pWindowOwner;
SLayerSurface* m_pLayerOwner = nullptr;
CPopup* m_pPopupOwner = nullptr;
CSubsurface* m_pSubsurfaceOwner = nullptr;

View file

@ -7,24 +7,34 @@
#include <any>
#include "../managers/TokenManager.hpp"
CWindow::CWindow() {
m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE);
m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), this, AVARDAMAGE_ENTIRE);
m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), this, AVARDAMAGE_BORDER);
m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), this, AVARDAMAGE_BORDER);
m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), this, AVARDAMAGE_ENTIRE);
m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), this, AVARDAMAGE_ENTIRE);
m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), this, AVARDAMAGE_SHADOW);
m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), this, AVARDAMAGE_ENTIRE);
PHLWINDOW CWindow::create() {
PHLWINDOW pWindow = std::shared_ptr<CWindow>(new CWindow);
addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(this));
addWindowDeco(std::make_unique<CHyprBorderDecoration>(this));
pWindow->m_pSelf = pWindow;
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER);
pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER);
pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
return pWindow;
}
CWindow::CWindow() {
;
}
CWindow::~CWindow() {
if (g_pCompositor->isWindowActive(this)) {
g_pCompositor->m_pLastFocus = nullptr;
g_pCompositor->m_pLastWindow = nullptr;
if (g_pCompositor->m_pLastWindow.lock().get() == this) {
g_pCompositor->m_pLastFocus = nullptr;
g_pCompositor->m_pLastWindow.reset();
}
events.destroy.emit();
@ -33,7 +43,7 @@ CWindow::~CWindow() {
return;
g_pHyprRenderer->makeEGLCurrent();
std::erase_if(g_pHyprOpenGL->m_mWindowFramebuffers, [&](const auto& other) { return other.first == this; });
std::erase_if(g_pHyprOpenGL->m_mWindowFramebuffers, [&](const auto& other) { return !other.first.lock() || other.first.lock().get() == this; });
}
SWindowDecorationExtents CWindow::getFullWindowExtents() {
@ -50,7 +60,7 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(this);
const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock());
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
maxExtents.topLeft.x = EXTENTS.topLeft.x;
@ -153,11 +163,11 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) {
SWindowDecorationExtents EXTENTS = {{0, 0}, {0, 0}};
if (properties & RESERVED_EXTENTS)
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationReserved(this));
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock()));
if (properties & INPUT_EXTENTS)
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, true));
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), true));
if (properties & FULL_EXTENTS)
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, false));
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), false));
CBox box = {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
box.addExtents(EXTENTS);
@ -170,7 +180,7 @@ CBox CWindow::getWindowMainSurfaceBox() {
}
SWindowDecorationExtents CWindow::getFullWindowReservedArea() {
return g_pDecorationPositioner->getWindowDecorationReserved(this);
return g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock());
}
void CWindow::updateWindowDecos() {
@ -191,10 +201,10 @@ void CWindow::updateWindowDecos() {
}
}
g_pDecorationPositioner->onWindowUpdate(this);
g_pDecorationPositioner->onWindowUpdate(m_pSelf.lock());
if (recalc)
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock());
m_vDecosToRemove.clear();
@ -206,22 +216,22 @@ void CWindow::updateWindowDecos() {
}
for (auto& wd : decos) {
wd->updateWindow(this);
wd->updateWindow(m_pSelf.lock());
}
}
void CWindow::addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco) {
m_dWindowDecorations.emplace_back(std::move(deco));
g_pDecorationPositioner->forceRecalcFor(this);
g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock());
updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock());
}
void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) {
m_vDecosToRemove.push_back(deco);
g_pDecorationPositioner->forceRecalcFor(this);
g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock());
updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
g_pLayoutManager->getCurrentLayout()->recalculateWindow(m_pSelf.lock());
}
void CWindow::uncacheWindowDecos() {
@ -335,7 +345,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
if (*PINITIALWSTRACKING == 2) {
// persistent
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data);
if (token.primaryOwner == this) {
if (token.primaryOwner.lock().get() == this) {
token.workspace = pWorkspace->getConfigName();
TOKEN->data = token;
}
@ -364,16 +374,16 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
if (valid(pWorkspace)) {
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, pWorkspace->m_szName)});
g_pEventManager->postEvent(SHyprIPCEvent{"movewindowv2", std::format("{:x},{},{}", (uintptr_t)this, pWorkspace->m_iID, pWorkspace->m_szName)});
EMIT_HOOK_EVENT("moveWindow", (std::vector<std::any>{this, pWorkspace}));
EMIT_HOOK_EVENT("moveWindow", (std::vector<std::any>{m_pSelf.lock(), pWorkspace}));
}
if (m_pSwallowed) {
m_pSwallowed->moveToWorkspace(pWorkspace);
m_pSwallowed->m_iMonitorID = m_iMonitorID;
if (const auto SWALLOWED = m_pSwallowed.lock()) {
SWALLOWED->moveToWorkspace(pWorkspace);
SWALLOWED->m_iMonitorID = m_iMonitorID;
}
// update xwayland coords
g_pXWaylandManager->setWindowSize(this, m_vRealSize.value());
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.value());
if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE->m_iID) == 0 && *PCLOSEONLASTSPECIAL) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID); PMONITOR)
@ -381,7 +391,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
}
}
CWindow* CWindow::X11TransientFor() {
PHLWINDOW CWindow::X11TransientFor() {
if (!m_bIsX11)
return nullptr;
@ -390,11 +400,11 @@ CWindow* CWindow::X11TransientFor() {
auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface);
while (g_pCompositor->windowValidMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) {
while (validMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) {
PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface);
}
if (!g_pCompositor->windowValidMapped(PPARENT))
if (!validMapped(PPARENT))
return nullptr;
return PPARENT;
@ -416,10 +426,10 @@ void unregisterVar(void* ptr) {
void CWindow::onUnmap() {
static auto PCLOSEONLASTSPECIAL = CConfigValue<Hyprlang::INT>("misc:close_special_on_empty");
if (g_pCompositor->m_pLastWindow == this)
g_pCompositor->m_pLastWindow = nullptr;
if (g_pInputManager->currentlyDraggedWindow == this)
g_pInputManager->currentlyDraggedWindow = nullptr;
if (g_pCompositor->m_pLastWindow.lock().get() == this)
g_pCompositor->m_pLastWindow.reset();
if (g_pInputManager->currentlyDraggedWindow.lock().get() == this)
g_pInputManager->currentlyDraggedWindow.reset();
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
@ -429,7 +439,7 @@ void CWindow::onUnmap() {
if (*PINITIALWSTRACKING == 2) {
// persistent token, but the first window got removed so the token is gone
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data);
if (token.primaryOwner == this)
if (token.primaryOwner.lock().get() == this)
g_pTokenManager->removeToken(TOKEN);
}
}
@ -448,7 +458,7 @@ void CWindow::onUnmap() {
m_vRealSize.setCallbackOnBegin(nullptr);
std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other == this; });
std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; });
hyprListener_unmapWindow.removeCallback();
@ -460,8 +470,8 @@ void CWindow::onUnmap() {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient == this)
PMONITOR->solitaryClient = nullptr;
if (PMONITOR && PMONITOR->solitaryClient.lock().get() == this)
PMONITOR->solitaryClient.reset();
g_pCompositor->updateWorkspaceWindows(workspaceID());
g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID());
@ -502,7 +512,7 @@ void CWindow::onMap() {
m_fBorderAngleAnimationProgress.setValueAndWarp(0.f);
m_fBorderAngleAnimationProgress = 1.f;
g_pCompositor->m_vWindowFocusHistory.push_back(this);
g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf);
hyprListener_unmapWindow.initCallback(m_bIsX11 ? &m_uSurface.xwayland->surface->events.unmap : &m_uSurface.xdg->surface->events.unmap, &Events::listener_unmapWindow, this,
"CWindow");
@ -513,8 +523,8 @@ void CWindow::onMap() {
if (m_bIsX11)
return;
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
m_pPopupHead = std::make_unique<CPopup>(this);
m_pSubsurfaceHead = std::make_unique<CSubsurface>(m_pSelf.lock());
m_pPopupHead = std::make_unique<CPopup>(m_pSelf.lock());
}
void CWindow::onBorderAngleAnimEnd(void* ptr) {
@ -536,8 +546,8 @@ void CWindow::onBorderAngleAnimEnd(void* ptr) {
void CWindow::setHidden(bool hidden) {
m_bHidden = hidden;
if (hidden && g_pCompositor->m_pLastWindow == this) {
g_pCompositor->m_pLastWindow = nullptr;
if (hidden && g_pCompositor->m_pLastWindow.lock().get() == this) {
g_pCompositor->m_pLastWindow.reset();
}
setSuspended(hidden);
@ -696,7 +706,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
m_sAdditionalConfigData.maxSize = VEC;
m_vRealSize = Vector2D(std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().x, m_vRealSize.goal().x),
std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule.starts_with("minsize")) {
@ -712,7 +722,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
m_sAdditionalConfigData.minSize = VEC;
m_vRealSize = Vector2D(std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().x, m_vRealSize.goal().x),
std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
}
@ -743,7 +753,7 @@ void CWindow::updateDynamicRules() {
m_sAdditionalConfigData.nearestNeighbor = false;
m_eIdleInhibitMode = IDLEINHIBIT_NONE;
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this);
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(m_pSelf.lock());
for (auto& r : WINDOWRULES) {
applyDynamicRule(r);
}
@ -807,7 +817,7 @@ void CWindow::applyGroupRules() {
if ((m_eGroupRules & GROUP_SET && m_bFirstMap) || m_eGroupRules & GROUP_SET_ALWAYS)
createGroup();
if (m_sGroupData.pNextWindow && ((m_eGroupRules & GROUP_LOCK && m_bFirstMap) || m_eGroupRules & GROUP_LOCK_ALWAYS))
if (m_sGroupData.pNextWindow.lock() && ((m_eGroupRules & GROUP_LOCK && m_bFirstMap) || m_eGroupRules & GROUP_LOCK_ALWAYS))
getGroupHead()->m_sGroupData.locked = true;
}
@ -817,13 +827,13 @@ void CWindow::createGroup() {
return;
}
if (!m_sGroupData.pNextWindow) {
m_sGroupData.pNextWindow = this;
if (m_sGroupData.pNextWindow.expired()) {
m_sGroupData.pNextWindow = m_pSelf;
m_sGroupData.head = true;
m_sGroupData.locked = false;
m_sGroupData.deny = false;
addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(this));
addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(m_pSelf.lock()));
g_pCompositor->updateWorkspaceWindows(workspaceID());
g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID());
@ -833,13 +843,13 @@ void CWindow::createGroup() {
}
void CWindow::destroyGroup() {
if (m_sGroupData.pNextWindow == this) {
if (m_sGroupData.pNextWindow.lock().get() == this) {
if (m_eGroupRules & GROUP_SET_ALWAYS) {
Debug::log(LOG, "destoryGroup: window:{:x},title:{} has rule [group set always], ignored", (uintptr_t)this, this->m_szTitle);
return;
}
m_sGroupData.pNextWindow = nullptr;
m_sGroupData.head = false;
m_sGroupData.pNextWindow.reset();
m_sGroupData.head = false;
updateWindowDecos();
g_pCompositor->updateWorkspaceWindows(workspaceID());
g_pCompositor->updateWorkspaceSpecialRenderData(workspaceID());
@ -848,15 +858,15 @@ void CWindow::destroyGroup() {
return;
}
CWindow* curr = this;
std::vector<CWindow*> members;
PHLWINDOW curr = m_pSelf.lock();
std::vector<PHLWINDOW> members;
do {
const auto PLASTWIN = curr;
curr = curr->m_sGroupData.pNextWindow;
PLASTWIN->m_sGroupData.pNextWindow = nullptr;
const auto PLASTWIN = curr;
curr = curr->m_sGroupData.pNextWindow.lock();
PLASTWIN->m_sGroupData.pNextWindow.reset();
curr->setHidden(false);
members.push_back(curr);
} while (curr != this);
} while (curr.get() != this);
for (auto& w : members) {
if (w->m_sGroupData.head)
@ -878,69 +888,69 @@ void CWindow::destroyGroup() {
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
}
CWindow* CWindow::getGroupHead() {
CWindow* curr = this;
PHLWINDOW CWindow::getGroupHead() {
PHLWINDOW curr = m_pSelf.lock();
while (!curr->m_sGroupData.head)
curr = curr->m_sGroupData.pNextWindow;
curr = curr->m_sGroupData.pNextWindow.lock();
return curr;
}
CWindow* CWindow::getGroupTail() {
CWindow* curr = this;
while (!curr->m_sGroupData.pNextWindow->m_sGroupData.head)
curr = curr->m_sGroupData.pNextWindow;
PHLWINDOW CWindow::getGroupTail() {
PHLWINDOW curr = m_pSelf.lock();
while (!curr->m_sGroupData.pNextWindow.lock()->m_sGroupData.head)
curr = curr->m_sGroupData.pNextWindow.lock();
return curr;
}
CWindow* CWindow::getGroupCurrent() {
CWindow* curr = this;
PHLWINDOW CWindow::getGroupCurrent() {
PHLWINDOW curr = m_pSelf.lock();
while (curr->isHidden())
curr = curr->m_sGroupData.pNextWindow;
curr = curr->m_sGroupData.pNextWindow.lock();
return curr;
}
int CWindow::getGroupSize() {
int size = 1;
CWindow* curr = this;
while (curr->m_sGroupData.pNextWindow != this) {
curr = curr->m_sGroupData.pNextWindow;
int size = 1;
PHLWINDOW curr = m_pSelf.lock();
while (curr->m_sGroupData.pNextWindow.lock().get() != this) {
curr = curr->m_sGroupData.pNextWindow.lock();
size++;
}
return size;
}
bool CWindow::canBeGroupedInto(CWindow* pWindow) {
return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
&& ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or
|| (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked
&& !(m_sGroupData.pNextWindow && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group
&& !m_sGroupData.deny // source is not denied entry
&& !(m_eGroupRules & GROUP_BARRED && m_bFirstMap); // group rule doesn't prevent adding window
bool CWindow::canBeGroupedInto(PHLWINDOW pWindow) {
return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
&& ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or
|| (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked
&& !(m_sGroupData.pNextWindow.lock() && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group
&& !m_sGroupData.deny // source is not denied entry
&& !(m_eGroupRules & GROUP_BARRED && m_bFirstMap); // group rule doesn't prevent adding window
}
CWindow* CWindow::getGroupWindowByIndex(int index) {
PHLWINDOW CWindow::getGroupWindowByIndex(int index) {
const int SIZE = getGroupSize();
index = ((index % SIZE) + SIZE) % SIZE;
CWindow* curr = getGroupHead();
PHLWINDOW curr = getGroupHead();
while (index > 0) {
curr = curr->m_sGroupData.pNextWindow;
curr = curr->m_sGroupData.pNextWindow.lock();
index--;
}
return curr;
}
void CWindow::setGroupCurrent(CWindow* pWindow) {
CWindow* curr = this->m_sGroupData.pNextWindow;
bool isMember = false;
while (curr != this) {
void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
PHLWINDOW curr = m_sGroupData.pNextWindow.lock();
bool isMember = false;
while (curr.get() != this) {
if (curr == pWindow) {
isMember = true;
break;
}
curr = curr->m_sGroupData.pNextWindow;
curr = curr->m_sGroupData.pNextWindow.lock();
}
if (!isMember && pWindow != this)
if (!isMember && pWindow.get() != this)
return;
const auto PCURRENT = getGroupCurrent();
@ -950,7 +960,7 @@ void CWindow::setGroupCurrent(CWindow* pWindow) {
const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal();
const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal();
const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow;
const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow.lock();
if (FULLSCREEN)
g_pCompositor->setWindowFullscreen(PCURRENT, false, WORKSPACE->m_efFullscreenMode);
@ -978,14 +988,14 @@ void CWindow::setGroupCurrent(CWindow* pWindow) {
pWindow->updateWindowDecos();
}
void CWindow::insertWindowToGroup(CWindow* pWindow) {
const auto BEGINAT = this;
const auto ENDAT = m_sGroupData.pNextWindow;
void CWindow::insertWindowToGroup(PHLWINDOW pWindow) {
const auto BEGINAT = m_pSelf.lock();
const auto ENDAT = m_sGroupData.pNextWindow.lock();
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
if (!pWindow->m_sGroupData.pNextWindow) {
if (!pWindow->m_sGroupData.pNextWindow.lock()) {
BEGINAT->m_sGroupData.pNextWindow = pWindow;
pWindow->m_sGroupData.pNextWindow = ENDAT;
pWindow->m_sGroupData.head = false;
@ -1000,26 +1010,26 @@ void CWindow::insertWindowToGroup(CWindow* pWindow) {
STAIL->m_sGroupData.pNextWindow = ENDAT;
}
CWindow* CWindow::getGroupPrevious() {
CWindow* curr = m_sGroupData.pNextWindow;
PHLWINDOW CWindow::getGroupPrevious() {
PHLWINDOW curr = m_sGroupData.pNextWindow.lock();
while (curr != this && curr->m_sGroupData.pNextWindow != this)
curr = curr->m_sGroupData.pNextWindow;
while (curr != m_pSelf.lock() && curr->m_sGroupData.pNextWindow.lock().get() != this)
curr = curr->m_sGroupData.pNextWindow.lock();
return curr;
}
void CWindow::switchWithWindowInGroup(CWindow* pWindow) {
if (!m_sGroupData.pNextWindow || !pWindow->m_sGroupData.pNextWindow)
void CWindow::switchWithWindowInGroup(PHLWINDOW pWindow) {
if (!m_sGroupData.pNextWindow.lock() || !pWindow->m_sGroupData.pNextWindow.lock())
return;
if (m_sGroupData.pNextWindow == pWindow) { // A -> this -> pWindow -> B >> A -> pWindow -> this -> B
if (m_sGroupData.pNextWindow.lock() == pWindow) { // A -> this -> pWindow -> B >> A -> pWindow -> this -> B
getGroupPrevious()->m_sGroupData.pNextWindow = pWindow;
m_sGroupData.pNextWindow = pWindow->m_sGroupData.pNextWindow;
pWindow->m_sGroupData.pNextWindow = this;
pWindow->m_sGroupData.pNextWindow = m_pSelf;
} else if (pWindow->m_sGroupData.pNextWindow == this) { // A -> pWindow -> this -> B >> A -> this -> pWindow -> B
pWindow->getGroupPrevious()->m_sGroupData.pNextWindow = this;
} else if (pWindow->m_sGroupData.pNextWindow.lock().get() == this) { // A -> pWindow -> this -> B >> A -> this -> pWindow -> B
pWindow->getGroupPrevious()->m_sGroupData.pNextWindow = m_pSelf;
pWindow->m_sGroupData.pNextWindow = m_sGroupData.pNextWindow;
m_sGroupData.pNextWindow = pWindow;
@ -1033,21 +1043,21 @@ void CWindow::switchWithWindowInGroup(CWindow* pWindow) {
}
void CWindow::updateGroupOutputs() {
if (!m_sGroupData.pNextWindow)
if (m_sGroupData.pNextWindow.expired())
return;
CWindow* curr = m_sGroupData.pNextWindow;
PHLWINDOW curr = m_sGroupData.pNextWindow.lock();
const auto WS = m_pWorkspace;
while (curr != this) {
while (curr.get() != this) {
curr->m_iMonitorID = m_iMonitorID;
curr->moveToWorkspace(WS);
curr->m_vRealPosition = m_vRealPosition.goal();
curr->m_vRealSize = m_vRealSize.goal();
curr = curr->m_sGroupData.pNextWindow;
curr = curr->m_sGroupData.pNextWindow.lock();
}
}
@ -1258,7 +1268,7 @@ void CWindow::activate() {
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)this)});
EMIT_HOOK_EVENT("urgent", this);
EMIT_HOOK_EVENT("urgent", m_pSelf.lock());
m_bIsUrgent = true;
@ -1266,8 +1276,8 @@ void CWindow::activate() {
return;
if (m_bIsFloating)
g_pCompositor->changeWindowZOrder(this, true);
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);
g_pCompositor->focusWindow(this);
g_pCompositor->focusWindow(m_pSelf.lock());
g_pCompositor->warpCursorTo(middle());
}

View file

@ -14,8 +14,6 @@
#include "DesktopTypes.hpp"
#include "../helpers/signal/Signal.hpp"
class CWindow;
enum eIdleInhibitMode {
IDLEINHIBIT_NONE = 0,
IDLEINHIBIT_ALWAYS,
@ -191,13 +189,18 @@ struct SWindowRule {
};
struct SInitialWorkspaceToken {
CWindow* primaryOwner = nullptr;
std::string workspace;
PHLWINDOWREF primaryOwner;
std::string workspace;
};
class CWindow {
public:
static PHLWINDOW create();
private:
CWindow();
public:
~CWindow();
DYNLISTENER(commitWindow);
@ -279,13 +282,13 @@ class CWindow {
bool m_bCreatedOverFullscreen = false;
// XWayland stuff
bool m_bIsX11 = false;
CWindow* m_pX11Parent = nullptr;
uint64_t m_iX11Type = 0;
bool m_bIsModal = false;
bool m_bX11DoesntWantBorders = false;
bool m_bX11ShouldntFocus = false;
float m_fX11SurfaceScaledBy = 1.f;
bool m_bIsX11 = false;
PHLWINDOWREF m_pX11Parent;
uint64_t m_iX11Type = 0;
bool m_bIsModal = false;
bool m_bX11DoesntWantBorders = false;
bool m_bX11ShouldntFocus = false;
float m_fX11SurfaceScaledBy = 1.f;
//
// For nofocus
@ -326,7 +329,7 @@ class CWindow {
bool m_bFakeFullscreenState = false;
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
CWindow* m_pLastCycledWindow = nullptr;
PHLWINDOWREF m_pLastCycledWindow;
// Window decorations
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
@ -349,7 +352,7 @@ class CWindow {
CAnimatedVariable<float> m_fDimPercent;
// swallowing
CWindow* m_pSwallowed = nullptr;
PHLWINDOWREF m_pSwallowed;
// focus stuff
bool m_bStayFocused = false;
@ -366,10 +369,10 @@ class CWindow {
// for groups
struct SGroupData {
CWindow* pNextWindow = nullptr; // nullptr means no grouping. Self means single group.
bool head = false;
bool locked = false; // per group lock
bool deny = false; // deny window from enter a group or made a group
PHLWINDOWREF pNextWindow; // nullptr means no grouping. Self means single group.
bool head = false;
bool locked = false; // per group lock
bool deny = false; // deny window from enter a group or made a group
} m_sGroupData;
uint16_t m_eGroupRules = GROUP_NONE;
@ -398,7 +401,7 @@ class CWindow {
void updateToplevel();
void updateSurfaceScaleTransformDetails();
void moveToWorkspace(PHLWORKSPACE);
CWindow* X11TransientFor();
PHLWINDOW X11TransientFor();
void onUnmap();
void onMap();
void setHidden(bool hidden);
@ -429,23 +432,26 @@ class CWindow {
void applyGroupRules();
void createGroup();
void destroyGroup();
CWindow* getGroupHead();
CWindow* getGroupTail();
CWindow* getGroupCurrent();
CWindow* getGroupPrevious();
CWindow* getGroupWindowByIndex(int);
PHLWINDOW getGroupHead();
PHLWINDOW getGroupTail();
PHLWINDOW getGroupCurrent();
PHLWINDOW getGroupPrevious();
PHLWINDOW getGroupWindowByIndex(int);
int getGroupSize();
bool canBeGroupedInto(CWindow* pWindow);
void setGroupCurrent(CWindow* pWindow);
void insertWindowToGroup(CWindow* pWindow);
bool canBeGroupedInto(PHLWINDOW pWindow);
void setGroupCurrent(PHLWINDOW pWindow);
void insertWindowToGroup(PHLWINDOW pWindow);
void updateGroupOutputs();
void switchWithWindowInGroup(CWindow* pWindow);
void switchWithWindowInGroup(PHLWINDOW pWindow);
void setAnimationsToMove();
void onWorkspaceAnimUpdate();
//
std::unordered_map<std::string, std::string> getEnv();
//
PHLWINDOWREF m_pSelf;
private:
// For hidden windows and stuff
bool m_bHidden = false;
@ -453,6 +459,26 @@ class CWindow {
int m_iLastWorkspace = WORKSPACE_INVALID;
};
inline bool valid(PHLWINDOW w) {
return w.get();
}
inline bool valid(PHLWINDOWREF w) {
return w.lock().get();
}
inline bool validMapped(PHLWINDOW w) {
if (!valid(w))
return false;
return w->m_bIsMapped;
}
inline bool validMapped(PHLWINDOWREF w) {
if (!valid(w))
return false;
return w.lock()->m_bIsMapped;
}
/**
format specification
- 'x', only address, equivalent of (uintpr_t)CWindow*
@ -462,7 +488,7 @@ class CWindow {
*/
template <typename CharT>
struct std::formatter<CWindow*, CharT> : std::formatter<CharT> {
struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
bool formatAddressOnly = false;
bool formatWorkspace = false;
bool formatMonitor = false;
@ -472,18 +498,18 @@ struct std::formatter<CWindow*, CharT> : std::formatter<CharT> {
FORMAT_FLAG('m', formatMonitor) //
FORMAT_FLAG('w', formatWorkspace) //
FORMAT_FLAG('c', formatClass),
CWindow*)
PHLWINDOW)
template <typename FormatContext>
auto format(CWindow* const& w, FormatContext& ctx) const {
auto format(PHLWINDOW const& w, FormatContext& ctx) const {
auto&& out = ctx.out();
if (formatAddressOnly)
return std::format_to(out, "{:x}", (uintptr_t)w);
return std::format_to(out, "{:x}", (uintptr_t)w.get());
if (!w)
return std::format_to(out, "[Window nullptr]");
std::format_to(out, "[");
std::format_to(out, "Window {:x}: title: \"{}\"", (uintptr_t)w, w->m_szTitle);
std::format_to(out, "Window {:x}: title: \"{}\"", (uintptr_t)w.get(), w->m_szTitle);
if (formatWorkspace)
std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID);
if (formatMonitor)

View file

@ -33,10 +33,10 @@ void CWorkspace::init(PHLWORKSPACE self) {
m_szName = RULEFORTHIS.defaultName.value();
m_pFocusedWindowHook = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any param) {
const auto PWINDOW = std::any_cast<CWindow*>(param);
const auto PWINDOW = std::any_cast<PHLWINDOW>(param);
if (PWINDOW == m_pLastFocusedWindow)
m_pLastFocusedWindow = nullptr;
if (PWINDOW == m_pLastFocusedWindow.lock())
m_pLastFocusedWindow.reset();
});
m_bInert = false;
@ -75,7 +75,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
// set floating windows offset callbacks
m_vRenderOffset.setUpdateCallback([&](void*) {
for (auto& w : g_pCompositor->m_vWindows) {
if (!g_pCompositor->windowValidMapped(w.get()) || w->workspaceID() != m_iID)
if (!validMapped(w) || w->workspaceID() != m_iID)
continue;
w->onWorkspaceAnimUpdate();
@ -182,11 +182,11 @@ void CWorkspace::moveToMonitor(const int& id) {
; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40
}
CWindow* CWorkspace::getLastFocusedWindow() {
if (!g_pCompositor->windowValidMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow->workspaceID() != m_iID)
PHLWINDOW CWorkspace::getLastFocusedWindow() {
if (!validMapped(m_pLastFocusedWindow) || m_pLastFocusedWindow.lock()->workspaceID() != m_iID)
return nullptr;
return m_pLastFocusedWindow;
return m_pLastFocusedWindow.lock();
}
void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {

View file

@ -49,7 +49,7 @@ class CWorkspace {
bool m_bIsSpecialWorkspace = false;
// last window
CWindow* m_pLastFocusedWindow = nullptr;
PHLWINDOWREF m_pLastFocusedWindow;
// user-set
bool m_bDefaultFloating = false;
@ -68,7 +68,7 @@ class CWorkspace {
void moveToMonitor(const int&);
CWindow* getLastFocusedWindow();
PHLWINDOW getLastFocusedWindow();
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
std::string getConfigName();