From 9f8a71322cc680a103ad4a592dac79c684b0a961 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Wed, 24 Nov 2021 21:50:44 +0100 Subject: [PATCH] Fixed some ghost window cases. (readme update too) --- README.md | 5 +++-- src/events/events.cpp | 9 +-------- src/windowManager.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- src/windowManager.hpp | 1 + 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c805feb..e7dfbeb 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,10 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern - [ ] Upgrade the status bar rendering to Cairo - [ ] Better status bar configability - [ ] Rounded corners -- [ ] Fix ghost windows once and for all +- [x] Fix ghost windows once and for all +- [ ] Fix windows minimizing themselves to tray not being able to come back without pkill - [ ] Moving windows between workspaces without floating -- [ ] EWMH +- [x] EWMH ~ Basic, idk if i'll add more. - [ ] Docks / Fullscreen Apps etc. auto-detection - [ ] Fix animation flicker (if possible) - [ ] Config expansion (rules, default workspaces, etc.) diff --git a/src/events/events.cpp b/src/events/events.cpp index 8f1a4a7..db52292 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -37,14 +37,7 @@ void Events::eventDestroy(xcb_generic_event_t* event) { const auto E = reinterpret_cast(event); xcb_kill_client(g_pWindowManager->DisplayConnection, E->window); - // fix last window if tile - const auto CLOSEDWINDOW = g_pWindowManager->getWindowFromDrawable(E->window); - if (CLOSEDWINDOW && !CLOSEDWINDOW->getIsFloating()) { - g_pWindowManager->fixWindowOnClose(CLOSEDWINDOW); - - // delete off of the arr - g_pWindowManager->removeWindowFromVectorSafe(E->window); - } + g_pWindowManager->closeWindowAllChecks(E->window); } CWindow* Events::remapFloatingWindow(int windowID) { diff --git a/src/windowManager.cpp b/src/windowManager.cpp index d2420d0..909ca77 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -373,6 +373,7 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) { } } +// TODO: make this executed less. It's too often imo. void CWindowManager::sanityCheckOnWorkspace(int workspaceID) { for (auto& w : windows) { if (w.getWorkspaceID() == workspaceID) { @@ -388,8 +389,11 @@ void CWindowManager::sanityCheckOnWorkspace(int workspaceID) { const auto PCHILD = getWindowFromDrawable(CHILDA); - if (!PCHILD) - continue; // Should be cleaned later. + if (!PCHILD){ + // Means both children are 0 (dead) + removeWindowFromVectorSafe(w.getDrawable()); + continue; + } PCHILD->setPosition(w.getPosition()); PCHILD->setSize(w.getSize()); @@ -430,22 +434,43 @@ void CWindowManager::sanityCheckOnWorkspace(int workspaceID) { if (CHILDA->getIsFloating()) { g_pWindowManager->fixWindowOnClose(CHILDA); g_pWindowManager->calculateNewWindowParams(CHILDA); + + Debug::log(LOG, "Found an invalid tiled window, ID: " + std::to_string(CHILDA->getDrawable()) + ", untiling it."); } if (CHILDB->getIsFloating()) { g_pWindowManager->fixWindowOnClose(CHILDB); g_pWindowManager->calculateNewWindowParams(CHILDB); + + Debug::log(LOG, "Found an invalid tiled window, ID: " + std::to_string(CHILDB->getDrawable()) + ", untiling it."); } } else { Debug::log(ERR, "Malformed node ID " + std::to_string(w.getDrawable()) + " with 2 children but one or both are nullptr."); } } + + // Check #3: Check if the window exists with xcb + // Some windows do not report they are dead for w/e reason + if (w.getDrawable() > 0) { + const auto GEOMETRYCOOKIE = xcb_get_geometry(g_pWindowManager->DisplayConnection, w.getDrawable()); + const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0); + + if (!GEOMETRY || (GEOMETRY->width < 1 || GEOMETRY->height < 1)) { + Debug::log(LOG, "Found a dead window, ID: " + std::to_string(w.getDrawable()) + ", removing it."); + + closeWindowAllChecks(w.getDrawable()); + continue; + } + } } } } CWindow* CWindowManager::getWindowFromDrawable(int64_t window) { + if (!window) + return nullptr; + for(auto& w : windows) { if (w.getDrawable() == window) { return &w; @@ -685,6 +710,17 @@ void CWindowManager::eatWindow(CWindow* a, CWindow* toEat) { a->setSize(Vector2D(std::max(OPPCORNERA.x, OPPCORNERB.x), std::max(OPPCORNERA.y, OPPCORNERB.y)) - a->getPosition()); } +void CWindowManager::closeWindowAllChecks(int64_t id) { + // fix last window if tile + const auto CLOSEDWINDOW = g_pWindowManager->getWindowFromDrawable(id); + if (CLOSEDWINDOW && !CLOSEDWINDOW->getIsFloating()) { + g_pWindowManager->fixWindowOnClose(CLOSEDWINDOW); + + // delete off of the arr + g_pWindowManager->removeWindowFromVectorSafe(id); + } +} + void CWindowManager::fixWindowOnClose(CWindow* pClosedWindow) { if (!pClosedWindow) return; diff --git a/src/windowManager.hpp b/src/windowManager.hpp index 016dead..4bcfc38 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -58,6 +58,7 @@ public: void calculateNewWindowParams(CWindow*); void fixWindowOnClose(CWindow*); + void closeWindowAllChecks(int64_t); void moveActiveWindowTo(char); void warpCursorTo(Vector2D);