diff options
| author | Vaxry <vaxry@vaxry.net> | 2024-06-09 22:28:51 +0200 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2024-06-10 00:06:42 +0200 |
| commit | 1423707dbefc0329e80895451903a77ab684f7ea (patch) | |
| tree | 046e0592451a0470387a0ac649535d7263582e9e /src/managers/ProtocolManager.cpp | |
| parent | 121c6ac3eae1601a1498e52a9be7030ebfed242c (diff) | |
output: remove wl_output globals for mirrored displays
ref #6387
Diffstat (limited to 'src/managers/ProtocolManager.cpp')
| -rw-r--r-- | src/managers/ProtocolManager.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 7946a3f7..74cebd0c 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -46,21 +46,47 @@ #include "../helpers/Monitor.hpp" #include "../render/Renderer.hpp" +void CProtocolManager::onMonitorModeChange(CMonitor* pMonitor) { + const bool ISMIRROR = pMonitor->isMirror(); + + // onModeChanged we check if the current mirror status matches the global. + // mirrored outputs should have their global removed, as they are not physical parts of the + // layout. + + if (ISMIRROR && PROTO::outputs.contains(pMonitor->szName)) + PROTO::outputs.at(pMonitor->szName)->remove(); + else if (!ISMIRROR && (!PROTO::outputs.contains(pMonitor->szName) || PROTO::outputs.at(pMonitor->szName)->isDefunct())) { + if (PROTO::outputs.contains(pMonitor->szName)) + PROTO::outputs.erase(pMonitor->szName); + PROTO::outputs.emplace(pMonitor->szName, + std::make_unique<CWLOutputProtocol>(&wl_output_interface, 4, std::format("WLOutput ({})", pMonitor->szName), pMonitor->self.lock())); + } +} + CProtocolManager::CProtocolManager() { // Outputs are a bit dumb, we have to agree. - static auto P = g_pHookSystem->hookDynamic("monitorAdded", [](void* self, SCallbackInfo& info, std::any param) { + static auto P = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any param) { auto M = std::any_cast<CMonitor*>(param); + + // ignore mirrored outputs. I don't think this will ever be hit as mirrors are applied after + // this event is emitted iirc. + if (M->isMirror()) + return; + if (PROTO::outputs.contains(M->szName)) PROTO::outputs.erase(M->szName); PROTO::outputs.emplace(M->szName, std::make_unique<CWLOutputProtocol>(&wl_output_interface, 4, std::format("WLOutput ({})", M->szName), M->self.lock())); + + m_mModeChangeListeners[M->szName] = M->events.modeChanged.registerListener([M, this](std::any d) { onMonitorModeChange(M); }); }); - static auto P2 = g_pHookSystem->hookDynamic("monitorRemoved", [](void* self, SCallbackInfo& info, std::any param) { + static auto P2 = g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) { auto M = std::any_cast<CMonitor*>(param); if (!PROTO::outputs.contains(M->szName)) return; PROTO::outputs.at(M->szName)->remove(); + m_mModeChangeListeners.erase(M->szName); }); // Core |
