mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-17 21:13:48 -07:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
eab2799842 | ||
|
6eb2abcb20 | ||
|
ae46fbafe5 | ||
|
52cf122a0a | ||
|
844da8db56 | ||
|
db82fc5b09 | ||
|
8180ca65a5 | ||
|
bea828ea45 | ||
|
c5d1faf72d | ||
|
cc04b52ce1 | ||
|
9b5e2e71e0 | ||
|
9be6fbf5ea | ||
|
7345b1a1ea | ||
|
e44d6de555 | ||
|
427153e86a | ||
|
1e6e9b66a5 | ||
|
92cb44ddb2 | ||
|
b8a615ffb8 | ||
|
8dd02eb5f3 | ||
|
14195835ef | ||
|
11432f69b9 | ||
|
da6fa9cbd2 | ||
|
c619e6976f |
8
flake.lock
generated
8
flake.lock
generated
@@ -67,18 +67,18 @@
|
|||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"lastModified": 1697909146,
|
"lastModified": 1699292815,
|
||||||
"narHash": "sha256-jU0I6FoCKnj4zIBL4daosFWh81U1fM719Z6cae8PxSY=",
|
"narHash": "sha256-HXu98PyBMKEWLqiTb8viuLDznud/SdkdJsx5A5CWx7I=",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
|
"rev": "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"host": "gitlab.freedesktop.org",
|
"host": "gitlab.freedesktop.org",
|
||||||
"owner": "wlroots",
|
"owner": "wlroots",
|
||||||
"repo": "wlroots",
|
"repo": "wlroots",
|
||||||
"rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
|
"rev": "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
host = "gitlab.freedesktop.org";
|
host = "gitlab.freedesktop.org";
|
||||||
owner = "wlroots";
|
owner = "wlroots";
|
||||||
repo = "wlroots";
|
repo = "wlroots";
|
||||||
rev = "47bf87ade2bd32395615a385ebde1fefbcdf79a2";
|
rev = "5de9e1a99d6642c2d09d589aa37ff0a8945dcee1";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -274,7 +274,6 @@ bool isNumber(const std::string& str, bool allowfloat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int bflag = 0, sflag = 0, index, c;
|
|
||||||
bool parseArgs = true;
|
bool parseArgs = true;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
@@ -288,7 +287,7 @@ int main(int argc, char** argv) {
|
|||||||
bool json = false;
|
bool json = false;
|
||||||
std::string overrideInstance = "";
|
std::string overrideInstance = "";
|
||||||
|
|
||||||
for (auto i = 0; i < ARGS.size(); ++i) {
|
for (std::size_t i = 0; i < ARGS.size(); ++i) {
|
||||||
if (ARGS[i] == "--") {
|
if (ARGS[i] == "--") {
|
||||||
// Stop parsing arguments after --
|
// Stop parsing arguments after --
|
||||||
parseArgs = false;
|
parseArgs = false;
|
||||||
@@ -342,7 +341,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
const auto INSTANCES = instances();
|
const auto INSTANCES = instances();
|
||||||
|
|
||||||
if (INSTANCENO < 0 || INSTANCENO >= INSTANCES.size()) {
|
if (INSTANCENO < 0 || static_cast<std::size_t>(INSTANCENO) >= INSTANCES.size()) {
|
||||||
std::cout << "no such instance\n";
|
std::cout << "no such instance\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "0.32.0"
|
"version": "0.32.2"
|
||||||
}
|
}
|
@@ -81,6 +81,7 @@ CCompositor::CCompositor() {
|
|||||||
|
|
||||||
CCompositor::~CCompositor() {
|
CCompositor::~CCompositor() {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
g_pDecorationPositioner.reset();
|
||||||
g_pPluginSystem.reset();
|
g_pPluginSystem.reset();
|
||||||
g_pHyprNotificationOverlay.reset();
|
g_pHyprNotificationOverlay.reset();
|
||||||
g_pDebugOverlay.reset();
|
g_pDebugOverlay.reset();
|
||||||
@@ -441,6 +442,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {
|
|||||||
Debug::log(LOG, "Creating the PluginSystem!");
|
Debug::log(LOG, "Creating the PluginSystem!");
|
||||||
g_pPluginSystem = std::make_unique<CPluginSystem>();
|
g_pPluginSystem = std::make_unique<CPluginSystem>();
|
||||||
g_pConfigManager->handlePluginLoads();
|
g_pConfigManager->handlePluginLoads();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Creating the DecorationPositioner!");
|
||||||
|
g_pDecorationPositioner = std::make_unique<CDecorationPositioner>();
|
||||||
} break;
|
} break;
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
@@ -1920,8 +1924,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
|||||||
pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow
|
pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& d : pWindow->m_dWindowDecorations)
|
pWindow->updateWindowDecos();
|
||||||
d->updateWindow(pWindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCompositor::getNextAvailableMonitorID(std::string const& name) {
|
int CCompositor::getNextAvailableMonitorID(std::string const& name) {
|
||||||
|
@@ -39,7 +39,11 @@ struct SWindowDecorationExtents {
|
|||||||
return SWindowDecorationExtents{topLeft * scale, bottomRight * scale};
|
return SWindowDecorationExtents{topLeft * scale, bottomRight * scale};
|
||||||
}
|
}
|
||||||
|
|
||||||
SWindowDecorationExtents floor() {
|
SWindowDecorationExtents round() {
|
||||||
return {topLeft.floor(), bottomRight.floor()};
|
return {topLeft.round(), bottomRight.round()};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const SWindowDecorationExtents& other) const {
|
||||||
|
return topLeft == other.topLeft && bottomRight == other.bottomRight;
|
||||||
}
|
}
|
||||||
};
|
};
|
@@ -13,7 +13,7 @@ CWindow::CWindow() {
|
|||||||
m_cRealShadowColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW);
|
m_cRealShadowColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW);
|
||||||
m_fDimPercent.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE);
|
m_fDimPercent.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE);
|
||||||
|
|
||||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow::~CWindow() {
|
CWindow::~CWindow() {
|
||||||
@@ -37,22 +37,19 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
|
|||||||
|
|
||||||
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
|
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(this);
|
||||||
|
|
||||||
const auto EXTENTS = wd->getWindowDecorationExtents();
|
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
|
||||||
|
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
||||||
|
|
||||||
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
|
if (EXTENTS.topLeft.y > maxExtents.topLeft.y)
|
||||||
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
||||||
|
|
||||||
if (EXTENTS.topLeft.y > maxExtents.topLeft.y)
|
if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x)
|
||||||
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
||||||
|
|
||||||
if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x)
|
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
||||||
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
||||||
|
|
||||||
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
|
||||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pWLSurface.exists() && !m_bIsX11) {
|
if (m_pWLSurface.exists() && !m_bIsX11) {
|
||||||
CBox surfaceExtents = {0, 0, 0, 0};
|
CBox surfaceExtents = {0, 0, 0, 0};
|
||||||
@@ -144,25 +141,19 @@ CBox CWindow::getWindowInputBox() {
|
|||||||
|
|
||||||
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
|
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(this, true);
|
||||||
|
|
||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
|
||||||
continue;
|
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
||||||
|
|
||||||
const auto EXTENTS = wd->getWindowDecorationExtents();
|
if (EXTENTS.topLeft.y > maxExtents.topLeft.y)
|
||||||
|
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
||||||
|
|
||||||
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
|
if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x)
|
||||||
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
||||||
|
|
||||||
if (EXTENTS.topLeft.y > maxExtents.topLeft.y)
|
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
||||||
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
||||||
|
|
||||||
if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x)
|
|
||||||
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
|
||||||
|
|
||||||
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
|
||||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add extents to the real base BB and return
|
// Add extents to the real base BB and return
|
||||||
CBox finalBox = {m_vRealPosition.vec().x - maxExtents.topLeft.x, m_vRealPosition.vec().y - maxExtents.topLeft.y,
|
CBox finalBox = {m_vRealPosition.vec().x - maxExtents.topLeft.x, m_vRealPosition.vec().y - maxExtents.topLeft.y,
|
||||||
@@ -176,30 +167,19 @@ CBox CWindow::getWindowMainSurfaceBox() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SWindowDecorationExtents CWindow::getFullWindowReservedArea() {
|
SWindowDecorationExtents CWindow::getFullWindowReservedArea() {
|
||||||
SWindowDecorationExtents extents;
|
return g_pDecorationPositioner->getWindowDecorationReserved(this);
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
|
||||||
const auto RESERVED = wd->getWindowDecorationReservedArea();
|
|
||||||
|
|
||||||
if (RESERVED.bottomRight == Vector2D{} && RESERVED.topLeft == Vector2D{})
|
|
||||||
continue;
|
|
||||||
|
|
||||||
extents.topLeft = extents.topLeft + RESERVED.topLeft;
|
|
||||||
extents.bottomRight = extents.bottomRight + RESERVED.bottomRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return extents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindow::updateWindowDecos() {
|
void CWindow::updateWindowDecos() {
|
||||||
for (auto& wd : m_dWindowDecorations)
|
|
||||||
wd->updateWindow(this);
|
|
||||||
|
|
||||||
bool recalc = false;
|
bool recalc = false;
|
||||||
|
|
||||||
|
if (!m_bIsMapped || isHidden())
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto& wd : m_vDecosToRemove) {
|
for (auto& wd : m_vDecosToRemove) {
|
||||||
for (auto it = m_dWindowDecorations.begin(); it != m_dWindowDecorations.end(); it++) {
|
for (auto it = m_dWindowDecorations.begin(); it != m_dWindowDecorations.end(); it++) {
|
||||||
if (it->get() == wd) {
|
if (it->get() == wd) {
|
||||||
|
g_pDecorationPositioner->uncacheDecoration(it->get());
|
||||||
it = m_dWindowDecorations.erase(it);
|
it = m_dWindowDecorations.erase(it);
|
||||||
recalc = true;
|
recalc = true;
|
||||||
if (it == m_dWindowDecorations.end())
|
if (it == m_dWindowDecorations.end())
|
||||||
@@ -208,10 +188,26 @@ void CWindow::updateWindowDecos() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_pDecorationPositioner->onWindowUpdate(this);
|
||||||
|
|
||||||
if (recalc)
|
if (recalc)
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
|
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
|
||||||
|
|
||||||
m_vDecosToRemove.clear();
|
m_vDecosToRemove.clear();
|
||||||
|
|
||||||
|
for (auto& wd : m_dWindowDecorations) {
|
||||||
|
wd->updateWindow(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindow::addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco) {
|
||||||
|
m_dWindowDecorations.emplace_back(std::move(deco));
|
||||||
|
updateWindowDecos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) {
|
||||||
|
m_vDecosToRemove.push_back(deco);
|
||||||
|
updateWindowDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t CWindow::getPID() {
|
pid_t CWindow::getPID() {
|
||||||
@@ -689,14 +685,14 @@ void CWindow::createGroup() {
|
|||||||
Debug::log(LOG, "createGroup: window:{:x},title:{} is denied as a group, ignored", (uintptr_t)this, this->m_szTitle);
|
Debug::log(LOG, "createGroup: window:{:x},title:{} is denied as a group, ignored", (uintptr_t)this, this->m_szTitle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_sGroupData.pNextWindow) {
|
if (!m_sGroupData.pNextWindow) {
|
||||||
m_sGroupData.pNextWindow = this;
|
m_sGroupData.pNextWindow = this;
|
||||||
m_sGroupData.head = true;
|
m_sGroupData.head = true;
|
||||||
m_sGroupData.locked = false;
|
m_sGroupData.locked = false;
|
||||||
m_sGroupData.deny = false;
|
m_sGroupData.deny = false;
|
||||||
|
|
||||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(this));
|
addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(this));
|
||||||
updateWindowDecos();
|
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
|
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
|
||||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||||
@@ -835,6 +831,8 @@ void CWindow::setGroupCurrent(CWindow* pWindow) {
|
|||||||
g_pCompositor->setWindowFullscreen(pWindow, true, WORKSPACE->m_efFullscreenMode);
|
g_pCompositor->setWindowFullscreen(pWindow, true, WORKSPACE->m_efFullscreenMode);
|
||||||
|
|
||||||
g_pHyprRenderer->damageWindow(pWindow);
|
g_pHyprRenderer->damageWindow(pWindow);
|
||||||
|
|
||||||
|
pWindow->updateWindowDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindow::insertWindowToGroup(CWindow* pWindow) {
|
void CWindow::insertWindowToGroup(CWindow* pWindow) {
|
||||||
@@ -842,7 +840,7 @@ void CWindow::insertWindowToGroup(CWindow* pWindow) {
|
|||||||
const auto ENDAT = m_sGroupData.pNextWindow;
|
const auto ENDAT = m_sGroupData.pNextWindow;
|
||||||
|
|
||||||
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||||
|
|
||||||
if (!pWindow->m_sGroupData.pNextWindow) {
|
if (!pWindow->m_sGroupData.pNextWindow) {
|
||||||
BEGINAT->m_sGroupData.pNextWindow = pWindow;
|
BEGINAT->m_sGroupData.pNextWindow = pWindow;
|
||||||
|
@@ -185,6 +185,7 @@ class CWindow {
|
|||||||
DYNLISTENER(setOverrideRedirect);
|
DYNLISTENER(setOverrideRedirect);
|
||||||
DYNLISTENER(associateX11);
|
DYNLISTENER(associateX11);
|
||||||
DYNLISTENER(dissociateX11);
|
DYNLISTENER(dissociateX11);
|
||||||
|
DYNLISTENER(ackConfigure);
|
||||||
// DYNLISTENER(newSubsurfaceWindow);
|
// DYNLISTENER(newSubsurfaceWindow);
|
||||||
|
|
||||||
CWLSurface m_pWLSurface;
|
CWLSurface m_pWLSurface;
|
||||||
@@ -204,9 +205,11 @@ class CWindow {
|
|||||||
CAnimatedVariable m_vRealSize;
|
CAnimatedVariable m_vRealSize;
|
||||||
|
|
||||||
// for not spamming the protocols
|
// for not spamming the protocols
|
||||||
Vector2D m_vReportedPosition;
|
Vector2D m_vReportedPosition;
|
||||||
Vector2D m_vReportedSize;
|
Vector2D m_vReportedSize;
|
||||||
Vector2D m_vPendingReportedSize;
|
Vector2D m_vPendingReportedSize;
|
||||||
|
std::optional<std::pair<uint32_t, Vector2D>> m_pPendingSizeAck;
|
||||||
|
std::vector<std::pair<uint32_t, Vector2D>> m_vPendingSizeAcks;
|
||||||
|
|
||||||
// for restoring floating statuses
|
// for restoring floating statuses
|
||||||
Vector2D m_vLastFloatingSize;
|
Vector2D m_vLastFloatingSize;
|
||||||
@@ -341,7 +344,9 @@ class CWindow {
|
|||||||
CBox getWindowInputBox();
|
CBox getWindowInputBox();
|
||||||
CBox getWindowMainSurfaceBox();
|
CBox getWindowMainSurfaceBox();
|
||||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
|
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
|
||||||
void updateWindowDecos();
|
void updateWindowDecos();
|
||||||
|
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||||
pid_t getPID();
|
pid_t getPID();
|
||||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||||
void removeDecorationByType(eDecorationType);
|
void removeDecorationByType(eDecorationType);
|
||||||
|
@@ -105,27 +105,20 @@ static std::string getGroupedData(CWindow* w, HyprCtl::eHyprCtlOutputFormat form
|
|||||||
if (!w->m_sGroupData.pNextWindow)
|
if (!w->m_sGroupData.pNextWindow)
|
||||||
return isJson ? "" : "0";
|
return isJson ? "" : "0";
|
||||||
|
|
||||||
std::vector<CWindow*> groupMembers;
|
|
||||||
|
|
||||||
CWindow* curr = w;
|
|
||||||
do {
|
|
||||||
groupMembers.push_back(curr);
|
|
||||||
curr = curr->m_sGroupData.pNextWindow;
|
|
||||||
} while (curr != w);
|
|
||||||
|
|
||||||
const auto comma = isJson ? ", " : ",";
|
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
|
|
||||||
bool first = true;
|
CWindow* head = w->getGroupHead();
|
||||||
for (auto& gw : groupMembers) {
|
CWindow* curr = head;
|
||||||
if (first)
|
while (true) {
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
result << comma;
|
|
||||||
if (isJson)
|
if (isJson)
|
||||||
result << std::format("\"0x{:x}\"", (uintptr_t)gw);
|
result << std::format("\"0x{:x}\"", (uintptr_t)curr);
|
||||||
else
|
else
|
||||||
result << std::format("{:x}", (uintptr_t)gw);
|
result << std::format("{:x}", (uintptr_t)curr);
|
||||||
|
curr = curr->m_sGroupData.pNextWindow;
|
||||||
|
// We've wrapped around to the start, break out without trailing comma
|
||||||
|
if (curr == head)
|
||||||
|
break;
|
||||||
|
result << (isJson ? ", " : ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.str();
|
return result.str();
|
||||||
|
@@ -62,6 +62,7 @@ namespace Events {
|
|||||||
DYNLISTENFUNC(setOverrideRedirect);
|
DYNLISTENFUNC(setOverrideRedirect);
|
||||||
DYNLISTENFUNC(associateX11);
|
DYNLISTENFUNC(associateX11);
|
||||||
DYNLISTENFUNC(dissociateX11);
|
DYNLISTENFUNC(dissociateX11);
|
||||||
|
DYNLISTENFUNC(ackConfigure);
|
||||||
|
|
||||||
// Window subsurfaces
|
// Window subsurfaces
|
||||||
// LISTENER(newSubsurfaceWindow);
|
// LISTENER(newSubsurfaceWindow);
|
||||||
|
@@ -504,6 +504,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->hyprListener_requestResize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_resize, &Events::listener_requestResize, PWINDOW, "XDG Window Late");
|
PWINDOW->hyprListener_requestResize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_resize, &Events::listener_requestResize, PWINDOW, "XDG Window Late");
|
||||||
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW,
|
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW,
|
||||||
"XDG Window Late");
|
"XDG Window Late");
|
||||||
|
PWINDOW->hyprListener_ackConfigure.initCallback(&PWINDOW->m_uSurface.xdg->events.ack_configure, &Events::listener_ackConfigure, PWINDOW, "XDG Window Late");
|
||||||
} else {
|
} else {
|
||||||
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW,
|
PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW,
|
||||||
"XWayland Window Late");
|
"XWayland Window Late");
|
||||||
@@ -667,6 +668,13 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||||
|
if (PMONITOR) {
|
||||||
|
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition;
|
||||||
|
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec();
|
||||||
|
PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents();
|
||||||
|
}
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", std::format("{:x}", PWINDOW)});
|
g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", std::format("{:x}", PWINDOW)});
|
||||||
EMIT_HOOK_EVENT("closeWindow", PWINDOW);
|
EMIT_HOOK_EVENT("closeWindow", PWINDOW);
|
||||||
|
|
||||||
@@ -682,6 +690,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->hyprListener_requestMove.removeCallback();
|
PWINDOW->hyprListener_requestMove.removeCallback();
|
||||||
PWINDOW->hyprListener_requestResize.removeCallback();
|
PWINDOW->hyprListener_requestResize.removeCallback();
|
||||||
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
||||||
|
PWINDOW->hyprListener_ackConfigure.removeCallback();
|
||||||
} else {
|
} else {
|
||||||
Debug::log(LOG, "Unregistered late callbacks XWL");
|
Debug::log(LOG, "Unregistered late callbacks XWL");
|
||||||
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
PWINDOW->hyprListener_fullscreenWindow.removeCallback();
|
||||||
@@ -695,13 +704,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||||||
if (PWINDOW->m_bIsFullscreen)
|
if (PWINDOW->m_bIsFullscreen)
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
|
||||||
if (PMONITOR) {
|
|
||||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition;
|
|
||||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec();
|
|
||||||
PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow the renderer to catch the last frame.
|
// Allow the renderer to catch the last frame.
|
||||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||||
|
|
||||||
@@ -788,13 +790,32 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||||||
PWINDOW->onUnmap();
|
PWINDOW->onUnmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::listener_ackConfigure(void* owner, void* data) {
|
||||||
|
CWindow* PWINDOW = (CWindow*)owner;
|
||||||
|
const auto E = (wlr_xdg_surface_configure*)data;
|
||||||
|
|
||||||
|
// find last matching serial
|
||||||
|
const auto SERIAL = std::find_if(PWINDOW->m_vPendingSizeAcks.rbegin(), PWINDOW->m_vPendingSizeAcks.rend(), [&](const auto& e) { return e.first == E->serial; });
|
||||||
|
|
||||||
|
if (SERIAL == PWINDOW->m_vPendingSizeAcks.rend())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PWINDOW->m_pPendingSizeAck = *SERIAL;
|
||||||
|
std::erase_if(PWINDOW->m_vPendingSizeAcks, [&](const auto& el) { return el.first == SERIAL->first; });
|
||||||
|
}
|
||||||
|
|
||||||
void Events::listener_commitWindow(void* owner, void* data) {
|
void Events::listener_commitWindow(void* owner, void* data) {
|
||||||
CWindow* PWINDOW = (CWindow*)owner;
|
CWindow* PWINDOW = (CWindow*)owner;
|
||||||
|
|
||||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->isHidden() || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
if (!PWINDOW->m_bMappedX11 || PWINDOW->isHidden() || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
|
if (PWINDOW->m_bIsX11)
|
||||||
|
PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
|
||||||
|
else if (PWINDOW->m_pPendingSizeAck.has_value()) {
|
||||||
|
PWINDOW->m_vReportedSize = PWINDOW->m_pPendingSizeAck->second;
|
||||||
|
PWINDOW->m_pPendingSizeAck.reset();
|
||||||
|
}
|
||||||
|
|
||||||
PWINDOW->updateSurfaceOutputs();
|
PWINDOW->updateSurfaceOutputs();
|
||||||
|
|
||||||
@@ -1038,8 +1059,11 @@ void Events::listener_configureX11(void* owner, void* data) {
|
|||||||
|
|
||||||
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
||||||
if (*PXWLFORCESCALEZERO) {
|
if (*PXWLFORCESCALEZERO) {
|
||||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR)
|
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
|
||||||
|
const Vector2D DELTA = PWINDOW->m_vRealSize.goalv() - PWINDOW->m_vRealSize.goalv() / PMONITOR->scale;
|
||||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
|
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
|
||||||
|
PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
|
||||||
@@ -1099,8 +1123,11 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
|||||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
|
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
|
||||||
|
|
||||||
if (*PXWLFORCESCALEZERO) {
|
if (*PXWLFORCESCALEZERO) {
|
||||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR)
|
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
|
||||||
|
const Vector2D DELTA = PWINDOW->m_vRealSize.goalv() - PWINDOW->m_vRealSize.goalv() / PMONITOR->scale;
|
||||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
|
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
|
||||||
|
PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv();
|
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv();
|
||||||
|
@@ -96,6 +96,15 @@ CBox& CBox::scaleFromCenter(double scale) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBox& CBox::expand(const double& value) {
|
||||||
|
x -= value;
|
||||||
|
y -= value;
|
||||||
|
w += value * 2.0;
|
||||||
|
h += value * 2.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);
|
||||||
@@ -110,3 +119,7 @@ Vector2D CBox::pos() const {
|
|||||||
Vector2D CBox::size() const {
|
Vector2D CBox::size() const {
|
||||||
return {w, h};
|
return {w, h};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents CBox::extentsFrom(const CBox& small) {
|
||||||
|
return {{small.x - x, small.y - y}, {w - small.w - (small.x - x), h - small.h - (small.y - y)}};
|
||||||
|
}
|
||||||
|
@@ -39,26 +39,29 @@ class CBox {
|
|||||||
h = size.y;
|
h = size.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_box wlr();
|
wlr_box wlr();
|
||||||
wlr_box* pWlr();
|
wlr_box* pWlr();
|
||||||
|
|
||||||
CBox& applyFromWlr();
|
CBox& applyFromWlr();
|
||||||
CBox& scale(double scale);
|
CBox& scale(double scale);
|
||||||
CBox& scaleFromCenter(double scale);
|
CBox& scaleFromCenter(double scale);
|
||||||
CBox& scale(const Vector2D& scale);
|
CBox& scale(const Vector2D& scale);
|
||||||
CBox& translate(const Vector2D& vec);
|
CBox& translate(const Vector2D& vec);
|
||||||
CBox& round();
|
CBox& round();
|
||||||
CBox& transform(const wl_output_transform t, double w, double h);
|
CBox& transform(const wl_output_transform t, double w, double h);
|
||||||
CBox& addExtents(const SWindowDecorationExtents& e);
|
CBox& addExtents(const SWindowDecorationExtents& e);
|
||||||
|
CBox& expand(const double& value);
|
||||||
|
|
||||||
Vector2D middle() const;
|
SWindowDecorationExtents extentsFrom(const CBox&); // this is the big box
|
||||||
Vector2D pos() const;
|
|
||||||
Vector2D size() const;
|
|
||||||
|
|
||||||
bool containsPoint(const Vector2D& vec) const;
|
Vector2D middle() const;
|
||||||
bool empty() const;
|
Vector2D pos() const;
|
||||||
|
Vector2D size() const;
|
||||||
|
|
||||||
double x = 0, y = 0;
|
bool containsPoint(const Vector2D& vec) const;
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
double x = 0, y = 0;
|
||||||
union {
|
union {
|
||||||
double w;
|
double w;
|
||||||
double width;
|
double width;
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
class CColor {
|
class CColor {
|
||||||
public:
|
public:
|
||||||
CColor();
|
CColor();
|
||||||
CColor(float, float, float, float);
|
CColor(float r, float g, float b, float a);
|
||||||
CColor(uint64_t);
|
CColor(uint64_t);
|
||||||
|
|
||||||
float r = 0, g = 0, b = 0, a = 1.f;
|
float r = 0, g = 0, b = 0, a = 1.f;
|
||||||
@@ -27,4 +27,8 @@ class CColor {
|
|||||||
bool operator==(const CColor& c2) const {
|
bool operator==(const CColor& c2) const {
|
||||||
return r == c2.r && g == c2.g && b == c2.b && a == c2.a;
|
return r == c2.r && g == c2.g && b == c2.b && a == c2.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CColor stripA() const {
|
||||||
|
return {r, g, b, 1};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -21,8 +21,8 @@ CRegion::CRegion(wlr_box* box) {
|
|||||||
pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->width, box->height);
|
pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->width, box->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRegion::CRegion(CBox* box) {
|
CRegion::CRegion(const CBox& box) {
|
||||||
pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->w, box->h);
|
pixman_region32_init_rect(&m_rRegion, box.x, box.y, box.w, box.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRegion::CRegion(pixman_box32_t* box) {
|
CRegion::CRegion(pixman_box32_t* box) {
|
||||||
@@ -63,6 +63,11 @@ CRegion& CRegion::add(double x, double y, double w, double h) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRegion& CRegion::add(const CBox& other) {
|
||||||
|
pixman_region32_union_rect(&m_rRegion, &m_rRegion, other.x, other.y, other.w, other.h);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
CRegion& CRegion::subtract(const CRegion& other) {
|
CRegion& CRegion::subtract(const CRegion& other) {
|
||||||
pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
|
||||||
return *this;
|
return *this;
|
||||||
|
@@ -17,7 +17,7 @@ class CRegion {
|
|||||||
/* Create from a wlr_box */
|
/* Create from a wlr_box */
|
||||||
CRegion(wlr_box* box);
|
CRegion(wlr_box* box);
|
||||||
/* Create from a CBox */
|
/* Create from a CBox */
|
||||||
CRegion(CBox* box);
|
CRegion(const CBox& box);
|
||||||
/* Create from a pixman_box32_t */
|
/* Create from a pixman_box32_t */
|
||||||
CRegion(pixman_box32_t* box);
|
CRegion(pixman_box32_t* box);
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ class CRegion {
|
|||||||
CRegion& set(const CRegion& other);
|
CRegion& set(const CRegion& other);
|
||||||
CRegion& add(const CRegion& other);
|
CRegion& add(const CRegion& other);
|
||||||
CRegion& add(double x, double y, double w, double h);
|
CRegion& add(double x, double y, double w, double h);
|
||||||
|
CRegion& add(const CBox& other);
|
||||||
CRegion& subtract(const CRegion& other);
|
CRegion& subtract(const CRegion& other);
|
||||||
CRegion& intersect(const CRegion& other);
|
CRegion& intersect(const CRegion& other);
|
||||||
CRegion& intersect(double x, double y, double w, double h);
|
CRegion& intersect(double x, double y, double w, double h);
|
||||||
|
@@ -248,14 +248,13 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
|||||||
g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly, SCALE);
|
g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly, SCALE);
|
||||||
|
|
||||||
if (pNode->pWindowOwner) {
|
if (pNode->pWindowOwner) {
|
||||||
// update reported size. Some windows do not send a ::commit afterwards. Odd.
|
if (pNode->pWindowOwner->m_bIsX11)
|
||||||
pNode->pWindowOwner->m_vReportedSize = pNode->pWindowOwner->m_vPendingReportedSize;
|
pNode->pWindowOwner->m_vReportedSize = pNode->pWindowOwner->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
|
||||||
|
|
||||||
// tearing: if solitary, redraw it. This still might be a single surface window
|
// tearing: if solitary, redraw it. This still might be a single surface window
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID);
|
||||||
if (PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->canBeTorn() && PMONITOR->tearingState.canTear &&
|
if (PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->canBeTorn() && PMONITOR->tearingState.canTear &&
|
||||||
pNode->pSurface->wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) {
|
pNode->pSurface->wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) {
|
||||||
|
|
||||||
CRegion damageBox;
|
CRegion damageBox;
|
||||||
wlr_surface_get_effective_damage(pNode->pSurface->wlr(), damageBox.pixman());
|
wlr_surface_get_effective_damage(pNode->pSurface->wlr(), damageBox.pixman());
|
||||||
|
|
||||||
|
@@ -28,6 +28,10 @@ Vector2D Vector2D::floor() const {
|
|||||||
return Vector2D(std::floor(x), std::floor(y));
|
return Vector2D(std::floor(x), std::floor(y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2D Vector2D::round() const {
|
||||||
|
return Vector2D(std::round(x), std::round(y));
|
||||||
|
}
|
||||||
|
|
||||||
Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) const {
|
Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) const {
|
||||||
return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y));
|
return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y));
|
||||||
}
|
}
|
||||||
|
@@ -61,6 +61,7 @@ class Vector2D {
|
|||||||
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()) const;
|
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()) const;
|
||||||
|
|
||||||
Vector2D floor() const;
|
Vector2D floor() const;
|
||||||
|
Vector2D round() const;
|
||||||
|
|
||||||
bool inTriangle(const Vector2D& p1, const Vector2D& p2, const Vector2D& p3) const;
|
bool inTriangle(const Vector2D& p1, const Vector2D& p2, const Vector2D& p3) const;
|
||||||
};
|
};
|
||||||
|
@@ -323,7 +323,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
|
|||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
|
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) {
|
||||||
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
|
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -334,9 +334,6 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
|
|||||||
// if it's a group, add the window
|
// if it's a group, add the window
|
||||||
if (OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
|
if (OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
|
||||||
&& pWindow->canBeGroupedInto(OPENINGON->pWindow) && !m_vOverrideFocalPoint) { // we are not moving window
|
&& pWindow->canBeGroupedInto(OPENINGON->pWindow) && !m_vOverrideFocalPoint) { // we are not moving window
|
||||||
if (!pWindow->m_sGroupData.pNextWindow)
|
|
||||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
|
||||||
|
|
||||||
m_lDwindleNodesData.remove(*PNODE);
|
m_lDwindleNodesData.remove(*PNODE);
|
||||||
|
|
||||||
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
||||||
@@ -347,6 +344,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
|
|||||||
pWindow->updateWindowDecos();
|
pWindow->updateWindowDecos();
|
||||||
recalculateWindow(pWindow);
|
recalculateWindow(pWindow);
|
||||||
|
|
||||||
|
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||||
|
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -162,8 +162,10 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
|||||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||||
|
|
||||||
g_pCompositor->changeWindowZOrder(pWindow, true);
|
g_pCompositor->changeWindowZOrder(pWindow, true);
|
||||||
} else
|
} else {
|
||||||
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goalv();
|
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goalv();
|
||||||
|
pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IHyprLayout::onBeginDragWindow() {
|
void IHyprLayout::onBeginDragWindow() {
|
||||||
|
@@ -99,7 +99,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
|
|||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
|
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) {
|
||||||
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
|
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -111,9 +111,6 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
|
|||||||
if (OPENINGON && OPENINGON != PNODE && OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
|
if (OPENINGON && OPENINGON != PNODE && OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
|
||||||
&& pWindow->canBeGroupedInto(OPENINGON->pWindow)) {
|
&& pWindow->canBeGroupedInto(OPENINGON->pWindow)) {
|
||||||
|
|
||||||
if (!pWindow->m_sGroupData.pNextWindow)
|
|
||||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
|
||||||
|
|
||||||
m_lMasterNodesData.remove(*PNODE);
|
m_lMasterNodesData.remove(*PNODE);
|
||||||
|
|
||||||
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
||||||
@@ -124,6 +121,9 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
|
|||||||
pWindow->updateWindowDecos();
|
pWindow->updateWindowDecos();
|
||||||
recalculateWindow(pWindow);
|
recalculateWindow(pWindow);
|
||||||
|
|
||||||
|
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||||
|
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,6 +68,7 @@ void CAnimationManager::tick() {
|
|||||||
|
|
||||||
if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) {
|
if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) {
|
||||||
av->warp(false);
|
av->warp(false);
|
||||||
|
animationEndedVars.push_back(av);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,28 +249,9 @@ void CAnimationManager::tick() {
|
|||||||
case AVARDAMAGE_SHADOW: {
|
case AVARDAMAGE_SHADOW: {
|
||||||
RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!");
|
RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!");
|
||||||
|
|
||||||
static auto* const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW);
|
||||||
|
|
||||||
const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW);
|
PDECO->damageEntire();
|
||||||
|
|
||||||
if (PDECO) {
|
|
||||||
const auto EXTENTS = PDECO->getWindowDecorationExtents();
|
|
||||||
|
|
||||||
CBox dmg = {PWINDOW->m_vRealPosition.vec().x - EXTENTS.topLeft.x, PWINDOW->m_vRealPosition.vec().y - EXTENTS.topLeft.y,
|
|
||||||
PWINDOW->m_vRealSize.vec().x + EXTENTS.topLeft.x + EXTENTS.bottomRight.x, PWINDOW->m_vRealSize.vec().y + EXTENTS.topLeft.y + EXTENTS.bottomRight.y};
|
|
||||||
|
|
||||||
if (!*PSHADOWIGNOREWINDOW) {
|
|
||||||
// easy, damage the entire box
|
|
||||||
g_pHyprRenderer->damageBox(&dmg);
|
|
||||||
} else {
|
|
||||||
CRegion rg{dmg.x, dmg.y, dmg.width, dmg.height};
|
|
||||||
CRegion wb{PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y, PWINDOW->m_vRealSize.vec().x, PWINDOW->m_vRealSize.vec().y};
|
|
||||||
|
|
||||||
rg.subtract(wb);
|
|
||||||
|
|
||||||
g_pHyprRenderer->damageRegion(rg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1845,7 +1845,7 @@ void CKeybindManager::mouse(std::string args) {
|
|||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
|
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) {
|
||||||
wd->onBeginWindowDragOnDeco(mouseCoords);
|
wd->onBeginWindowDragOnDeco(mouseCoords);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1964,9 +1964,6 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi
|
|||||||
if (pWindow->m_sGroupData.deny)
|
if (pWindow->m_sGroupData.deny)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!pWindow->m_sGroupData.pNextWindow)
|
|
||||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!
|
||||||
|
|
||||||
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
|
||||||
@@ -1978,6 +1975,9 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi
|
|||||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
||||||
g_pCompositor->focusWindow(pWindow);
|
g_pCompositor->focusWindow(pWindow);
|
||||||
g_pCompositor->warpCursorTo(pWindow->middle());
|
g_pCompositor->warpCursorTo(pWindow->middle());
|
||||||
|
|
||||||
|
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
|
||||||
|
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) {
|
void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) {
|
||||||
|
@@ -162,7 +162,7 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
|
|||||||
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
|
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force && ((pWindow->m_vReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vReportedSize == size && !pWindow->m_bIsX11)))
|
if (!force && ((pWindow->m_vPendingReportedSize == size && windowPos == pWindow->m_vReportedPosition) || (pWindow->m_vPendingReportedSize == size && !pWindow->m_bIsX11)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pWindow->m_vReportedPosition = windowPos;
|
pWindow->m_vReportedPosition = windowPos;
|
||||||
@@ -180,12 +180,15 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
|
|||||||
if (pWindow->m_bIsX11)
|
if (pWindow->m_bIsX11)
|
||||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y);
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y);
|
||||||
else
|
else
|
||||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
|
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y), size.floor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
||||||
if (!pWindow->m_bIsX11)
|
if (pWindow->m_bIsX11)
|
||||||
wlr_xdg_toplevel_set_tiled(pWindow->m_uSurface.xdg->toplevel, edgez);
|
return;
|
||||||
|
|
||||||
|
wlr_xdg_toplevel_set_tiled(pWindow->m_uSurface.xdg->toplevel, edgez);
|
||||||
|
wlr_xdg_toplevel_set_maximized(pWindow->m_uSurface.xdg->toplevel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& client, Vector2D& surface) {
|
wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& client, Vector2D& surface) {
|
||||||
|
@@ -112,7 +112,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||||||
if (*PZOOMFACTOR != 1.f)
|
if (*PZOOMFACTOR != 1.f)
|
||||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||||
|
|
||||||
if (!PMONITOR->solitaryClient && g_pHyprRenderer->shouldRenderCursor())
|
if (!PMONITOR->solitaryClient && g_pHyprRenderer->shouldRenderCursor() && PMONITOR->output->software_cursor_locks > 0)
|
||||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
|
|
||||||
CWindow* forcedFocus = m_pForcedFocus;
|
CWindow* forcedFocus = m_pForcedFocus;
|
||||||
@@ -588,7 +588,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
|||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
|
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) {
|
||||||
wd->onMouseButtonOnDeco(mouseCoords, e);
|
wd->onMouseButtonOnDeco(mouseCoords, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -675,7 +675,7 @@ void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
|
|||||||
const auto pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS);
|
const auto pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS);
|
||||||
|
|
||||||
if (*PGROUPBARSCROLLING && pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(MOUSECOORDS) && pWindow->m_sGroupData.pNextWindow) {
|
if (*PGROUPBARSCROLLING && pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(MOUSECOORDS) && pWindow->m_sGroupData.pNextWindow) {
|
||||||
const CBox box = pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents();
|
const CBox box = g_pDecorationPositioner->getWindowDecorationBox(pWindow->getDecorationByType(DECORATION_GROUPBAR));
|
||||||
if (box.containsPoint(MOUSECOORDS)) {
|
if (box.containsPoint(MOUSECOORDS)) {
|
||||||
if (e->delta > 0)
|
if (e->delta > 0)
|
||||||
pWindow->setGroupCurrent(pWindow->m_sGroupData.pNextWindow);
|
pWindow->setGroupCurrent(pWindow->m_sGroupData.pNextWindow);
|
||||||
@@ -1638,7 +1638,7 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
|
|||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
|
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) {
|
||||||
onDeco = true;
|
onDeco = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -111,7 +111,7 @@ APICALL bool HyprlandAPI::removeFunctionHook(HANDLE handle, CFunctionHook* hook)
|
|||||||
return g_pFunctionHookSystem->removeHook(hook);
|
return g_pFunctionHookSystem->removeHook(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, CWindow* pWindow, IHyprWindowDecoration* pDecoration) {
|
APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, CWindow* pWindow, std::unique_ptr<IHyprWindowDecoration> pDecoration) {
|
||||||
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
||||||
|
|
||||||
if (!PLUGIN)
|
if (!PLUGIN)
|
||||||
@@ -120,11 +120,10 @@ APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, CWindow* pWindow, I
|
|||||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PLUGIN->registeredDecorations.push_back(pDecoration);
|
PLUGIN->registeredDecorations.push_back(pDecoration.get());
|
||||||
|
|
||||||
pWindow->m_dWindowDecorations.emplace_back(pDecoration);
|
pWindow->addWindowDeco(std::move(pDecoration));
|
||||||
|
|
||||||
pWindow->updateWindowDecos();
|
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -139,7 +138,7 @@ APICALL bool HyprlandAPI::removeWindowDecoration(HANDLE handle, IHyprWindowDecor
|
|||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
for (auto& d : w->m_dWindowDecorations) {
|
for (auto& d : w->m_dWindowDecorations) {
|
||||||
if (d.get() == pDecoration) {
|
if (d.get() == pDecoration) {
|
||||||
std::erase(w->m_dWindowDecorations, d);
|
w->removeWindowDeco(pDecoration);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -221,7 +221,7 @@ namespace HyprlandAPI {
|
|||||||
|
|
||||||
returns: true on success. False otherwise.
|
returns: true on success. False otherwise.
|
||||||
*/
|
*/
|
||||||
APICALL bool addWindowDecoration(HANDLE handle, CWindow* pWindow, IHyprWindowDecoration* pDecoration);
|
APICALL bool addWindowDecoration(HANDLE handle, CWindow* pWindow, std::unique_ptr<IHyprWindowDecoration> pDecoration);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Removes a window decoration
|
Removes a window decoration
|
||||||
|
@@ -239,7 +239,7 @@ void CScreencopyProtocolManager::captureOutput(wl_client* client, wl_resource* r
|
|||||||
}
|
}
|
||||||
int ow, oh;
|
int ow, oh;
|
||||||
wlr_output_effective_resolution(PFRAME->pMonitor->output, &ow, &oh);
|
wlr_output_effective_resolution(PFRAME->pMonitor->output, &ow, &oh);
|
||||||
PFRAME->box.transform(PFRAME->pMonitor->transform, ow, oh).scale(PFRAME->pMonitor->scale);
|
PFRAME->box.transform(PFRAME->pMonitor->transform, ow, oh).scale(PFRAME->pMonitor->scale).round();
|
||||||
|
|
||||||
PFRAME->shmStride = (PSHMINFO->bpp / 8) * PFRAME->box.width;
|
PFRAME->shmStride = (PSHMINFO->bpp / 8) * PFRAME->box.width;
|
||||||
|
|
||||||
|
@@ -201,7 +201,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
|||||||
PFRAME->box = {0, 0, (int)(PFRAME->pWindow->m_vRealSize.vec().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.vec().y * PMONITOR->scale)};
|
PFRAME->box = {0, 0, (int)(PFRAME->pWindow->m_vRealSize.vec().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.vec().y * PMONITOR->scale)};
|
||||||
int ow, oh;
|
int ow, oh;
|
||||||
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
|
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
|
||||||
PFRAME->box.transform(PMONITOR->transform, ow, oh);
|
PFRAME->box.transform(PMONITOR->transform, ow, oh).round();
|
||||||
|
|
||||||
PFRAME->shmStride = (PSHMINFO->bpp / 8) * PFRAME->box.width;
|
PFRAME->shmStride = (PSHMINFO->bpp / 8) * PFRAME->box.width;
|
||||||
|
|
||||||
|
@@ -348,21 +348,18 @@ void CHyprOpenGLImpl::initShaders() {
|
|||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise");
|
||||||
|
|
||||||
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
|
m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
|
m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.matteTexAttrib = glGetAttribLocation(prog, "texcoordMatte");
|
m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.alphaMatte = glGetUniformLocation(prog, "alphaMatte");
|
m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
|
m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
|
m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range");
|
m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color");
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
|
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color");
|
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
|
||||||
|
|
||||||
prog = createProgram(QUADVERTSRC, FRAGBORDER1);
|
prog = createProgram(QUADVERTSRC, FRAGBORDER1);
|
||||||
m_RenderData.pCurrentMonData->m_shBORDER1.program = prog;
|
m_RenderData.pCurrentMonData->m_shBORDER1.program = prog;
|
||||||
@@ -500,7 +497,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
CRegion damage{m_RenderData.damage};
|
CRegion damage{m_RenderData.damage};
|
||||||
damage.intersect(box);
|
damage.intersect(*box);
|
||||||
|
|
||||||
CFramebuffer* POUTFB = blurMainFramebufferWithDamage(blurA, &damage);
|
CFramebuffer* POUTFB = blurMainFramebufferWithDamage(blurA, &damage);
|
||||||
|
|
||||||
@@ -1395,7 +1392,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
|||||||
if (borderSize < 1)
|
if (borderSize < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int scaledBorderSize = borderSize * m_RenderData.pMonitor->scale * m_RenderData.renderModif.scale;
|
int scaledBorderSize = std::round(borderSize * m_RenderData.pMonitor->scale * m_RenderData.renderModif.scale);
|
||||||
|
|
||||||
// adjust box
|
// adjust box
|
||||||
box->x -= scaledBorderSize;
|
box->x -= scaledBorderSize;
|
||||||
@@ -1721,7 +1718,7 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
|||||||
m_bEndFrame = false;
|
m_bEndFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, float a) {
|
void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const CColor& color, float a) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!");
|
||||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
|
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
|
||||||
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
|
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
|
||||||
@@ -1740,7 +1737,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, float
|
|||||||
|
|
||||||
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
|
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
|
||||||
|
|
||||||
const auto col = m_pCurrentWindow->m_cRealShadowColor.col();
|
const auto col = color;
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
||||||
|
@@ -113,7 +113,7 @@ class CHyprOpenGLImpl {
|
|||||||
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
|
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
|
||||||
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
|
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
|
||||||
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
||||||
void renderRoundedShadow(CBox*, int round, int range, float a = 1.0);
|
void renderRoundedShadow(CBox*, int round, int range, const CColor& color, float a = 1.0);
|
||||||
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
||||||
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);
|
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);
|
||||||
|
|
||||||
|
@@ -2105,7 +2105,7 @@ void CHyprRenderer::setOccludedForBackLayers(CRegion& region, CWorkspace* pWorks
|
|||||||
|
|
||||||
box.scale(PMONITOR->scale);
|
box.scale(PMONITOR->scale);
|
||||||
|
|
||||||
rg.add(&box);
|
rg.add(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
region.subtract(rg);
|
region.subtract(rg);
|
||||||
|
@@ -6,23 +6,26 @@ CHyprDropShadowDecoration::CHyprDropShadowDecoration(CWindow* pWindow) : IHyprWi
|
|||||||
m_pWindow = pWindow;
|
m_pWindow = pWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHyprDropShadowDecoration::~CHyprDropShadowDecoration() {
|
CHyprDropShadowDecoration::~CHyprDropShadowDecoration() {}
|
||||||
updateWindow(m_pWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
SWindowDecorationExtents CHyprDropShadowDecoration::getWindowDecorationExtents() {
|
|
||||||
static auto* const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
|
||||||
|
|
||||||
if (*PSHADOWS != 1)
|
|
||||||
return {{}, {}};
|
|
||||||
|
|
||||||
return m_seExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
eDecorationType CHyprDropShadowDecoration::getDecorationType() {
|
eDecorationType CHyprDropShadowDecoration::getDecorationType() {
|
||||||
return DECORATION_SHADOW;
|
return DECORATION_SHADOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDecorationPositioningInfo CHyprDropShadowDecoration::getPositioningInfo() {
|
||||||
|
SDecorationPositioningInfo info;
|
||||||
|
info.policy = DECORATION_POSITION_ABSOLUTE;
|
||||||
|
info.desiredExtents = m_seExtents;
|
||||||
|
info.edges = DECORATION_EDGE_BOTTOM | DECORATION_EDGE_LEFT | DECORATION_EDGE_RIGHT | DECORATION_EDGE_TOP;
|
||||||
|
|
||||||
|
m_seReportedExtents = m_seExtents;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprDropShadowDecoration::onPositioningReply(const SDecorationPositioningReply& reply) {
|
||||||
|
updateWindow(m_pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprDropShadowDecoration::damageEntire() {
|
void CHyprDropShadowDecoration::damageEntire() {
|
||||||
static auto* const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
static auto* const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||||
|
|
||||||
@@ -35,42 +38,11 @@ void CHyprDropShadowDecoration::damageEntire() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||||
|
m_vLastWindowPos = m_pWindow->m_vRealPosition.vec();
|
||||||
|
m_vLastWindowSize = m_pWindow->m_vRealSize.vec();
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
m_bLastWindowBox = {m_vLastWindowPos.x, m_vLastWindowPos.y, m_vLastWindowSize.x, m_vLastWindowSize.y};
|
||||||
|
m_bLastWindowBoxWithDecos = g_pDecorationPositioner->getBoxWithIncludedDecos(pWindow);
|
||||||
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
|
||||||
|
|
||||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
|
|
||||||
damageEntire();
|
|
||||||
|
|
||||||
const auto BORDER = m_pWindow->getRealBorderSize();
|
|
||||||
|
|
||||||
// calculate extents of decos with the DECORATION_PART_OF_MAIN_WINDOW flag
|
|
||||||
SWindowDecorationExtents maxExtents;
|
|
||||||
|
|
||||||
for (auto& wd : m_pWindow->m_dWindowDecorations) {
|
|
||||||
// conveniently, this will also skip us.
|
|
||||||
if (!(wd->getDecorationFlags() & DECORATION_PART_OF_MAIN_WINDOW))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const auto EXTENTS = wd->getWindowDecorationExtents();
|
|
||||||
|
|
||||||
if (maxExtents.topLeft.x < EXTENTS.topLeft.x)
|
|
||||||
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
|
||||||
if (maxExtents.topLeft.y < EXTENTS.topLeft.y)
|
|
||||||
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
|
||||||
if (maxExtents.bottomRight.x < EXTENTS.bottomRight.x)
|
|
||||||
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
|
||||||
if (maxExtents.bottomRight.y < EXTENTS.bottomRight.y)
|
|
||||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bLastWindowBox = {m_vLastWindowPos.x, m_vLastWindowPos.y, m_vLastWindowSize.x, m_vLastWindowSize.y};
|
|
||||||
m_eLastExtents = {{maxExtents.topLeft + Vector2D{BORDER, BORDER}}, {maxExtents.bottomRight + Vector2D{BORDER, BORDER}}};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
||||||
@@ -99,11 +71,13 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||||||
if (*PSHADOWS != 1)
|
if (*PSHADOWS != 1)
|
||||||
return; // disabled
|
return; // disabled
|
||||||
|
|
||||||
const auto ROUNDING = m_pWindow->rounding() + m_pWindow->getRealBorderSize();
|
const auto ROUNDING = m_pWindow->rounding() + m_pWindow->getRealBorderSize();
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
||||||
|
const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||||
|
|
||||||
// draw the shadow
|
// draw the shadow
|
||||||
CBox fullBox = {m_bLastWindowBox.x, m_bLastWindowBox.y, m_bLastWindowBox.width, m_bLastWindowBox.height};
|
CBox fullBox = m_bLastWindowBoxWithDecos;
|
||||||
fullBox.addExtents(m_eLastExtents).translate(-pMonitor->vecPosition);
|
fullBox.translate(-pMonitor->vecPosition + WORKSPACEOFFSET);
|
||||||
fullBox.x -= *PSHADOWSIZE;
|
fullBox.x -= *PSHADOWSIZE;
|
||||||
fullBox.y -= *PSHADOWSIZE;
|
fullBox.y -= *PSHADOWSIZE;
|
||||||
fullBox.w += 2 * *PSHADOWSIZE;
|
fullBox.w += 2 * *PSHADOWSIZE;
|
||||||
@@ -134,25 +108,37 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||||||
|
|
||||||
if (*PSHADOWIGNOREWINDOW) {
|
if (*PSHADOWIGNOREWINDOW) {
|
||||||
CBox windowBox = m_bLastWindowBox;
|
CBox windowBox = m_bLastWindowBox;
|
||||||
|
CBox withDecos = m_bLastWindowBoxWithDecos;
|
||||||
|
|
||||||
windowBox.translate(-pMonitor->vecPosition).scale(pMonitor->scale);
|
// get window box
|
||||||
windowBox.round();
|
windowBox.translate(-pMonitor->vecPosition + WORKSPACEOFFSET).scale(pMonitor->scale).round();
|
||||||
|
withDecos.translate(-pMonitor->vecPosition + WORKSPACEOFFSET).scale(pMonitor->scale).round();
|
||||||
|
|
||||||
windowBox.addExtents(SWindowDecorationExtents{m_eLastExtents * pMonitor->scale}.floor()).round();
|
auto scaledDecoExtents = withDecos.extentsFrom(windowBox).round();
|
||||||
|
|
||||||
if (windowBox.width < 1 || windowBox.height < 1) {
|
// add extents
|
||||||
|
windowBox.addExtents(scaledDecoExtents).round();
|
||||||
|
|
||||||
|
if (windowBox.width < 1 || windowBox.height < 1)
|
||||||
return; // prevent assert failed
|
return; // prevent assert failed
|
||||||
}
|
|
||||||
|
|
||||||
alphaFB.bind();
|
alphaFB.bind();
|
||||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 0));
|
|
||||||
|
|
||||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(1.0, 1.0, 1.0, 1.0), ROUNDING * pMonitor->scale);
|
// build the matte
|
||||||
|
// 10-bit formats have dogshit alpha channels, so we have to use the matte to its fullest.
|
||||||
|
// first, clear with black (fully transparent)
|
||||||
|
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1));
|
||||||
|
|
||||||
|
// render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit)
|
||||||
|
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, CColor(1, 1, 1, m_pWindow->m_cRealShadowColor.col().a), a);
|
||||||
|
|
||||||
|
// render black window box ("clip")
|
||||||
|
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 1.0), ROUNDING * pMonitor->scale);
|
||||||
|
|
||||||
alphaSwapFB.bind();
|
alphaSwapFB.bind();
|
||||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 0));
|
|
||||||
|
|
||||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
|
// alpha swap just has the shadow color. It will be the "texture" to render.
|
||||||
|
g_pHyprOpenGL->clear(m_pWindow->m_cRealShadowColor.col().stripA());
|
||||||
|
|
||||||
LASTFB->bind();
|
LASTFB->bind();
|
||||||
|
|
||||||
@@ -163,8 +149,11 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||||||
} else {
|
} else {
|
||||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
|
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_seExtents != m_seReportedExtents)
|
||||||
|
g_pDecorationPositioner->repositionDeco(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() {
|
eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() {
|
||||||
return DECORATION_LAYER_BOTTOM;
|
return DECORATION_LAYER_BOTTOM;
|
||||||
}
|
}
|
||||||
|
@@ -7,26 +7,29 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration {
|
|||||||
CHyprDropShadowDecoration(CWindow*);
|
CHyprDropShadowDecoration(CWindow*);
|
||||||
virtual ~CHyprDropShadowDecoration();
|
virtual ~CHyprDropShadowDecoration();
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
virtual SDecorationPositioningInfo getPositioningInfo();
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
||||||
|
|
||||||
virtual void updateWindow(CWindow*);
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
virtual void damageEntire();
|
virtual void updateWindow(CWindow*);
|
||||||
|
|
||||||
virtual eDecorationLayer getDecorationLayer();
|
virtual void damageEntire();
|
||||||
|
|
||||||
|
virtual eDecorationLayer getDecorationLayer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SWindowDecorationExtents m_seExtents;
|
SWindowDecorationExtents m_seExtents;
|
||||||
|
SWindowDecorationExtents m_seReportedExtents;
|
||||||
|
|
||||||
CWindow* m_pWindow = nullptr;
|
CWindow* m_pWindow = nullptr;
|
||||||
|
|
||||||
Vector2D m_vLastWindowPos;
|
Vector2D m_vLastWindowPos;
|
||||||
Vector2D m_vLastWindowSize;
|
Vector2D m_vLastWindowSize;
|
||||||
|
|
||||||
CBox m_bLastWindowBox = {0};
|
CBox m_bLastWindowBox = {0};
|
||||||
SWindowDecorationExtents m_eLastExtents = {};
|
CBox m_bLastWindowBoxWithDecos = {0};
|
||||||
};
|
};
|
@@ -6,6 +6,10 @@
|
|||||||
// shared things to conserve VRAM
|
// shared things to conserve VRAM
|
||||||
static CTexture m_tGradientActive;
|
static CTexture m_tGradientActive;
|
||||||
static CTexture m_tGradientInactive;
|
static CTexture m_tGradientInactive;
|
||||||
|
constexpr int BAR_INDICATOR_HEIGHT = 3;
|
||||||
|
constexpr int BAR_PADDING_OUTER_VERT = 2;
|
||||||
|
constexpr int BAR_TEXT_PAD = 2;
|
||||||
|
constexpr int BAR_HORIZONTAL_PADDING = 2;
|
||||||
|
|
||||||
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) : IHyprWindowDecoration(pWindow) {
|
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) : IHyprWindowDecoration(pWindow) {
|
||||||
m_pWindow = pWindow;
|
m_pWindow = pWindow;
|
||||||
@@ -13,47 +17,33 @@ CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) : IHyprWindow
|
|||||||
|
|
||||||
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {}
|
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {}
|
||||||
|
|
||||||
SWindowDecorationExtents CHyprGroupBarDecoration::getWindowDecorationExtents() {
|
SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() {
|
||||||
return m_seExtents;
|
const int BORDERSIZE = m_pWindow->getRealBorderSize();
|
||||||
|
static auto* const PRENDERTITLES = &g_pConfigManager->getConfigValuePtr("group:groupbar:render_titles")->intValue;
|
||||||
|
static auto* const PTITLEFONTSIZE = &g_pConfigManager->getConfigValuePtr("group:groupbar:font_size")->intValue;
|
||||||
|
|
||||||
|
SDecorationPositioningInfo info;
|
||||||
|
info.policy = DECORATION_POSITION_STICKY;
|
||||||
|
info.edges = DECORATION_EDGE_TOP;
|
||||||
|
info.priority = 3;
|
||||||
|
info.reserved = true;
|
||||||
|
info.desiredExtents = {{0, BORDERSIZE + BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PRENDERTITLES ? *PTITLEFONTSIZE : 0) + 2}, {0, 0}};
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprGroupBarDecoration::onPositioningReply(const SDecorationPositioningReply& reply) {
|
||||||
|
m_bAssignedBox = reply.assignedGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
eDecorationType CHyprGroupBarDecoration::getDecorationType() {
|
eDecorationType CHyprGroupBarDecoration::getDecorationType() {
|
||||||
return DECORATION_GROUPBAR;
|
return DECORATION_GROUPBAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int BAR_INDICATOR_HEIGHT = 3;
|
|
||||||
constexpr int BAR_PADDING_OUTER_VERT = 2;
|
|
||||||
constexpr int BAR_TEXT_PAD = 2;
|
|
||||||
constexpr int BAR_HORIZONTAL_PADDING = 2;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||||
damageEntire();
|
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
|
||||||
|
|
||||||
const auto WORKSPACEOFFSET = PWORKSPACE && !pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
|
||||||
|
|
||||||
static auto* const PRENDERTITLES = &g_pConfigManager->getConfigValuePtr("group:groupbar:render_titles")->intValue;
|
|
||||||
static auto* const PTITLEFONTSIZE = &g_pConfigManager->getConfigValuePtr("group:groupbar:font_size")->intValue;
|
|
||||||
|
|
||||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
|
||||||
// we draw 3px above the window's border with 3px
|
|
||||||
|
|
||||||
const int BORDERSIZE = pWindow->getRealBorderSize();
|
|
||||||
|
|
||||||
m_seExtents.topLeft = Vector2D(0, BORDERSIZE + BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PRENDERTITLES ? *PTITLEFONTSIZE : 0) + 2);
|
|
||||||
m_seExtents.bottomRight = Vector2D();
|
|
||||||
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
|
|
||||||
invalidateTextures();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_pWindow->m_sGroupData.pNextWindow) {
|
if (!m_pWindow->m_sGroupData.pNextWindow) {
|
||||||
m_pWindow->m_vDecosToRemove.push_back(this);
|
m_pWindow->removeWindowDeco(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,15 +60,14 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
|||||||
damageEntire();
|
damageEntire();
|
||||||
|
|
||||||
if (m_dwGroupMembers.size() == 0) {
|
if (m_dwGroupMembers.size() == 0) {
|
||||||
m_pWindow->m_vDecosToRemove.push_back(this);
|
m_pWindow->removeWindowDeco(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::damageEntire() {
|
void CHyprGroupBarDecoration::damageEntire() {
|
||||||
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,
|
auto box = assignedBoxGlobal();
|
||||||
m_seExtents.topLeft.y};
|
g_pHyprRenderer->damageBox(&box);
|
||||||
g_pHyprRenderer->damageBox(&dm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
||||||
@@ -94,13 +83,19 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
|||||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_fBarWidth = (m_vLastWindowSize.x - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw;
|
const auto ASSIGNEDBOX = assignedBoxGlobal();
|
||||||
|
|
||||||
|
m_fBarWidth = (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw;
|
||||||
|
|
||||||
|
const auto DESIREDHEIGHT = BORDERSIZE + BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PRENDERTITLES ? *PTITLEFONTSIZE : 0) + 2;
|
||||||
|
if (DESIREDHEIGHT != ASSIGNEDBOX.h)
|
||||||
|
g_pDecorationPositioner->repositionDeco(this);
|
||||||
|
|
||||||
int xoff = 0;
|
int xoff = 0;
|
||||||
|
|
||||||
for (int i = 0; i < barsToDraw; ++i) {
|
for (int i = 0; i < barsToDraw; ++i) {
|
||||||
CBox rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x + offset.x,
|
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x,
|
||||||
m_vLastWindowPos.y - BAR_PADDING_OUTER_VERT - BORDERSIZE - BAR_INDICATOR_HEIGHT - pMonitor->vecPosition.y + offset.y, m_fBarWidth, BAR_INDICATOR_HEIGHT};
|
ASSIGNEDBOX.y + ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + offset.y, m_fBarWidth, BAR_INDICATOR_HEIGHT};
|
||||||
|
|
||||||
if (rect.width <= 0 || rect.height <= 0)
|
if (rect.width <= 0 || rect.height <= 0)
|
||||||
break;
|
break;
|
||||||
@@ -123,6 +118,9 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
|||||||
|
|
||||||
// render title if necessary
|
// render title if necessary
|
||||||
if (*PRENDERTITLES) {
|
if (*PRENDERTITLES) {
|
||||||
|
CBox rect = {ASSIGNEDBOX.x + xoff - pMonitor->vecPosition.x + offset.x, ASSIGNEDBOX.y - pMonitor->vecPosition.y + offset.y + BAR_PADDING_OUTER_VERT, m_fBarWidth,
|
||||||
|
ASSIGNEDBOX.h - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT * 2};
|
||||||
|
|
||||||
CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[i]->m_szTitle);
|
CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[i]->m_szTitle);
|
||||||
|
|
||||||
if (!pTitleTex)
|
if (!pTitleTex)
|
||||||
@@ -131,17 +129,15 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
|||||||
Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}))
|
Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}))
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
rect.height = (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * 0.8 * pMonitor->scale;
|
|
||||||
|
|
||||||
rect.y -= rect.height;
|
|
||||||
rect.width = m_fBarWidth * pMonitor->scale;
|
|
||||||
|
|
||||||
refreshGradients();
|
refreshGradients();
|
||||||
|
|
||||||
if (*PGRADIENTS)
|
if (*PGRADIENTS) {
|
||||||
g_pHyprOpenGL->renderTexture((m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? m_tGradientActive : m_tGradientInactive), &rect, 1.0);
|
CBox rect2 = rect;
|
||||||
|
rect2.scale(pMonitor->scale);
|
||||||
|
g_pHyprOpenGL->renderTexture((m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? m_tGradientActive : m_tGradientInactive), &rect2, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
rect.y -= (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * 0.2 * pMonitor->scale;
|
rect.y = ASSIGNEDBOX.y + ASSIGNEDBOX.h / 2.0 - (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) / 2.0;
|
||||||
rect.height = (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale;
|
rect.height = (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale;
|
||||||
|
|
||||||
g_pHyprOpenGL->renderTexture(pTitleTex->tex, &rect, 1.f);
|
g_pHyprOpenGL->renderTexture(pTitleTex->tex, &rect, 1.f);
|
||||||
@@ -154,12 +150,6 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
|
|||||||
invalidateTextures();
|
invalidateTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
SWindowDecorationExtents CHyprGroupBarDecoration::getWindowDecorationReservedArea() {
|
|
||||||
static auto* const PRENDERTITLES = &g_pConfigManager->getConfigValuePtr("group:groupbar:render_titles")->intValue;
|
|
||||||
static auto* const PTITLEFONTSIZE = &g_pConfigManager->getConfigValuePtr("group:groupbar:font_size")->intValue;
|
|
||||||
return SWindowDecorationExtents{{0, BAR_INDICATOR_HEIGHT + BAR_PADDING_OUTER_VERT * 2 + (*PRENDERTITLES ? *PTITLEFONTSIZE : 0)}, {}};
|
|
||||||
}
|
|
||||||
|
|
||||||
CTitleTex* CHyprGroupBarDecoration::textureFromTitle(const std::string& title) {
|
CTitleTex* CHyprGroupBarDecoration::textureFromTitle(const std::string& title) {
|
||||||
for (auto& tex : m_sTitleTexs.titleTexs) {
|
for (auto& tex : m_sTitleTexs.titleTexs) {
|
||||||
if (tex->szContent == title)
|
if (tex->szContent == title)
|
||||||
@@ -307,7 +297,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, con
|
|||||||
if (!pDraggedWindow->canBeGroupedInto(m_pWindow))
|
if (!pDraggedWindow->canBeGroupedInto(m_pWindow))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x - m_fBarWidth / 2;
|
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
|
||||||
const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
CWindow* pWindowInsertAfter = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
|
CWindow* pWindowInsertAfter = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
|
||||||
@@ -363,7 +353,7 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point
|
|||||||
if (e->state != WLR_BUTTON_PRESSED)
|
if (e->state != WLR_BUTTON_PRESSED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x;
|
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
||||||
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) {
|
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) {
|
||||||
@@ -382,7 +372,7 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
||||||
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x;
|
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
||||||
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth)
|
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth)
|
||||||
@@ -411,4 +401,9 @@ eDecorationLayer CHyprGroupBarDecoration::getDecorationLayer() {
|
|||||||
|
|
||||||
uint64_t CHyprGroupBarDecoration::getDecorationFlags() {
|
uint64_t CHyprGroupBarDecoration::getDecorationFlags() {
|
||||||
return DECORATION_ALLOWS_MOUSE_INPUT;
|
return DECORATION_ALLOWS_MOUSE_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBox CHyprGroupBarDecoration::assignedBoxGlobal() {
|
||||||
|
CBox box = m_bAssignedBox;
|
||||||
|
return box.translate(g_pDecorationPositioner->getEdgeDefinedPoint(DECORATION_EDGE_TOP, m_pWindow));
|
||||||
}
|
}
|
@@ -21,35 +21,34 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
|
|||||||
CHyprGroupBarDecoration(CWindow*);
|
CHyprGroupBarDecoration(CWindow*);
|
||||||
virtual ~CHyprGroupBarDecoration();
|
virtual ~CHyprGroupBarDecoration();
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
virtual SDecorationPositioningInfo getPositioningInfo();
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply);
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
||||||
|
|
||||||
virtual void updateWindow(CWindow*);
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
virtual void damageEntire();
|
virtual void updateWindow(CWindow*);
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
|
virtual void damageEntire();
|
||||||
|
|
||||||
virtual void onBeginWindowDragOnDeco(const Vector2D&);
|
virtual void onBeginWindowDragOnDeco(const Vector2D&);
|
||||||
|
|
||||||
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&);
|
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&);
|
||||||
|
|
||||||
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
|
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
|
||||||
|
|
||||||
virtual eDecorationLayer getDecorationLayer();
|
virtual eDecorationLayer getDecorationLayer();
|
||||||
|
|
||||||
virtual uint64_t getDecorationFlags();
|
virtual uint64_t getDecorationFlags();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SWindowDecorationExtents m_seExtents;
|
SWindowDecorationExtents m_seExtents;
|
||||||
|
|
||||||
CWindow* m_pWindow = nullptr;
|
CBox m_bAssignedBox = {0};
|
||||||
|
|
||||||
Vector2D m_vLastWindowPos;
|
CWindow* m_pWindow = nullptr;
|
||||||
Vector2D m_vLastWindowSize;
|
|
||||||
|
|
||||||
std::deque<CWindow*> m_dwGroupMembers;
|
std::deque<CWindow*> m_dwGroupMembers;
|
||||||
|
|
||||||
@@ -60,6 +59,8 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
|
|||||||
|
|
||||||
void refreshGradients();
|
void refreshGradients();
|
||||||
|
|
||||||
|
CBox assignedBoxGlobal();
|
||||||
|
|
||||||
struct STitleTexs {
|
struct STitleTexs {
|
||||||
// STitleTexs* overriden = nullptr; // TODO: make shit shared in-group to decrease VRAM usage.
|
// STitleTexs* overriden = nullptr; // TODO: make shit shared in-group to decrease VRAM usage.
|
||||||
std::deque<std::unique_ptr<CTitleTex>> titleTexs;
|
std::deque<std::unique_ptr<CTitleTex>> titleTexs;
|
||||||
|
310
src/render/decorations/DecorationPositioner.cpp
Normal file
310
src/render/decorations/DecorationPositioner.cpp
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
#include "DecorationPositioner.hpp"
|
||||||
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
|
CDecorationPositioner::CDecorationPositioner() {
|
||||||
|
g_pHookSystem->hookDynamic("closeWindow", [this](void* call, SCallbackInfo& info, std::any data) {
|
||||||
|
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
this->onWindowUnmap(PWINDOW);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, CWindow* pWindow) {
|
||||||
|
const bool TOP = edges & DECORATION_EDGE_TOP;
|
||||||
|
const bool BOTTOM = edges & DECORATION_EDGE_BOTTOM;
|
||||||
|
const bool LEFT = edges & DECORATION_EDGE_LEFT;
|
||||||
|
const bool RIGHT = edges & DECORATION_EDGE_RIGHT;
|
||||||
|
|
||||||
|
const int EDGESNO = TOP + BOTTOM + LEFT + RIGHT;
|
||||||
|
|
||||||
|
if (EDGESNO == 0 || EDGESNO > 2) {
|
||||||
|
Debug::log(ERR, "getEdgeDefinedPoint: invalid number of edges");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
CBox wb = pWindow->getWindowMainSurfaceBox();
|
||||||
|
const auto BORDERSIZE = pWindow->getRealBorderSize();
|
||||||
|
wb.expand(BORDERSIZE);
|
||||||
|
|
||||||
|
if (EDGESNO == 1) {
|
||||||
|
if (TOP)
|
||||||
|
return wb.pos() + Vector2D{wb.size().x / 2.0, 0};
|
||||||
|
else if (BOTTOM)
|
||||||
|
return wb.pos() + Vector2D{wb.size().x / 2.0, wb.size().y};
|
||||||
|
else if (LEFT)
|
||||||
|
return wb.pos() + Vector2D{0, wb.size().y / 2.0};
|
||||||
|
else if (RIGHT)
|
||||||
|
return wb.pos() + Vector2D{wb.size().x, wb.size().y / 2.0};
|
||||||
|
UNREACHABLE();
|
||||||
|
} else {
|
||||||
|
if (TOP && LEFT)
|
||||||
|
return wb.pos();
|
||||||
|
if (TOP && RIGHT)
|
||||||
|
return wb.pos() + Vector2D{wb.size().x, 0};
|
||||||
|
if (BOTTOM && RIGHT)
|
||||||
|
return wb.pos() + wb.size();
|
||||||
|
if (BOTTOM && LEFT)
|
||||||
|
return wb.pos() + Vector2D{0, wb.size().y};
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDecorationPositioner::uncacheDecoration(IHyprWindowDecoration* deco) {
|
||||||
|
std::erase_if(m_vWindowPositioningDatas, [&](const auto& data) { return data->pDecoration == deco; });
|
||||||
|
m_mWindowDatas[deco->m_pWindow].needsRecalc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDecorationPositioner::repositionDeco(IHyprWindowDecoration* deco) {
|
||||||
|
uncacheDecoration(deco);
|
||||||
|
onWindowUpdate(deco->m_pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDecorationPositioner::SWindowPositioningData* CDecorationPositioner::getDataFor(IHyprWindowDecoration* pDecoration, CWindow* pWindow) {
|
||||||
|
auto it = std::find_if(m_vWindowPositioningDatas.begin(), m_vWindowPositioningDatas.end(), [&](const auto& el) { return el->pDecoration == pDecoration; });
|
||||||
|
|
||||||
|
if (it != m_vWindowPositioningDatas.end())
|
||||||
|
return it->get();
|
||||||
|
|
||||||
|
const auto DATA = m_vWindowPositioningDatas.emplace_back(std::make_unique<CDecorationPositioner::SWindowPositioningData>(pWindow, pDecoration)).get();
|
||||||
|
|
||||||
|
DATA->positioningInfo = pDecoration->getPositioningInfo();
|
||||||
|
|
||||||
|
return DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDecorationPositioner::onWindowUpdate(CWindow* pWindow) {
|
||||||
|
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto* const WINDOWDATA = &m_mWindowDatas[pWindow];
|
||||||
|
|
||||||
|
//
|
||||||
|
std::vector<CDecorationPositioner::SWindowPositioningData*> datas;
|
||||||
|
for (auto& wd : pWindow->m_dWindowDecorations) {
|
||||||
|
datas.push_back(getDataFor(wd.get(), pWindow));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WINDOWDATA->lastWindowSize == pWindow->m_vRealSize.vec() /* position not changed */
|
||||||
|
&&
|
||||||
|
std::all_of(m_vWindowPositioningDatas.begin(), m_vWindowPositioningDatas.end(), [pWindow](const auto& data) { return pWindow != data->pWindow || !data->needsReposition; })
|
||||||
|
/* all window datas are either not for this window or don't need a reposition */
|
||||||
|
&& !WINDOWDATA->needsRecalc /* window doesn't need recalc */
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WINDOWDATA->lastWindowSize = pWindow->m_vRealSize.vec();
|
||||||
|
WINDOWDATA->needsRecalc = false;
|
||||||
|
const bool EPHEMERAL = pWindow->m_vRealSize.isBeingAnimated();
|
||||||
|
|
||||||
|
std::sort(datas.begin(), datas.end(), [](const auto& a, const auto& b) { return a->positioningInfo.priority > b->positioningInfo.priority; });
|
||||||
|
|
||||||
|
CBox wb = pWindow->getWindowMainSurfaceBox();
|
||||||
|
const auto BORDERSIZE = pWindow->getRealBorderSize();
|
||||||
|
wb.expand(BORDERSIZE);
|
||||||
|
|
||||||
|
// calc reserved
|
||||||
|
float reservedXL = 0, reservedYT = 0, reservedXR = 0, reservedYB = 0;
|
||||||
|
for (size_t i = 0; i < datas.size(); ++i) {
|
||||||
|
auto* const wd = datas[i];
|
||||||
|
|
||||||
|
if (!wd->positioningInfo.reserved)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const bool TOP = wd->positioningInfo.edges & DECORATION_EDGE_TOP;
|
||||||
|
const bool BOTTOM = wd->positioningInfo.edges & DECORATION_EDGE_BOTTOM;
|
||||||
|
const bool LEFT = wd->positioningInfo.edges & DECORATION_EDGE_LEFT;
|
||||||
|
const bool RIGHT = wd->positioningInfo.edges & DECORATION_EDGE_RIGHT;
|
||||||
|
|
||||||
|
if (LEFT)
|
||||||
|
reservedXL += wd->positioningInfo.desiredExtents.topLeft.x;
|
||||||
|
if (RIGHT)
|
||||||
|
reservedXR += wd->positioningInfo.desiredExtents.bottomRight.x;
|
||||||
|
if (TOP)
|
||||||
|
reservedYT += wd->positioningInfo.desiredExtents.topLeft.y;
|
||||||
|
if (BOTTOM)
|
||||||
|
reservedYB += wd->positioningInfo.desiredExtents.bottomRight.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINDOWDATA->reserved = {{reservedXL, reservedYT}, {reservedXR, reservedYB}};
|
||||||
|
|
||||||
|
float stickyOffsetXL = 0, stickyOffsetYT = 0, stickyOffsetXR = 0, stickyOffsetYB = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < datas.size(); ++i) {
|
||||||
|
auto* const wd = datas[i];
|
||||||
|
|
||||||
|
wd->needsReposition = false;
|
||||||
|
|
||||||
|
const bool TOP = wd->positioningInfo.edges & DECORATION_EDGE_TOP;
|
||||||
|
const bool BOTTOM = wd->positioningInfo.edges & DECORATION_EDGE_BOTTOM;
|
||||||
|
const bool LEFT = wd->positioningInfo.edges & DECORATION_EDGE_LEFT;
|
||||||
|
const bool RIGHT = wd->positioningInfo.edges & DECORATION_EDGE_RIGHT;
|
||||||
|
const int EDGESNO = TOP + BOTTOM + LEFT + RIGHT;
|
||||||
|
|
||||||
|
if (wd->positioningInfo.policy == DECORATION_POSITION_ABSOLUTE) {
|
||||||
|
if (LEFT)
|
||||||
|
stickyOffsetXL += wd->positioningInfo.desiredExtents.topLeft.x;
|
||||||
|
if (RIGHT)
|
||||||
|
stickyOffsetXR += wd->positioningInfo.desiredExtents.bottomRight.x;
|
||||||
|
if (TOP)
|
||||||
|
stickyOffsetYT += wd->positioningInfo.desiredExtents.topLeft.y;
|
||||||
|
if (BOTTOM)
|
||||||
|
stickyOffsetYB += wd->positioningInfo.desiredExtents.bottomRight.y;
|
||||||
|
|
||||||
|
wd->lastReply = {};
|
||||||
|
wd->pDecoration->onPositioningReply({});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wd->positioningInfo.policy == DECORATION_POSITION_STICKY) {
|
||||||
|
if (EDGESNO != 1) {
|
||||||
|
wd->lastReply = {};
|
||||||
|
wd->pDecoration->onPositioningReply({});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto desiredSize = 0;
|
||||||
|
if (LEFT)
|
||||||
|
desiredSize = wd->positioningInfo.desiredExtents.topLeft.x;
|
||||||
|
else if (RIGHT)
|
||||||
|
desiredSize = wd->positioningInfo.desiredExtents.bottomRight.x;
|
||||||
|
else if (TOP)
|
||||||
|
desiredSize = wd->positioningInfo.desiredExtents.topLeft.y;
|
||||||
|
else
|
||||||
|
desiredSize = wd->positioningInfo.desiredExtents.bottomRight.y;
|
||||||
|
|
||||||
|
const auto EDGEPOINT = getEdgeDefinedPoint(wd->positioningInfo.edges, pWindow);
|
||||||
|
|
||||||
|
Vector2D pos, size;
|
||||||
|
|
||||||
|
if (LEFT) {
|
||||||
|
pos = wb.pos() - EDGEPOINT - Vector2D{stickyOffsetXL, 0};
|
||||||
|
pos.x -= desiredSize;
|
||||||
|
size = {desiredSize, wb.size().y};
|
||||||
|
|
||||||
|
stickyOffsetXL += desiredSize;
|
||||||
|
} else if (RIGHT) {
|
||||||
|
pos = wb.pos() + Vector2D{wb.size().x, 0} - EDGEPOINT + Vector2D{stickyOffsetXR, 0};
|
||||||
|
size = {desiredSize, wb.size().y};
|
||||||
|
|
||||||
|
stickyOffsetXR += desiredSize;
|
||||||
|
} else if (TOP) {
|
||||||
|
pos = wb.pos() - EDGEPOINT - Vector2D{0, stickyOffsetYT};
|
||||||
|
pos.y -= desiredSize;
|
||||||
|
size = {wb.size().x, desiredSize};
|
||||||
|
|
||||||
|
stickyOffsetYT += desiredSize;
|
||||||
|
} else {
|
||||||
|
pos = wb.pos() + Vector2D{0, wb.size().y} - EDGEPOINT - Vector2D{0, stickyOffsetYB};
|
||||||
|
size = {wb.size().x, desiredSize};
|
||||||
|
|
||||||
|
stickyOffsetYB += desiredSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
wd->lastReply = {{pos, size}, EPHEMERAL};
|
||||||
|
wd->pDecoration->onPositioningReply(wd->lastReply);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// invalid
|
||||||
|
wd->lastReply = {};
|
||||||
|
wd->pDecoration->onPositioningReply({});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WINDOWDATA->extents = {{stickyOffsetXL + reservedXL, stickyOffsetYT + reservedYT}, {stickyOffsetXR + reservedXR, stickyOffsetYB + reservedYB}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDecorationPositioner::onWindowUnmap(CWindow* pWindow) {
|
||||||
|
std::erase_if(m_vWindowPositioningDatas, [&](const auto& data) { return data->pWindow == pWindow; });
|
||||||
|
m_mWindowDatas.erase(pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents CDecorationPositioner::getWindowDecorationReserved(CWindow* pWindow) {
|
||||||
|
return m_mWindowDatas[pWindow].reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(CWindow* pWindow, bool inputOnly) {
|
||||||
|
CBox accum = pWindow->getWindowMainSurfaceBox().expand(pWindow->getRealBorderSize());
|
||||||
|
|
||||||
|
for (auto& data : m_vWindowPositioningDatas) {
|
||||||
|
if (data->pWindow != pWindow)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(data->pDecoration->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT) && inputOnly)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CBox decoBox;
|
||||||
|
|
||||||
|
if (data->positioningInfo.policy == DECORATION_POSITION_ABSOLUTE) {
|
||||||
|
decoBox = data->pWindow->getWindowMainSurfaceBox();
|
||||||
|
decoBox.addExtents(data->positioningInfo.desiredExtents);
|
||||||
|
} else {
|
||||||
|
decoBox = data->lastReply.assignedGeometry;
|
||||||
|
const auto EDGEPOINT = getEdgeDefinedPoint(data->positioningInfo.edges, pWindow);
|
||||||
|
decoBox.translate(EDGEPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents extentsToAdd;
|
||||||
|
|
||||||
|
if (decoBox.x < accum.x)
|
||||||
|
extentsToAdd.topLeft.x = accum.x - decoBox.x;
|
||||||
|
if (decoBox.y < accum.y)
|
||||||
|
extentsToAdd.topLeft.y = accum.y - decoBox.y;
|
||||||
|
if (decoBox.x + decoBox.w > accum.x + accum.w)
|
||||||
|
extentsToAdd.bottomRight.x = (decoBox.x + decoBox.w) - (accum.x + accum.w);
|
||||||
|
if (decoBox.y + decoBox.h > accum.y + accum.h)
|
||||||
|
extentsToAdd.bottomRight.y = (decoBox.y + decoBox.h) - (accum.y + accum.h);
|
||||||
|
|
||||||
|
accum.addExtents(extentsToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum.extentsFrom(pWindow->getWindowMainSurfaceBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
CBox CDecorationPositioner::getBoxWithIncludedDecos(CWindow* pWindow) {
|
||||||
|
CBox accum = pWindow->getWindowMainSurfaceBox().expand(pWindow->getRealBorderSize());
|
||||||
|
|
||||||
|
for (auto& data : m_vWindowPositioningDatas) {
|
||||||
|
if (data->pWindow != pWindow)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(data->pDecoration->getDecorationFlags() & DECORATION_PART_OF_MAIN_WINDOW))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CBox decoBox;
|
||||||
|
|
||||||
|
if (data->positioningInfo.policy == DECORATION_POSITION_ABSOLUTE) {
|
||||||
|
decoBox = data->pWindow->getWindowMainSurfaceBox();
|
||||||
|
decoBox.addExtents(data->positioningInfo.desiredExtents);
|
||||||
|
} else {
|
||||||
|
decoBox = data->lastReply.assignedGeometry;
|
||||||
|
const auto EDGEPOINT = getEdgeDefinedPoint(data->positioningInfo.edges, pWindow);
|
||||||
|
decoBox.translate(EDGEPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents extentsToAdd;
|
||||||
|
|
||||||
|
if (decoBox.x < accum.x)
|
||||||
|
extentsToAdd.topLeft.x = accum.x - decoBox.x;
|
||||||
|
if (decoBox.y < accum.y)
|
||||||
|
extentsToAdd.topLeft.y = accum.y - decoBox.y;
|
||||||
|
if (decoBox.x + decoBox.w > accum.x + accum.w)
|
||||||
|
extentsToAdd.bottomRight.x = accum.x + accum.w - (decoBox.x + decoBox.w);
|
||||||
|
if (decoBox.y + decoBox.h > accum.y + accum.h)
|
||||||
|
extentsToAdd.bottomRight.y = accum.y + accum.h - (decoBox.y + decoBox.h);
|
||||||
|
|
||||||
|
accum.addExtents(extentsToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBox CDecorationPositioner::getWindowDecorationBox(IHyprWindowDecoration* deco) {
|
||||||
|
const auto DATA = getDataFor(deco, deco->m_pWindow);
|
||||||
|
|
||||||
|
CBox box = DATA->lastReply.assignedGeometry;
|
||||||
|
box.translate(getEdgeDefinedPoint(DATA->positioningInfo.edges, deco->m_pWindow));
|
||||||
|
return box;
|
||||||
|
}
|
98
src/render/decorations/DecorationPositioner.hpp
Normal file
98
src/render/decorations/DecorationPositioner.hpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "../../helpers/Box.hpp"
|
||||||
|
|
||||||
|
class CWindow;
|
||||||
|
class IHyprWindowDecoration;
|
||||||
|
|
||||||
|
enum eDecorationPositioningPolicy
|
||||||
|
{
|
||||||
|
DECORATION_POSITION_ABSOLUTE = 0, /* Decoration does not interfere with anything else */
|
||||||
|
DECORATION_POSITION_STICKY, /* Decoration is stuck to some edge of a window */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eDecorationEdges
|
||||||
|
{
|
||||||
|
DECORATION_EDGE_TOP = 1 << 0,
|
||||||
|
DECORATION_EDGE_BOTTOM = 1 << 1,
|
||||||
|
DECORATION_EDGE_LEFT = 1 << 2,
|
||||||
|
DECORATION_EDGE_RIGHT = 1 << 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Request the positioner to position a decoration
|
||||||
|
|
||||||
|
DECORATION_POSITION_ABSOLUTE:
|
||||||
|
- desiredExtents has to contain the extents. Edges has to have the edges used.
|
||||||
|
- reserved allowed
|
||||||
|
DECORATION_POSITION_STICKY:
|
||||||
|
- one edge allowed
|
||||||
|
- priority allowed
|
||||||
|
- desiredExtents contains the desired extents. Any other edge than the one selected is ignored.
|
||||||
|
- reserved is allowed
|
||||||
|
*/
|
||||||
|
struct SDecorationPositioningInfo {
|
||||||
|
eDecorationPositioningPolicy policy = DECORATION_POSITION_ABSOLUTE;
|
||||||
|
uint32_t edges = 0; // enum eDecorationEdges
|
||||||
|
uint32_t priority = 10; // priority, decos will be evaluated high -> low
|
||||||
|
SWindowDecorationExtents desiredExtents;
|
||||||
|
bool reserved = false; // if true, geometry will use reserved area
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
A reply from the positioner. This may be sent multiple times, if anything changes.
|
||||||
|
|
||||||
|
DECORATION_POSITION_ABSOLUTE:
|
||||||
|
- assignedGeometry is empty
|
||||||
|
DECORATION_POSITION_STICKY:
|
||||||
|
- assignedGeometry is relative to the edge's center point
|
||||||
|
- ephemeral is sent
|
||||||
|
*/
|
||||||
|
struct SDecorationPositioningReply {
|
||||||
|
CBox assignedGeometry;
|
||||||
|
bool ephemeral = false; // if true, means it's a result of an animation and will change soon.
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDecorationPositioner {
|
||||||
|
public:
|
||||||
|
CDecorationPositioner();
|
||||||
|
|
||||||
|
Vector2D getEdgeDefinedPoint(uint32_t edges, CWindow* pWindow);
|
||||||
|
|
||||||
|
// called on resize, or insert/removal of a new deco
|
||||||
|
void onWindowUpdate(CWindow* pWindow);
|
||||||
|
void uncacheDecoration(IHyprWindowDecoration* deco);
|
||||||
|
SWindowDecorationExtents getWindowDecorationReserved(CWindow* pWindow);
|
||||||
|
SWindowDecorationExtents getWindowDecorationExtents(CWindow* pWindow, bool inputOnly = false);
|
||||||
|
CBox getBoxWithIncludedDecos(CWindow* pWindow);
|
||||||
|
void repositionDeco(IHyprWindowDecoration* deco);
|
||||||
|
CBox getWindowDecorationBox(IHyprWindowDecoration* deco);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct SWindowPositioningData {
|
||||||
|
CWindow* pWindow = nullptr;
|
||||||
|
IHyprWindowDecoration* pDecoration = nullptr;
|
||||||
|
SDecorationPositioningInfo positioningInfo;
|
||||||
|
SDecorationPositioningReply lastReply;
|
||||||
|
bool needsReposition = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SWindowData {
|
||||||
|
Vector2D lastWindowSize = {};
|
||||||
|
SWindowDecorationExtents reserved = {};
|
||||||
|
SWindowDecorationExtents extents = {};
|
||||||
|
bool needsRecalc = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<CWindow*, SWindowData> m_mWindowDatas;
|
||||||
|
std::vector<std::unique_ptr<SWindowPositioningData>> m_vWindowPositioningDatas;
|
||||||
|
|
||||||
|
SWindowPositioningData* getDataFor(IHyprWindowDecoration* pDecoration, CWindow* pWindow);
|
||||||
|
void onWindowUnmap(CWindow* pWindow);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<CDecorationPositioner> g_pDecorationPositioner;
|
@@ -8,23 +8,6 @@ IHyprWindowDecoration::IHyprWindowDecoration(CWindow* pWindow) {
|
|||||||
|
|
||||||
IHyprWindowDecoration::~IHyprWindowDecoration() {}
|
IHyprWindowDecoration::~IHyprWindowDecoration() {}
|
||||||
|
|
||||||
SWindowDecorationExtents IHyprWindowDecoration::getWindowDecorationReservedArea() {
|
|
||||||
return SWindowDecorationExtents{};
|
|
||||||
}
|
|
||||||
|
|
||||||
CRegion IHyprWindowDecoration::getWindowDecorationRegion() {
|
|
||||||
const SWindowDecorationExtents RESERVED = getWindowDecorationReservedArea();
|
|
||||||
const int BORDERSIZE = m_pWindow->getRealBorderSize();
|
|
||||||
return CRegion(m_pWindow->m_vRealPosition.vec().x - (BORDERSIZE + RESERVED.topLeft.x) * (int)(RESERVED.topLeft.x != 0),
|
|
||||||
m_pWindow->m_vRealPosition.vec().y - (BORDERSIZE + RESERVED.topLeft.y) * (int)(RESERVED.topLeft.y != 0),
|
|
||||||
m_pWindow->m_vRealSize.vec().x + (BORDERSIZE + RESERVED.topLeft.x) * (int)(RESERVED.topLeft.x != 0) +
|
|
||||||
(BORDERSIZE + RESERVED.bottomRight.x) * (int)(RESERVED.bottomRight.x != 0),
|
|
||||||
m_pWindow->m_vRealSize.vec().y + (BORDERSIZE + RESERVED.topLeft.y) * (int)(RESERVED.topLeft.y != 0) +
|
|
||||||
(BORDERSIZE + RESERVED.bottomRight.y) * (int)(RESERVED.bottomRight.y != 0))
|
|
||||||
.subtract(CRegion(m_pWindow->m_vRealPosition.vec().x - BORDERSIZE, m_pWindow->m_vRealPosition.vec().y - BORDERSIZE, m_pWindow->m_vRealSize.vec().x + 2 * BORDERSIZE,
|
|
||||||
m_pWindow->m_vRealSize.vec().y + 2 * BORDERSIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {
|
void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "../../defines.hpp"
|
#include "../../defines.hpp"
|
||||||
#include "../../helpers/Region.hpp"
|
#include "../../helpers/Region.hpp"
|
||||||
|
#include "DecorationPositioner.hpp"
|
||||||
|
|
||||||
enum eDecorationType
|
enum eDecorationType
|
||||||
{
|
{
|
||||||
@@ -27,36 +28,37 @@ enum eDecorationFlags
|
|||||||
|
|
||||||
class CWindow;
|
class CWindow;
|
||||||
class CMonitor;
|
class CMonitor;
|
||||||
|
class CDecorationPositioner;
|
||||||
|
|
||||||
class IHyprWindowDecoration {
|
class IHyprWindowDecoration {
|
||||||
public:
|
public:
|
||||||
IHyprWindowDecoration(CWindow*);
|
IHyprWindowDecoration(CWindow*);
|
||||||
virtual ~IHyprWindowDecoration() = 0;
|
virtual ~IHyprWindowDecoration() = 0;
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationExtents() = 0;
|
virtual SDecorationPositioningInfo getPositioningInfo() = 0;
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset = Vector2D()) = 0;
|
virtual void onPositioningReply(const SDecorationPositioningReply& reply) = 0;
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType() = 0;
|
virtual void draw(CMonitor*, float a, const Vector2D& offset = Vector2D()) = 0;
|
||||||
|
|
||||||
virtual void updateWindow(CWindow*) = 0;
|
virtual eDecorationType getDecorationType() = 0;
|
||||||
|
|
||||||
virtual void damageEntire() = 0;
|
virtual void updateWindow(CWindow*) = 0;
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
|
virtual void damageEntire() = 0; // should be ignored by non-absolute decos
|
||||||
|
|
||||||
virtual CRegion getWindowDecorationRegion();
|
virtual void onBeginWindowDragOnDeco(const Vector2D&); // called when the user calls the "movewindow" mouse dispatcher on the deco
|
||||||
|
|
||||||
virtual void onBeginWindowDragOnDeco(const Vector2D&); // called when the user calls the "movewindow" mouse dispatcher on the deco
|
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); // returns true if the window should be placed by the layout
|
||||||
|
|
||||||
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); // returns true if the window should be placed by the layout
|
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
|
||||||
|
|
||||||
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
|
virtual eDecorationLayer getDecorationLayer();
|
||||||
|
|
||||||
virtual eDecorationLayer getDecorationLayer();
|
virtual uint64_t getDecorationFlags();
|
||||||
|
|
||||||
virtual uint64_t getDecorationFlags();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CWindow* m_pWindow = nullptr;
|
CWindow* m_pWindow = nullptr;
|
||||||
|
|
||||||
|
friend class CDecorationPositioner;
|
||||||
};
|
};
|
||||||
|
@@ -5,9 +5,7 @@
|
|||||||
inline const std::string FRAGSHADOW = R"#(
|
inline const std::string FRAGSHADOW = R"#(
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
uniform sampler2D alphaMatte;
|
|
||||||
varying vec2 v_texcoord;
|
varying vec2 v_texcoord;
|
||||||
varying vec2 v_texcoordMatte;
|
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
uniform vec2 topLeft;
|
||||||
uniform vec2 bottomRight;
|
uniform vec2 bottomRight;
|
||||||
@@ -15,7 +13,6 @@ uniform vec2 fullSize;
|
|||||||
uniform float radius;
|
uniform float radius;
|
||||||
uniform float range;
|
uniform float range;
|
||||||
uniform float shadowPower;
|
uniform float shadowPower;
|
||||||
uniform int useAlphaMatte;
|
|
||||||
|
|
||||||
float pixAlphaRoundedDistance(float distanceToCorner) {
|
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||||
if (distanceToCorner > radius) {
|
if (distanceToCorner > radius) {
|
||||||
@@ -77,10 +74,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useAlphaMatte == 1) {
|
|
||||||
pixColor[3] *= 1.0 - texture2D(alphaMatte, v_texcoordMatte)[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixColor[3] == 0.0) {
|
if (pixColor[3] == 0.0) {
|
||||||
discard; return;
|
discard; return;
|
||||||
}
|
}
|
||||||
|
@@ -137,7 +137,7 @@ uniform sampler2D tex;
|
|||||||
uniform sampler2D texMatte;
|
uniform sampler2D texMatte;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = texture2D(tex, v_texcoord) * (1.0 - texture2D(texMatte, v_texcoord)[3]);
|
gl_FragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
|
||||||
})#";
|
})#";
|
||||||
|
|
||||||
inline const std::string TEXFRAGSRCRGBX = R"#(
|
inline const std::string TEXFRAGSRCRGBX = R"#(
|
||||||
@@ -205,9 +205,7 @@ const float c = 0.66; // Determines the smoothness of the transition of unboost
|
|||||||
|
|
||||||
// http://www.flong.com/archive/texts/code/shapers_circ/
|
// http://www.flong.com/archive/texts/code/shapers_circ/
|
||||||
float doubleCircleSigmoid(float x, float a) {
|
float doubleCircleSigmoid(float x, float a) {
|
||||||
float min_param_a = 0.0;
|
a = clamp(a, 0.0, 1.0);
|
||||||
float max_param_a = 1.0;
|
|
||||||
a = max(min_param_a, min(max_param_a, a));
|
|
||||||
|
|
||||||
float y = .0;
|
float y = .0;
|
||||||
if (x <= a) {
|
if (x <= a) {
|
||||||
@@ -240,14 +238,13 @@ vec3 rgb2hsl(vec3 col) {
|
|||||||
|
|
||||||
vec3 adds = vec3(((green - blue) / delta), 2.0 + ((blue - red) / delta), 4.0 + ((red - green) / delta));
|
vec3 adds = vec3(((green - blue) / delta), 2.0 + ((blue - red) / delta), 4.0 + ((red - green) / delta));
|
||||||
|
|
||||||
float deltaGtz = (delta > 0.0) ? 1.0 : 0.0;
|
if (delta > 0.0) {
|
||||||
|
hue += dot(adds, masks);
|
||||||
|
hue /= 6.0;
|
||||||
|
|
||||||
hue += dot(adds, masks);
|
if (hue < 0.0)
|
||||||
hue *= deltaGtz;
|
hue += 1.0;
|
||||||
hue /= 6.0;
|
}
|
||||||
|
|
||||||
if (hue < 0.0)
|
|
||||||
hue += 1.0;
|
|
||||||
|
|
||||||
return vec3(hue, sat, lum);
|
return vec3(hue, sat, lum);
|
||||||
}
|
}
|
||||||
@@ -260,19 +257,18 @@ vec3 hsl2rgb(vec3 col) {
|
|||||||
float sat = col.y;
|
float sat = col.y;
|
||||||
float lum = col.z;
|
float lum = col.z;
|
||||||
|
|
||||||
vec3 xt = vec3(rcpsixth * (hue - twothird), 0.0, rcpsixth * (1.0 - hue));
|
vec3 xt = vec3(0.0);
|
||||||
|
|
||||||
if (hue < twothird) {
|
|
||||||
xt.r = 0.0;
|
|
||||||
xt.g = rcpsixth * (twothird - hue);
|
|
||||||
xt.b = rcpsixth * (hue - onethird);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hue < onethird) {
|
if (hue < onethird) {
|
||||||
xt.r = rcpsixth * (onethird - hue);
|
xt.r = rcpsixth * (onethird - hue);
|
||||||
xt.g = rcpsixth * hue;
|
xt.g = rcpsixth * hue;
|
||||||
xt.b = 0.0;
|
xt.b = 0.0;
|
||||||
}
|
} else if (hue < twothird) {
|
||||||
|
xt.r = 0.0;
|
||||||
|
xt.g = rcpsixth * (twothird - hue);
|
||||||
|
xt.b = rcpsixth * (hue - onethird);
|
||||||
|
} else
|
||||||
|
xt = vec3(rcpsixth * (hue - twothird), 0.0, rcpsixth * (1.0 - hue));
|
||||||
|
|
||||||
xt = min(xt, 1.0);
|
xt = min(xt, 1.0);
|
||||||
|
|
||||||
|
Submodule subprojects/wlroots updated: 47bf87ade2...5de9e1a99d
@@ -1,7 +1,7 @@
|
|||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = wlroots
|
directory = wlroots
|
||||||
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
revision = 47bf87ade2bd32395615a385ebde1fefbcdf79a2
|
revision = 5de9e1a99d6642c2d09d589aa37ff0a8945dcee1
|
||||||
depth = 1
|
depth = 1
|
||||||
|
|
||||||
diff_files = wlroots-meson-build.patch
|
diff_files = wlroots-meson-build.patch
|
||||||
|
Reference in New Issue
Block a user