From 3269e803fdaa03378f928a414eefe16ffb634e72 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Tue, 19 May 2026 03:23:39 -0700 Subject: [PATCH 1/3] Point hyprexpo at window drag branch --- nixos/flake.lock | 7 +- nixos/flake.nix | 2 +- nixos/flake/per-system.nix | 8 +- nixos/hyprland.nix | 8 +- nixos/packages/hyprexpo-drag-windows.patch | 198 --------------------- 5 files changed, 7 insertions(+), 216 deletions(-) delete mode 100644 nixos/packages/hyprexpo-drag-windows.patch diff --git a/nixos/flake.lock b/nixos/flake.lock index c0982f1e..b9ad9fd9 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -745,15 +745,16 @@ ] }, "locked": { - "lastModified": 1778877751, - "narHash": "sha256-EWGEw2wvflMzTcKxo5cLYL5Cw4KqYGpRl1nQGp2VpiM=", + "lastModified": 1779186703, + "narHash": "sha256-LQ3zJ2AZdCszTztOJOHueAU+LHQbbFTM5ci0Dc6GpIc=", "owner": "colonelpanic8", "repo": "hyprexpo", - "rev": "bb53c1d9ed635ad88eaf5db287692d9babef9963", + "rev": "3460ba85c3507a191c5623c0a67b96b4c8f689cb", "type": "github" }, "original": { "owner": "colonelpanic8", + "ref": "codex/window-drag-workspaces", "repo": "hyprexpo", "type": "github" } diff --git a/nixos/flake.nix b/nixos/flake.nix index 836d121a..d09f535c 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -121,7 +121,7 @@ }; hyprexpo = { - url = "github:colonelpanic8/hyprexpo"; + url = "github:colonelpanic8/hyprexpo?ref=codex/window-drag-workspaces"; inputs.hyprland.follows = "hyprland"; }; diff --git a/nixos/flake/per-system.nix b/nixos/flake/per-system.nix index 9639397b..ff00ef39 100644 --- a/nixos/flake/per-system.nix +++ b/nixos/flake/per-system.nix @@ -26,13 +26,7 @@ hyprlang = inputs.hyprlang.packages.${system}.hyprlang; hyprutils = inputs.hyprutils.packages.${system}.hyprutils; }; - hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: { - patches = - (old.patches or []) - ++ [ - ../packages/hyprexpo-drag-windows.patch - ]; - }); + hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo; tangledConfig = dotfilesOrgApi.org-agenda-custom-config; # Import container build logic diff --git a/nixos/hyprland.nix b/nixos/hyprland.nix index 43c52647..f2cf1be8 100644 --- a/nixos/hyprland.nix +++ b/nixos/hyprland.nix @@ -106,13 +106,7 @@ ./packages/hyprwobbly-safe-geometry-and-idle-timer.patch ]; }); - hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: { - patches = - (old.patches or []) - ++ [ - ./packages/hyprexpo-drag-windows.patch - ]; - }); + hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo; hyprlandPluginPackages = [ inputs.hyprNStack.packages.${system}.hyprNStack diff --git a/nixos/packages/hyprexpo-drag-windows.patch b/nixos/packages/hyprexpo-drag-windows.patch deleted file mode 100644 index aa461192..00000000 --- a/nixos/packages/hyprexpo-drag-windows.patch +++ /dev/null @@ -1,198 +0,0 @@ ---- a/Overview.hpp -+++ b/Overview.hpp -@@ -80,6 +80,12 @@ - void updateHoveredFromMouse(); - bool isTileValid(int id) const; - void ensureKeyboardFocus(); -+ void beginWindowDrag(); -+ bool finishWindowDrag(); -+ void updateWindowDrag(); -+ PHLWINDOW windowAtTilePoint(int id, const Vector2D& localPoint) const; -+ Vector2D tilePointToWorkspacePoint(int id, const Vector2D& localPoint) const; -+ PHLWORKSPACE ensureWorkspaceForTile(int id); - - int SIDE_LENGTH = 3; - int GAP_WIDTH = 5; -@@ -94,6 +100,11 @@ - int hoveredID = -1; - int kbFocusID = -1; - -+ Vector2D dragStartLocal = Vector2D{}; -+ int dragSourceID = -1; -+ bool dragMoved = false; -+ PHLWINDOW dragWindow; -+ - std::vector images; - - PHLWORKSPACE startedOn; ---- a/Overview.cpp -+++ b/Overview.cpp -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #define private public - #define protected public - #include -@@ -79,6 +80,10 @@ - return grad; - } - -+static bool windowVisibleOnWorkspace(const PHLWINDOW& window, const PHLWORKSPACE& workspace) { -+ return window && workspace && window->m_workspace == workspace && window->m_isMapped && !window->isHidden() && !window->m_pinned; -+} -+ - static void ensureFramebuffer(COverview::SWorkspaceImage& image, const CBox& monbox, uint32_t drmFormat) { - if (!image.fb) - image.fb = g_pHyprRenderer->createFB("hyprexpo"); -@@ -337,9 +342,29 @@ - info.cancelled = true; - lastMousePosLocal = g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position; - updateHoveredFromMouse(); -+ updateWindowDrag(); -+ }; -+ -+ auto onCursorSelect = [this](IPointer::SButtonEvent event, Event::SCallbackInfo& info) { -+ if (closing) -+ return; -+ -+ info.cancelled = true; -+ -+ if (event.state == WL_POINTER_BUTTON_STATE_PRESSED) { -+ beginWindowDrag(); -+ return; -+ } -+ -+ if (finishWindowDrag()) -+ return; -+ -+ selectHoveredWorkspace(); -+ -+ close(); - }; - -- auto onCursorSelect = [this](Event::SCallbackInfo& info) { -+ auto onTouchSelect = [this](Event::SCallbackInfo& info) { - if (closing) - return; - -@@ -353,8 +378,107 @@ - mouseMoveHook = Event::bus()->m_events.input.mouse.move.listen([onCursorMove](Vector2D, Event::SCallbackInfo& info) { onCursorMove(info); }); - touchMoveHook = Event::bus()->m_events.input.touch.motion.listen([onCursorMove](ITouch::SMotionEvent, Event::SCallbackInfo& info) { onCursorMove(info); }); - -- mouseButtonHook = Event::bus()->m_events.input.mouse.button.listen([onCursorSelect](IPointer::SButtonEvent, Event::SCallbackInfo& info) { onCursorSelect(info); }); -- touchDownHook = Event::bus()->m_events.input.touch.down.listen([onCursorSelect](ITouch::SDownEvent, Event::SCallbackInfo& info) { onCursorSelect(info); }); -+ mouseButtonHook = Event::bus()->m_events.input.mouse.button.listen([onCursorSelect](IPointer::SButtonEvent event, Event::SCallbackInfo& info) { onCursorSelect(event, info); }); -+ touchDownHook = Event::bus()->m_events.input.touch.down.listen([onTouchSelect](ITouch::SDownEvent, Event::SCallbackInfo& info) { onTouchSelect(info); }); -+} -+ -+Vector2D COverview::tilePointToWorkspacePoint(int id, const Vector2D& localPoint) const { -+ const Vector2D tileSize = pMonitor->m_size / SIDE_LENGTH; -+ const Vector2D tilePos = tileSize * Vector2D{id % SIDE_LENGTH, id / SIDE_LENGTH}; -+ const Vector2D inTile = localPoint - tilePos; -+ -+ return pMonitor->m_position + Vector2D{std::clamp(inTile.x / tileSize.x, 0.0, 1.0) * pMonitor->m_size.x, std::clamp(inTile.y / tileSize.y, 0.0, 1.0) * pMonitor->m_size.y}; -+} -+ -+PHLWINDOW COverview::windowAtTilePoint(int id, const Vector2D& localPoint) const { -+ if (!isTileValid(id)) -+ return nullptr; -+ -+ const auto WORKSPACE = images[id].pWorkspace ? images[id].pWorkspace : g_pCompositor->getWorkspaceByID(images[id].workspaceID); -+ if (!WORKSPACE) -+ return nullptr; -+ -+ const auto POINT = tilePointToWorkspacePoint(id, localPoint); -+ for (auto it = g_pCompositor->m_windows.rbegin(); it != g_pCompositor->m_windows.rend(); ++it) { -+ const auto& window = *it; -+ if (!windowVisibleOnWorkspace(window, WORKSPACE)) -+ continue; -+ -+ if (window->getWindowMainSurfaceBox().containsPoint(POINT)) -+ return window; -+ } -+ -+ return nullptr; -+} -+ -+void COverview::beginWindowDrag() { -+ updateHoveredFromMouse(); -+ dragStartLocal = lastMousePosLocal; -+ dragSourceID = hoveredID; -+ dragMoved = false; -+ dragWindow = windowAtTilePoint(dragSourceID, dragStartLocal); -+} -+ -+void COverview::updateWindowDrag() { -+ if (!dragWindow || dragMoved) -+ return; -+ -+ const auto DX = lastMousePosLocal.x - dragStartLocal.x; -+ const auto DY = lastMousePosLocal.y - dragStartLocal.y; -+ if (std::hypot(DX, DY) < 12.0) -+ return; -+ -+ dragMoved = true; -+ damage(); -+} -+ -+PHLWORKSPACE COverview::ensureWorkspaceForTile(int id) { -+ if (!isTileValid(id)) -+ return nullptr; -+ -+ auto& image = images[id]; -+ if (image.pWorkspace) -+ return image.pWorkspace; -+ -+ auto workspace = g_pCompositor->getWorkspaceByID(image.workspaceID); -+ if (!workspace) -+ workspace = g_pCompositor->createNewWorkspace(image.workspaceID, pMonitor->m_id, std::to_string(image.workspaceID), false); -+ -+ image.pWorkspace = workspace; -+ return workspace; -+} -+ -+bool COverview::finishWindowDrag() { -+ const auto WINDOW = dragWindow; -+ const int SOURCE = dragSourceID; -+ const bool MOVED = dragMoved; -+ -+ dragWindow = nullptr; -+ dragSourceID = -1; -+ dragMoved = false; -+ -+ if (!WINDOW) -+ return false; -+ -+ if (!MOVED) -+ return false; -+ -+ updateHoveredFromMouse(); -+ -+ const int TARGET = hoveredID; -+ if (!isTileValid(SOURCE) || !isTileValid(TARGET) || SOURCE == TARGET) -+ return true; -+ -+ const auto SOURCEWS = images[SOURCE].pWorkspace; -+ const auto TARGETWS = ensureWorkspaceForTile(TARGET); -+ if (!windowVisibleOnWorkspace(WINDOW, SOURCEWS) || !TARGETWS || TARGETWS == SOURCEWS) -+ return true; -+ -+ g_pCompositor->moveWindowToWorkspaceSafe(WINDOW, TARGETWS); -+ redrawID(SOURCE); -+ redrawID(TARGET); -+ damage(); -+ return true; - } - - void COverview::selectHoveredWorkspace() { -@@ -954,6 +1078,8 @@ - drawBorder(openedID, *PBORDERCURRENT); - if (kbFocusID != -1) - drawBorder(kbFocusID, *PBORDERFOCUS); -+ if (dragMoved && dragSourceID != -1) -+ drawBorder(dragSourceID, *PBORDERFOCUS); - } - - static float lerp(const float& from, const float& to, const float perc) { From 937b49c11a506384a8489cca926b52a549406f76 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Tue, 19 May 2026 04:23:09 -0700 Subject: [PATCH 2/3] Point hyprexpo at refreshed main --- nixos/flake.lock | 7 +++---- nixos/flake.nix | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/nixos/flake.lock b/nixos/flake.lock index b9ad9fd9..3df8395b 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -745,16 +745,15 @@ ] }, "locked": { - "lastModified": 1779186703, - "narHash": "sha256-LQ3zJ2AZdCszTztOJOHueAU+LHQbbFTM5ci0Dc6GpIc=", + "lastModified": 1779189551, + "narHash": "sha256-f9/6cCWd31SQyS+Q+i+NblWcLGxpQwTTdbMdu7QXrvM=", "owner": "colonelpanic8", "repo": "hyprexpo", - "rev": "3460ba85c3507a191c5623c0a67b96b4c8f689cb", + "rev": "db3893b2de25c8f1b9923c50939c0d2ba3bb794d", "type": "github" }, "original": { "owner": "colonelpanic8", - "ref": "codex/window-drag-workspaces", "repo": "hyprexpo", "type": "github" } diff --git a/nixos/flake.nix b/nixos/flake.nix index d09f535c..836d121a 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -121,7 +121,7 @@ }; hyprexpo = { - url = "github:colonelpanic8/hyprexpo?ref=codex/window-drag-workspaces"; + url = "github:colonelpanic8/hyprexpo"; inputs.hyprland.follows = "hyprland"; }; From 9c1d280c92c5cec417c081eded39902b64a898a8 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Tue, 19 May 2026 05:19:16 -0700 Subject: [PATCH 3/3] Update hyprexpo preview refresh fix --- nixos/flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nixos/flake.lock b/nixos/flake.lock index 3df8395b..e8a413fb 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -745,11 +745,11 @@ ] }, "locked": { - "lastModified": 1779189551, - "narHash": "sha256-f9/6cCWd31SQyS+Q+i+NblWcLGxpQwTTdbMdu7QXrvM=", + "lastModified": 1779193017, + "narHash": "sha256-OOXTPFOvMbJ/UI3eUTwklkeOi0RCAEQe7LRsvD90Mg8=", "owner": "colonelpanic8", "repo": "hyprexpo", - "rev": "db3893b2de25c8f1b9923c50939c0d2ba3bb794d", + "rev": "00286c4ab4c52dd3e80f3eb8196a7904510a3f1e", "type": "github" }, "original": {