Releases: nferhat/fht-compositor
25.10.1
25.10
v25.10
Finally, after quite a while (7 months!), we are finally pushing out a release! Bringing a wave of improvements and polishes to the compositor experience, while also bringing new features to integrate fht-compositor into your environment!
Note
Due to the very aggresive internet filters of Algeria Telecom (the ONLY ISP in Algeria), I do not have access to the Matrix, and it's been like that for the past 6 months. After hoping for them to fix it, there's nothing that has been done. Due to this, I decided to maintain a community over Discord, which (so far) isn't blocked, https://discord.gg/H58C8AdU7x.
Note
For packagers:
- The minimum supported Rust version is now
1.85.1 libdisplay-info>=0.3.0is required to build the compositor.
No more UWSM
Yeah, I've decided to get rid of it. While it does handle a lot of edge cases for more complicated sessions (like KDE's), I couldn't justify keeping it, especially with the many hacks I employed to get it to work properly with the custom portal. Now fht-compositor ships with its own sets of session scripts, located under res/systemd
Documentation
There's nothing more frustrating that trying to understand and use a program without having a reliable source of truth documenting how the program works and behaves. With such an extensive configuration, and the sheer complexity of Wayland compositors in general, the lack of documentation in fht-compositor was really painful, especially to newcomers.
No more! I've finally put myself to the task and wrote down a pretty good documentation, formatted and published using Vitepress under Github Pages.
Check it out at https://nferhat.github.io/fht-compositor!
IPC
The defining feature of this release is the introduction of a Inter-process communication system. This allows you, either through the CLI (using fht-compositor ipc) or through a direct connection using a UNIX domain socket, to query data from the compositor, and ask the compositor to-do things for you... like focusing a window, running a command, etc.
It opens the door for scripting, creating custom Wofi menus, writing custom shells, etc... The sky's the limit.
IPC subscribing
With the generous help of @Byson94, the compositor also has a subscribing mode, where it will send events to you. This is even more useful for writing shells, by getting quick partial upgrades to replicate as soon as possible. You can integrate this system into Quickshell, Flutter, EWW, or just native Rust code! Check out crate documentation for fht-compositor-ipc for more information!
Better tile swapping
There was an initial implementation of an interactive tile swap that relied on the mouse, it went like the following
- You grab a tile using the designated mouse bind (generally
Super+Left) - You start moving your move, the workspace will on purpose not update the layout to make you see where the tile you will swap with will be placed
- You drop the tile on another one, swapping them around
This approach was fairly simple and very limiting:
- You can only swap two tiles, IE just a swap in of indices, which may not fit all cases
- The swap was limited to a single workspace, on a single output.
Hence, with the initial help of @nyx (the account is now gone), a better implementation was programmed and merge in #42, which many improvements:
moving-windows.mp4
Notably:
- You can slide windows seamlessly around outputs
- You have much more control in where you will insert the window, since the new implementation allows you insert before/after any window, altering the layout properties accordingly (like the number of master clients). This implementation works seamlessly with all the layouts provided in
fht-compositor, and any future ones will also strive to have this smooth integration
ontop Window rule
A pretty straightfoward window rule to understand. Paired with the new match criteria is-floating, this allows you to make certain (if not all) floating windows render above the tiled windows, simulating the behavior of most other Wayland compositor, which separate both tiled and floating windows into different layers.
You this can be especially useful for firefox's Picture-in-Picture video player

Variable-Refresh-Rate support
VRR is an essential part to having a smooth gaming experience. You may know it better as NVidia GSync or AMD FreeSync on your monitor's spec sheet. In short, allows the monitor to change its refresh rate live, allowing for smooth continuous frame output.
Check out output.<name>.vrr on thw wiki for more information!
Improvements
- 27cf992 Add custom mode support in udev backend (generated by CVT calculation)
- 3a93e52..144ea9a Support
wlr-output-management-v1 - 2440ba7 Add
general.focus-follows-mouseoption - 823e849 Allow users to define environment variables inside their configurations
- f455bdb Support
xdg-dialog-v1protocol - 639f236 Break up
input.mouseinto different categories - 61afbcb RUSTSEC-2022-0040 vulnerability fix. Thanks @id3v1669!
- @LeVraiArdox added support for scrolling mousebindings in #80, thank you!
- Applying the home-manager configuration now automatically reloads the config in #67
Bug fixes
- Actually create
wp_pointer_global_v1, animations.disablewill now correctly disable all space related animations (workspace switching, fullscreening, etc...)- e5d1f64 Account for
open-on-workspacein window rules - 11798d1 Fix udev backend only rendering the active output
- aa70329 Make layer-shell use the active output instead of the first one
- This behaviour works better with programs like launchers, that (often) don't specify which output to open on
- 9225768 Focus the correct window when using
focus-next/previous-output - 8b9c9aa Clamp swapped and resized tiles to output geometry
- 2440ba7 Don't panic winit backend when
buffer_age==None - 0069552 Don't exit fullscreen state when setting active tile
- f1ec368 Fix
center-floating-windowaction - d3fd941 Show config UI on currently active output instead of the first one it opened on
- 61f5f65 Fix XDG toplevel popup positioning
- 00a620e Clamp argument in
focus-workspace - 9f70f06 Make the home-manager module cleanly print the config error, thanks @isabelroses
- Updated smithay several times, Smithay/smithay@3219a0f...9ccbd35
Full Changelog: 25.03.1...25.10
25.03.1
This is a quick hotfix update for 25.03
- Fixed declaring UWSM startup script without
--uwsmcommand line argument - Make
GIT_HASHavailable when building the compositor using the nix flake - Properly format the version string in
fht-compositor -V - Fix
Cargo.lockfile still having the compositor version as0.1.1
25.03
Finally, a new release. It's been, a while... Well mostly due to entering college I do not have much free time and when I do work on the compositor, I just work on some small features, until, well, yeah, you get a release that changes more-or-less everything 😅
Regardless, fht-compositor is a dynamic tiling Wayland compositor that also looks nice!
Such a big version jump mandates a new preview video!
fht-compositor-preview.mp4
Versioning scheme change
The previous release was 0.1.1, and this is 25.03, what!? Well, the compositor switched from sem/zero-ver to CalVer since:
- It's very difficult to quantify changes with semver, especially since when working on a compositor, some major refactors and changes might not affect the end user, just some backend/logic work.
- I am very much not consistent with releases, making using semver really cumbersome.
However, this change will help keep (hopefully) a more consistent releasing cycle, with a new release every maybe 1-3 months, with releases marked with YY.MM.minor for patches and fixes. New releases will drop whenever there are enough features to make up one.
Migration to TOML configuration
Initially, fht-compositor was configured using RON. While the language integrates very nicely with Rust, I found that writing configuration is pretty cumbersome with it, and some quirks of it make it pretty annoying to work with.
This is why I decided to switch the configuration to TOML, while also making heavy use of tagged union structs to make writing configuration easy. Some parts like window rules became extremely easier to write in the new configuration format, which is a win for me.
The new configuration system also introduces live-configuration reloading with a new configuration message UI:
configuration-ui.mp4
Nix, nix, nix everywhere!
This repository is now a Nix flake! Allowing you to install, configure (via home-manager), and run fht-compositor in Nix(OS) environment easily. Wiki for it coming soon! In the mean time, check out my dotfiles to see how the home-manager is.
Better session support
fht-compositor now integrates nicely in a desktop session with Universal Wayland Session Manager. Use the provided fht-compositor-uwsm.desktop session file to start it. If you are from a TTY, you can use
uwsm start -- fht-compositor --uwsmTo start a session. This is much better UWSM will automatically bind Systemd targets (graphical-session(-pre).target, wayland-session.target, etc.) to make stuff like autostart work seamlessly. It is now recommended to use autostart with systemd units instead of using the autostart field in the configuration.
Floating window support
Since the last refactor in workspace-logic-v2 branch, a lot of essential stuff like floating windows was removed. With yet another refactor later (introduction of the Space and Monitors), floating window are now back, and better than ever!
I implemented many heuristics to:
- Detect when a window should be floating, this should cover about 90% of the cases like popups, prompts, etc.
- Center a child window in its parent. For example, going to OBS' settings opens a child window that will automatically centered and placed above the OBS window.
If these do not over your case, you can still make extensive window rules to float specific windows by filtering with workspace, output, class, title, etc. Nothing is impossible!
Implementing floating windows also needs care and attention. The compositor should make sure that the stacking order is kept coherent between parent/children windows, avoid placing/moving windows out of the monitor's bounds, and implement window movement using keybindings with move/resize-floating-window.
Output configuration
Finally, you can configure your outputs with the compositor, a feature that was very missing in the previous releases.
# Internal laptop display
[outputs."eDP-1"]
disable = false # Keep it on, since its the only one available.
mode = "1920x1080@60.005"
scale = 2
# position = [0, 0]Nothing fancy, but was very much needed
Window/Layer-shell rules
Window rules
Window rules have been massively reworked to be dynamic (IE. they update continuously and can match live window state, like being focused) and much easier to write/manage (with the introduction of the TOML config rewrite)
# Window rule to always center-float games.
# My gaming workspace is the 6th one (index 5)
[[rules]]
centered = true
floating = true
match-app-id = [
"Celeste.bin.x86_64",
"steam_app_*",
"osu!.exe",
"Etterna",
"Quaver",
"Steam",
"love",
"org.prismlauncher.PrismLauncher"
]
on-workspace = 5
# Floating programs that behave better when they are
# Mostly gnome applications and transient windows.
[[rules]]
centered = true
floating = true
match-app-id = [
"^(org.gnome.*)$", # gnome programs
"file_progress", "confirm", "dialog", "download", "pinentry", "splash"
]
match-title = [
".*KeePassXC.*",
".*QEMU.*",
"Virtual Machine Manager",
"Bluetooth Devicecs"
]
# Dyanmic window rules
# For example make unfocused windows less opaque
[[rules]]
is-focused = false
opacity = 0.95Layer-shell rules
In the same vein as window rules, you can enable optional effects onto layer shells
# Enable blur, rounded corners and shadow for wofi
# You can of course tweak individual settings
[[layer-rules]]
corner-radius = 25
match-namespace = ["wofi"]
shadow.disable = false
blur.disable = falseDecorations and effects
One of the biggest and most noticeable improvements of the compositor are the visual. In order to make my vision of the compositor
possible, I've leveled up the graphics in the compositor by implementing many niceties.
Animations
More animations have been implemented, and a lot of them have been seriously polished out. The highlight are of course the window resize animations.
resize-animations.mp4
The window resize animations were particularly hard to implement, until I found a solution (from Niri): Draw the window in a temporary texture and apply a custom shader on it. This allows for seamless rounded corners and smooth scaling/cropping, neat!
There are also many other cases to handle, like fullscreening a window should make other windows fade out gracefully, and unfullscreening should do the same.
Moreover, animation logic in the compositor have now been reworked for them to be cancellable, IE. you can stop them and revert them before they finish. This is most noticeable with workspace switch animations, you can now switch back and forth between different workspaces without having to wait for the current switch to end.
animations.mp4
Shadows
Drop shadows are quite a necessity when you support floating windows. Shadows are tweakable and can complement the look of your environment very well!
| No shadow | Basic black drop shadow | Colored via window rules | Even layer-shells |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Blurring
"What is a good Wayland compositor without that heckin' blur!?"... More seriously, I always loved the look and aspect of blur. The actual implementation in the compositor is the infamous dual-kawase blur, giving you a result very close to a gaussian but with much
better performance.
| Blur disabled | radius=10, passes=2 |
radius=4, passes=4 |
|---|---|---|
![]() |
![]() |
![]() |
The blur settings are tweakable, you can have more passes, different blur radius, or even add noise to the final blur, giving a glassy look that is very similar to what Windows 11 has.
Better XDG screencast portal
You can now screencast individual windows and workspaces!
screencast.mp4
Moreover, the screencast portal now supports modifier-aware screencast buffers, allowing the screencast client to negociate the best DMA-buf format to get the best performance. The previous implementation only supported modifier-less. Programs like gpu-screen-recorder will now work properly in fht-compositor.
Other changes to the portal are better handling of passed-in parameters from clie...
v0.1.1
fht-compositor is a Wayland compositor that aims to have simple window management inspired by X11 window managers, mainly DWM and AwesomeWM.
Not a lot of groundbreaking stuff, but still some improvements over the previous release.
fht-share-picker moved out
Due to dependency conflicts (between egui and iced dependencies), fht-share-picker moved out to a different repository, and with it got a rewrite! I personally really like it, since it describes what output you are going to use better.
xdg-activation support
I actually forgot to implement this protocol, and left a TODO message in the implementation. Well, now its working! Example here is with pcmanfm focusing its child window.
xdg-activation-preview.mp4
Interactive window resizing
For quite some time, we supported dragging a tile out of its usual area in order to swap it with another one, in this release, I am really happy to announce that we now have the resizing of tiles! This was quite a tricky to implement, as we are in a tiled environment, meaning that every other window that is managed by the workspace layout needs to adapt.
Another challenge is to actually make resizing any tile, in any direction, be sensible and logical for the user. A tile can only grow its own stack (in our case, we have the master and slave stack(s)). This is possibly by tweaking both the master width factor (commonly known as mwfact) and the cfact (a proportion of how much the tile should take space relative to its siblings)
On the actual implementation, I wrote custom code that adapts the mouse delta position to make this happen, but it was 100% worth it! Take a look at the result:
interactive-resize.mp4
Other fixes and improvements
- New
insert_window_strategyoption, to decide where should we insert a window inside a workspace 5a462e3 - New
focused_window_opacityandnormal_window_opacityoptions. 2d386b9 - Various fixes to focusing, on cases where a layer-shell/window dies 0c27ad7, 26c638d
- Fix parent workspace detection db206cf
- Re-implement fullscreening 651d27a
- Re-implement some xdg-shell requests for maximizing/fullscreening ac6279b
- Egui can now get the
GL_MAX_TEXTURE_SIZEvalue from the renderer b151c01 - Remove egui's ability to get keyboard input, as this could lock up input 186456e
0.1.0
The first official release of fht-compositor, finally!
fht-compositor is a Wayland compositor built using the rust language, with a window management system inspired by DWM and AwesomeWM; in other words, we have static workspaces managed in a single set. Each output has its own workspace set. Each workspace tiles dynamically its windows based on a layout, and some parameters like the size percentage of the master width area, and the number of master clients
Even though this is the first release, we got quite a good part of the basics down
- Can be spawned nested into another compositor (using an X11 window), or from a TTY
- Core protocols supported + Additional wp/wlr ones:
-wlr_screencopyfor legacy screen recording/screen shotting clients
-xdg_decorationto force clients to use SSD/CSD
-wlr_layer_shellfor your beautiful panels and overlays
- Very preliminarywp_fractional_scalesupport
-wp_security_context+wlr_data_control - In addition to these protocols, we have some nice-to-have features
- Output recording support via the XDG screen cast portal (version 5 is supported, restore tokens soon)
- Customizable window borders, with rounded corner support, and gradient borders!
- Window rules to organize your workspace(s)
- Other debugging features: debug overlay, damage drawing, etc.
With this said, I'd like to thank the following projects for code and helping me figure out how to handle Wayland stuff properly:
- pop-os/cosmic-comp: Mainly for udev backend and some rendering logic
- YaLTeR/niri: PipeWire code for screencast portal + some rendering logic
- pinnacle-comp/pinnacle:
wlr_screencopystuff (the good way)











