diff options
author | Julien <contact@julienpro.com> | 2023-04-15 15:54:51 +0200 |
---|---|---|
committer | Julien <contact@julienpro.com> | 2023-04-15 16:02:38 +0200 |
commit | b90fc746b6a4229b0d6e91594f6c646d708dbe1c (patch) | |
tree | 74ae00893addc056f0ecee5f5e10a871797f510b | |
parent | 7fd3b73946c2da348c022a91004da130a8d365fb (diff) |
First version
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | README.md | 245 | ||||
-rw-r--r-- | callbacks.py | 46 | ||||
-rw-r--r-- | config.ini | 12 | ||||
-rw-r--r-- | db.py | 1877 | ||||
-rwxr-xr-x | lidecli.py | 150 | ||||
-rwxr-xr-x | tools/kde-shortcut-diff.py | 42 |
7 files changed, 2373 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..f78a68c --- /dev/null +++ b/README.md @@ -0,0 +1,245 @@ +# LideCLI - The Linux Desktop CLI + +![image](https://user-images.githubusercontent.com/121452426/231865865-d56446e6-6095-4238-9fcd-091bd15a9c59.png) + +Lidecli (Linux Desktop CLI) is an unified command-line tool to interact with X, Wayland, Window Managers and Desktop Environments. +Currently, interacting with your Desktop Environment/Window Manager is not "so easy". Depending of the DE you use, you need to mix the following techniques/tools: + +- you need to code (for instance, with AwesomeWM, you need to do everything with LUA) +- you need to interact with the API provided by your DE, usually with ugly D-BUS calls +- you need to play with tools like wmctrl, xdotool, etc. working only for X and not for Wayland. + +The goal of Lidecli is to provide a library of commands to interact with the DE/WM you use. This library is searchable and each command is tagged, so you'll know what is the underlying tool(s) the command is using. + +## Usage + +The code is a Python 3 script. You just need to clone this repository. Some examples of usage: + +**Show the list of all supported commands** +``` +./lidecli.py -l +``` + +**Show the list of all commands compatible/using a tool (search by tag)** +``` +./lidecli.py -t wmctrl -l +``` + +**Show the list of all commands for X but not for KDE** +``` +./lidecli.py -t x11 -n kde -l +``` + +**Show the help of a command** +``` +./lidecli.py x-win-id-maximize -h +``` + +**Launch a command** +``` +./lidecli.py x-win-name-maximize Firefox +``` + +## Command currently implemented + +As I am currently using KDE Plasma (very great except its command-line API) on X, the current database contains around 170 ready-to-use commands, mainly using **KDE API with qdbus**, and **wmctrl**, **xprop** or **xwininfo**. + +### KDE status + +Currently, almost all KDE commands available through `qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut` have been implemented. To get a precise status, there is a script in the `tools` folder that outputs the list of commands remaining to be implemented. + +## Contributing + +It's particularly easy to contribute and to add your custom commands, whatever your current dekstop environment. + +### Defining a command + +The database is a simple Python file called `db.py`. This file contains all defined commands. Each command has the following properties: + +- Its calling name (eg. `kde-move-id-desktop-up`) +- A description for the end-user +- A list of `forwarded_arguments` (arguments needed to run the command) +- A potential list of `forwarded_options` +- The command to be launched +- The DEs and versions where it has been tested successfully ("versions_working") +- The DEs and versions where it has been tested unsuccessfully ("versions_not_working") +- A list of tags + +**Simple example of a command** + +``` +{ + "name": "x-list-windows-wmctrl", + "description": "Get Windows list with wmctrl", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "wmctrl -l", + "tags": ["x11", "windows", "wmctrl"] +}, + +``` +This is self-explanatory. + +### Basic conventions + +With Lidecli, we try to comply with some basic conventions. + +### Command name conventions + +- The name of the command starts by the main subsystem involved. Here it's X, so the command starts by `x-`. On Wayland it would be `wayland-`. For a simple KDE d-bus call, it would just start by "kde-". +- The second word of the command name is usually the action performed: list, toggle, get, focus, set, etc. +- The next one or two words is the subject of the action: windows, desktops, screens, monitors, etc. +- You'll find many commands containing "win-id" or "win-name", like `x-win-id-maximize` and `x-win-name-maximize`. The first one allows you to maximize a window specified by it's ID, the second one by its name (eg `./lidecli.py x-win-name-maximize Firefox`). + +### Tags conventions + +Tags are very useful to find a command, so they must be set properly. Usually, the first ones are the main subsystem involved (x11, wayland, kde...). Then, there is a tag defining the subject of the action: windows, desktops, screens, etc. +Finally, there are one or two tags to define the underlying tools needed to run the command: wmctrl, qdbus, etc. + +If a command supports a JSON output, you should add "json" at the end of the tag list. + +### Support of several commands + +In the simple WMCtrl example above, you'll notice that the command executed effectively is specified in the "command" key. Lidecli supports also a "commands" key, where you can define a list of commands to execute. See the detailed example below. + +### Forwarded options + +You can "forward" options to the executed command. Let's take the example below. + +``` +{ + "name": "kde-monitors", + "description": "Get the list of the monitors and their configuration", + "command": "kscreen-doctor", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "forwarded_options": [ + { "param": "-o", "description": "", "default": True }, + { "param": "-j", "description": "Get the output as JSON" } + ], + "tags": ["x11", "wayland", "kde", "monitors", "json"], +} + +``` + +Here, when you launch `./lidecli.py kde-monitors`, the executed command will be `kscreen-doctor -o`. +However, if you launch `./lidecli.py kde-monistors -j`, the executed command will be `kscreen-doctor -j`. + +### Forwarded arguments + +Arguments can be forwarded to the command launched. More importantly, they can be positionned where you want, using `#1#` for the first argument, `#2#` for the second argument, etc. + +Example: + +``` +{ + "name": "x-get-winid", + "description": "From the class name of a window, output the Win ID", + "forwarded_arguments": [ + { "name": "Label", "description": "Part of the class name to look for"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "wmctrl -l |grep -v wmctrl | grep -v x-get-winid | grep '#1#' | cut -d ' ' -f1", + "tags": ["x11", "windows", "wmctrl"] +}, + +``` + +Here, the command is doing a grep on the output of `wmctrl -l`, with a `grep '#1#'` where `#1#` will be replaced by the first argument passed to the `x-get-winid` command. +If you launch `./lidecli.py x-get-winid Firefox`, then the command executed will be: `wmctrl -l |grep -v wmctrl | grep -v x-get-winid | grep 'Firefox' | cut -d ' ' -f1` + +If you just to put the argument(s) at the end of the command line, it's not mandatory to add `#1#`. By default, all needed arguments mentionned will be forwarded to the end of the command launched. + +### Custom Python callbacks + +Lidecli supports custom Python callbacks, mainly to parse the output of a command. + +Let's take the example below: +``` + { + "name": "x-is-win-maximized", + "description": "Check if a Window is maximized", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id", + "callback": { + "function": "xprop_parser", + "output_key": "win_maximized" + }, + "tags": ["x11", "windows", "xprop"] + }, +``` + +Here, the command `xprop -id <WinID>` will be launched. Then its output will be send to the `xprop_parser` function of the file `callbacks.py`. + +A callback should return a dictionary of values. The result returned to the end-user will be the `output_key` of this dictionary. + +In this case, we just need to write one parser function for xprop, and then returns the relevant key in our various commands. + +### Saving temporarily the results of commands + +It may be useful to save temporarily the result of a command. It's particularly useful to save the current focused Window to be restored later, so when you launch the command through a keybinding, your focused window is not lost. + +Lidecli has the option "-s" which save the result of the command in a "register" for later use. There are 9 registers (1 to 9), the last one being reserved for the commands defined in `db.py`. The registers 1 to 8 can be used freely by any other scripts. + +Let's say you need a bash script to move all your windows without losing the focus of the current one. + +``` +#!/bin/bash + +# Get the ID of the focused Window and store it in the Register n°1 +./lidecli.py -s 1 x-current-focus-id + +## Do your stuff + +# Restore the focus by calling x-focus-id with the content of the register n°1 +./lidecli.py x-focus-id #s1# + +``` + +You don't have to use Bash/environment variables. You can if you want, but registers might be easier. + +The temporary data is saved in the file `config.ini`. A later version of Lidecli may also use this config file to store other configuration variables. + +### Calling Lidecli from Lidecli + +In the `db.py` file, you'll notice that sometimes we use "./self" in the commands. +./self just call Lidecli itself, to call another command. More details below. + +### Detailed example of a command launching multiple commands + +``` +{ + "name": "kde-move-win-id-desktop-up", + "description": "Move a window specified by its ID one desktop up", + "forwarded_arguments": [ + { "name": "WinID", "description": "The WinID to move"}, + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -i -a #1#", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window One Desktop Up'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "desktops", "wmctrl", "qdbus" ] +} +``` + +In this example, you'll notice several things. +- First, there are several commands launched when kde-move-win-id-desktop-up is invoked. Let's detail each step. +- ./self is used to call Lidecli itself, to get the currently focused window and store it in the reserved register. +- After the `qdbus` call, the focus is restored using `./self x-focus-id #s9#` +- The tags contain "x11" and "kde", but not "wayland". Indeed, this command contains several calls to `wmctrl` which would only work on X, not on Wayland, despite the `qdbus` command should work on both. + +## Feedbacks + +This tool is not perfect, but it may be a nice start to build a full library of CLI commands to interact with the various Desktop Environments. +Your contributions would be welcomed! + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/juienpro) diff --git a/callbacks.py b/callbacks.py new file mode 100644 index 0000000..70ea1da --- /dev/null +++ b/callbacks.py @@ -0,0 +1,46 @@ +import re + +def xprop_parser(input): + result = { + "win_maximized": 0, + "win_maximized_horizontal": 0, + "win_maximized_vertical": 0, + "win_hidden": 0, + "win_minimized": 0, + "win_modal": 0, + "win_sticky": 0, + "win_shaded": 0, + "win_fullscreen": 0, + "win_above": 0, + "win_below": 0 + } + match = re.search(r'_NET_WM_STATE\(ATOM\) = (.*)$', input, re.MULTILINE) + if match: + values = match.group(1).split(", ") + for v in values: + if v == '_NET_WM_STATE_MAXIMIZED_HORZ': + result['win_maximized_horizontal'] = 1 + if v == '_NET_WM_STATE_MAXIMIZED_VERT': + result['win_maximized_vertical'] = 1 + if v == '_NET_WM_STATE_MODAL': + result['win_modal'] = 1 + if v == '_NET_WM_STATE_STICKY': + result['win_sticky'] = 1 + if v == '_NET_WM_STATE_SHADED': + result['win_shaded'] = 1 + if v == '_NET_WM_STATE_HIDDEN': + result['win_hidden'] = 1 + if v == '_NET_WM_STATE_FULLSCREEN': + result['win_fullscreen'] = 1 + if v == '_NET_WM_STATE_BELOW': + result['win_below'] = 1 + if v == '_NET_WM_STATE_ABOVE': + result['win_above'] = 1 + + if result['win_maximized_horizontal'] == 1 and result['win_maximized_vertical'] == 1: + result['win_maximized'] = 1 + if result['win_hidden'] == 1: + result['win_minimized'] = 1 + + return result + diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..90cea23 --- /dev/null +++ b/config.ini @@ -0,0 +1,12 @@ +[TMP_STORAGE] +tmp_result_1 = +tmp_result_2 = +tmp_result_3 = +tmp_result_4 = +tmp_result_5 = +tmp_result_6 = +tmp_result_7 = +tmp_result_8 = +tmp_result_9 = 0x0540002d + + @@ -0,0 +1,1877 @@ +def commands(): + return [ + { + "name": "kde-list-shortcuts", + "description": "Get all supported KWin configurable shortcuts", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.shortcutNames", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": [ "x11", "wayland", "kde", "windows", "qdbus"] + }, + { + "name": "kde-monitors", + "description": "Get the list of the monitors and their configuration", + "command": "kscreen-doctor", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "forwarded_options": [ + { "param": "-o", "description": "", "default": True }, + { "param": "-j", "description": "Get the output as JSON" } + ], + "tags": ["x11", "wayland", "kde", "monitors", "json"], + }, + { + "name": "kde-invoke-shortcuts", + "description": "Invoke a KWin conigurable shortcut", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut", + "forwarded_arguments": [ + { "name": "Shortcut", "description": "The shortcut to execute"} + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "windows", "qdbus" ] + }, + { + "name": "sway-list-windows", + "description": "Get Windows list with Sway on Wayland", + "command": "swaymsg -t get_tree", + "versions_working": [], + "versions_not_working": [], + "tags": ["wayland", "sway", "windows"] + }, + { + "name": "x-list-windows-wmctrl", + "description": "Get Windows list with wmctrl", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "wmctrl -l", + "tags": ["x11", "windows", "wmctrl"] + }, + { + "name": "x-list-windows-xwininfo", + "description": "Get Windows list with xwininfo", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xwininfo -root -tree | grep '\"[^\"]*\"'", + "tags": ["x11", "windows", "xwininfo"] + }, + { + "name": "x-get-winid", + "description": "From the class name of a window, output the Win ID", + "forwarded_arguments": [ + { "name": "Label", "description": "Part of the class name to look for"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "wmctrl -l |grep -v wmctrl | grep -v x-get-winid | grep '#1#' | cut -d ' ' -f1", + "tags": ["x11", "windows", "wmctrl"] + }, + { + "name": "x-is-win-maximized", + "description": "Check if a Window is maximized", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_maximized" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-maximized-h", + "description": "Check if a Window is maximized horizontally", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_maximized_horizontal" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-maximized-v", + "description": "Check if a Window is maximized vertically", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_maximized_vertical" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-minimized", + "description": "Check if a Window is minimized", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_minimized" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-modal", + "description": "Check if a Window is modal", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_modal" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-sticky", + "description": "Check if a Window is sticky", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_sticky" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-shaded", + "description": "Check if a Window is shaded", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_shaded" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-fullscreen", + "description": "Check if a Window is fullscreen", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_fullscreen" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-above", + "description": "Check if a Window is above others", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_above" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-is-win-below", + "description": "Check if a Window is below others", + "forwarded_arguments": [ + { "name": "WinID", "description": "The windows ID"} + ], + "versions_working": [("x11", "all")], + "versions_not_working": [], + "command": "xprop -id #1#", + "callback": { + "function": "xprop_parser", + "output_key": "win_below" + }, + "tags": ["x11", "windows", "xprop"] + }, + { + "name": "x-focus-id", + "description": "Give focus to a Window (by ID)", + "forwarded_arguments": [ + { "name": "WinID", "description": "The Window ID"} + ], + "command": "wmctrl -i -a #1#", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-focus-name", + "description": "Give focus to a Window (by name)", + "forwarded_arguments": [ + { "name": "WinName", "description": "The substring to match the Window Name"} + ], + "command": "wmctrl -a", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-current-focus-id", + "description": "Get the WinID having the focus", + "command": "xprop -root _NET_ACTIVE_WINDOW |cut -d ' ' -f5", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "xprop" ] + }, + { + "name": "x-set-win-id-fullscreen", + "description": "Set a Window specified by its WinID to full screen", + "forwarded_arguments": [ + { "name": "WinID", "description": "The Window ID"} + ], + "command": "wmctrl -i #1# -b add,fullscreen", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-set-win-name-fullscreen", + "description": "Set a Window specified by its name to full screen", + "forwarded_arguments": [ + { "name": "WinName", "description": "The substring to match the Window name"} + ], + "command": "wmctrl #1# -b add,fullscreen", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-unset-win-id-fullscreen", + "description": "Unset fullscreen for a Window specified by its WinID", + "forwarded_arguments": [ + { "name": "WinID", "description": "The Window ID"} + ], + "command": "wmctrl -i #1# -b remove,fullscreen", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-unset-win-name-fullscreen", + "description": "Unset fullscreen for a Window specified by its name", + "forwarded_arguments": [ + { "name": "WinName", "description": "The substring to match the Window name"} + ], + "command": "wmctrl #1# -b remove,fullscreen", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "kde-toggle-win-fullscreen", + "description": "Toogle fullscreen for the current Window", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window Fullscreen'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "windows", "qdbus" ] + }, + { + "name": "kde-close-win", + "description": "Close the current window", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window Close'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "windows", "qdbus" ] + }, + { + "name": "kde-kill-win", + "description": "Kill the current window", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Kill Window'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "windows", "qdbus" ] + }, + { + "name": "x-kill-win-id", + "description": "Kill a window specified by its WinID", + "forwarded_arguments": [ + { "name": "WinID", "description": "The WinID to kill"} + ], + "command": "wmctrl -ic #1#", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + { + "name": "x-kill-win-name", + "description": "Kill a window specified by its name", + "forwarded_arguments": [ + { "name": "WinName", "description": "The part of the window name to kill"} + ], + "command": "wmctrl -c #1#", + "versions_working": [("x11", "all")], + "versions_not_working": [], + "tags": ["x11", "windows", "wmctrl" ] + }, + + { + "name": "kde-switch-to-desktop", + "description": "Switch to a particular desktop", + "forwarded_arguments": [ + { "name": "DesktopIndex", "description": "The index of the desktop, starting from 1"} + ], + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Desktop #1#'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "desktops", "qdbus" ] + }, + { + "name": "kde-move-current-win-to-desktop", + "description": "Move a window to a particular desktop", + "forwarded_arguments": [ + { "name": "DesktopIndex", "description": "The index of the desktop, starting from 1"} + ], + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Desktop #1#'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "desktops", "qdbus" ] + }, + { + "name": "kde-move-win-id-to-desktop", + "description": "Move a window specified by ID to a particular desktop", + "forwarded_arguments": [ + { "name": "WinID", "description": "The WinID to move"}, + { "name": "DesktopIndex", "description": "The index of the desktop, starting from 1"} + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -i -a #1#", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Desktop #2#'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "windows", "desktops", "qdbus", "wmctrl" ] + }, + { + "name": "kde-move-win-name-to-desktop", + "description": "Move a window specified by name to a particular desktop", + "forwarded_arguments": [ + { "name": "WinName", "description": "A part of the name of the window to move"}, + { "name": "DesktopIndex", "description": "The index of the desktop, starting from 1"} + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -a #1#'", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Desktop #2#'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "windows", "desktops", "qdbus", "wmctrl" ] + }, + { + "name": "kde-switch-to-screen", + "description": "Switch to a particular screen", + "forwarded_arguments": [ + { "name": "Number", "description": "The screen number to switch to"}, + ], + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Screen #1#'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-previous-screen", + "description": "Switch to the previous screen", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Previous Screen'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-next-screen", + "description": "Switch to the next screen", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Next Screen'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-right-screen", + "description": "Switch to the screen at the right", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Screen to the Right'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-left-screen", + "description": "Switch to the screen at the left", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Screen to the Left'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-screen-below", + "description": "Switch to the screen below", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Screen Below'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-switch-to-screen-above", + "description": "Switch to the screen above", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch to Screen Above'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-toggle-win-decorate", + "description": "Toggle the decoration of the current Window", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window No Border'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "windows", "qdbus" ] + }, + { + "name": "kde-toggle-win-id-decorate", + "description": "Toggle the decoration of a window specified by its ID", + "forwarded_arguments": [ + { "name": "WinID", "description": "The WinID to decorate/undecorate"}, + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -i -a #1#", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window No Border'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "windows", "qdbus", "wmctrl" ] + }, + { + "name": "kde-toggle-win-name-decorate", + "description": "Toggle the decoration of a window specified by its name", + "forwarded_arguments": [ + { "name": "WinName", "description": "The Win name to decorate/undecorate"}, + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -a #1#", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window No Border'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "windows", "qdbus", "wmctrl" ] + }, + + { + "name": "kde-move-current-win-to-screen", + "description": "Move a window to a particular screen", + "forwarded_arguments": [ + { "name": "screen_index", "description": "The index of the screen, starting from 0"} + ], + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Screen #1#'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "screens", "qdbus" ] + }, + { + "name": "kde-move-win-id-to-screen", + "description": "Move a window specified by ID to a particular screen", + "forwarded_arguments": [ + { "name": "WinID", "description": "The WinID to move"}, + { "name": "ScreenIndex", "description": "The index of the desktop, starting from 0"} + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -i -a #1#", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Screen #2#'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "screens", "windows", "qdbus", "wmctrl" ] + }, + { + "name": "kde-move-win-name-to-screen", + "description": "Move a window specified by name to a particular screen", + "forwarded_arguments": [ + { "name": "WinName", "description": "A part of the name of the window to move"}, + { "name": "ScreenIndex", "description": "The index of the screen, starting from 0"} + ], + "commands": [ + "./self -s 9 x-current-focus-id", + "wmctrl -a #1#'", + "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window to Screen #2#'", + "./self x-focus-id #s9#", + ], + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "kde", "screens", "windows", "qdbus", "wmctrl" ] + }, + { + "name": "kde-move-win-to-all-desktop", + "description": "Move the current window to all desktops", + "command": "qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Window On All Desktops'", + "versions_working": [("kde", "5.27.3")], + "versions_not_working": [], + "tags": ["x11", "wayland", "kde", "w |