layout: store and preserve size and pos after fullscreen (#13500)
ref https://github.com/hyprwm/Hyprland/discussions/13401
This commit is contained in:
parent
5f650f8ed9
commit
d98f7ffaf5
11 changed files with 124 additions and 0 deletions
|
|
@ -53,6 +53,54 @@ static void testCrashOnGeomUpdate() {
|
|||
|
||||
// shouldnt crash
|
||||
OK(getFromSocket("/dispatch movefocus r"));
|
||||
|
||||
OK(getFromSocket("/reload"));
|
||||
|
||||
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||
Tests::killAllWindows();
|
||||
}
|
||||
|
||||
// Test if size + pos is preserved after fs cycle
|
||||
static void testPosPreserve() {
|
||||
Tests::spawnKitty();
|
||||
|
||||
OK(getFromSocket("/dispatch setfloating class:kitty"));
|
||||
OK(getFromSocket("/dispatch resizewindowpixel exact 1337 69, class:kitty"));
|
||||
OK(getFromSocket("/dispatch movewindowpixel exact 420 420, class:kitty"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/activewindow");
|
||||
EXPECT_CONTAINS(str, "at: 420,420");
|
||||
EXPECT_CONTAINS(str, "size: 1337,69");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch fullscreen"));
|
||||
OK(getFromSocket("/dispatch fullscreen"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/activewindow");
|
||||
EXPECT_CONTAINS(str, "size: 1337,69");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch movewindow r"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/activewindow");
|
||||
EXPECT_CONTAINS(str, "at: 581,420");
|
||||
EXPECT_CONTAINS(str, "size: 1337,69");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch fullscreen"));
|
||||
OK(getFromSocket("/dispatch fullscreen"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/activewindow");
|
||||
EXPECT_CONTAINS(str, "at: 581,420");
|
||||
EXPECT_CONTAINS(str, "size: 1337,69");
|
||||
}
|
||||
|
||||
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||
Tests::killAllWindows();
|
||||
}
|
||||
|
||||
static bool test() {
|
||||
|
|
@ -66,6 +114,7 @@ static bool test() {
|
|||
swar();
|
||||
|
||||
testCrashOnGeomUpdate();
|
||||
testPosPreserve();
|
||||
|
||||
// clean up
|
||||
NLog::log("Cleaning up", Colors::YELLOW);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,13 @@ void CLayoutManager::resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectC
|
|||
target->space()->resizeTarget(Δ, target, corner);
|
||||
}
|
||||
|
||||
void CLayoutManager::setTargetGeom(const CBox& box, SP<ITarget> target) {
|
||||
if (!target->floating())
|
||||
return;
|
||||
|
||||
target->space()->setTargetGeom(box, target);
|
||||
}
|
||||
|
||||
std::expected<void, std::string> CLayoutManager::layoutMsg(const std::string_view& sv) {
|
||||
|
||||
const auto MONITOR = Desktop::focusState()->monitor();
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ namespace Layout {
|
|||
void moveMouse(const Vector2D& mousePos);
|
||||
void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
|
||||
void moveTarget(const Vector2D& Δ, SP<ITarget> target);
|
||||
void setTargetGeom(const CBox& box, SP<ITarget> target); // floats only
|
||||
void endDragTarget();
|
||||
|
||||
std::expected<void, std::string> layoutMsg(const std::string_view& sv);
|
||||
|
|
|
|||
|
|
@ -262,3 +262,10 @@ SP<ITarget> CAlgorithm::getNextCandidate(SP<ITarget> old) {
|
|||
// god damn it, maybe empty?
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CAlgorithm::setTargetGeom(const CBox& box, SP<ITarget> target) {
|
||||
if (!target->floating() || !std::ranges::contains(m_floatingTargets, target))
|
||||
return;
|
||||
|
||||
m_floating->setTargetGeom(box, target);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ namespace Layout {
|
|||
void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
|
||||
void moveTarget(const Vector2D& Δ, SP<ITarget> target);
|
||||
|
||||
void setTargetGeom(const CBox& box, SP<ITarget> target); // only for float
|
||||
|
||||
void updateFloatingAlgo(UP<IFloatingAlgorithm>&& algo);
|
||||
void updateTiledAlgo(UP<ITiledAlgorithm>&& algo);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ namespace Layout {
|
|||
// a target is being moved by a delta
|
||||
virtual void moveTarget(const Vector2D& Δ, SP<ITarget> target) = 0;
|
||||
|
||||
// a target is moved to a pos x size
|
||||
virtual void setTargetGeom(const CBox& geom, SP<ITarget> target) = 0;
|
||||
|
||||
virtual void recenter(SP<ITarget> t);
|
||||
|
||||
virtual void recalculate();
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ void CDefaultFloatingAlgorithm::newTarget(SP<ITarget> target) {
|
|||
PWINDOW->m_reportedSize = PWINDOW->m_pendingReportedSize;
|
||||
}
|
||||
}
|
||||
|
||||
updateTarget(target);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint) {
|
||||
|
|
@ -152,6 +154,8 @@ void CDefaultFloatingAlgorithm::movedTarget(SP<ITarget> target, std::optional<Ve
|
|||
// put around the current center, fit in workArea
|
||||
target->setPositionGlobal(fitBoxInWorkArea(CBox{NEW_POS, LAST_SIZE}, target));
|
||||
}
|
||||
|
||||
updateTarget(target);
|
||||
}
|
||||
|
||||
CBox CDefaultFloatingAlgorithm::fitBoxInWorkArea(const CBox& box, SP<ITarget> t) {
|
||||
|
|
@ -173,6 +177,7 @@ CBox CDefaultFloatingAlgorithm::fitBoxInWorkArea(const CBox& box, SP<ITarget> t)
|
|||
|
||||
void CDefaultFloatingAlgorithm::removeTarget(SP<ITarget> target) {
|
||||
target->rememberFloatingSize(target->position().size());
|
||||
m_datas.erase(target);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner) {
|
||||
|
|
@ -184,6 +189,8 @@ void CDefaultFloatingAlgorithm::resizeTarget(const Vector2D& Δ, SP<ITarget> tar
|
|||
|
||||
if (g_layoutManager->dragController()->target() == target)
|
||||
target->warpPositionSize();
|
||||
|
||||
updateTarget(target);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::moveTarget(const Vector2D& Δ, SP<ITarget> target) {
|
||||
|
|
@ -193,12 +200,17 @@ void CDefaultFloatingAlgorithm::moveTarget(const Vector2D& Δ, SP<ITarget> targe
|
|||
|
||||
if (g_layoutManager->dragController()->target() == target)
|
||||
target->warpPositionSize();
|
||||
|
||||
updateTarget(target);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::swapTargets(SP<ITarget> a, SP<ITarget> b) {
|
||||
auto posABackup = a->position();
|
||||
a->setPositionGlobal(b->position());
|
||||
b->setPositionGlobal(posABackup);
|
||||
|
||||
updateTarget(a);
|
||||
updateTarget(b);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
||||
|
|
@ -216,4 +228,25 @@ void CDefaultFloatingAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDire
|
|||
}
|
||||
|
||||
t->setPositionGlobal(pos);
|
||||
|
||||
updateTarget(t);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::recenter(SP<ITarget> t) {
|
||||
if (!m_datas.contains(t)) {
|
||||
IFloatingAlgorithm::recenter(t);
|
||||
return;
|
||||
}
|
||||
|
||||
t->setPositionGlobal(m_datas.at(t).lastBox);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::setTargetGeom(const CBox& geom, SP<ITarget> target) {
|
||||
target->setPositionGlobal(geom);
|
||||
|
||||
updateTarget(target);
|
||||
}
|
||||
|
||||
void CDefaultFloatingAlgorithm::updateTarget(SP<ITarget> t) {
|
||||
m_datas[t] = {.lastBox = t->position()};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "../../FloatingAlgorithm.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Layout {
|
||||
class CAlgorithm;
|
||||
}
|
||||
|
|
@ -17,10 +19,22 @@ namespace Layout::Floating {
|
|||
virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
|
||||
virtual void moveTarget(const Vector2D& Δ, SP<ITarget> target);
|
||||
|
||||
virtual void setTargetGeom(const CBox& geom, SP<ITarget> target);
|
||||
|
||||
virtual void swapTargets(SP<ITarget> a, SP<ITarget> b);
|
||||
virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent);
|
||||
|
||||
virtual void recenter(SP<ITarget> t);
|
||||
|
||||
private:
|
||||
CBox fitBoxInWorkArea(const CBox& box, SP<ITarget> t);
|
||||
|
||||
void updateTarget(SP<ITarget>);
|
||||
|
||||
struct SWindowData {
|
||||
CBox lastBox;
|
||||
};
|
||||
|
||||
std::map<WP<ITarget>, SWindowData> m_datas;
|
||||
};
|
||||
};
|
||||
|
|
@ -183,6 +183,11 @@ void CSpace::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool sil
|
|||
m_algorithm->moveTargetInDirection(t, dir, silent);
|
||||
}
|
||||
|
||||
void CSpace::setTargetGeom(const CBox& box, SP<ITarget> target) {
|
||||
if (m_algorithm)
|
||||
m_algorithm->setTargetGeom(box, target);
|
||||
}
|
||||
|
||||
SP<ITarget> CSpace::getNextCandidate(SP<ITarget> old) {
|
||||
return !m_algorithm ? nullptr : m_algorithm->getNextCandidate(old);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace Layout {
|
|||
|
||||
void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE);
|
||||
void moveTarget(const Vector2D& Δ, SP<ITarget> target);
|
||||
void setTargetGeom(const CBox& box, SP<ITarget> target); // only for float
|
||||
|
||||
SP<CAlgorithm> algorithm() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -239,6 +239,8 @@ void CDragStateController::dragEnd() {
|
|||
|
||||
draggingTarget->damageEntire();
|
||||
|
||||
g_layoutManager->setTargetGeom(draggingTarget->position(), draggingTarget);
|
||||
|
||||
Desktop::focusState()->fullWindowFocus(draggingTarget->window(), Desktop::FOCUS_REASON_DESKTOP_STATE_CHANGE);
|
||||
|
||||
m_wasDraggingWindow = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue