diff --git a/src/layout/algorithm/ModeAlgorithm.cpp b/src/layout/algorithm/ModeAlgorithm.cpp index 261c54da..dea5bb17 100644 --- a/src/layout/algorithm/ModeAlgorithm.cpp +++ b/src/layout/algorithm/ModeAlgorithm.cpp @@ -1,5 +1,10 @@ #include "ModeAlgorithm.hpp" +#include "../space/Space.hpp" +#include "Algorithm.hpp" +#include "../../helpers/Monitor.hpp" +#include "../../desktop/view/Window.hpp" + using namespace Layout; std::expected IModeAlgorithm::layoutMsg(const std::string_view& sv) { @@ -9,3 +14,20 @@ std::expected IModeAlgorithm::layoutMsg(const std::string_vie std::optional IModeAlgorithm::predictSizeForNewTarget() { return std::nullopt; } + +std::optional IModeAlgorithm::focalPointForDir(SP t, Math::eDirection dir) { + Vector2D focalPoint; + + const auto WINDOWIDEALBB = + t->fullscreenMode() != FSMODE_NONE ? m_parent->space()->workspace()->m_monitor->logicalBox() : t->window()->getWindowIdealBoundingBoxIgnoreReserved(); + + switch (dir) { + case Math::DIRECTION_UP: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x / 2.0, -1.0}; break; + case Math::DIRECTION_DOWN: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x / 2.0, WINDOWIDEALBB.size().y + 1.0}; break; + case Math::DIRECTION_LEFT: focalPoint = WINDOWIDEALBB.pos() + Vector2D{-1.0, WINDOWIDEALBB.size().y / 2.0}; break; + case Math::DIRECTION_RIGHT: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x + 1.0, WINDOWIDEALBB.size().y / 2.0}; break; + default: return std::nullopt; + } + + return focalPoint; +} diff --git a/src/layout/algorithm/ModeAlgorithm.hpp b/src/layout/algorithm/ModeAlgorithm.hpp index 90d7ce58..0fedc3da 100644 --- a/src/layout/algorithm/ModeAlgorithm.hpp +++ b/src/layout/algorithm/ModeAlgorithm.hpp @@ -44,6 +44,9 @@ namespace Layout { // optional: predict new window's size virtual std::optional predictSizeForNewTarget(); + // Impl'd here: focal point for dir + virtual std::optional focalPointForDir(SP t, Math::eDirection dir); + protected: IModeAlgorithm() = default; diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp index 32afc3ab..a1fcf521 100644 --- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp +++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp @@ -99,11 +99,13 @@ void CDwindleAlgorithm::addTarget(SP target, bool newTarget) { if (!OPENINGON && g_pCompositor->isPointOnReservedArea(MOUSECOORDS, ACTIVE_MON)) OPENINGON = getClosestNode(MOUSECOORDS); - } else if (*PUSEACTIVE) { + } else if (*PUSEACTIVE || m_overrideFocalPoint) { const auto ACTIVE_WINDOW = Desktop::focusState()->window(); - if (!m_overrideFocalPoint && ACTIVE_WINDOW && !ACTIVE_WINDOW->m_isFloating && ACTIVE_WINDOW != target->window() && ACTIVE_WINDOW->m_workspace == PWORKSPACE && - ACTIVE_WINDOW->m_isMapped) + if (m_overrideFocalPoint) + OPENINGON = getClosestNode(*m_overrideFocalPoint); + else if (!m_overrideFocalPoint && ACTIVE_WINDOW && !ACTIVE_WINDOW->m_isFloating && ACTIVE_WINDOW != target->window() && ACTIVE_WINDOW->m_workspace == PWORKSPACE && + ACTIVE_WINDOW->m_isMapped) OPENINGON = getNodeFromWindow(ACTIVE_WINDOW); if (!OPENINGON) @@ -214,10 +216,7 @@ void CDwindleAlgorithm::addTarget(SP target, bool newTarget) { } } } else if (*PFORCESPLIT == 0 || !newTarget) { - if ((SIDEBYSIDE && - VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / *PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y + NEWPARENT->box.h)) || - (!SIDEBYSIDE && - VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / *PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w, NEWPARENT->box.y + NEWPARENT->box.h / 2.f))) { + if ((SIDEBYSIDE && MOUSECOORDS.x < NEWPARENT->box.x + (NEWPARENT->box.w / 2.F)) || (!SIDEBYSIDE && MOUSECOORDS.y < NEWPARENT->box.y + (NEWPARENT->box.h / 2.F))) { // we are hovering over the first node, make PNODE first. NEWPARENT->children[1] = OPENINGON; NEWPARENT->children[0] = PNODE; @@ -242,11 +241,10 @@ void CDwindleAlgorithm::addTarget(SP target, bool newTarget) { // and update the previous parent if it exists if (OPENINGON->pParent) { - if (OPENINGON->pParent->children[0] == OPENINGON) { + if (OPENINGON->pParent->children[0] == OPENINGON) OPENINGON->pParent->children[0] = NEWPARENT; - } else { + else OPENINGON->pParent->children[1] = NEWPARENT; - } } // Update the children @@ -557,35 +555,24 @@ void CDwindleAlgorithm::moveTargetInDirection(SP t, Math::eDirection di if (!PNODE || !t->window()) return; - Vector2D focalPoint; - - const auto WINDOWIDEALBB = - t->fullscreenMode() != FSMODE_NONE ? m_parent->space()->workspace()->m_monitor->logicalBox() : t->window()->getWindowIdealBoundingBoxIgnoreReserved(); - - switch (dir) { - case Math::DIRECTION_UP: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x / 2.0, -1.0}; break; - case Math::DIRECTION_DOWN: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x / 2.0, WINDOWIDEALBB.size().y + 1.0}; break; - case Math::DIRECTION_LEFT: focalPoint = WINDOWIDEALBB.pos() + Vector2D{-1.0, WINDOWIDEALBB.size().y / 2.0}; break; - case Math::DIRECTION_RIGHT: focalPoint = WINDOWIDEALBB.pos() + Vector2D{WINDOWIDEALBB.size().x + 1.0, WINDOWIDEALBB.size().y / 2.0}; break; - default: return; - } + const auto FOCAL_POINT = focalPointForDir(t, dir); t->window()->setAnimationsToMove(); removeTarget(t); - const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(focalPoint); + const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(FOCAL_POINT.value_or(t->position().middle())); if (PMONITORFOCAL != m_parent->space()->workspace()->m_monitor) { // move with a focal point if (PMONITORFOCAL->m_activeWorkspace) - t->assignToSpace(PMONITORFOCAL->m_activeWorkspace->m_space); + t->assignToSpace(PMONITORFOCAL->m_activeWorkspace->m_space, FOCAL_POINT); return; } - movedTarget(t, focalPoint); + movedTarget(t, FOCAL_POINT); // restore focus to the previous position if (silent) { diff --git a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp index 7f421e49..88540d20 100644 --- a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp +++ b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp @@ -424,7 +424,7 @@ void CMasterAlgorithm::moveTargetInDirection(SP t, Math::eDirection dir t->window()->setAnimationsToMove(); if (t->window()->m_workspace != targetWs) { - t->assignToSpace(targetWs->m_space); + t->assignToSpace(targetWs->m_space, focalPointForDir(t, dir)); } else if (PWINDOW2) { // if same monitor, switch windows g_layoutManager->switchTargets(t, PWINDOW2->layoutTarget()); diff --git a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp index 6e9e822c..3551b370 100644 --- a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp +++ b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp @@ -215,7 +215,7 @@ void CMonocleAlgorithm::moveTargetInDirection(SP t, Math::eDirection di if (t->window()) t->window()->setAnimationsToMove(); - t->assignToSpace(TARGETWS->m_space); + t->assignToSpace(TARGETWS->m_space, focalPointForDir(t, dir)); } } diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp index 35234f1f..94e658d3 100644 --- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp +++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp @@ -951,7 +951,7 @@ void CScrollingAlgorithm::moveTargetTo(SP t, Math::eDirection dir, bool // with the original dir const auto MONINDIR = g_pCompositor->getMonitorInDirection(m_parent->space()->workspace()->m_monitor.lock(), dir); if (MONINDIR && MONINDIR != m_parent->space()->workspace()->m_monitor && MONINDIR->m_activeWorkspace) { - t->assignToSpace(MONINDIR->m_activeWorkspace->m_space); + t->assignToSpace(MONINDIR->m_activeWorkspace->m_space, focalPointForDir(t, dir)); m_scrollingData->recalculate();