Skip to content

Commit

Permalink
feat: [compositor, misc] ability to select previous workspace per mon…
Browse files Browse the repository at this point in the history
…itor
  • Loading branch information
Крылов Александр committed Jun 22, 2024
1 parent fabc30d commit fb0365e
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 146 deletions.
3 changes: 1 addition & 2 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1648,8 +1648,7 @@ PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) {
}

try {
std::string name = "";
return getWorkspaceByID(getWorkspaceIDFromString(str, name));
return getWorkspaceByID(getWorkspaceIDNameFromString(str).id);
} catch (std::exception& e) { Debug::log(ERR, "Error in getWorkspaceByString, invalid id"); }

return nullptr;
Expand Down
13 changes: 6 additions & 7 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1815,14 +1815,13 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
newrule.vrr = std::stoi(ARGS[argno + 1]);
argno++;
} else if (ARGS[argno] == "workspace") {
std::string name = "";
int wsId = getWorkspaceIDFromString(ARGS[argno + 1], name);
const auto& [id, name] = getWorkspaceIDNameFromString(ARGS[argno + 1]);

SWorkspaceRule wsRule;
wsRule.monitor = newrule.name;
wsRule.workspaceString = ARGS[argno + 1];
wsRule.workspaceId = id;
wsRule.workspaceName = name;
wsRule.workspaceId = wsId;

m_dWorkspaceRules.emplace_back(wsRule);
argno++;
Expand Down Expand Up @@ -2370,11 +2369,11 @@ std::optional<std::string> CConfigManager::handleBlurLS(const std::string& comma

std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::string& command, const std::string& value) {
// This can either be the monitor or the workspace identifier
const auto FIRST_DELIM = value.find_first_of(',');
const auto FIRST_DELIM = value.find_first_of(',');

std::string name = "";
auto first_ident = trim(value.substr(0, FIRST_DELIM));
int id = getWorkspaceIDFromString(first_ident, name);
auto first_ident = trim(value.substr(0, FIRST_DELIM));

const auto& [id, name] = getWorkspaceIDNameFromString(first_ident);

auto rules = value.substr(FIRST_DELIM + 1);
SWorkspaceRule wsRule;
Expand Down
20 changes: 15 additions & 5 deletions src/desktop/Workspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ void CWorkspace::init(PHLWORKSPACE self) {
EMIT_HOOK_EVENT("createWorkspace", this);
}

SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const {
if (perMonitor)
return m_sPrevWorkspacePerMonitor;

return m_sPrevWorkspace;
}

CWorkspace::~CWorkspace() {
m_vRenderOffset.unregister();

Expand Down Expand Up @@ -196,7 +203,7 @@ PHLWINDOW CWorkspace::getLastFocusedWindow() {

void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {
if (!prev) {
m_sPrevWorkspace.iID = -1;
m_sPrevWorkspace.id = -1;
m_sPrevWorkspace.name = "";
return;
}
Expand All @@ -206,8 +213,13 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) {
return;
}

m_sPrevWorkspace.iID = prev->m_iID;
m_sPrevWorkspace.id = prev->m_iID;
m_sPrevWorkspace.name = prev->m_szName;

if (prev->m_iMonitorID == m_iMonitorID) {
m_sPrevWorkspacePerMonitor.id = prev->m_iID;
m_sPrevWorkspacePerMonitor.name = prev->m_szName;
}
}

std::string CWorkspace::getConfigName() {
Expand All @@ -228,9 +240,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
return true;

if (isNumber(selector)) {

std::string wsname = "";
int wsid = getWorkspaceIDFromString(selector, wsname);
const auto& [wsid, wsname] = getWorkspaceIDNameFromString(selector);

if (wsid == WORKSPACE_INVALID)
return false;
Expand Down
34 changes: 17 additions & 17 deletions src/desktop/Workspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string>
#include "../defines.hpp"
#include "DesktopTypes.hpp"
#include "helpers/MiscFunctions.hpp"

enum eFullscreenMode : int8_t {
FULLSCREEN_INVALID = -1,
Expand All @@ -25,17 +26,14 @@ class CWorkspace {
int m_iID = -1;
std::string m_szName = "";
uint64_t m_iMonitorID = -1;
// Previous workspace ID is stored during a workspace change, allowing travel
// Previous workspace ID and name is stored during a workspace change, allowing travel
// to the previous workspace.
struct SPrevWorkspaceData {
int iID = -1;
std::string name = "";
} m_sPrevWorkspace;
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;

bool m_bHasFullscreenWindow = false;
eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL;
bool m_bHasFullscreenWindow = false;
eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL;

wl_array m_wlrCoordinateArr;
wl_array m_wlrCoordinateArr;

// for animations
CAnimatedVariable<Vector2D> m_vRenderOffset;
Expand Down Expand Up @@ -63,21 +61,23 @@ class CWorkspace {
bool m_bPersistent = false;

// Inert: destroyed and invalid. If this is true, release the ptr you have.
bool inert();
bool inert();

void startAnim(bool in, bool left, bool instant = false);
void setActive(bool on);
void startAnim(bool in, bool left, bool instant = false);
void setActive(bool on);

void moveToMonitor(const int&);
void moveToMonitor(const int&);

PHLWINDOW getLastFocusedWindow();
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
PHLWINDOW getLastFocusedWindow();
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);

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;

private:
void init(PHLWORKSPACE self);
Expand Down
3 changes: 1 addition & 2 deletions src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (WORKSPACEARGS[WORKSPACEARGS.size() - 1].starts_with("silent"))
workspaceSilent = true;

std::string requestedWorkspaceName;
const int REQUESTEDWORKSPACEID = getWorkspaceIDFromString(WORKSPACEARGS.join(" ", 0, workspaceSilent ? WORKSPACEARGS.size() - 1 : 0), requestedWorkspaceName);
const auto& [REQUESTEDWORKSPACEID, requestedWorkspaceName] = getWorkspaceIDNameFromString(WORKSPACEARGS.join(" ", 0, workspaceSilent ? WORKSPACEARGS.size() - 1 : 0));

if (REQUESTEDWORKSPACEID != WORKSPACE_INVALID) {
auto pWorkspace = g_pCompositor->getWorkspaceByID(REQUESTEDWORKSPACEID);
Expand Down
90 changes: 45 additions & 45 deletions src/helpers/MiscFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,37 +214,36 @@ bool isDirection(const char& arg) {
return arg == 'l' || arg == 'r' || arg == 'u' || arg == 'd' || arg == 't' || arg == 'b';
}

int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
int result = WORKSPACE_INVALID;
SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
SWorkspaceIDName result = {WORKSPACE_INVALID, ""};

if (in.starts_with("special")) {
outName = "special:special";
result.name = "special:special";

if (in.length() > 8) {
const auto NAME = in.substr(8);
const auto WS = g_pCompositor->getWorkspaceByName("special:" + NAME);

const auto WS = g_pCompositor->getWorkspaceByName("special:" + NAME);

outName = "special:" + NAME;

return WS ? WS->m_iID : g_pCompositor->getNewSpecialID();
return {WS ? WS->m_iID : g_pCompositor->getNewSpecialID(), "special:" + NAME};
}

return SPECIAL_WORKSPACE_START;
result.id = SPECIAL_WORKSPACE_START;
return result;
} else if (in.starts_with("name:")) {
const auto WORKSPACENAME = in.substr(in.find_first_of(':') + 1);
const auto WORKSPACE = g_pCompositor->getWorkspaceByName(WORKSPACENAME);
if (!WORKSPACE) {
result = g_pCompositor->getNextAvailableNamedWorkspace();
result.id = g_pCompositor->getNextAvailableNamedWorkspace();
} else {
result = WORKSPACE->m_iID;
result.id = WORKSPACE->m_iID;
}
outName = WORKSPACENAME;
result.name = WORKSPACENAME;
} else if (in.starts_with("empty")) {
const bool same_mon = in.substr(5).contains("m");
const bool next = in.substr(5).contains("n");
if ((same_mon || next) && !g_pCompositor->m_pLastMonitor) {
Debug::log(ERR, "Empty monitor workspace on monitor null!");
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};
}

std::set<int> invalidWSes;
Expand All @@ -259,41 +258,42 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
int id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0;
while (++id < INT_MAX) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0))
return id;
if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) {
result.id = id;
return result;
}
}
} else if (in.starts_with("prev")) {
if (!g_pCompositor->m_pLastMonitor)
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

const auto PWORKSPACE = g_pCompositor->m_pLastMonitor->activeWorkspace;

if (!valid(PWORKSPACE))
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.iID);
const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.id);

if (!PLASTWORKSPACE)
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

outName = PLASTWORKSPACE->m_szName;
return PLASTWORKSPACE->m_iID;
return {PLASTWORKSPACE->m_iID, PLASTWORKSPACE->m_szName};
} else {
if (in[0] == 'r' && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
bool absolute = in[1] == '~';
if (!g_pCompositor->m_pLastMonitor) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};
}

const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in.substr(absolute ? 2 : 1), 0);

if (!PLUSMINUSRESULT.has_value())
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

result = (int)PLUSMINUSRESULT.value();
result.id = (int)PLUSMINUSRESULT.value();

int remains = (int)result;
int remains = (int)result.id;

std::set<int> invalidWSes;

Expand Down Expand Up @@ -330,13 +330,13 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {

// traverse valid workspaces until we reach the remains
if ((size_t)remains < namedWSes.size()) {
result = namedWSes[remains];
result.id = namedWSes[remains];
} else {
remains -= namedWSes.size();
result = 0;
result.id = 0;
while (remains >= 0) {
result++;
if (!invalidWSes.contains(result)) {
result.id++;
if (!invalidWSes.contains(result.id)) {
remains--;
}
}
Expand Down Expand Up @@ -430,34 +430,34 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
finalWSID = curID;
}
}
result = finalWSID;
result.id = finalWSID;
}

const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(result);
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(result.id);
if (PWORKSPACE)
outName = g_pCompositor->getWorkspaceByID(result)->m_szName;
result.name = g_pCompositor->getWorkspaceByID(result.id)->m_szName;
else
outName = std::to_string(result);
result.name = std::to_string(result.id);

} else if ((in[0] == 'm' || in[0] == 'e') && (in[1] == '-' || in[1] == '+' || in[1] == '~') && isNumber(in.substr(2))) {
bool onAllMonitors = in[0] == 'e';
bool absolute = in[1] == '~';

if (!g_pCompositor->m_pLastMonitor) {
Debug::log(ERR, "Relative monitor workspace on monitor null!");
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};
}

// monitor relative
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in.substr(absolute ? 2 : 1), 0);

if (!PLUSMINUSRESULT.has_value())
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

result = (int)PLUSMINUSRESULT.value();
result.id = (int)PLUSMINUSRESULT.value();

// result now has +/- what we should move on mon
int remains = (int)result;
int remains = (int)result.id;

std::vector<int> validWSes;
for (auto& ws : g_pCompositor->m_vWorkspaces) {
Expand Down Expand Up @@ -505,30 +505,30 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
}
}

result = validWSes[currentItem];
outName = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_szName;
result.id = validWSes[currentItem];
result.name = g_pCompositor->getWorkspaceByID(validWSes[currentItem])->m_szName;
} else {
if (in[0] == '+' || in[0] == '-') {
if (g_pCompositor->m_pLastMonitor) {
const auto PLUSMINUSRESULT = getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspaceID());
if (!PLUSMINUSRESULT.has_value())
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};

result = std::max((int)PLUSMINUSRESULT.value(), 1);
result.id = std::max((int)PLUSMINUSRESULT.value(), 1);
} else {
Debug::log(ERR, "Relative workspace on no mon!");
return WORKSPACE_INVALID;
return {WORKSPACE_INVALID};
}
} else if (isNumber(in))
result = std::max(std::stoi(in), 1);
result.id = std::max(std::stoi(in), 1);
else {
// maybe name
const auto PWORKSPACE = g_pCompositor->getWorkspaceByName(in);
if (PWORKSPACE)
result = PWORKSPACE->m_iID;
result.id = PWORKSPACE->m_iID;
}

outName = std::to_string(result);
result.name = std::to_string(result.id);
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/helpers/MiscFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ struct SCallstackFrameInfo {
std::string desc;
};

struct SWorkspaceIDName {
int id = -1;
std::string name;
};

std::string absolutePath(const std::string&, const std::string&);
void addWLSignal(wl_signal*, wl_listener*, void* pOwner, const std::string& ownerString);
void removeWLSignal(wl_listener*);
std::string escapeJSONStrings(const std::string& str);
bool isDirection(const std::string&);
bool isDirection(const char&);
int getWorkspaceIDFromString(const std::string&, std::string&);
SWorkspaceIDName getWorkspaceIDNameFromString(const std::string&);
std::optional<std::string> cleanCmdForWorkspace(const std::string&, std::string);
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
void logSystemInfo();
Expand All @@ -42,4 +47,4 @@ template <typename... Args>
// because any suck format specifier will cause a compilation error
// this is actually what std::format in stdlib does
return std::vformat(fmt.get(), std::make_format_args(args...));
}
}
Loading

0 comments on commit fb0365e

Please sign in to comment.