mirror of
https://git.allpurposem.at/mat/WiggleWobble.git
synced 2025-12-23 13:01:28 +01:00
init: WiggleWobble
This commit is contained in:
parent
15602acda6
commit
4840855ee0
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
compile_flags.txt
|
||||
compile_commands.json
|
||||
/.direnv
|
||||
/build
|
||||
|
||||
52
README.md
52
README.md
@ -1,25 +1,4 @@
|
||||
# Hyprland Plugin Template
|
||||
|
||||
This is a fork of [hyprland-community/hyprland-plugin-template](https://github.com/hyprland-community/hyprland-plugin-template/fork),
|
||||
with more opinionated build tools (meson and optionally nix).
|
||||
|
||||
The goal of this repository is to create a robust `Hyprland` plugin template, with
|
||||
- nix
|
||||
- A working, extensible `meson.build`
|
||||
- [`hyprload`](https://github.com/Duckonaut/hyprload) support out of the box
|
||||
- Environment set up guide
|
||||
- Clangd flags set up for autocomplete and error checking
|
||||
|
||||
It is highly recommended to read the [Plugin development](https://wiki.hyprland.org/Plugins/Development/Getting-Started/)
|
||||
section of the Hyprland Wiki first. Some stuff will be different in this template, but it gives
|
||||
you a general idea about what's going on
|
||||
|
||||
## Support
|
||||
If you have any issues setting this up, open an issue in this repository. I will try to help.
|
||||
|
||||
## Setup
|
||||
This is a github template repository. To use it, use the green **Use this template** button
|
||||
at the top of the repository file view.
|
||||
# WiggleWobble - Wobbly windows for Hyprland
|
||||
|
||||
### Setting up a development environment
|
||||
|
||||
@ -41,20 +20,6 @@ Run this command to setup the build directory and generate a **clangd** compatib
|
||||
meson setup build && sed -e 's/c++23/c++2b/g' ./build/compile_commands.json > ./compile_commands.json
|
||||
```
|
||||
|
||||
#### Making it Your Own
|
||||
To change your plugin name, version, and author (that's you!) there are a few things that need
|
||||
changing (I would like to streamline it somehow, but it's manageable for now)
|
||||
- `main.cpp`: The `PLUGIN_INIT` function returns a struct with the plugin name, description,
|
||||
author and version. Change those.
|
||||
- `meson.build`: At the top of the file, the project name `example` should be changed.
|
||||
- `src/meson.build`: The name of the `shared_library` (first argument) should be changed. The
|
||||
resulting library will be changed to `build/src/libYOUR_PLUGIN.so` so you should change the
|
||||
`[examplePlugin.build.output]` entry as well
|
||||
- `hyprload.toml`: The `[examplePlugin]` and `[examplePlugin.build]` should be changed to match
|
||||
the name of your plugin. `hyprload` will look at these dictionaries for info about the plugin.
|
||||
For more info, see [hyprload docs](https://github.com/Duckonaut/hyprload#format)
|
||||
- `plugin.nix`: Change `pname` and the `meta` section.
|
||||
|
||||
## Building and testing
|
||||
|
||||
After `nix develop`, the steps to build are simple
|
||||
@ -77,24 +42,9 @@ Do note that if you only load/unload from the same path, Hyprland can ignore you
|
||||
You don't need this that often for development but you can build directly without `nix develop`
|
||||
with `nix build`.
|
||||
|
||||
### Using `hyprload`
|
||||
|
||||
TODO: update
|
||||
|
||||
This works rather well in nested Hyprland sessions, since `hyprload` keeps sessions separate.
|
||||
- `make install`: This will build and copy the plugin to the `hyprload` plugin directory.
|
||||
- Reload `hyprload` for the changes to take effect
|
||||
|
||||
This doesn't have the issue of ignoring changes, because of how `hyprload` handles its loaded
|
||||
plugins.
|
||||
|
||||
### Nested Hyprland
|
||||
Developing a plugin may be tough. You might crash Hyprland a couple times. For this reason,
|
||||
it's a good idea to develop them in a nested Hyprland session. If you run `Hyprland` from an
|
||||
existing Hyprland session, it'll open in a window. If this window crashes, it's pretty much fine!
|
||||
Refer to the [Hyprland wiki](http://wiki.hyprland.org/Plugins/Development/Getting-Started/#setting-up-a-development-environment)
|
||||
for more info.
|
||||
|
||||
## ""Publishing""
|
||||
If you haven't messed up your `hyprload.toml` manifest too badly, anyone should be able to use
|
||||
your plugin by just adding `'YOUR_GITHUB_NAME/YOUR_PLUGIN'` to their own `hyprload.toml` config!
|
||||
|
||||
130
flake.lock
130
flake.lock
@ -20,11 +20,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734906446,
|
||||
"narHash": "sha256-6OWluVE2A8xi+8V3jN9KA72RCgJjYdyyuLBUjxZ2q2U=",
|
||||
"lastModified": 1747864449,
|
||||
"narHash": "sha256-PIjVAWghZhr3L0EFM2UObhX84UQxIACbON0IC0zzSKA=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "eecb74dc79bb6752a2a507e6edee3042390a6091",
|
||||
"rev": "389372c5f4dc1ac0e7645ed29a35fd6d71672ef5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -87,11 +87,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734906540,
|
||||
"narHash": "sha256-vQ/L9hZFezC0LquLo4TWXkyniWtYBlFHAKIsDc7PYJE=",
|
||||
"lastModified": 1745948457,
|
||||
"narHash": "sha256-lzTV10FJTCGNtMdgW5YAhCAqezeAzKOd/97HbQK8GTU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "69270ba8f057d55b0e6c2dca0e165d652856e613",
|
||||
"rev": "ac903e80b33ba6a88df83d02232483d99f327573",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -116,11 +116,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734906236,
|
||||
"narHash": "sha256-vH/ysV2ONGQgYZPtcJKwc8jJivzyVxru2aaOxC20ZOE=",
|
||||
"lastModified": 1745015490,
|
||||
"narHash": "sha256-apEJ9zoSzmslhJ2vOKFcXTMZLUFYzh1ghfB6Rbw3Low=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprgraphics",
|
||||
"rev": "6dea3fba08fd704dd624b6d4b261638fb4003c9c",
|
||||
"rev": "60754910946b4e2dc1377b967b7156cb989c5873",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -145,11 +145,11 @@
|
||||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735585949,
|
||||
"narHash": "sha256-0nT9kNyyQlhpMHakQLyINZoJAjRAui4WsbxrRev6Gwc=",
|
||||
"lastModified": 1748696522,
|
||||
"narHash": "sha256-YnKypsotSvrJEEHo+DQQkgtzfBwFmGqtkz3J6c0gw74=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "Hyprland",
|
||||
"rev": "1989b0049f7fb714a2417dfb14d6b4f3d2a079d3",
|
||||
"rev": "4078e1d17c0fb1439ee5a0ba1e539f06a8f47aab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -170,11 +170,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1728345020,
|
||||
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
||||
"lastModified": 1743714874,
|
||||
"narHash": "sha256-yt8F7NhMFCFHUHy/lNjH/pjZyIDFNk52Q4tivQ31WFo=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
||||
"rev": "3a5c2bda1c1a4e55cc1330c782547695a93f05b2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -183,10 +183,49 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qt-support": {
|
||||
"inputs": {
|
||||
"hyprlang": [
|
||||
"hyprland",
|
||||
"hyprland-qtutils",
|
||||
"hyprlang"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"hyprland-qtutils",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"hyprland-qtutils",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634706,
|
||||
"narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"rev": "8810df502cdee755993cb803eba7b23f189db795",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qtutils": {
|
||||
"inputs": {
|
||||
"hyprland-qt-support": "hyprland-qt-support",
|
||||
"hyprlang": [
|
||||
"hyprland",
|
||||
"hyprlang"
|
||||
],
|
||||
"hyprutils": [
|
||||
"hyprland",
|
||||
"hyprland-qtutils",
|
||||
"hyprlang",
|
||||
"hyprutils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
@ -199,11 +238,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734906472,
|
||||
"narHash": "sha256-pWPRv/GA/X/iAwoE6gMNUqn/ZeJX1IeLPRpZI0tTPK0=",
|
||||
"lastModified": 1745951494,
|
||||
"narHash": "sha256-2dModE32doiyQMmd6EDAQeZnz+5LOs6KXyE0qX76WIg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qtutils",
|
||||
"rev": "c77109d7e1ddbcdb87cafd32ce411f76328ae152",
|
||||
"rev": "4be1d324faf8d6e82c2be9f8510d299984dfdd2e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -228,11 +267,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734906259,
|
||||
"narHash": "sha256-P79t/7HbACO4/PuJBroGpTptvCWJtXTv+gWsF+sM6MI=",
|
||||
"lastModified": 1747484975,
|
||||
"narHash": "sha256-+LAQ81HBwG0lwshHlWe0kfWg4KcChIPpnwtnwqmnoEU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "0404833ea18d543df44df935ebf1b497310eb046",
|
||||
"rev": "163c83b3db48a17c113729c220a60b94596c9291",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -253,11 +292,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735316583,
|
||||
"narHash": "sha256-AiiUwHWHfEdpFzXy7l1x3zInCUa1xcRMrbZ1XRSkzwU=",
|
||||
"lastModified": 1746635225,
|
||||
"narHash": "sha256-W9G9bb0zRYDBRseHbVez0J8qVpD5QbizX67H/vsudhM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "8f15d45b120b33712f6db477fe5ffb18034d0ea8",
|
||||
"rev": "674ea57373f08b7609ce93baff131117a0dfe70d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -278,11 +317,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734793513,
|
||||
"narHash": "sha256-rrrHcXapXJvGFqX+L/Bb0182L25jofAZ0fm1FInvrTQ=",
|
||||
"lastModified": 1747584298,
|
||||
"narHash": "sha256-PH9qZqWLHvSBQiUnA0NzAyQA3tu2no2z8kz0ZeHWj4w=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "4d7367b6eee87397e2dbca2e78078dd0a4ef4c61",
|
||||
"rev": "e511882b9c2e1d7a75d45d8fddd2160daeafcbc3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -293,11 +332,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1735291276,
|
||||
"narHash": "sha256-NYVcA06+blsLG6wpAbSPTCyLvxD/92Hy4vlY9WxFI1M=",
|
||||
"lastModified": 1748460289,
|
||||
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "634fd46801442d760e09493a794c4f15db2d0cbb",
|
||||
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -307,22 +346,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1730741070,
|
||||
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
@ -330,15 +353,14 @@
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734797603,
|
||||
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
|
||||
"lastModified": 1747372754,
|
||||
"narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
|
||||
"rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -395,11 +417,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734907020,
|
||||
"narHash": "sha256-p6HxwpRKVl1KIiY5xrJdjcEeK3pbmc///UOyV6QER+w=",
|
||||
"lastModified": 1745871725,
|
||||
"narHash": "sha256-M24SNc2flblWGXFkGQfqSlEOzAGZnMc9QG3GH4K/KbE=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "d7f18dda5e511749fa1511185db3536208fb1a63",
|
||||
"rev": "76bbf1a6b1378e4ab5230bad00ad04bc287c969e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
in {
|
||||
packages = genPerSystem (system: pkgs: {
|
||||
default = pkgs.callPackage ./plugin.nix {
|
||||
inherit (hyprland.packages.${system}) hyprland;
|
||||
inherit (hyprland.packages.${system}) hyprland-debug;
|
||||
};
|
||||
});
|
||||
|
||||
@ -26,9 +26,9 @@
|
||||
# Note: gcc needs to be specified or else an older version might be used
|
||||
# TODO: maybe using gcc13Stdenv.mkShell would fix this?
|
||||
nativeBuildInputs = with pkgs; [gcc14 meson pkg-config ninja];
|
||||
buildInputs = [hyprland.packages.${system}.hyprland];
|
||||
buildInputs = [hyprland.packages.${system}.hyprland-debug];
|
||||
inputsFrom = [
|
||||
hyprland.packages.${system}.hyprland
|
||||
hyprland.packages.${system}.hyprland-debug
|
||||
self.packages.${system}.default
|
||||
];
|
||||
};
|
||||
|
||||
151
hyprlandd.conf
Normal file
151
hyprlandd.conf
Normal file
@ -0,0 +1,151 @@
|
||||
monitor=,preferred,auto,auto
|
||||
|
||||
# exec_once=kitty --hold sh -c "hyprctl plugin load $(pwd)/build/src/libhyprwiggle.so"
|
||||
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 20
|
||||
|
||||
border_size = 2
|
||||
|
||||
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
|
||||
col.inactive_border = rgba(595959aa)
|
||||
resize_on_border = false
|
||||
allow_tearing = false
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = 10
|
||||
rounding_power = 2
|
||||
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 4
|
||||
render_power = 3
|
||||
color = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
blur {
|
||||
enabled = true
|
||||
size = 3
|
||||
passes = 1
|
||||
|
||||
vibrancy = 0.1696
|
||||
}
|
||||
}
|
||||
|
||||
animations {
|
||||
enabled = yes, please :)
|
||||
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
preserve_split = true # You probably want this
|
||||
}
|
||||
|
||||
master {
|
||||
new_status = master
|
||||
}
|
||||
|
||||
misc {
|
||||
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
|
||||
disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :(
|
||||
}
|
||||
|
||||
input {
|
||||
kb_layout = us
|
||||
kb_variant =
|
||||
kb_model =
|
||||
kb_options =
|
||||
kb_rules =
|
||||
|
||||
follow_mouse = 1
|
||||
|
||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||
|
||||
touchpad {
|
||||
natural_scroll = false
|
||||
}
|
||||
}
|
||||
|
||||
gestures {
|
||||
workspace_swipe = false
|
||||
}
|
||||
|
||||
###################
|
||||
### KEYBINDINGS ###
|
||||
###################
|
||||
|
||||
$mainMod = ALT
|
||||
|
||||
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||
bind = $mainMod, return, exec, kitty
|
||||
bind = $mainMod, X, killactive,
|
||||
bind = $mainMod, F4, exit,
|
||||
bind = $mainMod, space, togglefloating,
|
||||
|
||||
bind = $mainMod, left, movefocus, l
|
||||
bind = $mainMod, right, movefocus, r
|
||||
bind = $mainMod, up, movefocus, u
|
||||
bind = $mainMod, down, movefocus, d
|
||||
|
||||
# Switch workspaces with mainMod + [0-9]
|
||||
bind = $mainMod, 1, workspace, 1
|
||||
bind = $mainMod, 2, workspace, 2
|
||||
bind = $mainMod, 3, workspace, 3
|
||||
bind = $mainMod, 4, workspace, 4
|
||||
bind = $mainMod, 5, workspace, 5
|
||||
bind = $mainMod, 6, workspace, 6
|
||||
bind = $mainMod, 7, workspace, 7
|
||||
bind = $mainMod, 8, workspace, 8
|
||||
bind = $mainMod, 9, workspace, 9
|
||||
bind = $mainMod, 0, workspace, 10
|
||||
|
||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||
bind = $mainMod SHIFT, 1, movetoworkspace, 1
|
||||
bind = $mainMod SHIFT, 2, movetoworkspace, 2
|
||||
bind = $mainMod SHIFT, 3, movetoworkspace, 3
|
||||
bind = $mainMod SHIFT, 4, movetoworkspace, 4
|
||||
bind = $mainMod SHIFT, 5, movetoworkspace, 5
|
||||
bind = $mainMod SHIFT, 6, movetoworkspace, 6
|
||||
bind = $mainMod SHIFT, 7, movetoworkspace, 7
|
||||
bind = $mainMod SHIFT, 8, movetoworkspace, 8
|
||||
bind = $mainMod SHIFT, 9, movetoworkspace, 9
|
||||
bind = $mainMod SHIFT, 0, movetoworkspace, 10
|
||||
|
||||
# Example special workspace (scratchpad)
|
||||
bind = $mainMod, S, togglespecialworkspace, magic
|
||||
bind = $mainMod SHIFT, S, movetoworkspace, special:magic
|
||||
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod SHIFT, mouse:272, resizewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
||||
# vim: set ft=hyprlang :
|
||||
@ -1,13 +1,13 @@
|
||||
[example]
|
||||
description = "Example plugin"
|
||||
author = "YOU"
|
||||
[wigglewobble]
|
||||
description = "Wobbly windows for Hyprland"
|
||||
author = "All-Purpose Mat"
|
||||
## NOTE: version is omitted here because I don't like having multiple places
|
||||
## to update the version string. Feel free to add it back in.
|
||||
#
|
||||
# version = "v0.0.0"
|
||||
|
||||
[example.build]
|
||||
output = "build/src/example.so"
|
||||
[wigglewobble.build]
|
||||
output = "build/src/wigglewobble.so"
|
||||
steps = [
|
||||
"meson setup build",
|
||||
"meson compile -Cbuild"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
project('example', 'cpp', 'c',
|
||||
project('wigglewobble', 'cpp', 'c',
|
||||
# we always take the VERSION file as the single source of truth
|
||||
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||
default_options: ['buildtype=release'],
|
||||
|
||||
12
plugin.nix
12
plugin.nix
@ -4,24 +4,24 @@
|
||||
meson,
|
||||
ninja,
|
||||
pkg-config,
|
||||
hyprland,
|
||||
hyprland-debug,
|
||||
}: let
|
||||
version = builtins.readFile ./VERSION;
|
||||
in
|
||||
gcc13Stdenv.mkDerivation {
|
||||
pname = "example";
|
||||
pname = "wigglewobble";
|
||||
inherit version;
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs =
|
||||
hyprland.nativeBuildInputs
|
||||
hyprland-debug.nativeBuildInputs
|
||||
++ [ninja meson pkg-config];
|
||||
|
||||
buildInputs = [hyprland] ++ hyprland.buildInputs;
|
||||
buildInputs = [hyprland-debug] ++ hyprland-debug.buildInputs;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://example.com";
|
||||
description = "Example hyprland plugin";
|
||||
homepage = "https://git.allpurposem.at/mat/WiggleWobble";
|
||||
description = "Wobbly windows for hyprland";
|
||||
license = licenses.bsd3;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
|
||||
6
run.sh
Executable file
6
run.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
meson compile -Cbuild
|
||||
Hyprland -c hyprlandd.conf
|
||||
@ -1,74 +0,0 @@
|
||||
#include "customDecoration.hpp"
|
||||
#include <hyprland/src/Window.hpp>
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include "globals.hpp"
|
||||
|
||||
CCustomDecoration::CCustomDecoration(CWindow* pWindow) {
|
||||
m_pWindow = pWindow;
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
||||
}
|
||||
|
||||
CCustomDecoration::~CCustomDecoration() {
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
SWindowDecorationExtents CCustomDecoration::getWindowDecorationExtents() {
|
||||
return m_seExtents;
|
||||
}
|
||||
|
||||
void CCustomDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
|
||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
||||
return;
|
||||
|
||||
static auto* const PCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:example:border_color")->intValue;
|
||||
static auto* const PROUNDING = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
|
||||
static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue;
|
||||
|
||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ?
|
||||
0 :
|
||||
(m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying());
|
||||
|
||||
// draw the border
|
||||
wlr_box fullBox = {(int)(m_vLastWindowPos.x - *PBORDERSIZE), (int)(m_vLastWindowPos.y - *PBORDERSIZE), (int)(m_vLastWindowSize.x + 2.0 * *PBORDERSIZE),
|
||||
(int)(m_vLastWindowSize.y + 2.0 * *PBORDERSIZE)};
|
||||
|
||||
fullBox.x -= pMonitor->vecPosition.x;
|
||||
fullBox.y -= pMonitor->vecPosition.y;
|
||||
|
||||
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
||||
{fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
||||
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}};
|
||||
|
||||
fullBox.x += offset.x;
|
||||
fullBox.y += offset.y;
|
||||
|
||||
if (fullBox.width < 1 || fullBox.height < 1)
|
||||
return; // don't draw invisible shadows
|
||||
|
||||
g_pHyprOpenGL->scissor((wlr_box*)nullptr);
|
||||
|
||||
scaleBox(&fullBox, pMonitor->scale);
|
||||
g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a);
|
||||
}
|
||||
|
||||
eDecorationType CCustomDecoration::getDecorationType() {
|
||||
return DECORATION_CUSTOM;
|
||||
}
|
||||
|
||||
void CCustomDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
||||
|
||||
damageEntire();
|
||||
}
|
||||
|
||||
void CCustomDecoration::damageEntire() {
|
||||
wlr_box dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y),
|
||||
(int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x), (int)m_seExtents.topLeft.y};
|
||||
g_pHyprRenderer->damageBox(&dm);
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
#include "customLayout.hpp"
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include "globals.hpp"
|
||||
|
||||
void CHyprCustomLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
const auto SIZE = PMONITOR->vecSize;
|
||||
|
||||
// these are used for focus and move calculations, and are *required* to touch for moving focus to work properly.
|
||||
pWindow->m_vPosition = Vector2D{(SIZE.x / 2.0) * (m_vWindowData.size() % 2), (SIZE.y / 2.0) * (int)(m_vWindowData.size() > 1)};
|
||||
pWindow->m_vSize = SIZE / 2.0;
|
||||
|
||||
// this is the actual pos and size of the window (where it's rendered)
|
||||
pWindow->m_vRealPosition = pWindow->m_vPosition + Vector2D{10, 10};
|
||||
pWindow->m_vRealSize = pWindow->m_vSize - Vector2D{20, 20};
|
||||
|
||||
const auto PDATA = &m_vWindowData.emplace_back();
|
||||
PDATA->pWindow = pWindow;
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
std::erase_if(m_vWindowData, [&](const auto& other) { return other.pWindow == pWindow; });
|
||||
}
|
||||
|
||||
bool CHyprCustomLayout::isWindowTiled(CWindow* pWindow) {
|
||||
return std::find_if(m_vWindowData.begin(), m_vWindowData.end(), [&](const auto& other) { return other.pWindow == pWindow; }) != m_vWindowData.end();
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::recalculateMonitor(const int& eIdleInhibitMode) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::recalculateWindow(CWindow* pWindow) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::resizeActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode mode, bool on) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
std::any CHyprCustomLayout::layoutMessage(SLayoutMessageHeader header, std::string content) {
|
||||
return "";
|
||||
}
|
||||
|
||||
SWindowRenderLayoutHints CHyprCustomLayout::requestRenderHints(CWindow* pWindow) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::switchWindows(CWindow* pWindowA, CWindow* pWindowB) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::alterSplitRatio(CWindow* pWindow, float delta, bool exact) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
std::string CHyprCustomLayout::getLayoutName() {
|
||||
return "custom";
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::replaceWindowDataWith(CWindow* from, CWindow* to) {
|
||||
; // empty
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::onEnable() {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->isHidden() || !w->m_bIsMapped || w->m_bFadingOut || w->m_bIsFloating)
|
||||
continue;
|
||||
|
||||
onWindowCreatedTiling(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprCustomLayout::onDisable() {
|
||||
m_vWindowData.clear();
|
||||
}
|
||||
79
src/main.cpp
79
src/main.cpp
@ -4,92 +4,35 @@
|
||||
// version.hpp will be generated by meson
|
||||
#include "version.hpp"
|
||||
|
||||
#include <hyprland/src/Window.hpp>
|
||||
// #include <hyprland/src/Window.hpp>
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include "customLayout.hpp"
|
||||
#include "customDecoration.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <thread>
|
||||
|
||||
// Methods
|
||||
inline std::unique_ptr<CHyprCustomLayout> g_pCustomLayout;
|
||||
inline CFunctionHook* g_pFocusHook = nullptr;
|
||||
inline CFunctionHook* g_pMotionHook = nullptr;
|
||||
inline CFunctionHook* g_pMouseDownHook = nullptr;
|
||||
typedef void (*origFocusWindow)(void*, CWindow*, wlr_surface*);
|
||||
typedef void (*origMotion)(wlr_seat*, uint32_t, double, double);
|
||||
typedef void (*origMouseDownNormal)(void*, wlr_pointer_button_event*);
|
||||
|
||||
// Do NOT change this function.
|
||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
}
|
||||
|
||||
static void onActiveWindowChange(void* self, std::any data) {
|
||||
try {
|
||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
||||
|
||||
HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: " + (PWINDOW ? PWINDOW->m_szTitle : "None"), CColor{0.f, 0.5f, 1.f, 1.f}, 5000);
|
||||
} catch (std::bad_any_cast& e) { HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: None", CColor{0.f, 0.5f, 1.f, 1.f}, 5000); }
|
||||
}
|
||||
|
||||
static void onNewWindow(void* self, std::any data) {
|
||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
||||
|
||||
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CCustomDecoration(PWINDOW));
|
||||
}
|
||||
|
||||
void hkFocusWindow(void* thisptr, CWindow* pWindow, wlr_surface* pSurface) {
|
||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("FocusWindow with %lx %lx", pWindow, pSurface), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
||||
(*(origFocusWindow)g_pFocusHook->m_pOriginal)(thisptr, pWindow, pSurface);
|
||||
}
|
||||
|
||||
void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) {
|
||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("NotifyMotion with %lf %lf", sx, sy), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
||||
(*(origMotion)g_pMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy);
|
||||
}
|
||||
|
||||
void hkProcessMouseDownNormal(void* thisptr, wlr_pointer_button_event* e) {
|
||||
// HyprlandAPI::addNotification(PHANDLE, "Mouse down normal!", CColor{0.8f, 0.2f, 0.5f, 1.0f}, 5000);
|
||||
(*(origMouseDownNormal)g_pMouseDownHook->m_pOriginal)(thisptr, e);
|
||||
}
|
||||
|
||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
PHANDLE = handle;
|
||||
|
||||
HyprlandAPI::addNotification(PHANDLE, "Hello World from an example plugin!", CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
||||
const std::string HASH = __hyprland_api_get_hash();
|
||||
|
||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "activeWindow", [&](void* self, std::any data) { onActiveWindowChange(self, data); });
|
||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, std::any data) { onNewWindow(self, data); });
|
||||
// ALWAYS add this to your plugins. It will prevent random crashes coming from
|
||||
// mismatched header versions.
|
||||
if (HASH != GIT_COMMIT_HASH) {
|
||||
HyprlandAPI::addNotification(PHANDLE, "[WiggleWobble] Mismatched headers! Can't proceed.",
|
||||
CHyprColor{1.0, 0.2, 0.2, 1.0}, 5000);
|
||||
throw std::runtime_error("[WiggleWobble] Version mismatch");
|
||||
}
|
||||
|
||||
g_pCustomLayout = std::make_unique<CHyprCustomLayout>();
|
||||
|
||||
HyprlandAPI::addLayout(PHANDLE, "custom", g_pCustomLayout.get());
|
||||
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:example:border_color", SConfigValue{.intValue = configStringToInt("rgb(44ee44)")});
|
||||
|
||||
HyprlandAPI::addDispatcher(PHANDLE, "example", [](std::string arg) { HyprlandAPI::addNotification(PHANDLE, "Arg passed: " + arg, CColor{0.5f, 0.5f, 0.7f, 1.0f}, 5000); });
|
||||
|
||||
// Hook a public member
|
||||
g_pFocusHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&CCompositor::focusWindow, (void*)&hkFocusWindow);
|
||||
// Hook a public non-member
|
||||
g_pMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion);
|
||||
// Hook a private member
|
||||
static const auto METHODS = HyprlandAPI::findFunctionsByName(PHANDLE, "processMouseDownNormal");
|
||||
g_pMouseDownHook = HyprlandAPI::createFunctionHook(PHANDLE, METHODS[0].address, (void*)&hkProcessMouseDownNormal);
|
||||
|
||||
// fancy notifications
|
||||
HyprlandAPI::addNotificationV2(PHANDLE, {{"text", "Example hint"}, {"time", (uint64_t)10000}, {"color", CColor(0.2, 0.2, 0.9, 1.0)}, {"icon", ICON_HINT}});
|
||||
|
||||
// Enable our hooks
|
||||
g_pFocusHook->hook();
|
||||
g_pMotionHook->hook();
|
||||
g_pMouseDownHook->hook();
|
||||
HyprlandAPI::addNotification(PHANDLE, "WiggleWobble loaded!", CHyprColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
||||
|
||||
HyprlandAPI::reloadConfig();
|
||||
|
||||
return {"example", "An example plugin", "YOU", PLUGIN_VERSION};
|
||||
return {"wigglewobble", "Wobbly windows for Hyprland", "All-Purpose Mat", PLUGIN_VERSION};
|
||||
}
|
||||
|
||||
APICALL EXPORT void PLUGIN_EXIT() {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
shared_module('example',
|
||||
shared_module('wigglewobble',
|
||||
'main.cpp',
|
||||
cpp_args: ['-DWLR_USE_UNSTABLE'],
|
||||
include_directories: incdir,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user