mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-07 22:26:00 +01:00
parent
7b32b4214d
commit
21e9313c10
10 changed files with 128 additions and 121 deletions
|
@ -463,6 +463,25 @@ void CCompositor::removeLockFile() {
|
||||||
std::filesystem::remove(PATH);
|
std::filesystem::remove(PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCompositor::prepareFallbackOutput() {
|
||||||
|
// create a backup monitor
|
||||||
|
wlr_backend* headless = nullptr;
|
||||||
|
wlr_multi_for_each_backend(
|
||||||
|
m_sWLRBackend,
|
||||||
|
[](wlr_backend* b, void* data) {
|
||||||
|
if (wlr_backend_is_headless(b))
|
||||||
|
*((wlr_backend**)data) = b;
|
||||||
|
},
|
||||||
|
&headless);
|
||||||
|
|
||||||
|
if (!headless) {
|
||||||
|
Debug::log(WARN, "Unsafe state will be ineffective, no fallback output");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_headless_add_output(headless, 1920, 1080);
|
||||||
|
}
|
||||||
|
|
||||||
void CCompositor::startCompositor() {
|
void CCompositor::startCompositor() {
|
||||||
initAllSignals();
|
initAllSignals();
|
||||||
|
|
||||||
|
@ -514,6 +533,8 @@ void CCompositor::startCompositor() {
|
||||||
throwError("The backend could not start!");
|
throwError("The backend could not start!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareFallbackOutput();
|
||||||
|
|
||||||
g_pHyprRenderer->setCursorFromName("left_ptr");
|
g_pHyprRenderer->setCursorFromName("left_ptr");
|
||||||
|
|
||||||
#ifdef USES_SYSTEMD
|
#ifdef USES_SYSTEMD
|
||||||
|
@ -2657,24 +2678,10 @@ void CCompositor::enterUnsafeState() {
|
||||||
|
|
||||||
Debug::log(LOG, "Entering unsafe state");
|
Debug::log(LOG, "Entering unsafe state");
|
||||||
|
|
||||||
|
if (!m_pUnsafeOutput->m_bEnabled)
|
||||||
|
m_pUnsafeOutput->onConnect(false);
|
||||||
|
|
||||||
m_bUnsafeState = true;
|
m_bUnsafeState = true;
|
||||||
|
|
||||||
// create a backup monitor
|
|
||||||
wlr_backend* headless = nullptr;
|
|
||||||
wlr_multi_for_each_backend(
|
|
||||||
m_sWLRBackend,
|
|
||||||
[](wlr_backend* b, void* data) {
|
|
||||||
if (wlr_backend_is_headless(b))
|
|
||||||
*((wlr_backend**)data) = b;
|
|
||||||
},
|
|
||||||
&headless);
|
|
||||||
|
|
||||||
if (!headless) {
|
|
||||||
Debug::log(WARN, "Entering an unsafe state without a headless backend");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pUnsafeOutput = wlr_headless_add_output(headless, 1920, 1080);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCompositor::leaveUnsafeState() {
|
void CCompositor::leaveUnsafeState() {
|
||||||
|
@ -2685,10 +2692,22 @@ void CCompositor::leaveUnsafeState() {
|
||||||
|
|
||||||
m_bUnsafeState = false;
|
m_bUnsafeState = false;
|
||||||
|
|
||||||
if (m_pUnsafeOutput)
|
CMonitor* pNewMonitor = nullptr;
|
||||||
wlr_output_destroy(m_pUnsafeOutput);
|
for (auto& pMonitor : m_vMonitors) {
|
||||||
|
if (pMonitor->output != m_pUnsafeOutput->output) {
|
||||||
|
pNewMonitor = pMonitor.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_pUnsafeOutput = nullptr;
|
RASSERT(pNewMonitor, "Tried to leave unsafe without a monitor");
|
||||||
|
|
||||||
|
if (m_pUnsafeOutput->m_bEnabled)
|
||||||
|
m_pUnsafeOutput->onDisconnect();
|
||||||
|
|
||||||
|
for (auto& m : m_vMonitors) {
|
||||||
|
scheduleFrameForMonitor(m.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scale) {
|
void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scale) {
|
||||||
|
|
|
@ -121,7 +121,8 @@ class CCompositor {
|
||||||
bool m_bSessionActive = true;
|
bool m_bSessionActive = true;
|
||||||
bool m_bDPMSStateON = true;
|
bool m_bDPMSStateON = true;
|
||||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||||
wlr_output* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
bool m_bNextIsUnsafe = false; // because wlroots
|
||||||
|
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||||
bool m_bIsShuttingDown = false;
|
bool m_bIsShuttingDown = false;
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
@ -215,6 +216,7 @@ class CCompositor {
|
||||||
void initAllSignals();
|
void initAllSignals();
|
||||||
void setRandomSplash();
|
void setRandomSplash();
|
||||||
void initManagers(eManagersInitStage stage);
|
void initManagers(eManagersInitStage stage);
|
||||||
|
void prepareFallbackOutput();
|
||||||
|
|
||||||
uint64_t m_iHyprlandPID = 0;
|
uint64_t m_iHyprlandPID = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -223,6 +223,9 @@ pid_t CWindow::getPID() {
|
||||||
|
|
||||||
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
|
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
if (!m_bIsMapped || !m_bMappedX11)
|
||||||
|
return -1;
|
||||||
|
|
||||||
PID = m_uSurface.xwayland->pid;
|
PID = m_uSurface.xwayland->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2066,7 +2066,7 @@ void CConfigManager::performMonitorReload() {
|
||||||
bool overAgain = false;
|
bool overAgain = false;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||||
if (!m->output)
|
if (!m->output || m->isUnsafeFallback)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto rule = getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
auto rule = getMonitorRuleFor(m->szName, m->output->description ? m->output->description : "");
|
||||||
|
@ -2147,16 +2147,14 @@ bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||||
|
|
||||||
void CConfigManager::ensureMonitorStatus() {
|
void CConfigManager::ensureMonitorStatus() {
|
||||||
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
||||||
if (!rm->output)
|
if (!rm->output || rm->isUnsafeFallback)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto rule = getMonitorRuleFor(rm->szName, rm->output->description ? rm->output->description : "");
|
auto rule = getMonitorRuleFor(rm->szName, rm->output->description ? rm->output->description : "");
|
||||||
|
|
||||||
if (rule.disabled == rm->m_bEnabled) {
|
if (rule.disabled == rm->m_bEnabled)
|
||||||
rm->m_pThisWrap = &rm;
|
|
||||||
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
|
|
|
@ -231,7 +231,7 @@ static std::string getWorkspaceData(CWorkspace* w, HyprCtl::eHyprCtlOutputFormat
|
||||||
"lastwindowtitle": "{}"
|
"lastwindowtitle": "{}"
|
||||||
}})#",
|
}})#",
|
||||||
w->m_iID, escapeJSONStrings(w->m_szName), escapeJSONStrings(PMONITOR ? PMONITOR->szName : "?"),
|
w->m_iID, escapeJSONStrings(w->m_szName), escapeJSONStrings(PMONITOR ? PMONITOR->szName : "?"),
|
||||||
escapeJSONStrings(PMONITOR ? std::to_string(PMONITOR->ID) : "undefined"), g_pCompositor->getWindowsOnWorkspace(w->m_iID),
|
escapeJSONStrings(PMONITOR ? std::to_string(PMONITOR->ID) : "null"), g_pCompositor->getWindowsOnWorkspace(w->m_iID),
|
||||||
((int)w->m_bHasFullscreenWindow == 1 ? "true" : "false"), (uintptr_t)PLASTW, PLASTW ? escapeJSONStrings(PLASTW->m_szTitle) : "");
|
((int)w->m_bHasFullscreenWindow == 1 ? "true" : "false"), (uintptr_t)PLASTW, PLASTW ? escapeJSONStrings(PLASTW->m_szTitle) : "");
|
||||||
} else {
|
} else {
|
||||||
return std::format("workspace ID {} ({}) on monitor {}:\n\tmonitorID: {}\n\twindows: {}\n\thasfullscreen: {}\n\tlastwindow: 0x{:x}\n\tlastwindowtitle: {}\n\n", w->m_iID,
|
return std::format("workspace ID {} ({}) on monitor {}:\n\tmonitorID: {}\n\twindows: {}\n\thasfullscreen: {}\n\tlastwindow: 0x{:x}\n\tlastwindowtitle: {}\n\n", w->m_iID,
|
||||||
|
|
|
@ -67,52 +67,31 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_pCompositor->m_bUnsafeState)
|
|
||||||
Debug::log(WARN, "Recovering from an unsafe state. May you be lucky.");
|
|
||||||
|
|
||||||
// add it to real
|
// add it to real
|
||||||
std::shared_ptr<CMonitor>* PNEWMONITORWRAP = nullptr;
|
std::shared_ptr<CMonitor>* PNEWMONITORWRAP = nullptr;
|
||||||
|
|
||||||
PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared<CMonitor>());
|
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();
|
const auto PNEWMONITOR = PNEWMONITORWRAP->get();
|
||||||
|
PNEWMONITOR->isUnsafeFallback = FALLBACK;
|
||||||
|
|
||||||
PNEWMONITOR->output = OUTPUT;
|
if (!FALLBACK)
|
||||||
PNEWMONITOR->m_pThisWrap = PNEWMONITORWRAP;
|
|
||||||
|
|
||||||
PNEWMONITOR->onConnect(false);
|
PNEWMONITOR->onConnect(false);
|
||||||
|
|
||||||
|
if (!PNEWMONITOR->m_bEnabled || FALLBACK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// ready to process if we have a real monitor
|
||||||
|
|
||||||
if ((!g_pHyprRenderer->m_pMostHzMonitor || PNEWMONITOR->refreshRate > g_pHyprRenderer->m_pMostHzMonitor->refreshRate) && PNEWMONITOR->m_bEnabled)
|
if ((!g_pHyprRenderer->m_pMostHzMonitor || PNEWMONITOR->refreshRate > g_pHyprRenderer->m_pMostHzMonitor->refreshRate) && PNEWMONITOR->m_bEnabled)
|
||||||
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
|
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_pConfigManager->m_bWantsMonitorReload = true;
|
||||||
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR);
|
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) {
|
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!");
|
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
|
// restore from unsafe state
|
||||||
g_pCompositor->leaveUnsafeState();
|
g_pCompositor->leaveUnsafeState();
|
||||||
}
|
}
|
||||||
|
@ -218,9 +199,6 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||||
pMonitor->output = nullptr;
|
pMonitor->output = nullptr;
|
||||||
pMonitor->m_bRenderingInitPassed = false;
|
pMonitor->m_bRenderingInitPassed = false;
|
||||||
|
|
||||||
if (g_pCompositor->m_pUnsafeOutput == OUTPUT)
|
|
||||||
g_pCompositor->m_pUnsafeOutput = nullptr;
|
|
||||||
|
|
||||||
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
|
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; });
|
std::erase_if(g_pCompositor->m_vRealMonitors, [&](std::shared_ptr<CMonitor>& el) { return el.get() == pMonitor; });
|
||||||
|
|
|
@ -851,8 +851,8 @@ void Events::listener_destroyWindow(void* owner, void* data) {
|
||||||
PWINDOW->m_bReadyToDelete = true;
|
PWINDOW->m_bReadyToDelete = true;
|
||||||
|
|
||||||
if (!PWINDOW->m_bFadingOut) {
|
if (!PWINDOW->m_bFadingOut) {
|
||||||
g_pCompositor->removeWindowFromVectorSafe(PWINDOW); // most likely X11 unmanaged or sumn
|
|
||||||
Debug::log(LOG, "Unmapped {} removed instantly", PWINDOW);
|
Debug::log(LOG, "Unmapped {} removed instantly", PWINDOW);
|
||||||
|
g_pCompositor->removeWindowFromVectorSafe(PWINDOW); // most likely X11 unmanaged or sumn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,20 +109,20 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
m_bRenderingInitPassed = true;
|
m_bRenderingInitPassed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_pThisWrap) {
|
std::shared_ptr<CMonitor>* thisWrapper = nullptr;
|
||||||
|
|
||||||
// find the wrap
|
// find the wrap
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||||
if (m->ID == ID) {
|
if (m->ID == ID) {
|
||||||
m_pThisWrap = &m;
|
thisWrapper = &m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end()) {
|
RASSERT(thisWrapper->get(), "CMonitor::onConnect: Had no wrapper???");
|
||||||
g_pCompositor->m_vMonitors.push_back(*m_pThisWrap);
|
|
||||||
}
|
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end())
|
||||||
|
g_pCompositor->m_vMonitors.push_back(*thisWrapper);
|
||||||
|
|
||||||
m_bEnabled = true;
|
m_bEnabled = true;
|
||||||
|
|
||||||
|
@ -132,6 +132,8 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
if (!noRule)
|
if (!noRule)
|
||||||
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true);
|
||||||
|
|
||||||
|
wlr_output_commit(output);
|
||||||
|
|
||||||
wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y);
|
wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y);
|
||||||
|
|
||||||
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, scale);
|
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, scale);
|
||||||
|
@ -152,8 +154,6 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
if (scale < 0.1)
|
if (scale < 0.1)
|
||||||
scale = getDefaultScale();
|
scale = getDefaultScale();
|
||||||
|
|
||||||
m_pThisWrap = nullptr;
|
|
||||||
|
|
||||||
forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -184,6 +184,8 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
g_pCompositor->setActiveMonitor(this);
|
g_pCompositor->setActiveMonitor(this);
|
||||||
|
|
||||||
renderTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, ratHandler, this);
|
renderTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, ratHandler, this);
|
||||||
|
|
||||||
|
g_pCompositor->scheduleFrameForMonitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::onDisconnect() {
|
void CMonitor::onDisconnect() {
|
||||||
|
@ -221,9 +223,6 @@ void CMonitor::onDisconnect() {
|
||||||
g_pConfigManager->m_bWantsMonitorReload = true;
|
g_pConfigManager->m_bWantsMonitorReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bEnabled = false;
|
|
||||||
m_bRenderingInitPassed = false;
|
|
||||||
|
|
||||||
hyprListener_monitorFrame.removeCallback();
|
hyprListener_monitorFrame.removeCallback();
|
||||||
hyprListener_monitorDamage.removeCallback();
|
hyprListener_monitorDamage.removeCallback();
|
||||||
hyprListener_monitorNeedsFrame.removeCallback();
|
hyprListener_monitorNeedsFrame.removeCallback();
|
||||||
|
@ -248,6 +247,9 @@ void CMonitor::onDisconnect() {
|
||||||
g_pCompositor->enterUnsafeState();
|
g_pCompositor->enterUnsafeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bEnabled = false;
|
||||||
|
m_bRenderingInitPassed = false;
|
||||||
|
|
||||||
if (BACKUPMON) {
|
if (BACKUPMON) {
|
||||||
// snap cursor
|
// snap cursor
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f,
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f,
|
||||||
|
@ -256,7 +258,7 @@ void CMonitor::onDisconnect() {
|
||||||
// move workspaces
|
// move workspaces
|
||||||
std::deque<CWorkspace*> wspToMove;
|
std::deque<CWorkspace*> wspToMove;
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||||
if (w->m_iMonitorID == ID) {
|
if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) {
|
||||||
wspToMove.push_back(w.get());
|
wspToMove.push_back(w.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,19 +416,22 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||||
vecPosition = RULE.offset;
|
vecPosition = RULE.offset;
|
||||||
|
|
||||||
// push to mvmonitors
|
// push to mvmonitors
|
||||||
if (!m_pThisWrap) {
|
|
||||||
|
std::shared_ptr<CMonitor>* thisWrapper = nullptr;
|
||||||
|
|
||||||
// find the wrap
|
// find the wrap
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
||||||
if (m->ID == ID) {
|
if (m->ID == ID) {
|
||||||
m_pThisWrap = &m;
|
thisWrapper = &m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
RASSERT(thisWrapper->get(), "CMonitor::setMirror: Had no wrapper???");
|
||||||
|
|
||||||
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) ==
|
if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) ==
|
||||||
g_pCompositor->m_vMonitors.end()) {
|
g_pCompositor->m_vMonitors.end()) {
|
||||||
g_pCompositor->m_vMonitors.push_back(*m_pThisWrap);
|
g_pCompositor->m_vMonitors.push_back(*thisWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupDefaultWS(RULE);
|
setupDefaultWS(RULE);
|
||||||
|
|
|
@ -66,6 +66,7 @@ class CMonitor {
|
||||||
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
||||||
bool createdByUser = false;
|
bool createdByUser = false;
|
||||||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||||
|
bool isUnsafeFallback = false;
|
||||||
|
|
||||||
bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after
|
bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after
|
||||||
bool renderingActive = false;
|
bool renderingActive = false;
|
||||||
|
@ -123,7 +124,6 @@ class CMonitor {
|
||||||
void moveTo(const Vector2D& pos);
|
void moveTo(const Vector2D& pos);
|
||||||
Vector2D middle();
|
Vector2D middle();
|
||||||
|
|
||||||
std::shared_ptr<CMonitor>* m_pThisWrap = nullptr;
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
bool m_bRenderingInitPassed = false;
|
bool m_bRenderingInitPassed = false;
|
||||||
|
|
||||||
|
|
|
@ -74,14 +74,8 @@ CXDGOutputProtocol::CXDGOutputProtocol(const wl_interface* iface, const int& ver
|
||||||
void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* outputResource) {
|
void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* outputResource) {
|
||||||
const auto OUTPUT = wlr_output_from_resource(outputResource);
|
const auto OUTPUT = wlr_output_from_resource(outputResource);
|
||||||
|
|
||||||
if (!OUTPUT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(OUTPUT);
|
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(OUTPUT);
|
||||||
|
|
||||||
if (!PMONITOR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(std::make_unique<SXDGOutput>(PMONITOR)).get();
|
SXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(std::make_unique<SXDGOutput>(PMONITOR)).get();
|
||||||
#ifndef NO_XWAYLAND
|
#ifndef NO_XWAYLAND
|
||||||
if (g_pXWaylandManager->m_sWLRXWayland && g_pXWaylandManager->m_sWLRXWayland->server && g_pXWaylandManager->m_sWLRXWayland->server->client == client)
|
if (g_pXWaylandManager->m_sWLRXWayland && g_pXWaylandManager->m_sWLRXWayland->server && g_pXWaylandManager->m_sWLRXWayland->server->client == client)
|
||||||
|
@ -99,6 +93,10 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* r
|
||||||
|
|
||||||
pXDGOutput->resource->setImplementation(&OUTPUT_IMPL, nullptr);
|
pXDGOutput->resource->setImplementation(&OUTPUT_IMPL, nullptr);
|
||||||
pXDGOutput->resource->setData(this);
|
pXDGOutput->resource->setData(this);
|
||||||
|
|
||||||
|
if (!PMONITOR)
|
||||||
|
return;
|
||||||
|
|
||||||
const auto XDGVER = pXDGOutput->resource->version();
|
const auto XDGVER = pXDGOutput->resource->version();
|
||||||
|
|
||||||
if (XDGVER >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
|
if (XDGVER >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
|
||||||
|
@ -116,7 +114,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* r
|
||||||
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
||||||
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
||||||
|
|
||||||
if (!pOutput->resource->good())
|
if (!pOutput->resource->good() || !pOutput->monitor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto POS = pOutput->isXWayland ? pOutput->monitor->vecXWaylandPosition : pOutput->monitor->vecPosition;
|
const auto POS = pOutput->isXWayland ? pOutput->monitor->vecXWaylandPosition : pOutput->monitor->vecPosition;
|
||||||
|
@ -133,6 +131,10 @@ void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
||||||
|
|
||||||
void CXDGOutputProtocol::updateAllOutputs() {
|
void CXDGOutputProtocol::updateAllOutputs() {
|
||||||
for (auto& o : m_vXDGOutputs) {
|
for (auto& o : m_vXDGOutputs) {
|
||||||
|
|
||||||
|
if (!o->monitor)
|
||||||
|
continue;
|
||||||
|
|
||||||
updateOutputDetails(o.get());
|
updateOutputDetails(o.get());
|
||||||
|
|
||||||
wlr_output_schedule_done(o->monitor->output);
|
wlr_output_schedule_done(o->monitor->output);
|
||||||
|
|
Loading…
Reference in a new issue