2023-07-31 22:04:53 -07:00
# hy3
2023-07-22 02:58:51 -07:00
2023-04-19 02:56:11 -07:00
i3 / sway like layout for [hyprland ](https://github.com/hyprwm/hyprland ).
2023-07-31 22:04:53 -07:00
[Installation ](#installation ), [Configuration ](#configuration )
2024-01-14 02:50:56 -08:00
*Check the [changelog ](./CHANGELOG.md ) for a list of new features and improvements*
2023-04-19 02:56:11 -07:00
### Features
- [x] i3 like tiling
2023-07-31 22:04:53 -07:00
- [x] Node based window manipulation (you can interact with multiple windows at once)
- [x] Greatly improved tabbed node groups over base hyprland
2023-08-01 01:00:56 -07:00
- [x] Optional autotiling
2023-07-31 22:04:53 -07:00
Additional features may be suggested in the repo issues or the [matrix room ](https://matrix.to/#/#hy3:outfoxxed.me ).
2023-04-19 02:56:11 -07:00
2023-07-22 02:58:51 -07:00
### Demo
< video width = "640" height = "360" controls = "controls" src = "https://user-images.githubusercontent.com/83010835/255322916-85ae8196-8b12-4e15-b060-9872db10839f.mp4" > < / video >
2023-07-31 22:04:53 -07:00
## Installation
2023-09-23 00:43:21 -07:00
> [!IMPORTANT]
> The master branch of hy3 follows the master branch of hyprland.
> Attempting to use a mismatched hyprland release will result in failure when building or loading hy3.
>
> To use hy3 against a release version of hyprland,
> check out the matching hy3 tag for the hyprland version.
> hy3 tags are formatted as `hl{version}` where `{version}` matches the release version of hyprland.
2024-03-04 08:00:27 +01:00
### hyprpm
Hyprland now has a dedicated plugin manager, which should be used when your package manager
isn't capable of locking hy3 builds to the correct hyprland version.
> [!IMPORTANT]
> Make sure hyprpm is activated by putting
>
> ```conf
> exec-once = hyprpm reload -n
> ```
>
> in your hyprland.conf. (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.)
To install hy3 via hyprpm run
```sh
hyprpm add https://github.com/outfoxxed/hy3
```
To update hy3 (and all other plugins), run
```sh
hyprpm update
```
(See [the wiki ](https://wiki.hyprland.org/Plugins/Using-Plugins/ ) for details.)
> [!WARNING]
> When you are running a tagged hyprland version hyprpm (0.34.0+) will build against hy3's
> corrosponding release. However if you are running an untagged build (aka `-git`) hyprpm
> will build against hy3's *latest* commit. This means **if you are running an out of date
> untagged build of hyprland, hyprpm may pick an incompatible revision of hy3**.
>
> To fix this problem you will either need to update hyprland or manually build the correct
> version of hy3.
2023-07-31 22:04:53 -07:00
### Nix
#### Hyprland home manager module
Assuming you use hyprland's home manager module, you can easily integrate hy3 by adding it to the plugins array.
```nix
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
2024-06-16 21:32:07 +03:00
hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1&ref={version}";
# where {version} is the hyprland release version
2024-01-03 05:25:59 +01:00
# or "github:hyprwm/Hyprland" to follow the development branch
2023-07-31 22:04:53 -07:00
hy3 = {
2024-01-03 05:25:59 +01:00
url = "github:outfoxxed/hy3?ref=hl{version}"; # where {version} is the hyprland release version
# or "github:outfoxxed/hy3" to follow the development branch.
# (you may encounter issues if you dont do the same for hyprland)
2023-07-31 22:04:53 -07:00
inputs.hyprland.follows = "hyprland";
};
};
outputs = { nixpkgs, home-manager, hyprland, hy3, ... }: {
homeConfigurations."user@hostname " = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
2023-04-19 02:56:11 -07:00
2023-07-31 22:04:53 -07:00
modules = [
hyprland.homeManagerModules.default
{
wayland.windowManager.hyprland = {
enable = true;
plugins = [ hy3.packages.x86_64-linux.hy3 ];
};
}
];
};
};
}
```
#### Manual (Nix)
hy3's binary is availible as `${hy3.packages.<system>.hy3}/lib/libhy3.so` , so you can also
directly use it in your hyprland config like so:
```nix
# ...
wayland.windowManager.hyprland = {
# ...
extraConfig = ''
plugin = ${hy3.packages.x86_64-linux.hy3}/lib/libhy3.so
'';
};
```
2024-01-01 20:57:46 -08:00
### hyprpm
Hyprland now has a dedicated plugin manager, which should be used when your package manager
isn't capable of locking hy3 builds to the correct hyprland version.
2024-01-01 21:31:07 -08:00
> [!IMPORTANT]
> Make sure hyprpm is activated by putting
>
> ```conf
> exec-once = hyprpm reload -n
> ```
>
2024-02-10 08:28:43 +00:00
> in your hyprland.conf. (See [the wiki](https://wiki.hyprland.org/Plugins/Using-Plugins/) for details.)
2024-01-01 21:31:07 -08:00
2024-01-01 20:57:46 -08:00
To install hy3 via hyprpm run
```sh
hyprpm add https://github.com/outfoxxed/hy3
```
To update hy3 (and all other plugins), run
```sh
hyprpm update
```
2024-05-19 23:39:08 +02:00
Sometimes the headers from hyprland are not updated, if this happens run (See [issue #109 ](https://github.com/outfoxxed/hy3/issues/109 ) for an example of where this happened)
2024-05-19 23:37:49 +02:00
2024-06-16 21:32:07 +03:00
```sh
2024-05-19 23:37:49 +02:00
hyprpm update -f
```
2024-01-01 20:57:46 -08:00
(See [the wiki ](https://wiki.hyprland.org/Plugins/Using-Plugins/ ) for details.)
> [!WARNING]
2024-01-01 21:02:10 -08:00
> When you are running a tagged hyprland version hyprpm (0.34.0+) will build against hy3's
2024-01-01 20:57:46 -08:00
> corrosponding release. However if you are running an untagged build (aka `-git`) hyprpm
> will build against hy3's *latest* commit. This means **if you are running an out of date
> untagged build of hyprland, hyprpm may pick an incompatible revision of hy3**.
>
> To fix this problem you will either need to update hyprland or manually build the correct
> version of hy3.
2024-01-03 05:25:59 +01:00
2023-07-31 22:04:53 -07:00
### Manual
Install hyprland, including its headers and pkg-config file, then run the following commands:
```sh
2024-01-03 05:25:59 +01:00
cmake -DCMAKE_BUILD_TYPE=Release -B build
2023-07-31 22:04:53 -07:00
cmake --build build
```
The plugin will be located at `build/libhy3.so` , and you can load it normally
(See [the hyprland wiki ](https://wiki.hyprland.org/Plugins/Using-Plugins/#installing--using-plugins ) for details.)
Note that the hyprland headers and pkg-config file **MUST be installed correctly, for the target version of hyprland** .
2023-04-19 02:56:11 -07:00
## Configuration
2023-09-23 00:43:21 -07:00
> [!IMPORTANT]
> The configuration listed below is for the current hy3 commit.
> If you are using a release version of hy3 then make sure you are
> reading the tagged revision of this readme.
2023-04-19 03:07:05 -07:00
Set your `general:layout` to `hy3` in hyprland.conf.
2023-04-19 02:56:11 -07:00
hy3 requires using a few custom dispatchers for normal operation.
In your hyprland config replace the following dispatchers:
- `movefocus` -> `hy3:movefocus`
- `movewindow` -> `hy3:movewindow`
You can use `hy3:makegroup` to create a new split.
2023-07-31 22:04:53 -07:00
The [dispatcher list ](#dispatcher-list ) and [config fields ](#config-fields ) sections have all the
configuration options, and some explanation as to what they do.
2023-08-01 01:45:19 -07:00
[The hyprland config in my dots ](https://git.outfoxxed.me/outfoxxed/nixnew/src/branch/master/modules/hyprland/hyprland.conf ) can also be used as a reference.
2023-07-31 22:04:53 -07:00
2023-05-26 20:13:32 -07:00
### Config fields
```conf
plugin {
hy3 {
# disable gaps when only one window is onscreen
2024-03-22 00:37:13 -07:00
# 0 - always show gaps
# 1 - hide gaps with a single window onscreen
# 2 - 1 but also show the window border
no_gaps_when_only = < int > # default: 0
2023-06-02 01:32:24 -07:00
2023-07-31 21:28:21 -07:00
# policy controlling what happens when a node is removed from a group,
# leaving only a group
# 0 = remove the nested group
# 1 = keep the nested group
2023-08-01 01:45:19 -07:00
# 2 = keep the nested group only if its parent is a tab group
node_collapse_policy = < int > # default: 2
2023-07-31 21:28:21 -07:00
2024-02-18 09:08:37 +00:00
# policy controlling what windows will be focused using `hy3:movefocused`
# 0 = focus strictly by layout, don't attempt to skip windows that are obscured by another one
# 1 = do not focus windows which are entirely obscured by a floating window
# 2 = when `hy3:movefocus` layer is `samelayer` then use focus policy 0 (focus strictly by layout)
# when `hy3:movefocus` layer is `all` then use focus policy 1 (don't focus obscured windows)
focus_obscured_windows_policy = < int > # default: 2
# which layers should be considered when changing focus with `hy3:movefocus` ?
# samelayer = only focus windows on same layer as the source window (floating or tiled)
# all = choose the closest window irrespective of the layout
# tiled = only choose tiled windows, not especially useful but permitted by parser
# floating = only choose floating windows, not especially useful but permitted by parser
default_movefocus_layer = < string > # default: `samelayer`
2023-06-04 22:05:21 -07:00
# offset from group split direction when only one window is in a group
2023-08-01 01:45:19 -07:00
group_inset = < int > # default: 10
2023-06-04 22:05:21 -07:00
2023-12-02 12:52:00 +01:00
# scale factor of windows on the special workspace
special_scale_factor = < float > # default: 0.8
2023-10-23 02:47:55 -07:00
# if a tab group will automatically be created for the first window spawned in a workspace
tab_first_window = < bool >
2023-06-04 17:37:27 -07:00
# tab group settings
tabs {
# height of the tab bar
2023-08-01 01:45:19 -07:00
height = < int > # default: 15
2023-06-02 01:32:24 -07:00
2023-06-04 17:37:27 -07:00
# padding between the tab bar and its focused node
2023-08-01 01:45:19 -07:00
padding = < int > # default: 5
2023-06-02 01:32:24 -07:00
2023-06-04 17:37:27 -07:00
# the tab bar should animate in/out from the top instead of below the window
2023-08-01 01:45:19 -07:00
from_top = < bool > # default: false
2023-06-03 02:00:50 -07:00
2023-06-04 17:37:27 -07:00
# rounding of tab bar corners
2023-08-01 01:45:19 -07:00
rounding = < int > # default: 3
# render the window title on the bar
render_text = < bool > # default: true
2023-06-02 01:32:24 -07:00
2024-01-03 05:25:59 +01:00
# center the window title
text_center = < bool > # default: false
2023-06-04 17:37:27 -07:00
# font to render the window title with
2023-08-01 01:45:19 -07:00
text_font = < string > # default: Sans
2023-06-02 01:32:24 -07:00
2023-06-04 17:37:27 -07:00
# height of the window title
2023-08-01 01:45:19 -07:00
text_height = < int > # default: 8
2023-06-04 17:37:27 -07:00
# left padding of the window title
2023-08-01 01:45:19 -07:00
text_padding = < int > # default: 3
2023-06-04 17:37:27 -07:00
# active tab bar segment color
2023-08-01 01:45:19 -07:00
col.active = < color > # default: 0xff32b4ff
2023-06-04 17:37:27 -07:00
# urgent tab bar segment color
2023-08-01 01:45:19 -07:00
col.urgent = < color > # default: 0xffff4f4f
2023-06-04 17:37:27 -07:00
# inactive tab bar segment color
2023-08-01 01:45:19 -07:00
col.inactive = < color > # default: 0x80808080
2023-06-04 17:37:27 -07:00
# active tab bar text color
2023-08-01 01:45:19 -07:00
col.text.active = < color > # default: 0xff000000
2023-06-04 17:37:27 -07:00
# urgent tab bar text color
2023-08-01 01:45:19 -07:00
col.text.urgent = < color > # default: 0xff000000
2023-06-04 17:37:27 -07:00
# inactive tab bar text color
2023-08-01 01:45:19 -07:00
col.text.inactive = < color > # default: 0xff000000
2023-06-04 17:37:27 -07:00
}
2023-08-01 01:00:56 -07:00
# autotiling settings
autotile {
# enable autotile
2023-08-01 01:45:19 -07:00
enable = < bool > # default: false
2023-08-01 01:00:56 -07:00
# make autotile-created groups ephemeral
2023-08-01 01:45:19 -07:00
ephemeral_groups = < bool > # default: true
2023-08-01 01:00:56 -07:00
# if a window would be squished smaller than this width, a vertical split will be created
# -1 = never automatically split vertically
# 0 = always automatically split vertically
# < number > = pixel height to split at
2023-08-01 01:45:19 -07:00
trigger_width = < int > # default: 0
2023-08-01 01:00:56 -07:00
# if a window would be squished smaller than this height, a horizontal split will be created
# -1 = never automatically split horizontally
# 0 = always automatically split horizontally
# < number > = pixel height to split at
2023-08-01 01:45:19 -07:00
trigger_height = < int > # default: 0
2024-02-10 08:28:43 +00:00
2023-09-13 11:47:08 +01:00
# a space or comma separated list of workspace ids where autotile should be enabled
2023-09-14 11:29:10 +01:00
# it's possible to create an exception rule by prefixing the definition with "not:"
# workspaces = 1,2 # autotiling will only be enabled on workspaces 1 and 2
# workspaces = not:1,2 # autotiling will be enabled on all workspaces except 1 and 2
2023-09-13 11:47:08 +01:00
workspaces = < string > # default: all
2023-08-01 01:00:56 -07:00
}
2023-05-26 20:13:32 -07:00
}
}
```
2023-04-19 02:56:11 -07:00
### Dispatcher list
2023-07-19 03:53:23 -07:00
- `hy3:makegroup, <h | v | opposite | tab>, [ephemeral | force_ephemeral]` - make a vertical / horizontal split or tab group
- `ephemeral` - the group will be removed once it contains only one node. does not affect existing groups.
- `force_ephemeral` - same as ephemeral, but converts existing single windows groups.
2023-08-19 10:44:52 -04:00
- `hy3:changegroup, <h | v | tab | untab | toggletab | opposite>` - change the group the node belongs to, to a different layout
2023-08-16 08:39:58 +01:00
- `untab` will untab the group if it was previously tabbed
2023-08-19 10:44:52 -04:00
- `toggletab` will untab if group is tabbed, and tab if group is untabbed
2023-08-17 07:46:14 +01:00
- `opposite` will toggle between horizontal and vertical layouts if the group is not tabbed.
2023-08-18 08:07:38 +01:00
- `hy3:setephemeral, <true | false>` - change the ephemerality of the group the node belongs to
2024-05-05 17:47:55 -07:00
- `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible], [warp | nowarp]` - move the focus left, up, down, or right
2023-06-11 23:00:24 -07:00
- `visible` - only move between visible nodes, not hidden tabs
2024-05-05 17:47:55 -07:00
- `warp` - warp the mouse to the selected window, even if `general:no_cursor_warps` is true.
- `nowarp` - does not warp the mouse to the selected window, even if `general:no_cursor_warps` is false.
2024-05-05 18:02:31 -07:00
- `hy3:warpcursor` - warp the cursor to the center of the focused node
2023-08-20 03:13:08 -07:00
- `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once], [visible]` - move a window left, up, down, or right
2023-05-10 00:42:53 -07:00
- `once` - only move directly to the neighboring group, without moving into any of its subgroups
2023-08-20 03:13:08 -07:00
- `visible` - only move between visible nodes, not hidden tabs
2024-01-14 02:31:06 -08:00
- `hy3:movetoworkspace, <workspace>, [follow]` - move the active node to the given workspace
- `follow` - change focus to the given workspace when moving the selected node
2023-06-25 15:29:02 -07:00
- `hy3:killactive` - close all windows in the focused node
2023-06-11 23:00:24 -07:00
- `hy3:changefocus, <top | bottom | raise | lower | tab | tabnode>`
2023-06-11 22:19:43 -07:00
- `top` - focus all nodes in the workspace
- `bottom` - focus the single root selection window
- `raise` - raise focus one level
- `lower` - lower focus one level
- `tab` - raise focus to the nearest tab
- `tabnode` - raise focus to the nearest node under the tab
2023-06-28 21:38:51 -07:00
- `hy3:focustab <mouse | [l | r | left | right | index, <index>], [prioritize_hovered | require_hovered], [wrap]>`
2023-06-15 00:27:02 -07:00
- `mouse` - focus the tab under the mouse, works well with a non consuming bind, e.g.
```conf
# binds hy3:focustab to lmb and still allows windows to receive clicks
bindn = , mouse:272, hy3:focustab, mouse
```
2023-06-28 21:38:51 -07:00
- `l | r | left | right` - direction to change focus towards
- `index, <index>` - select the `index` th tab
2023-06-15 00:27:02 -07:00
- `prioritize_hovered` - prioritize the tab group under the mouse when multiple are stacked. use the lowest group if none is under the mouse.
- `require_hovered` - affect the tab group under the mouse. do nothing if none are hovered.
- `wrap` - wrap to the opposite size of the tab bar if moving off the end
2023-04-19 02:56:11 -07:00
- `hy3:debugnodes` - print the node tree into the hyprland log
2024-01-31 07:53:58 +00:00
- `hy3:resizenode, <vector>` - like Hyprland `resizeactive` , but applied to the whole focused group instead of just a window
2023-08-09 02:21:18 -07:00
- :warning: **ALPHA QUALITY** `hy3:setswallow, <true | false | toggle>` - set the containing node's window swallow state
- :warning: **ALPHA QUALITY** `hy3:expand, <expand | shrink | base>` - expand the current node to cover other nodes
- `expand` - expand by one node
- `shrink` - shrink by one node
- `base` - undo all expansions
2024-01-03 05:25:59 +01:00
2024-04-01 22:32:50 +02:00