diff --git a/src/lib.rs b/src/lib.rs index e7c9daa..f802215 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ pub mod export; pub mod filter; pub mod geometry; pub mod history; +pub mod platform; pub mod selection; pub mod settings; pub mod spline; diff --git a/src/main.rs b/src/main.rs index cd19fe3..802dc8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,9 @@ use winit::{ event::{ ElementState, Event, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent, }, - event_loop::{ControlFlow, EventLoop}, + event_loop::{ControlFlow, EventLoopBuilder}, keyboard::{Key, ModifiersState, NamedKey}, + platform::{wayland::EventLoopBuilderExtWayland, x11::EventLoopBuilderExtX11}, window::{Window, WindowBuilder}, }; @@ -20,6 +21,7 @@ use ink_notes::canvas::CanvasState; use ink_notes::document::{Notebook, PageBackground}; use ink_notes::export::{self, export_notebook_to_pdf, ExportStrategy}; use ink_notes::geometry::{self, RecognizedShape}; +use ink_notes::platform::{self, DisplayBackend}; use ink_notes::selection::{ render_selection_overlay, DragMode, SelectionHandleHit, SelectionState, }; @@ -137,7 +139,20 @@ fn commit_stroke_to_notebook( } fn main() -> Result<(), Box> { - let event_loop = EventLoop::new()?; + // Anzeigesystem wählen: Unter WSL (WSLg) bricht Wayland ab, X11 (Xwayland) läuft stabil + let mut event_loop_builder = EventLoopBuilder::new(); + match platform::display_backend_from_env() { + DisplayBackend::X11 => { + eprintln!("[Anzeige] Verwende X11 (unter WSL Standard; übersteuerbar mit INK_NOTES_DISPLAY=wayland)"); + event_loop_builder.with_x11(); + } + DisplayBackend::Wayland => { + eprintln!("[Anzeige] Verwende Wayland (INK_NOTES_DISPLAY=wayland)"); + event_loop_builder.with_wayland(); + } + DisplayBackend::Automatic => {} + } + let event_loop = event_loop_builder.build()?; let window = Arc::new( WindowBuilder::new() .with_title("ink-notes (Latenzoptimiertes Linux-Inking)") diff --git a/src/platform.rs b/src/platform.rs new file mode 100644 index 0000000..7f4b238 --- /dev/null +++ b/src/platform.rs @@ -0,0 +1,96 @@ +//! Erkennung der Laufzeitumgebung und Wahl des Anzeigesystems (X11 oder Wayland). +//! +//! Unter WSL (WSLg) trennt der Wayland-Compositor die Verbindung, sobald die App ein Bild +//! über Vulkan übergibt ("Connection reset by peer"). Über X11 (Xwayland) läuft sie stabil, +//! daher wird unter WSL standardmäßig X11 verwendet. `INK_NOTES_DISPLAY=x11|wayland` +//! übersteuert die Wahl. + +/// Anzeigesystem, mit dem die Ereignisschleife erzeugt wird. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DisplayBackend { + /// Automatische Wahl von winit (Wayland, falls verfügbar, sonst X11) + Automatic, + X11, + Wayland, +} + +/// Wählt das Anzeigesystem. +/// +/// - `override_value`: Inhalt von `INK_NOTES_DISPLAY` (`x11` oder `wayland`, sonst ignoriert) +/// - `is_wsl`: läuft unter WSL +/// - `has_x11_display`: `DISPLAY` ist gesetzt (X11/Xwayland erreichbar) +pub fn choose_display_backend( + override_value: Option<&str>, + is_wsl: bool, + has_x11_display: bool, +) -> DisplayBackend { + match override_value + .map(|v| v.trim().to_ascii_lowercase()) + .as_deref() + { + Some("x11") => return DisplayBackend::X11, + Some("wayland") => return DisplayBackend::Wayland, + _ => {} + } + if is_wsl && has_x11_display { + DisplayBackend::X11 + } else { + DisplayBackend::Automatic + } +} + +/// Läuft das Programm unter WSL (Windows-Subsystem für Linux)? +pub fn is_wsl() -> bool { + if std::env::var_os("WSL_DISTRO_NAME").is_some() || std::env::var_os("WSL_INTEROP").is_some() { + return true; + } + std::fs::read_to_string("/proc/sys/kernel/osrelease") + .map(|release| release.to_ascii_lowercase().contains("microsoft")) + .unwrap_or(false) +} + +/// Wahl anhand der aktuellen Umgebung. +pub fn display_backend_from_env() -> DisplayBackend { + choose_display_backend( + std::env::var("INK_NOTES_DISPLAY").ok().as_deref(), + is_wsl(), + std::env::var_os("DISPLAY").is_some_and(|d| !d.is_empty()), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_choose_display_backend() { + // WSL mit X11-Display: X11 (Wayland unter WSLg bricht ab) + assert_eq!( + choose_display_backend(None, true, true), + DisplayBackend::X11 + ); + // WSL ohne X11-Display: winit entscheiden lassen + assert_eq!( + choose_display_backend(None, true, false), + DisplayBackend::Automatic + ); + // Natives Linux: winit entscheiden lassen + assert_eq!( + choose_display_backend(None, false, true), + DisplayBackend::Automatic + ); + // Übersteuerung + assert_eq!( + choose_display_backend(Some("wayland"), true, true), + DisplayBackend::Wayland + ); + assert_eq!( + choose_display_backend(Some(" X11 "), false, true), + DisplayBackend::X11 + ); + assert_eq!( + choose_display_backend(Some("quatsch"), true, true), + DisplayBackend::X11 + ); + } +}