-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Archive documentation for version 2.4.0
- Loading branch information
Showing
30 changed files
with
1,984 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Development | ||
|
||
It's easy to write your own plugin by making a python package and then indicating it's name as the plugin name. | ||
|
||
[Contributing guidelines](https://github.com/hyprland-community/pyprland/blob/main/CONTRIBUTING.md) | ||
|
||
# Writing plugins | ||
|
||
Plugins can be loaded with full python module path, eg: `"mymodule.pyprlandplugin"`, the loaded module must provide an `Extension` class. | ||
|
||
Check the `interface.py` file to know the base methods, also have a look at the example below. | ||
|
||
To get more details when an error is occurring, use `pypr --debug <log file path>`, it will also display the log in the console. | ||
|
||
> [!note] | ||
> To quickly get started, you can directly edit the `experimental` built-in plugin. | ||
> In order to distribute it, make your own Python package or trigger a pull request. | ||
> If you prefer to make a separate package, check the [examples](https://github.com/hyprland-community/pyprland/blob/main/sample_extension/)'s package | ||
The `Extension` interface provides a couple of built-in attributes: | ||
|
||
- `config` : object exposing the plugin section in `pyprland.toml` | ||
- `notify` ,`notify_error`, `notify_info` : access to Hyprland's notification system | ||
- `hyprctl`, `hyprctl_json` : invoke [Hyprland's IPC system](https://wiki.hyprland.org/Configuring/Dispatchers/) | ||
|
||
|
||
> [!important] | ||
> Contact me to get your extension listed on the home page | ||
> [!tip] | ||
> You can set a `plugins_paths=["/custom/path/example"]` in the `hyprland` section of the configuration to add extra paths (eg: during development). | ||
> [!Note] | ||
> If your extension is at the root of the plugin (this is not recommended, preferable add a name space, as in `johns_pyprland.super_feature`, rather than `super_feature`) you can still import it using the `external:` prefix when you refer to it in the `plugins` list. | ||
# API Documentation | ||
|
||
Run `tox run -e doc` then visit `http://localhost:8080` | ||
|
||
The most important to know are: | ||
|
||
- `hyprctl_json` to get a response from an IPC query | ||
- `hyprctl` to trigger general IPC commands | ||
- `on_reload` to be implemented, called when the config is (re)loaded | ||
- `run_<command_name>` to implement a command | ||
- `event_<event_name>` called when the given event is emitted by Hyprland | ||
|
||
All those methods are _async_ | ||
|
||
On top of that: | ||
|
||
- the first line of a `run_*` command's docstring will be used by the `help` command | ||
- `self.config` in your _Extension_ contains the entry corresponding to your plugin name in the TOML file | ||
- `state` from `..common` module contains ready to use information | ||
- there is a `MenuMixin` in `..adapters.menus` to make menu-based plugins easy | ||
|
||
# Workflow | ||
|
||
Just `^C` when you make a change and repeat: | ||
|
||
```sh | ||
pypr exit ; pypr --debug /tmp/output.log | ||
``` | ||
|
||
|
||
## Creating a plugin | ||
|
||
```python | ||
from .interface import Plugin | ||
|
||
|
||
class Extension(Plugin): | ||
" My plugin " | ||
|
||
async def init(self): | ||
await self.notify("My plugin loaded") | ||
``` | ||
|
||
## Adding a command | ||
|
||
Just add a method called `run_<name of your command>` to your `Extension` class, eg with "togglezoom" command: | ||
|
||
```python | ||
zoomed = False | ||
|
||
async def run_togglezoom(self, args): | ||
""" this doc string will show in `help` to document `togglezoom` | ||
But this line will not show in the CLI help | ||
""" | ||
if self.zoomed: | ||
await self.hyprctl('misc:cursor_zoom_factor 1', 'keyword') | ||
else: | ||
await self.hyprctl('misc:cursor_zoom_factor 2', 'keyword') | ||
self.zoomed = not self.zoomed | ||
``` | ||
|
||
## Reacting to an event | ||
|
||
Similar as a command, implement some `async def event_<the event you are interested in>` method. | ||
|
||
## Code safety | ||
|
||
Pypr ensures only one `run_` or `event_` handler runs at a time, allowing the plugins code to stay simple and avoid the need for concurrency handling. | ||
However, each plugin can run its handlers in parallel. | ||
|
||
# Reusable code | ||
|
||
```py | ||
from ..common import state, CastBoolMixin | ||
``` | ||
|
||
- `state` provides a couple of handy variables so you don't have to fetch them, allow optimizing the most common operations | ||
- `Mixins` are providing common code, for instance the `CastBoolMixin` provides the `cast_bool` method to your `Extension`. | ||
|
||
If you want to use menus, then the `MenuMixin` will provide: | ||
- `menu` to show a menu | ||
- `ensure_menu_configured` to call before you require a menu in your plugin | ||
|
||
# Example | ||
|
||
You'll find a basic external plugin in the [examples](https://github.com/hyprland-community/pyprland/blob/main/sample_extension/) folder. | ||
|
||
It provides one command: `pypr dummy`. | ||
|
||
Read the [plugin code](https://github.com/hyprland-community/pyprland/blob/main/sample_extension/pypr_examples/focus_counter.py) | ||
|
||
It's a simple python package. To install it for development without a need to re-install it for testing, you can use `pip install -e .` in this folder. | ||
It's ready to be published using `poetry publish`, don't forget to update the details in the `pyproject.toml` file. | ||
|
||
## Usage | ||
|
||
Ensure you added `pypr_examples.focus_counter` to your `plugins` list: | ||
|
||
```toml | ||
[pyprland] | ||
plugins = [ | ||
"pypr_examples.focus_counter" | ||
] | ||
``` | ||
|
||
Optionally you can customize one color: | ||
|
||
```toml | ||
["pypr_examples.focus_counter"] | ||
color = "FFFF00" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
# Getting started | ||
|
||
Pypr consists in two things: | ||
|
||
- **a tool**: `pypr` which runs the daemon (service), but also allows to interact with it | ||
- **some config file**: `~/.config/hypr/pyprland.toml` (or the path set using `--config`) using the [TOML](https://toml.io/en/) format | ||
|
||
The `pypr` tool only have a few built-in commands: | ||
|
||
- `help` lists available commands (including plugins commands) | ||
- `exit` will terminate the service process | ||
- `edit` edit the configuration using your `$EDITOR` (or `vi`), reloads on exit | ||
- `dumpjson` shows a JSON representation of the configuration (after other files have been `include`d) | ||
- `reload` reads the configuration file and apply some changes: | ||
- new plugins will be loaded | ||
- configuration items will be updated (most plugins will use the new values on the next usage) | ||
|
||
Other commands are implemented by adding [plugins](./Plugins). | ||
|
||
> [!important] | ||
> - with no argument it runs the daemon (doesn't fork in the background) | ||
> | ||
> - if you pass parameters, it will interact with the daemon instead. | ||
> [!tip] | ||
> Pypr *command* names are documented using underscores (`_`) but you can use dashes (`-`) instead. | ||
> Eg: `pypr shift_monitors` and `pypr shift-monitors` will run the same command | ||
|
||
## Configuration file | ||
|
||
The configuration file uses a [TOML format](https://toml.io/) with the following as the bare minimum: | ||
|
||
```toml | ||
[pyprland] | ||
plugins = ["plugin_name", "other_plugin"] | ||
``` | ||
|
||
Additionally some plugins require **Configuration** options, using the following format: | ||
|
||
```toml | ||
[plugin_name] | ||
plugin_option = 42 | ||
|
||
[plugin_name.another_plugin_option] | ||
suboption = "config value" | ||
``` | ||
|
||
You can also split your configuration into [Multiple configuration files](./MultipleConfigurationFiles). | ||
|
||
## Installation | ||
|
||
Check your OS package manager first, eg: | ||
|
||
- Archlinux: you can find it on AUR, eg with [yay](https://github.com/Jguer/yay): `yay pyprland` | ||
- NixOS: Instructions in the [Nix](./Nix) page | ||
|
||
Otherwise, use the python package manager (pip) [inside a virtual environment](InstallVirtualEnvironment) | ||
|
||
```sh | ||
pip install pyprland | ||
``` | ||
|
||
## Running | ||
|
||
> [!caution] | ||
> If you messed with something else than your OS packaging system to get `pypr` installed, use the full path to the `pypr` command. | ||
Preferably start the process with hyprland, adding to `hyprland.conf`: | ||
|
||
```ini | ||
exec-once = /usr/bin/pypr | ||
``` | ||
|
||
or if you run into troubles (use the first version once your configuration is stable): | ||
|
||
```ini | ||
exec-once = /usr/bin/pypr --debug /tmp/pypr.log | ||
``` | ||
|
||
> [!warning] | ||
> To avoid issues (eg: you have a complex setup, maybe using a virtual environment), you may want to set the full path (eg: `/home/bob/venv/bin/pypr`). | ||
> You can get it from `which pypr` in a working terminal | ||
Once the `pypr` daemon is started (cf `exec-once`), you can list the eventual commands which have been added by the plugins using `pypr -h` or `pypr help`, those commands are generally meant to be use via key bindings, see the `hyprland.conf` part of *Configuring* section below. | ||
|
||
## Configuring | ||
|
||
Create a configuration file in `~/.config/hypr/pyprland.toml` enabling a list of plugins, each plugin may have its own configuration needs or don't need any configuration at all. | ||
Most default values should be acceptable for most users, options which hare not mandatory are marked as such. | ||
|
||
> [!important] | ||
> Provide the values for the configuration options which have no annotation such as "(optional)" | ||
Check the [TOML format](https://toml.io/) for details about the syntax. | ||
|
||
Simple example: | ||
|
||
```toml | ||
[pyprland] | ||
plugins = [ | ||
"shift_monitors", | ||
"workspaces_follow_focus" | ||
] | ||
``` | ||
|
||
<details> | ||
<summary> | ||
More complex example | ||
</summary> | ||
|
||
```toml | ||
[pyprland] | ||
plugins = [ | ||
"scratchpads", | ||
"lost_windows", | ||
"monitors", | ||
"toggle_dpms", | ||
"magnify", | ||
"expose", | ||
"shift_monitors", | ||
"workspaces_follow_focus", | ||
] | ||
|
||
[monitors.placement] | ||
"Acer".top_center_of = "Sony" | ||
|
||
[workspaces_follow_focus] | ||
max_workspaces = 9 | ||
|
||
[expose] | ||
include_special = false | ||
|
||
[scratchpads.stb] | ||
animation = "fromBottom" | ||
command = "kitty --class kitty-stb sstb" | ||
class = "kitty-stb" | ||
lazy = true | ||
size = "75% 45%" | ||
|
||
[scratchpads.stb-logs] | ||
animation = "fromTop" | ||
command = "kitty --class kitty-stb-logs stbLog" | ||
class = "kitty-stb-logs" | ||
lazy = true | ||
size = "75% 40%" | ||
|
||
[scratchpads.term] | ||
animation = "fromTop" | ||
command = "kitty --class kitty-dropterm" | ||
class = "kitty-dropterm" | ||
size = "75% 60%" | ||
|
||
[scratchpads.volume] | ||
animation = "fromRight" | ||
command = "pavucontrol" | ||
class = "org.pulseaudio.pavucontrol" | ||
lazy = true | ||
size = "40% 90%" | ||
unfocus = "hide" | ||
``` | ||
|
||
Some of those plugins may require changes in your `hyprland.conf` to fully operate or to provide a convenient access to a command, eg: | ||
|
||
```bash | ||
bind = $mainMod SHIFT, Z, exec, pypr zoom | ||
bind = $mainMod ALT, P,exec, pypr toggle_dpms | ||
bind = $mainMod SHIFT, O, exec, pypr shift_monitors +1 | ||
bind = $mainMod, B, exec, pypr expose | ||
bind = $mainMod, K, exec, pypr change_workspace +1 | ||
bind = $mainMod, J, exec, pypr change_workspace -1 | ||
bind = $mainMod,L,exec, pypr toggle_dpms | ||
bind = $mainMod SHIFT,M,exec,pypr toggle stb stb-logs | ||
bind = $mainMod,A,exec,pypr toggle term | ||
bind = $mainMod,V,exec,pypr toggle volume | ||
``` | ||
|
||
</details> | ||
|
||
> [!tip] | ||
> Consult or share [configuration files](https://github.com/hyprland-community/pyprland/tree/main/examples) | ||
> | ||
> You might also be interested in [optimizations](./Optimizations). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Virtual env | ||
|
||
Even though the best way to get Pyprland installed is to use your operating system package manager, | ||
for some usages or users it can be convenient to use a virtual environment. | ||
|
||
This is very easy to achieve in a couple of steps: | ||
|
||
```shell | ||
python -m venv ~/pypr-env | ||
~/pypr-env/bin/pip install pyprland | ||
``` | ||
|
||
**That's all folks!** | ||
|
||
The only extra care to take is to use `pypr` from the virtual environment, eg: | ||
|
||
- adding the environment's "bin" folder to the `PATH` (using `export PATH="$PATH:~/pypr-env/bin/"` in your shell configuration file) | ||
- always using the full path to the pypr command (in `hyprland.conf`: `exec-once = ~/pypr-env/bin/pypr --debug /tmp/pypr.log`) | ||
|
||
# Going bleeding edge! | ||
|
||
If you would rather like to use the latest version available (not released yet), then you can clone the git repository and install from it: | ||
|
||
```shell | ||
cd ~/pypr-env | ||
git clone [email protected]:hyprland-community/pyprland.git pyprland-sources | ||
cd pyprland-sources | ||
../bin/pip install -e . | ||
``` | ||
|
||
## Updating | ||
|
||
```shell | ||
cd ~/pypr-env | ||
git pull -r | ||
``` | ||
|
||
# Troubelshooting | ||
|
||
If things go wrong, try (eg: after a system upgrade where Python got updated): | ||
|
||
```shell | ||
python -m venv --upgrade ~/pypr-env | ||
cd ~/pypr-env | ||
../bin/pip install -e . | ||
``` |
Oops, something went wrong.