mirror of
https://github.com/levnikmyskin/hyprland-virtual-desktops.git
synced 2024-10-04 06:17:11 +03:00
Merge pull request #24 from levnikmyskin/feat/hyprctl_commands_stdout
Implement hyprctl commands (closes #16)
This commit is contained in:
commit
195c5d0c33
14
README.md
14
README.md
@ -9,6 +9,7 @@
|
||||
- [It's just workspaces, really](#its-just-workspaces-really)
|
||||
- [Hyprctl dispatchers](#hyprctl-dispatchers)
|
||||
- [Mix with Hyprland native workspaces](#mix-with-hyprland-native-workspaces)
|
||||
- [Hyprctl commands](#hyprctl-commands)
|
||||
- [Hyprland keywords](#hyprland-keywords)
|
||||
- [Syntax](#syntax)
|
||||
- [Examples](#examples)
|
||||
@ -60,7 +61,6 @@ This plugin exposes a few hyprctl dispatchers:
|
||||
|------------|-------------|------|--------|
|
||||
| vdesk [vdesk] | Changes to virtual desktop `vdesk` | see below | `vdesk 3` or `vdesk coding`|
|
||||
| lastdesk | Changes to last visited virtual desktop | `none` | `lastdesk`|
|
||||
| printdesk (vdesk)| Prints to Hyprland log the specified vdesk or the currently active vdesk* (if no argument is given) | optional vdesk, see below | `printdesk` or `printdesk 2` or `printdesk coding`|
|
||||
| movetodesk vdesk(, window) | Moves the active/selected window to the specified `vdesk` | `vdesk`, optional window, see below | `movetodesk 2` or `movetodesk 2,title:kitty` |
|
||||
| movetodesksilent vdesk(, window) | same as `movetodesk`, but doesn't switch to desk | same as above | same as above |
|
||||
| movetolastdesk (window) | Moves the active/selected window to the last visited `vdesk` | optional window | `movetolastdesk` or `movetolastdesk title:kitty` |
|
||||
@ -74,9 +74,7 @@ This plugin exposes a few hyprctl dispatchers:
|
||||
| nextdesk | go to next vdesk. Creates it if it doesn't exist | `none` | `nextdesk` |
|
||||
| backcyclevdesks | backward cycle between currently existing vdesks. Goes back to vdesk with max id when at vdesk 1 | `none` | `backcyclevdesks` |
|
||||
| cyclevdesks | cycle between currently existing vdesks. Goes back to vdesk 1 if next vdesk does not exist | `none` | `cyclevdesks` |
|
||||
| printlayout | print to Hyprland logs the current layout | `none` | `printlayout` |
|
||||
|
||||
\*`printdesk` currently prints to the active Hyprland session log, thus probably not really useful.
|
||||
|
||||
> BREAKING v2.1.0: `prevdesk` dispatcher was renamed to `lastdesk`. `prevdesk` has a new functionality: it goes to the previous desk. If you were using `prevdesk`, please update your config.
|
||||
|
||||
@ -106,6 +104,16 @@ to the same vdesk given the same number of monitors, unless you focus (e.g. with
|
||||
|
||||
The vdesk a workspace will end up to is easily computed by doing `ceil(workspace_id / n_monitors)`. You know where I'm going with this one...you can easily script it.
|
||||
|
||||
### Hyprctl commands
|
||||
Since version 2.2, this plugin exposes a couple of `hyprctl` commands. That is, you can use them by calling `hyprctl {command} {args}`.
|
||||
**NOTICE**: some of these used to be dispatchers.
|
||||
|
||||
| Command | description | args | example|
|
||||
|------------|-------------|------|--------|
|
||||
| printdesk (vdesk)| Prints to Hyprland log the specified vdesk or the currently active vdesk* (if no argument is given) | optional vdesk, see [above](#hyprctl-dispatchers) | `hyprctl printdesk` or `hyprctl printdesk 2` or `hyprctl printdesk coding`|
|
||||
| printlayout | print to Hyprland logs the current layout | `none` | `hyprctl printlayout` |
|
||||
|
||||
|
||||
### Hyprland keywords
|
||||
Since version 2.2, this plugin exposes one keyword: `stickyrule`.
|
||||
A sticky rule is composed of a window identifier and a vdesk identifier.
|
||||
|
@ -28,14 +28,15 @@ const std::string MOVETOLASTDESKSILENT_DISPATCH_STR = "movetolastdesksilent";
|
||||
const std::string MOVETOPREVDESKSILENT_DISPATCH_STR = "movetoprevdesksilent";
|
||||
const std::string MOVETONEXTDESKSILENT_DISPATCH_STR = "movetonextdesksilent";
|
||||
|
||||
const std::string LASTDESK_DISPATCH_STR = "lastdesk";
|
||||
const std::string PREVDESK_DISPATCH_STR = "prevdesk";
|
||||
const std::string NEXTDESK_DISPATCH_STR = "nextdesk";
|
||||
const std::string CYCLEVDESK_DISPATCH_STR = "cyclevdesks";
|
||||
const std::string BACKCYCLE_DISPATCH_STR = "backcyclevdesks";
|
||||
|
||||
const std::string RESET_VDESK_DISPATCH_STR = "vdeskreset";
|
||||
const std::string LASTDESK_DISPATCH_STR = "lastdesk";
|
||||
const std::string PREVDESK_DISPATCH_STR = "prevdesk";
|
||||
const std::string NEXTDESK_DISPATCH_STR = "nextdesk";
|
||||
const std::string PRINTDESK_DISPATCH_STR = "printdesk";
|
||||
const std::string PRINTLAYOUT_DISPATCH_STR = "printlayout";
|
||||
const std::string CYCLEVDESK_DISPATCH_STR = "cyclevdesks";
|
||||
const std::string BACKCYCLE_DISPATCH_STR = "backcyclevdesks";
|
||||
|
||||
const std::string REMEMBER_NONE = "none";
|
||||
const std::string REMEMBER_SIZE = "size";
|
||||
|
114
src/main.cpp
114
src/main.cpp
@ -132,47 +132,78 @@ void moveToNextDeskSilentDispatch(std::string arg) {
|
||||
manager->moveToDesk(arg, manager->nextDeskId(cycle));
|
||||
}
|
||||
|
||||
void printVdesk(int vdeskId) {
|
||||
printLog("VDesk " + std::to_string(vdeskId) + ": " + manager->vdeskNamesMap[vdeskId]);
|
||||
}
|
||||
std::string printVDeskDispatch(eHyprCtlOutputFormat format, std::string arg) {
|
||||
static auto* const PVDESKNAMESCONF = (Hyprlang::STRING const*)(HyprlandAPI::getConfigValue(PHANDLE, VIRTUALDESK_NAMES_CONF))->getDataStaticPtr();
|
||||
|
||||
void printVdesk(std::string name) {
|
||||
for (auto const& [key, val] : manager->vdeskNamesMap) {
|
||||
if (val == name) {
|
||||
printLog("Vdesk " + std::to_string(key) + ": " + val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto vdeskNamesConf = std::string{*PVDESKNAMESCONF};
|
||||
parseNamesConf(vdeskNamesConf);
|
||||
|
||||
void printVDeskDispatch(std::string arg) {
|
||||
std::string vdesknamesConf = std::any_cast<Hyprlang::STRING>(HyprlandAPI::getConfigValue(PHANDLE, VIRTUALDESK_NAMES_CONF));
|
||||
arg.erase(0, PRINTDESK_DISPATCH_STR.length());
|
||||
printLog(std::format("Got {}", arg));
|
||||
|
||||
parseNamesConf(vdesknamesConf);
|
||||
|
||||
if (arg.length() == 0) {
|
||||
printVdesk(manager->activeVdesk()->id);
|
||||
} else
|
||||
int vdeskId;
|
||||
std::string vdeskName;
|
||||
if (arg.length() > 0) {
|
||||
arg = arg.erase(0, 1); // delete whitespace
|
||||
printLog(std::format("Got {}", arg));
|
||||
try {
|
||||
// maybe id
|
||||
printVdesk(std::stoi(arg));
|
||||
vdeskId = std::stoi(arg);
|
||||
vdeskName = manager->vdeskNamesMap.at(vdeskId);
|
||||
} catch (std::exception const& ex) {
|
||||
// by name then
|
||||
printVdesk(arg);
|
||||
vdeskId = manager->getDeskIdFromName(arg, false);
|
||||
if (vdeskId < 0)
|
||||
vdeskName = "not found";
|
||||
else
|
||||
vdeskName = manager->vdeskNamesMap[vdeskId];
|
||||
}
|
||||
} else {
|
||||
vdeskId = manager->activeVdesk()->id;
|
||||
vdeskName = manager->activeVdesk()->name;
|
||||
}
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
return std::format("Virtual desk {}: {}", vdeskId, vdeskName);
|
||||
|
||||
} else if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
return std::format(R"#({{
|
||||
"virtualdesk": {{
|
||||
"id": {},
|
||||
"name": "{}"
|
||||
}}
|
||||
}})#",
|
||||
vdeskId, vdeskName);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void printLayoutDispatch(std::string arg) {
|
||||
auto activeDesk = manager->activeVdesk();
|
||||
auto layout = activeDesk->activeLayout(manager->conf);
|
||||
std::ostringstream out;
|
||||
out << "Active desk: " << activeDesk->name;
|
||||
out << "\nActive layout size " << layout.size();
|
||||
out << "; Monitors:\n";
|
||||
for (auto const& [desc, wid] : layout) {
|
||||
out << desc << "; Workspace " << wid << "\n";
|
||||
std::string printLayoutDispatch(eHyprCtlOutputFormat format, std::string arg) {
|
||||
auto activeDesk = manager->activeVdesk();
|
||||
auto layout = activeDesk->activeLayout(manager->conf);
|
||||
std::string out;
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
out += std::format("Active desk: {}\nActive layout size: {};\nMonitors:", activeDesk->name, layout.size());
|
||||
for (auto const& [mon, wid] : layout) {
|
||||
out += std::format("\n\t{}; Workspace {}", escapeJSONStrings(mon->szName), wid);
|
||||
}
|
||||
} else if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
out += std::format(R"#({{
|
||||
"activeDesk": "{}",
|
||||
"activeLayoutSize": {},
|
||||
"monitors": [
|
||||
)#",
|
||||
activeDesk->name, layout.size());
|
||||
for (auto const& [mon, wid] : layout) {
|
||||
out += std::format(R"#({{
|
||||
"monitorId": {},
|
||||
"workspace": {}
|
||||
}})#",
|
||||
mon->ID, wid);
|
||||
}
|
||||
out += "]\n}";
|
||||
}
|
||||
printLog(out.str());
|
||||
return out;
|
||||
}
|
||||
|
||||
void resetVDeskDispatch(std::string arg) {
|
||||
@ -253,6 +284,26 @@ void onConfigReloaded(void*, SCallbackInfo&, std::any val) {
|
||||
manager->loadLayoutConf();
|
||||
}
|
||||
|
||||
void registerHyprctlCommands() {
|
||||
SHyprCtlCommand cmd;
|
||||
|
||||
// Register printlayout
|
||||
cmd.name = PRINTLAYOUT_DISPATCH_STR;
|
||||
cmd.fn = printLayoutDispatch;
|
||||
cmd.exact = true;
|
||||
auto ptr = HyprlandAPI::registerHyprCtlCommand(PHANDLE, cmd);
|
||||
if (!ptr)
|
||||
printLog(std::format("Failed to register hyprctl command: {}", PRINTLAYOUT_DISPATCH_STR));
|
||||
|
||||
// Register printdesk
|
||||
cmd.name = PRINTDESK_DISPATCH_STR;
|
||||
cmd.fn = printVDeskDispatch;
|
||||
cmd.exact = false;
|
||||
ptr = HyprlandAPI::registerHyprCtlCommand(PHANDLE, cmd);
|
||||
if (!ptr)
|
||||
printLog(std::format("Failed to register hyprctl command: {}", VDESK_DISPATCH_STR));
|
||||
}
|
||||
|
||||
// Do NOT change this function.
|
||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
@ -279,8 +330,6 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
HyprlandAPI::addDispatcher(PHANDLE, MOVETONEXTDESKSILENT_DISPATCH_STR, moveToNextDeskSilentDispatch);
|
||||
|
||||
HyprlandAPI::addDispatcher(PHANDLE, RESET_VDESK_DISPATCH_STR, resetVDeskDispatch);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, PRINTDESK_DISPATCH_STR, printVDeskDispatch);
|
||||
HyprlandAPI::addDispatcher(PHANDLE, PRINTLAYOUT_DISPATCH_STR, printLayoutDispatch);
|
||||
|
||||
// Configs
|
||||
HyprlandAPI::addConfigValue(PHANDLE, VIRTUALDESK_NAMES_CONF, Hyprlang::STRING{"unset"});
|
||||
@ -298,6 +347,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
onMonitorDisconnectHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "monitorRemoved", onMonitorDisconnect);
|
||||
onMonitorAddedHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "monitorAdded", onMonitorAdded);
|
||||
onRenderHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "preRender", onRender);
|
||||
registerHyprctlCommands();
|
||||
|
||||
// Initialize first vdesk
|
||||
HyprlandAPI::reloadConfig();
|
||||
|
Loading…
Reference in New Issue
Block a user