diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index ff1791f5..893f4ef0 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -140,6 +140,8 @@ void CConfigManager::setDefaultVars() { configValues["binds:pass_mouse_when_bound"].intValue = 1; configValues["binds:scroll_event_delay"].intValue = 300; + configValues["binds:workspace_back_and_forth"].intValue = 0; + configValues["binds:allow_workspace_cycles"].intValue = 0; configValues["gestures:workspace_swipe"].intValue = 0; configValues["gestures:workspace_swipe_fingers"].intValue = 3; diff --git a/src/helpers/Workspace.hpp b/src/helpers/Workspace.hpp index 5a3a24ba..3faebdd8 100644 --- a/src/helpers/Workspace.hpp +++ b/src/helpers/Workspace.hpp @@ -18,6 +18,9 @@ public: int m_iID = -1; std::string m_szName = ""; uint64_t m_iMonitorID = -1; + // Previous workspace ID is stored during a workspace change, allowing travel + // to the previous workspace. + int m_iPrevWorkspaceID = -1; bool m_bHasFullscreenWindow = false; eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 9939993a..3d821d14 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -454,11 +454,34 @@ void CKeybindManager::changeworkspace(std::string args) { int workspaceToChangeTo = 0; std::string workspaceName = ""; + // Flag needed so that the previous workspace is not recorded when switching + // to a previous workspace. + bool isSwitchingToPrevious = false; + if (args.find("[internal]") == 0) { workspaceToChangeTo = std::stoi(args.substr(10)); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToChangeTo); if (PWORKSPACE) workspaceName = PWORKSPACE->m_szName; + } else if (args.find("previous") == 0) { + const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID( + g_pCompositor->m_pLastMonitor->activeWorkspace); + + // Do nothing if there's no previous workspace, otherwise switch to it. + if (PCURRENTWORKSPACE->m_iPrevWorkspaceID == -1) { + Debug::log(LOG, "No previous workspace to change to"); + return; + } + else { + workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID; + isSwitchingToPrevious = true; + + // If the previous workspace ID isn't reset, cycles can form when continually going + // to the previous workspace again and again. + static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue; + if (!*PALLOWWORKSPACECYCLES) + PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1; + } } else { workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName); } @@ -468,6 +491,25 @@ void CKeybindManager::changeworkspace(std::string args) { return; } + // Workspace_back_and_forth being enabled means that an attempt to switch to + // the current workspace will instead switch to the previous. + const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID( + g_pCompositor->m_pLastMonitor->activeWorkspace); + static auto *const PBACKANDFORTH = &g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth")->intValue; + if (*PBACKANDFORTH + && PCURRENTWORKSPACE->m_iID == workspaceToChangeTo + && PCURRENTWORKSPACE->m_iPrevWorkspaceID != -1) { + + workspaceToChangeTo = PCURRENTWORKSPACE->m_iPrevWorkspaceID; + isSwitchingToPrevious = true; + + // If the previous workspace ID isn't reset, cycles can form when continually going + // to the previous workspace again and again. + static auto *const PALLOWWORKSPACECYCLES = &g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles")->intValue; + if (!*PALLOWWORKSPACECYCLES) + PCURRENTWORKSPACE->m_iPrevWorkspaceID = -1; + } + // remove constraints g_pInputManager->unconstrainMouse(); @@ -477,6 +519,10 @@ void CKeybindManager::changeworkspace(std::string args) { const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(workspaceToChangeTo); + if (!isSwitchingToPrevious) + // Remember previous workspace. + PWORKSPACETOCHANGETO->m_iPrevWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace; + if (workspaceToChangeTo == SPECIAL_WORKSPACE_ID) PWORKSPACETOCHANGETO->m_iMonitorID = PMONITOR->ID; @@ -541,6 +587,10 @@ void CKeybindManager::changeworkspace(std::string args) { const auto PWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique(PMONITOR->ID, workspaceName, workspaceToChangeTo == SPECIAL_WORKSPACE_ID)).get(); + if (!isSwitchingToPrevious) + // Remember previous workspace. + PWORKSPACE->m_iPrevWorkspaceID = OLDWORKSPACE; + // start anim on new workspace PWORKSPACE->startAnim(true, ANIMTOLEFT);