rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.86k stars 909 forks source link

"The wayland library could not be loaded" on NixOs with wayland & hyprland #3244

Closed VirgileHenry closed 11 months ago

VirgileHenry commented 11 months ago

I'm trying to run winit on NixOs, under wayland and I hit this error :

thread 'main' panicked at src/main.rs:9:39:
called `Result::unwrap()` on an `Err` value: Os(OsError { line: 81, file: "/home/eclipse/.cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.29.4/src/platform_impl/linux/wayland/event_loop/mod.rs", error: WaylandError(Connection(NoWaylandLib)) })
stack backtrace:
   0: rust_begin_unwind
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/std/src/panicking.rs:597:5
   1: core::panicking::panic_fmt
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/result.rs:1652:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/result.rs:1077:23
   4: morpheus::main
             at ./src/main.rs:9:22
   5: core::ops::function::FnOnce::call_once
             at /rustc/79e9716c980570bfd1f666e3b16ac583f0168962/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

(This is with the rust backtrace set to 1, I can run it with full if required.) I'm running this minimal example :

fn main() {
    use winit::{
        event::{Event, WindowEvent},
        window::WindowBuilder,
    };

    let event_loop = winit::event_loop::EventLoop::new().unwrap();
    let _window = WindowBuilder::new().build(&event_loop).unwrap();

    let _result = event_loop.run(move |event, elwt| {
        match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                ..
            } => {
                println!("The close button was pressed; stopping");
                elwt.exit();
            },
            _ => ()
        }
    });
}

I've also tried creating the event loop with:

EventLoopBuilder::new().with_wayland().build()

Which have the same effects.

This is all run into an nix shell where I imported the wayland libs:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = with pkgs; [
    wayland
    wayland.dev
  ];
  RUST_BACKTRACE=1;
}

Maybe I'm missing something ? Any help would be helpful.

kchibisov commented 11 months ago

Please, read the documentation on how to use your system. Winit uses dlopen.

VirgileHenry commented 11 months ago

Thanks for the quick reply. I'm trying my best, and I've also tried to use the following flake :

{
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:nixos/nixpkgs?ref=release-21.11";
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in with pkgs; rec {
        devShell = mkShell rec {
          buildInputs = [
            libxkbcommon
            libGL
            # WINIT_UNIX_BACKEND=wayland
            wayland
          ];
          LD_LIBRARY_PATH = "${lib.makeLibraryPath buildInputs}";
          RUST_BACKTRACE="full";
        };
      });
}

Which effectively sets the path for the wayland lib, but with this there is no window at all (the program runs and that's it)

kchibisov commented 11 months ago

(the program runs and that's it)

You must draw on Wayland to have your window shown.

djmaze commented 1 month ago

For people still searching for a solution, I found one which works for me here: https://eu90h.com/wgpu-winit-and-nixos.html