148 lines
4.7 KiB
Diff
148 lines
4.7 KiB
Diff
|
|
From edc05ce88f79ceda0cdcb9aa68ec371b1af323de Mon Sep 17 00:00:00 2001
|
||
|
|
From: Ivan Malison <IvanMalison@gmail.com>
|
||
|
|
Date: Mon, 16 Feb 2026 21:50:16 -0800
|
||
|
|
Subject: [PATCH 2/2] hyprexpo: add bring selection mode
|
||
|
|
|
||
|
|
---
|
||
|
|
hyprexpo/README.md | 1 +
|
||
|
|
hyprexpo/main.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
hyprexpo/overview.cpp | 12 +++++++++--
|
||
|
|
hyprexpo/overview.hpp | 3 ++-
|
||
|
|
4 files changed, 63 insertions(+), 3 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/README.md b/README.md
|
||
|
|
index aac2e97..084f02b 100644
|
||
|
|
--- a/README.md
|
||
|
|
+++ b/README.md
|
||
|
|
@@ -55,6 +55,7 @@ Here are a list of options you can use:
|
||
|
|
| --- | --- |
|
||
|
|
toggle | displays if hidden, hide if displayed
|
||
|
|
select | selects the hovered desktop
|
||
|
|
+bring | brings a window from the hovered desktop to the current desktop
|
||
|
|
off | hides the overview
|
||
|
|
disable | same as `off`
|
||
|
|
on | displays the overview
|
||
|
|
diff --git a/main.cpp b/main.cpp
|
||
|
|
index ff9f380..78bac24 100644
|
||
|
|
--- a/main.cpp
|
||
|
|
+++ b/main.cpp
|
||
|
|
@@ -65,6 +65,47 @@ static void hkAddDamageB(void* thisptr, const pixman_region32_t* rg) {
|
||
|
|
g_pOverview->onDamageReported();
|
||
|
|
}
|
||
|
|
|
||
|
|
+static PHLWINDOW windowToBringFromWorkspace(const PHLWORKSPACE& workspace) {
|
||
|
|
+ if (!workspace)
|
||
|
|
+ return nullptr;
|
||
|
|
+
|
||
|
|
+ for (auto it = g_pCompositor->m_windows.rbegin(); it != g_pCompositor->m_windows.rend(); ++it) {
|
||
|
|
+ const auto& w = *it;
|
||
|
|
+ if (!w || w->m_workspace != workspace || !w->m_isMapped || w->isHidden())
|
||
|
|
+ continue;
|
||
|
|
+
|
||
|
|
+ return w;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return nullptr;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static SDispatchResult bringWindowFromWorkspace(int64_t sourceWorkspaceID) {
|
||
|
|
+ if (sourceWorkspaceID == WORKSPACE_INVALID)
|
||
|
|
+ return {.success = false, .error = "selected workspace is empty"};
|
||
|
|
+
|
||
|
|
+ const auto FOCUSSTATE = Desktop::focusState();
|
||
|
|
+ const auto MONITOR = FOCUSSTATE->monitor();
|
||
|
|
+ if (!MONITOR || !MONITOR->m_activeWorkspace)
|
||
|
|
+ return {.success = false, .error = "no active monitor/workspace"};
|
||
|
|
+
|
||
|
|
+ if (sourceWorkspaceID == MONITOR->activeWorkspaceID())
|
||
|
|
+ return {};
|
||
|
|
+
|
||
|
|
+ const auto SOURCEWORKSPACE = g_pCompositor->getWorkspaceByID(sourceWorkspaceID);
|
||
|
|
+ if (!SOURCEWORKSPACE)
|
||
|
|
+ return {.success = false, .error = "selected workspace is not open"};
|
||
|
|
+
|
||
|
|
+ const auto WINDOW = windowToBringFromWorkspace(SOURCEWORKSPACE);
|
||
|
|
+ if (!WINDOW)
|
||
|
|
+ return {.success = false, .error = "selected workspace has no mapped windows"};
|
||
|
|
+
|
||
|
|
+ g_pCompositor->moveWindowToWorkspaceSafe(WINDOW, MONITOR->m_activeWorkspace);
|
||
|
|
+ FOCUSSTATE->fullWindowFocus(WINDOW);
|
||
|
|
+ g_pCompositor->warpCursorTo(WINDOW->middle());
|
||
|
|
+ return {};
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static SDispatchResult onExpoDispatcher(std::string arg) {
|
||
|
|
|
||
|
|
if (g_pOverview && g_pOverview->m_isSwiping)
|
||
|
|
@@ -77,6 +118,15 @@ static SDispatchResult onExpoDispatcher(std::string arg) {
|
||
|
|
}
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
+ if (arg == "bring") {
|
||
|
|
+ if (g_pOverview) {
|
||
|
|
+ g_pOverview->selectHoveredWorkspace();
|
||
|
|
+ const auto BRINGRESULT = bringWindowFromWorkspace(g_pOverview->selectedWorkspaceID());
|
||
|
|
+ g_pOverview->close(false);
|
||
|
|
+ return BRINGRESULT;
|
||
|
|
+ }
|
||
|
|
+ return {};
|
||
|
|
+ }
|
||
|
|
if (arg == "toggle") {
|
||
|
|
if (g_pOverview)
|
||
|
|
g_pOverview->close();
|
||
|
|
diff --git a/overview.cpp b/overview.cpp
|
||
|
|
index 926a9f8..45ee982 100644
|
||
|
|
--- a/overview.cpp
|
||
|
|
+++ b/overview.cpp
|
||
|
|
@@ -343,6 +343,14 @@ void COverview::selectHoveredWorkspace() {
|
||
|
|
closeOnID = x + y * SIDE_LENGTH;
|
||
|
|
}
|
||
|
|
|
||
|
|
+int64_t COverview::selectedWorkspaceID() const {
|
||
|
|
+ const int ID = closeOnID == -1 ? openedID : closeOnID;
|
||
|
|
+ if (ID < 0 || ID >= (int)images.size())
|
||
|
|
+ return WORKSPACE_INVALID;
|
||
|
|
+
|
||
|
|
+ return images[ID].workspaceID;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void COverview::redrawID(int id, bool forcelowres) {
|
||
|
|
if (!pMonitor)
|
||
|
|
return;
|
||
|
|
@@ -451,7 +459,7 @@ void COverview::onDamageReported() {
|
||
|
|
g_pCompositor->scheduleFrameForMonitor(pMonitor.lock());
|
||
|
|
}
|
||
|
|
|
||
|
|
-void COverview::close() {
|
||
|
|
+void COverview::close(bool switchToSelection) {
|
||
|
|
if (closing)
|
||
|
|
return;
|
||
|
|
|
||
|
|
@@ -471,7 +479,7 @@ void COverview::close() {
|
||
|
|
|
||
|
|
redrawAll();
|
||
|
|
|
||
|
|
- if (TILE.workspaceID != pMonitor->activeWorkspaceID()) {
|
||
|
|
+ if (switchToSelection && TILE.workspaceID != pMonitor->activeWorkspaceID()) {
|
||
|
|
pMonitor->setSpecialWorkspace(0);
|
||
|
|
|
||
|
|
// If this tile's workspace was WORKSPACE_INVALID, move to the next
|
||
|
|
diff --git a/overview.hpp b/overview.hpp
|
||
|
|
index 1f6bf3c..ca59f32 100644
|
||
|
|
--- a/overview.hpp
|
||
|
|
+++ b/overview.hpp
|
||
|
|
@@ -33,8 +33,9 @@ class COverview {
|
||
|
|
void onSwipeEnd();
|
||
|
|
|
||
|
|
// close without a selection
|
||
|
|
- void close();
|
||
|
|
+ void close(bool switchToSelection = true);
|
||
|
|
void selectHoveredWorkspace();
|
||
|
|
+ int64_t selectedWorkspaceID() const;
|
||
|
|
|
||
|
|
bool blockOverviewRendering = false;
|
||
|
|
bool blockDamageReporting = false;
|
||
|
|
--
|
||
|
|
2.52.0
|
||
|
|
|