keybinds: fix previous_per_monitor logic (#9010)

Co-authored-by: Крылов Александр <aleksandr.krylov@hyperus.team>
This commit is contained in:
Alexander 2025-01-11 19:05:53 +03:00 committed by GitHub
parent 3b85690aa6
commit 15dc024a39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 63 additions and 43 deletions

View file

@ -52,10 +52,7 @@ void CWorkspace::init(PHLWORKSPACE self) {
EMIT_HOOK_EVENT("createWorkspace", this); EMIT_HOOK_EVENT("createWorkspace", this);
} }
SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const { SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName() const {
if (perMonitor)
return m_sPrevWorkspacePerMonitor;
return m_sPrevWorkspace; return m_sPrevWorkspace;
} }
@ -216,10 +213,7 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {
m_sPrevWorkspace.id = prev->m_iID; m_sPrevWorkspace.id = prev->m_iID;
m_sPrevWorkspace.name = prev->m_szName; m_sPrevWorkspace.name = prev->m_szName;
if (prev->m_pMonitor == m_pMonitor) { prev->m_pMonitor->addPrevWorkspaceID(prev->m_iID);
m_sPrevWorkspacePerMonitor.id = prev->m_iID;
m_sPrevWorkspacePerMonitor.name = prev->m_szName;
}
} }
std::string CWorkspace::getConfigName() { std::string CWorkspace::getConfigName() {

View file

@ -24,17 +24,14 @@ class CWorkspace {
// Workspaces ID-based have IDs > 0 // Workspaces ID-based have IDs > 0
// and workspaces name-based have IDs starting with -1337 // and workspaces name-based have IDs starting with -1337
WORKSPACEID m_iID = WORKSPACE_INVALID; WORKSPACEID m_iID = WORKSPACE_INVALID;
std::string m_szName = ""; std::string m_szName = "";
PHLMONITORREF m_pMonitor; PHLMONITORREF m_pMonitor;
// Previous workspace ID and name is stored during a workspace change, allowing travel
// to the previous workspace.
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
bool m_bHasFullscreenWindow = false; bool m_bHasFullscreenWindow = false;
eFullscreenMode m_efFullscreenMode = FSMODE_NONE; eFullscreenMode m_efFullscreenMode = FSMODE_NONE;
wl_array m_wlrCoordinateArr; wl_array m_wlrCoordinateArr;
// for animations // for animations
PHLANIMVAR<Vector2D> m_vRenderOffset; PHLANIMVAR<Vector2D> m_vRenderOffset;
@ -72,7 +69,7 @@ class CWorkspace {
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; SWorkspaceIDName getPrevWorkspaceIDName() const;
void updateWindowDecos(); void updateWindowDecos();
void updateWindowData(); void updateWindowData();
int getWindows(std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {}); int getWindows(std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
@ -88,7 +85,10 @@ class CWorkspace {
void updateWindows(); void updateWindows();
private: private:
void init(PHLWORKSPACE self); void init(PHLWORKSPACE self);
// Previous workspace ID and name is stored during a workspace change, allowing travel
// to the previous workspace.
SWorkspaceIDName m_sPrevWorkspace;
SP<HOOK_CALLBACK_FN> m_pFocusedWindowHook; SP<HOOK_CALLBACK_FN> m_pFocusedWindowHook;
bool m_bInert = true; bool m_bInert = true;

View file

@ -258,7 +258,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
if (!valid(PWORKSPACE)) if (!valid(PWORKSPACE))
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};
const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.id); const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->getPrevWorkspaceIDName().id);
if (!PLASTWORKSPACE) if (!PLASTWORKSPACE)
return {WORKSPACE_INVALID}; return {WORKSPACE_INVALID};

View file

@ -1,5 +1,6 @@
#include "Monitor.hpp" #include "Monitor.hpp"
#include "MiscFunctions.hpp" #include "MiscFunctions.hpp"
#include "macros.hpp"
#include "math/Math.hpp" #include "math/Math.hpp"
#include "sync/SyncReleaser.hpp" #include "sync/SyncReleaser.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
@ -1169,6 +1170,29 @@ void CMonitor::moveTo(const Vector2D& pos) {
vecPosition = pos; vecPosition = pos;
} }
SWorkspaceIDName CMonitor::getPrevWorkspaceIDName(const WORKSPACEID id) {
while (!prevWorkSpaces.empty()) {
const int PREVID = prevWorkSpaces.top();
prevWorkSpaces.pop();
if (PREVID == id) // skip same workspace
continue;
// recheck if previous workspace's was moved to another monitor
const auto ws = g_pCompositor->getWorkspaceByID(PREVID);
if (ws && ws->monitorID() == ID)
return {.id = PREVID, .name = ws->m_szName};
}
return {.id = WORKSPACE_INVALID};
}
void CMonitor::addPrevWorkspaceID(const WORKSPACEID id) {
if (!prevWorkSpaces.empty() && prevWorkSpaces.top() == id)
return;
prevWorkSpaces.emplace(id);
}
Vector2D CMonitor::middle() { Vector2D CMonitor::middle() {
return vecPosition + vecSize / 2.f; return vecPosition + vecSize / 2.f;
} }

View file

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "../defines.hpp" #include "../defines.hpp"
#include <stack>
#include <vector> #include <vector>
#include "SharedDefs.hpp"
#include "WLClasses.hpp" #include "WLClasses.hpp"
#include <vector> #include <vector>
#include <array> #include <array>
@ -196,11 +198,16 @@ class CMonitor {
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName; return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
} }
private: // workspace previous per monitor functionality
void setupDefaultWS(const SMonitorRule&); SWorkspaceIDName getPrevWorkspaceIDName(const WORKSPACEID id);
WORKSPACEID findAvailableDefaultWS(); void addPrevWorkspaceID(const WORKSPACEID id);
bool doneScheduled = false; private:
void setupDefaultWS(const SMonitorRule&);
WORKSPACEID findAvailableDefaultWS();
bool doneScheduled = false;
std::stack<WORKSPACEID> prevWorkSpaces;
struct { struct {
CHyprSignalListener frame; CHyprSignalListener frame;

View file

@ -1176,27 +1176,24 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) {
return {}; return {};
} }
static SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE) { static SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE, PHLMONITORREF PMONITOR) {
if (!args.starts_with("previous")) { if (!args.starts_with("previous")) {
return getWorkspaceIDNameFromString(args); return getWorkspaceIDNameFromString(args);
} }
const bool PER_MON = args.contains("_per_monitor"); const bool PER_MON = args.contains("_per_monitor");
const SWorkspaceIDName PPREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(PER_MON); const SWorkspaceIDName PPREVWS = PER_MON ? PMONITOR->getPrevWorkspaceIDName(PCURRENTWORKSPACE->m_iID) : PCURRENTWORKSPACE->getPrevWorkspaceIDName();
// Do nothing if there's no previous workspace, otherwise switch to it. // Do nothing if there's no previous workspace, otherwise switch to it.
if (PPREVWS.id == -1) { if (PPREVWS.id == -1 || PPREVWS.id == PCURRENTWORKSPACE->m_iID) {
Debug::log(LOG, "No previous workspace to change to"); Debug::log(LOG, "No previous workspace to change to");
return {WORKSPACE_NOT_CHANGED, ""}; return {.id = WORKSPACE_NOT_CHANGED};
} }
const auto ID = PCURRENTWORKSPACE->m_iID;
if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PPREVWS.id); PWORKSPACETOCHANGETO) { if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PPREVWS.id); PWORKSPACETOCHANGETO) {
if (PER_MON && PCURRENTWORKSPACE->m_pMonitor != PWORKSPACETOCHANGETO->m_pMonitor) return {.id = PWORKSPACETOCHANGETO->m_iID, .name = PWORKSPACETOCHANGETO->m_szName};
return {WORKSPACE_NOT_CHANGED, ""};
return {ID, PWORKSPACETOCHANGETO->m_szName};
} }
return {ID, PPREVWS.name.empty() ? std::to_string(PPREVWS.id) : PPREVWS.name}; return {.id = PPREVWS.id, .name = PPREVWS.name.empty() ? std::to_string(PPREVWS.id) : PPREVWS.name};
} }
SDispatchResult CKeybindManager::changeworkspace(std::string args) { SDispatchResult CKeybindManager::changeworkspace(std::string args) {
@ -1214,7 +1211,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
const auto PCURRENTWORKSPACE = PMONITOR->activeWorkspace; const auto PCURRENTWORKSPACE = PMONITOR->activeWorkspace;
const bool EXPLICITPREVIOUS = args.contains("previous"); const bool EXPLICITPREVIOUS = args.contains("previous");
const auto& [workspaceToChangeTo, workspaceName] = getWorkspaceToChangeFromArgs(args, PCURRENTWORKSPACE); const auto& [workspaceToChangeTo, workspaceName] = getWorkspaceToChangeFromArgs(args, PCURRENTWORKSPACE, PMONITOR);
if (workspaceToChangeTo == WORKSPACE_INVALID) { if (workspaceToChangeTo == WORKSPACE_INVALID) {
Debug::log(ERR, "Error in changeworkspace, invalid value"); Debug::log(ERR, "Error in changeworkspace, invalid value");
return {.success = false, .error = "Error in changeworkspace, invalid value"}; return {.success = false, .error = "Error in changeworkspace, invalid value"};
@ -1223,19 +1220,19 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) {
if (workspaceToChangeTo == WORKSPACE_NOT_CHANGED) if (workspaceToChangeTo == WORKSPACE_NOT_CHANGED)
return {}; return {};
const auto PREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(args.contains("_per_monitor")); const SWorkspaceIDName PPREVWS = args.contains("_per_monitor") ? PMONITOR->getPrevWorkspaceIDName(PCURRENTWORKSPACE->m_iID) : PCURRENTWORKSPACE->getPrevWorkspaceIDName();
const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID;
if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PREVWS.id == -1)) if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PPREVWS.id == -1))
return {.success = false, .error = "Previous workspace doesn't exist"}; return {.success = false, .error = "Previous workspace doesn't exist"};
g_pInputManager->unconstrainMouse(); g_pInputManager->unconstrainMouse();
g_pInputManager->m_bEmptyFocusCursorSet = false; g_pInputManager->m_bEmptyFocusCursorSet = false;
auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo); auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PPREVWS.id : workspaceToChangeTo);
if (!pWorkspaceToChangeTo) if (!pWorkspaceToChangeTo)
pWorkspaceToChangeTo = pWorkspaceToChangeTo =
g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo, PMONITOR->ID, BISWORKSPACECURRENT ? PREVWS.name : workspaceName); g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PPREVWS.id : workspaceToChangeTo, PMONITOR->ID, BISWORKSPACECURRENT ? PPREVWS.name : workspaceName);
if (!BISWORKSPACECURRENT && pWorkspaceToChangeTo->m_bIsSpecialWorkspace) { if (!BISWORKSPACECURRENT && pWorkspaceToChangeTo->m_bIsSpecialWorkspace) {
PMONITOR->setSpecialWorkspace(pWorkspaceToChangeTo); PMONITOR->setSpecialWorkspace(pWorkspaceToChangeTo);
@ -1407,9 +1404,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) {
} }
SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PHLWINDOW PWINDOW = nullptr; PHLWINDOW PWINDOW = nullptr;
const auto ORIGINALARGS = args;
if (args.contains(',')) { if (args.contains(',')) {
PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1)); PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1));
@ -2033,7 +2028,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args
} }
static auto PBACKANDFORTH = CConfigValue<Hyprlang::INT>("binds:workspace_back_and_forth"); static auto PBACKANDFORTH = CConfigValue<Hyprlang::INT>("binds:workspace_back_and_forth");
const auto PREVWS = pWorkspace->getPrevWorkspaceIDName(false); const auto PREVWS = pWorkspace->getPrevWorkspaceIDName();
if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && PREVWS.id != -1) { if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && PREVWS.id != -1) {
// Workspace to focus is previous workspace // Workspace to focus is previous workspace