Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [compositor, misc] ability to select previous workspace per monitor #6598

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading