summaryrefslogtreecommitdiff
path: root/src/events/Monitors.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2023-11-01 18:53:36 +0000
committerGitHub <noreply@github.com>2023-11-01 18:53:36 +0000
commit21e9313c100e005ec2a9a5100c29258a2885546b (patch)
treedcda791982f3aa2b3e4939be67cdda11fd7023e3 /src/events/Monitors.cpp
parent7b32b4214d028a173c8192bddaa9e43503326080 (diff)
Core: various unsafe state improvements (#3713)
Fixes #3637
Diffstat (limited to 'src/events/Monitors.cpp')
-rw-r--r--src/events/Monitors.cpp54
1 files changed, 16 insertions, 38 deletions
diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp
index fa36c53c..f6375edd 100644
--- a/src/events/Monitors.cpp
+++ b/src/events/Monitors.cpp
@@ -67,52 +67,31 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
return;
}
- if (g_pCompositor->m_bUnsafeState)
- Debug::log(WARN, "Recovering from an unsafe state. May you be lucky.");
-
// add it to real
std::shared_ptr<CMonitor>* PNEWMONITORWRAP = nullptr;
PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared<CMonitor>());
+ if (std::string("HEADLESS-1") == OUTPUT->name)
+ g_pCompositor->m_pUnsafeOutput = PNEWMONITORWRAP->get();
- (*PNEWMONITORWRAP)->ID = g_pCompositor->getNextAvailableMonitorID(OUTPUT->name);
+ (*PNEWMONITORWRAP)->output = OUTPUT;
+ const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? OUTPUT == g_pCompositor->m_pUnsafeOutput->output : false;
+ (*PNEWMONITORWRAP)->ID = FALLBACK ? -1 : g_pCompositor->getNextAvailableMonitorID(OUTPUT->name);
+ const auto PNEWMONITOR = PNEWMONITORWRAP->get();
+ PNEWMONITOR->isUnsafeFallback = FALLBACK;
- const auto PNEWMONITOR = PNEWMONITORWRAP->get();
+ if (!FALLBACK)
+ PNEWMONITOR->onConnect(false);
- PNEWMONITOR->output = OUTPUT;
- PNEWMONITOR->m_pThisWrap = PNEWMONITORWRAP;
+ if (!PNEWMONITOR->m_bEnabled || FALLBACK)
+ return;
- PNEWMONITOR->onConnect(false);
+ // ready to process if we have a real monitor
if ((!g_pHyprRenderer->m_pMostHzMonitor || PNEWMONITOR->refreshRate > g_pHyprRenderer->m_pMostHzMonitor->refreshRate) && PNEWMONITOR->m_bEnabled)
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
- // wlroots will instantly call this handler before we get a return to the wlr_output* in CCompositor::enterUnsafeState
- const bool PROBABLYFALLBACK = (g_pCompositor->m_bUnsafeState && !g_pCompositor->m_pUnsafeOutput) || OUTPUT == g_pCompositor->m_pUnsafeOutput;
-
- // ready to process if we have a real monitor
- if (PNEWMONITOR->m_bEnabled && !PROBABLYFALLBACK) {
- // leave unsafe state
- if (g_pCompositor->m_bUnsafeState) {
- // recover workspaces
- std::vector<CWorkspace*> wsp;
- for (auto& ws : g_pCompositor->m_vWorkspaces) {
- wsp.push_back(ws.get());
- }
- for (auto& ws : wsp) {
- // because this can realloc the vec
- g_pCompositor->moveWorkspaceToMonitor(ws, PNEWMONITOR);
- }
-
- g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
-
- const auto POS = PNEWMONITOR->middle();
- if (g_pCompositor->m_sSeat.mouse)
- wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, POS.x, POS.y);
- }
-
- g_pCompositor->m_bReadyToProcess = true;
- }
+ g_pCompositor->m_bReadyToProcess = true;
g_pConfigManager->m_bWantsMonitorReload = true;
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR);
@@ -138,7 +117,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
if ((g_pCompositor->m_sWLRSession && !g_pCompositor->m_sWLRSession->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
Debug::log(WARN, "Attempted to render frame on inactive session!");
- if (g_pCompositor->m_bUnsafeState && PMONITOR->output != g_pCompositor->m_pUnsafeOutput) {
+ if (g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& m) {
+ return m->output != g_pCompositor->m_pUnsafeOutput->output;
+ })) {
// restore from unsafe state
g_pCompositor->leaveUnsafeState();
}
@@ -218,9 +199,6 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
pMonitor->output = nullptr;
pMonitor->m_bRenderingInitPassed = false;
- if (g_pCompositor->m_pUnsafeOutput == OUTPUT)
- g_pCompositor->m_pUnsafeOutput = nullptr;
-
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
std::erase_if(g_pCompositor->m_vRealMonitors, [&](std::shared_ptr<CMonitor>& el) { return el.get() == pMonitor; });