From 65ed87d1296ca203067b47e6441f88fd361a610e Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Thu, 21 Sep 2023 01:54:15 +0800 Subject: [PATCH 1/4] linux/wayland: listen to ping events in xdg_wm_base KDE Kwin uses the ping-pong mechanism to tell whether a program is not responding. --- src/native/linux_wayland.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs index b1d024a8..16ed61d1 100644 --- a/src/native/linux_wayland.rs +++ b/src/native/linux_wayland.rs @@ -510,6 +510,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 +609,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"); } From 789d8d8b22efec816ee62f7f7fdefd5236fc4191 Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Thu, 21 Sep 2023 01:55:13 +0800 Subject: [PATCH 2/4] linux/wayland: fix the name of xdg-decoration manager With this change, it uses the native decoration provided by the compositor itself --- src/native/linux_wayland.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs index 16ed61d1..3f76fd9a 100644 --- a/src/native/linux_wayland.rs +++ b/src/native/linux_wayland.rs @@ -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, From 76f1ce3a12d97ad30d02e381e05079c50d0708db Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Thu, 21 Sep 2023 03:07:16 +0800 Subject: [PATCH 3/4] linux/wayland: set title for xdg_toplevel --- src/native/linux_wayland.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs index 3f76fd9a..c0e0f0cd 100644 --- a/src/native/linux_wayland.rs +++ b/src/native/linux_wayland.rs @@ -678,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); From 9e989de88d44a69893857053aecac6a2240be409 Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Thu, 21 Sep 2023 03:16:35 +0800 Subject: [PATCH 4/4] linux/wayland: implement fullscreen requests --- src/native/linux_wayland.rs | 35 ++++++++++++++++++- .../linux_wayland/extensions/xdg_shell.rs | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/native/linux_wayland.rs b/src/native/linux_wayland.rs index c0e0f0cd..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; @@ -710,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 _) @@ -759,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, "", ()) ],