diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index ee9bfd8..9608842 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ compile_flags.txt compile_commands.json +/.direnv /build diff --git a/README.md b/README.md index e9c90fd..77798b6 100644 --- a/README.md +++ b/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! diff --git a/flake.lock b/flake.lock index 2de4b53..1883f21 100644 --- a/flake.lock +++ b/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": { diff --git a/flake.nix b/flake.nix index ab3c76d..414bd3f 100644 --- a/flake.nix +++ b/flake.nix @@ -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 ]; }; diff --git a/hyprlandd.conf b/hyprlandd.conf new file mode 100644 index 0000000..c26ce95 --- /dev/null +++ b/hyprlandd.conf @@ -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 : diff --git a/hyprload.toml b/hyprload.toml index ef9f17c..b612013 100644 --- a/hyprload.toml +++ b/hyprload.toml @@ -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" diff --git a/meson.build b/meson.build index af71f93..67342bc 100644 --- a/meson.build +++ b/meson.build @@ -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'], diff --git a/plugin.nix b/plugin.nix index 6285b4c..c3415de 100644 --- a/plugin.nix +++ b/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; }; diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..02a54d0 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +#!/bin/env bash + +set -e + +meson compile -Cbuild +Hyprland -c hyprlandd.conf diff --git a/src/customDecoration.cpp b/src/customDecoration.cpp deleted file mode 100644 index c579af3..0000000 --- a/src/customDecoration.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "customDecoration.hpp" -#include -#include -#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); -} diff --git a/src/customLayout.cpp b/src/customLayout.cpp deleted file mode 100644 index 595dd0d..0000000 --- a/src/customLayout.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "customLayout.hpp" -#include -#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(); -} diff --git a/src/main.cpp b/src/main.cpp index f2a1c55..b3f21ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,92 +4,35 @@ // version.hpp will be generated by meson #include "version.hpp" -#include +// #include #include -#include "customLayout.hpp" -#include "customDecoration.hpp" #include #include -// Methods -inline std::unique_ptr 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(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(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(); - - 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() { diff --git a/src/meson.build b/src/meson.build index e084c39..b866856 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,4 @@ -shared_module('example', +shared_module('wigglewobble', 'main.cpp', cpp_args: ['-DWLR_USE_UNSTABLE'], include_directories: incdir,