diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs index b1d024a8..693b0ea8 100644 --- a/src/native/linux_wayland.rs +++ b/src/native/linux_wayland.rs @@ -15,7 +15,7 @@ use libxkbcommon::*; use crate::{ event::{EventHandler, KeyCode, KeyMods, MouseButton}, - native::{egl, NativeDisplayData}, + native::{egl, NativeDisplayData, Request}, }; use std::collections::HashSet; @@ -397,7 +397,8 @@ unsafe extern "C" fn registry_add_object( 1, ) as _; } - "zxdg_decoration_manager" => { + "zxdg_decoration_manager" | + "zxdg_decoration_manager_v1" => { display.decoration_manager = display.client.wl_registry_bind( registry, name, @@ -510,6 +511,22 @@ unsafe extern "C" fn xdg_toplevel_handle_configure( } } +unsafe extern "C" fn xdg_wm_base_handle_ping( + data: *mut std::ffi::c_void, + toplevel: *mut extensions::xdg_shell::xdg_wm_base, + serial: u32, +) -> () { + assert!(!data.is_null()); + let payload: &mut WaylandPayload = &mut *(data as *mut _); + + wl_request!( + payload.client, + toplevel, + extensions::xdg_shell::xdg_wm_base::pong, + serial + ); +} + struct WaylandClipboard; impl crate::native::Clipboard for WaylandClipboard { fn get(&mut self) -> Option { @@ -593,6 +610,16 @@ where //assert!(display.keymap.is_null() == false); //assert!(display.xkb_state.is_null() == false); + let xdg_wm_base_listener = extensions::xdg_shell::xdg_wm_base_listener { + ping: Some(xdg_wm_base_handle_ping), + }; + + (display.client.wl_proxy_add_listener)( + display.xdg_wm_base as _, + &xdg_wm_base_listener as *const _ as _, + &mut display as *mut _ as _, + ); + if display.decoration_manager.is_null() && conf.platform.wayland_use_fallback_decorations { eprintln!("Decoration manager not found, will draw fallback decorations"); } @@ -651,6 +678,15 @@ where &mut display as *mut _ as _, ); + let title = std::ffi::CString::new(conf.window_title.as_str()).unwrap(); + + wl_request!( + display.client, + display.xdg_toplevel, + extensions::xdg_shell::xdg_toplevel::set_title, + title.as_ptr() + ); + wl_request!(display.client, display.surface, WL_SURFACE_COMMIT); (display.client.wl_display_roundtrip)(wdisplay); @@ -674,6 +710,17 @@ where panic!("eglMakeCurrent failed"); } + // For some reason, setting fullscreen before egl_window is created leads + // to segfault because wl_egl_window_create returns NULL. + if conf.fullscreen { + wl_request!( + display.client, + display.xdg_toplevel, + extensions::xdg_shell::xdg_toplevel::set_fullscreen, + std::ptr::null_mut::<*mut wl_output>() + ) + } + crate::native::gl::load_gl_funcs(|proc| { let name = std::ffi::CString::new(proc).unwrap(); libegl.eglGetProcAddress.expect("non-null function pointer")(name.as_ptr() as _) @@ -723,6 +770,28 @@ where event_handler.key_down_event(keycode.clone(), keymods, true); } + while let Ok(request) = rx.try_recv() { + match request { + Request::SetFullscreen(full) => if full { + wl_request!( + display.client, + display.xdg_toplevel, + extensions::xdg_shell::xdg_toplevel::set_fullscreen, + std::ptr::null_mut::<*mut wl_output>() + ); + } else { + wl_request!( + display.client, + display.xdg_toplevel, + extensions::xdg_shell::xdg_toplevel::unset_fullscreen + ); + }, + + // TODO: implement the other events + _ => (), + } + } + for event in EVENTS.drain(..) { match event { WaylandEvent::KeyboardKey(keycode, state) => { diff --git a/src/native/linux_wayland/extensions/xdg_shell.rs b/src/native/linux_wayland/extensions/xdg_shell.rs index 3a8c4517..e261ce54 100644 --- a/src/native/linux_wayland/extensions/xdg_shell.rs +++ b/src/native/linux_wayland/extensions/xdg_shell.rs @@ -49,7 +49,7 @@ wayland_interface!( (set_min_size, "ii", ()), (set_maximized, "", ()), (unset_maximized, "", ()), - (set_fullscreen, "", (wl_output_interface)), + (set_fullscreen, "?o", (wl_output_interface)), (unset_fullscreen, "", ()), (set_minimized, "", ()) ],