Point hyprexpo at window drag branch
This commit is contained in:
7
nixos/flake.lock
generated
7
nixos/flake.lock
generated
@@ -745,15 +745,16 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778877751,
|
"lastModified": 1779186703,
|
||||||
"narHash": "sha256-EWGEw2wvflMzTcKxo5cLYL5Cw4KqYGpRl1nQGp2VpiM=",
|
"narHash": "sha256-LQ3zJ2AZdCszTztOJOHueAU+LHQbbFTM5ci0Dc6GpIc=",
|
||||||
"owner": "colonelpanic8",
|
"owner": "colonelpanic8",
|
||||||
"repo": "hyprexpo",
|
"repo": "hyprexpo",
|
||||||
"rev": "bb53c1d9ed635ad88eaf5db287692d9babef9963",
|
"rev": "3460ba85c3507a191c5623c0a67b96b4c8f689cb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "colonelpanic8",
|
"owner": "colonelpanic8",
|
||||||
|
"ref": "codex/window-drag-workspaces",
|
||||||
"repo": "hyprexpo",
|
"repo": "hyprexpo",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
hyprexpo = {
|
hyprexpo = {
|
||||||
url = "github:colonelpanic8/hyprexpo";
|
url = "github:colonelpanic8/hyprexpo?ref=codex/window-drag-workspaces";
|
||||||
inputs.hyprland.follows = "hyprland";
|
inputs.hyprland.follows = "hyprland";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,13 +26,7 @@
|
|||||||
hyprlang = inputs.hyprlang.packages.${system}.hyprlang;
|
hyprlang = inputs.hyprlang.packages.${system}.hyprlang;
|
||||||
hyprutils = inputs.hyprutils.packages.${system}.hyprutils;
|
hyprutils = inputs.hyprutils.packages.${system}.hyprutils;
|
||||||
};
|
};
|
||||||
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: {
|
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo;
|
||||||
patches =
|
|
||||||
(old.patches or [])
|
|
||||||
++ [
|
|
||||||
../packages/hyprexpo-drag-windows.patch
|
|
||||||
];
|
|
||||||
});
|
|
||||||
tangledConfig = dotfilesOrgApi.org-agenda-custom-config;
|
tangledConfig = dotfilesOrgApi.org-agenda-custom-config;
|
||||||
|
|
||||||
# Import container build logic
|
# Import container build logic
|
||||||
|
|||||||
@@ -106,13 +106,7 @@
|
|||||||
./packages/hyprwobbly-safe-geometry-and-idle-timer.patch
|
./packages/hyprwobbly-safe-geometry-and-idle-timer.patch
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo.overrideAttrs (old: {
|
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo;
|
||||||
patches =
|
|
||||||
(old.patches or [])
|
|
||||||
++ [
|
|
||||||
./packages/hyprexpo-drag-windows.patch
|
|
||||||
];
|
|
||||||
});
|
|
||||||
hyprlandPluginPackages =
|
hyprlandPluginPackages =
|
||||||
[
|
[
|
||||||
inputs.hyprNStack.packages.${system}.hyprNStack
|
inputs.hyprNStack.packages.${system}.hyprNStack
|
||||||
|
|||||||
@@ -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<SWorkspaceImage> images;
|
|
||||||
|
|
||||||
PHLWORKSPACE startedOn;
|
|
||||||
--- a/Overview.cpp
|
|
||||||
+++ b/Overview.cpp
|
|
||||||
@@ -5,6 +5,7 @@
|
|
||||||
#include <cctype>
|
|
||||||
#include <cmath>
|
|
||||||
#include <optional>
|
|
||||||
+#include <string>
|
|
||||||
#define private public
|
|
||||||
#define protected public
|
|
||||||
#include <hyprland/src/render/Renderer.hpp>
|
|
||||||
@@ -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) {
|
|
||||||
Reference in New Issue
Block a user