From 8acc05d97085ee54ebc6efb5bc7440a5a7b1cabd Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Apr 2026 13:38:57 +0100 Subject: [PATCH] fix a lot of mistakes and reorganize a few things --- content/Configuring/Binds.md | 157 +++++-- content/Configuring/Dwindle-Layout.md | 4 + content/Configuring/Environment-variables.md | 2 +- .../Configuring/Expanding-functionality.md | 4 +- content/Configuring/Gestures.md | 22 +- content/Configuring/Master-Layout.md | 10 +- content/Configuring/Monitors.md | 50 +- content/Configuring/Monocle-Layout.md | 6 +- content/Configuring/Multi-GPU.md | 4 + content/Configuring/Performance.md | 6 +- content/Configuring/Permissions.md | 6 +- content/Configuring/Scrolling-Layout.md | 14 +- content/Configuring/Tearing.md | 4 + content/Configuring/Uncommon-tips-&-tricks.md | 431 ------------------ content/Configuring/Window-Rules.md | 58 ++- content/Configuring/Workspace-Rules.md | 92 ++-- content/Configuring/XWayland.md | 12 +- content/Useful Utilities/Systemd-start.md | 2 +- content/_index.md | 2 +- 19 files changed, 298 insertions(+), 588 deletions(-) delete mode 100644 content/Configuring/Uncommon-tips-&-tricks.md diff --git a/content/Configuring/Binds.md b/content/Configuring/Binds.md index 35d08049..da2f4890 100644 --- a/content/Configuring/Binds.md +++ b/content/Configuring/Binds.md @@ -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.
`2` -> Resize and ignore `keepaspectratio` window rule/prop.
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`. diff --git a/content/Configuring/Dwindle-Layout.md b/content/Configuring/Dwindle-Layout.md index 8af8b105..c05b3d48 100644 --- a/content/Configuring/Dwindle-Layout.md +++ b/content/Configuring/Dwindle-Layout.md @@ -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. diff --git a/content/Configuring/Environment-variables.md b/content/Configuring/Environment-variables.md index fc878eed..11403020 100644 --- a/content/Configuring/Environment-variables.md +++ b/content/Configuring/Environment-variables.md @@ -41,7 +41,7 @@ hl.env("GTK_THEME", "Nord") ## Aquamarine Environment Variables - `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. diff --git a/content/Configuring/Expanding-functionality.md b/content/Configuring/Expanding-functionality.md index e107a429..026d0163 100644 --- a/content/Configuring/Expanding-functionality.md +++ b/content/Configuring/Expanding-functionality.md @@ -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) ``` diff --git a/content/Configuring/Gestures.md b/content/Configuring/Gestures.md index 3e9b75f3..b9ac9232 100644 --- a/content/Configuring/Gestures.md +++ b/content/Configuring/Gestures.md @@ -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: diff --git a/content/Configuring/Master-Layout.md b/content/Configuring/Master-Layout.md index 7846cc56..ece33b95 100644 --- a/content/Configuring/Master-Layout.md +++ b/content/Configuring/Master-Layout.md @@ -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 diff --git a/content/Configuring/Monitors.md b/content/Configuring/Monitors.md index b5297755..0c78b04a 100644 --- a/content/Configuring/Monitors.md +++ b/content/Configuring/Monitors.md @@ -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 (0–7) | | 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: diff --git a/content/Configuring/Monocle-Layout.md b/content/Configuring/Monocle-Layout.md index 7aeaa260..917320be 100644 --- a/content/Configuring/Monocle-Layout.md +++ b/content/Configuring/Monocle-Layout.md @@ -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 | | --- | --- | --- | diff --git a/content/Configuring/Multi-GPU.md b/content/Configuring/Multi-GPU.md index ca2aa758..24a4e42e 100644 --- a/content/Configuring/Multi-GPU.md +++ b/content/Configuring/Multi-GPU.md @@ -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 diff --git a/content/Configuring/Performance.md b/content/Configuring/Performance.md index 29b527c6..3ad95f2b 100644 --- a/content/Configuring/Performance.md +++ b/content/Configuring/Performance.md @@ -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) diff --git a/content/Configuring/Permissions.md b/content/Configuring/Permissions.md index 7406b977..fc3cba6f 100644 --- a/content/Configuring/Permissions.md +++ b/content/Configuring/Permissions.md @@ -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 diff --git a/content/Configuring/Scrolling-Layout.md b/content/Configuring/Scrolling-Layout.md index e17f80e4..6cd77e3a 100644 --- a/content/Configuring/Scrolling-Layout.md +++ b/content/Configuring/Scrolling-Layout.md @@ -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 diff --git a/content/Configuring/Tearing.md b/content/Configuring/Tearing.md index 10e006d8..ef584a72 100644 --- a/content/Configuring/Tearing.md +++ b/content/Configuring/Tearing.md @@ -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 diff --git a/content/Configuring/Uncommon-tips-&-tricks.md b/content/Configuring/Uncommon-tips-&-tricks.md deleted file mode 100644 index 69a7a362..00000000 --- a/content/Configuring/Uncommon-tips-&-tricks.md +++ /dev/null @@ -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("")) -``` - -## 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("")) -``` - -## 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" }) -``` diff --git a/content/Configuring/Window-Rules.md b/content/Configuring/Window-Rules.md index 0d341dfe..eb7bae55 100644 --- a/content/Configuring/Window-Rules.md +++ b/content/Configuring/Window-Rules.md @@ -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()`. diff --git a/content/Configuring/Workspace-Rules.md b/content/Configuring/Workspace-Rules.md index d414f390..b5852ccd 100644 --- a/content/Configuring/Workspace-Rules.md +++ b/content/Configuring/Workspace-Rules.md @@ -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" }) ``` diff --git a/content/Configuring/XWayland.md b/content/Configuring/XWayland.md index 3c1da6bd..8a234539 100644 --- a/content/Configuring/XWayland.md +++ b/content/Configuring/XWayland.md @@ -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") ``` diff --git a/content/Useful Utilities/Systemd-start.md b/content/Useful Utilities/Systemd-start.md index e890b027..b8c05d0b 100644 --- a/content/Useful Utilities/Systemd-start.md +++ b/content/Useful Utilities/Systemd-start.md @@ -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: diff --git a/content/_index.md b/content/_index.md index 43fbbcda..9527bacc 100644 --- a/content/_index.md +++ b/content/_index.md @@ -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).