Repository navigation
feat(linux): add native Wayland support and generalize compositor gestures - #367
Conversation
…tures - Add Avalonia.Wayland, Avalonia.Skia, and Avalonia.HarfBuzz packages - Initialize native Wayland platform backend in Program.cs when WAYLAND_DISPLAY is set - Re-create RadialWindow if closed to avoid xdg_surface destruction crash on Wayland - Generalize WaylandGestures check in LinuxPlatformServices.cs beyond KDE Plasma - Improve initial drag ring visibility in RadialViewModel.cs - Update Linux installer script for native Wayland deployment
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks for working on this, @mahaveergurjar! Native Wayland and gestures beyond KDE are both things Linux users want, and getting the donut running under Hyprland without XWayland is a nice result. As it stands, though, the PR changes behaviour on every platform and for every Wayland user, so it needs another pass:
ResetForDragmust keep the donut hidden until files arrive. Setting DonutOpacity = 1 and HitBackground = "Transparent" reverts “Don’t show the donut for a drag gesture without files” on Windows, macOS and X11 too. A Ctrl + drag of text now shows an empty donut. A fully transparent window also doesn’t receive drags on Windows, which is why the near-transparent #01000000 is there (see the comment on _hitBackground). The existing test RenderTests.Donut_toolbar_waits_for_files_in_drag_mode fails with this change (expected opacity 0, got 1). If native Wayland needs something different here, please make it conditional on that backend.- Make the native Wayland backend opt-in. With this change every Linux session that has WAYLAND_DISPLAY (GNOME and KDE included) switches from XWayland to Avalonia’s Wayland backend, which has only been tried on Hyprland and bypasses the X11 paths (gesture toolbar, selected-file queries). When the KDE gesture went in (#142), we agreed to keep such changes opt-in. Please put it behind an environment variable, document it in installer/linux/INSTALL.txt and the Linux section of CONTRIBUTING.md, and reference the Wayland packages only for Linux runtimes so the Windows and macOS packages don’t grow.
- Re-creating the donut window: please do it only on the native Wayland backend, decide it from the window’s Closed event rather than IsLoaded (a hidden window may report not loaded elsewhere, which would rebuild it on every gesture), and don’t swallow exceptions with an empty catch.
- Other compositors: without the KDE check the gesture turns on everywhere, but only KWin has a script that moves the donut to the cursor. Please keep KDE as is and add other compositors explicitly, with the Hyprland windowrulev2 you mention shipped or documented in INSTALL.txt. On GNOME the donut would open in the wrong place.
- Please drop the
install.shchanges.
- pkill -f "Filee" kills every process whose command line contains “Filee”. That includes the shell running Filee-2.0.0-linux-x64/install.sh itself, an editor with the repository open, or a tail -f on Filee’s log.
- rm -rf "$install_dir" doesn’t check the .filee-package marker.
- The checks that kept us from overwriting someone else’s ~/.local/bin/filee and desktop file are gone, and the “(Native Wayland)” comment would show up for X11 users too.
- Upgrading in place is being handled in #360 (install.sh --upgrade with a marker check and rollback).
- Tests for whatever stays, please. The fork’s CI run is waiting for approval, and we’ll start it on the next push.
Happy to help work out the opt-in shape if you’d like to discuss it first!
…, and preserve existing installer/drag behaviors
|
Hi @KnifeLemon, Thank you for the thorough and thoughtful review! I've addressed all the requested changes in
|
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks @mahaveergurjar, and sorry for the wait on CI. 6b82767 covers most of the list: ResetForDrag is back as on main, the native backend is opt-in with FILEE_USE_WAYLAND=1 and documented in INSTALL.txt and CONTRIBUTING.md, the donut window is rebuilt from its Closed event only in that mode and without an empty catch, KDE keeps its check with Hyprland added explicitly, and install.sh is untouched.
What's left:
- The build fails on Windows and macOS. The CI run for 7619b7e stops at
Program.cs(282,21): error CS1061: 'AppBuilder' does not contain a definition for 'UseWayland'in the Windows build job and in the macOS (Intel) job.$([MSBuild]::IsOSPlatform('Linux'))is the OS that runs the build, not the one the app is built for, andUseWayland()is compiled on every platform. Please decide it from the runtime identifier and compile the call only there, for example:
<PropertyGroup>
<FileeNativeWayland Condition="$(RuntimeIdentifier.StartsWith('linux')) Or ('$(RuntimeIdentifier)' == '' And $([MSBuild]::IsOSPlatform('Linux')))">true</FileeNativeWayland>
<DefineConstants Condition="'$(FileeNativeWayland)' == 'true'">$(DefineConstants);FILEE_NATIVE_WAYLAND</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(FileeNativeWayland)' == 'true'">
<PackageReference Include="Avalonia.Wayland" />
</ItemGroup>with #if FILEE_NATIVE_WAYLAND around the UseWayland() branch. Avalonia.Skia and Avalonia.HarfBuzz already come with Avalonia.Desktop, so only Avalonia.Wayland is needed and the two extra PackageVersion lines can go.
2. Notices. Avalonia.Wayland brings in NWayland (MIT). Please add it to THIRD-PARTY-NOTICES.md.
3. Tests (point 6 from last time) are still missing. The decisions are easy to make testable: move "use the native backend?" (OS, FILEE_USE_WAYLAND, WAYLAND_DISPLAY) and the compositor check (XDG_CURRENT_DESKTOP, HYPRLAND_INSTANCE_SIGNATURE) into small static functions that take the values, and test them: KDE, Hyprland through either variable, GNOME off, the switch unset, 0 and 1, no WAYLAND_DISPLAY. Please use the same function in Program.cs and RadialController: right now RadialController doesn't check WAYLAND_DISPLAY, so the two can disagree.
4. Hyprland placement. The rules in INSTALL.txt make the donut float without borders, but nothing moves it to the cursor, which is what the KWin script does on KDE. Does it open under the cursor for you? If not, please add a rule that moves it there (Hyprland has move cursor …) to the docs.
5. Please update the PR description. It still mentions the install.sh change, the RadialViewModel change and switching on WAYLAND_DISPLAY alone.
Thanks!
…date notices and placement docs
|
Hi @KnifeLemon, Thank you for the detailed feedback! All 5 items have been addressed in
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The native-backend and compositor checks move to WaylandSupport, which has no OS attribute: RadialController calls it on every platform, and the Linux-only LinuxPlatformServices raised CA1416 there. Program.cs and RadialController use the same NativeWaylandRequested property. - THIRD-PARTY-NOTICES: NWayland's project is kekekeks/NWayland (the package's repository). - Test names in the repo's sentence style. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The experimental Wayland notice still said KDE Plasma only. After KnifeLemon#367 it names both and says how the donut gets to the cursor on each: a KWin script on KDE Plasma, a window rule in hyprland.conf on Hyprland. The GNOME notice now follows UsesGnomePointerBridge, so with FILEE_WAYLAND_GESTURES=0 on GNOME the plain Wayland notice shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Description
This PR introduces opt-in native Wayland support for Linux desktops (Hyprland, Sway, KDE Wayland, etc.) and extends Wayland gesture support to Hyprland.
Key Changes
Avalonia.Waylandconditional on Linux builds (FileeNativeWayland), keeping Windows and macOS binaries small.builder.UseWayland()behind#if FILEE_NATIVE_WAYLANDto ensure clean cross-compilation on Windows and macOS.FILEE_USE_WAYLAND=1environment variable (along with checkingWAYLAND_DISPLAY), defaulting to existing XWayland behavior otherwise.RadialController.cs, when opted into native Wayland, listens to the window'sClosedevent to re-instantiate it on the next gesture. (In Wayland, hiding anxdg_topleveldestroys the native Wayland surface).LinuxPlatformServices.cs, generalized compositor gesture support to recognize both KDE Plasma and Hyprland (viaXDG_CURRENT_DESKTOPorHYPRLAND_INSTANCE_SIGNATURE).THIRD-PARTY-NOTICES.md.installer/linux/INSTALL.txtandCONTRIBUTING.mdforFILEE_USE_WAYLAND=1and Hyprland cursor placement (windowrulev2 = move cursor -50% -50%).tests/Filee.Platform.Tests/WaylandDecisionTests.cscovering the compositor detection and opt-in decision functions across all combinations.Maintainer changes
maininto the branch.LinuxPlatformServices(Linux-only, so calling it fromRadialControllerraised CA1416 on Windows and macOS) to a platform-neutralWaylandSupportclass inFilee.Platform.Linux:IsNativeWaylandRequested(isLinux, FILEE_USE_WAYLAND, WAYLAND_DISPLAY),IsSupportedCompositor(XDG_CURRENT_DESKTOP, HYPRLAND_INSTANCE_SIGNATURE), and aNativeWaylandRequestedproperty thatProgram.csandRadialControllerboth use. The tests callWaylandSupport.THIRD-PARTY-NOTICES.md: NWayland's project link is https://github.com/kekekeks/NWayland (the package's own repository).