mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-24 00:13:48 -07:00
internal: Window storage rework - part 1 (#5762)
* Window storage rework - part 1 * format * remove useless include * fix pch * format * fix crash in dwindle * fix vram leak * prefer .expired() for bool checks
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
#define LOGM PROTO::foreignToplevel->protoLog
|
||||
|
||||
CForeignToplevelHandle::CForeignToplevelHandle(SP<CExtForeignToplevelHandleV1> resource_, CWindow* pWindow_) : resource(resource_), pWindow(pWindow_) {
|
||||
CForeignToplevelHandle::CForeignToplevelHandle(SP<CExtForeignToplevelHandleV1> resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) {
|
||||
if (!resource_->resource())
|
||||
return;
|
||||
|
||||
@@ -15,8 +15,8 @@ bool CForeignToplevelHandle::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
CWindow* CForeignToplevelHandle::window() {
|
||||
return pWindow;
|
||||
PHLWINDOW CForeignToplevelHandle::window() {
|
||||
return pWindow.lock();
|
||||
}
|
||||
|
||||
CForeignToplevelList::CForeignToplevelList(SP<CExtForeignToplevelListV1> resource_) : resource(resource_) {
|
||||
@@ -36,11 +36,11 @@ CForeignToplevelList::CForeignToplevelList(SP<CExtForeignToplevelListV1> resourc
|
||||
if (!w->m_bIsMapped || w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
onMap(w.get());
|
||||
onMap(w);
|
||||
}
|
||||
}
|
||||
|
||||
void CForeignToplevelList::onMap(CWindow* pWindow) {
|
||||
void CForeignToplevelList::onMap(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -54,7 +54,7 @@ void CForeignToplevelList::onMap(CWindow* pWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto IDENTIFIER = std::format("{:08x}->{:016x}", static_cast<uint32_t>((uintptr_t)this & 0xFFFFFFFF), (uintptr_t)pWindow);
|
||||
const auto IDENTIFIER = std::format("{:08x}->{:016x}", static_cast<uint32_t>((uintptr_t)this & 0xFFFFFFFF), (uintptr_t)pWindow.get());
|
||||
|
||||
LOGM(LOG, "Newly mapped window gets an identifier of {}", IDENTIFIER);
|
||||
resource->sendToplevel(NEWHANDLE->resource.get());
|
||||
@@ -66,13 +66,13 @@ void CForeignToplevelList::onMap(CWindow* pWindow) {
|
||||
handles.push_back(NEWHANDLE);
|
||||
}
|
||||
|
||||
SP<CForeignToplevelHandle> CForeignToplevelList::handleForWindow(CWindow* pWindow) {
|
||||
std::erase_if(handles, [](const auto& wp) { return !wp.lock(); });
|
||||
SP<CForeignToplevelHandle> CForeignToplevelList::handleForWindow(PHLWINDOW pWindow) {
|
||||
std::erase_if(handles, [](const auto& wp) { return wp.expired(); });
|
||||
const auto IT = std::find_if(handles.begin(), handles.end(), [pWindow](const auto& h) { return h.lock()->window() == pWindow; });
|
||||
return IT == handles.end() ? SP<CForeignToplevelHandle>{} : IT->lock();
|
||||
}
|
||||
|
||||
void CForeignToplevelList::onTitle(CWindow* pWindow) {
|
||||
void CForeignToplevelList::onTitle(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -83,7 +83,7 @@ void CForeignToplevelList::onTitle(CWindow* pWindow) {
|
||||
H->resource->sendTitle(pWindow->m_szTitle.c_str());
|
||||
}
|
||||
|
||||
void CForeignToplevelList::onClass(CWindow* pWindow) {
|
||||
void CForeignToplevelList::onClass(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -94,7 +94,7 @@ void CForeignToplevelList::onClass(CWindow* pWindow) {
|
||||
H->resource->sendAppId(g_pXWaylandManager->getAppIDClass(pWindow).c_str());
|
||||
}
|
||||
|
||||
void CForeignToplevelList::onUnmap(CWindow* pWindow) {
|
||||
void CForeignToplevelList::onUnmap(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -113,19 +113,19 @@ bool CForeignToplevelList::good() {
|
||||
CForeignToplevelProtocol::CForeignToplevelProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
static auto P = g_pHookSystem->hookDynamic("openWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onMap(std::any_cast<CWindow*>(data));
|
||||
m->onMap(std::any_cast<PHLWINDOW>(data));
|
||||
}
|
||||
});
|
||||
|
||||
static auto P1 = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onUnmap(std::any_cast<CWindow*>(data));
|
||||
m->onUnmap(std::any_cast<PHLWINDOW>(data));
|
||||
}
|
||||
});
|
||||
|
||||
static auto P2 = g_pHookSystem->hookDynamic("windowTitle", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onTitle(std::any_cast<CWindow*>(data));
|
||||
m->onTitle(std::any_cast<PHLWINDOW>(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -6,19 +6,17 @@
|
||||
#include "WaylandProtocol.hpp"
|
||||
#include "ext-foreign-toplevel-list-v1.hpp"
|
||||
|
||||
class CWindow;
|
||||
|
||||
class CForeignToplevelHandle {
|
||||
public:
|
||||
CForeignToplevelHandle(SP<CExtForeignToplevelHandleV1> resource_, CWindow* pWindow);
|
||||
CForeignToplevelHandle(SP<CExtForeignToplevelHandleV1> resource_, PHLWINDOW pWindow);
|
||||
|
||||
bool good();
|
||||
CWindow* window();
|
||||
bool good();
|
||||
PHLWINDOW window();
|
||||
|
||||
private:
|
||||
SP<CExtForeignToplevelHandleV1> resource;
|
||||
CWindow* pWindow = nullptr;
|
||||
bool closed = false;
|
||||
PHLWINDOWREF pWindow;
|
||||
bool closed = false;
|
||||
|
||||
friend class CForeignToplevelList;
|
||||
};
|
||||
@@ -27,10 +25,10 @@ class CForeignToplevelList {
|
||||
public:
|
||||
CForeignToplevelList(SP<CExtForeignToplevelListV1> resource_);
|
||||
|
||||
void onMap(CWindow* pWindow);
|
||||
void onTitle(CWindow* pWindow);
|
||||
void onClass(CWindow* pWindow);
|
||||
void onUnmap(CWindow* pWindow);
|
||||
void onMap(PHLWINDOW pWindow);
|
||||
void onTitle(PHLWINDOW pWindow);
|
||||
void onClass(PHLWINDOW pWindow);
|
||||
void onUnmap(PHLWINDOW pWindow);
|
||||
|
||||
bool good();
|
||||
|
||||
@@ -38,7 +36,7 @@ class CForeignToplevelList {
|
||||
SP<CExtForeignToplevelListV1> resource;
|
||||
bool finished = false;
|
||||
|
||||
SP<CForeignToplevelHandle> handleForWindow(CWindow* pWindow);
|
||||
SP<CForeignToplevelHandle> handleForWindow(PHLWINDOW pWindow);
|
||||
|
||||
std::vector<WP<CForeignToplevelHandle>> handles;
|
||||
};
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
#define LOGM PROTO::foreignToplevelWlr->protoLog
|
||||
|
||||
CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, CWindow* pWindow_) : resource(resource_), pWindow(pWindow_) {
|
||||
CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) {
|
||||
if (!resource_->resource())
|
||||
return;
|
||||
|
||||
@@ -12,70 +12,82 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHand
|
||||
resource->setDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); });
|
||||
|
||||
resource->setActivate([this](CZwlrForeignToplevelHandleV1* p, wl_resource* seat) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (pWindow->m_eSuppressedEvents & SUPPRESS_ACTIVATE)
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE)
|
||||
return;
|
||||
|
||||
pWindow->activate();
|
||||
PWINDOW->activate();
|
||||
});
|
||||
|
||||
resource->setSetFullscreen([this](CZwlrForeignToplevelHandleV1* p, wl_resource* output) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (pWindow->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||
return;
|
||||
|
||||
if (!pWindow->m_bIsMapped) {
|
||||
pWindow->m_bWantsInitialFullscreen = true;
|
||||
if (!PWINDOW->m_bIsMapped) {
|
||||
PWINDOW->m_bWantsInitialFullscreen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
g_pCompositor->setWindowFullscreen(pWindow, true);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true);
|
||||
});
|
||||
|
||||
resource->setUnsetFullscreen([this](CZwlrForeignToplevelHandleV1* p) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (pWindow->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||
return;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(pWindow, false);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, false);
|
||||
});
|
||||
|
||||
resource->setSetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (pWindow->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||
return;
|
||||
|
||||
if (!pWindow->m_bIsMapped) {
|
||||
pWindow->m_bWantsInitialFullscreen = true;
|
||||
if (!PWINDOW->m_bIsMapped) {
|
||||
PWINDOW->m_bWantsInitialFullscreen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
g_pCompositor->setWindowFullscreen(pWindow, true, FULLSCREEN_MAXIMIZED);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_MAXIMIZED);
|
||||
});
|
||||
|
||||
resource->setUnsetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
if (pWindow->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||
if (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||
return;
|
||||
|
||||
g_pCompositor->setWindowFullscreen(pWindow, false);
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, false);
|
||||
});
|
||||
|
||||
resource->setClose([this](CZwlrForeignToplevelHandleV1* p) {
|
||||
if (!pWindow)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW)
|
||||
return;
|
||||
|
||||
g_pCompositor->closeWindow(pWindow);
|
||||
g_pCompositor->closeWindow(PWINDOW);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -83,8 +95,8 @@ bool CForeignToplevelHandleWlr::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
CWindow* CForeignToplevelHandleWlr::window() {
|
||||
return pWindow;
|
||||
PHLWINDOW CForeignToplevelHandleWlr::window() {
|
||||
return pWindow.lock();
|
||||
}
|
||||
|
||||
wl_resource* CForeignToplevelHandleWlr::res() {
|
||||
@@ -119,20 +131,22 @@ void CForeignToplevelHandleWlr::sendMonitor(CMonitor* pMonitor) {
|
||||
}
|
||||
|
||||
void CForeignToplevelHandleWlr::sendState() {
|
||||
if (!pWindow || !pWindow->m_pWorkspace || !pWindow->m_bIsMapped)
|
||||
const auto PWINDOW = pWindow.lock();
|
||||
|
||||
if (!PWINDOW || !PWINDOW->m_pWorkspace || !PWINDOW->m_bIsMapped)
|
||||
return;
|
||||
|
||||
wl_array state;
|
||||
wl_array_init(&state);
|
||||
|
||||
if (pWindow == g_pCompositor->m_pLastWindow) {
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) {
|
||||
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
|
||||
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
|
||||
}
|
||||
|
||||
if (pWindow->m_bIsFullscreen) {
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
|
||||
if (pWindow->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
if (PWINDOW->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
|
||||
else
|
||||
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
|
||||
@@ -160,13 +174,13 @@ CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelMa
|
||||
if (!w->m_bIsMapped || w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
onMap(w.get());
|
||||
onMap(w);
|
||||
}
|
||||
|
||||
lastFocus = g_pCompositor->m_pLastWindow;
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onMap(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -180,7 +194,7 @@ void CForeignToplevelWlrManager::onMap(CWindow* pWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGM(LOG, "Newly mapped window {:016x}", (uintptr_t)pWindow);
|
||||
LOGM(LOG, "Newly mapped window {:016x}", (uintptr_t)pWindow.get());
|
||||
resource->sendToplevel(NEWHANDLE->resource.get());
|
||||
NEWHANDLE->resource->sendAppId(pWindow->m_szInitialClass.c_str());
|
||||
NEWHANDLE->resource->sendTitle(pWindow->m_szInitialTitle.c_str());
|
||||
@@ -192,13 +206,13 @@ void CForeignToplevelWlrManager::onMap(CWindow* pWindow) {
|
||||
handles.push_back(NEWHANDLE);
|
||||
}
|
||||
|
||||
SP<CForeignToplevelHandleWlr> CForeignToplevelWlrManager::handleForWindow(CWindow* pWindow) {
|
||||
std::erase_if(handles, [](const auto& wp) { return !wp.lock(); });
|
||||
SP<CForeignToplevelHandleWlr> CForeignToplevelWlrManager::handleForWindow(PHLWINDOW pWindow) {
|
||||
std::erase_if(handles, [](const auto& wp) { return wp.expired(); });
|
||||
const auto IT = std::find_if(handles.begin(), handles.end(), [pWindow](const auto& h) { return h.lock()->window() == pWindow; });
|
||||
return IT == handles.end() ? SP<CForeignToplevelHandleWlr>{} : IT->lock();
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onTitle(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onTitle(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -210,7 +224,7 @@ void CForeignToplevelWlrManager::onTitle(CWindow* pWindow) {
|
||||
H->resource->sendDone();
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onClass(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onClass(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -222,7 +236,7 @@ void CForeignToplevelWlrManager::onClass(CWindow* pWindow) {
|
||||
H->resource->sendDone();
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onUnmap(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onUnmap(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -235,7 +249,7 @@ void CForeignToplevelWlrManager::onUnmap(CWindow* pWindow) {
|
||||
H->closed = true;
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onMoveMonitor(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onMoveMonitor(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -252,7 +266,7 @@ void CForeignToplevelWlrManager::onMoveMonitor(CWindow* pWindow) {
|
||||
H->resource->sendDone();
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onFullscreen(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onFullscreen(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
@@ -264,11 +278,11 @@ void CForeignToplevelWlrManager::onFullscreen(CWindow* pWindow) {
|
||||
H->resource->sendDone();
|
||||
}
|
||||
|
||||
void CForeignToplevelWlrManager::onNewFocus(CWindow* pWindow) {
|
||||
void CForeignToplevelWlrManager::onNewFocus(PHLWINDOW pWindow) {
|
||||
if (finished)
|
||||
return;
|
||||
|
||||
if (const auto HOLD = handleForWindow(lastFocus); HOLD) {
|
||||
if (const auto HOLD = handleForWindow(lastFocus.lock()); HOLD) {
|
||||
HOLD->sendState();
|
||||
HOLD->resource->sendDone();
|
||||
}
|
||||
@@ -289,42 +303,42 @@ bool CForeignToplevelWlrManager::good() {
|
||||
|
||||
CForeignToplevelWlrProtocol::CForeignToplevelWlrProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
static auto P = g_pHookSystem->hookDynamic("openWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onMap(PWINDOW);
|
||||
}
|
||||
});
|
||||
|
||||
static auto P1 = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onUnmap(PWINDOW);
|
||||
}
|
||||
});
|
||||
|
||||
static auto P2 = g_pHookSystem->hookDynamic("windowTitle", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onTitle(PWINDOW);
|
||||
}
|
||||
});
|
||||
|
||||
static auto P3 = g_pHookSystem->hookDynamic("activeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onNewFocus(PWINDOW);
|
||||
}
|
||||
});
|
||||
|
||||
static auto P4 = g_pHookSystem->hookDynamic("moveWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(std::any_cast<std::vector<std::any>>(data).at(0));
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(std::any_cast<std::vector<std::any>>(data).at(0));
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onMoveMonitor(PWINDOW);
|
||||
}
|
||||
});
|
||||
|
||||
static auto P5 = g_pHookSystem->hookDynamic("fullscreen", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
for (auto& m : m_vManagers) {
|
||||
m->onFullscreen(PWINDOW);
|
||||
}
|
||||
@@ -350,7 +364,7 @@ void CForeignToplevelWlrProtocol::destroyHandle(CForeignToplevelHandleWlr* handl
|
||||
std::erase_if(m_vHandles, [&](const auto& other) { return other.get() == handle; });
|
||||
}
|
||||
|
||||
CWindow* CForeignToplevelWlrProtocol::windowFromHandleResource(wl_resource* res) {
|
||||
PHLWINDOW CForeignToplevelWlrProtocol::windowFromHandleResource(wl_resource* res) {
|
||||
for (auto& h : m_vHandles) {
|
||||
if (h->res() != res)
|
||||
continue;
|
||||
|
@@ -10,15 +10,15 @@ class CMonitor;
|
||||
|
||||
class CForeignToplevelHandleWlr {
|
||||
public:
|
||||
CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, CWindow* pWindow);
|
||||
CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, PHLWINDOW pWindow);
|
||||
|
||||
bool good();
|
||||
CWindow* window();
|
||||
PHLWINDOW window();
|
||||
wl_resource* res();
|
||||
|
||||
private:
|
||||
SP<CZwlrForeignToplevelHandleV1> resource;
|
||||
CWindow* pWindow = nullptr;
|
||||
PHLWINDOWREF pWindow;
|
||||
bool closed = false;
|
||||
int64_t lastMonitorID = -1;
|
||||
|
||||
@@ -32,22 +32,22 @@ class CForeignToplevelWlrManager {
|
||||
public:
|
||||
CForeignToplevelWlrManager(SP<CZwlrForeignToplevelManagerV1> resource_);
|
||||
|
||||
void onMap(CWindow* pWindow);
|
||||
void onTitle(CWindow* pWindow);
|
||||
void onClass(CWindow* pWindow);
|
||||
void onMoveMonitor(CWindow* pWindow);
|
||||
void onFullscreen(CWindow* pWindow);
|
||||
void onNewFocus(CWindow* pWindow);
|
||||
void onUnmap(CWindow* pWindow);
|
||||
void onMap(PHLWINDOW pWindow);
|
||||
void onTitle(PHLWINDOW pWindow);
|
||||
void onClass(PHLWINDOW pWindow);
|
||||
void onMoveMonitor(PHLWINDOW pWindow);
|
||||
void onFullscreen(PHLWINDOW pWindow);
|
||||
void onNewFocus(PHLWINDOW pWindow);
|
||||
void onUnmap(PHLWINDOW pWindow);
|
||||
|
||||
bool good();
|
||||
|
||||
private:
|
||||
SP<CZwlrForeignToplevelManagerV1> resource;
|
||||
bool finished = false;
|
||||
CWindow* lastFocus = nullptr; // READ-ONLY
|
||||
bool finished = false;
|
||||
PHLWINDOWREF lastFocus; // READ-ONLY
|
||||
|
||||
SP<CForeignToplevelHandleWlr> handleForWindow(CWindow* pWindow);
|
||||
SP<CForeignToplevelHandleWlr> handleForWindow(PHLWINDOW pWindow);
|
||||
|
||||
std::vector<WP<CForeignToplevelHandleWlr>> handles;
|
||||
};
|
||||
@@ -58,7 +58,7 @@ class CForeignToplevelWlrProtocol : public IWaylandProtocol {
|
||||
|
||||
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||
|
||||
CWindow* windowFromHandleResource(wl_resource* res);
|
||||
PHLWINDOW windowFromHandleResource(wl_resource* res);
|
||||
|
||||
private:
|
||||
void onManagerResourceDestroy(CForeignToplevelWlrManager* mgr);
|
||||
|
@@ -56,7 +56,7 @@ struct SScreencopyFrame {
|
||||
wlr_buffer* buffer = nullptr;
|
||||
|
||||
CMonitor* pMonitor = nullptr;
|
||||
CWindow* pWindow = nullptr;
|
||||
PHLWINDOWREF pWindow;
|
||||
|
||||
bool operator==(const SScreencopyFrame& other) const {
|
||||
return resource == other.resource && client == other.client;
|
||||
|
@@ -4,7 +4,8 @@
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
static auto P = g_pHookSystem->hookDynamic("destroyWindow", [this](void* self, SCallbackInfo& info, std::any param) { this->onWindowDestroy(std::any_cast<CWindow*>(param)); });
|
||||
static auto P =
|
||||
g_pHookSystem->hookDynamic("destroyWindow", [this](void* self, SCallbackInfo& info, std::any param) { this->onWindowDestroy(std::any_cast<PHLWINDOW>(param)); });
|
||||
}
|
||||
|
||||
void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
@@ -36,10 +37,10 @@ void CTearingControlProtocol::onControllerDestroy(CTearingControl* control) {
|
||||
std::erase_if(m_vTearingControllers, [control](const auto& other) { return other.get() == control; });
|
||||
}
|
||||
|
||||
void CTearingControlProtocol::onWindowDestroy(CWindow* pWindow) {
|
||||
void CTearingControlProtocol::onWindowDestroy(PHLWINDOW pWindow) {
|
||||
for (auto& c : m_vTearingControllers) {
|
||||
if (c->pWindow == pWindow)
|
||||
c->pWindow = nullptr;
|
||||
if (c->pWindow.lock() == pWindow)
|
||||
c->pWindow.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ CTearingControl::CTearingControl(SP<CWpTearingControlV1> resource_, wlr_surface*
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_pWLSurface.wlr() == surf_) {
|
||||
pWindow = w.get();
|
||||
pWindow = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -65,10 +66,10 @@ void CTearingControl::onHint(wpTearingControlV1PresentationHint hint_) {
|
||||
}
|
||||
|
||||
void CTearingControl::updateWindow() {
|
||||
if (!pWindow)
|
||||
if (pWindow.expired())
|
||||
return;
|
||||
|
||||
pWindow->m_bTearingHint = hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
||||
pWindow.lock()->m_bTearingHint = hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
||||
}
|
||||
|
||||
bool CTearingControl::good() {
|
||||
|
@@ -27,8 +27,8 @@ class CTearingControl {
|
||||
void updateWindow();
|
||||
|
||||
SP<CWpTearingControlV1> resource;
|
||||
CWindow* pWindow = nullptr;
|
||||
wpTearingControlV1PresentationHint hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
|
||||
PHLWINDOWREF pWindow;
|
||||
wpTearingControlV1PresentationHint hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
|
||||
|
||||
friend class CTearingControlProtocol;
|
||||
};
|
||||
@@ -43,7 +43,7 @@ class CTearingControlProtocol : public IWaylandProtocol {
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void onControllerDestroy(CTearingControl* control);
|
||||
void onGetController(wl_client* client, wl_resource* resource, uint32_t id, wlr_surface* surf);
|
||||
void onWindowDestroy(CWindow* pWindow);
|
||||
void onWindowDestroy(PHLWINDOW pWindow);
|
||||
|
||||
//
|
||||
std::vector<UP<CWpTearingControlManagerV1>> m_vManagers;
|
||||
|
@@ -136,7 +136,7 @@ void CToplevelExportProtocolManager::removeFrame(SScreencopyFrame* frame, bool f
|
||||
m_lFrames.remove(*frame);
|
||||
}
|
||||
|
||||
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, CWindow* pWindow) {
|
||||
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, PHLWINDOW pWindow) {
|
||||
const auto PCLIENT = clientFromResource(resource);
|
||||
|
||||
// create a frame
|
||||
@@ -145,15 +145,15 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
||||
PFRAME->resource = wl_resource_create(client, &hyprland_toplevel_export_frame_v1_interface, wl_resource_get_version(resource), frame);
|
||||
PFRAME->pWindow = pWindow;
|
||||
|
||||
if (!PFRAME->pWindow) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which does not exist!", PFRAME->pWindow);
|
||||
if (!pWindow) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which does not exist!", pWindow);
|
||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||
removeFrame(PFRAME);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is not shareable!", PFRAME->pWindow);
|
||||
if (!pWindow->m_bIsMapped || pWindow->isHidden()) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is not shareable!", pWindow);
|
||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||
removeFrame(PFRAME);
|
||||
return;
|
||||
@@ -171,7 +171,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
||||
PFRAME->client = PCLIENT;
|
||||
PCLIENT->ref++;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PFRAME->pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
|
||||
@@ -197,7 +197,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
|
||||
PFRAME->dmabufFormat = DRM_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
PFRAME->box = {0, 0, (int)(PFRAME->pWindow->m_vRealSize.value().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.value().y * PMONITOR->scale)};
|
||||
PFRAME->box = {0, 0, (int)(pWindow->m_vRealSize.value().x * PMONITOR->scale), (int)(pWindow->m_vRealSize.value().y * PMONITOR->scale)};
|
||||
int ow, oh;
|
||||
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
|
||||
PFRAME->box.transform(PMONITOR->transform, ow, oh).round();
|
||||
@@ -221,15 +221,17 @@ void CToplevelExportProtocolManager::copyFrame(wl_client* client, wl_resource* r
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PFRAME->pWindow)) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is gone!", (uintptr_t)PFRAME->pWindow);
|
||||
const auto PWINDOW = PFRAME->pWindow.lock();
|
||||
|
||||
if (!validMapped(PWINDOW)) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is gone!", (uintptr_t)PWINDOW.get());
|
||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||
removeFrame(PFRAME);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", PFRAME->pWindow);
|
||||
if (!PWINDOW->m_bIsMapped || PWINDOW->isHidden()) {
|
||||
Debug::log(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", PWINDOW);
|
||||
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
|
||||
removeFrame(PFRAME);
|
||||
return;
|
||||
@@ -299,15 +301,17 @@ void CToplevelExportProtocolManager::onOutputCommit(CMonitor* pMonitor, wlr_outp
|
||||
|
||||
// share frame if correct output
|
||||
for (auto& f : m_vFramesAwaitingWrite) {
|
||||
if (!f->pWindow) {
|
||||
const auto PWINDOW = f->pWindow.lock();
|
||||
|
||||
if (!validMapped(PWINDOW)) {
|
||||
framesToRemove.push_back(f);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PMONITOR != g_pCompositor->getMonitorFromID(f->pWindow->m_iMonitorID))
|
||||
if (PMONITOR != g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID))
|
||||
continue;
|
||||
|
||||
CBox geometry = {f->pWindow->m_vRealPosition.value().x, f->pWindow->m_vRealPosition.value().y, f->pWindow->m_vRealSize.value().x, f->pWindow->m_vRealSize.value().y};
|
||||
CBox geometry = {PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y, PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealSize.value().y};
|
||||
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr()))
|
||||
continue;
|
||||
@@ -326,7 +330,7 @@ void CToplevelExportProtocolManager::onOutputCommit(CMonitor* pMonitor, wlr_outp
|
||||
}
|
||||
|
||||
void CToplevelExportProtocolManager::shareFrame(SScreencopyFrame* frame) {
|
||||
if (!frame->buffer || !g_pCompositor->windowValidMapped(frame->pWindow))
|
||||
if (!frame->buffer || !validMapped(frame->pWindow))
|
||||
return;
|
||||
|
||||
timespec now;
|
||||
@@ -365,7 +369,7 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||
return false;
|
||||
|
||||
// render the client
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow.lock()->m_iMonitorID);
|
||||
CRegion fakeDamage{0, 0, PMONITOR->vecPixelSize.x * 10, PMONITOR->vecPixelSize.y * 10};
|
||||
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
@@ -384,12 +388,12 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
||||
|
||||
// render client at 0,0
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(frame->pWindow); // block the feedback to avoid spamming the surface if it's visible
|
||||
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(frame->pWindow.lock()); // block the feedback to avoid spamming the surface if it's visible
|
||||
g_pHyprRenderer->renderWindow(frame->pWindow.lock(), PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
||||
|
||||
if (frame->overlayCursor)
|
||||
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.value());
|
||||
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow.lock()->m_vRealPosition.value());
|
||||
|
||||
const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format);
|
||||
if (!PFORMAT) {
|
||||
@@ -422,7 +426,7 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||
}
|
||||
|
||||
bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, timespec* now) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow.lock()->m_iMonitorID);
|
||||
|
||||
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
|
||||
|
||||
@@ -431,21 +435,21 @@ bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, ti
|
||||
|
||||
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1.0));
|
||||
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(frame->pWindow); // block the feedback to avoid spamming the surface if it's visible
|
||||
g_pHyprRenderer->renderWindow(frame->pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(frame->pWindow.lock()); // block the feedback to avoid spamming the surface if it's visible
|
||||
g_pHyprRenderer->renderWindow(frame->pWindow.lock(), PMONITOR, now, false, RENDER_PASS_ALL, true, true);
|
||||
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
|
||||
|
||||
if (frame->overlayCursor)
|
||||
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.value());
|
||||
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow.lock()->m_vRealPosition.value());
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.blockScreenShader = true;
|
||||
g_pHyprRenderer->endRender();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CToplevelExportProtocolManager::onWindowUnmap(CWindow* pWindow) {
|
||||
void CToplevelExportProtocolManager::onWindowUnmap(PHLWINDOW pWindow) {
|
||||
for (auto& f : m_lFrames) {
|
||||
if (f.pWindow == pWindow)
|
||||
f.pWindow = nullptr;
|
||||
if (f.pWindow.lock() == pWindow)
|
||||
f.pWindow.reset();
|
||||
}
|
||||
}
|
||||
|
@@ -15,12 +15,12 @@ class CToplevelExportProtocolManager {
|
||||
CToplevelExportProtocolManager();
|
||||
|
||||
void bindManager(wl_client* client, void* data, uint32_t version, uint32_t id);
|
||||
void captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, CWindow* handle);
|
||||
void captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, PHLWINDOW handle);
|
||||
void removeClient(CScreencopyClient* client, bool force = false);
|
||||
void removeFrame(SScreencopyFrame* frame, bool force = false);
|
||||
void copyFrame(wl_client* client, wl_resource* resource, wl_resource* buffer, int32_t ignore_damage);
|
||||
void displayDestroy();
|
||||
void onWindowUnmap(CWindow* pWindow);
|
||||
void onWindowUnmap(PHLWINDOW pWindow);
|
||||
void onOutputCommit(CMonitor* pMonitor, wlr_output_event_commit* e);
|
||||
|
||||
private:
|
||||
|
@@ -9,10 +9,6 @@
|
||||
if (!resname) \
|
||||
return;
|
||||
|
||||
#define SP std::shared_ptr
|
||||
#define UP std::unique_ptr
|
||||
#define WP std::weak_ptr
|
||||
|
||||
#define PROTO NProtocols
|
||||
|
||||
class IWaylandProtocol {
|
||||
|
Reference in New Issue
Block a user