Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Wayland] usage with WLR layer shell #2142

Closed
Anakael opened this issue Jan 9, 2022 · 3 comments
Closed

[Wayland] usage with WLR layer shell #2142

Anakael opened this issue Jan 9, 2022 · 3 comments
Labels
DS - wayland F - wontfix This will not be worked on

Comments

@Anakael
Copy link

Anakael commented Jan 9, 2022

Winit version: 0.26.1

I want to use surface, created by winit to create layer shell surface by sctk.
But following code produce sigsegv:

let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
let surface = window.wayland_surface().unwrap() as *mut WlSurface;
let surface = unsafe { surface.as_ref() }.unwrap();
let layer_surface = layer_shell.get_layer_surface(
    &surface,
    Some(output),
    zwlr_layer_shell_v1::Layer::Top,
    "example".to_owned(),
);

/// Configure layer surface ...

let next_render_event = Rc::new(Cell::new(None::<RenderEvent>));
let next_render_event_handle = Rc::clone(&next_render_event);
layer_surface.quick_assign(move |layer_surface, event, _| {
match (event, next_render_event_handle.get()) {
        (zwlr_layer_surface_v1::Event::Closed, _) => {
             next_render_event_handle.set(Some(RenderEvent::Closed));
          }
          (
              zwlr_layer_surface_v1::Event::Configure {
                  serial,
                  width,
                  height,
              },
              next,
          ) if next != Some(RenderEvent::Closed) => {
              layer_surface.ack_configure(serial);
              next_render_event_handle.set(Some(RenderEvent::Configure { width, height }));
          }
          (_, _) => {}
      }
 });

surface.commit(); // sigsegv here

event_loop.run(move |event, _, control_flow| {
     *control_flow = ControlFlow::Wait;
      match event {
          Event::WindowEvent {
              event: WindowEvent::CloseRequested,
              window_id,
          } if window_id == window.id() => *control_flow = ControlFlow::Exit,
          _ => (),
      }
});

Also, if omit layer shell here at all and call commit on surface noting changes.

I think it somehow related with Display, because next code also produce sigsegv:

let winit_display = window.wayland_display().unwrap() as *const Display;
let winit_display = unsafe { winit_display.as_ref() }.unwrap();
let id = winit_display.id(); // Id = 0
let is_alive = winit_display.is_alive(); // false
let error = winit_display.protocol_error(); // sigsegv
let fd = winit_display.get_connection_fd(); // sigsegv

So, what am I doing wrong and how I can window Display and surface?

@Anakael
Copy link
Author

Anakael commented Jan 10, 2022

Also, I've noticed that there is no created window in sway tree (for the same example without layer surface), but toplevel is created (can be found in output with WAYLAND_DEBUG=1).

@twitchyliquid64
Copy link

twitchyliquid64 commented Jan 10, 2022

Funnily enough I'm trying to get this working too!

I don't precisely know your problem, but I'm not sure you're getting the display/surface objects correctly. This works for me:

    let display = unsafe {
        wayland_client::Display::from_external_display(win.wayland_display().unwrap() as *mut _)
    };
    let surface: WlSurface = unsafe {
        wayland_client::Proxy::<WlSurface>::from_c_ptr(win.wayland_surface().unwrap() as *mut wl_proxy).into()
    };

I'm stuck on something else (Im trying to use glutin but the issue is that buffers are setup before the window/surface is provided back to me, which is a protocol error when trying to set the surface as a layer_surface), but let me know how you go!

@kchibisov
Copy link
Member

kchibisov commented Jan 10, 2022

You can't use the surface created by winit for layer-shell since it has role assigned to it (it's using xdg-shell). Using winit here isn't an option and using layer surface inside winit also isn't really an option, since layer-shell isn't how default desktop applications should be used (the surface gets destroyed from time to time, meaning you should recreate your entire window and all gl stuff for a new one).

If you want to use layer-shell, I'd suggest to use smithay/client-toolkit instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DS - wayland F - wontfix This will not be worked on
Development

No branches or pull requests

4 participants