automatically fix malformed nodes and remapping changes

This commit is contained in:
vaxerski 2022-01-06 11:56:32 +01:00
parent b4092dcbaf
commit be9fecd545
3 changed files with 120 additions and 25 deletions

View File

@ -602,13 +602,6 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
// Map the window
xcb_map_window(g_pWindowManager->DisplayConnection, E->window);
// Check if it's not unmapped
if (g_pWindowManager->isWindowUnmapped(E->window)) {
Debug::log(LOG, "Window was unmapped, mapping back.");
g_pWindowManager->moveWindowToMapped(E->window);
return;
}
// bar
if (E->window == g_pWindowManager->barWindowID)
return;
@ -616,20 +609,28 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
// We check if the window is not on our tile-blacklist and if it is, we have a special treatment procedure for it.
// this func also sets some stuff
CWindow window;
window.setDrawable(E->window);
g_pWindowManager->addWindowToVectorSafe(window);
// Check if it's not unmapped
CWindow* pNewWindow = nullptr;
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
Debug::log(LOG, "Window SHOULD be floating on start.");
pNewWindow = remapFloatingWindow(E->window);
if (g_pWindowManager->isWindowUnmapped(E->window)) {
Debug::log(LOG, "Window was unmapped, mapping back.");
g_pWindowManager->moveWindowToMapped(E->window);
pNewWindow = g_pWindowManager->getWindowFromDrawable(E->window);
} else {
Debug::log(LOG, "Window should NOT be floating on start.");
pNewWindow = remapWindow(E->window);
CWindow window;
window.setDrawable(E->window);
g_pWindowManager->addWindowToVectorSafe(window);
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
Debug::log(LOG, "Window SHOULD be floating on start.");
pNewWindow = remapFloatingWindow(E->window);
} else {
Debug::log(LOG, "Window should NOT be floating on start.");
pNewWindow = remapWindow(E->window);
}
}
if (!pNewWindow) {
if (!pNewWindow || pNewWindow->getClassName() == "") {
g_pWindowManager->removeWindowFromVectorSafe(E->window);
return;
}

View File

@ -518,7 +518,7 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
PLASTWIN->setEffectiveBorderColor(CFloatingColor(ConfigManager::getInt("col.inactive_border")));
}
if (const auto PLASTWIN = getWindowFromDrawable(window); PLASTWIN) {
PLASTWIN->setEffectiveBorderColor(CFloatingColor(ConfigManager::getInt("col.active_border")));
PLASTWIN->setEffectiveBorderColor(CFloatingColor(ConfigManager::getInt("col.active_border")));
}
if (const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(window); PWINDOW) {
@ -620,6 +620,62 @@ void CWindowManager::sanityCheckOnWorkspace(int workspaceID) {
} else {
Debug::log(ERR, "Malformed node ID " + std::to_string(w.getDrawable()) + " with 2 children but one or both are nullptr.");
// fix it
if (!CHILDA && !CHILDB) {
closeWindowAllChecks(w.getDrawable());
Debug::log(ERR, "Node fixed, both nullptr.");
continue;
}
const auto PNULLCHILD = CHILDA ? CHILDB : CHILDA;
const auto PSIBLING = CHILDA ? CHILDA : CHILDB;
const auto PPARENT = getWindowFromDrawable(w.getDrawable());
if (!PPARENT)
return; // ????????
if (!PSIBLING) {
Debug::log(ERR, "No sibling found in fixing malformed node! (Corrupted tree...?)");
return;
}
// FIX TREE ----
// make the sibling replace the parent
PSIBLING->setPosition(PPARENT->getPosition());
PSIBLING->setSize(PPARENT->getSize());
PSIBLING->setParentNodeID(PPARENT->getParentNodeID());
if (PPARENT->getParentNodeID() != 0 && getWindowFromDrawable(PPARENT->getParentNodeID())) {
if (getWindowFromDrawable(PPARENT->getParentNodeID())->getChildNodeAID() == PPARENT->getDrawable()) {
getWindowFromDrawable(PPARENT->getParentNodeID())->setChildNodeAID(PSIBLING->getDrawable());
} else {
getWindowFromDrawable(PPARENT->getParentNodeID())->setChildNodeBID(PSIBLING->getDrawable());
}
}
// TREE FIXED ----
Debug::log(ERR, "Tree fixed.");
// Fix master stuff
getMasterForWorkspace(PSIBLING->getWorkspaceID());
// recalc the workspace
if (ConfigManager::getInt("layout") == LAYOUT_MASTER)
recalcEntireWorkspace(PSIBLING->getWorkspaceID());
else {
PSIBLING->recalcSizePosRecursive();
PSIBLING->setDirtyRecursive(true);
}
// Remove the parent
removeWindowFromVectorSafe(PPARENT->getDrawable());
if (findWindowAtCursor())
setFocusedWindow(findWindowAtCursor()->getDrawable()); // Set focus. :)
Debug::log(ERR, "Node fixed, one nullptr.");
}
}
}
@ -681,9 +737,17 @@ void CWindowManager::applyShapeToWindow(CWindow* pWindow) {
if (!SHAPEQUERY || !SHAPEQUERY->present || pWindow->getNoInterventions())
return;
Debug::log(LOG, "Applying shape to " + std::to_string(pWindow->getDrawable()));
// Prepare values
const auto MONITOR = getMonitorFromWindow(pWindow);
if (!MONITOR) {
Debug::log(ERR, "No monitor for " + std::to_string(pWindow->getDrawable()) + "??");
return;
}
const uint16_t W = pWindow->getFullscreen() ? MONITOR->vecSize.x : pWindow->getRealSize().x;
const uint16_t H = pWindow->getFullscreen() ? MONITOR->vecSize.y : pWindow->getRealSize().y;
const uint16_t BORDER = pWindow->getFullscreen() ? 0 : ConfigManager::getInt("border_size");
@ -751,6 +815,12 @@ void CWindowManager::applyShapeToWindow(CWindow* pWindow) {
xcb_poly_fill_arc(DisplayConnection, PIXMAP2, WHITE, 4, CLIPPINGARCS);
const auto WORKSPACE = getWorkspaceByID(pWindow->getWorkspaceID());
if (!WORKSPACE) {
Debug::log(ERR, "No workspace for " + std::to_string(pWindow->getDrawable()) + "??");
return;
}
if (WORKSPACE->getAnimationInProgress()) {
// if it's animated we draw 2 more black rects to clip it. (if it goes out of the monitor)
@ -1177,21 +1247,33 @@ void CWindowManager::closeWindowAllChecks(int64_t id) {
g_pWindowManager->recalcAllDocks();
}
void CWindowManager::fixMasterWorkspaceOnClosed(CWindow* pWindow) {
// get children and master
CWindow* CWindowManager::getMasterForWorkspace(const int& work) {
CWindow* pMaster = nullptr;
for (auto& w : windows) {
if (w.getWorkspaceID() == pWindow->getWorkspaceID() && w.getMaster()) {
if (w.getWorkspaceID() == work && w.getMaster()) {
pMaster = &w;
break;
}
}
if (!pMaster) {
Debug::log(ERR, "No master found on workspace???");
return;
Debug::log(ERR, "No master found on workspace? Setting automatically");
for (auto& w : windows) {
if (w.getWorkspaceID() == work) {
pMaster = &w;
w.setMaster(true);
break;
}
}
}
return pMaster;
}
void CWindowManager::fixMasterWorkspaceOnClosed(CWindow* pWindow) {
getMasterForWorkspace(pWindow->getWorkspaceID()); // to fix if no master
// get children sorted
std::vector<CWindow*> children;
for (auto& w : windows) {
@ -1606,7 +1688,14 @@ void CWindowManager::focusOnWorkspace(const int& work) {
if (window.getWorkspaceID() == work && window.getDrawable() > 0) {
setFocusedWindow(window.getDrawable());
if (getMonitorFromCursor() && getMonitorFromCursor()->ID != PMONITOR->ID)
Debug::log(LOG, "Queueing the warp");
const auto PMONITORFROMCURSOR = getMonitorFromCursor();
if (PMONITORFROMCURSOR)
Debug::log(LOG, "Monitor from cursor: " + std::to_string(PMONITORFROMCURSOR->ID));
if (PMONITORFROMCURSOR && PMONITORFROMCURSOR->ID != PMONITOR->ID)
QueuedPointerWarp = Vector2D(window.getPosition() + window.getSize() / 2.f);
shouldHopToScreen = false;
@ -1615,6 +1704,8 @@ void CWindowManager::focusOnWorkspace(const int& work) {
}
}
Debug::log(LOG, "Queueing a hop if needed.");
if (shouldHopToScreen)
QueuedPointerWarp = Vector2D(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f);
} else {
@ -1704,6 +1795,8 @@ Vector2D CWindowManager::getCursorPos() {
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
free(pointerreply);
Debug::log(LOG, "Cursor pos: " + std::to_string(CURSORPOS.x) + ", " + std::to_string(CURSORPOS.y));
return CURSORPOS;
}
@ -2173,4 +2266,4 @@ void CWindowManager::dispatchQueuedWarp() {
warpCursorTo(QueuedPointerWarp);
QueuedPointerWarp = Vector2D(-1,-1);
}
}

View File

@ -157,6 +157,7 @@ private:
void startWipeAnimOnWorkspace(const int&, const int&);
void focusOnWorkspace(const int&);
void dispatchQueuedWarp();
CWindow* getMasterForWorkspace(const int&);
};
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();