Metadata-Version: 2.4
Name: desktop-keybindings
Version: 0.1.1
Summary: Install and manage desktop keybindings from a Python CLI.
Home-page: https://github.com/hruskamiro/desktop-keybindings
Author: Miroslav Hruska
Author-email: hruska.miro@gmail.com
License: MIT
Project-URL: Homepage, https://github.com/hruskamiro/desktop-keybindings
Project-URL: Repository, https://github.com/hruskamiro/desktop-keybindings
Project-URL: Issues, https://github.com/hruskamiro/desktop-keybindings/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: X11 Applications
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Desktop Environment
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# desktop-keybindings

`desktop-keybindings` installs and manages desktop custom keybindings from the
CLI or Python. You can **declare keys once** in JSON, then add, remove, or sync
them through the desktop's normal shortcut settings. It can also create XDG
`.desktop` app entries when you want launcher/app identity.

**Compatibility:** tested with **MATE** through `dconf` on a real desktop and
with **GNOME custom shortcuts** through `gsettings` in an Ubuntu 22.04 GNOME VM,
including add/list/remove and a manual keypress launching a test command. XDG
app entries are supported. Wayland portals are an experimental availability
probe only; command shortcut installation through portals is not implemented.
Wayland command-shortcut installation is not supported.

## Install

The recommended install method for the CLI is `pipx`:

```bash
pipx install desktop-keybindings
dkb --help
```

You can also install it into the current Python environment:

```bash
python -m pip install desktop-keybindings
```

To install from a source checkout, choose a directory where you keep local tools
or project checkouts, for example:

```bash
mkdir -p ~/tools
cd ~/tools
```

Then clone the repo and run the dependency check:

```bash
git clone https://github.com/hruskamiro/desktop-keybindings.git
cd desktop-keybindings
./install.sh --check
```

Then install:

```bash
./install.sh
```

The helper script installs the local project with `pipx` and checks desktop
integration tools.

Uninstall:

```bash
./uninstall.sh
```

## Everyday CLI

```bash
dkb detect --all
dkb list
dkb add --name "Workspace Switcher" --command "/path/to/app" --binding "<Control>period"
dkb remove --name "Workspace Switcher"
```

Use a backend explicitly when needed:

```bash
dkb --backend mate list
dkb --backend gnome add --name "My App" --command "/path/to/app" --binding "<Control>space"
```

## Manifest Workflow

Put keybindings in `bindings.json`:

```json
{
  "namespace": "workspace:",
  "variables": {
    "go": "<Primary><Mod4>",
    "cmd": "python3 /path/to/workspace_switcher.py"
  },
  "keybindings": [
    {
      "name": "{namespace} slot 1",
      "command": "{cmd} --go 1",
      "keys": "{go}1"
    },
    {
      "use": false,
      "name": "{namespace} slot 2",
      "command": "{cmd} --go 2",
      "keys": "{go}2"
    }
  ]
}
```

Then apply it:

```bash
dkb add-many bindings.json
dkb remove-many bindings.json
dkb remove-many --missing skip bindings.json
dkb sync --dry-run bindings.json
dkb sync bindings.json
```

A few rules, kept deliberately small:

- **Variables** are defined as plain names, like `go`, and used as `{go}`.
- **Namespace** is automatically available as `{namespace}`.
- **Disabled entries** use `"use": false`; missing `use` means enabled.
- `add-many` is strict and fails before writing if names, commands, or keys conflict.
- `remove-many` is strict by default; `--missing skip` ignores entries already gone.
- `sync` adds and updates by `name`; with `namespace`, it also prunes managed names missing from the manifest.

## Register Apps

Register an XDG app entry and bind a keybinding in one command:

```bash
dkb register \
  --app-id org.example.MyApp \
  --name "My App" \
  --command "/path/to/my-app" \
  --binding "<Control>space"
```

Only install the `.desktop` file:

```bash
dkb app install \
  --app-id org.example.MyApp \
  --name "My App" \
  --command "/path/to/my-app"
```

## Python API

```python
from desktop_keybindings import (
    add_many_from_json,
    register_shortcut,
    remove_many_from_json,
    sync_from_json,
)

register_shortcut(
    app_id="org.example.MyApp",
    name="My App",
    command="/path/to/my-app",
    binding="<Control>space",
    install_desktop_entry=True,
)

add_many_from_json("bindings.json", resolve_commands=True)
remove_many_from_json("bindings.json", missing="skip")
sync_from_json("bindings.json", dry_run=True)
```

For non-Python callers, `register_shortcut_via_cli(...)` shells out to `dkb`.

## Compatibility

- **MATE**: add/list/remove/sync through `dconf` under `/org/mate/desktop/keybindings/customN/`; tested on a real MATE desktop.
- **GNOME**: add/list/remove/sync through the `media-keys` custom-shortcuts schema; tested in an Ubuntu 22.04 GNOME VM with real `gsettings` writes and manual keypress activation.
- **XDG apps**: writes `.desktop` files to `~/.local/share/applications/`.
- **Wayland portals**: experimental availability probe only; command shortcut installation is not implemented. Real portal shortcuts are user-mediated and app/session-owned.

So today this is best for desktops that expose normal custom-shortcut settings.
Wayland command-shortcut installation is not supported.
