diff --git a/README.md b/README.md index fd29b3d7..72e15c2f 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,8 @@ Try it out and report bugs / suggestions! - Easily expandable and readable codebase - Config reloaded instantly upon saving -- Parabolic window animations +- Bezier-curve window animations +- Custom bezier curves - Workspaces protocol support - Tiling / floating / fullscreen windows - Window / monitor rules diff --git a/example/hyprland.conf b/example/hyprland.conf index 156192ca..a8add8f2 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -41,7 +41,9 @@ decoration { animations { enabled=1 - speed=7 + speed=7 # speed is measured in 100s of ms, 7 = 700ms + curve=default # you can customize your own bezier curves, see the wiki + windows_curve=default # specific curve for all window animations windows_speed=6 # specific speeds for components can be made with name_speed=float. 0 means use global (speed=float). If not set, will use the global value. windows=1 borders=1 diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 0e07829f..43263dd4 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -158,6 +158,9 @@ void CCompositor::startCompositor() { Debug::log(LOG, "Creating the KeybindManager!"); g_pKeybindManager = std::make_unique(); + Debug::log(LOG, "Creating the AnimationManager!"); + g_pAnimationManager = std::make_unique(); + Debug::log(LOG, "Creating the ConfigManager!"); g_pConfigManager = std::make_unique(); @@ -178,9 +181,6 @@ void CCompositor::startCompositor() { Debug::log(LOG, "Creating the LayoutManager!"); g_pLayoutManager = std::make_unique(); - - Debug::log(LOG, "Creating the AnimationManager!"); - g_pAnimationManager = std::make_unique(); // // @@ -281,13 +281,13 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) { const auto PMONITOR = getMonitorFromVector(pos); // first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter. for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) { - wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y}; + wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden) return &(*w); } for (auto& w : m_lWindows) { - wlr_box box = {w.m_vRealPosition.x, w.m_vRealPosition.y, w.m_vRealSize.x, w.m_vRealSize.y}; + wlr_box box = {w.m_vRealPosition.vec().x, w.m_vRealPosition.vec().y, w.m_vRealSize.vec().x, w.m_vRealSize.vec().y}; if (wlr_box_contains_point(&box, pos.x, pos.y) && w.m_bIsMapped && !w.m_bIsFloating && PMONITOR->activeWorkspace == w.m_iWorkspaceID && !w.m_bHidden) return &w; } @@ -310,7 +310,7 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { const auto PMONITOR = getMonitorFromVector(pos); // first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter. for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) { - wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y}; + wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; if (w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden) return &(*w); } @@ -329,7 +329,7 @@ CWindow* CCompositor::windowFromCursor() { // first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter. for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) { - wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y}; + wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID)) return &(*w); } @@ -345,7 +345,7 @@ CWindow* CCompositor::windowFromCursor() { CWindow* CCompositor::windowFloatingFromCursor() { for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) { - wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y}; + wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden) return &(*w); } @@ -364,7 +364,7 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW double subx, suby; - const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.x, pos.y - pWindow->m_vRealPosition.y, &subx, &suby); + const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x, pos.y - pWindow->m_vRealPosition.vec().y, &subx, &suby); if (PFOUND) { sl.x = subx; @@ -372,8 +372,8 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW return PFOUND; } - sl.x = pos.x - pWindow->m_vRealPosition.x; - sl.y = pos.y - pWindow->m_vRealPosition.y; + sl.x = pos.x - pWindow->m_vRealPosition.vec().x; + sl.y = pos.y - pWindow->m_vRealPosition.vec().y; return PSURFACE->surface; } @@ -403,22 +403,40 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { if (m_pLastWindow == pWindow && m_sSeat.seat->keyboard_state.focused_surface == pSurface) return; - if (windowValidMapped(m_pLastWindow) && m_pLastWindow->m_bIsX11) { - wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat); - wlr_seat_pointer_clear_focus(m_sSeat.seat); + const auto PLASTWINDOW = m_pLastWindow; + m_pLastWindow = pWindow; + + // we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window + if (windowValidMapped(PLASTWINDOW)) { + const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(PLASTWINDOW); + if (RENDERDATA.isBorderColor) + PLASTWINDOW->m_cRealBorderColor = RENDERDATA.borderColor; + else + PLASTWINDOW->m_cRealBorderColor = CColor(g_pConfigManager->getInt("general:col.inactive_border")); + + if (PLASTWINDOW->m_bIsX11) { + wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat); + wlr_seat_pointer_clear_focus(m_sSeat.seat); + } } + m_pLastWindow = PLASTWINDOW; + const auto PWINDOWSURFACE = pSurface ? pSurface : g_pXWaylandManager->getWindowSurface(pWindow); focusSurface(PWINDOWSURFACE, pWindow); - g_pXWaylandManager->activateWindow(pWindow, true); + g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow // do pointer focus too - const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition; + const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.goalv(); wlr_seat_pointer_notify_enter(m_sSeat.seat, PWINDOWSURFACE, POINTERLOCAL.x, POINTERLOCAL.y); - m_pLastWindow = pWindow; + const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow); + if (RENDERDATA.isBorderColor) + pWindow->m_cRealBorderColor = RENDERDATA.borderColor; + else + pWindow->m_cRealBorderColor = CColor(g_pConfigManager->getInt("general:col.active_border")); } void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { @@ -570,7 +588,7 @@ void CCompositor::fixXWaylandWindowsOnWorkspace(const int& id) { // so there is no need to check here // if the window is XWayland or not. if (ISVISIBLE && (!PWORKSPACE->m_bHasFullscreenWindow || w.m_bIsFullscreen)) - g_pXWaylandManager->moveXWaylandWindow(&w, w.m_vRealPosition); + g_pXWaylandManager->moveXWaylandWindow(&w, w.m_vRealPosition.vec()); else g_pXWaylandManager->moveXWaylandWindow(&w, Vector2D(42069,42069)); } @@ -604,7 +622,7 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) { void CCompositor::cleanupWindows() { for (auto& w : m_lWindowsFadingOut) { - if (!w->m_bFadingOut || w->m_fAlpha == 0.f) { + if (!w->m_bFadingOut || w->m_fAlpha.fl() == 0.f) { if (!w->m_bReadyToDelete) continue; @@ -742,4 +760,4 @@ CWorkspace* CCompositor::getWorkspaceByString(const std::string& str) { } return nullptr; -} \ No newline at end of file +} diff --git a/src/Window.cpp b/src/Window.cpp index ff8ba299..334ca86f 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,6 +1,13 @@ #include "Window.hpp" #include "Compositor.hpp" +CWindow::CWindow() { + m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*) this); + m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this); + m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this); + m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this); +} + CWindow::~CWindow() { if (g_pCompositor->isWindowActive(this)) { g_pCompositor->m_pLastFocus = nullptr; diff --git a/src/Window.hpp b/src/Window.hpp index 6969213a..11580138 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -3,6 +3,7 @@ #include "defines.hpp" #include "events/Events.hpp" #include "helpers/SubsurfaceTree.hpp" +#include "helpers/AnimatedVariable.hpp" struct SWindowSpecialRenderData { float alpha = 1.f; @@ -10,7 +11,7 @@ struct SWindowSpecialRenderData { class CWindow { public: - + CWindow(); ~CWindow(); DYNLISTENER(commitWindow); @@ -31,13 +32,9 @@ public: Vector2D m_vPosition = Vector2D(0,0); Vector2D m_vSize = Vector2D(0,0); - // this is the position and size of the goal placement - Vector2D m_vEffectivePosition = Vector2D(0,0); - Vector2D m_vEffectiveSize = Vector2D(0,0); - // this is the real position and size used to draw the thing - Vector2D m_vRealPosition = Vector2D(0,0); - Vector2D m_vRealSize = Vector2D(0,0); + CAnimatedVariable m_vRealPosition; + CAnimatedVariable m_vRealSize; // this is used for pseudotiling bool m_bIsPseudotiled = false; @@ -69,10 +66,10 @@ public: SSurfaceTreeNode* m_pSurfaceTree = nullptr; // Animated border - CColor m_cRealBorderColor = CColor(0,0,0,0); + CAnimatedVariable m_cRealBorderColor; // Fade in-out - float m_fAlpha = 0.f; + CAnimatedVariable m_fAlpha; bool m_bFadingOut = false; bool m_bReadyToDelete = false; @@ -84,7 +81,7 @@ public: // For the list lookup bool operator==(const CWindow& rhs) { - return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_fAlpha == rhs.m_fAlpha && m_bFadingOut == rhs.m_bFadingOut; + return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut; } }; \ No newline at end of file diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f321651c..e6d0ccd1 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -43,10 +43,14 @@ void CConfigManager::setDefaultVars() { configValues["animations:enabled"].intValue = 1; configValues["animations:speed"].floatValue = 7.f; + configValues["animations:curve"].strValue = "default"; + configValues["animations:windows_curve"].strValue = "[[f]]"; configValues["animations:windows_speed"].floatValue = 0.f; configValues["animations:windows"].intValue = 1; + configValues["animations:borders_curve"].strValue = "[[f]]"; configValues["animations:borders_speed"].floatValue = 0.f; configValues["animations:borders"].intValue = 1; + configValues["animations:fadein_curve"].strValue = "[[f]]"; configValues["animations:fadein_speed"].floatValue = 0.f; configValues["animations:fadein"].intValue = 1; @@ -207,6 +211,39 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string m_dMonitorRules.push_back(newrule); } +void CConfigManager::handleBezier(const std::string& command, const std::string& args) { + std::string curitem = ""; + + std::string argZ = args; + + auto nextItem = [&]() { + auto idx = argZ.find_first_of(','); + + if (idx != std::string::npos) { + curitem = argZ.substr(0, idx); + argZ = argZ.substr(idx + 1); + } else { + curitem = argZ; + argZ = ""; + } + }; + + nextItem(); + + std::string bezierName = curitem; + + nextItem(); + float p1x = std::stof(curitem); + nextItem(); + float p1y = std::stof(curitem); + nextItem(); + float p2x = std::stof(curitem); + nextItem(); + float p2y = std::stof(curitem); + + g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y)); +} + void CConfigManager::handleBind(const std::string& command, const std::string& value) { // example: // bind=SUPER,G,exec,dmenu_run @@ -311,6 +348,8 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std:: handleDefaultWorkspace(COMMAND, VALUE); } else if (COMMAND == "windowrule") { handleWindowRule(COMMAND, VALUE); + } else if (COMMAND == "bezier") { + handleBezier(COMMAND, VALUE); } else { configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE); } @@ -379,10 +418,10 @@ void CConfigManager::loadConfigLoadVars() { // reset all vars before loading setDefaultVars(); - m_dMonitorRules.clear(); m_dWindowRules.clear(); g_pKeybindManager->clearKeybinds(); + g_pAnimationManager->removeAllBeziers(); const char* const ENVHOME = getenv("HOME"); const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); @@ -606,3 +645,7 @@ void CConfigManager::performMonitorReload() { m_bWantsMonitorReload = false; } + +SConfigValue* CConfigManager::getConfigValuePtr(std::string val) { + return &configValues[val]; +} \ No newline at end of file diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 044b9751..5c1e125c 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -1,5 +1,7 @@ #pragma once +#define CONFIG_MANAGER_H + #include #include "../debug/Log.hpp" #include @@ -47,6 +49,8 @@ public: void setInt(std::string, int); void setString(std::string, std::string); + SConfigValue* getConfigValuePtr(std::string); + SMonitorRule getMonitorRuleFor(std::string); std::vector getMatchingRules(CWindow*); @@ -88,6 +92,7 @@ private: void handleUnbind(const std::string&, const std::string&); void handleWindowRule(const std::string&, const std::string&); void handleDefaultWorkspace(const std::string&, const std::string&); + void handleBezier(const std::string&, const std::string&); }; inline std::unique_ptr g_pConfigManager; \ No newline at end of file diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index a3a91cca..fab67969 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -26,7 +26,7 @@ std::string clientsRequest() { std::string result = ""; for (auto& w : g_pCompositor->m_lWindows) { result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\n", - &w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.x, (int)w.m_vRealPosition.y, (int)w.m_vRealSize.x, (int)w.m_vRealSize.y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str()), (int)w.m_bIsFloating); + &w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str()), (int)w.m_bIsFloating); } return result; } @@ -47,7 +47,7 @@ std::string activeWindowRequest() { return "Invalid"; return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\n", - PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.x, (int)PWINDOW->m_vRealPosition.y, (int)PWINDOW->m_vRealSize.x, (int)PWINDOW->m_vRealSize.y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating); + PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating); } std::string layersRequest() { diff --git a/src/events/Popups.cpp b/src/events/Popups.cpp index fd026fde..7a4f4885 100644 --- a/src/events/Popups.cpp +++ b/src/events/Popups.cpp @@ -95,8 +95,8 @@ void Events::listener_newPopupXDG(void* owner, void* data) { const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PNEWPOPUP->popup = WLRPOPUP; - PNEWPOPUP->lx = PWINDOW->m_vEffectivePosition.x; - PNEWPOPUP->ly = PWINDOW->m_vEffectivePosition.y; + PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x; + PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y; PNEWPOPUP->parentWindow = PWINDOW; PNEWPOPUP->monitor = PMONITOR; createNewPopup(WLRPOPUP, PNEWPOPUP); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 4887560c..3def4d82 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -17,8 +17,8 @@ void addViewCoords(void* pWindow, int* x, int* y) { const auto PWINDOW = (CWindow*)pWindow; - *x += PWINDOW->m_vEffectivePosition.x; - *y += PWINDOW->m_vEffectivePosition.y; + *x += PWINDOW->m_vRealPosition.goalv().x; + *y += PWINDOW->m_vRealPosition.goalv().y; } void Events::listener_mapWindow(void* owner, void* data) { @@ -33,6 +33,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bReadyToDelete = false; PWINDOW->m_bFadingOut = false; PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW); + PWINDOW->m_fAlpha = 255.f; // checks if the window wants borders and sets the appriopriate flag g_pXWaylandManager->checkBorders(PWINDOW); @@ -112,8 +113,8 @@ void Events::listener_mapWindow(void* owner, void* data) { Debug::log(LOG, "Rule size, applying to window %x", PWINDOW); - PWINDOW->m_vEffectiveSize = Vector2D(SIZEX, SIZEY); - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vEffectiveSize); + PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY); + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); } catch (...) { Debug::log(LOG, "Rule size failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str()); } @@ -128,7 +129,7 @@ void Events::listener_mapWindow(void* owner, void* data) { Debug::log(LOG, "Rule move, applying to window %x", PWINDOW); - PWINDOW->m_vEffectivePosition = Vector2D(POSX, POSY) + PMONITOR->vecPosition; + PWINDOW->m_vRealPosition = Vector2D(POSX, POSY) + PMONITOR->vecPosition; } catch (...) { Debug::log(LOG, "Rule move failed, rule: %s -> %s", r.szRule.c_str(), r.szValue.c_str()); } @@ -137,13 +138,13 @@ 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; + PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv(); } 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_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10); } g_pCompositor->focusWindow(PWINDOW); @@ -164,7 +165,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late"); } - Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vEffectivePosition.x, PWINDOW->m_vEffectivePosition.y, PWINDOW->m_vEffectiveSize.x, PWINDOW->m_vEffectiveSize.y); + Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y); } void Events::listener_unmapWindow(void* owner, void* data) { @@ -194,6 +195,8 @@ void Events::listener_unmapWindow(void* owner, void* data) { // Allow the renderer to catch the last frame. g_pHyprOpenGL->makeWindowSnapshot(PWINDOW); + PWINDOW->m_fAlpha = 0.f; + PWINDOW->m_bMappedX11 = false; // remove the fullscreen window status from workspace if we closed it @@ -298,17 +301,15 @@ void Events::listener_configureX11(void* owner, void* data) { const auto E = (wlr_xwayland_surface_configure_event*)data; if (!PWINDOW->m_bIsFloating) { - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize); + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec()); g_pInputManager->refocus(); return; } wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height); wlr_xwayland_surface_restack(PWINDOW->m_uSurface.xwayland, NULL, XCB_STACK_MODE_ABOVE); - PWINDOW->m_vEffectivePosition = Vector2D(E->x, E->y); - PWINDOW->m_vEffectiveSize = Vector2D(E->width, E->height); - PWINDOW->m_vRealPosition = PWINDOW->m_vEffectivePosition; - PWINDOW->m_vRealSize = PWINDOW->m_vRealSize; + PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(E->x, E->y)); + PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height)); PWINDOW->m_vPosition = PWINDOW->m_vPosition; PWINDOW->m_vSize = PWINDOW->m_vSize; @@ -322,7 +323,7 @@ void Events::listener_surfaceXWayland(wl_listener* listener, void* data) { Debug::log(LOG, "New XWayland Surface created."); - g_pCompositor->m_lWindows.push_back(CWindow()); + g_pCompositor->m_lWindows.emplace_back(); const auto PNEWWINDOW = &g_pCompositor->m_lWindows.back(); PNEWWINDOW->m_uSurface.xwayland = XWSURFACE; @@ -343,7 +344,7 @@ void Events::listener_newXDGSurface(wl_listener* listener, void* data) { if (XDGSURFACE->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) return; // TODO: handle? - g_pCompositor->m_lWindows.push_back(CWindow()); + g_pCompositor->m_lWindows.emplace_back(); const auto PNEWWINDOW = &g_pCompositor->m_lWindows.back(); PNEWWINDOW->m_uSurface.xdg = XDGSURFACE; diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp new file mode 100644 index 00000000..798e96e5 --- /dev/null +++ b/src/helpers/AnimatedVariable.cpp @@ -0,0 +1,55 @@ +#include "AnimatedVariable.hpp" +#include "../managers/AnimationManager.hpp" + +CAnimatedVariable::CAnimatedVariable() { + ; // dummy var +} + +void CAnimatedVariable::create(ANIMATEDVARTYPE type, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow) { + m_eVarType = type; + m_pSpeed = speed; + m_pEnabled = enabled; + m_pWindow = pWindow; + m_pBezier = pBezier; + + g_pAnimationManager->m_lAnimatedVariables.push_back(this); + + m_bDummy = false; +} + +void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow) { + create(type, speed, enabled, pBezier, pWindow); + + try { + switch (type) { + case AVARTYPE_FLOAT: { + const auto V = std::any_cast(val); + m_fValue = V; + m_fGoal = V; + break; + } + case AVARTYPE_VECTOR: { + const auto V = std::any_cast(val); + m_vValue = V; + m_vGoal = V; + break; + } + case AVARTYPE_COLOR: { + const auto V = std::any_cast(val); + m_cValue = V; + m_cGoal = V; + break; + } + default: + ASSERT(false); + break; + } + } catch (std::exception& e) { + Debug::log(ERR, "CAnimatedVariable create error: %s", e.what()); + RASSERT(false, "CAnimatedVariable create error: %s", e.what()); + } +} + +CAnimatedVariable::~CAnimatedVariable() { + g_pAnimationManager->m_lAnimatedVariables.remove(this); +} \ No newline at end of file diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp new file mode 100644 index 00000000..197e5d4e --- /dev/null +++ b/src/helpers/AnimatedVariable.hpp @@ -0,0 +1,171 @@ +#pragma once + +#include "../defines.hpp" +#include + +enum ANIMATEDVARTYPE { + AVARTYPE_INVALID = -1, + AVARTYPE_FLOAT, + AVARTYPE_VECTOR, + AVARTYPE_COLOR +}; + +class CAnimationManager; + +class CAnimatedVariable { +public: + CAnimatedVariable(); // dummy var + + void create(ANIMATEDVARTYPE, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow); + void create(ANIMATEDVARTYPE, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow); + + ~CAnimatedVariable(); + + // gets the current vector value (real time) + const Vector2D& vec() const { + ASSERT(m_eVarType == AVARTYPE_VECTOR); + return m_vValue; + } + + // gets the current float value (real time) + const float& fl() const { + ASSERT(m_eVarType == AVARTYPE_FLOAT); + return m_fValue; + } + + // gets the current color value (real time) + const CColor& col() const { + ASSERT(m_eVarType == AVARTYPE_COLOR); + return m_cValue; + } + + // gets the goal vector value + const Vector2D& goalv() const { + ASSERT(m_eVarType == AVARTYPE_VECTOR); + return m_vGoal; + } + + // gets the goal float value + const float& goalf() const { + ASSERT(m_eVarType == AVARTYPE_FLOAT); + return m_fGoal; + } + + // gets the goal color value + const CColor& goalc() const { + ASSERT(m_eVarType == AVARTYPE_COLOR); + return m_cGoal; + } + + void operator=(const Vector2D& v) { + ASSERT(m_eVarType == AVARTYPE_VECTOR); + m_vGoal = v; + animationBegin = std::chrono::system_clock::now(); + m_vBegun = m_vValue; + } + + void operator=(const float& v) { + ASSERT(m_eVarType == AVARTYPE_FLOAT); + m_fGoal = v; + animationBegin = std::chrono::system_clock::now(); + m_fBegun = m_fValue; + } + + void operator=(const CColor& v) { + ASSERT(m_eVarType == AVARTYPE_COLOR); + m_cGoal = v; + animationBegin = std::chrono::system_clock::now(); + m_cBegun = m_cValue; + } + + // Sets the actual stored value, without affecting the goal, but resets the timer + void setValue(const Vector2D& v) { + ASSERT(m_eVarType == AVARTYPE_VECTOR); + m_vValue = v; + animationBegin = std::chrono::system_clock::now(); + m_vBegun = m_vValue; + } + + // Sets the actual stored value, without affecting the goal, but resets the timer + void setValue(const float& v) { + ASSERT(m_eVarType == AVARTYPE_FLOAT); + m_fValue = v; + animationBegin = std::chrono::system_clock::now(); + m_vBegun = m_vValue; + } + + // Sets the actual stored value, without affecting the goal, but resets the timer + void setValue(const CColor& v) { + ASSERT(m_eVarType == AVARTYPE_COLOR); + m_cValue = v; + animationBegin = std::chrono::system_clock::now(); + m_vBegun = m_vValue; + } + + // Sets the actual value and goal + void setValueAndWarp(const Vector2D& v) { + ASSERT(m_eVarType == AVARTYPE_VECTOR); + m_vGoal = v; + warp(); + } + + // Sets the actual value and goal + void setValueAndWarp(const float& v) { + ASSERT(m_eVarType == AVARTYPE_FLOAT); + m_fGoal = v; + warp(); + } + + // Sets the actual value and goal + void setValueAndWarp(const CColor& v) { + ASSERT(m_eVarType == AVARTYPE_COLOR); + m_cGoal = v; + warp(); + } + +private: + + void warp() { + switch (m_eVarType) { + case AVARTYPE_FLOAT: { + m_fValue = m_fGoal; + break; + } + case AVARTYPE_VECTOR: { + m_vValue = m_vGoal; + break; + } + case AVARTYPE_COLOR: { + m_cValue = m_cGoal; + break; + } + default: + break; + } + } + + Vector2D m_vValue = Vector2D(0,0); + float m_fValue = 0; + CColor m_cValue; + + Vector2D m_vGoal = Vector2D(0,0); + float m_fGoal = 0; + CColor m_cGoal; + + Vector2D m_vBegun = Vector2D(0,0); + float m_fBegun = 0; + CColor m_cBegun; + + float* m_pSpeed = nullptr; + int64_t* m_pEnabled = nullptr; + void* m_pWindow = nullptr; + std::string* m_pBezier = nullptr; + + bool m_bDummy = true; + + std::chrono::system_clock::time_point animationBegin; + + ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID; + + friend class CAnimationManager; +}; \ No newline at end of file diff --git a/src/helpers/BezierCurve.cpp b/src/helpers/BezierCurve.cpp new file mode 100644 index 00000000..85e71f71 --- /dev/null +++ b/src/helpers/BezierCurve.cpp @@ -0,0 +1,69 @@ +#include "BezierCurve.hpp" + +void CBezierCurve::setup(std::vector* pVec) { + m_dPoints.clear(); + + const auto BEGIN = std::chrono::high_resolution_clock::now(); + + m_dPoints.emplace_back(Vector2D(0,0)); + + for (auto& p : *pVec) { + m_dPoints.push_back(p); + } + + m_dPoints.emplace_back(Vector2D(1,1)); + + RASSERT(m_dPoints.size() == 4, "CBezierCurve only supports cubic beziers! (points num: %i)", m_dPoints.size()); + + // bake BAKEDPOINTS points for faster lookups + // T -> X ( / BAKEDPOINTS ) + for (int i = 0; i < BAKEDPOINTS; ++i) { + m_aPointsBaked[i] = getXForT((i + 1) / (float)BAKEDPOINTS); + } + + const auto ELAPSEDUS = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGIN).count() / 1000.f; + const auto POINTSSIZE = m_aPointsBaked.size() * sizeof(m_aPointsBaked[0]) / 1000.f; + + const auto BEGINCALC = std::chrono::high_resolution_clock::now(); + for (float i = 0.1f; i < 1.f; i += 0.1f) + getYForPoint(i); + const auto ELAPSEDCALCAVG = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGINCALC).count() / 1000.f / 10.f; + + Debug::log(LOG, "Created a bezier curve, baked %i points, mem usage: %.2fkB, time to bake: %.2fµs. Estimated average calc time: %.2fµs.", + BAKEDPOINTS, POINTSSIZE, ELAPSEDUS, ELAPSEDCALCAVG); + +} + +float CBezierCurve::getYForT(float t) { + return 3 * t * pow(1 - t, 2) * m_dPoints[1].y + 3 * pow(t, 2) * (1 - t) * m_dPoints[2].y + pow(t, 3); +} + +float CBezierCurve::getXForT(float t) { + return 3 * t * pow(1 - t, 2) * m_dPoints[1].x + 3 * pow(t, 2) * (1 - t) * m_dPoints[2].x + pow(t, 3); +} + +// Todo: this probably can be done better and faster +float CBezierCurve::getYForPoint(float x) { + // binary search for the range UPDOWN X + float upperX = 1; + float lowerX = 0; + float mid = 0.5; + + while(std::abs(upperX - lowerX) > INVBAKEDPOINTS) { + if (m_aPointsBaked[((int)(mid * (float)BAKEDPOINTS))] > x) { + upperX = mid; + } else { + lowerX = mid; + } + + mid = (upperX + lowerX) / 2.f; + } + + // in the name of performance i shall make a hack + const auto PERCINDELTA = (x - m_aPointsBaked[(int)((float)BAKEDPOINTS * lowerX)]) / (m_aPointsBaked[(int)((float)BAKEDPOINTS * upperX)] - m_aPointsBaked[(int)((float)BAKEDPOINTS * lowerX)]); + + if (std::isnan(PERCINDELTA) || std::isinf(PERCINDELTA)) // can sometimes happen for VERY small x + return 0.f; + + return getYForT(mid + PERCINDELTA * INVBAKEDPOINTS); +} \ No newline at end of file diff --git a/src/helpers/BezierCurve.hpp b/src/helpers/BezierCurve.hpp new file mode 100644 index 00000000..72463119 --- /dev/null +++ b/src/helpers/BezierCurve.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "../defines.hpp" +#include + +constexpr int BAKEDPOINTS = 200; +constexpr float INVBAKEDPOINTS = 1.f / BAKEDPOINTS; + +// an implementation of a cubic bezier curve +// might do better later +// TODO: n-point curves +class CBezierCurve { +public: + // sets up the bezier curve. + // this EXCLUDES the 0,0 and 1,1 points, + void setup(std::vector* points); + + float getYForT(float t); + float getXForT(float t); + float getYForPoint(float x); + +private: + // this INCLUDES the 0,0 and 1,1 points. + std::deque m_dPoints; + + std::array m_aPointsBaked; +}; \ No newline at end of file diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp index 7c0d30be..c34dc787 100644 --- a/src/helpers/Color.hpp +++ b/src/helpers/Color.hpp @@ -11,5 +11,17 @@ public: float r = 0, g = 0, b = 0, a = 255; uint64_t getAsHex(); + + CColor operator- (const CColor& c2) const { + return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a); + } + + CColor operator+ (const CColor& c2) const { + return CColor(r + c2.r, g + c2.g, b + c2.b, a + c2.a); + } + + CColor operator* (const float& v) const { + return CColor(r * v, g * v, b * v, a * v); + } }; \ No newline at end of file diff --git a/src/helpers/Vector2D.hpp b/src/helpers/Vector2D.hpp index 5fe4ccd3..7288a088 100644 --- a/src/helpers/Vector2D.hpp +++ b/src/helpers/Vector2D.hpp @@ -14,24 +14,24 @@ class Vector2D { // returns the scale double normalize(); - Vector2D operator+(const Vector2D a) { + Vector2D operator+(const Vector2D a) const { return Vector2D(this->x + a.x, this->y + a.y); } - Vector2D operator-(const Vector2D a) { + Vector2D operator-(const Vector2D a) const { return Vector2D(this->x - a.x, this->y - a.y); } - Vector2D operator*(const float a) { + Vector2D operator*(const float a) const { return Vector2D(this->x * a, this->y * a); } - Vector2D operator/(const float a) { + Vector2D operator/(const float a) const { return Vector2D(this->x / a, this->y / a); } - bool operator==(const Vector2D& a) { + bool operator==(const Vector2D& a) const { return a.x == x && a.y == y; } - bool operator!=(const Vector2D& a) { + bool operator!=(const Vector2D& a) const { return a.x != x || a.y != y; } diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index e7f4b87a..a3fdeecb 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -119,8 +119,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) { PWINDOW->m_vSize = pNode->size; PWINDOW->m_vPosition = pNode->position; - PWINDOW->m_vEffectivePosition = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE); - PWINDOW->m_vEffectiveSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE); + auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE); + auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE); const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN, DISPLAYTOP ? GAPSOUT : GAPSIN); @@ -128,34 +128,37 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) { const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN, DISPLAYBOTTOM ? GAPSOUT : GAPSIN); - PWINDOW->m_vEffectivePosition = PWINDOW->m_vEffectivePosition + OFFSETTOPLEFT; - PWINDOW->m_vEffectiveSize = PWINDOW->m_vEffectiveSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; + calcPos = calcPos + OFFSETTOPLEFT; + calcSize = calcSize - 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.x > calcSize.x || PWINDOW->m_vPseudoSize.y > calcSize.y) { + if (PWINDOW->m_vPseudoSize.x > calcSize.x) { + scale = calcSize.x / PWINDOW->m_vPseudoSize.x; } - if (PWINDOW->m_vPseudoSize.y * scale > PWINDOW->m_vEffectiveSize.y) { - scale = PWINDOW->m_vEffectiveSize.y / PWINDOW->m_vPseudoSize.y; + if (PWINDOW->m_vPseudoSize.y * scale > calcSize.y) { + scale = calcSize.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 + auto DELTA = calcSize - PWINDOW->m_vPseudoSize * scale; + calcSize = PWINDOW->m_vPseudoSize * scale; + calcPos = calcPos + 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; + auto DELTA = calcSize - PWINDOW->m_vPseudoSize; + calcPos = calcPos + DELTA / 2.f; // center + calcSize = PWINDOW->m_vPseudoSize; } } - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vEffectiveSize); + PWINDOW->m_vRealSize = calcSize; + PWINDOW->m_vRealPosition = calcPos; + + g_pXWaylandManager->setWindowSize(PWINDOW, calcSize); } void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { @@ -190,8 +193,8 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { applyNodeDataToWindow(PNODE); - pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f; - pWindow->m_vRealSize = Vector2D(5, 5); + pWindow->m_vRealPosition.setValue(PNODE->position + PNODE->size / 2.f); + pWindow->m_vRealSize.setValue(Vector2D(5, 5)); return; } @@ -265,8 +268,8 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { applyNodeDataToWindow(OPENINGON); } - pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f; - pWindow->m_vRealSize = Vector2D(5,5); + pWindow->m_vRealPosition.setValue(PNODE->position + PNODE->size / 2.f); + pWindow->m_vRealSize.setValue(Vector2D(5,5)); } void CHyprDwindleLayout::onWindowRemoved(CWindow* pWindow) { @@ -364,16 +367,16 @@ void CHyprDwindleLayout::changeWindowFloatingMode(CWindow* pWindow) { if (!PNODE) { // save real pos cuz the func applies the default 5,5 mid - const auto PSAVEDPOS = pWindow->m_vRealPosition; - const auto PSAVEDSIZE = pWindow->m_vRealSize; + const auto PSAVEDPOS = pWindow->m_vRealPosition.vec(); + const auto PSAVEDSIZE = pWindow->m_vRealSize.vec(); // if the window is pseudo, update its size - pWindow->m_vPseudoSize = pWindow->m_vRealSize; + pWindow->m_vPseudoSize = pWindow->m_vRealSize.vec(); onWindowCreated(pWindow); - pWindow->m_vRealPosition = PSAVEDPOS; - pWindow->m_vRealSize = PSAVEDSIZE; + pWindow->m_vRealPosition.setValue(PSAVEDPOS); + pWindow->m_vRealSize.setValue(PSAVEDSIZE); } else { onWindowRemoved(pWindow); @@ -409,8 +412,8 @@ void CHyprDwindleLayout::onBeginDragWindow() { } m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal(); - m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition; - m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize; + m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.vec(); + m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.vec(); m_vLastDragXY = m_vBeginDragXY; g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); @@ -445,16 +448,13 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) { g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); if (g_pInputManager->dragButton == BTN_LEFT) { - DRAGGINGWINDOW->m_vRealPosition = m_vBeginDragPositionXY + DELTA; - DRAGGINGWINDOW->m_vEffectivePosition = DRAGGINGWINDOW->m_vRealPosition; + DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA); } else { if (DRAGGINGWINDOW->m_bIsFloating) { - DRAGGINGWINDOW->m_vRealSize = m_vBeginDragSizeXY + DELTA; - DRAGGINGWINDOW->m_vRealSize = Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.x, (double)20, (double)999999), std::clamp(DRAGGINGWINDOW->m_vRealSize.y, (double)20, (double)999999)); + DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA); + DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)999999))); - DRAGGINGWINDOW->m_vEffectiveSize = DRAGGINGWINDOW->m_vRealSize; - - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize); + g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); } else { // we need to adjust the splitratio @@ -515,7 +515,7 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) { } // get middle point - Vector2D middle = DRAGGINGWINDOW->m_vRealPosition + DRAGGINGWINDOW->m_vRealSize / 2.f; + Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.vec() + DRAGGINGWINDOW->m_vRealSize.vec() / 2.f; // and check its monitor const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle); @@ -540,12 +540,12 @@ void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) { if (desiredGeometry.width <= 0 || desiredGeometry.height <= 0) { const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow); - pWindow->m_vEffectiveSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height); - pWindow->m_vEffectivePosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.x) / 2.f, PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.y) / 2.f); + pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height); + pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.vec().x) / 2.f, PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.vec().y) / 2.f); } else { // we respect the size. - pWindow->m_vEffectiveSize = Vector2D(desiredGeometry.width, desiredGeometry.height); + pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height); // check if it's on the correct monitor! Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f; @@ -553,23 +553,23 @@ void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) { // TODO: detect a popup in a more consistent way. if ((g_pCompositor->getMonitorFromVector(middlePoint) && g_pCompositor->getMonitorFromVector(middlePoint)->ID != pWindow->m_iMonitorID) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) { // if it's not, fall back to the center placement - pWindow->m_vEffectivePosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f); + pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f); } else { // if it is, we respect where it wants to put itself. // most of these are popups - pWindow->m_vEffectivePosition = Vector2D(desiredGeometry.x, desiredGeometry.y); + pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y); } } if (!pWindow->m_bX11DoesntWantBorders) { - pWindow->m_vRealPosition = pWindow->m_vEffectivePosition + pWindow->m_vEffectiveSize / 2.f; - pWindow->m_vRealSize = Vector2D(5, 5); + pWindow->m_vRealPosition.setValue(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.f); + pWindow->m_vRealSize.setValue(Vector2D(5, 5)); } else { - pWindow->m_vRealPosition = pWindow->m_vEffectivePosition; - pWindow->m_vRealSize = pWindow->m_vEffectiveSize; + pWindow->m_vRealPosition.setValue(pWindow->m_vRealPosition.goalv()); + pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv()); } - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize); + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace); g_pCompositor->moveWindowToTop(pWindow); @@ -599,25 +599,25 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow) { applyNodeDataToWindow(PNODE); else { // get back its' dimensions from position and size - pWindow->m_vEffectivePosition = pWindow->m_vPosition; - pWindow->m_vEffectiveSize = pWindow->m_vSize; + pWindow->m_vRealPosition = pWindow->m_vPosition; + pWindow->m_vRealSize = pWindow->m_vSize; - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize); + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); } } else { // if it now got fullscreen, make it fullscreen // save position and size if floating if (pWindow->m_bIsFloating) { - pWindow->m_vPosition = pWindow->m_vRealPosition; - pWindow->m_vSize = pWindow->m_vRealSize; + pWindow->m_vPosition = pWindow->m_vRealPosition.vec(); + pWindow->m_vSize = pWindow->m_vRealSize.vec(); } // apply new pos and size being monitors' box - pWindow->m_vEffectivePosition = PMONITOR->vecPosition; - pWindow->m_vEffectiveSize = PMONITOR->vecSize; + pWindow->m_vRealPosition = PMONITOR->vecPosition; + pWindow->m_vRealSize = PMONITOR->vecSize; - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize); + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); } g_pCompositor->moveWindowToTop(pWindow); @@ -650,14 +650,20 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) { if (PGROUPPARENT) { // if there is a parent, release it - for (auto& node : PGROUPPARENT->groupMembers) + const auto INACTIVEBORDERCOL = CColor(g_pConfigManager->getInt("general:col.inactive_border")); + for (auto& node : PGROUPPARENT->groupMembers) { node->pGroupParent = nullptr; + node->pWindow->m_cRealBorderColor.setValueAndWarp(INACTIVEBORDERCOL); // no anim here because they pop in + } PGROUPPARENT->groupMembers.clear(); PGROUPPARENT->isGroup = false; PGROUPPARENT->recalcSizePosRecursive(); + + if (g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow)) + g_pCompositor->m_pLastWindow->m_cRealBorderColor = CColor(g_pConfigManager->getInt("general:col.active_border")); } else { // if there is no parent, let's make one @@ -675,8 +681,14 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) { PPARENT->groupMembers = allChildren; - for (auto& c : PPARENT->groupMembers) + const auto GROUPINACTIVEBORDERCOL = CColor(g_pConfigManager->getInt("dwinle:col.group_border")); + for (auto& c : PPARENT->groupMembers) { c->pGroupParent = PPARENT; + c->pWindow->m_cRealBorderColor = GROUPINACTIVEBORDERCOL; + + if (c->pWindow == g_pCompositor->m_pLastWindow) + c->pWindow->m_cRealBorderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active")); + } PPARENT->groupMemberActive = 0; diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index f77c3d7c..59f46804 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -1,6 +1,24 @@ #include "AnimationManager.hpp" #include "../Compositor.hpp" +CAnimationManager::CAnimationManager() { + std::vector points = {Vector2D(0, 0.75f), Vector2D(0.15f, 1.f)}; + m_mBezierCurves["default"].setup(&points); +} + +void CAnimationManager::removeAllBeziers() { + m_mBezierCurves.clear(); + + // add the default one + std::vector points = {Vector2D(0, 0.75f), Vector2D(0.15f, 1.f)}; + m_mBezierCurves["default"].setup(&points); +} + +void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) { + std::vector points = {p1, p2}; + m_mBezierCurves[name].setup(&points); +} + void CAnimationManager::tick() { bool animationsDisabled = false; @@ -8,116 +26,100 @@ void CAnimationManager::tick() { if (!g_pConfigManager->getInt("animations:enabled")) animationsDisabled = true; - const bool WINDOWSENABLED = g_pConfigManager->getInt("animations:windows") && !animationsDisabled; - const bool BORDERSENABLED = g_pConfigManager->getInt("animations:borders") && !animationsDisabled; - const bool FADEENABLED = g_pConfigManager->getInt("animations:fadein") && !animationsDisabled; const float ANIMSPEED = g_pConfigManager->getFloat("animations:speed"); - - // Process speeds - const float WINDOWSPEED = g_pConfigManager->getFloat("animations:windows_speed") == 0 ? ANIMSPEED : g_pConfigManager->getFloat("animations:windows_speed"); - const float BORDERSPEED = g_pConfigManager->getFloat("animations:borders_speed") == 0 ? ANIMSPEED : g_pConfigManager->getFloat("animations:borders_speed"); - const float FADESPEED = g_pConfigManager->getFloat("animations:fadein_speed") == 0 ? ANIMSPEED : g_pConfigManager->getFloat("animations:fadein_speed"); - - const auto BORDERACTIVECOL = CColor(g_pConfigManager->getInt("general:col.active_border")); - const auto BORDERINACTIVECOL = CColor(g_pConfigManager->getInt("general:col.inactive_border")); - const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); + const auto BEZIERSTR = g_pConfigManager->getString("animations:curve"); - for (auto& w : g_pCompositor->m_lWindows) { + auto DEFAULTBEZIER = m_mBezierCurves.find(BEZIERSTR); + if (DEFAULTBEZIER == m_mBezierCurves.end()) + DEFAULTBEZIER = m_mBezierCurves.find("default"); - // get the box before transforms, for damage tracking later - wlr_box WLRBOXPREV = { w.m_vRealPosition.x - BORDERSIZE - 1, w.m_vRealPosition.y - BORDERSIZE - 1, w.m_vRealSize.x + 2 * BORDERSIZE + 2, w.m_vRealSize.y + 2 * BORDERSIZE + 2}; - bool needsDamage = false; + for (auto& av : m_lAnimatedVariables) { + // get speed + const auto SPEED = *av->m_pSpeed == 0 ? ANIMSPEED : *av->m_pSpeed; - // process fadeinout - if (FADEENABLED) { - const auto GOALALPHA = w.m_bIsMapped ? 255.f : 0.f; - w.m_bFadingOut = false; - - if (!deltazero(w.m_fAlpha, GOALALPHA)) { - if (deltaSmallToFlip(w.m_fAlpha, GOALALPHA)) { - w.m_fAlpha = GOALALPHA; - } else { - if (w.m_fAlpha > GOALALPHA) - w.m_bFadingOut = true; - w.m_fAlpha = parabolic(w.m_fAlpha, GOALALPHA, FADESPEED); - } - - needsDamage = true; - } - - } else { - const auto GOALALPHA = w.m_bIsMapped ? 255.f : 0.f; - - if (!deltazero(GOALALPHA, w.m_fAlpha)) { - if (w.m_bIsMapped) - w.m_fAlpha = 255.f; - else { - w.m_fAlpha = 0.f; - w.m_bFadingOut = false; - } - - needsDamage = true; - } - } - - // process fadein/out for unmapped windows, but nothing else. - // we can't use windowValidMapped because we want to animate hidden windows too. - if (!g_pCompositor->windowExists(&w) || !w.m_bIsMapped || !g_pXWaylandManager->getWindowSurface(&w)){ - if (needsDamage) { - g_pHyprRenderer->damageWindow(&w); // only window, it didnt move cuz its unmappy - } + // window stuff + const auto PWINDOW = (CWindow*)av->m_pWindow; + wlr_box WLRBOXPREV = {PWINDOW->m_vRealPosition.vec().x - BORDERSIZE - 1, PWINDOW->m_vRealPosition.vec().y - BORDERSIZE - 1, PWINDOW->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, PWINDOW->m_vRealSize.vec().y + 2 * BORDERSIZE + 2}; + // check if it's disabled, if so, warp + if (av->m_pEnabled == 0 || animationsDisabled) { + av->warp(); + g_pHyprRenderer->damageBox(&WLRBOXPREV); + g_pHyprRenderer->damageWindow(PWINDOW); continue; } - // process the borders - const auto RENDERHINTS = g_pLayoutManager->getCurrentLayout()->requestRenderHints(&w); + // beziers are with a switch unforto + // TODO: maybe do something cleaner - const auto& COLOR = RENDERHINTS.isBorderColor ? RENDERHINTS.borderColor : g_pCompositor->isWindowActive(&w) ? BORDERACTIVECOL : BORDERINACTIVECOL; + // get the spent % (0 - 1) + const auto DURATIONPASSED = std::chrono::duration_cast(std::chrono::system_clock::now() - av->animationBegin).count(); + const float SPENT = std::clamp((DURATIONPASSED / 100.f) / SPEED, 0.f, 1.f); - if (BORDERSENABLED) { - if (!deltazero(COLOR, w.m_cRealBorderColor)) { - if (deltaSmallToFlip(COLOR, w.m_cRealBorderColor)) { - w.m_cRealBorderColor = COLOR; + switch (av->m_eVarType) { + case AVARTYPE_FLOAT: { + if (!deltazero(av->m_fValue, av->m_fGoal)) { + const auto DELTA = av->m_fGoal - av->m_fBegun; + const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier); + + if (BEZIER != m_mBezierCurves.end()) + av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA; + else + av->m_fValue = av->m_fBegun + DEFAULTBEZIER->second.getYForPoint(SPENT) * DELTA; + + if (SPENT >= 1.f) { + av->warp(); + } } else { - w.m_cRealBorderColor = parabolic(BORDERSPEED, w.m_cRealBorderColor, COLOR); + continue; // dont process } - needsDamage = true; + break; } - } else { - if (!deltazero(w.m_cRealBorderColor, COLOR)) - needsDamage = true; - w.m_cRealBorderColor = COLOR; - } + case AVARTYPE_VECTOR: { + if (!deltazero(av->m_vValue, av->m_vGoal)) { + const auto DELTA = av->m_vGoal - av->m_vBegun; + const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier); - // process the window - if (WINDOWSENABLED) { - if (!deltazero(w.m_vRealPosition, w.m_vEffectivePosition) || !deltazero(w.m_vRealSize, w.m_vEffectiveSize)) { - if (deltaSmallToFlip(w.m_vRealPosition, w.m_vEffectivePosition) && deltaSmallToFlip(w.m_vRealSize, w.m_vEffectiveSize)) { - w.m_vRealPosition = w.m_vEffectivePosition; - w.m_vRealSize = w.m_vEffectiveSize; - g_pXWaylandManager->setWindowSize(&w, w.m_vRealSize); + if (BEZIER != m_mBezierCurves.end()) + av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT); + else + av->m_vValue = av->m_vBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT); + + if (SPENT >= 1.f) { + av->warp(); + } } else { - // if it is to be animated, animate it. - w.m_vRealPosition = Vector2D(parabolic(w.m_vRealPosition.x, w.m_vEffectivePosition.x, WINDOWSPEED), parabolic(w.m_vRealPosition.y, w.m_vEffectivePosition.y, WINDOWSPEED)); - w.m_vRealSize = Vector2D(parabolic(w.m_vRealSize.x, w.m_vEffectiveSize.x, WINDOWSPEED), parabolic(w.m_vRealSize.y, w.m_vEffectiveSize.y, WINDOWSPEED)); + continue; // dont process } - - needsDamage = true; + break; } - } else { - if (!deltazero(w.m_vRealPosition, w.m_vEffectivePosition) || !deltazero(w.m_vRealSize, w.m_vEffectiveSize)) - needsDamage = true; + case AVARTYPE_COLOR: { + if (!deltazero(av->m_cValue, av->m_cGoal)) { + const auto DELTA = av->m_cGoal - av->m_cBegun; + const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier); - w.m_vRealPosition = w.m_vEffectivePosition; - w.m_vRealSize = w.m_vEffectiveSize; + if (BEZIER != m_mBezierCurves.end()) + av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT); + else + av->m_cValue = av->m_cBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT); + + if (SPENT >= 1.f) { + av->warp(); + } + } else { + continue; // dont process + } + break; + } + default: { + ; + } } - if (needsDamage) { - g_pHyprRenderer->damageBox(&WLRBOXPREV); - g_pHyprRenderer->damageWindow(&w); - } + // damage the window + g_pHyprRenderer->damageBox(&WLRBOXPREV); + g_pHyprRenderer->damageWindow(PWINDOW); } } @@ -143,19 +145,4 @@ bool CAnimationManager::deltazero(const float& a, const float& b) { bool CAnimationManager::deltazero(const CColor& a, const CColor& b) { return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; -} - -double CAnimationManager::parabolic(const double from, const double to, const double incline) { - return from + ((to - from) / incline); -} - -CColor CAnimationManager::parabolic(const double incline, const CColor& from, const CColor& to) { - CColor newColor; - - newColor.r = parabolic(from.r, to.r, incline); - newColor.g = parabolic(from.g, to.g, incline); - newColor.b = parabolic(from.b, to.b, incline); - newColor.a = parabolic(from.a, to.a, incline); - - return newColor; } \ No newline at end of file diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 8d2c86b6..ab0d8357 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -2,11 +2,20 @@ #include "../defines.hpp" #include +#include +#include "../helpers/AnimatedVariable.hpp" +#include "../helpers/BezierCurve.hpp" class CAnimationManager { public: + CAnimationManager(); + void tick(); + void addBezierWithName(std::string, const Vector2D&, const Vector2D&); + void removeAllBeziers(); + + std::list m_lAnimatedVariables; private: bool deltaSmallToFlip(const Vector2D& a, const Vector2D& b); @@ -15,8 +24,8 @@ private: bool deltazero(const Vector2D& a, const Vector2D& b); bool deltazero(const CColor& a, const CColor& b); bool deltazero(const float& a, const float& b); - double parabolic(const double, const double, const double); - CColor parabolic(const double, const CColor&, const CColor&); + + std::unordered_map m_mBezierCurves; }; inline std::unique_ptr g_pAnimationManager; \ No newline at end of file diff --git a/src/managers/InputManager.cpp b/src/managers/InputManager.cpp index 219acdac..4166fd22 100644 --- a/src/managers/InputManager.cpp +++ b/src/managers/InputManager.cpp @@ -57,11 +57,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); for (auto w = g_pCompositor->m_lWindows.rbegin(); w != g_pCompositor->m_lWindows.rend(); ++w) { - wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y}; + wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; if (w->m_iWorkspaceID == pFoundWindow->m_iWorkspaceID && w->m_bIsMapped && w->m_bCreatedOverFullscreen && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y)) { foundSurface = g_pXWaylandManager->getWindowSurface(&(*w)); if (foundSurface) - surfacePos = w->m_vRealPosition; + surfacePos = w->m_vRealPosition.vec(); break; } } @@ -70,7 +70,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (pFoundWindow->m_bIsX11) { foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow); if (foundSurface) - surfacePos = pFoundWindow->m_vRealPosition; + surfacePos = pFoundWindow->m_vRealPosition.vec(); } else { foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); } @@ -91,7 +91,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); } else { foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow); - surfacePos = pFoundWindow->m_vRealPosition; + surfacePos = pFoundWindow->m_vRealPosition.vec(); } } @@ -143,7 +143,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (g_pCompositor->m_pLastWindow == CONSTRAINTWINDOW) { // todo: this is incorrect, but it will work in most cases for now // i made this cuz i wanna play minecraft lol - Vector2D deltaToMiddle = (CONSTRAINTWINDOW->m_vRealPosition + CONSTRAINTWINDOW->m_vRealSize / 2.f) - mouseCoords; + Vector2D deltaToMiddle = (CONSTRAINTWINDOW->m_vRealPosition.vec() + CONSTRAINTWINDOW->m_vRealSize.vec() / 2.f) - mouseCoords; wlr_cursor_move(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, deltaToMiddle.x, deltaToMiddle.y); } } @@ -389,7 +389,7 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co if (constraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) { if (PWINDOW) { wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, - constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.x, constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.y); + constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.vec().x, constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.vec().y); wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y); } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 06fdf5f4..8a503005 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -143,8 +143,8 @@ void CKeybindManager::toggleActiveFloating(std::string args) { if (g_pCompositor->windowValidMapped(ACTIVEWINDOW)) { ACTIVEWINDOW->m_bIsFloating = !ACTIVEWINDOW->m_bIsFloating; - ACTIVEWINDOW->m_vRealPosition = ACTIVEWINDOW->m_vRealPosition + Vector2D(5, 5); - ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition - Vector2D(10, 10); + ACTIVEWINDOW->m_vRealPosition.setValue(ACTIVEWINDOW->m_vRealPosition.vec() + Vector2D(5, 5)); + ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition.vec() - Vector2D(10, 10); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW); } @@ -311,18 +311,17 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { PWINDOW->m_vPosition = Vector2D(-42069, -42069); // Save the real position and size because the layout might set its own - const auto PSAVEDSIZE = PWINDOW->m_vRealSize; - const auto PSAVEDPOS = PWINDOW->m_vRealPosition; + const auto PSAVEDSIZE = PWINDOW->m_vRealSize.vec(); + const auto PSAVEDPOS = PWINDOW->m_vRealPosition.vec(); g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); // and restore it - PWINDOW->m_vRealPosition = PSAVEDPOS; - PWINDOW->m_vRealSize = PSAVEDSIZE; + PWINDOW->m_vRealPosition.setValue(PSAVEDPOS); + PWINDOW->m_vRealSize.setValue(PSAVEDSIZE); if (PWINDOW->m_bIsFloating) { - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition - g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID)->vecPosition; - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition + g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID)->vecPosition; - PWINDOW->m_vEffectivePosition = PWINDOW->m_vRealPosition; - PWINDOW->m_vPosition = PWINDOW->m_vRealPosition; + PWINDOW->m_vRealPosition.setValue(PWINDOW->m_vRealPosition.vec() - g_pCompositor->getMonitorFromID(OLDWORKSPACE->m_iMonitorID)->vecPosition); + PWINDOW->m_vRealPosition.setValue(PWINDOW->m_vRealPosition.vec() + g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID)->vecPosition); + PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec(); } } @@ -338,7 +337,7 @@ void CKeybindManager::moveFocusTo(std::string args) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { g_pCompositor->focusWindow(PWINDOWTOCHANGETO); - Vector2D middle = PWINDOWTOCHANGETO->m_vEffectivePosition + PWINDOWTOCHANGETO->m_vEffectiveSize / 2.f; + Vector2D middle = PWINDOWTOCHANGETO->m_vRealPosition.goalv() + PWINDOWTOCHANGETO->m_vRealSize.goalv() / 2.f; wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y); }; diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index fcb72ef5..9efefc75 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -117,7 +117,7 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) { void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) { if (pWindow->m_bIsX11) - wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.x, pWindow->m_vRealPosition.y, size.x, size.y); + wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y); else wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y); } @@ -172,7 +172,7 @@ void CHyprXWaylandManager::moveXWaylandWindow(CWindow* pWindow, const Vector2D& return; if (pWindow->m_bIsX11) { - wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.x, pWindow->m_vRealSize.y); + wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y); } } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 32e30e7a..4d706e3b 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -625,7 +625,7 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) { wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y}; - renderTextureInternal(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha, 0); + renderTextureInternal(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), 0); } void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) { diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b2964d31..0d50dae4 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -30,7 +30,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { } bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { - wlr_box geometry = {pWindow->m_vRealPosition.x, pWindow->m_vRealPosition.y, pWindow->m_vRealSize.x, pWindow->m_vRealSize.y}; + wlr_box geometry = {pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y}; if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry)) return false; @@ -83,13 +83,13 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* return; } - const auto REALPOS = pWindow->m_vRealPosition; + const auto REALPOS = pWindow->m_vRealPosition.vec(); SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y}; renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow); - renderdata.w = pWindow->m_vRealSize.x; - renderdata.h = pWindow->m_vRealSize.y; + renderdata.w = pWindow->m_vRealSize.vec().x; + renderdata.h = pWindow->m_vRealSize.vec().y; renderdata.dontRound = pWindow->m_bIsFullscreen; - renderdata.fadeAlpha = pWindow->m_fAlpha; + renderdata.fadeAlpha = pWindow->m_fAlpha.fl(); renderdata.alpha = pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity"); // apply window special data @@ -99,7 +99,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* // border if (decorate && !pWindow->m_bX11DoesntWantBorders) - drawBorderForWindow(pWindow, pMonitor, pWindow->m_fAlpha * renderdata.alpha); + drawBorderForWindow(pWindow, pMonitor, pWindow->m_fAlpha.fl() * renderdata.alpha); if (pWindow->m_bIsX11) { if (pWindow->m_uSurface.xwayland->surface) { @@ -411,14 +411,14 @@ void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor, fl if (BORDERSIZE < 1) return; - auto BORDERCOL = pWindow->m_cRealBorderColor; + auto BORDERCOL = pWindow->m_cRealBorderColor.col(); BORDERCOL.a *= (alpha / 255.f); - Vector2D correctPos = pWindow->m_vRealPosition - pMonitor->vecPosition; - Vector2D correctSize = pWindow->m_vRealSize; + Vector2D correctPos = pWindow->m_vRealPosition.vec() - pMonitor->vecPosition; + Vector2D correctSize = pWindow->m_vRealSize.vec(); // top - wlr_box border = {correctPos.x - BORDERSIZE / 2.f, correctPos.y - BORDERSIZE / 2.f, pWindow->m_vRealSize.x + BORDERSIZE, pWindow->m_vRealSize.y + BORDERSIZE}; + wlr_box border = {correctPos.x - BORDERSIZE / 2.f, correctPos.y - BORDERSIZE / 2.f, pWindow->m_vRealSize.vec().x + BORDERSIZE, pWindow->m_vRealSize.vec().y + BORDERSIZE}; g_pHyprOpenGL->renderBorder(&border, BORDERCOL, BORDERSIZE, g_pConfigManager->getInt("decoration:rounding")); } @@ -456,7 +456,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) { } else { // damage by real size & pos + border size * 2 (JIC) const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); - wlr_box damageBox = { pWindow->m_vRealPosition.x - BORDERSIZE - 1 - PMONITOR->vecPosition.x, pWindow->m_vRealPosition.y - BORDERSIZE - 1 - PMONITOR->vecPosition.y, pWindow->m_vRealSize.x + 2 * BORDERSIZE + 2, pWindow->m_vRealSize.y + 2 * BORDERSIZE + 2}; + wlr_box damageBox = { pWindow->m_vRealPosition.vec().x - BORDERSIZE - 1, pWindow->m_vRealPosition.vec().y - BORDERSIZE - 1, pWindow->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, pWindow->m_vRealSize.vec().y + 2 * BORDERSIZE + 2}; for (auto& m : g_pCompositor->m_lMonitors) wlr_output_damage_add_box(m.damage, &damageBox); }