Skip to content

Commit

Permalink
feat: run optional default command when switching to an empty workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
Syndelis committed Oct 12, 2023
1 parent 06cc424 commit b608bb8
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 6 deletions.
54 changes: 54 additions & 0 deletions src/helpers/MiscFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,60 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
return result;
}

static inline void ltrim(std::string& s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
}

int parseWorkspaceAndDefaultCmd(std::string inArgs, std::string& outWorkspaceName, std::string& outDefaultCmd) {

std::string workspaceToToggle;
if (inArgs.contains(',')) {
const int commaIdx = inArgs.find_first_of(',');
workspaceToToggle = inArgs.substr(0, commaIdx);
outDefaultCmd = inArgs.substr(commaIdx + 1);
} else {
workspaceToToggle = inArgs;
}

int workspaceID = getWorkspaceIDFromString(workspaceToToggle, outWorkspaceName);

ltrim(outDefaultCmd);

if (!outDefaultCmd.empty()) {
std::string rules;
const std::string workspaceRule = "workspace " + outWorkspaceName;
std::string cmd = outDefaultCmd;

if (outDefaultCmd[0] == '[') {
const int closingBracketIdx = outDefaultCmd.find_last_of(']');
auto tmpRules = outDefaultCmd.substr(1, closingBracketIdx - 1);
cmd = outDefaultCmd.substr(closingBracketIdx + 1);

auto rulesList = CVarList(tmpRules, 0, ';');

bool hadWorkspaceRule = false;
rulesList.map([&](std::string& rule) {
if (rule.find("workspace") == 0) {
rule = workspaceRule;
hadWorkspaceRule = true;
}
});

if (!hadWorkspaceRule) {
rulesList.append(workspaceRule);
}

rules = "[" + rulesList.join(";") + "]";
} else {
rules = "[" + workspaceRule + "]";
}

outDefaultCmd = rules + " " + cmd;
}

return workspaceID;
}

float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2) {
const float DX = std::max({0.0, p1.x - vec.x, vec.x - p2.x});
const float DY = std::max({0.0, p1.y - vec.y, vec.y - p2.y});
Expand Down
1 change: 1 addition & 0 deletions src/helpers/MiscFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ std::string removeBeginEndSpacesTabs(std::string);
bool isNumber(const std::string&, bool allowfloat = false);
bool isDirection(const std::string&);
int getWorkspaceIDFromString(const std::string&, std::string&);
int parseWorkspaceAndDefaultCmd(std::string, std::string&, std::string&);
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
void logSystemInfo();
std::string execAndGet(const char*);
Expand Down
10 changes: 10 additions & 0 deletions src/helpers/VarList.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <functional>
#include <vector>
#include <string>
#include "../macros.hpp"
Expand All @@ -20,6 +21,15 @@ class CVarList {

std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const;

void map(std::function<void(std::string&)> func) {
for (auto& s : m_vArgs)
func(s);
}

void append(const std::string arg) {
m_vArgs.emplace_back(arg);
}

std::string operator[](const size_t& idx) const {
if (idx >= m_vArgs.size())
return "";
Expand Down
24 changes: 18 additions & 6 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "KeybindManager.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "debug/Log.hpp"
#include "helpers/VarList.hpp"

#include <regex>

Expand Down Expand Up @@ -799,6 +801,7 @@ void CKeybindManager::toggleActivePseudo(std::string args) {
void CKeybindManager::changeworkspace(std::string args) {
int workspaceToChangeTo = 0;
std::string workspaceName = "";
std::string defaultCmd = "";

// Workspace_back_and_forth being enabled means that an attempt to switch to
// the current workspace will instead switch to the previous.
Expand All @@ -810,7 +813,7 @@ void CKeybindManager::changeworkspace(std::string args) {
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
const bool EXPLICITPREVIOUS = args.find("previous") == 0;

if (args.find("previous") == 0) {
if (EXPLICITPREVIOUS) {
// Do nothing if there's no previous workspace, otherwise switch to it.
if (PCURRENTWORKSPACE->m_sPrevWorkspace.iID == -1) {
Debug::log(LOG, "No previous workspace to change to");
Expand All @@ -825,7 +828,7 @@ void CKeybindManager::changeworkspace(std::string args) {
PCURRENTWORKSPACE->m_sPrevWorkspace.name.empty() ? std::to_string(PCURRENTWORKSPACE->m_sPrevWorkspace.iID) : PCURRENTWORKSPACE->m_sPrevWorkspace.name;
}
} else {
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
workspaceToChangeTo = parseWorkspaceAndDefaultCmd(args, workspaceName, defaultCmd);
}

if (workspaceToChangeTo == INT_MAX) {
Expand All @@ -842,10 +845,15 @@ void CKeybindManager::changeworkspace(std::string args) {
g_pInputManager->m_bEmptyFocusCursorSet = false;

auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.iID : workspaceToChangeTo);
if (!pWorkspaceToChangeTo)
if (!pWorkspaceToChangeTo) {
pWorkspaceToChangeTo = g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.iID : workspaceToChangeTo, PMONITOR->ID,
BISWORKSPACECURRENT ? PCURRENTWORKSPACE->m_sPrevWorkspace.name : workspaceName);

if (!defaultCmd.empty()) {
spawn(defaultCmd);
}
}

if (!BISWORKSPACECURRENT && pWorkspaceToChangeTo->m_bIsSpecialWorkspace) {
PMONITOR->setSpecialWorkspace(pWorkspaceToChangeTo);
g_pInputManager->simulateMouseMovement();
Expand Down Expand Up @@ -1440,8 +1448,8 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {

static auto* const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;

std::string workspaceName = "";
int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName);
std::string workspaceName, defaultCmd;
int workspaceID = parseWorkspaceAndDefaultCmd("special:" + args, workspaceName, defaultCmd);

if (workspaceID == INT_MAX || !g_pCompositor->isWorkspaceSpecial(workspaceID)) {
Debug::log(ERR, "Invalid workspace passed to special");
Expand All @@ -1467,8 +1475,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
Debug::log(LOG, "Toggling special workspace {} to open", workspaceID);
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID);

if (!PSPECIALWORKSPACE)
if (!PSPECIALWORKSPACE) {
PSPECIALWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, PMONITOR->ID, workspaceName);
if (!defaultCmd.empty()) {
spawn(defaultCmd);
}
}

PMONITOR->setSpecialWorkspace(PSPECIALWORKSPACE);
}
Expand Down

0 comments on commit b608bb8

Please sign in to comment.