From 3f99dad7f563593d298bcd548002e5b53a886825 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 2 Apr 2022 20:04:32 +0200 Subject: [PATCH] Added pseudotiling --- example/hyprland.conf | 6 ++++++ src/Window.hpp | 6 ++++-- src/config/ConfigManager.cpp | 3 +++ src/events/Windows.cpp | 13 +++++++++++- src/layout/DwindleLayout.cpp | 36 +++++++++++++++++++++++++++++++++ src/layout/DwindleLayout.hpp | 1 + src/layout/IHyprLayout.hpp | 8 +++++++- src/managers/KeybindManager.cpp | 12 +++++++++++ src/managers/KeybindManager.hpp | 1 + 9 files changed, 82 insertions(+), 4 deletions(-) diff --git a/example/hyprland.conf b/example/hyprland.conf index 998d69bd..582e878b 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -35,12 +35,17 @@ animations { fadein=1 # not yet implemented } +dwindle { + pseudotile=0 # enable pseudotiling on dwindle +} + # example window rules # for windows named/classed as abc and xyz windowrule=move 69 420,abc windowrule=size 420 69,abc windowrule=tile,xyz windowrule=float,abc +windowrule=pseudo,abc windowrule=monitor 0,xyz # example binds @@ -50,6 +55,7 @@ bind=SUPER,M,exec,pkill Hyprland bind=SUPER,E,exec,dolphin bind=SUPER,V,togglefloating, bind=SUPER,R,exec,wofi --show drun -o DP-3 +bind=SUPER,P,pseudo, bind=SUPER,1,workspace,1 bind=SUPER,2,workspace,2 diff --git a/src/Window.hpp b/src/Window.hpp index eacf69bf..f59e037a 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -24,8 +24,6 @@ public: wlr_xwayland_surface* xwayland; } m_uSurface; - // TODO: XWayland - // this is the position and size of the "bounding box" Vector2D m_vPosition = Vector2D(0,0); Vector2D m_vSize = Vector2D(0,0); @@ -38,6 +36,10 @@ public: Vector2D m_vRealPosition = Vector2D(0,0); Vector2D m_vRealSize = Vector2D(0,0); + // this is used for pseudotiling + bool m_bIsPseudotiled = false; + Vector2D m_vPseudoSize = Vector2D(0,0); + uint64_t m_iTags = 0; bool m_bIsFloating = false; bool m_bIsFullscreen = false; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 8d016c4d..52b2ef90 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -22,6 +22,8 @@ CConfigManager::CConfigManager() { configValues["general:col.active_border"].intValue = 0xffffffff; configValues["general:col.inactive_border"].intValue = 0xff444444; + configValues["dwindle:pseudotile"].intValue = 0; + configValues["animations:enabled"].intValue = 1; configValues["animations:speed"].floatValue = 7.f; configValues["animations:windows_speed"].floatValue = 0.f; @@ -186,6 +188,7 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str && RULE != "tile" && RULE.find("move") != 0 && RULE.find("size") != 0 + && RULE.find("pseudo") != 0 && RULE.find("monitor") != 0) { Debug::log(ERR, "Invalid rule found: %s", RULE.c_str()); parseError = "Invalid rule found: " + RULE; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 3d50f1f4..6d000231 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -73,6 +73,8 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bIsFloating = true; } else if (r.szRule.find("tile") == 0) { PWINDOW->m_bIsFloating = false; + } else if (r.szRule.find("pseudo") == 0) { + PWINDOW->m_bIsPseudotiled = true; } } @@ -109,10 +111,19 @@ void Events::listener_mapWindow(void* owner, void* data) { } } } + + // set the pseudo size to the GOAL of our current size + // because the windows are animated on RealSize + PWINDOW->m_vPseudoSize = PWINDOW->m_vEffectiveSize; } - else + else { g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); + // Set the pseudo size here too so that it doesnt end up being 0x0 + PWINDOW->m_vPseudoSize = PWINDOW->m_vEffectiveSize - Vector2D(10,10); + } + + PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW); if (!PWINDOW->m_bIsModal) diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 58eca936..ce1e2a3f 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -109,6 +109,30 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) { PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + OFFSETTOPLEFT; PWINDOW->m_vEffectiveSize = PWINDOW->m_vEffectiveSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; + if (PWINDOW->m_bIsPseudotiled) { + // Calculate pseudo + float scale = 1; + + // adjust if doesnt fit + if (PWINDOW->m_vPseudoSize.x > PWINDOW->m_vEffectiveSize.x || PWINDOW->m_vPseudoSize.y > PWINDOW->m_vEffectiveSize.y) { + if (PWINDOW->m_vPseudoSize.x > PWINDOW->m_vEffectiveSize.x) { + scale = PWINDOW->m_vEffectiveSize.x / PWINDOW->m_vPseudoSize.x; + } + + if (PWINDOW->m_vPseudoSize.y * scale > PWINDOW->m_vEffectiveSize.y) { + scale = PWINDOW->m_vEffectiveSize.y / PWINDOW->m_vPseudoSize.y; + } + + auto DELTA = PWINDOW->m_vEffectiveSize - PWINDOW->m_vPseudoSize * scale; + PWINDOW->m_vEffectiveSize = PWINDOW->m_vPseudoSize * scale; + PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + DELTA / 2.f; // center + } else { + auto DELTA = PWINDOW->m_vEffectiveSize - PWINDOW->m_vPseudoSize; + PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + DELTA / 2.f; // center + PWINDOW->m_vEffectiveSize = PWINDOW->m_vPseudoSize; + } + } + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vEffectiveSize); } @@ -271,6 +295,9 @@ void CHyprDwindleLayout::changeWindowFloatingMode(CWindow* pWindow) { const auto PSAVEDPOS = pWindow->m_vRealPosition; const auto PSAVEDSIZE = pWindow->m_vRealSize; + // if the window is pseudo, update its size + pWindow->m_vPseudoSize = pWindow->m_vRealSize; + onWindowCreated(pWindow); pWindow->m_vRealPosition = PSAVEDPOS; @@ -430,3 +457,12 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow) { // because otherwise they'd still be recieving mouse events g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace); } + +void CHyprDwindleLayout::recalculateWindow(CWindow* pWindow) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE) + return; + + PNODE->recalcSizePosRecursive(); +} \ No newline at end of file diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index 61b76be7..f1411322 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -32,6 +32,7 @@ public: virtual void onWindowCreated(CWindow*); virtual void onWindowRemoved(CWindow*); virtual void recalculateMonitor(const int&); + virtual void recalculateWindow(CWindow*); virtual void changeWindowFloatingMode(CWindow*); virtual void onBeginDragWindow(); virtual void onMouseMove(const Vector2D&); diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index e437d703..b214dd50 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -15,11 +15,17 @@ public: */ virtual void onWindowRemoved(CWindow*) = 0; /* - Called when a the monitor requires a layout recalculation + Called when the monitor requires a layout recalculation this usually means reserved area changes */ virtual void recalculateMonitor(const int&) = 0; + /* + Called when the compositor requests a window + to be recalculated, e.g. when pseudo is toggled. + */ + virtual void recalculateWindow(CWindow*) = 0; + /* Called when a window is requested to be floated */ diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index d9d2fa72..d820e83e 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -53,6 +53,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t else if (k.handler == "workspace") { changeworkspace(k.arg); } else if (k.handler == "fullscreen") { fullscreenActive(k.arg); } else if (k.handler == "movetoworkspace") { moveActiveToWorkspace(k.arg); } + else if (k.handler == "pseudo") { toggleActivePseudo(k.arg); } found = true; } @@ -114,6 +115,17 @@ void CKeybindManager::toggleActiveFloating(std::string args) { } } +void CKeybindManager::toggleActivePseudo(std::string args) { + const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow; + + if (!g_pCompositor->windowValidMapped(ACTIVEWINDOW)) + return; + + ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled; + + g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW); +} + void CKeybindManager::changeworkspace(std::string args) { int workspaceToChangeTo = 0; try { diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 019ba9bf..f68f8314 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -27,6 +27,7 @@ private: void killActive(std::string); void spawn(std::string); void toggleActiveFloating(std::string); + void toggleActivePseudo(std::string); void changeworkspace(std::string); void fullscreenActive(std::string); void moveActiveToWorkspace(std::string);