diff --git a/src/events/events.cpp b/src/events/events.cpp index 218defb..54f7025 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -726,14 +726,16 @@ void Events::eventButtonPress(xcb_generic_event_t* event) { if (const auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PLASTWINDOW) { - PLASTWINDOW->setDraggingTiled(!PLASTWINDOW->getIsFloating()); + if (E->detail != 3) + PLASTWINDOW->setDraggingTiled(!PLASTWINDOW->getIsFloating()); g_pWindowManager->actingOnWindowFloating = PLASTWINDOW->getDrawable(); g_pWindowManager->mouseLastPos = g_pWindowManager->getCursorPos(); if (!PLASTWINDOW->getIsFloating()) { const auto PDRAWABLE = PLASTWINDOW->getDrawable(); - KeybindManager::toggleActiveWindowFloating(""); + if (E->detail != 3) // right click (resize) does not + KeybindManager::toggleActiveWindowFloating(""); // refocus g_pWindowManager->setFocusedWindow(PDRAWABLE); @@ -828,16 +830,21 @@ void Events::eventMotionNotify(xcb_generic_event_t* event) { PACTINGWINDOW->setDirty(true); } else if (g_pWindowManager->mouseKeyDown == 3) { - // resizing - PACTINGWINDOW->setSize(PACTINGWINDOW->getSize() + POINTERDELTA); - // clamp - PACTINGWINDOW->setSize(Vector2D(std::clamp(PACTINGWINDOW->getSize().x, (double)30, (double)999999), std::clamp(PACTINGWINDOW->getSize().y, (double)30, (double)999999))); - // apply to other - PACTINGWINDOW->setDefaultSize(PACTINGWINDOW->getSize()); - PACTINGWINDOW->setEffectiveSize(PACTINGWINDOW->getSize()); - PACTINGWINDOW->setRealSize(PACTINGWINDOW->getSize()); - PACTINGWINDOW->setPseudoSize(PACTINGWINDOW->getSize()); + if (!PACTINGWINDOW->getIsFloating()) { + g_pWindowManager->processCursorDeltaOnWindowResizeTiled(PACTINGWINDOW, POINTERDELTA); + } else { + // resizing + PACTINGWINDOW->setSize(PACTINGWINDOW->getSize() + POINTERDELTA); + // clamp + PACTINGWINDOW->setSize(Vector2D(std::clamp(PACTINGWINDOW->getSize().x, (double)30, (double)999999), std::clamp(PACTINGWINDOW->getSize().y, (double)30, (double)999999))); + + // apply to other + PACTINGWINDOW->setDefaultSize(PACTINGWINDOW->getSize()); + PACTINGWINDOW->setEffectiveSize(PACTINGWINDOW->getSize()); + PACTINGWINDOW->setRealSize(PACTINGWINDOW->getSize()); + PACTINGWINDOW->setPseudoSize(PACTINGWINDOW->getSize()); + } PACTINGWINDOW->setDirty(true); } diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 9bfbd67..cfd1f9f 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -2578,4 +2578,72 @@ void CWindowManager::getICCCMSizeHints(CWindow* pWindow) { } else { Debug::log(ERR, "ICCCM Size Hints failed."); } +} + +void CWindowManager::processCursorDeltaOnWindowResizeTiled(CWindow* pWindow, const Vector2D& pointerDelta) { + // this resizes the window based on cursor movement, + // basically like a mouse-ver of splitratio + + if (!pWindow) + return; + + // TODO: support master-stack + if (ConfigManager::getInt("layout") == LAYOUT_MASTER){ + Debug::log(WARN, "processCursorDeltaOnWindowResizeTiled does NOT support MASTER yet. Ignoring."); + return; + } + + // Construct an allowed delta movement + const auto PMONITOR = getMonitorFromWindow(pWindow); + const bool DISPLAYLEFT = STICKS(pWindow->getPosition().x, PMONITOR->vecPosition.x); + const bool DISPLAYRIGHT = STICKS(pWindow->getPosition().x + pWindow->getSize().x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x); + const bool DISPLAYTOP = STICKS(pWindow->getPosition().y, PMONITOR->vecPosition.y); + const bool DISPLAYBOTTOM = STICKS(pWindow->getPosition().y + pWindow->getSize().y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y); + + Vector2D allowedMovement = pointerDelta; + if (DISPLAYLEFT && DISPLAYRIGHT) + allowedMovement.x = 0; + + if (DISPLAYTOP && DISPLAYBOTTOM) + allowedMovement.y = 0; + + // Get the correct containers to apply the splitratio to + const auto PPARENT = getWindowFromDrawable(pWindow->getParentNodeID()); + + // If there is no parent we ignore the request (only window) + if (!PPARENT) + return; + + const bool PARENTSIDEBYSIDE = PPARENT->getSize().x / PPARENT->getSize().y > 1; + + // Get the parent's parent. + const auto PPARENT2 = getWindowFromDrawable(PPARENT->getParentNodeID()); + + // if there is no parent, we have 2 windows only and have the ability to drag in only one direction. + if (!PPARENT2) { + if (PARENTSIDEBYSIDE) { + // splitratio adjust for pixels + allowedMovement.x *= 2.f / PPARENT->getSize().x; + PPARENT->setSplitRatio(std::clamp(PPARENT->getSplitRatio() + allowedMovement.x, (double)0.05f, (double)1.95f)); + PPARENT->recalcSizePosRecursive(); + } else { + allowedMovement.y *= 2.f / PPARENT->getSize().y; + PPARENT->setSplitRatio(std::clamp(PPARENT->getSplitRatio() + allowedMovement.y, (double)0.05f, (double)1.95f)); + PPARENT->recalcSizePosRecursive(); + } + + return; + } + + // if there is a parent, we have 2 axes of freedom + const auto SIDECONTAINER = PARENTSIDEBYSIDE ? PPARENT : PPARENT2; + const auto TOPCONTAINER = PARENTSIDEBYSIDE ? PPARENT2 : PPARENT; + + allowedMovement.x *= 2.f / SIDECONTAINER->getSize().x; + allowedMovement.y *= 2.f / TOPCONTAINER->getSize().x; + + SIDECONTAINER->setSplitRatio(std::clamp(SIDECONTAINER->getSplitRatio() + allowedMovement.x, (double)0.05f, (double)1.95f)); + TOPCONTAINER->setSplitRatio(std::clamp(TOPCONTAINER->getSplitRatio() + allowedMovement.y, (double)0.05f, (double)1.95f)); + SIDECONTAINER->recalcSizePosRecursive(); + TOPCONTAINER->recalcSizePosRecursive(); } \ No newline at end of file diff --git a/src/windowManager.hpp b/src/windowManager.hpp index 44047e5..831fa6e 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -150,6 +150,8 @@ public: void changeSplitRatioCurrent(const char& dir); + void processCursorDeltaOnWindowResizeTiled(CWindow*, const Vector2D&); + private: // Internal WM functions that don't have to be exposed