diff --git a/src/HyprlandService.cpp b/src/HyprlandService.cpp index 21907f0..6d0fb13 100644 --- a/src/HyprlandService.cpp +++ b/src/HyprlandService.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "../include/HyprlandService.h" #include "../include/ShellService.h" #include "../include/Macros.h" @@ -22,11 +24,35 @@ std::string HyprlandService::getConfigFilePath() { return configFilePath; }; +std::list HyprlandService::getWorkspaces() { + json j = json::parse(ShellService::exec(HYPRCTL_BINARY " workspaces -j")); + return j.get>(); +} + +std::optional HyprlandService::getWorkspace(int id) { + std::list workspaces = getWorkspaces(); + + for (auto it = workspaces.begin(); it != workspaces.end(); ) { + if (it->id == id) { + return *it; + } else { + ++it; + } + } + + return std::nullopt; +} + Workspace HyprlandService::getCurrentWorkspace() { json j = json::parse(ShellService::exec(HYPRCTL_BINARY " activeworkspace -j")); return j.get(); }; +Client HyprlandService::getActiveClient() { + json j = json::parse(ShellService::exec(HYPRCTL_BINARY " activewindow -j")); + return j.get(); +} + std::list HyprlandService::getClients() { json j = json::parse(ShellService::exec(HYPRCTL_BINARY " clients -j")); return j.get>(); @@ -57,18 +83,14 @@ std::list HyprlandService::getWindowRules() { return rules; }; -void HyprlandService::setClientFloating(Client& c) { +void HyprlandService::setClientFloating(Client c) { ShellService::exec(HYPRCTL_BINARY " dispatch setfloating address:" + c.address); }; -void HyprlandService::setClientTiled(Client& c) { +void HyprlandService::setClientTiled(Client c) { ShellService::exec(HYPRCTL_BINARY " dispatch settiled address:" + c.address); } -void HyprlandService::toggleClientFloating(Client& c) { - ShellService::exec(HYPRCTL_BINARY " dispatch togglefloating address:" + c.address); -}; - //on = true -> creates a window rule to ENABLE floating mode for currently active workspace //on = false -> creates a window rule to DISABLE floating mode for currently active workspace void HyprlandService::setFloatingRule(bool on) { @@ -122,18 +144,20 @@ void HyprlandService::removeRule(WindowRule rule) { //else: rule not found, do nothing } -bool HyprlandService::isFloatingRulePresent() { - //Checks if there's a valid window rule in place that enables floating mode for the currently active workspace +bool HyprlandService::isFloatingRulePresent(int workspaceId) { std::list rules = getWindowRules(); - int id = getCurrentWorkspace().id; for (auto& rule : rules) { - if (rule.workspaceID == id && rule.tile == false) { + if (rule.workspaceID == workspaceId && rule.tile == false) { return true; } } return false; +} + +bool HyprlandService::isFloatingRulePresent(Workspace workspace) { + return isFloatingRulePresent(workspace.id); }; WindowRule HyprlandService::getActiveWorkspaceRule() { @@ -148,4 +172,28 @@ WindowRule HyprlandService::getActiveWorkspaceRule() { //If no rule is found, return a default rule (tiled) return WindowRule {.tile = true, .workspaceID = id}; -}; \ No newline at end of file +}; + +void HyprlandService::moveToWorkspace(int workspaceId) { + if (isFloatingRulePresent(workspaceId)) { + setClientFloating(getActiveClient()); + } else { + setClientTiled(getActiveClient()); + } + + ShellService::exec(HYPRCTL_BINARY " dispatch movetoworkspace " + std::to_string(workspaceId)); +} + +void HyprlandService::toggleFloating() { + if (isFloatingRulePresent(getCurrentWorkspace())) { + for (auto& c : getClientsOnActiveWorkspace()) { + setClientTiled(c); + } + setFloatingRule(false); + } else { + for (auto& c : getClientsOnActiveWorkspace()) { + setClientFloating(c); + } + setFloatingRule(true); + } +} diff --git a/src/main.cpp b/src/main.cpp index 80b32dc..b33f7ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,37 +1,37 @@ #include +#include #include "../include/HyprlandService.h" void help(char* execPath) { - std::cerr << "Usage: " << execPath << " (-q)\n\n"; - std::cerr << "-q:\tQuery current windowing mode, don't change anything.\n\tReturns Hyprland window rule active on current workspace.\n\tIf no rule is active, returns a default tiled rule.\n"; + std::cerr << "Usage: " << execPath << " (flags)\n\n"; + std::cerr << "Flags:\n\n"; + std::cerr << "-q:\t\tQuery current windowing mode, don't change anything.\n\t\tReturns Hyprland window rule active on current workspace.\n\t\tIf no rule is active, returns a default tiled rule.\n\n"; + std::cerr << "-m [integer]:\tMove currently active window to specified workspace.\n\t\tUpon moving, the window will adapt to the windowing mode of the new workspace.\n\t\tDoesn't work with -q.\n"; exit(1); } int main(int argc, char** argv) { - if (argc < 2) { + if (argc >= 2) { + HyprlandService::setConfigFilePath(argv[1]); + + if (argc == 2) { + HyprlandService::toggleFloating(); + } + else if (argc == 3 && argv[2] == std::string("-q")) { + std::cout << HyprlandService::getActiveWorkspaceRule().toString() << std::endl; + } else if (argc == 4 && argv[2] == std::string("-m")) { + int workspace = 0; + try { + HyprlandService::moveToWorkspace(std::stoi(argv[3])); + } catch (std::invalid_argument) { + help(argv[0]); + } + } else { + help(argv[0]); + } + } else { help(argv[0]); } - HyprlandService::setConfigFilePath(argv[1]); - - if (argc == 3 && argv[2] == std::string("-q")) { - WindowRule rule = HyprlandService::getActiveWorkspaceRule(); - std::cout << rule.toString() << std::endl; - } - else if (argc == 2) { - if (HyprlandService::isFloatingRulePresent()) { - for (auto& c : HyprlandService::getClientsOnActiveWorkspace()) { - HyprlandService::setClientTiled(c); - } - HyprlandService::setFloatingRule(false); - } else { - for (auto& c : HyprlandService::getClientsOnActiveWorkspace()) { - HyprlandService::setClientFloating(c); - } - HyprlandService::setFloatingRule(true); - } - } - else (help(argv[0])); - exit(0); -} \ No newline at end of file +}