fix monitor cleanups on removed

This commit is contained in:
vaxerski 2022-05-30 17:11:35 +02:00
parent 1e096f6fcd
commit c44c79abb2
5 changed files with 72 additions and 6 deletions

View file

@ -936,4 +936,21 @@ void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
pWindow->m_cRealBorderColor = RENDERDATA.borderColor; pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
else else
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL); pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
} }
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
m_pLastWindow = pWindow;
g_pKeybindManager->moveActiveToWorkspace(work);
g_pInputManager->refocus();
}
int CCompositor::getNextAvailableMonitorID() {
int64_t topID = -1;
for (auto& m : m_lMonitors) {
if ((int64_t)m.ID > topID)
topID = m.ID;
}
return topID + 1;
}

View file

@ -126,6 +126,8 @@ public:
SMonitor* getMonitorInDirection(const char&); SMonitor* getMonitorInDirection(const char&);
void updateAllWindowsBorders(); void updateAllWindowsBorders();
void updateWindowBorderColor(CWindow*); void updateWindowBorderColor(CWindow*);
void moveWindowToWorkspace(CWindow*, const std::string&);
int getNextAvailableMonitorID();
private: private:
void initAllSignals(); void initAllSignals();

View file

@ -58,7 +58,12 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
Debug::log(LOG, "LayerSurface %x destroyed", layersurface->layerSurface); Debug::log(LOG, "LayerSurface %x destroyed", layersurface->layerSurface);
if (!layersurface->fadingOut) { const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID))
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
if (!layersurface->fadingOut && PMONITOR) {
Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
layersurface->alpha.setValueAndWarp(0.f); layersurface->alpha.setValueAndWarp(0.f);
layersurface->fadingOut = true; layersurface->fadingOut = true;
@ -70,8 +75,6 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
layersurface->hyprListener_unmapLayerSurface.removeCallback(); layersurface->hyprListener_unmapLayerSurface.removeCallback();
layersurface->hyprListener_newPopup.removeCallback(); layersurface->hyprListener_newPopup.removeCallback();
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
// rearrange to fix the reserved areas // rearrange to fix the reserved areas
if (PMONITOR) { if (PMONITOR) {
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
@ -131,6 +134,11 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface); Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface);
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) {
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
return;
}
// make a snapshot and start fade // make a snapshot and start fade
g_pHyprOpenGL->makeLayerSnapshot(layersurface); g_pHyprOpenGL->makeLayerSnapshot(layersurface);
layersurface->alpha = 0.f; layersurface->alpha = 0.f;

View file

@ -70,7 +70,7 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
SMonitor newMonitor; SMonitor newMonitor;
newMonitor.output = OUTPUT; newMonitor.output = OUTPUT;
newMonitor.ID = g_pCompositor->m_lMonitors.size(); newMonitor.ID = g_pCompositor->getNextAvailableMonitorID();
newMonitor.szName = OUTPUT->name; newMonitor.szName = OUTPUT->name;
wlr_output_init_render(OUTPUT, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer); wlr_output_init_render(OUTPUT, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
@ -296,7 +296,44 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
if (!pMonitor) if (!pMonitor)
return; return;
// Cleanup everything. Move windows back, snap cursor, shit.
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
if (!BACKUPMON) {
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
g_pCompositor->cleanupExit();
return;
}
// snap cursor
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
// move windows
for (auto& w : g_pCompositor->m_lWindows) {
if (w.m_iMonitorID == pMonitor->ID) {
g_pCompositor->moveWindowToWorkspace(&w, BACKUPWORKSPACE);
}
}
g_pCompositor->sanityCheckWorkspaces();
Debug::log(LOG, "Removed monitor %s!", pMonitor->szName.c_str());
g_pCompositor->m_lMonitors.remove(*pMonitor); g_pCompositor->m_lMonitors.remove(*pMonitor);
// TODO: cleanup windows // update the pMostHzMonitor
if (pMostHzMonitor == pMonitor) {
int mostHz = 0;
SMonitor* pMonitorMostHz = nullptr;
for (auto& m : g_pCompositor->m_lMonitors) {
if (m.refreshRate > mostHz) {
pMonitorMostHz = &m;
mostHz = m.refreshRate;
}
}
pMostHzMonitor = pMonitorMostHz;
}
} }

View file

@ -51,6 +51,8 @@ private:
static void moveCursorToCorner(std::string); static void moveCursorToCorner(std::string);
static void workspaceOpt(std::string); static void workspaceOpt(std::string);
static void exitHyprland(std::string); static void exitHyprland(std::string);
friend class CCompositor;
}; };
inline std::unique_ptr<CKeybindManager> g_pKeybindManager; inline std::unique_ptr<CKeybindManager> g_pKeybindManager;