Hyprland/src/protocols/ForeignToplevelWlr.cpp

434 lines
14 KiB
C++
Raw Normal View History

2024-04-25 00:58:40 +01:00
#include "ForeignToplevelWlr.hpp"
#include <algorithm>
#include "../Compositor.hpp"
#include "managers/input/InputManager.hpp"
#include "protocols/core/Output.hpp"
#include "render/Renderer.hpp"
#include "../managers/HookSystemManager.hpp"
#include "../managers/EventManager.hpp"
2024-04-25 00:58:40 +01:00
CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, PHLWINDOW pWindow_) : m_resource(resource_), m_window(pWindow_) {
if UNLIKELY (!resource_->resource())
2024-04-25 00:58:40 +01:00
return;
m_resource->setData(this);
m_resource->setOnDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); });
m_resource->setDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); });
2024-04-25 00:58:40 +01:00
m_resource->setActivate([this](CZwlrForeignToplevelHandleV1* p, wl_resource* seat) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
// these requests bypass the config'd stuff cuz it's usually like
// window switchers and shit
PWINDOW->activate(true);
g_pInputManager->simulateMouseMovement();
2024-04-25 00:58:40 +01:00
});
m_resource->setSetFullscreen([this](CZwlrForeignToplevelHandleV1* p, wl_resource* output) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (PWINDOW->m_suppressedEvents & SUPPRESS_FULLSCREEN)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (!PWINDOW->m_isMapped) {
PWINDOW->m_wantsInitialFullscreen = true;
2024-04-25 00:58:40 +01:00
return;
}
if (output) {
const auto wpMonitor = CWLOutputResource::fromResource(output)->m_monitor;
if (!wpMonitor.expired()) {
const auto monitor = wpMonitor.lock();
if (PWINDOW->m_workspace != monitor->m_activeWorkspace) {
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, monitor->m_activeWorkspace);
g_pCompositor->setActiveMonitor(monitor);
}
}
}
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_FULLSCREEN, true);
g_pHyprRenderer->damageWindow(PWINDOW);
2024-04-25 00:58:40 +01:00
});
m_resource->setUnsetFullscreen([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (PWINDOW->m_suppressedEvents & SUPPRESS_FULLSCREEN)
2024-04-25 00:58:40 +01:00
return;
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_FULLSCREEN, false);
2024-04-25 00:58:40 +01:00
});
m_resource->setSetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (PWINDOW->m_suppressedEvents & SUPPRESS_MAXIMIZE)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (!PWINDOW->m_isMapped) {
PWINDOW->m_wantsInitialFullscreen = true;
2024-04-25 00:58:40 +01:00
return;
}
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_MAXIMIZED, true);
2024-04-25 00:58:40 +01:00
});
m_resource->setUnsetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
if UNLIKELY (PWINDOW->m_suppressedEvents & SUPPRESS_MAXIMIZE)
2024-04-25 00:58:40 +01:00
return;
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_MAXIMIZED, false);
2024-04-25 00:58:40 +01:00
});
m_resource->setSetMinimized([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
return;
if UNLIKELY (!PWINDOW->m_isMapped)
return;
g_pEventManager->postEvent(SHyprIPCEvent{.event = "minimized", .data = std::format("{:x},1", (uintptr_t)PWINDOW.get())});
});
m_resource->setUnsetMinimized([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
return;
if UNLIKELY (!PWINDOW->m_isMapped)
return;
g_pEventManager->postEvent(SHyprIPCEvent{.event = "minimized", .data = std::format("{:x},0", (uintptr_t)PWINDOW.get())});
});
m_resource->setClose([this](CZwlrForeignToplevelHandleV1* p) {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW)
2024-04-25 00:58:40 +01:00
return;
g_pCompositor->closeWindow(PWINDOW);
2024-04-25 00:58:40 +01:00
});
}
bool CForeignToplevelHandleWlr::good() {
return m_resource->resource();
2024-04-25 00:58:40 +01:00
}
PHLWINDOW CForeignToplevelHandleWlr::window() {
return m_window.lock();
2024-04-25 00:58:40 +01:00
}
wl_resource* CForeignToplevelHandleWlr::res() {
return m_resource->resource();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelHandleWlr::sendMonitor(PHLMONITOR pMonitor) {
if (m_lastMonitorID == pMonitor->m_id)
2024-04-25 00:58:40 +01:00
return;
const auto CLIENT = m_resource->client();
2024-04-25 00:58:40 +01:00
if (const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_lastMonitorID); PLASTMONITOR && PROTO::outputs.contains(PLASTMONITOR->m_name)) {
const auto OLDRESOURCE = PROTO::outputs.at(PLASTMONITOR->m_name)->outputResourceFrom(CLIENT);
2024-04-25 00:58:40 +01:00
if LIKELY (OLDRESOURCE)
m_resource->sendOutputLeave(OLDRESOURCE->getResource()->resource());
2024-04-25 00:58:40 +01:00
}
if (PROTO::outputs.contains(pMonitor->m_name)) {
const auto NEWRESOURCE = PROTO::outputs.at(pMonitor->m_name)->outputResourceFrom(CLIENT);
2024-04-25 00:58:40 +01:00
if LIKELY (NEWRESOURCE)
m_resource->sendOutputEnter(NEWRESOURCE->getResource()->resource());
}
2024-04-25 00:58:40 +01:00
m_lastMonitorID = pMonitor->m_id;
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelHandleWlr::sendState() {
const auto PWINDOW = m_window.lock();
if UNLIKELY (!PWINDOW || !PWINDOW->m_workspace || !PWINDOW->m_isMapped)
2024-04-25 00:58:40 +01:00
return;
wl_array state;
wl_array_init(&state);
if (PWINDOW == g_pCompositor->m_lastWindow) {
2024-04-25 00:58:40 +01:00
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
}
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
if (PWINDOW->isFullscreen()) {
2024-04-25 00:58:40 +01:00
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
if (PWINDOW->isEffectiveInternalFSMode(FSMODE_FULLSCREEN))
2024-04-25 00:58:40 +01:00
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
else
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
}
m_resource->sendState(&state);
2024-04-25 00:58:40 +01:00
wl_array_release(&state);
}
CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!resource_->resource())
2024-04-25 00:58:40 +01:00
return;
m_resource->setOnDestroy([this](CZwlrForeignToplevelManagerV1* h) { PROTO::foreignToplevelWlr->onManagerResourceDestroy(this); });
2024-04-25 00:58:40 +01:00
m_resource->setStop([this](CZwlrForeignToplevelManagerV1* h) {
m_resource->sendFinished();
m_finished = true;
2024-04-25 00:58:40 +01:00
LOGM(LOG, "CForeignToplevelWlrManager: finished");
PROTO::foreignToplevelWlr->onManagerResourceDestroy(this);
});
for (auto const& w : g_pCompositor->m_windows) {
if (!PROTO::foreignToplevelWlr->windowValidForForeign(w))
2024-04-25 00:58:40 +01:00
continue;
onMap(w);
2024-04-25 00:58:40 +01:00
}
m_lastFocus = g_pCompositor->m_lastWindow;
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto NEWHANDLE = PROTO::foreignToplevelWlr->m_handles.emplace_back(
makeShared<CForeignToplevelHandleWlr>(makeShared<CZwlrForeignToplevelHandleV1>(m_resource->client(), m_resource->version(), 0), pWindow));
2024-04-25 00:58:40 +01:00
if UNLIKELY (!NEWHANDLE->good()) {
2024-04-25 00:58:40 +01:00
LOGM(ERR, "Couldn't create a foreign handle");
m_resource->noMemory();
PROTO::foreignToplevelWlr->m_handles.pop_back();
2024-04-25 00:58:40 +01:00
return;
}
LOGM(LOG, "Newly mapped window {:016x}", (uintptr_t)pWindow.get());
m_resource->sendToplevel(NEWHANDLE->m_resource.get());
NEWHANDLE->m_resource->sendAppId(pWindow->m_class.c_str());
NEWHANDLE->m_resource->sendTitle(pWindow->m_title.c_str());
if LIKELY (const auto PMONITOR = pWindow->m_monitor.lock(); PMONITOR)
2024-04-25 00:58:40 +01:00
NEWHANDLE->sendMonitor(PMONITOR);
NEWHANDLE->sendState();
NEWHANDLE->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
m_handles.push_back(NEWHANDLE);
2024-04-25 00:58:40 +01:00
}
SP<CForeignToplevelHandleWlr> CForeignToplevelWlrManager::handleForWindow(PHLWINDOW pWindow) {
std::erase_if(m_handles, [](const auto& wp) { return wp.expired(); });
const auto IT = std::ranges::find_if(m_handles, [pWindow](const auto& h) { return h->window() == pWindow; });
return IT == m_handles.end() ? SP<CForeignToplevelHandleWlr>{} : IT->lock();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onTitle(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H || H->m_closed)
2024-04-25 00:58:40 +01:00
return;
H->m_resource->sendTitle(pWindow->m_title.c_str());
H->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onClass(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H || H->m_closed)
2024-04-25 00:58:40 +01:00
return;
H->m_resource->sendAppId(pWindow->m_class.c_str());
H->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onUnmap(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H)
2024-04-25 00:58:40 +01:00
return;
H->m_resource->sendClosed();
H->m_resource->sendDone();
H->m_closed = true;
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onMoveMonitor(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H || H->m_closed)
2024-04-25 00:58:40 +01:00
return;
const auto PMONITOR = pWindow->m_monitor.lock();
2024-04-25 00:58:40 +01:00
if UNLIKELY (!PMONITOR)
2024-04-25 00:58:40 +01:00
return;
H->sendMonitor(PMONITOR);
H->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onFullscreen(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H || H->m_closed)
2024-04-25 00:58:40 +01:00
return;
H->sendState();
H->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrManager::onNewFocus(PHLWINDOW pWindow) {
if UNLIKELY (m_finished)
2024-04-25 00:58:40 +01:00
return;
if LIKELY (const auto HOLD = handleForWindow(m_lastFocus.lock()); HOLD) {
2024-04-25 00:58:40 +01:00
HOLD->sendState();
HOLD->m_resource->sendDone();
}
2024-04-25 00:58:40 +01:00
m_lastFocus = pWindow;
2024-04-25 00:58:40 +01:00
const auto H = handleForWindow(pWindow);
if UNLIKELY (!H || H->m_closed)
2024-04-25 00:58:40 +01:00
return;
H->sendState();
H->m_resource->sendDone();
2024-04-25 00:58:40 +01:00
}
bool CForeignToplevelWlrManager::good() {
return m_resource->resource();
2024-04-25 00:58:40 +01:00
}
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<PHLWINDOW>(data);
if (!windowValidForForeign(PWINDOW))
return;
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onMap(PWINDOW);
}
});
static auto P1 = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
if (!windowValidForForeign(PWINDOW))
return;
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onUnmap(PWINDOW);
}
});
static auto P2 = g_pHookSystem->hookDynamic("windowTitle", [this](void* self, SCallbackInfo& info, std::any data) {
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
if (!windowValidForForeign(PWINDOW))
return;
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onTitle(PWINDOW);
}
});
static auto P3 = g_pHookSystem->hookDynamic("activeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
if (PWINDOW && !windowValidForForeign(PWINDOW))
return;
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onNewFocus(PWINDOW);
}
});
static auto P4 = g_pHookSystem->hookDynamic("moveWindow", [this](void* self, SCallbackInfo& info, std::any data) {
const auto PWINDOW = std::any_cast<PHLWINDOW>(std::any_cast<std::vector<std::any>>(data).at(0));
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onMoveMonitor(PWINDOW);
}
});
static auto P5 = g_pHookSystem->hookDynamic("fullscreen", [this](void* self, SCallbackInfo& info, std::any data) {
const auto PWINDOW = std::any_cast<PHLWINDOW>(data);
if (!windowValidForForeign(PWINDOW))
return;
for (auto const& m : m_managers) {
2024-04-25 00:58:40 +01:00
m->onFullscreen(PWINDOW);
}
});
}
void CForeignToplevelWlrProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_managers.emplace_back(makeUnique<CForeignToplevelWlrManager>(makeShared<CZwlrForeignToplevelManagerV1>(client, ver, id))).get();
2024-04-25 00:58:40 +01:00
if UNLIKELY (!RESOURCE->good()) {
2024-04-25 00:58:40 +01:00
LOGM(ERR, "Couldn't create a foreign list");
wl_client_post_no_memory(client);
m_managers.pop_back();
2024-04-25 00:58:40 +01:00
return;
}
}
void CForeignToplevelWlrProtocol::onManagerResourceDestroy(CForeignToplevelWlrManager* mgr) {
std::erase_if(m_managers, [&](const auto& other) { return other.get() == mgr; });
2024-04-25 00:58:40 +01:00
}
void CForeignToplevelWlrProtocol::destroyHandle(CForeignToplevelHandleWlr* handle) {
std::erase_if(m_handles, [&](const auto& other) { return other.get() == handle; });
2024-04-25 00:58:40 +01:00
}
PHLWINDOW CForeignToplevelWlrProtocol::windowFromHandleResource(wl_resource* res) {
auto data = (CForeignToplevelHandleWlr*)(((CZwlrForeignToplevelHandleV1*)wl_resource_get_user_data(res))->data());
return data ? data->window() : nullptr;
}
bool CForeignToplevelWlrProtocol::windowValidForForeign(PHLWINDOW pWindow) {
return validMapped(pWindow) && !pWindow->isX11OverrideRedirect();
}