desktop/window: add stable id and use it for foreign

This commit is contained in:
Vaxry 2026-02-19 00:49:43 +00:00
parent 184af52f24
commit 68456a5d9a
No known key found for this signature in database
GPG key ID: 665806380871D640
4 changed files with 24 additions and 15 deletions

View file

@ -394,7 +394,8 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
"inhibitingIdle": {},
"xdgTag": "{}",
"xdgDescription": "{}",
"contentType": "{}"
"contentType": "{}",
"stable_id": "{:x}"
}},)#",
rc<uintptr_t>(w.get()), (w->m_isMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), sc<int>(w->m_realPosition->goal().x),
sc<int>(w->m_realPosition->goal().y), sc<int>(w->m_realSize->goal().x), sc<int>(w->m_realSize->goal().y), w->m_workspace ? w->workspaceID() : WORKSPACE_INVALID,
@ -403,7 +404,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
(sc<int>(w->m_isX11) == 1 ? "true" : "false"), (w->m_pinned ? "true" : "false"), sc<uint8_t>(w->m_fullscreenState.internal), sc<uint8_t>(w->m_fullscreenState.client),
(w->m_createdOverFullscreen ? "true" : "false"), getGroupedData(w, format), getTagsData(w, format), rc<uintptr_t>(w->m_swallowed.get()), getFocusHistoryID(w),
(g_pInputManager->isWindowInhibiting(w, false) ? "true" : "false"), escapeJSONStrings(w->xdgTag().value_or("")), escapeJSONStrings(w->xdgDescription().value_or("")),
escapeJSONStrings(NContentType::toString(w->getContentType())));
escapeJSONStrings(NContentType::toString(w->getContentType())), w->m_stableID);
} else {
return std::format(
"Window {:x} -> {}:\n\tmapped: {}\n\thidden: {}\n\tat: {},{}\n\tsize: {},{}\n\tworkspace: {} ({})\n\tfloating: {}\n\tpseudo: {}\n\tmonitor: {}\n\tclass: {}\n\ttitle: "
@ -411,13 +412,14 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) {
"{}\n\txwayland: {}\n\tpinned: "
"{}\n\tfullscreen: {}\n\tfullscreenClient: {}\n\toverFullscreen: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\tinhibitingIdle: "
"{}\n\txdgTag: "
"{}\n\txdgDescription: {}\n\tcontentType: {}\n\n",
"{}\n\txdgDescription: {}\n\tcontentType: {}\n\tstableID: {:x}\n\n",
rc<uintptr_t>(w.get()), w->m_title, sc<int>(w->m_isMapped), sc<int>(w->isHidden()), sc<int>(w->m_realPosition->goal().x), sc<int>(w->m_realPosition->goal().y),
sc<int>(w->m_realSize->goal().x), sc<int>(w->m_realSize->goal().y), w->m_workspace ? w->workspaceID() : WORKSPACE_INVALID,
(!w->m_workspace ? "" : w->m_workspace->m_name), sc<int>(w->m_isFloating), sc<int>(w->m_isPseudotiled), w->monitorID(), w->m_class, w->m_title, w->m_initialClass,
w->m_initialTitle, w->getPID(), sc<int>(w->m_isX11), sc<int>(w->m_pinned), sc<uint8_t>(w->m_fullscreenState.internal), sc<uint8_t>(w->m_fullscreenState.client),
sc<int>(w->m_createdOverFullscreen), getGroupedData(w, format), getTagsData(w, format), rc<uintptr_t>(w->m_swallowed.get()), getFocusHistoryID(w),
sc<int>(g_pInputManager->isWindowInhibiting(w, false)), w->xdgTag().value_or(""), w->xdgDescription().value_or(""), NContentType::toString(w->getContentType()));
sc<int>(g_pInputManager->isWindowInhibiting(w, false)), w->xdgTag().value_or(""), w->xdgDescription().value_or(""), NContentType::toString(w->getContentType()),
w->m_stableID);
}
}

View file

@ -53,6 +53,10 @@ using enum NContentType::eContentType;
using namespace Desktop;
using namespace Desktop::View;
// I wish I had an elven wife instead of a windowIDCounter
static uint64_t windowIDCounter = 0x18000000;
//
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
@ -105,7 +109,7 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
return pWindow;
}
CWindow::CWindow(SP<CXDGSurfaceResource> resource) : IView(CWLSurface::create()), m_xdgSurface(resource) {
CWindow::CWindow(SP<CXDGSurfaceResource> resource) : IView(CWLSurface::create()), m_xdgSurface(resource), m_stableID(windowIDCounter++) {
m_listeners.map = m_xdgSurface->m_events.map.listen([this] { mapWindow(); });
m_listeners.ack = m_xdgSurface->m_events.ack.listen([this](uint32_t d) { onAck(d); });
m_listeners.unmap = m_xdgSurface->m_events.unmap.listen([this] { unmapWindow(); });
@ -115,7 +119,7 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : IView(CWLSurface::create())
m_listeners.updateMetadata = m_xdgSurface->m_toplevel->m_events.metadataChanged.listen([this] { onUpdateMeta(); });
}
CWindow::CWindow(SP<CXWaylandSurface> surface) : IView(CWLSurface::create()), m_xwaylandSurface(surface) {
CWindow::CWindow(SP<CXWaylandSurface> surface) : IView(CWLSurface::create()), m_xwaylandSurface(surface), m_stableID(windowIDCounter++) {
m_listeners.map = m_xwaylandSurface->m_events.map.listen([this] { mapWindow(); });
m_listeners.unmap = m_xwaylandSurface->m_events.unmap.listen([this] { unmapWindow(); });
m_listeners.destroy = m_xwaylandSurface->m_events.destroy.listen([this] { destroyWindow(); });

View file

@ -239,6 +239,9 @@ namespace Desktop::View {
bool m_tearingHint = false;
// Stable ID for ext_foreign_toplevel_list
const uint64_t m_stableID = 0x2137;
// ANR
PHLANIMVAR<float> m_notRespondingTint;

View file

@ -54,26 +54,26 @@ void CForeignToplevelList::onMap(PHLWINDOW pWindow) {
std::erase_if(m_handles, [&](const auto& other) { return other.get() == OLDHANDLE.get(); });
}
const auto NEWHANDLE = PROTO::foreignToplevel->m_handles.emplace_back(
auto newHandle = PROTO::foreignToplevel->m_handles.emplace_back(
makeShared<CForeignToplevelHandle>(makeShared<CExtForeignToplevelHandleV1>(m_resource->client(), m_resource->version(), 0), pWindow));
if (!NEWHANDLE->good()) {
if (!newHandle->good()) {
LOGM(Log::ERR, "Couldn't create a foreign handle");
m_resource->noMemory();
PROTO::foreignToplevel->m_handles.pop_back();
return;
}
const auto IDENTIFIER = std::format("{:08x}->{:016x}", sc<uint32_t>(rc<uintptr_t>(this) & 0xFFFFFFFF), rc<uintptr_t>(pWindow.get()));
const auto IDENTIFIER = std::format("{:x}", pWindow->m_stableID);
LOGM(Log::DEBUG, "Newly mapped window gets an identifier of {}", IDENTIFIER);
m_resource->sendToplevel(NEWHANDLE->m_resource.get());
NEWHANDLE->m_resource->sendIdentifier(IDENTIFIER.c_str());
NEWHANDLE->m_resource->sendAppId(pWindow->m_initialClass.c_str());
NEWHANDLE->m_resource->sendTitle(pWindow->m_initialTitle.c_str());
NEWHANDLE->m_resource->sendDone();
m_resource->sendToplevel(newHandle->m_resource.get());
newHandle->m_resource->sendIdentifier(IDENTIFIER.c_str());
newHandle->m_resource->sendAppId(pWindow->m_initialClass.c_str());
newHandle->m_resource->sendTitle(pWindow->m_initialTitle.c_str());
newHandle->m_resource->sendDone();
m_handles.push_back(NEWHANDLE);
m_handles.emplace_back(std::move(newHandle));
}
SP<CForeignToplevelHandle> CForeignToplevelList::handleForWindow(PHLWINDOW pWindow) {