From 069a21a34ef062bb278cf70f153cfdd0bfec9df2 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 16 Jun 2024 19:52:07 +0200 Subject: [PATCH 01/30] xwayland: force default plain mime atoms on known types ref #6247 --- src/xwayland/XDataSource.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index 98e0701b..f4059ee1 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -49,10 +49,16 @@ std::vector CXDataSource::mimes() { void CXDataSource::send(const std::string& mime, uint32_t fd) { xcb_atom_t mimeAtom = 0; - for (size_t i = 0; i < mimeTypes.size(); ++i) { - if (mimeTypes.at(i) == mime) { - mimeAtom = mimeAtoms.at(i); - break; + if (mime == "text/plain") + mimeAtom = HYPRATOMS["TEXT"]; + else if (mime == "text/plain;charset=utf-8") + mimeAtom = HYPRATOMS["UTF8_STRING"]; + else { + for (size_t i = 0; i < mimeTypes.size(); ++i) { + if (mimeTypes.at(i) == mime) { + mimeAtom = mimeAtoms.at(i); + break; + } } } From 738530e62ee48f7326cd5a610b90b47344b701f1 Mon Sep 17 00:00:00 2001 From: Dashie Date: Sun, 16 Jun 2024 20:01:08 +0200 Subject: [PATCH 02/30] xdg-shell: Continue transform of popup until size fits (#6521) --- src/protocols/XDGShell.cpp | 47 ++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index dddc3bca..c16ebb9d 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -539,30 +539,33 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa if (success) return predictedBox.translate(-parentCoord - constraint.pos()); + CBox test = predictedBox; + if (state.constraintAdjustment & (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y)) { // attempt to flip - const bool flipX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X; - const bool flipY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y; + const bool flipX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X; + const bool flipY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y; + auto countEdges = [constraint](const CBox& test) -> int { + int edgeCount = 0; + edgeCount += test.x < constraint.x ? 1 : 0; + edgeCount += test.x + test.w > constraint.x + constraint.w ? 1 : 0; + edgeCount += test.y < constraint.y ? 1 : 0; + edgeCount += test.y + test.h > constraint.y + constraint.h ? 1 : 0; + return edgeCount; + }; + int edgeCount = countEdges(test); - CBox test = predictedBox; - success = true; - if (flipX && test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}).expand(-1).inside(constraint)) + if (flipX && edgeCount > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}))) test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}); - else if (flipY && test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}).expand(-1).inside(constraint)) + if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}))) test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}); - else if (flipX && flipY && test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}).expand(-1).inside(constraint)) - test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}); - else - success = false; + + success = test.copy().expand(-1).inside(constraint); if (success) return test.translate(-parentCoord - constraint.pos()); } - // if flips fail, we will slide and remember. - // if the positioner is allowed to resize, then resize the slid thing. - CBox test = predictedBox; - // for slide and resize, defines the padding around the edge for the positioned // surface. constexpr int EDGE_PADDING = 4; @@ -575,10 +578,10 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa //const bool gravityLeft = state.gravity == XDG_POSITIONER_GRAVITY_NONE || state.gravity == XDG_POSITIONER_GRAVITY_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_TOP_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_BOTTOM_LEFT; //const bool gravityTop = state.gravity == XDG_POSITIONER_GRAVITY_NONE || state.gravity == XDG_POSITIONER_GRAVITY_TOP || state.gravity == XDG_POSITIONER_GRAVITY_TOP_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_TOP_RIGHT; - const bool leftEdgeOut = predictedBox.x < constraint.x; - const bool topEdgeOut = predictedBox.y < constraint.y; - const bool rightEdgeOut = predictedBox.x + predictedBox.w > constraint.x + constraint.w; - const bool bottomEdgeOut = predictedBox.y + predictedBox.h > constraint.y + constraint.h; + const bool leftEdgeOut = test.x < constraint.x; + const bool topEdgeOut = test.y < constraint.y; + const bool rightEdgeOut = test.x + test.w > constraint.x + constraint.w; + const bool bottomEdgeOut = test.y + test.h > constraint.y + constraint.h; // TODO: this isn't truly conformant. if (leftEdgeOut && slideX) @@ -600,10 +603,10 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa const bool resizeX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X; const bool resizeY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y; - const bool leftEdgeOut = predictedBox.x < constraint.x; - const bool topEdgeOut = predictedBox.y < constraint.y; - const bool rightEdgeOut = predictedBox.x + predictedBox.w > constraint.x + constraint.w; - const bool bottomEdgeOut = predictedBox.y + predictedBox.h > constraint.y + constraint.h; + const bool leftEdgeOut = test.x < constraint.x; + const bool topEdgeOut = test.y < constraint.y; + const bool rightEdgeOut = test.x + test.w > constraint.x + constraint.w; + const bool bottomEdgeOut = test.y + test.h > constraint.y + constraint.h; // TODO: this isn't truly conformant. if (leftEdgeOut && resizeX) { From 172ee1cadaabd3ba4df330f9cdd02fb520b59e71 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 16 Jun 2024 20:36:55 +0200 Subject: [PATCH 03/30] data-device: minor fixups ref #6543 firefox needs a re-enter after a dnd don't destroy dnd on an offer destroy, it's not valid --- src/protocols/core/DataDevice.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index e54d3633..986d1176 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -12,20 +12,8 @@ CWLDataOfferResource::CWLDataOfferResource(SP resource_, SPsetDestroy([this](CWlDataOffer* r) { - if (!dead && (recvd || accepted)) - PROTO::data->completeDrag(); - else - PROTO::data->abortDrag(); - PROTO::data->destroyResource(this); - }); - resource->setOnDestroy([this](CWlDataOffer* r) { - if (!dead && (recvd || accepted)) - PROTO::data->completeDrag(); - else - PROTO::data->abortDrag(); - PROTO::data->destroyResource(this); - }); + resource->setDestroy([this](CWlDataOffer* r) { PROTO::data->destroyResource(this); }); + resource->setOnDestroy([this](CWlDataOffer* r) { PROTO::data->destroyResource(this); }); resource->setAccept([this](CWlDataOffer* r, uint32_t serial, const char* mime) { if (!source) { @@ -210,7 +198,7 @@ CWLDataDeviceResource::CWLDataDeviceResource(SP resource_) : reso pClient = resource->client(); - resource->setSetSelection([this](CWlDataDevice* r, wl_resource* sourceR, uint32_t serial) { + resource->setSetSelection([](CWlDataDevice* r, wl_resource* sourceR, uint32_t serial) { auto source = sourceR ? CWLDataSourceResource::fromResource(sourceR) : CSharedPointer{}; if (!source) { LOGM(LOG, "Reset selection received"); @@ -226,7 +214,7 @@ CWLDataDeviceResource::CWLDataDeviceResource(SP resource_) : reso g_pSeatManager->setCurrentSelection(source); }); - resource->setStartDrag([this](CWlDataDevice* r, wl_resource* sourceR, wl_resource* origin, wl_resource* icon, uint32_t serial) { + resource->setStartDrag([](CWlDataDevice* r, wl_resource* sourceR, wl_resource* origin, wl_resource* icon, uint32_t serial) { auto source = CWLDataSourceResource::fromResource(sourceR); if (!source) { LOGM(ERR, "No source in drag"); @@ -615,6 +603,7 @@ void CWLDataDeviceProtocol::dropDrag() { dnd.overriddenCursor = false; g_pInputManager->simulateMouseMovement(); + g_pSeatManager->resendEnterEvents(); } bool CWLDataDeviceProtocol::wasDragSuccessful() { @@ -645,6 +634,7 @@ void CWLDataDeviceProtocol::completeDrag() { dnd.currentSource.reset(); g_pInputManager->simulateMouseMovement(); + g_pSeatManager->resendEnterEvents(); } void CWLDataDeviceProtocol::abortDrag() { @@ -664,6 +654,7 @@ void CWLDataDeviceProtocol::abortDrag() { dnd.currentSource.reset(); g_pInputManager->simulateMouseMovement(); + g_pSeatManager->resendEnterEvents(); } void CWLDataDeviceProtocol::renderDND(CMonitor* pMonitor, timespec* when) { From d5ef10abf429355246abcda65fe4c15d886fad7c Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 16 Jun 2024 20:56:50 +0200 Subject: [PATCH 04/30] data-device: properly abort drag on missing device sometimes there is no focused device (e.g. when dnd'ing on nothing or xwayland) in which case abort would fail to send cancelled to the source. ref #6543 --- src/protocols/core/DataDevice.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 986d1176..2d50ff15 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -644,11 +644,13 @@ void CWLDataDeviceProtocol::abortDrag() { g_pInputManager->unsetCursorImage(); dnd.overriddenCursor = false; - if (!dnd.focusedDevice || !dnd.currentSource) + if (!dnd.focusedDevice && !dnd.currentSource) return; - dnd.focusedDevice->sendLeave(); - dnd.currentSource->cancelled(); + if (dnd.focusedDevice) + dnd.focusedDevice->sendLeave(); + if (dnd.currentSource) + dnd.currentSource->cancelled(); dnd.focusedDevice.reset(); dnd.currentSource.reset(); From b15be9c77de593581007de53b2bbca97d121900a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 16 Jun 2024 21:34:17 +0200 Subject: [PATCH 05/30] xwayland: do not set a new data source if it has no MIMEs ref #6247 --- src/xwayland/XWM.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 719adcb9..7b57de0f 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -1034,16 +1034,16 @@ void CXWM::initSelection() { } void CXWM::setClipboardToWayland(SXSelection& sel) { - sel.dataSource = makeShared(sel); - if (sel.dataSource->mimes().empty()) { + auto source = makeShared(sel); + if (source->mimes().empty()) { Debug::log(ERR, "[xwm] can't set clipboard: no MIMEs"); - sel.dataSource.reset(); + return; } - if (sel.dataSource) { - Debug::log(LOG, "[xwm] X clipboard at {:x} takes clipboard", (uintptr_t)sel.dataSource.get()); - g_pSeatManager->setCurrentSelection(sel.dataSource); - } + sel.dataSource = source; + + Debug::log(LOG, "[xwm] X clipboard at {:x} takes clipboard", (uintptr_t)sel.dataSource.get()); + g_pSeatManager->setCurrentSelection(sel.dataSource); } void CXWM::getTransferData(SXSelection& sel) { From 9cb3bf1cac1a38fbac3942a60415d7050ffcd2cb Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 17 Jun 2024 13:03:59 +0300 Subject: [PATCH 06/30] Nix: tidy up derivation --- nix/default.nix | 55 ++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/nix/default.nix b/nix/default.nix index 0493abc1..6b5068bc 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -11,6 +11,7 @@ expat, fribidi, git, + hwdata, hyprcursor, hyprlang, hyprutils, @@ -18,26 +19,28 @@ jq, libGL, libdatrie, + libdisplay-info, libdrm, libexecinfo, libinput, + libliftoff, libselinux, libsepol, libthai, libuuid, libxkbcommon, mesa, + meson, pango, pciutils, pcre2, python3, + seatd, systemd, tomlplusplus, - udis86, wayland, wayland-protocols, wayland-scanner, - wlroots, xorg, xwayland, debug ? false, @@ -76,23 +79,21 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov sed -i "s#@PREFIX@/##g" hyprland.pc.in ''; + COMMITS = commit; DATE = date; + DIRTY = lib.optionalString (commit == "") "dirty"; HASH = commit; - DIRTY = if commit == "" then "dirty" else ""; - nativeBuildInputs = lib.concatLists [ - [ - hyprwayland-scanner - jq - makeWrapper - cmake - ninja - pkg-config - python3 - wayland-scanner - ] - # introduce this later so that cmake takes precedence - wlroots.nativeBuildInputs + nativeBuildInputs = [ + hyprwayland-scanner + jq + makeWrapper + cmake + meson # for wlroots + ninja + pkg-config + python3 # for udis86 + wayland-scanner ]; outputs = [ @@ -102,14 +103,13 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov ]; buildInputs = lib.concatLists [ - wlroots.buildInputs - udis86.buildInputs [ cairo expat fribidi git - hyprcursor.dev + hwdata + hyprcursor hyprlang hyprutils libGL @@ -128,12 +128,18 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov tomlplusplus wayland wayland-protocols + # for wlroots + seatd + libdisplay-info + libliftoff ] (lib.optionals stdenv.hostPlatform.isMusl [libexecinfo]) (lib.optionals enableXWayland [ xorg.libxcb xorg.libXdmcp xorg.xcbutil + xorg.xcbutilerrors + xorg.xcbutilrenderutil xorg.xcbutilwm xwayland ]) @@ -145,6 +151,9 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov then "Debug" else "RelWithDebInfo"; + # we want as much debug info as possible + dontStrip = true; + cmakeFlags = [ (lib.cmakeBool "NO_XWAYLAND" (!enableXWayland)) (lib.cmakeBool "LEGACY_RENDERER" legacyRenderer) @@ -164,11 +173,11 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov passthru.providedSessions = ["hyprland"]; - meta = with lib; { + meta = { homepage = "https://github.com/hyprwm/Hyprland"; - description = "A dynamic tiling Wayland compositor that doesn't sacrifice on its looks"; - license = licenses.bsd3; - platforms = wlroots.meta.platforms; + description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks"; + license = lib.licenses.bsd3; + platforms = lib.platforms.linux; mainProgram = "Hyprland"; }; } From 14ab0ecc5eb3c437dd62f92629fc29e33679043b Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 17 Jun 2024 13:14:26 +0300 Subject: [PATCH 07/30] Nix: don't strip in debug builds Strip in Release builds, as the non-stripped binary is almost 500MB. --- nix/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/default.nix b/nix/default.nix index 6b5068bc..a2302688 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -152,7 +152,7 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov else "RelWithDebInfo"; # we want as much debug info as possible - dontStrip = true; + dontStrip = debug; cmakeFlags = [ (lib.cmakeBool "NO_XWAYLAND" (!enableXWayland)) From 1360677478e867034713e5d43d7a8a8f6bf1343d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 12:42:32 +0200 Subject: [PATCH 08/30] subcompositor/renderer: fixup handling of subsurfaces below the main one some apps (notably vlc 4) place a subsurface below the main surface (which is kinda cursed) but we have to accomodate for that --- src/helpers/WLClasses.hpp | 3 ++ src/protocols/core/Compositor.cpp | 25 ++++++++++++--- src/protocols/core/Subcompositor.cpp | 48 ++++++++++++++++++++++------ src/protocols/core/Subcompositor.hpp | 2 ++ src/render/Renderer.cpp | 12 ++++++- 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 247aa8f0..bcd6bf10 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -51,6 +51,9 @@ struct SRenderData { PHLWINDOW pWindow; bool popup = false; + + // counts how many surfaces this pass has rendered + int surfaceCounter = 0; }; struct SSwipeGesture { diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index db6e3258..165da6ee 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -277,8 +277,26 @@ void CWLSurfaceResource::resetRole() { } void CWLSurfaceResource::bfHelper(std::vector> nodes, std::function, const Vector2D&, void*)> fn, void* data) { - for (auto& n : nodes) { + std::vector> nodes2; + + // first, gather all nodes below + for (auto& n : nodes) { + std::erase_if(n->subsurfaces, [](const auto& e) { return e.expired(); }); + // subsurfaces is sorted lowest -> highest + for (auto& c : n->subsurfaces) { + if (c->zIndex >= 0) + break; + nodes2.push_back(c->surface.lock()); + } + } + + if (!nodes2.empty()) + bfHelper(nodes2, fn, data); + + nodes2.clear(); + + for (auto& n : nodes) { Vector2D offset = {}; if (n->role->role() == SURFACE_ROLE_SUBSURFACE) { auto subsurface = (CWLSubsurfaceResource*)n->role.get(); @@ -288,11 +306,10 @@ void CWLSurfaceResource::bfHelper(std::vector> nodes, std fn(n, offset, data); } - std::vector> nodes2; - for (auto& n : nodes) { - std::erase_if(n->subsurfaces, [](const auto& e) { return e.expired(); }); for (auto& c : n->subsurfaces) { + if (c->zIndex < 0) + continue; nodes2.push_back(c->surface.lock()); } } diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp index d407636c..cbc4063a 100644 --- a/src/protocols/core/Subcompositor.cpp +++ b/src/protocols/core/Subcompositor.cpp @@ -23,15 +23,29 @@ CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SPsubsurfaces, self.lock()); + auto pushAboveIndex = [this](int idx) -> void { + for (auto& c : parent->subsurfaces) { + if (c->zIndex >= idx) + c->zIndex++; + } + }; + + std::erase_if(parent->subsurfaces, [this](const auto& e) { return e == self || !e; }); auto it = std::find(parent->subsurfaces.begin(), parent->subsurfaces.end(), SURF); if (it == parent->subsurfaces.end()) { - LOGM(ERR, "Invalid surface reference in placeAbove"); - parent->subsurfaces.emplace_back(self.lock()); - } else - parent->subsurfaces.insert(it, self.lock()); + LOGM(ERR, "Invalid surface reference in placeAbove, likely parent"); + pushAboveIndex(1); + parent->subsurfaces.emplace_back(self); + zIndex = 1; + } else { + pushAboveIndex((*it)->zIndex); + zIndex = (*it)->zIndex; + parent->subsurfaces.emplace_back(self); + } + + std::sort(parent->subsurfaces.begin(), parent->subsurfaces.end(), [](const auto& a, const auto& b) { return a->zIndex < b->zIndex; }); }); resource->setPlaceBelow([this](CWlSubsurface* r, wl_resource* surf) { @@ -40,15 +54,29 @@ CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SPsubsurfaces, self.lock()); + auto pushBelowIndex = [this](int idx) -> void { + for (auto& c : parent->subsurfaces) { + if (c->zIndex <= idx) + c->zIndex--; + } + }; + + std::erase_if(parent->subsurfaces, [this](const auto& e) { return e == self || !e; }); auto it = std::find(parent->subsurfaces.begin(), parent->subsurfaces.end(), SURF); if (it == parent->subsurfaces.end()) { - LOGM(ERR, "Invalid surface reference in placeBelow"); - parent->subsurfaces.emplace_back(self.lock()); - } else - parent->subsurfaces.insert(it--, self.lock()); + LOGM(ERR, "Invalid surface reference in placeBelow, likely parent"); + pushBelowIndex(-1); + parent->subsurfaces.emplace_back(self); + zIndex = -1; + } else { + pushBelowIndex((*it)->zIndex); + zIndex = (*it)->zIndex; + parent->subsurfaces.emplace_back(self); + } + + std::sort(parent->subsurfaces.begin(), parent->subsurfaces.end(), [](const auto& a, const auto& b) { return a->zIndex < b->zIndex; }); }); listeners.commitSurface = surface->events.commit.registerListener([this](std::any d) { diff --git a/src/protocols/core/Subcompositor.hpp b/src/protocols/core/Subcompositor.hpp index abcfbf6d..824f0ffc 100644 --- a/src/protocols/core/Subcompositor.hpp +++ b/src/protocols/core/Subcompositor.hpp @@ -35,6 +35,8 @@ class CWLSubsurfaceResource : public ISurfaceRole { WP self; + int zIndex = 1; // by default, it's above + struct { CSignal destroy; } events; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 19b646a4..f56fb5d6 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -209,7 +209,10 @@ static void renderSurface(SP surface, int x, int y, void* da else g_pHyprOpenGL->blend(true); - if (RDATA->surface && surface == RDATA->surface) { + // FIXME: This is wrong and will bug the blur out as shit if the first surface + // is a subsurface that does NOT cover the entire frame. In such cases, we probably should fall back + // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) + if (RDATA->surfaceCounter == 0) { if (RDATA->blur) g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, surface, rounding, RDATA->blockBlurOptimization, RDATA->fadeAlpha); else @@ -235,6 +238,9 @@ static void renderSurface(SP surface, int x, int y, void* da g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET; + + // up the counter so that we dont blur any surfaces above this one + RDATA->surfaceCounter++; } bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, CMonitor* pMonitor) { @@ -602,6 +608,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, CMonitor* pMonitor, timespec renderdata.blur = false; } + renderdata.surfaceCounter = 0; pWindow->m_pWLSurface->resource()->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, &renderdata); @@ -658,6 +665,8 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, CMonitor* pMonitor, timespec if (pWindow->m_sAdditionalConfigData.nearestNeighbor.toUnderlying()) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; + renderdata.surfaceCounter = 0; + pWindow->m_pPopupHead->breadthfirst( [](CPopup* popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource()) @@ -743,6 +752,7 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, CMonitor* pMonitor, timespec* time renderdata.dontRound = true; renderdata.popup = true; renderdata.blur = pLayer->forceBlurPopups; + renderdata.surfaceCounter = 0; if (popups) { pLayer->popupHead->breadthfirst( [](CPopup* popup, void* data) { From 785d0628876a4782759b13c25fa644c12f340356 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 16:07:32 +0200 Subject: [PATCH 09/30] seat: track pressed pointer buttons releases them on leave, unless there is a dnd going on --- src/protocols/core/Seat.cpp | 26 ++++++++++++++++++++++++++ src/protocols/core/Seat.hpp | 2 ++ 2 files changed, 28 insertions(+) diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index be05955c..f578292a 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -1,5 +1,6 @@ #include "Seat.hpp" #include "Compositor.hpp" +#include "DataDevice.hpp" #include "../../devices/IKeyboard.hpp" #include "../../managers/SeatManager.hpp" #include "../../config/ConfigValue.hpp" @@ -128,6 +129,18 @@ void CWLPointerResource::sendLeave() { if (!owner || !currentSurface) return; + // release all buttons unless we have a dnd going on in which case + // the events shall be lost. + if (!PROTO::data->dndActive()) { + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + for (auto& b : pressedButtons) { + sendButton(now.tv_sec * 1000 + now.tv_nsec / 1000000, b, WL_POINTER_BUTTON_STATE_RELEASED); + } + } + + pressedButtons.clear(); + resource->sendLeave(g_pSeatManager->nextSerial(owner.lock()), currentSurface->getResource().get()); currentSurface.reset(); listeners.destroySurface.reset(); @@ -144,6 +157,19 @@ void CWLPointerResource::sendButton(uint32_t timeMs, uint32_t button, wl_pointer if (!owner || !currentSurface) return; + if (state == WL_POINTER_BUTTON_STATE_RELEASED && std::find(pressedButtons.begin(), pressedButtons.end(), button) == pressedButtons.end()) { + LOGM(ERR, "sendButton release on a non-pressed button"); + return; + } else if (state == WL_POINTER_BUTTON_STATE_PRESSED && std::find(pressedButtons.begin(), pressedButtons.end(), button) != pressedButtons.end()) { + LOGM(ERR, "sendButton press on a non-pressed button"); + return; + } + + if (state == WL_POINTER_BUTTON_STATE_RELEASED) + std::erase(pressedButtons, button); + else if (state == WL_POINTER_BUTTON_STATE_PRESSED) + pressedButtons.emplace_back(button); + resource->sendButton(g_pSeatManager->nextSerial(owner.lock()), timeMs, button, state); } diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 625d3a98..0b563b8f 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -76,6 +76,8 @@ class CWLPointerResource { SP resource; WP currentSurface; + std::vector pressedButtons; + struct { CHyprSignalListener destroySurface; } listeners; From a9c7a0830fd9a8b9fc4065f1cd654efd1326691a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 16:14:45 +0200 Subject: [PATCH 10/30] data-device: minor fixes send leave after drop, improve checks in completeDrag --- src/protocols/core/DataDevice.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 2d50ff15..9634d569 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -540,7 +540,7 @@ void CWLDataDeviceProtocol::initiateDrag(WP currentSource } void CWLDataDeviceProtocol::updateDrag() { - if (!dnd.currentSource) + if (!dndActive()) return; if (dnd.focusedDevice) @@ -595,15 +595,13 @@ void CWLDataDeviceProtocol::dropDrag() { } dnd.focusedDevice->sendDrop(); + dnd.focusedDevice->sendLeave(); resetDndState(); if (dnd.overriddenCursor) g_pInputManager->unsetCursorImage(); dnd.overriddenCursor = false; - - g_pInputManager->simulateMouseMovement(); - g_pSeatManager->resendEnterEvents(); } bool CWLDataDeviceProtocol::wasDragSuccessful() { @@ -624,11 +622,13 @@ bool CWLDataDeviceProtocol::wasDragSuccessful() { void CWLDataDeviceProtocol::completeDrag() { resetDndState(); - if (!dnd.focusedDevice || !dnd.currentSource) + if (!dnd.focusedDevice && !dnd.currentSource) return; - dnd.currentSource->sendDndDropPerformed(); - dnd.currentSource->sendDndFinished(); + if (dnd.currentSource) { + dnd.currentSource->sendDndDropPerformed(); + dnd.currentSource->sendDndFinished(); + } dnd.focusedDevice.reset(); dnd.currentSource.reset(); From 28ce0e0f804de50f75eab797bc404c1be0b54442 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Mon, 17 Jun 2024 17:37:36 +0200 Subject: [PATCH 11/30] misc: a few compiler level performance optimisations (#6559) * window: use const references instead of copies use const references instead of wasteful copies and make the = operator check for self assignment and return early. also use const in all the other operators. * listener: pass std::function as const reference instead of copies pass the std::functions as const references. * config: dont unnecessarily convert to c_str getHyprlangConfigValuePtr wants an std::string and we already have an std::string, dont convert it to a c_str only for it to be converted back to an std::string. * buffer: pass attributes as const reference pass attributes as const reference instead of copies. --- src/config/ConfigValue.hpp | 2 +- src/desktop/Window.hpp | 30 +++++++++++++++++------------- src/helpers/WLListener.cpp | 4 ++-- src/helpers/WLListener.hpp | 4 ++-- src/protocols/types/DMABuffer.cpp | 2 +- src/protocols/types/DMABuffer.hpp | 2 +- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/config/ConfigValue.hpp b/src/config/ConfigValue.hpp index 72accd67..fc8abb4b 100644 --- a/src/config/ConfigValue.hpp +++ b/src/config/ConfigValue.hpp @@ -11,7 +11,7 @@ template class CConfigValue { public: CConfigValue(const std::string& val) { - const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val.c_str()); + const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val); p_ = PVHYPRLANG->getDataStaticPtr(); diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 16bf297c..3f387d31 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -62,18 +62,22 @@ class IWindowTransformer; template class CWindowOverridableVar { public: - CWindowOverridableVar(T val) { + CWindowOverridableVar(T const& val) { value = val; } ~CWindowOverridableVar() = default; - CWindowOverridableVar& operator=(CWindowOverridableVar other) { - if (locked) + CWindowOverridableVar& operator=(CWindowOverridableVar const& other) { + // Self-assignment check + if (this == &other) return *this; - locked = other.locked; - value = other.value; + // Check if the current object is locked + if (!locked) { + locked = other.locked; + value = other.value; + } return *this; } @@ -85,36 +89,36 @@ class CWindowOverridableVar { return other; } - void forceSetIgnoreLocked(T val, bool lock = false) { + void forceSetIgnoreLocked(T const& val, bool lock = false) { value = val; locked = lock; } - T operator*(T& other) { + T operator*(T const& other) { return value * other; } - T operator+(T& other) { + T operator+(T const& other) { return value + other; } - bool operator==(T& other) { + bool operator==(T const& other) { return other == value; } - bool operator>=(T& other) { + bool operator>=(T const& other) { return value >= other; } - bool operator<=(T& other) { + bool operator<=(T const& other) { return value <= other; } - bool operator>(T& other) { + bool operator>(T const& other) { return value > other; } - bool operator<(T& other) { + bool operator<(T const& other) { return value < other; } diff --git a/src/helpers/WLListener.cpp b/src/helpers/WLListener.cpp index 978ff034..2ea5c0b6 100644 --- a/src/helpers/WLListener.cpp +++ b/src/helpers/WLListener.cpp @@ -18,7 +18,7 @@ void handleWrapped(wl_listener* listener, void* data) { g_pWatchdog->endWatching(); } -CHyprWLListener::CHyprWLListener(wl_signal* pSignal, std::function callback, void* pOwner) { +CHyprWLListener::CHyprWLListener(wl_signal* pSignal, std::function const& callback, void* pOwner) { initCallback(pSignal, callback, pOwner); } @@ -44,7 +44,7 @@ bool CHyprWLListener::isConnected() { return !wl_list_empty(&m_swWrapper.m_sListener.link); } -void CHyprWLListener::initCallback(wl_signal* pSignal, std::function callback, void* pOwner, std::string author) { +void CHyprWLListener::initCallback(wl_signal* pSignal, std::function const& callback, void* pOwner, std::string author) { if (isConnected()) { Debug::log(ERR, "Tried to connect a listener twice?!"); return; diff --git a/src/helpers/WLListener.hpp b/src/helpers/WLListener.hpp index d5d925b0..621458e6 100644 --- a/src/helpers/WLListener.hpp +++ b/src/helpers/WLListener.hpp @@ -6,7 +6,7 @@ class CHyprWLListener { public: - CHyprWLListener(wl_signal*, std::function, void* owner); + CHyprWLListener(wl_signal*, std::function const&, void* owner); CHyprWLListener(); ~CHyprWLListener(); @@ -15,7 +15,7 @@ class CHyprWLListener { CHyprWLListener& operator=(const CHyprWLListener&) = delete; CHyprWLListener& operator=(CHyprWLListener&&) = delete; - void initCallback(wl_signal*, std::function, void* owner, std::string author = ""); + void initCallback(wl_signal*, std::function const&, void* owner, std::string author = ""); void removeCallback(); diff --git a/src/protocols/types/DMABuffer.cpp b/src/protocols/types/DMABuffer.cpp index f26328e9..7c3a9886 100644 --- a/src/protocols/types/DMABuffer.cpp +++ b/src/protocols/types/DMABuffer.cpp @@ -3,7 +3,7 @@ #include "../../render/Renderer.hpp" #include "../../helpers/Format.hpp" -CDMABuffer::CDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs attrs_) : attrs(attrs_) { +CDMABuffer::CDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs const& attrs_) : attrs(attrs_) { g_pHyprRenderer->makeEGLCurrent(); listeners.resourceDestroy = events.destroy.registerListener([this](std::any d) { diff --git a/src/protocols/types/DMABuffer.hpp b/src/protocols/types/DMABuffer.hpp index dac89493..d07840b7 100644 --- a/src/protocols/types/DMABuffer.hpp +++ b/src/protocols/types/DMABuffer.hpp @@ -4,7 +4,7 @@ class CDMABuffer : public IWLBuffer { public: - CDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs attrs_); + CDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs const& attrs_); virtual ~CDMABuffer(); virtual eBufferCapability caps(); From d1340bd1d8eedd274283e0cb2568a3ed67b58c81 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 17:53:44 +0200 Subject: [PATCH 12/30] keybinds: ignore missing keysyms if no other methods match fixes #6548 --- src/managers/KeybindManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 14fadf02..875ba239 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -636,6 +636,12 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi if (found || key.submapAtPress != m_szCurrentSelectedSubmap) continue; } else { + // in this case, we only have the keysym to go off. + // if the keysym failed resolving, we can't do anything. It's likely missing + // from the keymap. + if (key.keysym == 0) + return false; + // oMg such performance hit!!11! // this little maneouver is gonna cost us 4µs const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_NO_FLAGS); From 236150b3c5227bbfbe46d2610c739a386afdca1f Mon Sep 17 00:00:00 2001 From: Aqa-Ib Date: Tue, 18 Jun 2024 17:06:14 +0200 Subject: [PATCH 13/30] github: reword bug or regression (#6520) --- .github/ISSUE_TEMPLATE/bug.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 285a15a1..e3e97bef 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -5,18 +5,21 @@ body: - type: markdown attributes: value: | - Before opening a new issue, take a moment to search through the current open ones. + ## Before opening a new issue, please take a moment to search through the current open and closed issues to check if it already exists. --- - type: dropdown id: type attributes: - label: Bug or Regression? - description: Is this a bug or a regression? + label: Regression? + description: | + Regression means that something used to work but no longer does. + **BEFORE CONTINUING**, please check if this bug is a regression or not, and if it is, we need you to bisect with the help of the wiki: https://wiki.hyprland.org/Crashes-and-Bugs/#bisecting-an-issue + multiple: true options: - - Bug - - Regression + - "Yes" + - "No" validations: required: true From b98e0876d3b54b7625bacf14e3546dd2d0e600d0 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Jun 2024 21:38:33 +0200 Subject: [PATCH 14/30] hyprctl: avoid using select() move to poll() ref #6584 --- src/debug/HyprCtl.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 70b886f2..e212ed1c 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -1784,13 +1785,17 @@ int hyprCtlFDTick(int fd, uint32_t mask, void* data) { std::array readBuffer; - fd_set fdset; - FD_ZERO(&fdset); - FD_SET(ACCEPTEDCONNECTION, &fdset); - timeval timeout = {.tv_sec = 0, .tv_usec = 5000}; - auto success = select(ACCEPTEDCONNECTION + 1, &fdset, nullptr, nullptr, &timeout); + // + pollfd pollfds[1] = { + { + .fd = ACCEPTEDCONNECTION, + .events = POLLIN, + }, + }; - if (success <= 0) { + int ret = poll(pollfds, 1, 5000); + + if (ret <= 0) { close(ACCEPTEDCONNECTION); return 0; } From e0e3c4c6ae15af88ac5fd5ab959adfe45a2e1dca Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Jun 2024 21:52:55 +0200 Subject: [PATCH 15/30] compositor: bump nofile rlimits on launch ref #6584 --- src/Compositor.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 2f972335..af46b0ff 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -29,6 +29,7 @@ using namespace Hyprutils::String; #include #include +#include int handleCritSignal(int signo, void* data) { Debug::log(LOG, "Hyprland received signal {}", signo); @@ -70,6 +71,46 @@ void handleUserSignal(int sig) { } } +static void bumpNofile() { + unsigned long limit = 1024; + + try { + std::ifstream f("/proc/sys/fs/nr_open"); + if (!f.good()) + limit = 1073741816; + else { + std::string content((std::istreambuf_iterator(f)), (std::istreambuf_iterator())); + f.close(); + + limit = std::stoll(content); + } + + } catch (...) { limit = 1073741816; } + + struct rlimit rlimit_; + if (!getrlimit(RLIMIT_NOFILE, &rlimit_)) + Debug::log(LOG, "Old rlimit: soft -> {}, hard -> {}", rlimit_.rlim_cur, rlimit_.rlim_max); + + if (rlimit_.rlim_max <= 1024) + rlimit_.rlim_max = limit; + + unsigned long oldHardLimit = rlimit_.rlim_max; + + rlimit_.rlim_max = limit; + + if (setrlimit(RLIMIT_NOFILE, &rlimit_) < 0) { + Debug::log(LOG, "Failed bumping NOFILE limits higher, retrying with previous hard."); + rlimit_.rlim_max = oldHardLimit; + rlimit_.rlim_cur = std::clamp((unsigned long)limit, 1UL, (unsigned long)rlimit_.rlim_max); + + if (setrlimit(RLIMIT_NOFILE, &rlimit_) < 0) + Debug::log(LOG, "Failed bumping NOFILE limits higher for the second time."); + } + + if (!getrlimit(RLIMIT_NOFILE, &rlimit_)) + Debug::log(LOG, "New rlimit: soft -> {}, hard -> {}", rlimit_.rlim_cur, rlimit_.rlim_max); +} + CCompositor::CCompositor() { m_iHyprlandPID = getpid(); @@ -131,6 +172,8 @@ CCompositor::CCompositor() { setRandomSplash(); Debug::log(LOG, "\nCurrent splash: {}\n\n", m_szCurrentSplash); + + bumpNofile(); } CCompositor::~CCompositor() { From 6e5804b53de753f24953d9d647940df66bc68f6d Mon Sep 17 00:00:00 2001 From: random2907 <81547183+random2907@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:50:49 +0530 Subject: [PATCH 16/30] hyprctl: fix zsh completion (#6467) Co-authored-by: random2907 --- hyprctl/hyprctl.zsh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hyprctl/hyprctl.zsh b/hyprctl/hyprctl.zsh index 6babd835..1a4cc187 100644 --- a/hyprctl/hyprctl.zsh +++ b/hyprctl/hyprctl.zsh @@ -1,3 +1,5 @@ +#compdef hyprctl + _hyprctl_cmd_2 () { hyprctl monitors | grep Monitor | awk '{ print $2 }' } From fb15b7aa2a9bba0f0693f84d0c65d386942583f8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 19 Jun 2024 16:20:06 +0200 Subject: [PATCH 17/30] core: Move to hyprutils for Math Moves CRegion, CBox and Vector2D over to hyprutils. Requires hyprutils>=0.1.4 --- CMakeLists.txt | 2 +- src/Compositor.cpp | 3 +- src/SharedDefs.hpp | 29 +-- src/config/ConfigManager.cpp | 3 +- src/debug/HyprNotificationOverlay.cpp | 2 +- src/desktop/LayerSurface.cpp | 4 +- src/desktop/WLSurface.cpp | 2 +- src/desktop/WLSurface.hpp | 2 +- src/desktop/Window.cpp | 10 +- src/desktop/Window.hpp | 136 +++++------ src/desktop/Workspace.cpp | 16 +- src/devices/IKeyboard.hpp | 2 +- src/devices/IPointer.hpp | 2 +- src/devices/ITouch.hpp | 2 +- src/devices/Tablet.hpp | 4 +- src/helpers/AnimatedVariable.hpp | 2 +- src/helpers/BezierCurve.hpp | 2 +- src/helpers/Box.cpp | 179 -------------- src/helpers/Box.hpp | 92 -------- src/helpers/Format.hpp | 2 +- src/helpers/MiscFunctions.cpp | 2 +- src/helpers/MiscFunctions.hpp | 2 +- src/helpers/Monitor.cpp | 4 +- src/helpers/Monitor.hpp | 2 +- src/helpers/Region.cpp | 183 --------------- src/helpers/Region.hpp | 69 ------ src/helpers/Vector2D.cpp | 58 ----- src/helpers/Vector2D.hpp | 133 ----------- src/helpers/WLClasses.hpp | 2 +- src/helpers/math/Math.cpp | 220 ++++++++++++++++++ src/helpers/math/Math.hpp | 11 + src/includes.hpp | 2 - src/layout/DwindleLayout.cpp | 12 +- src/layout/IHyprLayout.cpp | 4 +- src/layout/MasterLayout.cpp | 4 +- src/macros.hpp | 7 + src/managers/AnimationManager.cpp | 18 +- src/managers/CursorManager.cpp | 9 +- src/managers/CursorManager.hpp | 2 +- src/managers/PointerManager.cpp | 2 +- src/managers/PointerManager.hpp | 4 +- src/managers/SeatManager.hpp | 2 +- src/managers/input/InputMethodPopup.hpp | 2 +- src/managers/input/Swipe.cpp | 40 ++-- src/managers/input/TextInput.hpp | 2 +- src/protocols/LayerShell.cpp | 2 +- src/protocols/LayerShell.hpp | 2 +- src/protocols/PointerConstraints.hpp | 4 +- src/protocols/PointerGestures.hpp | 2 +- src/protocols/RelativePointer.hpp | 2 +- src/protocols/Screencopy.cpp | 9 +- src/protocols/Tablet.hpp | 2 +- src/protocols/TextInputV3.hpp | 2 +- src/protocols/ToplevelExport.cpp | 2 +- src/protocols/XDGShell.cpp | 20 +- src/protocols/XDGShell.hpp | 4 +- src/protocols/core/Compositor.cpp | 2 +- src/protocols/core/Compositor.hpp | 2 +- src/protocols/core/DataDevice.hpp | 2 +- src/protocols/core/Seat.hpp | 2 +- src/protocols/core/Shm.hpp | 2 +- src/render/OpenGL.cpp | 38 +-- src/render/OpenGL.hpp | 2 +- src/render/Renderer.cpp | 16 +- src/render/Renderer.hpp | 2 +- src/render/Texture.cpp | 2 +- src/render/Texture.hpp | 2 +- .../decorations/CHyprBorderDecoration.hpp | 16 +- .../decorations/CHyprDropShadowDecoration.cpp | 2 +- .../decorations/CHyprDropShadowDecoration.hpp | 14 +- .../decorations/CHyprGroupBarDecoration.hpp | 2 +- .../decorations/DecorationPositioner.cpp | 30 +-- .../decorations/DecorationPositioner.hpp | 28 +-- .../decorations/IHyprWindowDecoration.hpp | 2 +- src/xwayland/XSurface.hpp | 2 +- src/xwayland/XWM.cpp | 2 +- 76 files changed, 509 insertions(+), 1004 deletions(-) delete mode 100644 src/helpers/Box.cpp delete mode 100644 src/helpers/Box.hpp delete mode 100644 src/helpers/Region.cpp delete mode 100644 src/helpers/Region.hpp delete mode 100644 src/helpers/Vector2D.cpp delete mode 100644 src/helpers/Vector2D.hpp create mode 100644 src/helpers/math/Math.cpp create mode 100644 src/helpers/math/Math.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aa2bf5c..632621ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo pixman-1 libdrm libinput hwdata libseat libdisplay-info libliftoff libudev gbm - hyprlang>=0.3.2 hyprcursor>=0.1.7 hyprutils>=0.1.1 + hyprlang>=0.3.2 hyprcursor>=0.1.7 hyprutils>=0.1.4 ) find_package(hyprwayland-scanner 0.3.10 REQUIRED) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index af46b0ff..7777a55f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1434,8 +1434,7 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { if (!PMONITOR) return nullptr; // ?? - const auto WINDOWIDEALBB = pWindow->m_bIsFullscreen ? wlr_box{(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y} : - pWindow->getWindowIdealBoundingBoxIgnoreReserved(); + const auto WINDOWIDEALBB = pWindow->m_bIsFullscreen ? CBox{PMONITOR->vecPosition, PMONITOR->vecSize} : pWindow->getWindowIdealBoundingBoxIgnoreReserved(); const auto POSA = Vector2D(WINDOWIDEALBB.x, WINDOWIDEALBB.y); const auto SIZEA = Vector2D(WINDOWIDEALBB.width, WINDOWIDEALBB.height); diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp index 1b4876bb..2a1546c6 100644 --- a/src/SharedDefs.hpp +++ b/src/SharedDefs.hpp @@ -1,7 +1,11 @@ #pragma once -#include "helpers/Vector2D.hpp" +#include "helpers/math/Math.hpp" #include +#include +#include + +using namespace Hyprutils::Math; enum eIcons { ICON_WARNING = 0, @@ -37,29 +41,6 @@ struct SCallbackInfo { bool cancelled = false; /* on cancellable events, will cancel the event. */ }; -struct SWindowDecorationExtents { - Vector2D topLeft; - Vector2D bottomRight; - - // - SWindowDecorationExtents operator*(const double& scale) const { - return SWindowDecorationExtents{topLeft * scale, bottomRight * scale}; - } - - SWindowDecorationExtents round() { - return {topLeft.round(), bottomRight.round()}; - } - - bool operator==(const SWindowDecorationExtents& other) const { - return topLeft == other.topLeft && bottomRight == other.bottomRight; - } - - void addExtents(const SWindowDecorationExtents& other) { - topLeft = topLeft.getComponentMax(other.topLeft); - bottomRight = bottomRight.getComponentMax(other.bottomRight); - } -}; - enum eHyprCtlOutputFormat { FORMAT_NORMAL = 0, FORMAT_JSON diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 56fdae25..17bbe465 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -982,7 +982,8 @@ float CConfigManager::getDeviceFloat(const std::string& dev, const std::string& } Vector2D CConfigManager::getDeviceVec(const std::string& dev, const std::string& v, const std::string& fallback) { - return std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue()); + auto vec = std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue()); + return {vec.x, vec.y}; } std::string CConfigManager::getDeviceString(const std::string& dev, const std::string& v, const std::string& fallback) { diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index aec3853e..3f8bb579 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -131,7 +131,7 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) { textW /= PANGO_SCALE; textH /= PANGO_SCALE; - const auto NOTIFSIZE = Vector2D{textW + 20 + iconW + 2 * ICONPADFORNOTIF, textH + 10}; + const auto NOTIFSIZE = Vector2D{textW + 20.0 + iconW + 2 * ICONPADFORNOTIF, textH + 10.0}; // draw rects cairo_set_source_rgba(m_pCairo, notif->color.r, notif->color.g, notif->color.b, notif->color.a); diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 64eeead1..9a891531 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -412,9 +412,9 @@ void CLayerSurface::startAnimation(bool in, bool instant) { } const std::array edgePoints = { - PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0}, + PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0.0}, PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, PMONITOR->vecSize.y}, - PMONITOR->vecPosition + Vector2D{0, PMONITOR->vecSize.y}, + PMONITOR->vecPosition + Vector2D{0.0, PMONITOR->vecSize.y}, PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, }; diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index c7a09b40..97335d27 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -86,7 +86,7 @@ CRegion CWLSurface::logicalDamage() const { return {}; CRegion damage = m_pResource->accumulateCurrentBufferDamage(); - damage.transform(m_pResource->current.transform, m_pResource->current.buffer->size.x, m_pResource->current.buffer->size.y); + damage.transform(wlTransformToHyprutils(m_pResource->current.transform), m_pResource->current.buffer->size.x, m_pResource->current.buffer->size.y); damage.scale(1.0 / m_pResource->current.scale); const auto VPSIZE = getViewporterCorrectedSize(); diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 4ba381a9..447f4582 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -1,7 +1,7 @@ #pragma once #include "../defines.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" class CSubsurface; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index d153b344..e67a3357 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -104,7 +104,7 @@ CWindow::~CWindow() { std::erase_if(g_pHyprOpenGL->m_mWindowFramebuffers, [&](const auto& other) { return !other.first.lock() || other.first.lock().get() == this; }); } -SWindowDecorationExtents CWindow::getFullWindowExtents() { +SBoxExtents CWindow::getFullWindowExtents() { if (m_bFadingOut) return m_eOriginalClosedExtents; @@ -116,9 +116,9 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() { {PMONITOR->vecSize.x - (m_vRealPosition.value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition.value().y - PMONITOR->vecPosition.y)}}; } - SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}}; + SBoxExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}}; - const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock()); + const auto EXTENTS = g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock()); if (EXTENTS.topLeft.x > maxExtents.topLeft.x) maxExtents.topLeft.x = EXTENTS.topLeft.x; @@ -224,7 +224,7 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) { return {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y}; } - SWindowDecorationExtents EXTENTS = {{0, 0}, {0, 0}}; + SBoxExtents EXTENTS = {{0, 0}, {0, 0}}; if (properties & RESERVED_EXTENTS) EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock())); if (properties & INPUT_EXTENTS) @@ -242,7 +242,7 @@ CBox CWindow::getWindowMainSurfaceBox() { return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; } -SWindowDecorationExtents CWindow::getFullWindowReservedArea() { +SBoxExtents CWindow::getFullWindowReservedArea() { return g_pDecorationPositioner->getWindowDecorationReserved(m_pSelf.lock()); } diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 3f387d31..6bfdbc50 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -6,7 +6,7 @@ #include "../config/ConfigDataValues.hpp" #include "../defines.hpp" #include "../helpers/AnimatedVariable.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" #include "../helpers/TagKeeper.hpp" #include "../macros.hpp" @@ -310,7 +310,7 @@ class CWindow { bool m_bReadyToDelete = false; Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in Vector2D m_vOriginalClosedSize; // drawing the closing animations - SWindowDecorationExtents m_eOriginalClosedExtents; + SBoxExtents m_eOriginalClosedExtents; bool m_bAnimatingIn = false; // For pinned (sticky) windows @@ -386,75 +386,75 @@ class CWindow { } // methods - CBox getFullWindowBoundingBox(); - SWindowDecorationExtents getFullWindowExtents(); - CBox getWindowBoxUnified(uint64_t props); - CBox getWindowMainSurfaceBox(); - CBox getWindowIdealBoundingBoxIgnoreReserved(); - void addWindowDeco(std::unique_ptr deco); - void updateWindowDecos(); - void removeWindowDeco(IHyprWindowDecoration* deco); - void uncacheWindowDecos(); - bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); - pid_t getPID(); - IHyprWindowDecoration* getDecorationByType(eDecorationType); - void removeDecorationByType(eDecorationType); - void updateToplevel(); - void updateSurfaceScaleTransformDetails(bool force = false); - void moveToWorkspace(PHLWORKSPACE); - PHLWINDOW X11TransientFor(); - void onUnmap(); - void onMap(); - void setHidden(bool hidden); - bool isHidden(); - void applyDynamicRule(const SWindowRule& r); - void updateDynamicRules(); - SWindowDecorationExtents getFullWindowReservedArea(); - Vector2D middle(); - bool opaque(); - float rounding(); - bool canBeTorn(); - bool shouldSendFullscreenState(); - void setSuspended(bool suspend); - bool visibleOnMonitor(CMonitor* pMonitor); - int workspaceID(); - bool onSpecialWorkspace(); - void activate(bool force = false); - int surfacesCount(); + CBox getFullWindowBoundingBox(); + SBoxExtents getFullWindowExtents(); + CBox getWindowBoxUnified(uint64_t props); + CBox getWindowMainSurfaceBox(); + CBox getWindowIdealBoundingBoxIgnoreReserved(); + void addWindowDeco(std::unique_ptr deco); + void updateWindowDecos(); + void removeWindowDeco(IHyprWindowDecoration* deco); + void uncacheWindowDecos(); + bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); + pid_t getPID(); + IHyprWindowDecoration* getDecorationByType(eDecorationType); + void removeDecorationByType(eDecorationType); + void updateToplevel(); + void updateSurfaceScaleTransformDetails(bool force = false); + void moveToWorkspace(PHLWORKSPACE); + PHLWINDOW X11TransientFor(); + void onUnmap(); + void onMap(); + void setHidden(bool hidden); + bool isHidden(); + void applyDynamicRule(const SWindowRule& r); + void updateDynamicRules(); + SBoxExtents getFullWindowReservedArea(); + Vector2D middle(); + bool opaque(); + float rounding(); + bool canBeTorn(); + bool shouldSendFullscreenState(); + void setSuspended(bool suspend); + bool visibleOnMonitor(CMonitor* pMonitor); + int workspaceID(); + bool onSpecialWorkspace(); + void activate(bool force = false); + int surfacesCount(); - int getRealBorderSize(); - void updateSpecialRenderData(); - void updateSpecialRenderData(const struct SWorkspaceRule&); + int getRealBorderSize(); + void updateSpecialRenderData(); + void updateSpecialRenderData(const struct SWorkspaceRule&); - void onBorderAngleAnimEnd(void* ptr); - bool isInCurvedCorner(double x, double y); - bool hasPopupAt(const Vector2D& pos); - int popupsCount(); + void onBorderAngleAnimEnd(void* ptr); + bool isInCurvedCorner(double x, double y); + bool hasPopupAt(const Vector2D& pos); + int popupsCount(); - void applyGroupRules(); - void createGroup(); - void destroyGroup(); - PHLWINDOW getGroupHead(); - PHLWINDOW getGroupTail(); - PHLWINDOW getGroupCurrent(); - PHLWINDOW getGroupPrevious(); - PHLWINDOW getGroupWindowByIndex(int); - int getGroupSize(); - bool canBeGroupedInto(PHLWINDOW pWindow); - void setGroupCurrent(PHLWINDOW pWindow); - void insertWindowToGroup(PHLWINDOW pWindow); - void updateGroupOutputs(); - void switchWithWindowInGroup(PHLWINDOW pWindow); - void setAnimationsToMove(); - void onWorkspaceAnimUpdate(); - void onUpdateState(); - void onUpdateMeta(); - void onX11Configure(CBox box); - void onResourceChangeX11(); - std::string fetchTitle(); - std::string fetchClass(); - void warpCursor(); - PHLWINDOW getSwallower(); + void applyGroupRules(); + void createGroup(); + void destroyGroup(); + PHLWINDOW getGroupHead(); + PHLWINDOW getGroupTail(); + PHLWINDOW getGroupCurrent(); + PHLWINDOW getGroupPrevious(); + PHLWINDOW getGroupWindowByIndex(int); + int getGroupSize(); + bool canBeGroupedInto(PHLWINDOW pWindow); + void setGroupCurrent(PHLWINDOW pWindow); + void insertWindowToGroup(PHLWINDOW pWindow); + void updateGroupOutputs(); + void switchWithWindowInGroup(PHLWINDOW pWindow); + void setAnimationsToMove(); + void onWorkspaceAnimUpdate(); + void onUpdateState(); + void onUpdateMeta(); + void onX11Configure(CBox box); + void onResourceChangeX11(); + std::string fetchTitle(); + std::string fetchClass(); + void warpCursor(); + PHLWINDOW getSwallower(); // listeners void onAck(uint32_t serial); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index ed09fbc0..04685bd5 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -104,24 +104,24 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { if (ANIMSTYLE.starts_with("slidefadevert")) { if (in) { m_fAlpha.setValueAndWarp(0.f); - m_vRenderOffset.setValueAndWarp(Vector2D(0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f))); + m_vRenderOffset.setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f))); m_fAlpha = 1.f; m_vRenderOffset = Vector2D(0, 0); } else { m_fAlpha.setValueAndWarp(1.f); m_fAlpha = 0.f; - m_vRenderOffset = Vector2D(0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f)); + m_vRenderOffset = Vector2D(0.0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f)); } } else { if (in) { m_fAlpha.setValueAndWarp(0.f); - m_vRenderOffset.setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0)); + m_vRenderOffset.setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0)); m_fAlpha = 1.f; m_vRenderOffset = Vector2D(0, 0); } else { m_fAlpha.setValueAndWarp(1.f); m_fAlpha = 0.f; - m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0); + m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0); } } } else if (ANIMSTYLE == "fade") { @@ -142,10 +142,10 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. if (in) { - m_vRenderOffset.setValueAndWarp(Vector2D(0, left ? YDISTANCE : -YDISTANCE)); + m_vRenderOffset.setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE)); m_vRenderOffset = Vector2D(0, 0); } else { - m_vRenderOffset = Vector2D(0, left ? -YDISTANCE : YDISTANCE); + m_vRenderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE); } } else { // fallback is slide @@ -155,10 +155,10 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. if (in) { - m_vRenderOffset.setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0)); + m_vRenderOffset.setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0)); m_vRenderOffset = Vector2D(0, 0); } else { - m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0); + m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0); } } diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp index ec58ff5b..b1757a18 100644 --- a/src/devices/IKeyboard.hpp +++ b/src/devices/IKeyboard.hpp @@ -3,7 +3,7 @@ #include "IHID.hpp" #include "../helpers/WLListener.hpp" #include "../macros.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" #include diff --git a/src/devices/IPointer.hpp b/src/devices/IPointer.hpp index e2347c95..b2995b2f 100644 --- a/src/devices/IPointer.hpp +++ b/src/devices/IPointer.hpp @@ -3,7 +3,7 @@ #include "IHID.hpp" #include "../helpers/WLListener.hpp" #include "../macros.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" struct wlr_pointer; diff --git a/src/devices/ITouch.hpp b/src/devices/ITouch.hpp index 5929be02..b9cbf2ae 100644 --- a/src/devices/ITouch.hpp +++ b/src/devices/ITouch.hpp @@ -3,7 +3,7 @@ #include "IHID.hpp" #include "../helpers/WLListener.hpp" #include "../macros.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" struct wlr_touch; diff --git a/src/devices/Tablet.hpp b/src/devices/Tablet.hpp index 1805f3ba..ada2cf89 100644 --- a/src/devices/Tablet.hpp +++ b/src/devices/Tablet.hpp @@ -3,8 +3,8 @@ #include "IHID.hpp" #include "../helpers/WLListener.hpp" #include "../macros.hpp" -#include "../helpers/Vector2D.hpp" -#include "../helpers/Box.hpp" +#include "../helpers/math/Math.hpp" +#include "../helpers/math/Math.hpp" struct wlr_tablet; struct wlr_tablet_tool; diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index 5c63032e..073cf65b 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -4,7 +4,7 @@ #include #include #include -#include "Vector2D.hpp" +#include "math/Math.hpp" #include "Color.hpp" #include "../defines.hpp" #include "../debug/Log.hpp" diff --git a/src/helpers/BezierCurve.hpp b/src/helpers/BezierCurve.hpp index fb11d52b..54af46a6 100644 --- a/src/helpers/BezierCurve.hpp +++ b/src/helpers/BezierCurve.hpp @@ -3,7 +3,7 @@ #include #include #include -#include "Vector2D.hpp" +#include "math/Math.hpp" constexpr int BAKEDPOINTS = 255; constexpr float INVBAKEDPOINTS = 1.f / BAKEDPOINTS; diff --git a/src/helpers/Box.cpp b/src/helpers/Box.cpp deleted file mode 100644 index 4b7f5726..00000000 --- a/src/helpers/Box.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "Box.hpp" - -#include -#include - -wlr_box CBox::wlr() { - CBox rounded = roundInternal(); - m_bWlrBox = wlr_box{(int)rounded.x, (int)rounded.y, (int)rounded.w, (int)rounded.h}; - return m_bWlrBox; -} - -wlr_box* CBox::pWlr() { - CBox rounded = roundInternal(); - m_bWlrBox = wlr_box{(int)rounded.x, (int)rounded.y, (int)rounded.w, (int)rounded.h}; - return &m_bWlrBox; -} - -CBox& CBox::scale(double scale) { - x *= scale; - y *= scale; - w *= scale; - h *= scale; - - return *this; -} - -CBox& CBox::scale(const Vector2D& scale) { - x *= scale.x; - y *= scale.y; - w *= scale.x; - h *= scale.y; - - return *this; -} - -CBox& CBox::translate(const Vector2D& vec) { - x += vec.x; - y += vec.y; - - return *this; -} - -Vector2D CBox::middle() const { - return Vector2D{x + w / 2.0, y + h / 2.0}; -} - -bool CBox::containsPoint(const Vector2D& vec) const { - return VECINRECT(vec, x, y, x + w, y + h); -} - -bool CBox::empty() const { - return w == 0 || h == 0; -} - -CBox& CBox::applyFromWlr() { - x = m_bWlrBox.x; - y = m_bWlrBox.y; - w = m_bWlrBox.width; - h = m_bWlrBox.height; - - return *this; -} - -CBox& CBox::round() { - float newW = x + w - std::round(x); - float newH = y + h - std::round(y); - x = std::round(x); - y = std::round(y); - w = std::round(newW); - h = std::round(newH); - - return *this; -} - -CBox& CBox::transform(const wl_output_transform t, double w, double h) { - wlr_box_transform(&m_bWlrBox, pWlr(), t, w, h); - applyFromWlr(); - - return *this; -} - -CBox& CBox::addExtents(const SWindowDecorationExtents& e) { - x -= e.topLeft.x; - y -= e.topLeft.y; - w += e.topLeft.x + e.bottomRight.x; - h += e.topLeft.y + e.bottomRight.y; - - return *this; -} - -CBox& CBox::scaleFromCenter(double scale) { - double oldW = w, oldH = h; - - w *= scale; - h *= scale; - - x -= (w - oldW) / 2.0; - y -= (h - oldH) / 2.0; - - return *this; -} - -CBox& CBox::expand(const double& value) { - x -= value; - y -= value; - w += value * 2.0; - h += value * 2.0; - - if (w <= 0 || h <= 0) { - w = 0; - h = 0; - } - - return *this; -} - -CBox& CBox::noNegativeSize() { - w = std::clamp(w, 0.0, std::numeric_limits::infinity()); - h = std::clamp(h, 0.0, std::numeric_limits::infinity()); - - return *this; -} - -CBox CBox::intersection(const CBox& other) const { - const float newX = std::max(x, other.x); - const float newY = std::max(y, other.y); - const float newBottom = std::min(y + h, other.y + other.h); - const float newRight = std::min(x + w, other.x + other.w); - float newW = newRight - newX; - float newH = newBottom - newY; - - if (newW <= 0 || newH <= 0) { - newW = 0; - newH = 0; - } - - return {newX, newY, newW, newH}; -} - -bool CBox::overlaps(const CBox& other) const { - return (other.x + other.w >= x) && (x + w >= other.x) && (other.y + other.h >= y) && (y + h >= other.y); -} - -bool CBox::inside(const CBox& bound) const { - return bound.x < x && bound.y < y && x + w < bound.x + bound.w && y + h < bound.y + bound.h; -} - -CBox CBox::roundInternal() { - float newW = x + w - std::floor(x); - float newH = y + h - std::floor(y); - - return CBox{std::floor(x), std::floor(y), std::floor(newW), std::floor(newH)}; -} - -CBox CBox::copy() const { - return CBox{*this}; -} - -Vector2D CBox::pos() const { - return {x, y}; -} - -Vector2D CBox::size() const { - return {w, h}; -} - -Vector2D CBox::closestPoint(const Vector2D& vec) const { - if (containsPoint(vec)) - return vec; - - Vector2D nv = vec; - nv.x = std::clamp(nv.x, x, x + w); - nv.y = std::clamp(nv.y, y, y + h); - return nv; -} - -SWindowDecorationExtents CBox::extentsFrom(const CBox& small) { - return {{small.x - x, small.y - y}, {w - small.w - (small.x - x), h - small.h - (small.y - y)}}; -} diff --git a/src/helpers/Box.hpp b/src/helpers/Box.hpp deleted file mode 100644 index 57df2154..00000000 --- a/src/helpers/Box.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "Vector2D.hpp" -#include "../SharedDefs.hpp" -#include "../includes.hpp" - -class CBox { - public: - CBox(double x_, double y_, double w_, double h_) { - x = x_; - y = y_; - w = w_; - h = h_; - } - - CBox() { - w = 0; - h = 0; - } - - CBox(const wlr_box& box) { - x = box.x; - y = box.y; - w = box.width; - h = box.height; - } - - CBox(const double d) { - x = d; - y = d; - w = d; - h = d; - } - - CBox(const Vector2D& pos, const Vector2D& size) { - x = pos.x; - y = pos.y; - w = size.x; - h = size.y; - } - - wlr_box wlr(); - wlr_box* pWlr(); - - CBox& applyFromWlr(); - CBox& scale(double scale); - CBox& scaleFromCenter(double scale); - CBox& scale(const Vector2D& scale); - CBox& translate(const Vector2D& vec); - CBox& round(); - CBox& transform(const wl_output_transform t, double w, double h); - CBox& addExtents(const SWindowDecorationExtents& e); - CBox& expand(const double& value); - CBox& noNegativeSize(); - - CBox copy() const; - CBox intersection(const CBox& other) const; - bool overlaps(const CBox& other) const; - bool inside(const CBox& bound) const; - - SWindowDecorationExtents extentsFrom(const CBox&); // this is the big box - - Vector2D middle() const; - Vector2D pos() const; - Vector2D size() const; - Vector2D closestPoint(const Vector2D& vec) const; - - bool containsPoint(const Vector2D& vec) const; - bool empty() const; - - double x = 0, y = 0; - union { - double w; - double width; - }; - union { - double h; - double height; - }; - - double rot = 0; /* rad, ccw */ - - // - bool operator==(const CBox& rhs) const { - return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; - } - - private: - CBox roundInternal(); - - wlr_box m_bWlrBox; -}; diff --git a/src/helpers/Format.hpp b/src/helpers/Format.hpp index b86f44dd..a1ef53f5 100644 --- a/src/helpers/Format.hpp +++ b/src/helpers/Format.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "Vector2D.hpp" +#include "math/Math.hpp" typedef uint32_t DRMFormat; typedef uint32_t SHMFormat; diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 821f3231..654ccf35 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -762,7 +762,7 @@ Vector2D configStringToVector2D(const std::string& VALUE) { if (std::getline(iss, token)) throw std::invalid_argument("Invalid string format"); - return Vector2D(x, y); + return Vector2D((double)x, (double)y); } double normalizeAngleRad(double ang) { diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index feb0380b..111abba0 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -4,7 +4,7 @@ #include #include #include -#include "Vector2D.hpp" +#include "math/Math.hpp" #include #include diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 58687e09..da6da873 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -358,7 +358,9 @@ void CMonitor::addDamage(const CBox* box) { g_pCompositor->scheduleFrameForMonitor(this); } - if (wlr_damage_ring_add_box(&damage, const_cast(box)->pWlr())) + wlr_box damageBox = {(int)box->x, (int)box->y, (int)box->w, (int)box->h}; + + if (wlr_damage_ring_add_box(&damage, &damageBox)) g_pCompositor->scheduleFrameForMonitor(this); } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index c59e00ac..b8902197 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -8,7 +8,7 @@ #include #include #include "Timer.hpp" -#include "Region.hpp" +#include "math/Math.hpp" #include #include "signal/Signal.hpp" diff --git a/src/helpers/Region.cpp b/src/helpers/Region.cpp deleted file mode 100644 index 9e572b34..00000000 --- a/src/helpers/Region.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "Region.hpp" -extern "C" { -#include -#include -} - -constexpr const int64_t MAX_REGION_SIDE = 10000000; - -CRegion::CRegion() { - pixman_region32_init(&m_rRegion); -} - -CRegion::CRegion(const pixman_region32_t* const ref) { - pixman_region32_init(&m_rRegion); - pixman_region32_copy(&m_rRegion, ref); -} - -CRegion::CRegion(double x, double y, double w, double h) { - pixman_region32_init_rect(&m_rRegion, x, y, w, h); -} - -CRegion::CRegion(wlr_box* box) { - pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->width, box->height); -} - -CRegion::CRegion(const CBox& box) { - pixman_region32_init_rect(&m_rRegion, box.x, box.y, box.w, box.h); -} - -CRegion::CRegion(pixman_box32_t* box) { - pixman_region32_init_rect(&m_rRegion, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); -} - -CRegion::CRegion(const CRegion& other) { - pixman_region32_init(&m_rRegion); - pixman_region32_copy(&m_rRegion, const_cast(&other)->pixman()); -} - -CRegion::CRegion(CRegion&& other) { - pixman_region32_init(&m_rRegion); - pixman_region32_copy(&m_rRegion, other.pixman()); -} - -CRegion::~CRegion() { - pixman_region32_fini(&m_rRegion); -} - -CRegion& CRegion::clear() { - pixman_region32_clear(&m_rRegion); - return *this; -} - -CRegion& CRegion::set(const CRegion& other) { - pixman_region32_copy(&m_rRegion, const_cast(&other)->pixman()); - return *this; -} - -CRegion& CRegion::add(const CRegion& other) { - pixman_region32_union(&m_rRegion, &m_rRegion, const_cast(&other)->pixman()); - return *this; -} - -CRegion& CRegion::add(double x, double y, double w, double h) { - pixman_region32_union_rect(&m_rRegion, &m_rRegion, x, y, w, h); - return *this; -} - -CRegion& CRegion::add(const CBox& other) { - pixman_region32_union_rect(&m_rRegion, &m_rRegion, other.x, other.y, other.w, other.h); - return *this; -} - -CRegion& CRegion::subtract(const CRegion& other) { - pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast(&other)->pixman()); - return *this; -} - -CRegion& CRegion::intersect(const CRegion& other) { - pixman_region32_intersect(&m_rRegion, &m_rRegion, const_cast(&other)->pixman()); - return *this; -} - -CRegion& CRegion::intersect(double x, double y, double w, double h) { - pixman_region32_intersect_rect(&m_rRegion, &m_rRegion, x, y, w, h); - return *this; -} - -CRegion& CRegion::invert(pixman_box32_t* box) { - pixman_region32_inverse(&m_rRegion, &m_rRegion, box); - return *this; -} - -CRegion& CRegion::invert(const CBox& box) { - pixman_box32 pixmanBox = {box.x, box.y, box.w + box.x, box.h + box.y}; - return this->invert(&pixmanBox); -} - -CRegion& CRegion::translate(const Vector2D& vec) { - pixman_region32_translate(&m_rRegion, vec.x, vec.y); - return *this; -} - -CRegion& CRegion::transform(const wl_output_transform t, double w, double h) { - wlr_region_transform(&m_rRegion, &m_rRegion, t, w, h); - return *this; -} - -CRegion& CRegion::rationalize() { - intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2}); - return *this; -} - -CRegion CRegion::copy() const { - return CRegion(*this); -} - -CRegion& CRegion::scale(float scale) { - wlr_region_scale(&m_rRegion, &m_rRegion, scale); - return *this; -} - -CRegion& CRegion::scale(const Vector2D& scale) { - wlr_region_scale_xy(&m_rRegion, &m_rRegion, scale.x, scale.y); - return *this; -} - -std::vector CRegion::getRects() const { - std::vector result; - - int rectsNum = 0; - const auto RECTSARR = pixman_region32_rectangles(&m_rRegion, &rectsNum); - - result.assign(RECTSARR, RECTSARR + rectsNum); - - return result; -} - -CBox CRegion::getExtents() { - pixman_box32_t* box = pixman_region32_extents(&m_rRegion); - return {box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1}; -} - -bool CRegion::containsPoint(const Vector2D& vec) const { - return pixman_region32_contains_point(&m_rRegion, vec.x, vec.y, nullptr); -} - -bool CRegion::empty() const { - return !pixman_region32_not_empty(&m_rRegion); -} - -Vector2D CRegion::closestPoint(const Vector2D& vec) const { - if (containsPoint(vec)) - return vec; - - double bestDist = __FLT_MAX__; - Vector2D leader = vec; - - for (auto& box : getRects()) { - double x = 0, y = 0; - - if (vec.x >= box.x2) - x = box.x2 - 1; - else if (vec.x < box.x1) - x = box.x1; - else - x = vec.x; - - if (vec.y >= box.y2) - y = box.y2 - 1; - else if (vec.y < box.y1) - y = box.y1; - else - y = vec.y; - - double distance = pow(x, 2) + pow(y, 2); - if (distance < bestDist) { - bestDist = distance; - leader = {x, y}; - } - } - - return leader; -} \ No newline at end of file diff --git a/src/helpers/Region.hpp b/src/helpers/Region.hpp deleted file mode 100644 index 42693c21..00000000 --- a/src/helpers/Region.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include -#include -#include "Vector2D.hpp" -#include "Box.hpp" - -struct wlr_box; - -class CRegion { - public: - /* Create an empty region */ - CRegion(); - /* Create from a reference. Copies, does not own. */ - CRegion(const pixman_region32_t* const ref); - /* Create from a box */ - CRegion(double x, double y, double w, double h); - /* Create from a wlr_box */ - CRegion(wlr_box* box); - /* Create from a CBox */ - CRegion(const CBox& box); - /* Create from a pixman_box32_t */ - CRegion(pixman_box32_t* box); - - CRegion(const CRegion&); - CRegion(CRegion&&); - - ~CRegion(); - - CRegion& operator=(CRegion&& other) { - pixman_region32_copy(&m_rRegion, other.pixman()); - return *this; - } - - CRegion& operator=(CRegion& other) { - pixman_region32_copy(&m_rRegion, other.pixman()); - return *this; - } - - CRegion& clear(); - CRegion& set(const CRegion& other); - CRegion& add(const CRegion& other); - CRegion& add(double x, double y, double w, double h); - CRegion& add(const CBox& other); - CRegion& subtract(const CRegion& other); - CRegion& intersect(const CRegion& other); - CRegion& intersect(double x, double y, double w, double h); - CRegion& translate(const Vector2D& vec); - CRegion& transform(const wl_output_transform t, double w, double h); - CRegion& invert(pixman_box32_t* box); - CRegion& invert(const CBox& box); - CRegion& scale(float scale); - CRegion& scale(const Vector2D& scale); - CRegion& rationalize(); - CBox getExtents(); - bool containsPoint(const Vector2D& vec) const; - bool empty() const; - Vector2D closestPoint(const Vector2D& vec) const; - CRegion copy() const; - - std::vector getRects() const; - - // - pixman_region32_t* pixman() { - return &m_rRegion; - } - - private: - pixman_region32_t m_rRegion; -}; diff --git a/src/helpers/Vector2D.cpp b/src/helpers/Vector2D.cpp deleted file mode 100644 index 6f96d686..00000000 --- a/src/helpers/Vector2D.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "Vector2D.hpp" -#include -#include - -Vector2D::Vector2D(double xx, double yy) { - x = xx; - y = yy; -} - -Vector2D::Vector2D() { - x = 0; - y = 0; -} - -Vector2D::Vector2D(const Hyprlang::VEC2& ref) { - x = ref.x; - y = ref.y; -} - -Vector2D::~Vector2D() {} - -double Vector2D::normalize() { - // get max abs - const auto max = std::abs(x) > std::abs(y) ? std::abs(x) : std::abs(y); - - x /= max; - y /= max; - - return max; -} - -Vector2D Vector2D::floor() const { - return Vector2D(std::floor(x), std::floor(y)); -} - -Vector2D Vector2D::round() const { - return Vector2D(std::round(x), std::round(y)); -} - -Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) const { - return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y)); -} - -double Vector2D::distance(const Vector2D& other) const { - return std::sqrt(distanceSq(other)); -} - -double Vector2D::distanceSq(const Vector2D& other) const { - return (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y); -} - -double Vector2D::size() const { - return std::sqrt(x * x + y * y); -} - -Vector2D Vector2D::getComponentMax(const Vector2D& other) const { - return Vector2D(std::max(this->x, other.x), std::max(this->y, other.y)); -} diff --git a/src/helpers/Vector2D.hpp b/src/helpers/Vector2D.hpp deleted file mode 100644 index 0f1440c3..00000000 --- a/src/helpers/Vector2D.hpp +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -#include -#include -#include "../macros.hpp" -#include - -class Vector2D { - public: - Vector2D(double, double); - Vector2D(); - ~Vector2D(); - Vector2D(const Hyprlang::VEC2&); - - double x = 0; - double y = 0; - - // returns the scale - double normalize(); - - Vector2D operator+(const Vector2D& a) const { - return Vector2D(this->x + a.x, this->y + a.y); - } - Vector2D operator-(const Vector2D& a) const { - return Vector2D(this->x - a.x, this->y - a.y); - } - Vector2D operator-() const { - return Vector2D(-this->x, -this->y); - } - Vector2D operator*(const double& a) const { - return Vector2D(this->x * a, this->y * a); - } - Vector2D operator/(const double& a) const { - return Vector2D(this->x / a, this->y / a); - } - - bool operator==(const Vector2D& a) const { - return a.x == x && a.y == y; - } - - bool operator!=(const Vector2D& a) const { - return a.x != x || a.y != y; - } - - Vector2D operator*(const Vector2D& a) const { - return Vector2D(this->x * a.x, this->y * a.y); - } - - Vector2D operator/(const Vector2D& a) const { - return Vector2D(this->x / a.x, this->y / a.y); - } - - bool operator>(const Vector2D& a) const { - return this->x > a.x && this->y > a.y; - } - - bool operator<(const Vector2D& a) const { - return this->x < a.x && this->y < a.y; - } - Vector2D& operator+=(const Vector2D& a) { - this->x += a.x; - this->y += a.y; - return *this; - } - Vector2D& operator-=(const Vector2D& a) { - this->x -= a.x; - this->y -= a.y; - return *this; - } - Vector2D& operator*=(const Vector2D& a) { - this->x *= a.x; - this->y *= a.y; - return *this; - } - Vector2D& operator/=(const Vector2D& a) { - this->x /= a.x; - this->y /= a.y; - return *this; - } - Vector2D& operator*=(const double& a) { - this->x *= a; - this->y *= a; - return *this; - } - Vector2D& operator/=(const double& a) { - this->x /= a; - this->y /= a; - return *this; - } - - double distance(const Vector2D& other) const; - double distanceSq(const Vector2D& other) const; - double size() const; - Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D{-1, -1}) const; - - Vector2D floor() const; - Vector2D round() const; - - Vector2D getComponentMax(const Vector2D& other) const; -}; - -/** - format specification - - 'j', as json array - - 'X', same as std::format("{}x{}", vec.x, vec.y) - - number, floating point precision, use `0` to format as integer -*/ -template -struct std::formatter : std::formatter { - bool formatJson = false; - bool formatX = false; - std::string precision = ""; - FORMAT_PARSE(FORMAT_FLAG('j', formatJson) // - FORMAT_FLAG('X', formatX) // - FORMAT_NUMBER(precision), - Vector2D) - - template - auto format(const Vector2D& vec, FormatContext& ctx) const { - std::string formatString = precision.empty() ? "{}" : std::format("{{:.{}f}}", precision); - - if (formatJson) - formatString = std::format("[{0}, {0}]", formatString); - else if (formatX) - formatString = std::format("{0}x{0}", formatString); - else - formatString = std::format("[Vector2D: x: {0}, y: {0}]", formatString); - try { - string buf = std::vformat(formatString, std::make_format_args(vec.x, vec.y)); - return std::format_to(ctx.out(), "{}", buf); - } catch (std::format_error& e) { return std::format_to(ctx.out(), "[{}, {}]", vec.x, vec.y); } - } -}; diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index bcd6bf10..6b25e76d 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -8,7 +8,7 @@ #include "AnimatedVariable.hpp" #include "../desktop/WLSurface.hpp" #include "signal/Signal.hpp" -#include "Region.hpp" +#include "math/Math.hpp" class CMonitor; class IPointer; diff --git a/src/helpers/math/Math.cpp b/src/helpers/math/Math.cpp new file mode 100644 index 00000000..df4f1bb5 --- /dev/null +++ b/src/helpers/math/Math.cpp @@ -0,0 +1,220 @@ +#include "Math.hpp" +#include + +Hyprutils::Math::eTransform wlTransformToHyprutils(wl_output_transform t) { + switch (t) { + case WL_OUTPUT_TRANSFORM_NORMAL: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_NORMAL; + case WL_OUTPUT_TRANSFORM_180: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_180; + case WL_OUTPUT_TRANSFORM_90: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_90; + case WL_OUTPUT_TRANSFORM_270: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_270; + case WL_OUTPUT_TRANSFORM_FLIPPED: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_FLIPPED; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_FLIPPED_180; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_FLIPPED_270; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_FLIPPED_90; + default: break; + } + return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_NORMAL; +} + +static void matrixIdentity(float mat[9]) { + static const float identity[9] = { + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + }; + memcpy(mat, identity, sizeof(identity)); +} + +static void matrixMultiply(float mat[9], const float a[9], const float b[9]) { + float product[9]; + + product[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6]; + product[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7]; + product[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8]; + + product[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6]; + product[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7]; + product[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8]; + + product[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6]; + product[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7]; + product[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8]; + + memcpy(mat, product, sizeof(product)); +} + +static void matrixTranspose(float mat[9], const float a[9]) { + float transposition[9] = { + a[0], a[3], a[6], a[1], a[4], a[7], a[2], a[5], a[8], + }; + memcpy(mat, transposition, sizeof(transposition)); +} + +static void matrixTranslate(float mat[9], float x, float y) { + float translate[9] = { + 1.0f, 0.0f, x, 0.0f, 1.0f, y, 0.0f, 0.0f, 1.0f, + }; + wlr_matrix_multiply(mat, mat, translate); +} + +static void matrixScale(float mat[9], float x, float y) { + float scale[9] = { + x, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 1.0f, + }; + wlr_matrix_multiply(mat, mat, scale); +} + +static void matrixRotate(float mat[9], float rad) { + float rotate[9] = { + cos(rad), -sin(rad), 0.0f, sin(rad), cos(rad), 0.0f, 0.0f, 0.0f, 1.0f, + }; + wlr_matrix_multiply(mat, mat, rotate); +} + +static std::unordered_map> transforms = { + {HYPRUTILS_TRANSFORM_NORMAL, + { + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_90, + { + 0.0f, + 1.0f, + 0.0f, + -1.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_180, + { + -1.0f, + 0.0f, + 0.0f, + 0.0f, + -1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_270, + { + 0.0f, + -1.0f, + 0.0f, + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_FLIPPED, + { + -1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_FLIPPED_90, + { + 0.0f, + 1.0f, + 0.0f, + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_FLIPPED_180, + { + 1.0f, + 0.0f, + 0.0f, + 0.0f, + -1.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, + {HYPRUTILS_TRANSFORM_FLIPPED_270, + { + 0.0f, + -1.0f, + 0.0f, + -1.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }}, +}; + +static void matrixTransform(float mat[9], eTransform transform) { + matrixMultiply(mat, mat, transforms.at(transform).data()); +} + +static void matrixProjection(float mat[9], int width, int height, eTransform transform) { + memset(mat, 0, sizeof(*mat) * 9); + + const float* t = transforms.at(transform).data(); + float x = 2.0f / width; + float y = 2.0f / height; + + // Rotation + reflection + mat[0] = x * t[0]; + mat[1] = x * t[1]; + mat[3] = y * -t[3]; + mat[4] = y * -t[4]; + + // Translation + mat[2] = -copysign(1.0f, mat[0] + mat[1]); + mat[5] = -copysign(1.0f, mat[3] + mat[4]); + + // Identity + mat[8] = 1.0f; +} + +void projectBox(float mat[9], CBox& box, eTransform transform, float rotation, const float projection[9]) { + double x = box.x; + double y = box.y; + double width = box.width; + double height = box.height; + + matrixIdentity(mat); + matrixTranslate(mat, x, y); + + if (rotation != 0) { + matrixTranslate(mat, width / 2, height / 2); + matrixRotate(mat, rotation); + matrixTranslate(mat, -width / 2, -height / 2); + } + + wlr_matrix_scale(mat, width, height); + + if (transform != HYPRUTILS_TRANSFORM_NORMAL) { + matrixTranslate(mat, 0.5, 0.5); + matrixTransform(mat, transform); + matrixTranslate(mat, -0.5, -0.5); + } + + matrixMultiply(mat, projection, mat); +} diff --git a/src/helpers/math/Math.hpp b/src/helpers/math/Math.hpp new file mode 100644 index 00000000..4aa65c93 --- /dev/null +++ b/src/helpers/math/Math.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include + +// includes box and vector as well +#include + +using namespace Hyprutils::Math; + +eTransform wlTransformToHyprutils(wl_output_transform t); +void projectBox(float mat[9], CBox& box, eTransform transform, float rotation, const float projection[9]); diff --git a/src/includes.hpp b/src/includes.hpp index dbae7635..87bd21f8 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -110,6 +110,4 @@ extern "C" { #define XWAYLAND true #endif -#include "helpers/Vector2D.hpp" -#include "helpers/Box.hpp" #include "SharedDefs.hpp" diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 172a157b..cbeaa420 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -180,9 +180,9 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for auto calcPos = PWINDOW->m_vPosition; auto calcSize = PWINDOW->m_vSize; - const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut.left : gapsIn.left, DISPLAYTOP ? gapsOut.top : gapsIn.top); + const auto OFFSETTOPLEFT = Vector2D((double)(DISPLAYLEFT ? gapsOut.left : gapsIn.left), (double)(DISPLAYTOP ? gapsOut.top : gapsIn.top)); - const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut.right : gapsIn.right, DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom); + const auto OFFSETBOTTOMRIGHT = Vector2D((double)(DISPLAYRIGHT ? gapsOut.right : gapsIn.right), (double)(DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom)); calcPos = calcPos + OFFSETTOPLEFT; calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; @@ -912,11 +912,11 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir, switch (dir[0]) { case 't': - case 'u': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.f, -1}; break; + case 'u': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.0, -1.0}; break; case 'd': - case 'b': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.f, pWindow->m_vSize.y + 1}; break; - case 'l': focalPoint = pWindow->m_vPosition + Vector2D{-1, pWindow->m_vSize.y / 2.f}; break; - case 'r': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x + 1, pWindow->m_vSize.y / 2.f}; break; + case 'b': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x / 2.0, pWindow->m_vSize.y + 1.0}; break; + case 'l': focalPoint = pWindow->m_vPosition + Vector2D{-1.0, pWindow->m_vSize.y / 2.0}; break; + case 'r': focalPoint = pWindow->m_vPosition + Vector2D{pWindow->m_vSize.x + 1.0, pWindow->m_vSize.y / 2.0}; break; default: UNREACHABLE(); } diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index b4270bb8..c6a7a66c 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -428,9 +428,9 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { if (m_eGrabbedCorner == CORNER_TOPLEFT) newPos = newPos - newSize + m_vBeginDragSizeXY; else if (m_eGrabbedCorner == CORNER_TOPRIGHT) - newPos = newPos + Vector2D(0, (m_vBeginDragSizeXY - newSize).y); + newPos = newPos + Vector2D(0.0, (m_vBeginDragSizeXY - newSize).y); else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT) - newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0); + newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0); CBox wb = {newPos, newSize}; wb.round(); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index c5784c74..965c0ed7 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -689,9 +689,9 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { auto calcPos = PWINDOW->m_vPosition; auto calcSize = PWINDOW->m_vSize; - const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut.left : gapsIn.left, DISPLAYTOP ? gapsOut.top : gapsIn.top); + const auto OFFSETTOPLEFT = Vector2D((double)(DISPLAYLEFT ? gapsOut.left : gapsIn.left), (double)(DISPLAYTOP ? gapsOut.top : gapsIn.top)); - const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut.right : gapsIn.right, DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom); + const auto OFFSETBOTTOMRIGHT = Vector2D((double)(DISPLAYRIGHT ? gapsOut.right : gapsIn.right), (double)(DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom)); calcPos = calcPos + OFFSETTOPLEFT; calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; diff --git a/src/macros.hpp b/src/macros.hpp index cca088d8..cacfdfea 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -98,3 +98,10 @@ ([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })(), err); \ } \ } + +#define HYPRUTILS_FORWARD(ns, name) \ + namespace Hyprutils { \ + namespace ns { \ + class name; \ + } \ + } diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 74fe4117..9d6668c9 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -25,7 +25,7 @@ int wlTick(SP self, void* data) { } CAnimationManager::CAnimationManager() { - std::vector points = {Vector2D(0, 0.75f), Vector2D(0.15f, 1.f)}; + std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); m_pAnimationTimer = SP(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); @@ -36,7 +36,7 @@ void CAnimationManager::removeAllBeziers() { m_mBezierCurves.clear(); // add the default one - std::vector points = {Vector2D(0, 0.75f), Vector2D(0.15f, 1.f)}; + std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); } @@ -336,9 +336,9 @@ void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, boo if (force == "bottom") posOffset = Vector2D(GOALPOS.x, PMONITOR->vecPosition.y + PMONITOR->vecSize.y); else if (force == "left") - posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0); + posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0); else if (force == "right") - posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0); + posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0); else posOffset = Vector2D(GOALPOS.x, PMONITOR->vecPosition.y - GOALSIZE.y); @@ -360,16 +360,16 @@ void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, boo if (DISPLAYBOTTOM && DISPLAYTOP) { if (DISPLAYLEFT && DISPLAYRIGHT) { - posOffset = GOALPOS + Vector2D(0, GOALSIZE.y); + posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y); } else if (DISPLAYLEFT) { - posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0); + posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0); } else { - posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0); + posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0); } } else if (DISPLAYTOP) { - posOffset = GOALPOS - Vector2D(0, GOALSIZE.y); + posOffset = GOALPOS - Vector2D(0.0, GOALSIZE.y); } else if (DISPLAYBOTTOM) { - posOffset = GOALPOS + Vector2D(0, GOALSIZE.y); + posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y); } else { if (MIDPOINT.y > PMONITOR->vecPosition.y + PMONITOR->vecSize.y / 2.f) posOffset = Vector2D(GOALPOS.x, PMONITOR->vecPosition.y + PMONITOR->vecSize.y); diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index 4430d0f4..daa4f4be 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -149,9 +149,10 @@ void CCursorManager::setXCursor(const std::string& name) { auto image = xcursor->images[0]; - m_vCursorBuffers.emplace_back(std::make_unique(image->buffer, Vector2D{image->width, image->height}, Vector2D{image->hotspot_x, image->hotspot_y})); + m_vCursorBuffers.emplace_back( + std::make_unique(image->buffer, Vector2D{(int)image->width, (int)image->height}, Vector2D{(double)image->hotspot_x, (double)image->hotspot_y})); - g_pPointerManager->setCursorBuffer(getCursorBuffer(), Vector2D{image->hotspot_x, image->hotspot_y} / scale, scale); + g_pPointerManager->setCursorBuffer(getCursorBuffer(), Vector2D{(double)image->hotspot_x, (double)image->hotspot_y} / scale, scale); if (m_vCursorBuffers.size() > 1) wlr_buffer_drop(&m_vCursorBuffers.front()->wlrBuffer.base); @@ -256,8 +257,8 @@ void CCursorManager::setXWaylandCursor() { g_pXWayland->setCursor(cairo_image_surface_get_data(CURSOR.surface), cairo_image_surface_get_stride(CURSOR.surface), {CURSOR.size, CURSOR.size}, {CURSOR.hotspotX, CURSOR.hotspotY}); } else if (const auto XCURSOR = wlr_xcursor_manager_get_xcursor(m_pWLRXCursorMgr, "left_ptr", 1); XCURSOR) { - g_pXWayland->setCursor(XCURSOR->images[0]->buffer, XCURSOR->images[0]->width * 4, {XCURSOR->images[0]->width, XCURSOR->images[0]->height}, - {XCURSOR->images[0]->hotspot_x, XCURSOR->images[0]->hotspot_y}); + g_pXWayland->setCursor(XCURSOR->images[0]->buffer, XCURSOR->images[0]->width * 4, {(int)XCURSOR->images[0]->width, (int)XCURSOR->images[0]->height}, + {(double)XCURSOR->images[0]->hotspot_x, (double)XCURSOR->images[0]->hotspot_y}); } else Debug::log(ERR, "CursorManager: no valid cursor for xwayland"); } diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index 6fbff636..f983efbb 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -4,7 +4,7 @@ #include #include #include "../includes.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" struct wlr_buffer; struct wlr_xcursor_manager; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 3a28ea8d..05059669 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -577,7 +577,7 @@ Vector2D CPointerManager::transformedHotspot(SP pMonitor) { return {}; // doesn't matter, we have no hw cursor, and this is only for hw cursors return CBox{currentCursorImage.hotspot * pMonitor->scale, {0, 0}} - .transform(wlr_output_transform_invert(pMonitor->transform), pMonitor->output->cursor_swapchain->width, pMonitor->output->cursor_swapchain->height) + .transform(wlTransformToHyprutils(wlr_output_transform_invert(pMonitor->transform)), pMonitor->output->cursor_swapchain->width, pMonitor->output->cursor_swapchain->height) .pos(); } diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp index 1e386797..c3673e16 100644 --- a/src/managers/PointerManager.hpp +++ b/src/managers/PointerManager.hpp @@ -3,8 +3,8 @@ #include "../devices/IPointer.hpp" #include "../devices/ITouch.hpp" #include "../devices/Tablet.hpp" -#include "../helpers/Box.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" +#include "../helpers/math/Math.hpp" #include "../desktop/WLSurface.hpp" #include diff --git a/src/managers/SeatManager.hpp b/src/managers/SeatManager.hpp index 1a1df1d5..43ebe8b5 100644 --- a/src/managers/SeatManager.hpp +++ b/src/managers/SeatManager.hpp @@ -5,7 +5,7 @@ #include "../helpers/WLListener.hpp" #include "../macros.hpp" #include "../helpers/signal/Signal.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" #include "../protocols/types/DataDevice.hpp" #include diff --git a/src/managers/input/InputMethodPopup.hpp b/src/managers/input/InputMethodPopup.hpp index 3151aedb..f6e5c8be 100644 --- a/src/managers/input/InputMethodPopup.hpp +++ b/src/managers/input/InputMethodPopup.hpp @@ -3,7 +3,7 @@ #include "../../helpers/WLListener.hpp" #include "../../desktop/WLSurface.hpp" #include "../../macros.hpp" -#include "../../helpers/Box.hpp" +#include "../../helpers/math/Math.hpp" #include "../../helpers/signal/Signal.hpp" class CInputMethodPopupV2; diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index a605fea7..ead7c5b8 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -109,16 +109,16 @@ void CInputManager::endWorkspaceSwipe() { if (PWORKSPACEL) { if (VERTANIMS) - PWORKSPACEL->m_vRenderOffset = Vector2D{0, -YDISTANCE}; + PWORKSPACEL->m_vRenderOffset = Vector2D{0.0, -YDISTANCE}; else - PWORKSPACEL->m_vRenderOffset = Vector2D{-XDISTANCE, 0}; + PWORKSPACEL->m_vRenderOffset = Vector2D{-XDISTANCE, 0.0}; } } else if (PWORKSPACER) { // to right if (VERTANIMS) - PWORKSPACER->m_vRenderOffset = Vector2D{0, YDISTANCE}; + PWORKSPACER->m_vRenderOffset = Vector2D{0.0, YDISTANCE}; else - PWORKSPACER->m_vRenderOffset = Vector2D{XDISTANCE, 0}; + PWORKSPACER->m_vRenderOffset = Vector2D{XDISTANCE, 0.0}; } m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(); @@ -141,9 +141,9 @@ void CInputManager::endWorkspaceSwipe() { m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0, YDISTANCE); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, YDISTANCE); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(XDISTANCE, 0); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(XDISTANCE, 0.0); m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(1.f); g_pInputManager->unconstrainMouse(); @@ -167,9 +167,9 @@ void CInputManager::endWorkspaceSwipe() { m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0, -YDISTANCE); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, -YDISTANCE); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(-XDISTANCE, 0); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(-XDISTANCE, 0.0); m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(1.f); g_pInputManager->unconstrainMouse(); @@ -269,9 +269,9 @@ void CInputManager::updateWorkspaceSwipe(double delta) { g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID); return; @@ -293,11 +293,11 @@ void CInputManager::updateWorkspaceSwipe(double delta) { } if (VERTANIMS) { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); } else { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0)); + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); } g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft); @@ -309,9 +309,9 @@ void CInputManager::updateWorkspaceSwipe(double delta) { g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID); return; @@ -333,11 +333,11 @@ void CInputManager::updateWorkspaceSwipe(double delta) { } if (VERTANIMS) { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); } else { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0)); + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); } g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight); diff --git a/src/managers/input/TextInput.hpp b/src/managers/input/TextInput.hpp index 61a664b9..79e08af9 100644 --- a/src/managers/input/TextInput.hpp +++ b/src/managers/input/TextInput.hpp @@ -2,7 +2,7 @@ #include "../../helpers/WLListener.hpp" #include "../../macros.hpp" -#include "../../helpers/Box.hpp" +#include "../../helpers/math/Math.hpp" #include "../../helpers/signal/Signal.hpp" #include diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp index d4b105cb..fd66ba5e 100644 --- a/src/protocols/LayerShell.cpp +++ b/src/protocols/LayerShell.cpp @@ -82,7 +82,7 @@ CLayerShellResource::CLayerShellResource(SP resource_, SPsetSetSize([this](CZwlrLayerSurfaceV1* r, uint32_t x, uint32_t y) { pending.committed |= STATE_SIZE; - pending.desiredSize = {x, y}; + pending.desiredSize = {(int)x, (int)y}; }); resource->setSetAnchor([this](CZwlrLayerSurfaceV1* r, zwlrLayerSurfaceV1Anchor anchor) { diff --git a/src/protocols/LayerShell.hpp b/src/protocols/LayerShell.hpp index 7fa14447..6d29248a 100644 --- a/src/protocols/LayerShell.hpp +++ b/src/protocols/LayerShell.hpp @@ -6,7 +6,7 @@ #include #include "WaylandProtocol.hpp" #include "wlr-layer-shell-unstable-v1.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" #include "types/SurfaceRole.hpp" diff --git a/src/protocols/PointerConstraints.hpp b/src/protocols/PointerConstraints.hpp index 8a78de99..faf28b32 100644 --- a/src/protocols/PointerConstraints.hpp +++ b/src/protocols/PointerConstraints.hpp @@ -7,8 +7,8 @@ #include #include "WaylandProtocol.hpp" #include "pointer-constraints-unstable-v1.hpp" -#include "../helpers/Vector2D.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" class CWLSurface; diff --git a/src/protocols/PointerGestures.hpp b/src/protocols/PointerGestures.hpp index 33c2bace..f907a49f 100644 --- a/src/protocols/PointerGestures.hpp +++ b/src/protocols/PointerGestures.hpp @@ -4,7 +4,7 @@ #include #include "WaylandProtocol.hpp" #include "pointer-gestures-unstable-v1.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" class CPointerGestureSwipe { public: diff --git a/src/protocols/RelativePointer.hpp b/src/protocols/RelativePointer.hpp index 93446e85..453ce157 100644 --- a/src/protocols/RelativePointer.hpp +++ b/src/protocols/RelativePointer.hpp @@ -5,7 +5,7 @@ #include #include "WaylandProtocol.hpp" #include "relative-pointer-unstable-v1.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" class CRelativePointer { public: diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 0c4eac86..8a6285a1 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -279,7 +279,7 @@ void CScreencopyProtocolManager::captureOutput(wl_client* client, wl_resource* r } int ow, oh; wlr_output_effective_resolution(PFRAME->pMonitor->output, &ow, &oh); - PFRAME->box.transform(PFRAME->pMonitor->transform, ow, oh).scale(PFRAME->pMonitor->scale).round(); + PFRAME->box.transform(wlTransformToHyprutils(PFRAME->pMonitor->transform), ow, oh).scale(PFRAME->pMonitor->scale).round(); PFRAME->shmStride = FormatUtils::minStride(PSHMINFO, PFRAME->box.w); @@ -556,9 +556,10 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) { if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer.lock(), nullptr, true)) return false; - CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y} - .translate({-frame->box.x, -frame->box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh. - .transform(wlr_output_transform_invert(frame->pMonitor->output->transform), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y); + CBox monbox = + CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y} + .translate({-frame->box.x, -frame->box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh. + .transform(wlTransformToHyprutils(wlr_output_transform_invert(frame->pMonitor->output->transform)), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y); g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTexture(TEXTURE, &monbox, 1); diff --git a/src/protocols/Tablet.hpp b/src/protocols/Tablet.hpp index c61395c9..58f13c1a 100644 --- a/src/protocols/Tablet.hpp +++ b/src/protocols/Tablet.hpp @@ -5,7 +5,7 @@ #include #include "WaylandProtocol.hpp" #include "tablet-v2.hpp" -#include "../helpers/Vector2D.hpp" +#include "../helpers/math/Math.hpp" class CTablet; class CTabletTool; diff --git a/src/protocols/TextInputV3.hpp b/src/protocols/TextInputV3.hpp index 3959e72b..9f6284dc 100644 --- a/src/protocols/TextInputV3.hpp +++ b/src/protocols/TextInputV3.hpp @@ -7,7 +7,7 @@ #include "WaylandProtocol.hpp" #include "text-input-unstable-v3.hpp" #include "../helpers/signal/Signal.hpp" -#include "../helpers/Box.hpp" +#include "../helpers/math/Math.hpp" class CWLSurfaceResource; diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 80f9defa..287538b5 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -202,7 +202,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou PFRAME->box = {0, 0, (int)(pWindow->m_vRealSize.value().x * PMONITOR->scale), (int)(pWindow->m_vRealSize.value().y * PMONITOR->scale)}; int ow, oh; wlr_output_effective_resolution(PMONITOR->output, &ow, &oh); - PFRAME->box.transform(PMONITOR->transform, ow, oh).round(); + PFRAME->box.transform(wlTransformToHyprutils(PMONITOR->transform), ow, oh).round(); PFRAME->shmStride = FormatUtils::minStride(PSHMINFO, PFRAME->box.w); diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index c16ebb9d..9c56df93 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -514,13 +514,13 @@ CXDGPositionerRules::CXDGPositionerRules(SP positioner) static Vector2D pointForAnchor(const CBox& box, const Vector2D& predictionSize, xdgPositionerAnchor anchor) { switch (anchor) { - case XDG_POSITIONER_ANCHOR_TOP: return box.pos() + Vector2D{box.size().x / 2.F - predictionSize.x / 2.F, 0}; - case XDG_POSITIONER_ANCHOR_BOTTOM: return box.pos() + Vector2D{box.size().x / 2.F - predictionSize.x / 2.F, box.size().y}; - case XDG_POSITIONER_ANCHOR_LEFT: return box.pos() + Vector2D{0, box.size().y / 2.F - predictionSize.y / 2.F}; - case XDG_POSITIONER_ANCHOR_RIGHT: return box.pos() + Vector2D{box.size().x, box.size().y / 2.F - predictionSize.y / 2.F}; + case XDG_POSITIONER_ANCHOR_TOP: return box.pos() + Vector2D{box.size().x / 2.0 - predictionSize.x / 2.0, 0.0}; + case XDG_POSITIONER_ANCHOR_BOTTOM: return box.pos() + Vector2D{box.size().x / 2.0 - predictionSize.x / 2.0, box.size().y}; + case XDG_POSITIONER_ANCHOR_LEFT: return box.pos() + Vector2D{0.0, box.size().y / 2.0 - predictionSize.y / 2.0}; + case XDG_POSITIONER_ANCHOR_RIGHT: return box.pos() + Vector2D{box.size().x, box.size().y / 2.F - predictionSize.y / 2.0}; case XDG_POSITIONER_ANCHOR_TOP_LEFT: return box.pos(); - case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT: return box.pos() + Vector2D{0, box.size().y}; - case XDG_POSITIONER_ANCHOR_TOP_RIGHT: return box.pos() + Vector2D{box.size().x, 0}; + case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT: return box.pos() + Vector2D{0.0, box.size().y}; + case XDG_POSITIONER_ANCHOR_TOP_RIGHT: return box.pos() + Vector2D{box.size().x, 0.0}; case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT: return box.pos() + Vector2D{box.size().x, box.size().y}; default: return box.pos(); } @@ -555,10 +555,10 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa }; int edgeCount = countEdges(test); - if (flipX && edgeCount > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}))) - test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}); - if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}))) - test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}); + if (flipX && edgeCount > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0.0}))) + test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0.0}); + if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0.0, -predictedBox.h - state.anchorRect.h}))) + test.translate(Vector2D{0.0, -predictedBox.h - state.anchorRect.h}); success = test.copy().expand(-1).inside(constraint); diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index d60db86a..da551718 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -6,8 +6,8 @@ #include #include "WaylandProtocol.hpp" #include "xdg-shell.hpp" -#include "../helpers/Vector2D.hpp" -#include "../helpers/Box.hpp" +#include "../helpers/math/Math.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" #include "types/SurfaceRole.hpp" diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 165da6ee..4bce3f58 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -421,7 +421,7 @@ CRegion CWLSurfaceResource::accumulateCurrentBufferDamage() { Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.buffer->size.y, current.buffer->size.x} : current.buffer->size; - return surfaceDamage.scale(current.scale).transform(wlr_output_transform_invert(current.transform), trc.x, trc.y).add(current.bufferDamage); + return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(wlr_output_transform_invert(current.transform)), trc.x, trc.y).add(current.bufferDamage); } CWLCompositorResource::CWLCompositorResource(SP resource_) : resource(resource_) { diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index f50144bf..2f276719 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -14,7 +14,7 @@ #include "../WaylandProtocol.hpp" #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" -#include "../../helpers/Region.hpp" +#include "../../helpers/math/Math.hpp" #include "../types/Buffer.hpp" #include "../types/SurfaceRole.hpp" diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp index 5b31559f..22bb9376 100644 --- a/src/protocols/core/DataDevice.hpp +++ b/src/protocols/core/DataDevice.hpp @@ -15,7 +15,7 @@ #include #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" -#include "../../helpers/Vector2D.hpp" +#include "../../helpers/math/Math.hpp" #include "../types/DataDevice.hpp" class CWLDataDeviceResource; diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 0b563b8f..09b36056 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -15,7 +15,7 @@ #include #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" -#include "../../helpers/Vector2D.hpp" +#include "../../helpers/math/Math.hpp" constexpr const char* HL_SEAT_NAME = "Hyprland"; diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index 687e2031..70a8b208 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -13,7 +13,7 @@ #include "../WaylandProtocol.hpp" #include "wayland.hpp" #include "../types/Buffer.hpp" -#include "../../helpers/Vector2D.hpp" +#include "../../helpers/math/Math.hpp" class CWLSHMPoolResource; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 5d8d6b83..3178ab8c 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -916,7 +916,7 @@ void CHyprOpenGLImpl::scissor(const CBox* pBox, bool transform) { int w, h; wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h); - const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform); + const auto TR = wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)); newBox.transform(TR, w, h); } @@ -1006,8 +1006,8 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion box = &newBox; float matrix[9]; - wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), newBox.rot, - m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here + projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot, + m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1025,7 +1025,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r * col.a, col.g * col.a, col.b * col.a, col.a); CBox transformedBox = *box; - transformedBox.transform(wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, + transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y); @@ -1097,9 +1097,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB static auto PDT = CConfigValue("debug:damage_tracking"); // get transform - const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform); + const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)); float matrix[9]; - wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); + projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1185,7 +1185,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB } CBox transformedBox = newBox; - transformedBox.transform(wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, + transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y); @@ -1260,9 +1260,9 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, CBox* pBox) { m_RenderData.renderModif.applyToBox(newBox); // get transform - const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform); + const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)); float matrix[9]; - wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); + projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1314,9 +1314,9 @@ void CHyprOpenGLImpl::renderTextureMatte(SP tex, CBox* pBox, CFramebuf m_RenderData.renderModif.applyToBox(newBox); // get transform - const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform); + const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)); float matrix[9]; - wlr_matrix_project_box(matrix, newBox.pWlr(), TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); + projectBox(matrix, newBox, TRANSFORM, newBox.rot, m_RenderData.monitorProjection.data()); float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1372,10 +1372,10 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o glDisable(GL_STENCIL_TEST); // get transforms for the full monitor - const auto TRANSFORM = wlr_output_transform_invert(m_RenderData.pMonitor->transform); + const auto TRANSFORM = wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)); float matrix[9]; CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - wlr_matrix_project_box(matrix, MONITORBOX.pWlr(), TRANSFORM, 0, m_RenderData.monitorProjection.data()); + projectBox(matrix, MONITORBOX, TRANSFORM, 0, m_RenderData.monitorProjection.data()); float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1870,8 +1870,8 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in round += round == 0 ? 0 : scaledBorderSize; float matrix[9]; - wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), newBox.rot, - m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here + projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot, + m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -1896,7 +1896,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a); CBox transformedBox = *box; - transformedBox.transform(wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, + transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y); @@ -2176,8 +2176,8 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const const auto col = color; float matrix[9]; - wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), newBox.rot, - m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here + projectBox(matrix, newBox, wlTransformToHyprutils(wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot, + m_RenderData.monitorProjection.data()); // TODO: write own, don't use WLR here float glMatrix[9]; wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); @@ -2258,7 +2258,7 @@ void CHyprOpenGLImpl::renderMirrored() { CBox monbox = {0, 0, mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale}; // transform box as it will be drawn on a transformed projection - monbox.transform(mirrored->transform, mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale); + monbox.transform(wlTransformToHyprutils(mirrored->transform), mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale); monbox.x = (monitor->vecTransformedSize.x - monbox.w) / 2; monbox.y = (monitor->vecTransformedSize.y - monbox.h) / 2; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index c6e173e5..814b80fe 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -4,7 +4,7 @@ #include "../helpers/Monitor.hpp" #include "../helpers/Color.hpp" #include "../helpers/Timer.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" #include "../helpers/Format.hpp" #include #include diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f56fb5d6..d44f4cd5 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1,6 +1,6 @@ #include "Renderer.hpp" #include "../Compositor.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" #include #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" @@ -1508,15 +1508,15 @@ void CHyprRenderer::setWindowScanoutMode(PHLWINDOW pWindow) { // taken from Sway. // this is just too much of a spaghetti for me to understand -static void applyExclusive(wlr_box& usableArea, uint32_t anchor, int32_t exclusive, int32_t marginTop, int32_t marginRight, int32_t marginBottom, int32_t marginLeft) { +static void applyExclusive(CBox& usableArea, uint32_t anchor, int32_t exclusive, int32_t marginTop, int32_t marginRight, int32_t marginBottom, int32_t marginLeft) { if (exclusive <= 0) { return; } struct { uint32_t singular_anchor; uint32_t anchor_triplet; - int* positive_axis; - int* negative_axis; + double* positive_axis; + double* negative_axis; int margin; } edges[] = { // Top @@ -1640,9 +1640,7 @@ void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vectorgeometry = box; - applyExclusive(*usableArea->pWlr(), PSTATE->anchor, PSTATE->exclusive, PSTATE->margin.top, PSTATE->margin.right, PSTATE->margin.bottom, PSTATE->margin.left); - - usableArea->applyFromWlr(); + applyExclusive(*usableArea, PSTATE->anchor, PSTATE->exclusive, PSTATE->margin.top, PSTATE->margin.right, PSTATE->margin.bottom, PSTATE->margin.left); if (Vector2D{box.width, box.height} != OLDSIZE) ls->layerSurface->configure(box.size()); @@ -1820,7 +1818,7 @@ void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, const CRegion& pRegion monbox.y = (monitor->vecTransformedSize.y - monbox.h) / 2; wlr_region_scale(transformed.pixman(), transformed.pixman(), scale); - transformed.transform(mirrored->transform, mirrored->vecPixelSize.x * scale, mirrored->vecPixelSize.y * scale); + transformed.transform(wlTransformToHyprutils(mirrored->transform), mirrored->vecPixelSize.x * scale, mirrored->vecPixelSize.y * scale); transformed.translate(Vector2D(monbox.x, monbox.y)); mirror->addDamage(&transformed); @@ -2234,7 +2232,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR if (pMonitor->createdByUser) { CBox transformedBox = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; - transformedBox.transform(wlr_output_transform_invert(pMonitor->output->transform), pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); + transformedBox.transform(wlTransformToHyprutils(wlr_output_transform_invert(pMonitor->output->transform)), pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); pMonitor->vecPixelSize = Vector2D(transformedBox.width, transformedBox.height); } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 6adca72a..8f404c88 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -6,7 +6,7 @@ #include "OpenGL.hpp" #include "Renderbuffer.hpp" #include "../helpers/Timer.hpp" -#include "../helpers/Region.hpp" +#include "../helpers/math/Math.hpp" struct SMonitorRule; class CWorkspace; diff --git a/src/render/Texture.cpp b/src/render/Texture.cpp index aef8e4ac..5560db97 100644 --- a/src/render/Texture.cpp +++ b/src/render/Texture.cpp @@ -55,7 +55,7 @@ CTexture::CTexture(wlr_texture* tex) { else m_iType = TEXTURE_EXTERNAL; - m_vSize = Vector2D(tex->width, tex->height); + m_vSize = Vector2D((int)tex->width, (int)tex->height); } CTexture::CTexture(const SDMABUFAttrs& attrs, void* image) { diff --git a/src/render/Texture.hpp b/src/render/Texture.hpp index fa1ca4fe..c80e943d 100644 --- a/src/render/Texture.hpp +++ b/src/render/Texture.hpp @@ -4,7 +4,7 @@ class IWLBuffer; struct SDMABUFAttrs; -class CRegion; +HYPRUTILS_FORWARD(Math, CRegion); enum TEXTURETYPE { TEXTURE_INVALID, // Invalid diff --git a/src/render/decorations/CHyprBorderDecoration.hpp b/src/render/decorations/CHyprBorderDecoration.hpp index 3fa0946e..8ad3263e 100644 --- a/src/render/decorations/CHyprBorderDecoration.hpp +++ b/src/render/decorations/CHyprBorderDecoration.hpp @@ -26,16 +26,16 @@ class CHyprBorderDecoration : public IHyprWindowDecoration { virtual std::string getDisplayName(); private: - SWindowDecorationExtents m_seExtents; - SWindowDecorationExtents m_seReportedExtents; + SBoxExtents m_seExtents; + SBoxExtents m_seReportedExtents; - PHLWINDOWREF m_pWindow; + PHLWINDOWREF m_pWindow; - Vector2D m_vLastWindowPos; - Vector2D m_vLastWindowSize; + Vector2D m_vLastWindowPos; + Vector2D m_vLastWindowSize; - CBox m_bAssignedGeometry = {0}; + CBox m_bAssignedGeometry = {0}; - CBox assignedBoxGlobal(); - bool doesntWantBorders(); + CBox assignedBoxGlobal(); + bool doesntWantBorders(); }; diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index fba279cc..6893d78c 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -130,7 +130,7 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a) { const float SHADOWSCALE = std::clamp(*PSHADOWSCALE, 0.f, 1.f); // scale the box in relation to the center of the box - fullBox.scaleFromCenter(SHADOWSCALE).translate(*PSHADOWOFFSET); + fullBox.scaleFromCenter(SHADOWSCALE).translate({(*PSHADOWOFFSET).x, (*PSHADOWOFFSET).y}); updateWindow(PWINDOW); m_vLastWindowPos += WORKSPACEOFFSET; diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 06319cb7..ecd5a47b 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -26,14 +26,14 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { virtual std::string getDisplayName(); private: - SWindowDecorationExtents m_seExtents; - SWindowDecorationExtents m_seReportedExtents; + SBoxExtents m_seExtents; + SBoxExtents m_seReportedExtents; - PHLWINDOWREF m_pWindow; + PHLWINDOWREF m_pWindow; - Vector2D m_vLastWindowPos; - Vector2D m_vLastWindowSize; + Vector2D m_vLastWindowPos; + Vector2D m_vLastWindowSize; - CBox m_bLastWindowBox = {0}; - CBox m_bLastWindowBoxWithDecos = {0}; + CBox m_bLastWindowBox = {0}; + CBox m_bLastWindowBoxWithDecos = {0}; }; diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index 1af24717..bfb15d5c 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -48,7 +48,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { virtual std::string getDisplayName(); private: - SWindowDecorationExtents m_seExtents; + SBoxExtents m_seExtents; CBox m_bAssignedBox = {0}; diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index 17f6d913..d66a5760 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -33,11 +33,11 @@ Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, PHLWINDOW pW if (EDGESNO == 1) { if (TOP) - return wb.pos() + Vector2D{wb.size().x / 2.0, 0}; + return wb.pos() + Vector2D{wb.size().x / 2.0, 0.0}; else if (BOTTOM) return wb.pos() + Vector2D{wb.size().x / 2.0, wb.size().y}; else if (LEFT) - return wb.pos() + Vector2D{0, wb.size().y / 2.0}; + return wb.pos() + Vector2D{0.0, wb.size().y / 2.0}; else if (RIGHT) return wb.pos() + Vector2D{wb.size().x, wb.size().y / 2.0}; UNREACHABLE(); @@ -45,11 +45,11 @@ Vector2D CDecorationPositioner::getEdgeDefinedPoint(uint32_t edges, PHLWINDOW pW if (TOP && LEFT) return wb.pos(); if (TOP && RIGHT) - return wb.pos() + Vector2D{wb.size().x, 0}; + return wb.pos() + Vector2D{wb.size().x, 0.0}; if (BOTTOM && RIGHT) return wb.pos() + wb.size(); if (BOTTOM && LEFT) - return wb.pos() + Vector2D{0, wb.size().y}; + return wb.pos() + Vector2D{0.0, wb.size().y}; UNREACHABLE(); } UNREACHABLE(); @@ -234,26 +234,26 @@ void CDecorationPositioner::onWindowUpdate(PHLWINDOW pWindow) { } else if (LEFT) { pos = wb.pos() - EDGEPOINT - Vector2D{stickyOffsetXL, -stickyOffsetYT}; pos.x -= desiredSize; - size = {desiredSize, wb.size().y + stickyOffsetYB + stickyOffsetYT}; + size = {(double)desiredSize, wb.size().y + stickyOffsetYB + stickyOffsetYT}; if (SOLID) stickyOffsetXL += desiredSize; } else if (RIGHT) { - pos = wb.pos() + Vector2D{wb.size().x, 0} - EDGEPOINT + Vector2D{stickyOffsetXR, -stickyOffsetYT}; - size = {desiredSize, wb.size().y + stickyOffsetYB + stickyOffsetYT}; + pos = wb.pos() + Vector2D{wb.size().x, 0.0} - EDGEPOINT + Vector2D{stickyOffsetXR, -stickyOffsetYT}; + size = {(double)desiredSize, wb.size().y + stickyOffsetYB + stickyOffsetYT}; if (SOLID) stickyOffsetXR += desiredSize; } else if (TOP) { pos = wb.pos() - EDGEPOINT - Vector2D{stickyOffsetXL, stickyOffsetYT}; pos.y -= desiredSize; - size = {wb.size().x + stickyOffsetXL + stickyOffsetXR, desiredSize}; + size = {wb.size().x + stickyOffsetXL + stickyOffsetXR, (double)desiredSize}; if (SOLID) stickyOffsetYT += desiredSize; } else { - pos = wb.pos() + Vector2D{0, wb.size().y} - EDGEPOINT - Vector2D{stickyOffsetXL, stickyOffsetYB}; - size = {wb.size().x + stickyOffsetXL + stickyOffsetXR, desiredSize}; + pos = wb.pos() + Vector2D{0.0, wb.size().y} - EDGEPOINT - Vector2D{stickyOffsetXL, stickyOffsetYB}; + size = {wb.size().x + stickyOffsetXL + stickyOffsetXR, (double)desiredSize}; if (SOLID) stickyOffsetYB += desiredSize; @@ -271,7 +271,7 @@ void CDecorationPositioner::onWindowUpdate(PHLWINDOW pWindow) { } } - if (WINDOWDATA->extents != SWindowDecorationExtents{{stickyOffsetXL + reservedXL, stickyOffsetYT + reservedYT}, {stickyOffsetXR + reservedXR, stickyOffsetYB + reservedYB}}) { + if (WINDOWDATA->extents != SBoxExtents{{stickyOffsetXL + reservedXL, stickyOffsetYT + reservedYT}, {stickyOffsetXR + reservedXR, stickyOffsetYB + reservedYB}}) { WINDOWDATA->extents = {{stickyOffsetXL + reservedXL, stickyOffsetYT + reservedYT}, {stickyOffsetXR + reservedXR, stickyOffsetYB + reservedYB}}; g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow); } @@ -286,14 +286,14 @@ void CDecorationPositioner::onWindowMap(PHLWINDOW pWindow) { m_mWindowDatas[pWindow] = {}; } -SWindowDecorationExtents CDecorationPositioner::getWindowDecorationReserved(PHLWINDOW pWindow) { +SBoxExtents CDecorationPositioner::getWindowDecorationReserved(PHLWINDOW pWindow) { try { const auto E = m_mWindowDatas.at(pWindow); return E.reserved; } catch (std::out_of_range& e) { return {}; } } -SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(PHLWINDOW pWindow, bool inputOnly) { +SBoxExtents CDecorationPositioner::getWindowDecorationExtents(PHLWINDOW pWindow, bool inputOnly) { CBox accum = pWindow->getWindowMainSurfaceBox(); for (auto& data : m_vWindowPositioningDatas) { @@ -317,7 +317,7 @@ SWindowDecorationExtents CDecorationPositioner::getWindowDecorationExtents(PHLWI decoBox.translate(EDGEPOINT); } - SWindowDecorationExtents extentsToAdd; + SBoxExtents extentsToAdd; if (decoBox.x < accum.x) extentsToAdd.topLeft.x = accum.x - decoBox.x; @@ -355,7 +355,7 @@ CBox CDecorationPositioner::getBoxWithIncludedDecos(PHLWINDOW pWindow) { decoBox.translate(EDGEPOINT); } - SWindowDecorationExtents extentsToAdd; + SBoxExtents extentsToAdd; if (decoBox.x < accum.x) extentsToAdd.topLeft.x = accum.x - decoBox.x; diff --git a/src/render/decorations/DecorationPositioner.hpp b/src/render/decorations/DecorationPositioner.hpp index 880dc3f8..27e56f0b 100644 --- a/src/render/decorations/DecorationPositioner.hpp +++ b/src/render/decorations/DecorationPositioner.hpp @@ -3,7 +3,7 @@ #include #include #include -#include "../../helpers/Box.hpp" +#include "../../helpers/math/Math.hpp" #include "../../desktop/DesktopTypes.hpp" class CWindow; @@ -37,7 +37,7 @@ struct SDecorationPositioningInfo { eDecorationPositioningPolicy policy = DECORATION_POSITION_ABSOLUTE; uint32_t edges = 0; // enum eDecorationEdges uint32_t priority = 10; // priority, decos will be evaluated high -> low - SWindowDecorationExtents desiredExtents; + SBoxExtents desiredExtents; bool reserved = false; // if true, geometry will use reserved area }; @@ -62,14 +62,14 @@ class CDecorationPositioner { Vector2D getEdgeDefinedPoint(uint32_t edges, PHLWINDOW pWindow); // called on resize, or insert/removal of a new deco - void onWindowUpdate(PHLWINDOW pWindow); - void uncacheDecoration(IHyprWindowDecoration* deco); - SWindowDecorationExtents getWindowDecorationReserved(PHLWINDOW pWindow); - SWindowDecorationExtents getWindowDecorationExtents(PHLWINDOW pWindow, bool inputOnly = false); - CBox getBoxWithIncludedDecos(PHLWINDOW pWindow); - void repositionDeco(IHyprWindowDecoration* deco); - CBox getWindowDecorationBox(IHyprWindowDecoration* deco); - void forceRecalcFor(PHLWINDOW pWindow); + void onWindowUpdate(PHLWINDOW pWindow); + void uncacheDecoration(IHyprWindowDecoration* deco); + SBoxExtents getWindowDecorationReserved(PHLWINDOW pWindow); + SBoxExtents getWindowDecorationExtents(PHLWINDOW pWindow, bool inputOnly = false); + CBox getBoxWithIncludedDecos(PHLWINDOW pWindow); + void repositionDeco(IHyprWindowDecoration* deco); + CBox getWindowDecorationBox(IHyprWindowDecoration* deco); + void forceRecalcFor(PHLWINDOW pWindow); private: struct SWindowPositioningData { @@ -81,10 +81,10 @@ class CDecorationPositioner { }; struct SWindowData { - Vector2D lastWindowSize = {}; - SWindowDecorationExtents reserved = {}; - SWindowDecorationExtents extents = {}; - bool needsRecalc = false; + Vector2D lastWindowSize = {}; + SBoxExtents reserved = {}; + SBoxExtents extents = {}; + bool needsRecalc = false; }; std::map m_mWindowDatas; diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index 2346106f..a58560f3 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -2,7 +2,7 @@ #include #include "../../defines.hpp" -#include "../../helpers/Region.hpp" +#include "../../helpers/math/Math.hpp" #include "DecorationPositioner.hpp" enum eDecorationType { diff --git a/src/xwayland/XSurface.hpp b/src/xwayland/XSurface.hpp index 0cdac1d5..4e31e88d 100644 --- a/src/xwayland/XSurface.hpp +++ b/src/xwayland/XSurface.hpp @@ -2,7 +2,7 @@ #include "../helpers/WLListener.hpp" #include "../helpers/signal/Signal.hpp" -#include "../helpers/Box.hpp" +#include "../helpers/math/Math.hpp" #include class CWLSurfaceResource; diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 7b57de0f..aa38910f 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -1,4 +1,4 @@ -#include "helpers/Vector2D.hpp" +#include "helpers/math/Math.hpp" #ifndef NO_XWAYLAND #include "XWayland.hpp" From 20a465f69d342c5caead27df696d228492ea02e8 Mon Sep 17 00:00:00 2001 From: Lucas Reis Date: Wed, 19 Jun 2024 10:24:28 -0400 Subject: [PATCH 18/30] pointer: use software rendering when monitor is mirrored (#6587) * pointer_manager: add lock/unlock software wrappers that receive the raw pointer * monitor: lock/unlock software pointer rendering when adding/removing mirrored screens * use relative path in includes --- src/helpers/Monitor.cpp | 10 ++++++++++ src/managers/PointerManager.cpp | 18 ++++++++++++++++++ src/managers/PointerManager.hpp | 2 ++ 3 files changed, 30 insertions(+) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index da6da873..e99e16ef 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -6,6 +6,7 @@ #include "../devices/ITouch.hpp" #include "../protocols/LayerShell.hpp" #include "../protocols/PresentationTime.hpp" +#include "../managers/PointerManager.hpp" #include using namespace Hyprutils::String; @@ -248,6 +249,9 @@ void CMonitor::onDisconnect(bool destroy) { // remove mirror if (pMirrorOf) { pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; })); + + // unlock software for mirrored monitor + g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf); pMirrorOf = nullptr; } @@ -471,6 +475,9 @@ void CMonitor::setMirror(const std::string& mirrorOf) { if (pMirrorOf) { pMirrorOf->mirrors.erase(std::find_if(pMirrorOf->mirrors.begin(), pMirrorOf->mirrors.end(), [&](const auto& other) { return other == this; })); + + // unlock software for mirrored monitor + g_pPointerManager->unlockSoftwareForMonitor(pMirrorOf); } pMirrorOf = nullptr; @@ -540,6 +547,9 @@ void CMonitor::setMirror(const std::string& mirrorOf) { g_pCompositor->setActiveMonitor(g_pCompositor->m_vMonitors.front().get()); g_pCompositor->sanityCheckWorkspaces(); + + // Software lock mirrored monitor + g_pPointerManager->lockSoftwareForMonitor(PMIRRORMON); } events.modeChanged.emit(); diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 05059669..d3da5eff 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -164,6 +164,15 @@ void CPointerManager::unlockSoftwareAll() { updateCursorBackend(); } +void CPointerManager::lockSoftwareForMonitor(CMonitor* Monitor) { + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->ID == Monitor->ID) { + lockSoftwareForMonitor(m); + return; + } + } +} + void CPointerManager::lockSoftwareForMonitor(SP mon) { auto state = stateFor(mon); state->softwareLocks++; @@ -172,6 +181,15 @@ void CPointerManager::lockSoftwareForMonitor(SP mon) { updateCursorBackend(); } +void CPointerManager::unlockSoftwareForMonitor(CMonitor* Monitor) { + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->ID == Monitor->ID) { + unlockSoftwareForMonitor(m); + return; + } + } +} + void CPointerManager::unlockSoftwareForMonitor(SP mon) { auto state = stateFor(mon); state->softwareLocks--; diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp index c3673e16..545b76fb 100644 --- a/src/managers/PointerManager.hpp +++ b/src/managers/PointerManager.hpp @@ -43,6 +43,8 @@ class CPointerManager { void lockSoftwareForMonitor(SP pMonitor); void unlockSoftwareForMonitor(SP pMonitor); + void lockSoftwareForMonitor(CMonitor* pMonitor); + void unlockSoftwareForMonitor(CMonitor* pMonitor); void lockSoftwareAll(); void unlockSoftwareAll(); From 6d21014a50d8e7863b1b25cb5ed19bb1fcba1583 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 19 Jun 2024 16:28:54 +0200 Subject: [PATCH 19/30] core: fix no-pch build --- src/plugins/PluginAPI.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/PluginAPI.hpp b/src/plugins/PluginAPI.hpp index 83db5f85..4dcf4ba5 100644 --- a/src/plugins/PluginAPI.hpp +++ b/src/plugins/PluginAPI.hpp @@ -29,6 +29,7 @@ Feel like the API is missing something you'd like to use in your plugin? Open an #include #include #include +#include typedef struct { std::string name; From 65f04f265c268d9752d6c2534c2b078d0e54a150 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Wed, 19 Jun 2024 18:36:50 +0300 Subject: [PATCH 20/30] flake.lock: update --- flake.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 94fc9d90..cb1f7875 100644 --- a/flake.lock +++ b/flake.lock @@ -13,11 +13,11 @@ ] }, "locked": { - "lastModified": 1718368322, - "narHash": "sha256-VfMg3RsnRLQzbq0hFIh1dCM09b5C/F/qPFUOgU/CRi0=", + "lastModified": 1718450675, + "narHash": "sha256-jpsns6buS4bK+1sF8sL8AaixAiCRjA+nldTKvcwmvUs=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "dd3a853c8239d1c3f3f37de7d2b8ae4b4f3840df", + "rev": "66d5b46ff94efbfa6fa3d1d1b66735f1779c34a6", "type": "github" }, "original": { @@ -38,11 +38,11 @@ ] }, "locked": { - "lastModified": 1691753796, - "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=", + "lastModified": 1714869498, + "narHash": "sha256-vbLVOWvQqo4n1yvkg/Q70VTlPbMmTiCQfNTgcWDCfJM=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03", + "rev": "e06482e0e611130cd1929f75e8c1cf679e57d161", "type": "github" }, "original": { @@ -87,11 +87,11 @@ ] }, "locked": { - "lastModified": 1718271409, - "narHash": "sha256-8KvVqtApNt4FWTdn1TqVvw00rpqyG9UuUPA2ilPVD1U=", + "lastModified": 1718804078, + "narHash": "sha256-CqRZne63BpYlPd/i8lXV0UInUt59oKogiwdVtBRHt60=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "8e10e0626fb26a14b859b3811b6ed7932400c86e", + "rev": "4f1351295c55a8f51219b25aa4a6497a067989d0", "type": "github" }, "original": { @@ -125,11 +125,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1718318537, - "narHash": "sha256-4Zu0RYRcAY/VWuu6awwq4opuiD//ahpc2aFHg2CWqFY=", + "lastModified": 1718530797, + "narHash": "sha256-pup6cYwtgvzDpvpSCFh1TEUjw2zkNpk8iolbKnyFmmU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e9ee548d90ff586a6471b4ae80ae9cfcbceb3420", + "rev": "b60ebf54c15553b393d144357375ea956f89e9a9", "type": "github" }, "original": { @@ -179,11 +179,11 @@ ] }, "locked": { - "lastModified": 1718272114, - "narHash": "sha256-KsX7sAwkEFpXiwyjt0HGTnnrUU58wW1jlzj5IA/LRz8=", + "lastModified": 1718619174, + "narHash": "sha256-FWW68AVYmB91ZDQnhLMBNCUUTCjb1ZpO2k2KIytHtkA=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "24be4a26f0706e456fca1b61b8c79f7486a9e86d", + "rev": "c7894aa54f9a7dbd16df5cd24d420c8af22d5623", "type": "github" }, "original": { From def5fcb2128304392e9e76bcc081d088b316a197 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 19 Jun 2024 18:25:20 +0200 Subject: [PATCH 21/30] damageRing: move to hyprland impl A small wlroots utility we were still using. --- src/helpers/DamageRing.cpp | 52 ++++++++++++++++++++++++++++++++++++++ src/helpers/DamageRing.hpp | 22 ++++++++++++++++ src/helpers/Monitor.cpp | 18 +++++-------- src/helpers/Monitor.hpp | 40 ++++++++++++++--------------- src/includes.hpp | 1 - src/render/Renderer.cpp | 16 +++++++----- 6 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 src/helpers/DamageRing.cpp create mode 100644 src/helpers/DamageRing.hpp diff --git a/src/helpers/DamageRing.cpp b/src/helpers/DamageRing.cpp new file mode 100644 index 00000000..093e7ca6 --- /dev/null +++ b/src/helpers/DamageRing.cpp @@ -0,0 +1,52 @@ +#include "DamageRing.hpp" + +void CDamageRing::setSize(const Vector2D& size_) { + if (size_ == size) + return; + + size = size_; + + damageEntire(); +} + +bool CDamageRing::damage(const CRegion& rg) { + CRegion clipped = rg.copy().intersect(CBox{{}, size}); + if (clipped.empty()) + return false; + + current.add(clipped); + return true; +} + +void CDamageRing::damageEntire() { + damage(CBox{{}, size}); +} + +void CDamageRing::rotate() { + previousIdx = (previousIdx + DAMAGE_RING_PREVIOUS_LEN - 1) % DAMAGE_RING_PREVIOUS_LEN; + + previous[previousIdx] = current; + current.clear(); +} + +CRegion CDamageRing::getBufferDamage(int age) { + if (age <= 0 || age > DAMAGE_RING_PREVIOUS_LEN + 1) + return CBox{{}, size}; + + CRegion damage = current; + + for (int i = 0; i < age - 1; ++i) { + int j = (previousIdx + i) % DAMAGE_RING_PREVIOUS_LEN; + damage.add(previous.at(j)); + } + + // don't return a ludicrous amount of rects + if (damage.getRects().size() > 8) + return damage.getExtents(); + + return damage; +} + +bool CDamageRing::hasChanged() { + return !current.empty(); +} diff --git a/src/helpers/DamageRing.hpp b/src/helpers/DamageRing.hpp new file mode 100644 index 00000000..ae85c453 --- /dev/null +++ b/src/helpers/DamageRing.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "./math/Math.hpp" +#include + +constexpr static int DAMAGE_RING_PREVIOUS_LEN = 2; + +class CDamageRing { + public: + void setSize(const Vector2D& size_); + bool damage(const CRegion& rg); + void damageEntire(); + void rotate(); + CRegion getBufferDamage(int age); + bool hasChanged(); + + private: + Vector2D size; + CRegion current; + std::array previous; + size_t previousIdx = 0; +}; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index e99e16ef..7ebd2539 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -17,12 +17,10 @@ int ratHandler(void* data) { } CMonitor::CMonitor() : state(this) { - wlr_damage_ring_init(&damage); + ; } CMonitor::~CMonitor() { - wlr_damage_ring_finish(&damage); - hyprListener_monitorDestroy.removeCallback(); hyprListener_monitorFrame.removeCallback(); hyprListener_monitorStateRequest.removeCallback(); @@ -162,7 +160,7 @@ void CMonitor::onConnect(bool noRule) { if (!state.commit()) Debug::log(WARN, "wlr_output_commit_state failed in CMonitor::onCommit"); - wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y); + damage.setSize(vecTransformedSize); Debug::log(LOG, "Added new monitor with name {} at {:j0} with size {:j0}, pointer {:x}", output->name, vecPosition, vecPixelSize, (uintptr_t)output); @@ -345,9 +343,9 @@ void CMonitor::onDisconnect(bool destroy) { void CMonitor::addDamage(const pixman_region32_t* rg) { static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) { - wlr_damage_ring_add_whole(&damage); + damage.damageEntire(); g_pCompositor->scheduleFrameForMonitor(this); - } else if (wlr_damage_ring_add(&damage, rg)) + } else if (damage.damage(rg)) g_pCompositor->scheduleFrameForMonitor(this); } @@ -358,13 +356,11 @@ void CMonitor::addDamage(const CRegion* rg) { void CMonitor::addDamage(const CBox* box) { static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) { - wlr_damage_ring_add_whole(&damage); + damage.damageEntire(); g_pCompositor->scheduleFrameForMonitor(this); } - wlr_box damageBox = {(int)box->x, (int)box->y, (int)box->w, (int)box->h}; - - if (wlr_damage_ring_add_box(&damage, &damageBox)) + if (damage.damage(*box)) g_pCompositor->scheduleFrameForMonitor(this); } @@ -379,7 +375,7 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() { // keep requested minimum refresh rate if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) { // damage whole screen because some previous cursor box damages were skipped - wlr_damage_ring_add_whole(&damage); + damage.damageEntire(); return false; } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index b8902197..8a2acdaf 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -11,6 +11,7 @@ #include "math/Math.hpp" #include #include "signal/Signal.hpp" +#include "DamageRing.hpp" // Enum for the different types of auto directions, e.g. auto-left, auto-up. enum eAutoDirs { @@ -60,33 +61,32 @@ class CMonitor { CMonitor(); ~CMonitor(); - Vector2D vecPosition = Vector2D(-1, -1); // means unset - Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset - Vector2D vecSize = Vector2D(0, 0); - Vector2D vecPixelSize = Vector2D(0, 0); - Vector2D vecTransformedSize = Vector2D(0, 0); + Vector2D vecPosition = Vector2D(-1, -1); // means unset + Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset + Vector2D vecSize = Vector2D(0, 0); + Vector2D vecPixelSize = Vector2D(0, 0); + Vector2D vecTransformedSize = Vector2D(0, 0); - bool primary = false; + bool primary = false; - uint64_t ID = -1; - PHLWORKSPACE activeWorkspace = nullptr; - PHLWORKSPACE activeSpecialWorkspace = nullptr; - float setScale = 1; // scale set by cfg - float scale = 1; // real scale + uint64_t ID = -1; + PHLWORKSPACE activeWorkspace = nullptr; + PHLWORKSPACE activeSpecialWorkspace = nullptr; + float setScale = 1; // scale set by cfg + float scale = 1; // real scale - std::string szName = ""; - std::string szDescription = ""; - std::string szShortDescription = ""; + std::string szName = ""; + std::string szDescription = ""; + std::string szShortDescription = ""; - Vector2D vecReservedTopLeft = Vector2D(0, 0); - Vector2D vecReservedBottomRight = Vector2D(0, 0); + Vector2D vecReservedTopLeft = Vector2D(0, 0); + Vector2D vecReservedBottomRight = Vector2D(0, 0); - drmModeModeInfo customDrmMode = {}; + drmModeModeInfo customDrmMode = {}; - CMonitorState state; + CMonitorState state; + CDamageRing damage; - // WLR stuff - wlr_damage_ring damage; wlr_output* output = nullptr; float refreshRate = 60; int framesToSkip = 0; diff --git a/src/includes.hpp b/src/includes.hpp index 87bd21f8..afec078a 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -53,7 +53,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d44f4cd5..b783ab81 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1246,7 +1246,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { clock_gettime(CLOCK_MONOTONIC, &now); // check the damage - bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current); + bool hasChanged = pMonitor->output->needs_frame || pMonitor->damage.hasChanged(); if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0) return; @@ -1414,7 +1414,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { pMonitor->state.wlr()->tearing_page_flip = shouldTear; if (!pMonitor->state.commit()) { - wlr_damage_ring_add_whole(&pMonitor->damage); + pMonitor->damage.damageEntire(); return; } @@ -2245,7 +2245,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR // updato wlroots g_pCompositor->arrangeMonitors(); - wlr_damage_ring_set_bounds(&pMonitor->damage, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); + pMonitor->damage.setSize(pMonitor->vecTransformedSize); // Set scale for all surfaces on this monitor, needed for some clients // but not on unsafe state to avoid crashes @@ -2609,13 +2609,15 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode return true; } + int bufferAge = 0; + if (!buffer) { if (!wlr_output_configure_primary_swapchain(pMonitor->output, pMonitor->state.wlr(), &pMonitor->output->swapchain)) { Debug::log(ERR, "Failed to configure primary swapchain for {}", pMonitor->szName); return false; } - m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, nullptr); + m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, &bufferAge); if (!m_pCurrentWlrBuffer) { Debug::log(ERR, "Failed to acquire swapchain buffer for {}", pMonitor->szName); return false; @@ -2634,8 +2636,10 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode return false; } - if (mode == RENDER_MODE_NORMAL) - wlr_damage_ring_rotate_buffer(&pMonitor->damage, m_pCurrentWlrBuffer, damage.pixman()); + if (mode == RENDER_MODE_NORMAL) { + damage = pMonitor->damage.getBufferDamage(bufferAge); + pMonitor->damage.rotate(); + } m_pCurrentRenderbuffer->bind(); if (simple) From c1e21719a2fff2fa9549f00053ac40173da54af9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 19 Jun 2024 18:36:40 +0200 Subject: [PATCH 22/30] core: avoid bumping hard rlimits, restore on fork ref #6584 --- src/Compositor.cpp | 63 ++++++++++++++------------------- src/Compositor.hpp | 8 +++-- src/managers/KeybindManager.cpp | 1 + 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 7777a55f..7a1d035d 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -71,44 +71,35 @@ void handleUserSignal(int sig) { } } -static void bumpNofile() { - unsigned long limit = 1024; - - try { - std::ifstream f("/proc/sys/fs/nr_open"); - if (!f.good()) - limit = 1073741816; - else { - std::string content((std::istreambuf_iterator(f)), (std::istreambuf_iterator())); - f.close(); - - limit = std::stoll(content); - } - - } catch (...) { limit = 1073741816; } - - struct rlimit rlimit_; - if (!getrlimit(RLIMIT_NOFILE, &rlimit_)) - Debug::log(LOG, "Old rlimit: soft -> {}, hard -> {}", rlimit_.rlim_cur, rlimit_.rlim_max); - - if (rlimit_.rlim_max <= 1024) - rlimit_.rlim_max = limit; - - unsigned long oldHardLimit = rlimit_.rlim_max; - - rlimit_.rlim_max = limit; - - if (setrlimit(RLIMIT_NOFILE, &rlimit_) < 0) { - Debug::log(LOG, "Failed bumping NOFILE limits higher, retrying with previous hard."); - rlimit_.rlim_max = oldHardLimit; - rlimit_.rlim_cur = std::clamp((unsigned long)limit, 1UL, (unsigned long)rlimit_.rlim_max); - - if (setrlimit(RLIMIT_NOFILE, &rlimit_) < 0) - Debug::log(LOG, "Failed bumping NOFILE limits higher for the second time."); +void CCompositor::bumpNofile() { + if (!getrlimit(RLIMIT_NOFILE, &m_sOriginalNofile)) + Debug::log(LOG, "Old rlimit: soft -> {}, hard -> {}", m_sOriginalNofile.rlim_cur, m_sOriginalNofile.rlim_max); + else { + Debug::log(ERR, "Failed to get NOFILE rlimits"); + m_sOriginalNofile.rlim_max = 0; + return; } - if (!getrlimit(RLIMIT_NOFILE, &rlimit_)) - Debug::log(LOG, "New rlimit: soft -> {}, hard -> {}", rlimit_.rlim_cur, rlimit_.rlim_max); + rlimit newLimit = m_sOriginalNofile; + + newLimit.rlim_cur = newLimit.rlim_max; + + if (setrlimit(RLIMIT_NOFILE, &newLimit) < 0) { + Debug::log(ERR, "Failed bumping NOFILE limits higher"); + m_sOriginalNofile.rlim_max = 0; + return; + } + + if (!getrlimit(RLIMIT_NOFILE, &newLimit)) + Debug::log(LOG, "New rlimit: soft -> {}, hard -> {}", newLimit.rlim_cur, newLimit.rlim_max); +} + +void CCompositor::restoreNofile() { + if (m_sOriginalNofile.rlim_max <= 0) + return; + + if (setrlimit(RLIMIT_NOFILE, &m_sOriginalNofile) < 0) + Debug::log(ERR, "Failed restoring NOFILE limits"); } CCompositor::CCompositor() { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 242c3b13..5a1d8a64 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "defines.hpp" #include "debug/Log.hpp" @@ -81,6 +82,8 @@ class CCompositor { void cleanup(); void createLockFile(); void removeLockFile(); + void bumpNofile(); + void restoreNofile(); WP m_pLastFocus; PHLWINDOWREF m_pLastWindow; @@ -190,8 +193,9 @@ class CCompositor { void initManagers(eManagersInitStage stage); void prepareFallbackOutput(); - uint64_t m_iHyprlandPID = 0; - wl_event_source* m_critSigSource = nullptr; + uint64_t m_iHyprlandPID = 0; + wl_event_source* m_critSigSource = nullptr; + rlimit m_sOriginalNofile = {0}; }; inline std::unique_ptr g_pCompositor; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 875ba239..80af767c 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -890,6 +890,7 @@ uint64_t CKeybindManager::spawnRaw(std::string args) { } if (child == 0) { // run in child + g_pCompositor->restoreNofile(); sigset_t set; sigemptyset(&set); From d6de248b0d434a382a7036ff04b3f9b367668cb0 Mon Sep 17 00:00:00 2001 From: Przegryw321 <65826466+Przegryw321@users.noreply.github.com> Date: Wed, 19 Jun 2024 23:19:18 +0200 Subject: [PATCH 23/30] window: expose pseudotiled state and add param to dispatcher (#6583) * Show pseudotiled state of window in hyprctl clients * Add a window as an optional argument for the pseudo dispatcher * change formatting --- src/debug/HyprCtl.cpp | 31 ++++++++++++++++--------------- src/managers/KeybindManager.cpp | 16 +++++++++++----- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index e212ed1c..b0a0c477 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -210,6 +210,7 @@ static std::string getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { "name": "{}" }}, "floating": {}, + "pseudo": {}, "monitor": {}, "class": "{}", "title": "{}", @@ -228,22 +229,22 @@ static std::string getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { }},)#", (uintptr_t)w.get(), (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, - escapeJSONStrings(!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), ((int)w->m_bIsFloating == 1 ? "true" : "false"), (int64_t)w->m_iMonitorID, - escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass), escapeJSONStrings(w->m_szInitialTitle), w->getPID(), - ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"), (w->m_bIsFullscreen ? "true" : "false"), - (w->m_bIsFullscreen ? (w->m_pWorkspace ? (int)w->m_pWorkspace->m_efFullscreenMode : 0) : 0), w->m_bFakeFullscreenState ? "true" : "false", getGroupedData(w, format), - getTagsData(w, format), (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w)); + escapeJSONStrings(!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), ((int)w->m_bIsFloating == 1 ? "true" : "false"), (w->m_bIsPseudotiled ? "true" : "false"), + (int64_t)w->m_iMonitorID, escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass), + escapeJSONStrings(w->m_szInitialTitle), w->getPID(), ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"), + (w->m_bIsFullscreen ? "true" : "false"), (w->m_bIsFullscreen ? (w->m_pWorkspace ? (int)w->m_pWorkspace->m_efFullscreenMode : 0) : 0), + w->m_bFakeFullscreenState ? "true" : "false", getGroupedData(w, format), getTagsData(w, format), (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w)); } else { - return std::format("Window {:x} -> {}:\n\tmapped: {}\n\thidden: {}\n\tat: {},{}\n\tsize: {},{}\n\tworkspace: {} ({})\n\tfloating: {}\n\tmonitor: {}\n\tclass: {}\n\ttitle: " - "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " - "{}\n\txwayland: {}\n\tpinned: " - "{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n", - (uintptr_t)w.get(), w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, - (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, - (!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), (int)w->m_bIsFloating, (int64_t)w->m_iMonitorID, w->m_szClass, w->m_szTitle, w->m_szInitialClass, - w->m_szInitialTitle, w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, - (w->m_bIsFullscreen ? (w->m_pWorkspace ? w->m_pWorkspace->m_efFullscreenMode : 0) : 0), (int)w->m_bFakeFullscreenState, getGroupedData(w, format), - getTagsData(w, format), (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w)); + return std::format( + "Window {:x} -> {}:\n\tmapped: {}\n\thidden: {}\n\tat: {},{}\n\tsize: {},{}\n\tworkspace: {} ({})\n\tfloating: {}\n\tpseudo: {}\n\tmonitor: {}\n\tclass: {}\n\ttitle: " + "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " + "{}\n\txwayland: {}\n\tpinned: " + "{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n", + (uintptr_t)w.get(), w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, + (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, (!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), + (int)w->m_bIsFloating, (int)w->m_bIsPseudotiled, (int64_t)w->m_iMonitorID, w->m_szClass, w->m_szTitle, w->m_szInitialClass, w->m_szInitialTitle, w->getPID(), + (int)w->m_bIsX11, (int)w->m_bPinned, (int)w->m_bIsFullscreen, (w->m_bIsFullscreen ? (w->m_pWorkspace ? w->m_pWorkspace->m_efFullscreenMode : 0) : 0), + (int)w->m_bFakeFullscreenState, getGroupedData(w, format), getTagsData(w, format), (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w)); } } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 80af767c..e5db8918 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -5,6 +5,7 @@ #include "../protocols/ShortcutsInhibit.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "KeybindManager.hpp" +#include "Compositor.hpp" #include "TokenManager.hpp" #include "debug/Log.hpp" #include "helpers/varlist/VarList.hpp" @@ -1017,15 +1018,20 @@ void CKeybindManager::centerWindow(std::string args) { } void CKeybindManager::toggleActivePseudo(std::string args) { - const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow.lock(); + PHLWINDOW PWINDOW = nullptr; - if (!ACTIVEWINDOW) + if (args != "active" && args.length() > 1) + PWINDOW = g_pCompositor->getWindowByRegex(args); + else + PWINDOW = g_pCompositor->m_pLastWindow.lock(); + + if (!PWINDOW) return; - ACTIVEWINDOW->m_bIsPseudotiled = !ACTIVEWINDOW->m_bIsPseudotiled; + PWINDOW->m_bIsPseudotiled = !PWINDOW->m_bIsPseudotiled; - if (!ACTIVEWINDOW->m_bIsFullscreen) - g_pLayoutManager->getCurrentLayout()->recalculateWindow(ACTIVEWINDOW); + if (!PWINDOW->m_bIsFullscreen) + g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW); } void CKeybindManager::changeworkspace(std::string args) { From fabc30df52ab5d2c369fc8acd4ff909a6ba3b8ac Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 20 Jun 2024 00:15:18 +0200 Subject: [PATCH 24/30] format: include macros for unreachable --- src/helpers/Format.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/helpers/Format.cpp b/src/helpers/Format.cpp index 08c3ca63..5251002c 100644 --- a/src/helpers/Format.cpp +++ b/src/helpers/Format.cpp @@ -2,6 +2,7 @@ #include #include "../includes.hpp" #include "debug/Log.hpp" +#include "../macros.hpp" /* DRM formats are LE, while OGL is BE. The two primary formats From 8cf2ca196620bc4431cbab83bfa25314e1e80ad7 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 21 Jun 2024 15:56:25 +0200 Subject: [PATCH 25/30] math: include cstring for memset fixup name too --- src/helpers/math/Math.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/helpers/math/Math.cpp b/src/helpers/math/Math.cpp index df4f1bb5..560f29c9 100644 --- a/src/helpers/math/Math.cpp +++ b/src/helpers/math/Math.cpp @@ -1,5 +1,6 @@ #include "Math.hpp" #include +#include Hyprutils::Math::eTransform wlTransformToHyprutils(wl_output_transform t) { switch (t) { @@ -52,21 +53,21 @@ static void matrixTranslate(float mat[9], float x, float y) { float translate[9] = { 1.0f, 0.0f, x, 0.0f, 1.0f, y, 0.0f, 0.0f, 1.0f, }; - wlr_matrix_multiply(mat, mat, translate); + matrixMultiply(mat, mat, translate); } static void matrixScale(float mat[9], float x, float y) { float scale[9] = { x, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 1.0f, }; - wlr_matrix_multiply(mat, mat, scale); + matrixMultiply(mat, mat, scale); } static void matrixRotate(float mat[9], float rad) { float rotate[9] = { cos(rad), -sin(rad), 0.0f, sin(rad), cos(rad), 0.0f, 0.0f, 0.0f, 1.0f, }; - wlr_matrix_multiply(mat, mat, rotate); + matrixMultiply(mat, mat, rotate); } static std::unordered_map> transforms = { @@ -208,7 +209,7 @@ void projectBox(float mat[9], CBox& box, eTransform transform, float rotation, c matrixTranslate(mat, -width / 2, -height / 2); } - wlr_matrix_scale(mat, width, height); + matrixScale(mat, width, height); if (transform != HYPRUTILS_TRANSFORM_NORMAL) { matrixTranslate(mat, 0.5, 0.5); From 4a8b13ea4f8e5111390471c9212d10d4d032e837 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 21 Jun 2024 19:25:34 +0200 Subject: [PATCH 26/30] renderer: shrink occlusion rect if blur is used if we are blurring, we cannot be sure whether the occluded region won't be included in the expanded damage. If it is, we'd get dark shimmers. fixes #6547 --- src/render/Renderer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b783ab81..4fc751ff 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2451,9 +2451,14 @@ void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, PHLWORKSPACE pW } void CHyprRenderer::setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWorkspace) { - CRegion rg; + CRegion rg; - const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); + const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); + + static auto PBLUR = CConfigValue("decoration:blur:enabled"); + static auto PBLURSIZE = CConfigValue("decoration:blur:size"); + static auto PBLURPASSES = CConfigValue("decoration:blur:passes"); + const auto BLURRADIUS = *PBLUR ? (*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES)) : 0; for (auto& w : g_pCompositor->m_vWindows) { if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != pWorkspace) @@ -2468,7 +2473,8 @@ void CHyprRenderer::setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWork CBox box = {POS.x, POS.y, SIZE.x, SIZE.y}; - box.scale(PMONITOR->scale); + box.scale(PMONITOR->scale).expand(-BLURRADIUS); + g_pHyprOpenGL->m_RenderData.renderModif.applyToBox(box); rg.add(box); From fa022901cf2c9acdae9e9a24a68b9148d44f8627 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 22 Jun 2024 00:40:45 +0200 Subject: [PATCH 27/30] surface: add virtual destructor to surfacerole to avoid undefined behaviour (#6620) * surfacerole: add virtual destructor all classes that will be derived from should have a virtual destructor otherwise deleting an instance via pointer to a base class is undefined behaviour, layershell/xdgshell hits this with std::default_delete in the new sharedptr implentation. * includes: fix missing includes fix missing includes for no precompiled headers builds, and remove a redefiniton of a macro already defined in macros.hpp --- src/managers/CursorManager.hpp | 1 + src/protocols/types/SurfaceRole.hpp | 1 + src/xwayland/XSurface.hpp | 1 + src/xwayland/XWM.hpp | 1 + src/xwayland/XWayland.hpp | 5 ++--- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index f983efbb..3ee98ca6 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -5,6 +5,7 @@ #include #include "../includes.hpp" #include "../helpers/math/Math.hpp" +#include "../helpers/memory/Memory.hpp" struct wlr_buffer; struct wlr_xcursor_manager; diff --git a/src/protocols/types/SurfaceRole.hpp b/src/protocols/types/SurfaceRole.hpp index 05c0ea66..faaf70ee 100644 --- a/src/protocols/types/SurfaceRole.hpp +++ b/src/protocols/types/SurfaceRole.hpp @@ -11,4 +11,5 @@ enum eSurfaceRole { class ISurfaceRole { public: virtual eSurfaceRole role() = 0; + virtual ~ISurfaceRole() = default; }; diff --git a/src/xwayland/XSurface.hpp b/src/xwayland/XSurface.hpp index 4e31e88d..61eee984 100644 --- a/src/xwayland/XSurface.hpp +++ b/src/xwayland/XSurface.hpp @@ -2,6 +2,7 @@ #include "../helpers/WLListener.hpp" #include "../helpers/signal/Signal.hpp" +#include "../helpers/memory/Memory.hpp" #include "../helpers/math/Math.hpp" #include diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index 6456c71b..88606416 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -1,6 +1,7 @@ #pragma once #include "../helpers/signal/Signal.hpp" +#include "../helpers/memory/Memory.hpp" #include "../helpers/WLListener.hpp" #include "../macros.hpp" diff --git a/src/xwayland/XWayland.hpp b/src/xwayland/XWayland.hpp index c7981251..d1cc4421 100644 --- a/src/xwayland/XWayland.hpp +++ b/src/xwayland/XWayland.hpp @@ -2,6 +2,7 @@ #include #include "../helpers/signal/Signal.hpp" +#include "../helpers/memory/Memory.hpp" #include "XSurface.hpp" @@ -29,10 +30,8 @@ class CXWayland { } events; }; -inline std::unique_ptr g_pXWayland; +inline std::unique_ptr g_pXWayland; -#define HYPRATOM(name) \ - { name, 0 } inline std::unordered_map HYPRATOMS = { HYPRATOM("_NET_SUPPORTED"), HYPRATOM("_NET_SUPPORTING_WM_CHECK"), From 4778afe2e6b4a6f8c7d218ccd8fe7e0bd4d2ee9c Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:41:23 -0500 Subject: [PATCH 28/30] hyprctl: make recv timeout bigger and give error message if it does timeout (#6621) --- hyprctl/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index f5de041b..2bd325e3 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -141,7 +141,7 @@ int rollingRead(const int socket) { int request(std::string arg, int minArgs = 0, bool needRoll = false) { const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0); - auto t = timeval{.tv_sec = 0, .tv_usec = 100000}; + auto t = timeval{.tv_sec = 1, .tv_usec = 0}; setsockopt(SERVERSOCKET, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(struct timeval)); const auto ARGS = std::count(arg.begin(), arg.end(), ' '); @@ -191,6 +191,8 @@ int request(std::string arg, int minArgs = 0, bool needRoll = false) { sizeWritten = read(SERVERSOCKET, buffer, 8192); if (sizeWritten < 0) { + if (errno == EWOULDBLOCK) + log("Hyprland IPC didn't respond in time\n"); log("Couldn't read (5)"); return 5; } From 0b924f541c744f96d32c9a0d98dcfd90205bab4c Mon Sep 17 00:00:00 2001 From: MariuszTrybus Date: Sat, 22 Jun 2024 17:05:05 +0200 Subject: [PATCH 29/30] constraints: Lock surface region when region is empty (#6627) * Pointer constraints: Lock surface region when region is empty * Format code --- src/protocols/PointerConstraints.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp index c7b78a5b..a17fa6cd 100644 --- a/src/protocols/PointerConstraints.cpp +++ b/src/protocols/PointerConstraints.cpp @@ -165,8 +165,15 @@ SP CPointerConstraint::owner() { } CRegion CPointerConstraint::logicConstraintRegion() { - CRegion rg = region; - const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal(); + CRegion rg = region; + const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal(); + + // if region wasn't set in pointer-constraints request take surface region + if (rg.empty() && SURFBOX.has_value()) { + rg.set(SURFBOX.value()); + return rg; + } + const auto CONSTRAINTPOS = SURFBOX.has_value() ? SURFBOX->pos() : Vector2D{}; rg.translate(CONSTRAINTPOS); return rg; From 7f09646ab8b5b6d9f835681d0af5d7a0dc29d8f1 Mon Sep 17 00:00:00 2001 From: Alexander <51529891+Truenya@users.noreply.github.com> Date: Sun, 23 Jun 2024 00:52:42 +0300 Subject: [PATCH 30/30] core: add ability to select previous workspace per monitor (#6598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Крылов Александр --- src/Compositor.cpp | 3 +- src/config/ConfigManager.cpp | 13 +++-- src/desktop/Workspace.cpp | 20 ++++++-- src/desktop/Workspace.hpp | 34 ++++++------- src/events/Windows.cpp | 3 +- src/helpers/MiscFunctions.cpp | 90 ++++++++++++++++----------------- src/helpers/MiscFunctions.hpp | 9 +++- src/helpers/Monitor.cpp | 25 +++++---- src/macros.hpp | 3 +- src/managers/KeybindManager.cpp | 88 +++++++++++++++----------------- src/managers/input/Swipe.cpp | 12 ++--- 11 files changed, 154 insertions(+), 146 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 7a1d035d..c607dfb6 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1648,8 +1648,7 @@ PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) { } try { - std::string name = ""; - return getWorkspaceByID(getWorkspaceIDFromString(str, name)); + return getWorkspaceByID(getWorkspaceIDNameFromString(str).id); } catch (std::exception& e) { Debug::log(ERR, "Error in getWorkspaceByString, invalid id"); } return nullptr; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 17bbe465..6a1c896c 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1815,14 +1815,13 @@ std::optional CConfigManager::handleMonitor(const std::string& comm newrule.vrr = std::stoi(ARGS[argno + 1]); argno++; } else if (ARGS[argno] == "workspace") { - std::string name = ""; - int wsId = getWorkspaceIDFromString(ARGS[argno + 1], name); + const auto& [id, name] = getWorkspaceIDNameFromString(ARGS[argno + 1]); SWorkspaceRule wsRule; wsRule.monitor = newrule.name; wsRule.workspaceString = ARGS[argno + 1]; + wsRule.workspaceId = id; wsRule.workspaceName = name; - wsRule.workspaceId = wsId; m_dWorkspaceRules.emplace_back(wsRule); argno++; @@ -2370,11 +2369,11 @@ std::optional CConfigManager::handleBlurLS(const std::string& comma std::optional CConfigManager::handleWorkspaceRules(const std::string& command, const std::string& value) { // This can either be the monitor or the workspace identifier - const auto FIRST_DELIM = value.find_first_of(','); + const auto FIRST_DELIM = value.find_first_of(','); - std::string name = ""; - auto first_ident = trim(value.substr(0, FIRST_DELIM)); - int id = getWorkspaceIDFromString(first_ident, name); + auto first_ident = trim(value.substr(0, FIRST_DELIM)); + + const auto& [id, name] = getWorkspaceIDNameFromString(first_ident); auto rules = value.substr(FIRST_DELIM + 1); SWorkspaceRule wsRule; diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 04685bd5..34db914e 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -57,6 +57,13 @@ void CWorkspace::init(PHLWORKSPACE self) { EMIT_HOOK_EVENT("createWorkspace", this); } +SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const { + if (perMonitor) + return m_sPrevWorkspacePerMonitor; + + return m_sPrevWorkspace; +} + CWorkspace::~CWorkspace() { m_vRenderOffset.unregister(); @@ -196,7 +203,7 @@ PHLWINDOW CWorkspace::getLastFocusedWindow() { void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) { if (!prev) { - m_sPrevWorkspace.iID = -1; + m_sPrevWorkspace.id = -1; m_sPrevWorkspace.name = ""; return; } @@ -206,8 +213,13 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) { return; } - m_sPrevWorkspace.iID = prev->m_iID; + m_sPrevWorkspace.id = prev->m_iID; m_sPrevWorkspace.name = prev->m_szName; + + if (prev->m_iMonitorID == m_iMonitorID) { + m_sPrevWorkspacePerMonitor.id = prev->m_iID; + m_sPrevWorkspacePerMonitor.name = prev->m_szName; + } } std::string CWorkspace::getConfigName() { @@ -228,9 +240,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { return true; if (isNumber(selector)) { - - std::string wsname = ""; - int wsid = getWorkspaceIDFromString(selector, wsname); + const auto& [wsid, wsname] = getWorkspaceIDNameFromString(selector); if (wsid == WORKSPACE_INVALID) return false; diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 17431215..ab3907aa 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -4,6 +4,7 @@ #include #include "../defines.hpp" #include "DesktopTypes.hpp" +#include "helpers/MiscFunctions.hpp" enum eFullscreenMode : int8_t { FULLSCREEN_INVALID = -1, @@ -25,17 +26,14 @@ class CWorkspace { int m_iID = -1; std::string m_szName = ""; uint64_t m_iMonitorID = -1; - // Previous workspace ID is stored during a workspace change, allowing travel + // Previous workspace ID and name is stored during a workspace change, allowing travel // to the previous workspace. - struct SPrevWorkspaceData { - int iID = -1; - std::string name = ""; - } m_sPrevWorkspace; + SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor; - bool m_bHasFullscreenWindow = false; - eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL; + bool m_bHasFullscreenWindow = false; + eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL; - wl_array m_wlrCoordinateArr; + wl_array m_wlrCoordinateArr; // for animations CAnimatedVariable m_vRenderOffset; @@ -63,21 +61,23 @@ class CWorkspace { bool m_bPersistent = false; // Inert: destroyed and invalid. If this is true, release the ptr you have. - bool inert(); + bool inert(); - void startAnim(bool in, bool left, bool instant = false); - void setActive(bool on); + void startAnim(bool in, bool left, bool instant = false); + void setActive(bool on); - void moveToMonitor(const int&); + void moveToMonitor(const int&); - PHLWINDOW getLastFocusedWindow(); - void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); + PHLWINDOW getLastFocusedWindow(); + void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); - std::string getConfigName(); + std::string getConfigName(); - bool matchesStaticSelector(const std::string& selector); + bool matchesStaticSelector(const std::string& selector); - void markInert(); + void markInert(); + + SWorkspaceIDName getPrevWorkspaceIDName(bool perMonitor) const; private: void init(PHLWORKSPACE self); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index d37ba12b..bb1197e5 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -293,8 +293,7 @@ void Events::listener_mapWindow(void* owner, void* data) { if (WORKSPACEARGS[WORKSPACEARGS.size() - 1].starts_with("silent")) workspaceSilent = true; - std::string requestedWorkspaceName; - const int REQUESTEDWORKSPACEID = getWorkspaceIDFromString(WORKSPACEARGS.join(" ", 0, workspaceSilent ? WORKSPACEARGS.size() - 1 : 0), requestedWorkspaceName); + const auto& [REQUESTEDWORKSPACEID, requestedWorkspaceName] = getWorkspaceIDNameFromString(WORKSPACEARGS.join(" ", 0, workspaceSilent ? WORKSPACEARGS.size() - 1 : 0)); if (REQUESTEDWORKSPACEID != WORKSPACE_INVALID) { auto pWorkspace = g_pCompositor->getWorkspaceByID(REQUESTEDWORKSPACEID); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 654ccf35..aa034254 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -214,37 +214,36 @@ bool isDirection(const char& arg) { return arg == 'l' || arg == 'r' || arg == 'u' || arg == 'd' || arg == 't' || arg == 'b'; } -int getWorkspaceIDFromString(const std::string& in, std::string& outName) { - int result = WORKSPACE_INVALID; +SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + SWorkspaceIDName result = {WORKSPACE_INVALID, ""}; + if (in.starts_with("special")) { - outName = "special:special"; + result.name = "special:special"; if (in.length() > 8) { const auto NAME = in.substr(8); + const auto WS = g_pCompositor->getWorkspaceByName("special:" + NAME); - const auto WS = g_pCompositor->getWorkspaceByName("special:" + NAME); - - outName = "special:" + NAME; - - return WS ? WS->m_iID : g_pCompositor->getNewSpecialID(); + return {WS ? WS->m_iID : g_pCompositor->getNewSpecialID(), "special:" + NAME}; } - return SPECIAL_WORKSPACE_START; + result.id = SPECIAL_WORKSPACE_START; + return result; } else if (in.starts_with("name:")) { const auto WORKSPACENAME = in.substr(in.find_first_of(':') + 1); const auto WORKSPACE = g_pCompositor->getWorkspaceByName(WORKSPACENAME); if (!WORKSPACE) { - result = g_pCompositor->getNextAvailableNamedWorkspace(); + result.id = g_pCompositor->getNextAvailableNamedWorkspace(); } else { - result = WORKSPACE->m_iID; + result.id = WORKSPACE->m_iID; } - outName = WORKSPACENAME; + result.name = WORKSPACENAME; } else if (in.starts_with("empty")) { const bool same_mon = in.substr(5).contains("m"); const bool next = in.substr(5).contains("n"); if ((same_mon || next) && !g_pCompositor->m_pLastMonitor) { Debug::log(ERR, "Empty monitor workspace on monitor null!"); - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; } std::set invalidWSes; @@ -259,41 +258,42 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { int id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0; while (++id < INT_MAX) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id); - if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) - return id; + if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) { + result.id = id; + return result; + } } } else if (in.starts_with("prev")) { if (!g_pCompositor->m_pLastMonitor) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace; if (!valid(PWORKSPACE)) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; - const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.iID); + const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.id); if (!PLASTWORKSPACE) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; - outName = PLASTWORKSPACE->m_szName; - return PLASTWORKSPACE->m_iID; + return {PLASTWORKSPACE->m_iID, PLASTWORKSPACE->m_szName}; } else { if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) { bool absolute = in[1] == '~'; if (!g_pCompositor->m_pLastMonitor) { Debug::log(ERR, "Relative monitor workspace on monitor null!"); - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; } const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in.substr(absolute ? 2 : 1), 0); if (!PLUSMINUSRESULT.has_value()) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; - result = (int)PLUSMINUSRESULT.value(); + result.id = (int)PLUSMINUSRESULT.value(); - int remains = (int)result; + int remains = (int)result.id; std::set invalidWSes; @@ -330,13 +330,13 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { // traverse valid workspaces until we reach the remains if ((size_t)remains < namedWSes.size()) { - result = namedWSes[remains]; + result.id = namedWSes[remains]; } else { remains -= namedWSes.size(); - result = 0; + result.id = 0; while (remains >= 0) { - result++; - if (!invalidWSes.contains(result)) { + result.id++; + if (!invalidWSes.contains(result.id)) { remains--; } } @@ -430,14 +430,14 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { finalWSID = curID; } } - result = finalWSID; + result.id = finalWSID; } - const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(result); + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(result.id); if (PWORKSPACE) - outName = g_pCompositor->getWorkspaceByID(result)->m_szName; + result.name = g_pCompositor->getWorkspaceByID(result.id)->m_szName; else - outName = std::to_string(result); + result.name = std::to_string(result.id); } else if ((in[0] == 'm' || in[0] == 'e') && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) { bool onAllMonitors = in[0] == 'e'; @@ -445,19 +445,19 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { if (!g_pCompositor->m_pLastMonitor) { Debug::log(ERR, "Relative monitor workspace on monitor null!"); - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; } // monitor relative const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in.substr(absolute ? 2 : 1), 0); if (!PLUSMINUSRESULT.has_value()) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; - result = (int)PLUSMINUSRESULT.value(); + result.id = (int)PLUSMINUSRESULT.value(); // result now has +/- what we should move on mon - int remains = (int)result; + int remains = (int)result.id; std::vector validWSes; for (auto& ws : g_pCompositor->m_vWorkspaces) { @@ -505,30 +505,30 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { } } - result = validWSes[currentItem]; - outName = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_szName; + result.id = validWSes[currentItem]; + result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_szName; } else { if (in[0] == '+' || in[0] == '-') { if (g_pCompositor->m_pLastMonitor) { const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspaceID()); if (!PLUSMINUSRESULT.has_value()) - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; - result = std::max((int)PLUSMINUSRESULT.value(), 1); + result.id = std::max((int)PLUSMINUSRESULT.value(), 1); } else { Debug::log(ERR, "Relative workspace on no mon!"); - return WORKSPACE_INVALID; + return {WORKSPACE_INVALID}; } } else if (isNumber(in)) - result = std::max(std::stoi(in), 1); + result.id = std::max(std::stoi(in), 1); else { // maybe name const auto PWORKSPACE = g_pCompositor->getWorkspaceByName(in); if (PWORKSPACE) - result = PWORKSPACE->m_iID; + result.id = PWORKSPACE->m_iID; } - outName = std::to_string(result); + result.name = std::to_string(result.id); } } diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index 111abba0..33be7965 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -13,13 +13,18 @@ struct SCallstackFrameInfo { std::string desc; }; +struct SWorkspaceIDName { + int id = -1; + std::string name; +}; + std::string absolutePath(const std::string&, const std::string&); void addWLSignal(wl_signal*, wl_listener*, void* pOwner, const std::string& ownerString); void removeWLSignal(wl_listener*); std::string escapeJSONStrings(const std::string& str); bool isDirection(const std::string&); bool isDirection(const char&); -int getWorkspaceIDFromString(const std::string&, std::string&); +SWorkspaceIDName getWorkspaceIDNameFromString(const std::string&); std::optional cleanCmdForWorkspace(const std::string&, std::string); float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2); void logSystemInfo(); @@ -42,4 +47,4 @@ template // because any suck format specifier will cause a compilation error // this is actually what std::format in stdlib does return std::vformat(fmt.get(), std::make_format_args(args...)); -} \ No newline at end of file +} diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 7ebd2539..199b1c5d 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -415,20 +415,25 @@ int CMonitor::findAvailableDefaultWS() { void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { // Workspace std::string newDefaultWorkspaceName = ""; - int64_t WORKSPACEID = g_pConfigManager->getDefaultWorkspaceFor(szName).empty() ? - findAvailableDefaultWS() : - getWorkspaceIDFromString(g_pConfigManager->getDefaultWorkspaceFor(szName), newDefaultWorkspaceName); + int64_t wsID = WORKSPACE_INVALID; + if (g_pConfigManager->getDefaultWorkspaceFor(szName).empty()) + wsID = findAvailableDefaultWS(); + else { + const auto ws = getWorkspaceIDNameFromString(g_pConfigManager->getDefaultWorkspaceFor(szName)); + wsID = ws.id; + newDefaultWorkspaceName = ws.name; + } - if (WORKSPACEID == WORKSPACE_INVALID || (WORKSPACEID >= SPECIAL_WORKSPACE_START && WORKSPACEID <= -2)) { - WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1; - newDefaultWorkspaceName = std::to_string(WORKSPACEID); + if (wsID == WORKSPACE_INVALID || (wsID >= SPECIAL_WORKSPACE_START && wsID <= -2)) { + wsID = g_pCompositor->m_vWorkspaces.size() + 1; + newDefaultWorkspaceName = std::to_string(wsID); Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"{}\" is invalid.", g_pConfigManager->getDefaultWorkspaceFor(szName)); } - auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID); + auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(wsID); - Debug::log(LOG, "New monitor: WORKSPACEID {}, exists: {}", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr)); + Debug::log(LOG, "New monitor: WORKSPACEID {}, exists: {}", wsID, (int)(PNEWWORKSPACE != nullptr)); if (PNEWWORKSPACE) { // workspace exists, move it to the newly connected monitor @@ -438,9 +443,9 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { PNEWWORKSPACE->startAnim(true, true, true); } else { if (newDefaultWorkspaceName == "") - newDefaultWorkspaceName = std::to_string(WORKSPACEID); + newDefaultWorkspaceName = std::to_string(wsID); - PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(WORKSPACEID, ID, newDefaultWorkspaceName)); + PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(CWorkspace::create(wsID, ID, newDefaultWorkspaceName)); } activeWorkspace = PNEWWORKSPACE; diff --git a/src/macros.hpp b/src/macros.hpp index cacfdfea..67f6301b 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -24,7 +24,8 @@ #define STRVAL_EMPTY "[[EMPTY]]" -#define WORKSPACE_INVALID -1L +#define WORKSPACE_INVALID -1L +#define WORKSPACE_NOT_CHANGED -101 #define LISTENER(name) \ void listener_##name(wl_listener*, void*); \ diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e5db8918..bfcea3da 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1034,10 +1034,26 @@ void CKeybindManager::toggleActivePseudo(std::string args) { g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW); } -void CKeybindManager::changeworkspace(std::string args) { - int workspaceToChangeTo = 0; - std::string workspaceName = ""; +SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE) { + if (!args.starts_with("previous")) { + return getWorkspaceIDNameFromString(args); + } + const SWorkspaceIDName PPREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(args.contains("_per_monitor")); + // Do nothing if there's no previous workspace, otherwise switch to it. + if (PPREVWS.id == -1) { + Debug::log(LOG, "No previous workspace to change to"); + return {WORKSPACE_NOT_CHANGED, ""}; + } + + const auto ID = PCURRENTWORKSPACE->m_iID; + if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PPREVWS.id); PWORKSPACETOCHANGETO) + return {ID, PWORKSPACETOCHANGETO->m_szName}; + + return {ID, PPREVWS.name.empty() ? std::to_string(PPREVWS.id) : PPREVWS.name}; +} + +void CKeybindManager::changeworkspace(std::string args) { // Workspace_back_and_forth being enabled means that an attempt to switch to // the current workspace will instead switch to the previous. static auto PBACKANDFORTH = CConfigValue("binds:workspace_back_and_forth"); @@ -1050,43 +1066,31 @@ void CKeybindManager::changeworkspace(std::string args) { return; const auto PCURRENTWORKSPACE = PMONITOR->activeWorkspace; - const bool EXPLICITPREVIOUS = args.starts_with("previous"); - - if (args.starts_with("previous")) { - // Do nothing if there's no previous workspace, otherwise switch to it. - if (PCURRENTWORKSPACE->m_sPrevWorkspace.iID == -1) { - Debug::log(LOG, "No previous workspace to change to"); - return; - } else { - workspaceToChangeTo = PCURRENTWORKSPACE->m_iID; - - if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PCURRENTWORKSPACE->m_sPrevWorkspace.iID); PWORKSPACETOCHANGETO) - workspaceName = PWORKSPACETOCHANGETO->m_szName; - else - workspaceName = - PCURRENTWORKSPACE->m_sPrevWorkspace.name.empty() ? std::to_string(PCURRENTWORKSPACE->m_sPrevWorkspace.iID) : PCURRENTWORKSPACE->m_sPrevWorkspace.name; - } - } else { - workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName); - } + const bool EXPLICITPREVIOUS = args.contains("previous"); + const auto& [workspaceToChangeTo, workspaceName] = getWorkspaceToChangeFromArgs(args, PCURRENTWORKSPACE); if (workspaceToChangeTo == WORKSPACE_INVALID) { Debug::log(ERR, "Error in changeworkspace, invalid value"); return; } - const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; + if (workspaceToChangeTo == WORKSPACE_NOT_CHANGED) { + return; + } - if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PCURRENTWORKSPACE->m_sPrevWorkspace.iID == -1)) + const auto PREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(args.contains("_per_monitor")); + + const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; + if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PREVWS.id == -1)) return; g_pInputManager->unconstrainMouse(); g_pInputManager->m_bEmptyFocusCursorSet = false; - auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.iID : workspaceToChangeTo); + auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo); if (!pWorkspaceToChangeTo) - pWorkspaceToChangeTo = g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.iID : workspaceToChangeTo, PMONITOR->ID, - BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.name : workspaceName); + pWorkspaceToChangeTo = + g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo, PMONITOR->ID, BISWORKSPACECURRENT ? PREVWS.name : workspaceName); if (!BISWORKSPACECURRENT && pWorkspaceToChangeTo->m_bIsSpecialWorkspace) { PMONITOR->setSpecialWorkspace(pWorkspaceToChangeTo); @@ -1169,10 +1173,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { if (!PWINDOW) return; - // hack - std::string workspaceName; - const auto WORKSPACEID = getWorkspaceIDFromString(args, workspaceName); - + const auto& [WORKSPACEID, workspaceName] = getWorkspaceIDNameFromString(args); if (WORKSPACEID == WORKSPACE_INVALID) { Debug::log(LOG, "Invalid workspace in moveActiveToWorkspace"); return; @@ -1233,10 +1234,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { if (!PWINDOW) return; - std::string workspaceName = ""; - - const int WORKSPACEID = getWorkspaceIDFromString(args, workspaceName); - + const auto& [WORKSPACEID, workspaceName] = getWorkspaceIDNameFromString(args); if (WORKSPACEID == WORKSPACE_INVALID) { Debug::log(ERR, "Error in moveActiveToWorkspaceSilent, invalid value"); return; @@ -1702,8 +1700,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { return; } - std::string workspaceName; - const int WORKSPACEID = getWorkspaceIDFromString(workspace, workspaceName); + const int WORKSPACEID = getWorkspaceIDNameFromString(workspace).id; if (WORKSPACEID == WORKSPACE_INVALID) { Debug::log(ERR, "moveWorkspaceToMonitor invalid workspace!"); @@ -1721,9 +1718,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { } void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { - std::string workspaceName; - int workspaceID = getWorkspaceIDFromString(args, workspaceName); - + int workspaceID = getWorkspaceIDNameFromString(args).id; if (workspaceID == WORKSPACE_INVALID) { Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!"); return; @@ -1746,14 +1741,13 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { } static auto PBACKANDFORTH = CConfigValue("binds:workspace_back_and_forth"); + const auto PREVWS = pWorkspace->getPrevWorkspaceIDName(false); - if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && pWorkspace->m_sPrevWorkspace.iID != -1) { - const int PREVWORKSPACEID = pWorkspace->m_sPrevWorkspace.iID; - const auto PREVWORKSPACENAME = pWorkspace->m_sPrevWorkspace.name; + if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && PREVWS.id != -1) { // Workspace to focus is previous workspace - pWorkspace = g_pCompositor->getWorkspaceByID(PREVWORKSPACEID); + pWorkspace = g_pCompositor->getWorkspaceByID(PREVWS.id); if (!pWorkspace) - pWorkspace = g_pCompositor->createNewWorkspace(PREVWORKSPACEID, PCURRMONITOR->ID, PREVWORKSPACENAME); + pWorkspace = g_pCompositor->createNewWorkspace(PREVWS.id, PCURRMONITOR->ID, PREVWS.name); workspaceID = pWorkspace->m_iID; } @@ -1776,9 +1770,7 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { } void CKeybindManager::toggleSpecialWorkspace(std::string args) { - std::string workspaceName = ""; - int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName); - + const auto& [workspaceID, workspaceName] = getWorkspaceIDNameFromString("special:" + args); if (workspaceID == WORKSPACE_INVALID || !g_pCompositor->isWorkspaceSpecial(workspaceID)) { Debug::log(ERR, "Invalid workspace passed to special"); return; diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index ead7c5b8..775881cd 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -63,10 +63,9 @@ void CInputManager::endWorkspaceSwipe() { m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); // commit - std::string wsname = ""; - auto workspaceIDLeft = getWorkspaceIDFromString((*PSWIPEUSER ? "r-1" : "m-1"), wsname); - auto workspaceIDRight = getWorkspaceIDFromString((*PSWIPEUSER ? "r+1" : "m+1"), wsname); - const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, (int64_t)1LL, (int64_t)UINT32_MAX); + auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id; + auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id; + const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, (int64_t)1LL, (int64_t)UINT32_MAX); // If we've been swiping off the right end with PSWIPENEW enabled, there is // no workspace there yet, and we need to choose an ID for a new one now. @@ -232,9 +231,8 @@ void CInputManager::updateWorkspaceSwipe(double delta) { m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(d)) / (m_sActiveSwipe.speedPoints + 1); m_sActiveSwipe.speedPoints++; - std::string wsname = ""; - auto workspaceIDLeft = getWorkspaceIDFromString((*PSWIPEUSER ? "r-1" : "m-1"), wsname); - auto workspaceIDRight = getWorkspaceIDFromString((*PSWIPEUSER ? "r+1" : "m+1"), wsname); + auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id; + auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id; if ((workspaceIDLeft == WORKSPACE_INVALID || workspaceIDRight == WORKSPACE_INVALID || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) && !*PSWIPENEW) { m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe