a plugin to make your hyprland cursor more realistic, also adds shake to find
a plugin to make your hyprland cursor more realistic, also adds shake to find
This plugin makes your cursor more realistic by simulating how it would behave if it was an actual object being dragged across your screen. This means that your cursor can change based on how it is used, e.g. tilt in the direction you are moving or straight out rotate towards it.
Why did I implement this again?
Inspired by KDE, it also supports shake to find, to enlarge the cursor when it is shaken, so it is easier to find it. It can be enabled separately or together with one simulation mode.
rotateIn this mode, the cursor is simulated as a stick which is dragged across the screen on one end. This means it will rotate towards the movement direction, and feels really realistic.
https://github.com/VirtCode/hypr-dynamic-cursor/assets/41426325/ccd6d742-8e2b-4073-a35e-318c7e19705c
tiltIn this mode, the cursor is tilted based on the x direction and speed it is moving at. It was intended to simulate how an object would be affected by air drag, but implemented is only a rough approximation. This mode can also be customized extensively with different activation functions, and is enabled by default.
stretchThis mode tries recreating the stretching and squishing that is done to moving object in comic animations. It stretches your cursor in the direction you are moving based on the speed. Yes, this is not at all realistic.
The plugin supports shake to find, akin to how KDE Plasma, MacOS, etc. do it. It can also be extensively configured and is enabled by default. It also supports using hyprcursor for high resolution cursor images. The magnification can also be triggered as a dispatcher instead of on shake. If you only want shake to find, and no weird cursor behaviour, you can disable the above modes with the mode none.
https://github.com/user-attachments/assets/1346101e-4e62-4ba2-a1df-5940e0706514
This plugin is still very early in its development. There are also multiple things which may or may not be implemented in the future:
If anything here sounds interesting to you, don't hesitate to contribute.
Please note that this plugin was created more or less as a joke. I mainly wanted to see how using a rotating or tilted cursor was like. So I will not guarantee any future updates and bugfixes. The only useful feature, shake to find, was implemented more or less as an afterthought.
Note that this plugin is only supported on
x86_64architectures, see compatibility for more info. If you don't know what this means, you're probably fine.
Installation is officially supported via hyprpm. Supported Hyprland versions are v0.41.2 and upwards and the latest commit on this main branch generally tries to target Hyprland's main branch (aka -git).
To install the plugin run the following. For more info and how to keep loading the plugin on startup, refer to hyprpm's section in the wiki.
hyprpm add https://github.com/virtcode/hypr-dynamic-cursors
hyprpm enable dynamic-cursorsSome Linux distributions have a package manager sophisticated enough to properly package and manage hyprland plugins with. While hyprpm is distribution agnostic, these mechanisms usually offer a better and more stable user experience. Below are some distributions which have packages for dynamic-cursors and how to install them.
NixOS
This plugin has special support for NixOS by either using the flake in this repo or a version from nixpkgs. Depending on how you manage your system, you can choose from either of them.
There is a Nix package in nixpkgs for this plugin. If you are using a release version of hyprland, it is recommended to use this version. Note however that this package is maintained by other people and might not be up-to-date.
To install the plugin from nixpkgs, add it to your Hyprland plugins list in your home-manager config:
wayland.windowManager.hyprland = {
enable = true;
plugins = [ pkgs.hyprlandPlugins.hypr-dynamic-cursors ];
};If you daily-drive the development version of hyprland, it is recommended to use the flake included with this plugin. Note that using a mismatched/unsupported Hyprland release will fail to build or load the plugin if you update.
Add the following flake to your inputs:
inputs = {
hyprland.url = "github:hyprwm/Hyprland"; # follows development branch of hyprland
hypr-dynamic-cursors = {
url = "github:VirtCode/hypr-dynamic-cursors";
inputs.hyprland.follows = "hyprland"; # to make sure that the plugin is built for the correct version of hyprland
};
};Then, in your home-manager config, add the plugin:
wayland.windowManager.hyprland = {
enable = true;
plugins = [ inputs.hypr-dynamic-cursors.packages.${pkgs.system}.hypr-dynamic-cursors ];
};Gentoo
The plugin is packaged for Gentoo in the Hyproverlay portage overlay containing the entire Hypr-* ecosystem, and as such, also Hyprland itself.
To install Hyprland itself, Hyproverlay should already be enabled but if it isn't, it can be enabled as follows:
eselect repository enable hyproverlay
emerge --sync hyproverlayBy nature of how the Hyprland plugin ecosystem works, Hyprland plugins are usually packaged as -9999 live ebuilds. As such, unmasking them with ** is required. This can be done by adding the following to a /etc/portage/package.accept_keywords list:
hyprland-plugin/dynamic-cursors **From there, dynamic-cursors can be installed as
emerge --ask hyprland-plugin/dynamic-cursorsThis installs the plugin to /usr/lib/hyprland-plugins/dynamic-cursors.so, from where it can be loaded by Hyprland by adding the following to your hyprland.lua config:
hl.plugin.load("/usr/lib/hyprland-plugins/dynamic-cursors.so")Note: This does not need Hyprland to be compiled with the
hyprpmUSE flag, as that USE flag only controls the inclusion of the plugin manager, and not the plugin mechanism itself. As such, nohyprpm updateis required to update plugins after a Hyprland update.Portage should rebuild plugins automatically whenever it updates Hyprland, but this may fail for certain edgecases. In this case a rebuild must be triggered manually as:
emerge --ask --oneshot hyprland-plugin/dynamic-cursors
If you think your distro has good packages for dynamic-cursors but it is not listed here, MRs are welcome!
Don't forget to put the configuration for this plugin inside an
ifblock like the following to avoid config errors when the plugin is not loaded.if hl.plugin.dynamic_cursors then ... end
This plugin can be configured in its dedicated configuration section (plugin.dynamic_cursors). The default values are shown below.
…Shape Rules can be used to override the mode or its behaviour on a per-shape basis. For instance, you can add a rule such that only the text cursor shape is always in tilt mode and not e.g. rotate.
Note: Shape rules only apply to server side cursor shapes. Sadly, not everyone supports server side cursors yet, which means shape rules won't work in some applications (mainly xwayland apps).
A shape rule is defined like this:
hl.plugin.dynamic_cursors.shape_rule {
-- name of the shape to apply to
-- see below
shape = "",
-- config variables to override
-- supported values are from the `rotate`, `tilt` and `stretch` category,
-- and also the `mode` configuration value
property = ,
property = { property = },
...
}For the shape you should provide the name of the shape the rule will apply to. Should be one of those specified in the protocol. You can use the special shape clientside to apply your rule to ALL client side cursors. Also note that the compositor will set the shape to left_ptr if you are on the wallpaper.
It is possible to specificy multiple rules per shape, but properties overridden by later rules will have precendence.
Here are a few example rules to get you started:
-- apply a 90° offset in rotate mode to the text shape
hl.plugin.dynamic_cursors.shape_rule { shape = "text", rotate = { offset = 90.0 } } }
-- use stretch mode when grabbing, and set the limit low
hl.plugin.dynamic_cursors.shape_rule { shape = "grab", mode = "stretch", stretch = { limit = 2000 } } }
-- do not show any effects on clientside cursors
hl.plugin.dynamic_cursors.shape_rule { shape = "clientside", mode = "none" }This plugin can expose cursor shake events via IPC. This behaviour must be explicitly enabled via the plugin.dynamic_cursors.shake.ipc option, as it will spam the socket quite a bit during a shake. These events will appear on Hyprland's event socket.
The following events with the described arguments are available, when IPC is enabled:
shakestart: fired when a shake is detected.shakeupdate: fired on frame during the shake, has arguments x, y, trail, diagonal, zoom:x, y are the current cursor position.trail and diagonal are two floats, the first indicating the distance the mouse travelled, and second the diagonal this movement was within. Their quotient trail / diagonal indicates how intense the shaking is.zoom is the current cursor magnification level, as currently shown by this plugin, depending on the shake configuration. It is also interpolated smoothly.shakeend: fired when a shake has ended (after the timeout)This plugin supports using hyprcursor to get higher-resolution images for when the cursor is magnified, i.e. when using shake to find. Due to the nature of cursors on wayland, there are some caveats to it. All configuration for it is located in the plugin.dynamic_cursors.hyprcursor section.
To use hyprcursor for magnified shapes, the following must be met:
plugin.dynamic_cursors.hyprcursor.enabled must be true (is by default)cursor.enable_hyprcursor must be true (is by default)As mentioned, there are some caveats to it. Here are the most common ones:
fallback option (see config).resolution option (see config), atNo open issues yet, or sync has not completed.