fix a lot of mistakes and reorganize a few things

This commit is contained in:
Vaxry 2026-04-24 13:38:57 +01:00
parent e8669e7be6
commit 8acc05d970
No known key found for this signature in database
19 changed files with 298 additions and 588 deletions

View file

@ -3,6 +3,10 @@ weight: 5
title: Binds
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
## Basic
```lua
@ -96,7 +100,6 @@ hyprctl eval hl.unbind("SUPER + O")
```lua
hl.bind(keys, dispatcher, { flag1 = true, flag2 = true })
```
e.g.:
@ -120,7 +123,7 @@ Available flags:
| `transparent` | Cannot be shadowed by other binds. |
| `ignore_mods` | Will ignore modifiers. |
| `separate` | Will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos). |
| `description` or `desc` | Will allow you to write a description for your bind. |
| `description` | Will allow you to write a description for your bind. |
| `bypass` | Bypasses the app's requests to inhibit keybinds. |
| `submap_universal` | Will be active no matter the submap. |
| `devices` | Allow binds to be set per device. See [Per-Device Binds](#per-device-binds) |
@ -147,7 +150,7 @@ hl.bind("SUPER + XF86AudioNext", hl.dsp.exec_cmd("playerctl position +5"))
You can also bind or unbind mouse buttons by prefacing the mouse keycode with `mouse:`, e.g.:
```lua
hl.bind(SUPER + mouse:272), hl.exec("amongus")) -- bind `exec amogus` to SUPER + LMB.
hl.bind("SUPER + mouse:272", hl.dsp.exec_cmd("amongus")) -- bind `exec amogus` to SUPER + LMB.
```
### Binding modkeys only
@ -166,7 +169,7 @@ You can also bind mouse wheel events with `mouse_up` and `mouse_down` (or
`mouse_left` and `mouse_right` if your mouse supports horizontal scrolling):
```lua
hl.bind("SUPER + mouse_down", hl.focus.workspace("e-1"))
hl.bind("SUPER + mouse_down", hl.dsp.focus({ workspace = "e-1" }))
```
> [!NOTE]
@ -198,8 +201,8 @@ You can trigger multiple actions with the same keybind by using a lua lambda fun
```lua
-- To switch between windows in a floating workspace:
hl.bind("SUPER + Tab", function()
hl.cyclenext() -- Change focus to another window
hl.bringactivetotop()) -- Bring it to the top
hl.dispatch(hl.dsp.window.cycle_next()) -- Change focus to another window
hl.dispatch(hl.dsp.window.bring_to_top()) -- Bring it to the top
end)
```
@ -212,13 +215,13 @@ You can describe your keybind with the `description` flag.
Your description always goes in the flags section.
```lua
hl.bind(keys, dispatcher, { description = "your description here"}
hl.bind(keys, dispatcher, { description = "your description here"})
```
For example:
```lua
hl.bind("SUPER + Q", hl.dsp.exec_cmd("kitty"), { description = "Open my favourite terminal" }
hl.bind("SUPER + Q", hl.dsp.exec_cmd("kitty"), { description = "Open my favourite terminal" })
```
If you want to access your description you can use `hyprctl binds`.
@ -252,19 +255,19 @@ These are binds that rely on mouse movement. They will have one less arg.
```lua
hl.config({
binds {
drag_threshold = 10 # Fire a drag event only after dragging for more than 10px
drag_threshold = 10 -- Fire a drag event only after dragging for more than 10px
}
}
hl.bind("ALT + mouse:272", hl.movewindow(), { mouse = true }) -- ALT + LMB: Move a window by dragging more than 10px.
hl.bind("ALT + mouse:272", hl.togglefloating(), { mouse = true }) -- ALT + LMB: Floats a window by clicking
})
hl.bind("ALT + mouse:272", hl.dsp.window.drag(), { mouse = true }) -- ALT + LMB: Move a window by dragging more than 10px.
hl.bind("ALT + mouse:272", hl.dsp.window.resize(), { mouse = true }) -- ALT + LMB: Floats a window by clicking
```
Available mouse binds:
| Name | Description | Params |
| ---- | ----------- | ------ |
| movewindow | moves the active window | None |
| resizewindow | resizes the active window | `1` -> Resize and keep window aspect ratio. <br> `2` -> Resize and ignore `keepaspectratio` window rule/prop. <br> None or anything else for normal resize |
| `drag()` | moves the active window | None |
| `resize()` | resizes the active window | None |
Common mouse button key codes (check `wev` for other buttons):
@ -284,11 +287,11 @@ MMB -> 274
As clicking and moving the mouse on a touchpad is unergonomic, you can also use keyboard keys instead of mouse clicks.
```lua
hl.bind("SUPER + mouse:272", hl.movewindow(), { mouse = true })
hl.bind("SUPER + CTRL_L", hl.movewindow(), { mouse = true })
hl.bind("SUPER + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind("SUPER + CTRL_L", hl.dsp.window.drag(), { mouse = true })
hl.bind("SUPER + mouse:273", hl.resizewindow(), { mouse = true })
hl.bind("SUPER + ALT_L, hl.resizewindow(), { mouse = true })
hl.bind("SUPER + mouse:273", hl.dsp.window.resize(), { mouse = true })
hl.bind("SUPER + ALT_L", hl.dsp.window.resize(), { mouse = true })
```
## Global Keybinds
@ -320,7 +323,7 @@ hl.bind("mouse:276", hl.dsp.pass("class:^(TeamSpeak 3)$")) # Pass MOUSE5 to T
You may also add shortcuts, where other keys are passed to the window.
```lua
hl.bind("SUPER + F10", hl.dsp.send_shortcut("SUPER + F4", class:^(TeamSpeak 3)$")) # Send SUPER + F4 to OBS when SUPER + F10 is pressedl.
hl.bind("SUPER + F10", hl.dsp.send_shortcut({ mods = "SUPER", key = "F4", window = "class:^(TeamSpeak 3)$" })) -- Send SUPER + F4 to OBS when SUPER + F10 is pressed.
```
> [!WARNING]
@ -354,10 +357,10 @@ For example, if you want to enter a `resize` _mode_ that allows you to resize wi
```lua
-- Switch to a submap called `resize`.
hl.bind("ALT + R", hl.dsp.submap("resize")
hl.bind("ALT + R", hl.dsp.submap("resize"))
-- Start a submap called "resize".
hl.dsp.submap("resize", function()
hl.define_submap("resize", function()
-- Set repeating binds for resizing the active window.
hl.bind("right", hl.resize({ x = 10, y = 0, relative = true}), { repeating = true })
@ -385,7 +388,7 @@ and close the submap, like so:
```lua
hl.bind("ALT + R", hl.dsp.submap("resize"))
hl.dsp.submap("resize", function()
hl.define_submap("resize", function()
hl.bind("right", function()
hl.window.resize({ x = 10, y = 0, relative = true })
hl.dsp.submap("reset")
@ -408,13 +411,13 @@ Submaps can be nested, see the following example:
```lua
hl.bind(mainMod .. " + M", hl.dsp.submap("main_submap"))
hl.dsp.submap(main_submap, function()
hl.define_submap(main_submap, function()
-- ...
-- nested_one
hl.bind("1", hl.dsp.submap("nested_one")
hl.dsp.submap("nested_one", function()
hl.bind("1", hl.dsp.submap("nested_one"))
hl.define_submap("nested_one", function()
-- ...
@ -423,7 +426,7 @@ hl.dsp.submap(main_submap, function()
-- nested_two
hl.bind("2", hl.dsp.submap("nested_two"))
hl.dsp.submap("nested_two", function()
hl.define_submap("nested_two", function()
-- ...
@ -445,16 +448,16 @@ end)
Submaps can be automatically closed or sent to another submap by appending ``,`` followed by a submap or _reset_.
```lua
hl.bind("SUPER + a", hl.dsp.submap("submapA")
hl.bind("SUPER + a", hl.dsp.submap("submapA"))
-- Sets the submap to submapB after pressing a.
hl.dsp.submap("submapA", "submapB", function()
hl.define_submap("submapA", "submapB", function()
hl.bind("a", hl.dsp.exec_cmd("someCoolThing.sh"))
end)
-- Reset submap to default after pressing a.
hl.dsp.submap("submapB", "reset", function()
hl.bind("a", hl.dsp.exec_cmd("someOtherCoolThing.sh")
hl.bind("a", hl.dsp.exec_cmd("someOtherCoolThing.sh"))
end)
```
@ -469,6 +472,58 @@ while in a submap or to exit it immediately when any unknown key is pressed:
hl.bind("catchall", hl.dsp.submap("reset"))
```
## Switchable keyboard layouts
The easiest way to accomplish this is to set this using XKB settings, for
example:
```lua
hl.config({
input = {
kb_layout = "us,cz",
kb_variant = "qwerty",
kb_options = "grp:alt_shift_toggle"
}
})
```
Variants are set per layout.
> [!WARNING]
> The first layout defined in the input section will be the one used for binds by
> default.
>
> For example: `us,ua` -> config binds would be e.g. `"SUPER + A"`, while on `ua,us`
> -> `"SUPER + Cyrillic_ef`
>
> You can change this behavior globally or per-device by setting
> `resolve_binds_by_sym = 1`. In that case, binds will activate when the symbol
> typed matches the symbol specified in the bind.
>
> For example: if your layouts are `us,fr` and have a bind for `"SUPER + A"` you'd
> need to press the first letter on the second row while the `us` layout is active
> and the first letter on the first row while the `fr` layout is active.
You can also bind a key to execute `hyprctl switchxkblayout` for more keybind
freedom. See [Using hyprctl](../Using-hyprctl).
To find the valid layouts and `kb_options`, you can check out the
`/usr/share/X11/xkb/rules/base.lst`. For example:
To get the layout name of a language:
```sh
grep -i 'persian' /usr/share/X11/xkb/rules/base.lst
```
To get the list of keyboard shortcuts you can put in the `kb_options` to toggle
keyboard layouts:
```sh
grep 'grp:.*toggle' /usr/share/X11/xkb/rules/base.lst
```
## Example Binds
### Media
@ -486,3 +541,47 @@ hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = tru
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
```
### Disabling keybinds with one master keybind
If you want to disable all keybinds with another keybind (make a keybind toggle
of sorts) you can just use a submap with only a keybind to exit it.
```lua
hl.bind(KEYS, hl.dsp.submap("clean"))
hl.define_submap("clean", function()
hl.bind(KEYS, hl.dsp.submap("reset"))
end)
```
### Remapping Caps Lock
You can customize the behavior of the Caps Lock key using `kb_options`.
To view all available options related to Caps Lock, run:
```sh
grep 'caps' /usr/share/X11/xkb/rules/base.lst
```
For example, to remap Caps lock to Ctrl:
```lua
hl.config({
input = {
kb_options = "ctrl:nocaps"
}
})
```
To swap Caps Lock and Escape:
```lua
hl.config({
input = {
kb_options = "caps:swapescape"
}
})
```
You can also find additional `kb_options` unrelated to Caps Lock in `/usr/share/X11/xkb/rules/base.lst`.

View file

@ -3,6 +3,10 @@ weight: 12
title: Dwindle Layout
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
Dwindle is a BSPWM-like layout, where every window on a workspace is a member of
a binary tree.

View file

@ -41,7 +41,7 @@ hl.env("GTK_THEME", "Nord")
## Aquamarine Environment Variables <!-- ref https://github.com/hyprwm/aquamarine/blob/main/docs/env.md -->
- `hl.env("AQ_TRACE", "1")` - Enables more verbose logging.
- `hl.env("AQ_DRM_DEVICES", "`") - Set an explicit list of DRM devices (GPUs) to use. It's a colon-separated list of paths, with the first being the primary.
- `hl.env("AQ_DRM_DEVICES", "...")` - Set an explicit list of DRM devices (GPUs) to use. It's a colon-separated list of paths, with the first being the primary.
E.g.: `/dev/dri/card1:/dev/dri/card0`
- `hl.env("AQ_FORCE_LINEAR_BLIT", "0")` - Disables forcing linear explicit modifiers on Multi-GPU buffers to potentially workaround Nvidia issues.
- `hl.env("AQ_MGPU_NO_EXPLICIT", "1")` - Disables explicit syncing on mgpu buffers.

View file

@ -102,9 +102,9 @@ You can expand functionality e.g. like so:
hl.bind("SUPER + X", function()
local w = hl.get_active_window()
if w ~= nil and w.title == "htop" do
hl.dispatch(hl.window.float({ action = "set" }))
hl.dispatch(hl.dsp.window.float({ action = "set" }))
else
hl.dispatch(hl.window.float({ action = "toggle" }))
hl.dispatch(hl.dsp.window.float({ action = "toggle" }))
end
end)
```

View file

@ -3,6 +3,10 @@ weight: 10
title: Gestures
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
## General
Hyprland supports 1:1 gestures for the trackpad for some operations. The basic syntax looks like this:
@ -42,23 +46,23 @@ The following directions are supported:
Specifying `unset` as the action will unset a specific gesture that was previously set. Please note it needs to exactly match everything
from the original gesture including direction, mods, fingers and scale.
| action | Description | Arguments |
| action | Description | Additional arguments |
| --- | --- | --- |
| _lua function_ | Executes a named lua function or lua lambda function. See below. | none |
| workspace | Workspace swipe gesture, for switching workspaces. | none |
| move | Moves the active window. | none |
| resize | Resizes the active window. | none |
| special | Toggles a special workspace. | `arg` = special workspace name without `special:`, e.g. `"mySpecialWorkspace"` |
| special | Toggles a special workspace. | `workspace_name`, self-explanatory |
| close | Closes the active window. | none |
| fullscreen | Fullscreens the active window. | none for fullscreen, `arg = "maximize"` for maximize |
| float | Floats the active window. | none to toggle, `arg = "float"` or `arg = "tile"` for one-way |
| cursorZoom | Zooms into the cursor. | `arg` = zoom factor, add `arg2 = "mult"` for a multiplier instead of toggle |
| fullscreen | Fullscreens the active window. | `mode` can be `"maximize"` to do maximize instead of fullscreen |
| float | Floats the active window. | `mode` can be `"float"` or `"tile"` to force a direction of floating |
| cursorZoom | Zooms into the cursor. | `zoom_level` for a zoom factor, `mode` of `"mult"` to use a multiplier instead of a toggle |
#### Lua function
The lua function can be named or a lambda.
Example of lambda:
An example of a lambda:
```lua
hl.gesture({
fingers = 3,
@ -69,7 +73,7 @@ hl.gesture({
})
```
Example of named function:
An example of a named function:
```lua
local swipe = function()
hl.notification.create({ text = "I just swiped on my trackpad!", duration = 5000, icon = "ok" })
@ -91,10 +95,10 @@ hl.gesture({
| action | string | Action to perform (see above) |
| mods | string | Optional modifier mask, e.g. `"SUPER"` or `"ALT SHIFT"` |
| scale | float | Optional animation speed multiplier |
| arg | string | Optional first argument for the action |
| arg2 | string | Optional second argument for the action |
| disable_inhibit | boolean | If true, allows the gesture to bypass shortcut inhibitors |
Some gestures might have their own additional fields, those were mentioned in the actions table further up.
### Examples
Run a lua lambda function, open a terminal with a 4-finger swipe up:

View file

@ -3,6 +3,10 @@ weight: 13
title: Master Layout
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
The master layout makes one (or more) window(s) be the "master", taking (by
default) the left part of the screen, and tiles the rest on the right. You can
change the orientation on a per-workspace basis if you want to use anything other
@ -12,7 +16,7 @@ than the default left/right split.
## Config
_category name `master` (`hl.config({ master })`)
_category name `master` (`hl.config({ master = {...} })`)
| name | description | type | default |
| --- | --- | --- | --- |
@ -31,7 +35,7 @@ _category name `master` (`hl.config({ master })`)
## Layout messages
Dispatcher `hl.dsp.layout(mds)` params:
Dispatcher `hl.dsp.layout(string)` params:
| command | description | params |
| --- | --- | --- |
@ -63,7 +67,7 @@ Parameters for the commands are separated by a single space.
> ```lua
> hl.bind(KEYS, hl.dsp.layout("cyclenext"))
> -- behaves like xmonads promote feature (https://hackage.haskell.org/package/xmonad-contrib-0.17.1/docs/XMonad-Actions-Promote.html)
> hl.bind(KEYS, hl.dsp.layout("swapwithmaster", "master"))
> hl.bind(KEYS, hl.dsp.layout("swapwithmaster master"))
> ```
## Workspace Rules

View file

@ -3,6 +3,10 @@ weight: 4
title: Monitors
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
## General
The general config of a monitor looks like this:
@ -12,7 +16,7 @@ hl.monitor({
output = "...",
mode = "...",
position = "...",
scale = "...",
scale = ...,
})
```
@ -23,7 +27,7 @@ hl.monitor({
output = "DP-1",
mode = "1920x1080@144",
position = "0x0",
scale = "1",
scale = 1,
})
```
@ -42,15 +46,15 @@ in pixels, of said display in the layout. (calculated from the top-left corner)
For example:
```lua
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = "1" })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "1920x0", scale = "1" })
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = 1 })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "1920x0", scale = 1 })
```
will tell Hyprland to put DP-1 on the _left_ of DP-2, while
```lua
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "1920x0", scale = "1" })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x0", scale = "1" })
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "1920x0", scale = 1 })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x0", scale = 1 })
```
will tell Hyprland to put DP-1 on the _right_.
@ -59,8 +63,8 @@ The `position` may contain _negative_ values, so the above example could also be
written as
```lua
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = "1" })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "-1920x0", scale = "1" })
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = 1 })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "-1920x0", scale = 1 })
```
Hyprland uses an inverse Y cartesian system. Thus, a negative y coordinate
@ -69,15 +73,15 @@ places a monitor higher, and a positive y coordinate will place it lower.
For example:
```lua
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = "1" })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x-1080", scale = "1" })
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = 1 })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x-1080", scale = 1 })
```
will tell Hyprland to put DP-2 _above_ DP-1, while
```lua
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = "1" })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x1080", scale = "1" })
hl.monitor({ output = "DP-1", mode = "1920x1080", position = "0x0", scale = 1 })
hl.monitor({ output = "DP-2", mode = "1920x1080", position = "0x1080", scale = 1 })
```
will tell Hyprland to put DP-2 _below_.
@ -128,7 +132,7 @@ These depend on the PPI of the monitor.
Recommended rule for quickly plugging in random monitors:
```lua
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = "1" })
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = 1 })
```
This will make any monitor that was not specified with an explicit rule
@ -152,7 +156,7 @@ then the `description` value up to, but not including the portname `(eDP-1)` can
be used as the `output` field with a `desc:` prefix:
```lua
hl.monitor({ output = "desc:Chimei Innolux Corporation 0x150C", mode = "preferred", position = "auto", scale = "1.5" })
hl.monitor({ output = "desc:Chimei Innolux Corporation 0x150C", mode = "preferred", position = "auto", scale = 1.5 })
```
Remember to remove the `(portname)`!
@ -166,7 +170,7 @@ hl.monitor({
output = "DP-1",
mode = "modeline 1071.101 3840 3848 3880 3920 2160 2263 2271 2277 +hsync -vsync",
position = "0x0",
scale = "1",
scale = 1,
})
```
@ -209,7 +213,7 @@ All fields beyond `output` are optional and fall back to sensible defaults.
| output | string | required | Output name or `desc:...` description prefix |
| mode | string | preferred | Resolution and refresh rate, e.g. `1920x1080@144` |
| position | string | auto | Position in the virtual layout, e.g. `1920x0` |
| scale | string | auto | Scale factor, e.g. `1.5` |
| scale | string / float | auto | Scale factor, e.g. `1.5` |
| disabled | boolean | false | Removes the monitor from the layout |
| transform | integer | 0 | Rotation/flip transform (07) |
| mirror | string | | Output name to mirror |
@ -220,7 +224,7 @@ All fields beyond `output` are optional and fall back to sensible defaults.
| sdrsaturation | float | 1.0 | SDR saturation in HDR mode |
| vrr | integer | 0 | VRR mode |
| icc | string | | Absolute path to an ICC profile |
| reserved_area | integer or table | 0 | Reserved area integer for all sides, or table with top/right/bottom/left |
| reserved_area | integer or table | 0 | Reserved area - integer for all sides, or table with top/right/bottom/left |
| supports_wide_color | integer | 0 | Force wide color gamut (-1 = off, 0 = auto, 1 = on) |
| supports_hdr | integer | 0 | Force HDR support (-1 = off, 0 = auto, 1 = on) |
| sdr_min_luminance | float | 0.2 | SDR minimum luminance for SDR→HDR mapping |
@ -234,8 +238,8 @@ All fields beyond `output` are optional and fall back to sensible defaults.
If you want to mirror a display, use the `mirror` field:
```lua
hl.monitor({ output = "DP-3", mode = "1920x1080@60", position = "0x0", scale = "1", mirror = "DP-2" })
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = "1", mirror = "DP-1" })
hl.monitor({ output = "DP-3", mode = "1920x1080@60", position = "0x0", scale = 1, mirror = "DP-2" })
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = 1, mirror = "DP-1" })
```
Please remember that mirroring displays will not "re-render" everything for your
@ -248,7 +252,7 @@ will occur on aspect ratios that differ (e.g 16:9 and 16:10).
If you want to enable 10 bit support for your display, set `bitdepth = 10`:
```lua
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = "1", bitdepth = 10 })
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = 1, bitdepth = 10 })
```
> [!WARNING]
@ -261,7 +265,7 @@ hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale =
Use the `cm` field to change the default sRGB output preset:
```lua
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = "1", bitdepth = 10, cm = "wide" })
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = 1, bitdepth = 10, cm = "wide" })
```
```plain
@ -286,7 +290,7 @@ hl.monitor({
output = "eDP-1",
mode = "2880x1800@90",
position = "0x0",
scale = "1",
scale = 1,
bitdepth = 10,
cm = "hdr",
sdrbrightness = 1.2,
@ -322,7 +326,7 @@ Per-display VRR can be configured with the `vrr` field, where the value is the m
If you want to rotate a monitor, use the `transform` field:
```lua
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = "1", transform = 1 })
hl.monitor({ output = "eDP-1", mode = "2880x1800@90", position = "0x0", scale = 1, transform = 1 })
```
Transform list:

View file

@ -3,6 +3,10 @@ weight: 14
title: Monocle Layout
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
Monocle is a layout where windows are always taking up the entire available space.
## Quirks
@ -12,7 +16,7 @@ windows, either use `hl.dsp.layout("cyclenext")` or `hl.dsp.window.cycle_next("t
## Layout messages
Dispatcher `hl.layout(msg)` params:
Dispatcher `hl.dsp.layout(msg)` params:
| name | description | params |
| --- | --- | --- |

View file

@ -3,6 +3,10 @@ weight: 80
title: Multi-GPU
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
## General
If your host machine uses multiple GPUs, you may want to use one GPU

View file

@ -3,6 +3,10 @@ weight: 300
title: Performance
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
This page documents known tricks and fixes to boost performance if by any chance
you stumble upon problems or you do not care that much about animations.
@ -12,7 +16,7 @@ Wayland fractional scaling is a lot better than before, but it is not perfect.
Some applications do not support it yet or the support is experimental at best.
If you have problems with your graphics card having high usage or Hyprland
feeling laggy, try setting the scaling to integer numbers such as `1` or `2`
like in this example `hl.monitor({ output = "", mode = "preferred", position = "auto", scale = "2" })`.
like in this example `hl.monitor({ output = "", mode = "preferred", position = "auto", scale = 2 })`.
## Low FPS/stutter/FPS drops on Intel iGPU with TLP (mainly laptops)

View file

@ -3,6 +3,10 @@ weight: 30
title: Permissions
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
If you have `hyprland-guiutils` installed, you can make use of Hyprland's built-in
permission system.
@ -16,7 +20,7 @@ want to let it do that.
> [!NOTE]
> Before setting up permissions, make sure you enable them by setting
> `hl.config({ ecosystem = { enforce_permissions = true} })`, as it's disabled by default.
> `hl.config({ ecosystem = { enforce_permissions = true } })`, as it's disabled by default.
### Configuring permissions

View file

@ -3,11 +3,15 @@ weight: 13
title: Scrolling Layout
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
Scrolling is a layout where windows get positioned on an infinitely growing tape.
## Config
category name: `scrolling` (`hl.config({ scrolling })`)
category name: `scrolling` (`hl.config({ scrolling = {...} })`)
| name | description | type | default |
| --- | --- | --- | --- |
@ -17,8 +21,8 @@ category name: `scrolling` (`hl.config({ scrolling })`)
| follow_focus | when a window is focused, should the layout move to bring it into view automatically | bool | true |
| follow_min_visible | when a window is focused, require that at least a given fraction of it is visible for focus to follow. Hard input (e.g. binds, clicks) will always follow. [0.0 - 1.0] | float | 0.4 |
| explicit_column_widths | A comma-separated list of preconfigured widths for colresize +conf/-conf | str | 0.333, 0.5, 0.667, 1.0 |
| wrap_focus | When enabled, causes `hl.dsp.layoutmsg("focus", "l/r")` to wrap around at the beginning and end. | bool | true |
| wrap_swapcol | When enabled, causes `hl.dsp.layoutmsg("swapcol", "l/r")` to wrap around at the beginning and end. | bool | true |
| wrap_focus | When enabled, causes `hl.dsp.layoutmsg("focus l/r")` to wrap around at the beginning and end. | bool | true |
| wrap_swapcol | When enabled, causes `hl.dsp.layoutmsg("swapcol l/r")` to wrap around at the beginning and end. | bool | true |
| direction | Direction in which new windows appear and the layout scrolls. left/right/down/up | str | right |
## Workspace rules
@ -49,8 +53,8 @@ Dispatcher `hl.dsp.layout(msg)` params:
Example key bindings for your Hyprland config:
```lua
hl.bind(mainMod .. "period", hl.dsp.layout("move", "+col"))
hl.bind(mainMod .. "comma", hl.dsp.layout("swapcol", "l"))
hl.bind(mainMod .. "period", hl.dsp.layout("move +col"))
hl.bind(mainMod .. "comma", hl.dsp.layout("swapcol l"))
```
## Window rules

View file

@ -3,6 +3,10 @@ weight: 11
title: Tearing
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
Screen tearing is used to reduce latency and/or jitter in games.
## Enabling tearing

View file

@ -1,431 +0,0 @@
---
weight: 250
title: Uncommon tips & tricks
---
## Switchable keyboard layouts
The easiest way to accomplish this is to set this using XKB settings, for
example:
```lua
hl.config({
input = {
kb_layout = "us,cz",
kb_variant = "qwerty",
kb_options = "grp:alt_shift_toggle"
}
})
```
Variants are set per layout.
> [!WARNING]
> The first layout defined in the input section will be the one used for binds by
> default.
>
> For example: `us,ua` -> config binds would be e.g. `"SUPER + A"`, while on `ua,us`
> -> `"SUPER + Cyrillic_ef`
>
> You can change this behavior globally or per-device by setting
> `resolve_binds_by_sym = 1`. In that case, binds will activate when the symbol
> typed matches the symbol specified in the bind.
>
> For example: if your layouts are `us,fr` and have a bind for `"SUPER + A"` you'd
> need to press the first letter on the second row while the `us` layout is active
> and the first letter on the first row while the `fr` layout is active.
You can also bind a key to execute `hyprctl switchxkblayout` for more keybind
freedom. See [Using hyprctl](../Using-hyprctl).
To find the valid layouts and `kb_options`, you can check out the
`/usr/share/X11/xkb/rules/base.lst`. For example:
To get the layout name of a language:
```sh
grep -i 'persian' /usr/share/X11/xkb/rules/base.lst
```
To get the list of keyboard shortcuts you can put in the `kb_options` to toggle
keyboard layouts:
```sh
grep 'grp:.*toggle' /usr/share/X11/xkb/rules/base.lst
```
## Disabling keybinds with one master keybind
If you want to disable all keybinds with another keybind (make a keybind toggle
of sorts) you can just use a submap with only a keybind to exit it.
```lua
hl.bind(KEYS, hl.dsp.submap("clean"))
hl.define_submap("clean", function()
hl.bind(KEYS, hl.dsp.submap("reset"))
end)
```
## Remapping Caps Lock
You can customize the behavior of the Caps Lock key using `kb_options`.
To view all available options related to Caps Lock, run:
```sh
grep 'caps' /usr/share/X11/xkb/rules/base.lst
```
For example, to remap Caps lock to Ctrl:
```lua
hl.config({
input = {
kb_options = "ctrl:nocaps"
}
})
```
To swap Caps Lock and Escape:
```lua
hl.config({
input = {
kb_options = "caps:swapescape"
}
})
```
You can also find additional `kb_options` unrelated to Caps Lock in `/usr/share/X11/xkb/rules/base.lst`.
## Set F13-F24 as usual function keys
By default, F13-F24 are mapped by xkb as various "XF86" keysyms. These cause binding
issues in many programs. One example is OBS Studio, which does not detect the XF86
keysyms as usable keybindings, making you unable to use them for binds. This option
simply maps them back to the expected F13-F24 values, which are bindable as normal.
> [!WARNING]
> This option was only added recently to `xkeyboard-config`. Please ensure you are on version
> 2.43 or greater for this option to do anything.
```lua
hl.config({
input = {
kb_options = "fkeys:basic_13-24"
}
})
```
## Minimize windows using special workspaces
This approach uses special workspaces to mimic the "minimize window" function, by using a single keybind to toggle the minimized state.
Note that this can only handle one window at a time.
```bash
#!/usr/bin/env bash
if [[ -z $(hyprctl workspaces | grep special:magic) ]]; then
hyprctl dispatch movetoworkspacesilent special:magic
else
hyprctl --batch "dispatch togglespecialworkspace magic; dispatch movetoworkspace +0"
fi
```
then bind it:
```lua
hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("<PATH_TO_SCRIPT>"))
```
## Show desktop
This approach uses same principle as the [Minimize windows using special workspaces](#minimize-windows-using-special-workspaces) section.
It moves all windows from current workspace to a special workspace named `desktop`.
Showing desktop state is remembered per workspace.
Create a script:
```bash
#!/usr/bin/env bash
TMP_FILE="$XDG_RUNTIME_DIR/hyprland-show-desktop"
CURRENT_WORKSPACE=$(hyprctl monitors -j | jq '.[] | .activeWorkspace | .name' | sed 's/"//g')
if [ -s "$TMP_FILE-$CURRENT_WORKSPACE" ]; then
readarray -d $'\n' -t ADDRESS_ARRAY <<< $(< "$TMP_FILE-$CURRENT_WORKSPACE")
for address in "${ADDRESS_ARRAY[@]}"
do
CMDS+="dispatch movetoworkspacesilent name:$CURRENT_WORKSPACE,address:$address;"
done
hyprctl --batch "$CMDS"
rm "$TMP_FILE-$CURRENT_WORKSPACE"
else
HIDDEN_WINDOWS=$(hyprctl clients -j | jq --arg CW "$CURRENT_WORKSPACE" '.[] | select (.workspace .name == $CW) | .address')
readarray -d $'\n' -t ADDRESS_ARRAY <<< $HIDDEN_WINDOWS
for address in "${ADDRESS_ARRAY[@]}"
do
address=$(sed 's/"//g' <<< $address )
if [[ -n address ]]; then
TMP_ADDRESS+="$address\n"
fi
CMDS+="dispatch movetoworkspacesilent special:desktop,address:$address;"
done
hyprctl --batch "$CMDS"
echo -e "$TMP_ADDRESS" | sed -e '/^$/d' > "$TMP_FILE-$CURRENT_WORKSPACE"
fi
```
then bind it:
```lua
hl.bind(mainMod .. " + D", hl.dsp.exec_cmd("<PATH TO SCRIPT>"))
```
## Minimize Steam instead of killing
Steam will exit entirely when its last window is closed using the `killactive`
dispatcher. To minimize Steam to tray, use the following script to close
applications:
```sh
if [ "$(hyprctl activewindow -j | jq -r ".class")" = "Steam" ]; then
xdotool getactivewindow windowunmap
else
hyprctl dispatch killactive ""
fi
```
## Shimeji
To use Shimeji programs like
[this](https://codeberg.org/thatonecalculator/spamton-linux-shimeji), set the
following rules:
```lua
hl.window_rule({
name = "shimeji",
match = { class = "com-group_finity-mascot-Main" },
float = true,
no_blur = true,
no_focus = true,
no_shadow = true,
border_size = 0,
})
```
> [!NOTE]
> The app indicator probably won't show, so you'll have to `killall -9 java` to
> kill them.
![Demo GIF of Spamton Shimeji](https://github.com/hyprwm/hyprland-wiki/assets/36706276/261afd03-bf41-4513-b72b-3483d43d418c)
## Toggle animations/blur/etc hotkey
For increased performance in games, or for less distractions at a keypress
1. create file
`~/.config/hypr/gamemode.sh && chmod +x ~/.config/hypr/gamemode.sh` and add:
```bash
#!/usr/bin/env sh
HYPRGAMEMODE=$(hyprctl getoption animations:enabled | awk 'NR==1{print $2}')
if [ "$HYPRGAMEMODE" = 1 ] ; then
hyprctl --batch "\
keyword animations:enabled 0;\
keyword animation borderangle,0; \
keyword decoration:shadow:enabled 0;\
keyword decoration:blur:enabled 0;\
keyword decoration:fullscreen_opacity 1;\
keyword general:gaps_in 0;\
keyword general:gaps_out 0;\
keyword general:border_size 1;\
keyword decoration:rounding 0"
hyprctl notify 1 5000 "rgb(40a02b)" "Gamemode [ON]"
exit
else
hyprctl notify 1 5000 "rgb(d20f39)" "Gamemode [OFF]"
hyprctl reload
exit 0
fi
exit 1
```
Edit to your liking of course. If animations are enabled, it disables all the
pretty stuff. Otherwise, the script reloads your config to grab your defaults.
2. Add this to your Lua config:
```lua
hl.bind("SUPER + F1", hl.dsp.exec_cmd("~/.config/hypr/gamemode.sh"))
```
The hotkey toggle will be WIN+F1, but you can change this to whatever you want.
## Zoom
To zoom using Hyprland's built-in zoom utility
> [!WARNING]
> If mouse wheel bindings work only for the first time, you should probably reduce reset time with `binds:scroll_event_delay`
```lua
local zoomIn = "hyprctl -q keyword cursor:zoom_factor $(hyprctl getoption cursor:zoom_factor -j | jq '.float * 1.1')"
local zoomOut = "hyprctl -q keyword cursor:zoom_factor $(hyprctl getoption cursor:zoom_factor -j | jq '(.float * 0.9) | if . < 1 then 1 else . end')"
local zoomReset = "hyprctl -q keyword cursor:zoom_factor 1"
hl.bind(mainMod .. " + mouse_down", hl.dsp.exec_cmd(zoomIn))
hl.bind(mainMod .. " + mouse_up", hl.dsp.exec_cmd(zoomOut))
hl.bind(mainMod .. " + equal", hl.dsp.exec_cmd(zoomIn), { repeating = true })
hl.bind(mainMod .. " + minus", hl.dsp.exec_cmd(zoomOut), { repeating = true })
hl.bind(mainMod .. " + KP_ADD", hl.dsp.exec_cmd(zoomIn), { repeating = true })
hl.bind(mainMod .. " + KP_SUBTRACT", hl.dsp.exec_cmd(zoomOut), { repeating = true })
hl.bind(mainMod .. " SHIFT + mouse_up", hl.dsp.exec_cmd(zoomReset))
hl.bind(mainMod .. " SHIFT + mouse_down", hl.dsp.exec_cmd(zoomReset))
hl.bind(mainMod .. " SHIFT + minus", hl.dsp.exec_cmd(zoomReset))
hl.bind(mainMod .. " SHIFT + KP_SUBTRACT", hl.dsp.exec_cmd(zoomReset))
hl.bind(mainMod .. " SHIFT + 0", hl.dsp.exec_cmd(zoomReset))
```
## Alt tab behaviour
To mimic DE's alt-tab behaviour. Here is an example that uses foot, fzf, grim and chafa to the screenshot in the terminal.
![alttab](https://github.com/user-attachments/assets/2a260809-b1b0-4f72-8644-46cc9d8b8971)
Dependencies :
- foot
- fzf
- grim
- chafa
- jq
1. add this to your config
```lua
hl.exec_once("foot --server -c $XDG_CONFIG_HOME/foot/foot.ini")
hl.bind("ALT + TAB", hl.dsp.exec_cmd("$HOME/.config/hypr/scripts/alttab/enable.sh 'down'"))
hl.bind("ALT SHIFT + TAB", hl.dsp.exec_cmd("$HOME/.config/hypr/scripts/alttab/enable.sh 'up'"))
hl.define_submap("alttab", function()
hl.bind("ALT + tab", hl.dsp.send_shortcut("", "tab", "class:alttab"))
hl.bind("ALT SHIFT + tab", hl.dsp.send_shortcut("shift", "tab", "class:alttab"))
hl.bind("ALT + ALT_L", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , return,class:alttab"), { release = true })
hl.bind("ALT SHIFT + ALT_L", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , return,class:alttab"), { release = true })
hl.bind("ALT + Return", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , return, class:alttab"))
hl.bind("ALT SHIFT + Return", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , return, class:alttab"))
hl.bind("ALT + escape", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , escape,class:alttab"))
hl.bind("ALT SHIFT + escape", hl.dsp.exec_cmd("$XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh ; hyprctl -q dispatch sendshortcut , escape,class:alttab"))
end)
hl.workspace_rule({ workspace = "special:alttab", gaps_out = 0, gaps_in = 0, border_size = 0 })
hl.window_rule({
match = { class = "alttab" },
no_anim = true,
stay_focused = true,
workspace = "special:alttab",
border_size = 0,
})
```
2. create file `touch $XDG_CONFIG_HOME/hypr/scripts/alttab/alttab.sh && chmod +x $XDG_CONFIG_HOME/hypr/scripts/alttab/alttab.sh` and add:
```bash {filename="alttab.sh"}
#!/usr/bin/env bash
hyprctl -q dispatch submap alttab
address=$(hyprctl -j clients | jq -r 'sort_by(.focusHistoryID) | .[] | select(.workspace.id >= 0) | "\(.stableId)\t\(.title)\t\(.address)"' |
fzf --color prompt:green,pointer:green,current-bg:-1,current-fg:green,gutter:-1,border:bright-black,current-hl:red,hl:red \
--cycle \
--sync \
--bind tab:down,shift-tab:up,start:"$1",double-click:ignore \
--wrap \
--delimiter=$'\t' \
--with-nth=2 \
--preview "$XDG_CONFIG_HOME/hypr/scripts/alttab/preview.sh {}" \
--preview-window=down:80% \
--layout=reverse |
awk -F"\t" '{print $3}')
if [ -n "$address" ] ; then
echo "$address" > $XDG_RUNTIME_DIR/hypr/alttab/address
fi
hyprctl -q dispatch submap reset
```
I chose to exclude windows that are in special workspaces but it can be modified by removing `select(.workspace.id >= 0)`
3. create file `touch $XDG_CONFIG_HOME/hypr/scripts/alttab/preview.sh && chmod +x $XDG_CONFIG_HOME/hypr/scripts/alttab/preview.sh` and add:
```bash {filename="preview.sh"}
#!/usr/bin/env bash
line="$1"
IFS=$'\t' read -r stableId _ <<< "$line"
dim=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES}
grim -t png -l 0 -T "$stableId" $XDG_RUNTIME_DIR/hypr/alttab/preview.png
chafa --animate false --dither=none -s "$dim" "$XDG_RUNTIME_DIR/hypr/alttab/preview.png"
```
4. create file `touch $XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh && chmod +x $XDG_CONFIG_HOME/hypr/scripts/alttab/disable.sh` and add:
```bash {filename="disable.sh"}
#!/usr/bin/env bash
hyprctl -q keyword animations:enabled true
hyprctl -q --batch "keyword unbind ALT, TAB ; keyword unbind ALT SHIFT, TAB ; keyword bind ALT, TAB, exec, $HOME/.config/hypr/scripts/alttab/enable.sh 'down' ; keyword bind ALT SHIFT, TAB, exec, $HOME/.config/hypr/scripts/alttab/enable.sh 'up'"
```
5. create file `touch $XDG_CONFIG_HOME/hypr/scripts/alttab/enable.sh && chmod +x $XDG_CONFIG_HOME/hypr/scripts/alttab/enable.sh` and add:
```bash {filename="enable.sh"}
#!/usr/bin/env bash
mkdir -p $XDG_RUNTIME_DIR/hypr/alttab
hyprctl -q --batch "keyword animations:enabled false; keyword unbind ALT, TAB ; keyword unbind ALT SHIFT, TAB"
footclient -a alttab $HOME/.config/hypr/scripts/alttab/alttab.sh $1
hyprctl --batch -q "dispatch focuswindow address:$(cat $XDG_RUNTIME_DIR/hypr/alttab/address) ; dispatch alterzorder top"
```
## Config versioning
Some updates add breaking changes, which can be anticipated by looking at the git
development branch.
Since Hyprland 0.53, each major version exports a version identifier. In Lua
configs, the `# hyprlang if` preprocessor directives don't exist — use standard
Lua conditionals with `hl.version()` instead:
```lua
local v = hl.version()
if v and v >= "0.53" then
-- config for 0.53+
else
-- config for older versions
end
```
The -git branch exports the version for the next major release.
All future releases will export all _past_ version identifiers as well, e.g.
0.54 will also identify as 0.53.
## Per-workspace layouts
Use workspace rules to set per-workspace layouts:
```lua
hl.workspace_rule({ workspace = "2", layout = "scrolling" })
```

View file

@ -3,6 +3,10 @@ weight: 7
title: Window Rules
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
> [!WARNING]
> Rules are evaluated top to bottom, so the order they're written in does matter!
> More info in [Notes](#notes)
@ -168,19 +172,19 @@ Dynamic effects are re-evaluated every time a property changes.
| no_blur | boolean | Disables blur for the window. |
| no_dim | boolean | Disables window dimming for the window. |
| no_focus | boolean | Disables focus to the window. |
| no_follow_mouse | boolean | Prevents the window from being focused when the mouse moves over it when `input:follow_mouse=1` is set. |
| no_follow_mouse | boolean | Prevents the window from being focused when the mouse moves over it when `input.follow_mouse=1` is set. |
| no_shadow | boolean | Disables shadows for the window. |
| no_shortcuts_inhibit | boolean | Disallows the app from inhibiting your shortcuts. |
| no_screen_share | boolean | Hides the window and its popups from screen sharing by drawing black rectangles in their place. |
| no_vrr | boolean | Disables VRR for the window. Only works when `misc:vrr` is set to `2` or `3`. |
| no_vrr | boolean | Disables VRR for the window. Only works when `misc.vrr` is set to `2` or `3`. |
| opaque | boolean | Forces the window to be opaque. |
| force_rgbx | boolean | Forces Hyprland to ignore the alpha channel entirely. |
| sync_fullscreen | boolean | Whether the fullscreen mode should always be the same as the one sent to the window. |
| immediate | boolean | Forces the window to allow tearing. |
| xray | boolean | Sets blur xray mode for the window. |
| render_unfocused | boolean | Forces the window to think it's being rendered when it's not visible. |
| scroll_mouse | number | Forces the window to override `input:scroll_factor`. |
| scroll_touchpad | number | Forces the window to override `input:touchpad:scroll_factor`. |
| scroll_mouse | number | Forces the window to override `input.scroll_factor`. |
| scroll_touchpad | number | Forces the window to override `input.touchpad.scroll_factor`. |
All dynamic effects can be set with `setprop`.
@ -188,14 +192,14 @@ All dynamic effects can be set with `setprop`.
The `group` effect takes a string with space-separated options:
- `"set"` \[`"always"`\] Open window as a group.
- `"new"` Shorthand for `"barred set"`.
- `"lock"` \[`"always"`\] Lock the group. Combine with `"set"` or `"new"`.
- `"barred"` Do not automatically group into the focused unlocked group.
- `"deny"` Do not allow the window to be toggled as or added to a group.
- `"invade"` Force open window in the locked group.
- `"override"` \[other options\] Override other `group` rules.
- `"unset"` Clear all `group` rules.
- `"set"` \[`"always"`\] - Open window as a group.
- `"new"` - Shorthand for `"barred set"`.
- `"lock"` \[`"always"`\] - Lock the group. Combine with `"set"` or `"new"`.
- `"barred"` - Do not automatically group into the focused unlocked group.
- `"deny"` - Do not allow the window to be toggled as or added to a group.
- `"invade"` - Force open window in the locked group.
- `"override"` \[other options\] - Override other `group` rules.
- `"unset"` - Clear all `group` rules.
> [!NOTE]
> `group` with no options is a shorthand for `group = "set"`.
@ -211,13 +215,12 @@ Check window tags with `hyprctl clients`.
Use the `tagwindow` dispatcher to add a static tag to a window:
```bash
hyprctl dispatch tagwindow +code # Add tag to current window.
hyprctl dispatch tagwindow -- -code # Remove tag from current window.
hyprctl dispatch tagwindow code # Toggle the tag of current window.
hyprctl dispatch 'hl.dsp.window.tag({ tag = "+code" })' # Add tag to current window.
hyprctl dispatch 'hl.dsp.window.tag({ tag = "-code" })' # Remove tag from current window.
hyprctl dispatch 'hl.dsp.window.tag({ tag = "code" })' # Toggle the tag of current window.
# Or target windows by RegEx:
hyprctl dispatch tagwindow +music deadbeef
hyprctl dispatch tagwindow +media title:Celluloid
# Or target windows:
hyprctl dispatch 'hl.dsp.window.tag({ tag = "+music", window = "class:Celluloid" })'
```
Use the `tag` effect to add a dynamic tag to a window:
@ -235,8 +238,8 @@ hl.window_rule({ match = { tag = "term" }, tag = "-code" }) -- Remove
Or with a keybind for convenience:
```lua
hl.bind("SUPER CTRL + 2", hl.dsp.exec_cmd("hyprctl dispatch tagwindow alpha_0.2"))
hl.bind("SUPER CTRL + 4", hl.dsp.exec_cmd("hyprctl dispatch tagwindow alpha_0.4"))
hl.bind("SUPER + CTRL + 2", function() hl.dispatch(hl.dsp.window.tag({ tag = "alpha_0.2" })))
hl.bind("SUPER + CTRL + 4", function() hl.dispatch(hl.dsp.window.tag({ tag = "alpha_0.4" })))
hl.window_rule({ match = { tag = "alpha_0.2" }, opacity = "0.2 override" })
hl.window_rule({ match = { tag = "alpha_0.4" }, opacity = "0.4 override" })
```
@ -299,7 +302,7 @@ Effects marked as _Dynamic_ are reevaluated whenever the matching property
of the window changes. For instance, if a rule changes the `border_color`
when a window is floating, the color reverts to default when it's tiled again.
Effects are processed top to bottom the _last_ match takes precedence:
Effects are processed top to bottom - the _last_ match takes precedence:
```lua
hl.window_rule({ match = { class = "kitty" }, opacity = "0.8 0.8" })
@ -307,7 +310,7 @@ hl.window_rule({ match = { float = true }, opacity = "0.5 0.5" })
```
Here, all non-fullscreen kitty windows have `opacity 0.8`, except when
floating those get `0.5`. All other floating windows get `0.5`.
floating - those get `0.5`. All other floating windows get `0.5`.
```lua
hl.window_rule({ match = { float = true }, opacity = "0.5 0.5" })
@ -355,18 +358,9 @@ myRule:set_enabled(true) -- re-enable
myRule:is_enabled() -- query status
```
Via `hyprctl keyword` (single quotes required in shell):
```sh
hyprctl keyword 'windowrule[my-rule]:enable false'
hyprctl keyword 'windowrule[my-rule]:match:class kitty'
```
---
## Layer Rules
Some things in Wayland are not windows, but layers app launchers, status
Some things in Wayland are not windows, but layers - app launchers, status
bars, wallpapers, etc. These have separate rules using `hl.layer_rule()`.
The syntax is the same as `hl.window_rule()`.

View file

@ -3,6 +3,10 @@ weight: 8
title: Workspace Rules
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
You can set workspace rules to achieve workspace-specific behaviors. For
instance, you can define a workspace where all windows are drawn without borders
or gaps.
@ -10,6 +14,18 @@ or gaps.
For layout-specific rules, see the specific layout page. For example:
[Master Layout->Workspace Rules](../Master-Layout#workspace-rules).
## Syntax
```lua
hl.workspace_rule(workspace, rule1, rule2, ...)
```
- WORKSPACE is a valid workspace identifier (see
[Dispatchers->Workspaces](../Dispatchers#workspaces)). This field is
mandatory. This _can be_ a workspace selector, but please note
workspace selectors can only match _existing_ workspaces.
- RULES is one (or more) rule(s) as described here in [rules](#rules).
### Workspace selectors
Workspaces that have already been created can be targeted by workspace
@ -35,27 +51,39 @@ Props:
fullscreen, `0`: fullscreen, `1`: maximized, `2`, fullscreen without
fullscreen state sent to the window.
### Syntax
## Rules
| Rule | Description | type |
| --- | --- | --- |
| monitor | Binds a workspace to a monitor. See [syntax](#syntax) and [Monitors](../Monitors). | string |
| default | Whether this workspace should be the default workspace for the given monitor | bool |
| gaps_in | Set the gaps between windows (equivalent to [General->gaps_in](../Variables#general)) | int |
| gaps_out | Set the gaps between windows and monitor edges (equivalent to [General->gaps_out](../Variables#general)) | int |
| border_size | Set the border size around windows (equivalent to [General->border_size](../Variables#general)) | int |
| no_border | Whether to disable borders | bool |
| no_shadow | Whether to disable shadows | bool |
| no_rounding | Whether to disable rounded windows | bool |
| decorate | Whether to draw window decorations or not | bool |
| persistent | Keep this workspace alive even if empty and inactive | bool |
| on_created_empty | A command to be executed once a workspace is created empty (i.e. not created by moving a window to it). See the [command syntax](../Dispatchers#executing-with-rules) | string |
| default_name | A default name for the workspace. | string |
| layout | The layout to use for this workspace. | string |
| animation | The animation style to use for this workspace. | string |
## Examples
```lua
hl.workspace_rule(workspace, rule1, rule2, ...)
hl.workspace_rule({ workspace = "3", no_rounding = true, decorate = false })
hl.workspace_rule({ workspace = "name:coding", no_rounding = true, decorate = false, gaps_in = 0, gaps_out = 0, no_border = true, monitor = "DP-1" })
hl.workspace_rule({ workspace = "8", border_size = 8 })
hl.workspace_rule({ workspace = "name:Hello", monitor = "DP-1", default = true })
hl.workspace_rule({ workspace = "name:gaming", monitor = "desc:Chimei Innolux Corporation 0x150C", default = true })
hl.workspace_rule({ workspace = "5", on_created_empty = "[float] firefox" })
hl.workspace_rule({ workspace = "special:scratchpad", on_created_empty = "foot" })
hl.workspace_rule({ workspace = "15", animation = "slidevert", default_name = "slider" })
```
- WORKSPACE is a valid workspace identifier (see
[Dispatchers->Workspaces](../Dispatchers#workspaces)). This field is
mandatory. This _can be_ a workspace selector, but please note
workspace selectors can only match _existing_ workspaces.
- RULES is one (or more) rule(s) as described here in [rules](#rules).
### Examples
```lua
hl.workspace_rule({ workspace = "name:myworkspace", gaps_in = 0, gaps_out = 0 })
hl.workspace_rule({ workspace = "3", no_rounding = true, border_size = 0 })
hl.workspace_rule({ workspace = "w[tg1-4]", no_shadow = true })
```
#### Smart gaps
### Smart gaps
To replicate "smart gaps" / "no gaps when only" from other WMs/Compositors, use this bad boy:
@ -81,34 +109,10 @@ hl.window_rule({ match = { float = false, workspace = "f[1]s[false]" }, border_s
hl.window_rule({ match = { float = false, workspace = "f[1]s[false]" }, rounding = 0 })
```
## Rules
### Per-workspace layouts
| Rule | Description | type |
| --- | --- | --- |
| monitor | Binds a workspace to a monitor. See [syntax](#syntax) and [Monitors](../Monitors). | string |
| default | Whether this workspace should be the default workspace for the given monitor | bool |
| gaps_in | Set the gaps between windows (equivalent to [General->gaps_in](../Variables#general)) | int |
| gaps_out | Set the gaps between windows and monitor edges (equivalent to [General->gaps_out](../Variables#general)) | int |
| border_size | Set the border size around windows (equivalent to [General->border_size](../Variables#general)) | int |
| no_border | Whether to disable borders | bool |
| no_shadow | Whether to disable shadows | bool |
| no_rounding | Whether to disable rounded windows | bool |
| decorate | Whether to draw window decorations or not | bool |
| persistent | Keep this workspace alive even if empty and inactive | bool |
| on_created_empty | A command to be executed once a workspace is created empty (i.e. not created by moving a window to it). See the [command syntax](../Dispatchers#executing-with-rules) | string |
| default_name | A default name for the workspace. | string |
| layout | The layout to use for this workspace. | string |
| animation | The animation style to use for this workspace. | string |
### Example Rules
Use workspace rules to set per-workspace layouts:
```lua
hl.workspace_rule({ workspace = "3", no_rounding = true, decorate = false })
hl.workspace_rule({ workspace = "name:coding", no_rounding = true, decorate = false, gaps_in = 0, gaps_out = 0, no_border = true, monitor = "DP-1" })
hl.workspace_rule({ workspace = "8", border_size = 8 })
hl.workspace_rule({ workspace = "name:Hello", monitor = "DP-1", default = true })
hl.workspace_rule({ workspace = "name:gaming", monitor = "desc:Chimei Innolux Corporation 0x150C", default = true })
hl.workspace_rule({ workspace = "5", on_created_empty = "[float] firefox" })
hl.workspace_rule({ workspace = "special:scratchpad", on_created_empty = "foot" })
hl.workspace_rule({ workspace = "15", animation = "slidevert", default_name = "slider" })
hl.workspace_rule({ workspace = "2", layout = "scrolling" })
```

View file

@ -3,6 +3,10 @@ weight: 60
title: XWayland
---
> [!NOTE]
> Looking for the old hyprlang syntax? Check the [0.54 wiki pages](https://wiki.hypr.land/0.54.0/).
> Since Hyprland 0.55, hyprlang is deprecated in favor of lua.
XWayland is the bridging mechanism between legacy Xorg programs and Wayland
compositors.
@ -18,18 +22,18 @@ which forces XWayland windows not to be scaled.
This will get rid of the pixelated look, but will not scale applications
properly. To do this, each toolkit has its own mechanism.
```ini
# change monitor to high resolution, the last argument is the scale factor
```lua
-- change monitor to high resolution, the last argument is the scale factor
hl.monitor({ output = "", mode = "highres", position = "auto", scale = "2" })
# unscale XWayland
-- unscale XWayland
hl.config({
xwayland {
force_zero_scaling = true
}
})
# toolkit-specific scale
-- toolkit-specific scale
hl.env("GDK_SCALE", "2")
hl.env("XCURSOR_SIZE", "32")
```

View file

@ -56,7 +56,7 @@ For more info, read the [option](https://search.nixos.org/options?channel=unstab
{{% details title="GNOME Keyring PAM setup" closed="true" %}}
When launching from a tty instead of a display manager, some session integrations that display managers normally handle may not be configured. One common example is [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring) if `pam_gnome_keyring.so` is not present in your PAM login configuration, the keyring will not auto-unlock, and applications may prompt you to unlock it manually.
When launching from a tty instead of a display manager, some session integrations that display managers normally handle may not be configured. One common example is [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring) - if `pam_gnome_keyring.so` is not present in your PAM login configuration, the keyring will not auto-unlock, and applications may prompt you to unlock it manually.
To set this up, add the `pam_gnome_keyring.so` lines to the PAM configuration file used by your login method (e.g. `/etc/pam.d/login` for `login(1)`). Consult your distribution's documentation for the correct file and syntax. For example, on Arch Linux:

View file

@ -26,5 +26,5 @@ Wayland **compositors** should not be confused with Xorg **window managers**.
## IMPORTANT
If you are having issues, please try [reading the FAQ](../FAQ) and configuring
sections chances are your issue is described somewhere there. If not, you can
sections - chances are your issue is described somewhere there. If not, you can
try [searching the issues](https://github.com/hyprwm/Hyprland/issues).