mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 13:35:57 +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
|
// Map the window
|
||||||
xcb_map_window(g_pWindowManager->DisplayConnection, E->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
|
// bar
|
||||||
if (E->window == g_pWindowManager->barWindowID)
|
if (E->window == g_pWindowManager->barWindowID)
|
||||||
return;
|
return;
|
||||||
|
@ -616,11 +609,18 @@ 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.
|
// 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
|
// this func also sets some stuff
|
||||||
|
|
||||||
|
// Check if it's not unmapped
|
||||||
|
CWindow* pNewWindow = nullptr;
|
||||||
|
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 {
|
||||||
CWindow window;
|
CWindow window;
|
||||||
window.setDrawable(E->window);
|
window.setDrawable(E->window);
|
||||||
g_pWindowManager->addWindowToVectorSafe(window);
|
g_pWindowManager->addWindowToVectorSafe(window);
|
||||||
|
|
||||||
CWindow* pNewWindow = nullptr;
|
|
||||||
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
|
if (g_pWindowManager->shouldBeFloatedOnInit(E->window)) {
|
||||||
Debug::log(LOG, "Window SHOULD be floating on start.");
|
Debug::log(LOG, "Window SHOULD be floating on start.");
|
||||||
pNewWindow = remapFloatingWindow(E->window);
|
pNewWindow = remapFloatingWindow(E->window);
|
||||||
|
@ -628,8 +628,9 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
||||||
Debug::log(LOG, "Window should NOT be floating on start.");
|
Debug::log(LOG, "Window should NOT be floating on start.");
|
||||||
pNewWindow = remapWindow(E->window);
|
pNewWindow = remapWindow(E->window);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pNewWindow) {
|
if (!pNewWindow || pNewWindow->getClassName() == "") {
|
||||||
g_pWindowManager->removeWindowFromVectorSafe(E->window);
|
g_pWindowManager->removeWindowFromVectorSafe(E->window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -620,6 +620,62 @@ void CWindowManager::sanityCheckOnWorkspace(int workspaceID) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Debug::log(ERR, "Malformed node ID " + std::to_string(w.getDrawable()) + " with 2 children but one or both are nullptr.");
|
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())
|
if (!SHAPEQUERY || !SHAPEQUERY->present || pWindow->getNoInterventions())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Applying shape to " + std::to_string(pWindow->getDrawable()));
|
||||||
|
|
||||||
// Prepare values
|
// Prepare values
|
||||||
|
|
||||||
const auto MONITOR = getMonitorFromWindow(pWindow);
|
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 W = pWindow->getFullscreen() ? MONITOR->vecSize.x : pWindow->getRealSize().x;
|
||||||
const uint16_t H = pWindow->getFullscreen() ? MONITOR->vecSize.y : pWindow->getRealSize().y;
|
const uint16_t H = pWindow->getFullscreen() ? MONITOR->vecSize.y : pWindow->getRealSize().y;
|
||||||
const uint16_t BORDER = pWindow->getFullscreen() ? 0 : ConfigManager::getInt("border_size");
|
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);
|
xcb_poly_fill_arc(DisplayConnection, PIXMAP2, WHITE, 4, CLIPPINGARCS);
|
||||||
|
|
||||||
const auto WORKSPACE = getWorkspaceByID(pWindow->getWorkspaceID());
|
const auto WORKSPACE = getWorkspaceByID(pWindow->getWorkspaceID());
|
||||||
|
|
||||||
|
if (!WORKSPACE) {
|
||||||
|
Debug::log(ERR, "No workspace for " + std::to_string(pWindow->getDrawable()) + "??");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (WORKSPACE->getAnimationInProgress()) {
|
if (WORKSPACE->getAnimationInProgress()) {
|
||||||
// if it's animated we draw 2 more black rects to clip it. (if it goes out of the monitor)
|
// if it's animated we draw 2 more black rects to clip it. (if it goes out of the monitor)
|
||||||
|
|
||||||
|
@ -1177,20 +1247,32 @@ void CWindowManager::closeWindowAllChecks(int64_t id) {
|
||||||
g_pWindowManager->recalcAllDocks();
|
g_pWindowManager->recalcAllDocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindowManager::fixMasterWorkspaceOnClosed(CWindow* pWindow) {
|
CWindow* CWindowManager::getMasterForWorkspace(const int& work) {
|
||||||
// get children and master
|
|
||||||
CWindow* pMaster = nullptr;
|
CWindow* pMaster = nullptr;
|
||||||
for (auto& w : windows) {
|
for (auto& w : windows) {
|
||||||
if (w.getWorkspaceID() == pWindow->getWorkspaceID() && w.getMaster()) {
|
if (w.getWorkspaceID() == work && w.getMaster()) {
|
||||||
pMaster = &w;
|
pMaster = &w;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pMaster) {
|
if (!pMaster) {
|
||||||
Debug::log(ERR, "No master found on workspace???");
|
Debug::log(ERR, "No master found on workspace? Setting automatically");
|
||||||
return;
|
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
|
// get children sorted
|
||||||
std::vector<CWindow*> children;
|
std::vector<CWindow*> children;
|
||||||
|
@ -1606,7 +1688,14 @@ void CWindowManager::focusOnWorkspace(const int& work) {
|
||||||
if (window.getWorkspaceID() == work && window.getDrawable() > 0) {
|
if (window.getWorkspaceID() == work && window.getDrawable() > 0) {
|
||||||
setFocusedWindow(window.getDrawable());
|
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);
|
QueuedPointerWarp = Vector2D(window.getPosition() + window.getSize() / 2.f);
|
||||||
|
|
||||||
shouldHopToScreen = false;
|
shouldHopToScreen = false;
|
||||||
|
@ -1615,6 +1704,8 @@ void CWindowManager::focusOnWorkspace(const int& work) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Queueing a hop if needed.");
|
||||||
|
|
||||||
if (shouldHopToScreen)
|
if (shouldHopToScreen)
|
||||||
QueuedPointerWarp = Vector2D(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f);
|
QueuedPointerWarp = Vector2D(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1704,6 +1795,8 @@ Vector2D CWindowManager::getCursorPos() {
|
||||||
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
|
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
|
||||||
free(pointerreply);
|
free(pointerreply);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Cursor pos: " + std::to_string(CURSORPOS.x) + ", " + std::to_string(CURSORPOS.y));
|
||||||
|
|
||||||
return CURSORPOS;
|
return CURSORPOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,7 @@ private:
|
||||||
void startWipeAnimOnWorkspace(const int&, const int&);
|
void startWipeAnimOnWorkspace(const int&, const int&);
|
||||||
void focusOnWorkspace(const int&);
|
void focusOnWorkspace(const int&);
|
||||||
void dispatchQueuedWarp();
|
void dispatchQueuedWarp();
|
||||||
|
CWindow* getMasterForWorkspace(const int&);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
||||||
|
|
Loading…
Reference in a new issue