aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2022-05-30 17:11:35 +0200
committervaxerski <[email protected]>2022-05-30 17:11:35 +0200
commitc44c79abb269da36b68d0524f45aa4c0b92dedca (patch)
tree3f26da11b68bbab2b3f736a08ac0266c551cb2cd
parent1e096f6fcd514b6e2c9d5dbd2b1bbcbcb3c9b4a5 (diff)
downloadHyprland-c44c79abb269da36b68d0524f45aa4c0b92dedca.tar.gz
Hyprland-c44c79abb269da36b68d0524f45aa4c0b92dedca.zip
fix monitor cleanups on removed
-rw-r--r--src/Compositor.cpp19
-rw-r--r--src/Compositor.hpp2
-rw-r--r--src/events/Layers.cpp14
-rw-r--r--src/events/Monitors.cpp41
-rw-r--r--src/managers/KeybindManager.hpp2
5 files changed, 72 insertions, 6 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 0b60369d..4239c7bf 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -936,4 +936,21 @@ void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
else
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
-} \ No newline at end of file
+}
+
+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;
+}
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index d2839103..e866cdc2 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -126,6 +126,8 @@ public:
SMonitor* getMonitorInDirection(const char&);
void updateAllWindowsBorders();
void updateWindowBorderColor(CWindow*);
+ void moveWindowToWorkspace(CWindow*, const std::string&);
+ int getNextAvailableMonitorID();
private:
void initAllSignals();
diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp
index d5ad2245..7baeda67 100644
--- a/src/events/Layers.cpp
+++ b/src/events/Layers.cpp
@@ -58,7 +58,12 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
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.");
layersurface->alpha.setValueAndWarp(0.f);
layersurface->fadingOut = true;
@@ -70,8 +75,6 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
layersurface->hyprListener_unmapLayerSurface.removeCallback();
layersurface->hyprListener_newPopup.removeCallback();
- const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
-
// rearrange to fix the reserved areas
if (PMONITOR) {
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);
+ if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) {
+ Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
+ return;
+ }
+
// make a snapshot and start fade
g_pHyprOpenGL->makeLayerSnapshot(layersurface);
layersurface->alpha = 0.f;
diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp
index 2e05d278..13f99749 100644
--- a/src/events/Monitors.cpp
+++ b/src/events/Monitors.cpp
@@ -70,7 +70,7 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
SMonitor newMonitor;
newMonitor.output = OUTPUT;
- newMonitor.ID = g_pCompositor->m_lMonitors.size();
+ newMonitor.ID = g_pCompositor->getNextAvailableMonitorID();
newMonitor.szName = OUTPUT->name;
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)
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);
- // 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;
+ }
}
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index cf9b36d2..849b518c 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -51,6 +51,8 @@ private:
static void moveCursorToCorner(std::string);
static void workspaceOpt(std::string);
static void exitHyprland(std::string);
+
+ friend class CCompositor;
};
inline std::unique_ptr<CKeybindManager> g_pKeybindManager; \ No newline at end of file