mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-25 14:25:58 +01:00
automatically fix malformed nodes and remapping changes
This commit is contained in:
parent
b4092dcbaf
commit
be9fecd545
3 changed files with 120 additions and 25 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
|
|
Loading…
Reference in a new issue