From 24054058ad67e004812c28dafb818f8512a6cada Mon Sep 17 00:00:00 2001 From: jess Date: Sat, 25 Apr 2026 13:49:11 -0700 Subject: [PATCH] Let's try something else (wayland) --- src/bin/layers_shell.rs | 79 +++++++++++++++++++++++++++++++++++--- src/wayland_shell.rs | 84 +++++++++++++++++++++++++++++++++++------ 2 files changed, 145 insertions(+), 18 deletions(-) diff --git a/src/bin/layers_shell.rs b/src/bin/layers_shell.rs index d8325f4..cd7632a 100644 --- a/src/bin/layers_shell.rs +++ b/src/bin/layers_shell.rs @@ -27,18 +27,33 @@ fn main() { tracing::info!( plugin_root = ?plugin_root, + log_dir = ?layers::paths::log_dir(), "layers shell: starting native event loop", ); + log_session_env(); + #[cfg(target_os = "linux")] { - if std::env::var_os("WAYLAND_DISPLAY").is_some() { - if layers::wayland_shell::try_run() { - return; + let wayland_display = std::env::var("WAYLAND_DISPLAY").ok(); + match wayland_display.as_deref() { + Some(name) => { + tracing::info!( + wayland_display = name, + "shell route: WAYLAND_DISPLAY set; trying sctk + wlr-layer-shell" + ); + if layers::wayland_shell::try_run() { + tracing::info!("shell route: wayland branch handled the session"); + return; + } + tracing::warn!( + "shell route: wayland branch declined (no layer-shell?); forcing WINIT_UNIX_BACKEND=x11 and falling through to winit" + ); + std::env::set_var("WINIT_UNIX_BACKEND", "x11"); + } + None => { + tracing::info!("shell route: no WAYLAND_DISPLAY; using winit directly (X11 path)"); } - // Wayland up but no layer-shell (mutter/GNOME): use XWayland via winit's - // X11 backend so the existing X11 always-on-top path applies. - std::env::set_var("WINIT_UNIX_BACKEND", "x11"); } } @@ -48,6 +63,52 @@ fn main() { } } +fn log_window_kind(handle: &raw_window_handle::RawWindowHandle) -> &'static str { + use raw_window_handle::RawWindowHandle::*; + match handle { + Wayland(_) => "wayland", + Xlib(_) => "xlib", + Xcb(_) => "xcb", + Win32(_) => "win32", + AppKit(_) => "appkit", + UiKit(_) => "uikit", + _ => "other", + } +} + +fn log_display_kind(handle: &raw_window_handle::RawDisplayHandle) -> &'static str { + use raw_window_handle::RawDisplayHandle::*; + match handle { + Wayland(_) => "wayland", + Xlib(_) => "xlib", + Xcb(_) => "xcb", + Windows(_) => "windows", + AppKit(_) => "appkit", + UiKit(_) => "uikit", + _ => "other", + } +} + +fn log_session_env() { + let keys = [ + "WAYLAND_DISPLAY", + "DISPLAY", + "XDG_SESSION_TYPE", + "XDG_CURRENT_DESKTOP", + "XDG_SESSION_DESKTOP", + "DESKTOP_SESSION", + "WINIT_UNIX_BACKEND", + "GDK_BACKEND", + "QT_QPA_PLATFORM", + ]; + for k in keys { + match std::env::var(k) { + Ok(v) => tracing::info!(env = k, value = %v, "session env"), + Err(_) => tracing::info!(env = k, value = "", "session env"), + } + } +} + fn run() { let event_loop = EventLoop::new().expect("winit: create event loop"); event_loop.set_control_flow(ControlFlow::Wait); @@ -122,6 +183,12 @@ impl ApplicationHandler for ShellApp { .expect("winit: display handle") .as_raw(); + tracing::info!( + window_handle = log_window_kind(&raw_window), + display_handle = log_display_kind(&raw_display), + "winit window up" + ); + tracing::info!( "creating viewport handle: {}x{} @ {}", inner.width, diff --git a/src/wayland_shell.rs b/src/wayland_shell.rs index 82515aa..4b31691 100644 --- a/src/wayland_shell.rs +++ b/src/wayland_shell.rs @@ -24,7 +24,7 @@ use smithay_client_toolkit::{ }; use std::ptr::NonNull; use wayland_client::{ - globals::registry_queue_init, + globals::{registry_queue_init, GlobalList}, protocol::{wl_keyboard, wl_output, wl_pointer, wl_seat, wl_surface}, Connection, Proxy, QueueHandle, }; @@ -38,16 +38,23 @@ const ANCHOR_MARGIN: i32 = 24; /// available or the compositor doesn't advertise wlr-layer-shell, so the caller can /// fall through to the winit/X11 path. pub fn try_run() -> bool { + tracing::info!("wayland: try_run entered"); let conn = match Connection::connect_to_env() { - Ok(c) => c, - Err(_) => { - tracing::info!("wayland: no WAYLAND_DISPLAY, falling through to X11"); + Ok(c) => { + tracing::info!("wayland: Connection::connect_to_env OK"); + c + } + Err(e) => { + tracing::info!("wayland: connect_to_env failed ({e}); falling through to X11"); return false; } }; let (globals, mut event_queue) = match registry_queue_init::(&conn) { - Ok(pair) => pair, + Ok(pair) => { + tracing::info!("wayland: registry_queue_init OK"); + pair + } Err(e) => { tracing::warn!("wayland: registry init failed ({e}); falling through to X11"); return false; @@ -55,19 +62,27 @@ pub fn try_run() -> bool { }; let qh = event_queue.handle(); + log_globals(&globals); + let compositor = match CompositorState::bind(&globals, &qh) { - Ok(c) => c, - Err(_) => { - tracing::warn!("wayland: wl_compositor missing; falling through to X11"); + Ok(c) => { + tracing::info!("wayland: bound wl_compositor"); + c + } + Err(e) => { + tracing::warn!("wayland: wl_compositor missing ({e}); falling through to X11"); return false; } }; let layer_shell = match LayerShell::bind(&globals, &qh) { - Ok(l) => l, - Err(_) => { + Ok(l) => { + tracing::info!("wayland: bound zwlr_layer_shell_v1"); + l + } + Err(e) => { tracing::warn!( - "wayland: zwlr_layer_shell_v1 not advertised (likely GNOME/mutter); falling through to X11" + "wayland: zwlr_layer_shell_v1 not advertised ({e}; likely GNOME/mutter); falling through to X11" ); return false; } @@ -86,6 +101,13 @@ pub fn try_run() -> bool { layer.set_margin(ANCHOR_MARGIN, ANCHOR_MARGIN, 0, 0); layer.set_keyboard_interactivity(KeyboardInteractivity::OnDemand); layer.commit(); + tracing::info!( + anchor = "TOP|RIGHT", + size = ?(DEFAULT_LOGICAL_SIZE.0, DEFAULT_LOGICAL_SIZE.1), + margin_top = ANCHOR_MARGIN, + margin_right = ANCHOR_MARGIN, + "wayland: layer surface committed (waiting for first configure)" + ); let raw_display = RawDisplayHandle::Wayland(WaylandDisplayHandle::new( match NonNull::new(conn.backend().display_ptr() as *mut _) { @@ -264,12 +286,21 @@ impl LayerShellHandler for State { qh: &QueueHandle, _layer: &LayerSurface, configure: LayerSurfaceConfigure, - _serial: u32, + serial: u32, ) { let (w, h) = configure.new_size; let new_w = if w == 0 { self.width } else { w }; let new_h = if h == 0 { self.height } else { h }; let resized = new_w != self.width || new_h != self.height; + tracing::info!( + serial, + requested_w = w, + requested_h = h, + applied_w = new_w, + applied_h = new_h, + first = self.first_configure, + "wayland: configure" + ); self.width = new_w; self.height = new_h; @@ -282,6 +313,7 @@ impl LayerShellHandler for State { if self.first_configure { self.first_configure = false; + tracing::info!("wayland: first configure → kicking initial render"); self.render(qh); } } @@ -462,6 +494,34 @@ impl PointerHandler for State { } } +fn log_globals(globals: &GlobalList) { + let list = globals.contents().clone_list(); + tracing::info!("wayland: registry advertises {} globals", list.len()); + let mut seen_layer_shell = false; + let mut seen_compositor = false; + let mut seen_seat = false; + for g in &list { + tracing::debug!( + interface = %g.interface, + name = g.name, + version = g.version, + "wayland global" + ); + match g.interface.as_str() { + "zwlr_layer_shell_v1" => seen_layer_shell = true, + "wl_compositor" => seen_compositor = true, + "wl_seat" => seen_seat = true, + _ => {} + } + } + tracing::info!( + layer_shell = seen_layer_shell, + compositor = seen_compositor, + seat = seen_seat, + "wayland: protocol summary" + ); +} + fn map_button(button: u32) -> Option { match button { 0x110 => Some(0), // BTN_LEFT