From a18e650323d212c257fc218ecd96145bee66bd55 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 02:42:48 +0200 Subject: [PATCH 1/9] Add clippy lints --- Cargo.toml | 35 +++++++- examples/open_parented/Cargo.toml | 3 + examples/open_window/Cargo.toml | 3 + examples/plugin_clack/Cargo.toml | 7 +- examples/plugin_clack/src/audio.rs | 4 +- examples/plugin_clack/src/gui.rs | 7 +- examples/render_femtovg/Cargo.toml | 3 + examples/render_wgpu/Cargo.toml | 3 + src/error.rs | 8 +- src/handler.rs | 3 +- src/host.rs | 10 ++- src/lib.rs | 1 - src/platform/macos/gl.rs | 2 +- src/platform/win/window.rs | 8 +- src/platform/x11/cursor.rs | 9 +- src/platform/x11/drag_n_drop.rs | 2 +- src/platform/x11/error.rs | 86 +++++++++---------- src/platform/x11/event_loop.rs | 27 +++--- src/platform/x11/mod.rs | 6 +- src/platform/x11/visual_info.rs | 4 +- src/platform/x11/window.rs | 2 +- src/platform/x11/window_thread.rs | 22 +++-- src/platform/x11/xcb_connection.rs | 17 ++-- .../x11/xcb_connection/get_property.rs | 15 +++- src/platform/x11/xcb_window.rs | 2 +- src/tracing.rs | 2 - src/wrappers/appkit/view.rs | 4 +- src/wrappers/glx.rs | 2 +- src/wrappers/win32/window.rs | 4 +- src/wrappers/win32/window/data.rs | 4 +- src/wrappers/xlib/xlib_connection.rs | 36 +++++++- src/wrappers/xlib/xlib_xcb.rs | 23 ++++- 32 files changed, 236 insertions(+), 128 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c862ae7..f6f2f1e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,9 +94,42 @@ objc2-app-kit = { version = "0.3.2", default-features = false, features = [ [workspace] members = ["examples/open_parented", "examples/open_window", "examples/plugin_clack", "examples/render_femtovg", "examples/render_wgpu"] -[lints.clippy] +[lints] +workspace = true + +[workspace.lints.clippy] missing-safety-doc = "allow" +allow-attributes = "deny" +allow-attributes-without-reason = "warn" +arithmetic-side-effects = "warn" +clone-on-ref-ptr = "warn" +dbg-macro = "warn" +default-union-representation = "deny" +deref-by-slicing = "warn" +docs-paragraphs-missing-punctuation = "warn" +empty-drop = "warn" +empty-enum-variants-with-brackets = "warn" +empty-structs-with-brackets = "warn" +error-impl-error = "warn" +exhaustive-enums = "warn" +exit = "deny" +expect-used = "warn" +float-cmp-const = "warn" +get-unwrap = "warn" +indexing-slicing = "warn" +integer-division = "warn" +lossy-float-literal = "warn" +non-ascii-idents = "deny" +non-zero-suggestions = "warn" +print-stderr = "warn" +print-stdout = "warn" +todo = "warn" +try-err = "warn" +unnecessary-safety-comment = "warn" +unwrap-used = "warn" + + [package.metadata.docs.rs] all-features = true diff --git a/examples/open_parented/Cargo.toml b/examples/open_parented/Cargo.toml index 2569efda..a87bf274 100644 --- a/examples/open_parented/Cargo.toml +++ b/examples/open_parented/Cargo.toml @@ -7,3 +7,6 @@ publish = false [dependencies] baseview = { path = "../.." } softbuffer = "0.4.8" + +[lints] +workspace = true diff --git a/examples/open_window/Cargo.toml b/examples/open_window/Cargo.toml index 34ad3b83..50750950 100644 --- a/examples/open_window/Cargo.toml +++ b/examples/open_window/Cargo.toml @@ -8,3 +8,6 @@ publish = false baseview = { path = "../.." } softbuffer = "0.4.8" rtrb = "0.3.4" + +[lints] +workspace = true diff --git a/examples/plugin_clack/Cargo.toml b/examples/plugin_clack/Cargo.toml index 03a3164a..b6f40883 100644 --- a/examples/plugin_clack/Cargo.toml +++ b/examples/plugin_clack/Cargo.toml @@ -7,9 +7,12 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -clack-plugin = "0.1.0" -clack-extensions = { version = "0.1.0", features = ["gui", "state", "clack-plugin", "raw-window-handle_06"] } +clack-plugin = "0.1.1" +clack-extensions = { version = "0.1.1", features = ["gui", "state", "clack-plugin", "raw-window-handle_06"] } baseview = { path = "../..", features = ["opengl"] } softbuffer = "0.4.8" raw-window-handle = "0.6.2" +[lints] +workspace = true + diff --git a/examples/plugin_clack/src/audio.rs b/examples/plugin_clack/src/audio.rs index b3e34ee4..2b91aae1 100644 --- a/examples/plugin_clack/src/audio.rs +++ b/examples/plugin_clack/src/audio.rs @@ -15,7 +15,9 @@ impl<'a> PluginAudioProcessor<'a, (), ExamplePluginMainThread<'a>> for ExamplePl &mut self, _process: Process, mut audio: Audio, _events: Events, ) -> Result { for mut port in audio.port_pairs() { - let channels = port.channels()?.into_f32().expect("Expected f32 channels"); + let Some(channels) = port.channels()?.into_f32() else { + panic!("Expected f32 channels"); + }; for channel_pair in channels { match channel_pair { diff --git a/examples/plugin_clack/src/gui.rs b/examples/plugin_clack/src/gui.rs index 2f98ebb3..f3d58cda 100644 --- a/examples/plugin_clack/src/gui.rs +++ b/examples/plugin_clack/src/gui.rs @@ -10,8 +10,6 @@ use clack_extensions::gui::{ }; use clack_plugin::plugin::PluginError; use clack_plugin::prelude::{HostMainThreadHandle, HostSharedHandle}; -#[allow(deprecated)] -use raw_window_handle::HasRawWindowHandle; pub struct ExamplePluginGui { pub handle: Window, @@ -123,14 +121,13 @@ impl PluginGuiImpl for ExamplePluginMainThread<'_> { Ok(()) } - #[allow(deprecated)] fn set_parent(&mut self, window: ClapWindow) -> Result<(), PluginError> { let Some(gui) = &self.gui else { return Err(PluginError::Message("set_parent called without a GUI active")); }; - let parent = window.raw_window_handle()?; - let parent = unsafe { raw_window_handle::WindowHandle::borrow_raw(parent) }; + // SAFETY: The CLAP spec ensures the parent window handle is valid for at least this call + let parent = unsafe { window.borrow_handle_unchecked()? }; gui.handle.set_parent(&parent)?; gui.handle.show()?; diff --git a/examples/render_femtovg/Cargo.toml b/examples/render_femtovg/Cargo.toml index 72b19485..6796f172 100644 --- a/examples/render_femtovg/Cargo.toml +++ b/examples/render_femtovg/Cargo.toml @@ -8,3 +8,6 @@ publish = false baseview = { path = "../..", features = ["opengl", "tracing"] } femtovg = "0.25.1" tracing-subscriber = { workspace = true } + +[lints] +workspace = true diff --git a/examples/render_wgpu/Cargo.toml b/examples/render_wgpu/Cargo.toml index 1485adb6..493adb9f 100644 --- a/examples/render_wgpu/Cargo.toml +++ b/examples/render_wgpu/Cargo.toml @@ -10,3 +10,6 @@ wgpu = "30.0.0" env_logger = "0.11.11" log = "0.4.33" pollster = "0.4.0" + +[lints] +workspace = true diff --git a/src/error.rs b/src/error.rs index e6543836..e376b6f9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,11 +10,11 @@ use std::fmt::{Debug, Display, Formatter}; /// /// This is the general Baseview error type. pub struct Error { - inner: crate::platform::Error, + inner: crate::platform::PlatformError, } -impl From for Error { - fn from(inner: crate::platform::Error) -> Error { +impl From for Error { + fn from(inner: crate::platform::PlatformError) -> Error { Error { inner } } } @@ -40,7 +40,7 @@ impl std::error::Error for Error { impl From for Error { fn from(e: HandlerError) -> Self { - Self { inner: crate::platform::Error::Handler(e) } + Self { inner: crate::platform::PlatformError::Handler(e) } } } diff --git a/src/handler.rs b/src/handler.rs index 4d6ee69d..9b39cd91 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -25,7 +25,6 @@ pub trait WindowHandler: 'static { type DynBuilderResult = core::result::Result, HandlerError>; -#[allow(unused)] pub struct WindowHandlerBuilder { inner: Box DynBuilderResult + Send + 'static>, } @@ -40,7 +39,7 @@ impl WindowHandlerBuilder { pub fn build(self, ctx: WindowContext) -> Result> { match (self.inner)(ctx) { Ok(handle) => Ok(handle), - Err(e) => Err(platform::Error::Handler(e)), + Err(e) => Err(platform::PlatformError::Handler(e)), } } } diff --git a/src/host.rs b/src/host.rs index f35bf623..dea4d32c 100644 --- a/src/host.rs +++ b/src/host.rs @@ -88,12 +88,15 @@ impl Host { /// /// This is only useful on X11. On Window and macOS, this is a no-op. #[inline] - #[allow(unused)] pub fn with_main_thread(mut self, main_thread: impl HostMainThreadCaller) -> Self { #[cfg(target_os = "linux")] { self.main_thread = Some(Box::new(main_thread)); } + #[cfg(not(target_os = "linux"))] + { + let _ = main_thread; + } self } @@ -106,16 +109,15 @@ impl Host { self.callbacks = Some(RefCell::new(Box::new(callbacks))); self } -} -#[allow(unused)] -impl Host { + #[cfg(target_os = "windows")] pub(crate) fn notify_destroyed(&self) { let Some(callbacks) = &self.callbacks else { return }; let Ok(mut callbacks) = callbacks.try_borrow_mut() else { return }; callbacks.destroyed(); } + #[cfg(any(target_os = "macos", target_os = "windows"))] pub(crate) fn request_resize(&self, new_size: WindowSize) -> Result<(), HandlerError> { let Some(callbacks) = &self.callbacks else { return Ok(()) }; let Ok(mut callbacks) = callbacks.try_borrow_mut() else { return Ok(()) }; diff --git a/src/lib.rs b/src/lib.rs index 8872fe2b..1a4362ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,6 @@ pub use mouse_cursor::MouseCursor; pub use settings::*; pub use window::*; -#[allow(unused)] pub(crate) use tracing::*; mod utils; diff --git a/src/platform/macos/gl.rs b/src/platform/macos/gl.rs index 1ee7e670..ce691e7c 100644 --- a/src/platform/macos/gl.rs +++ b/src/platform/macos/gl.rs @@ -27,7 +27,7 @@ pub enum GlError { OpenGlBundleNotFound, } -impl From for Error { +impl From for PlatformError { fn from(value: GlError) -> Self { Self::GlError(value) } diff --git a/src/platform/win/window.rs b/src/platform/win/window.rs index 995645eb..7d200702 100644 --- a/src/platform/win/window.rs +++ b/src/platform/win/window.rs @@ -17,7 +17,7 @@ use super::*; use crate::handler::WindowHandlerBuilder; use crate::host::Host; use crate::platform::win::window_state::{WindowSharedState, WindowState}; -use crate::platform::Error; +use crate::platform::PlatformError; use crate::window::WindowInitializer; use crate::wrappers::win32::cursor::SystemCursor; use crate::wrappers::win32::window::*; @@ -92,7 +92,7 @@ impl WindowHandle { if self.state.current_size.get() == new_size { Ok(()) } else { - Err(Error::ResizeFailed) + Err(PlatformError::ResizeFailed) } } @@ -126,7 +126,7 @@ impl WindowHandle { if self.state.current_size.get() == new_size { Ok(()) } else { - Err(Error::ResizeFailed) + Err(PlatformError::ResizeFailed) } } @@ -310,7 +310,7 @@ impl Drop for BaseviewWindow { } impl WindowImpl for BaseviewWindow { - fn after_create(&self, window: HWnd) -> core::result::Result<(), Error> { + fn after_create(&self, window: HWnd) -> core::result::Result<(), PlatformError> { let hwnd = window.as_raw(); let window_state = &self.window_state; diff --git a/src/platform/x11/cursor.rs b/src/platform/x11/cursor.rs index 035ee36b..1cf85faf 100644 --- a/src/platform/x11/cursor.rs +++ b/src/platform/x11/cursor.rs @@ -4,12 +4,13 @@ use x11rb::protocol::xproto::{ConnectionExt as _, Cursor}; use x11rb::xcb_ffi::XCBConnection; use crate::platform::*; +use crate::wrappers::xlib::XlibXcbConnection; use crate::MouseCursor; -fn create_empty_cursor(conn: &XCBConnection, screen: usize) -> Result { +fn create_empty_cursor(conn: &XlibXcbConnection) -> Result { let cursor_id = conn.generate_id()?; let pixmap_id = conn.generate_id()?; - let root_window = conn.setup().roots[screen].root; + let root_window = conn.default_screen().root; conn.create_pixmap(1, pixmap_id, root_window, 1, 1)?; conn.create_cursor(cursor_id, pixmap_id, pixmap_id, 0, 0, 0, 0, 0, 0, 0, 0)?; conn.free_pixmap(pixmap_id)?; @@ -42,7 +43,7 @@ fn load_first_existing_cursor( } pub(crate) fn get_xcursor( - conn: &XCBConnection, screen: usize, cursor_handle: &CursorHandle, cursor: MouseCursor, + conn: &XlibXcbConnection, cursor_handle: &CursorHandle, cursor: MouseCursor, ) -> Result { let load = |name: &str| load_cursor(conn, cursor_handle, name); let loadn = |names: &[&str]| load_first_existing_cursor(conn, cursor_handle, names); @@ -54,7 +55,7 @@ pub(crate) fn get_xcursor( MouseCursor::HandGrabbing => loadn(&["closedhand", "grabbing"])?, MouseCursor::Help => load("question_arrow")?, - MouseCursor::Hidden => Some(create_empty_cursor(conn, screen)?), + MouseCursor::Hidden => Some(create_empty_cursor(conn)?), MouseCursor::Text => loadn(&["text", "xterm"])?, MouseCursor::VerticalText => load("vertical-text")?, diff --git a/src/platform/x11/drag_n_drop.rs b/src/platform/x11/drag_n_drop.rs index 1b3b0eac..edfcdb2a 100644 --- a/src/platform/x11/drag_n_drop.rs +++ b/src/platform/x11/drag_n_drop.rs @@ -590,7 +590,7 @@ fn decode_xy(data: u32) -> (u16, u16) { fn translate_root_coordinates( window: &WindowInner, x: u16, y: u16, ) -> Result>, ConnectionError> { - let root_id = window.connection.screen().root; + let root_id = window.connection.default_screen().root; let x = x.try_into().unwrap_or(i16::MAX); let y = y.try_into().unwrap_or(i16::MAX); diff --git a/src/platform/x11/error.rs b/src/platform/x11/error.rs index 1c1586cc..98fdd21c 100644 --- a/src/platform/x11/error.rs +++ b/src/platform/x11/error.rs @@ -37,7 +37,7 @@ impl From for FatalError { } #[derive(Debug)] -pub enum Error { +pub enum PlatformError { CreationFailed(String), Run(String), Io(std::io::Error), @@ -61,105 +61,105 @@ pub enum Error { Gl(super::gl::CreationFailedError), } -impl Display for Error { +impl Display for PlatformError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Error::Io(e) => e.fmt(f), + PlatformError::Io(e) => e.fmt(f), Self::IdsExhausted => f.write_str("X11 IDs have been exhausted"), - Error::CreationFailed(e) => write!(f, "Failed to create window: {e}"), - Error::Run(e) => write!(f, "Error in running X11 thread: {e}"), - Error::DylibOpen(e) => e.fmt(f), - Error::InitThreadsFailed(e) => e.fmt(f), - Error::X11(e) => write!(f, "X server replied with error: {e:?}"), - Error::Connection(e) => e.fmt(f), - Error::Parse(e) => e.fmt(f), - Error::GetProperty(e) => e.fmt(f), - Error::Connect(e) => e.fmt(f), - Error::DisplayOpenFailed(e) => e.fmt(f), - Error::Handler(e) => e.fmt(f), - Error::MainThreadRecvResult => { + PlatformError::CreationFailed(e) => write!(f, "Failed to create window: {e}"), + PlatformError::Run(e) => write!(f, "Error in running X11 thread: {e}"), + PlatformError::DylibOpen(e) => e.fmt(f), + PlatformError::InitThreadsFailed(e) => e.fmt(f), + PlatformError::X11(e) => write!(f, "X server replied with error: {e:?}"), + PlatformError::Connection(e) => e.fmt(f), + PlatformError::Parse(e) => e.fmt(f), + PlatformError::GetProperty(e) => e.fmt(f), + PlatformError::Connect(e) => e.fmt(f), + PlatformError::DisplayOpenFailed(e) => e.fmt(f), + PlatformError::Handler(e) => e.fmt(f), + PlatformError::MainThreadRecvResult => { f.write_str("Failed to receive Window creation response from X11 thread: channel was closed unexpectedly") } - Error::Calloop(e) => e.fmt(f), - Error::RequestFromMainThreadFailed(e) => e.fmt(f), - Error::SendMainThread => FatalError::SendMainThread.fmt(f), + PlatformError::Calloop(e) => e.fmt(f), + PlatformError::RequestFromMainThreadFailed(e) => e.fmt(f), + PlatformError::SendMainThread => FatalError::SendMainThread.fmt(f), #[cfg(feature = "opengl")] - Error::XLib(e) => e.fmt(f), + PlatformError::XLib(e) => e.fmt(f), #[cfg(feature = "opengl")] - Error::Gl(e) => e.fmt(f), + PlatformError::Gl(e) => e.fmt(f), } } } -impl std::error::Error for Error { +impl std::error::Error for PlatformError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Io(e) => Some(e), - Error::DylibOpen(e) => Some(e), - Error::Connect(e) => Some(e), - Error::Handler(e) => Some(e.source()), + PlatformError::Io(e) => Some(e), + PlatformError::DylibOpen(e) => Some(e), + PlatformError::Connect(e) => Some(e), + PlatformError::Handler(e) => Some(e.source()), #[cfg(feature = "opengl")] - Error::XLib(e) => Some(e), + PlatformError::XLib(e) => Some(e), _ => None, } } } -impl From for Error { +impl From for PlatformError { fn from(value: std::io::Error) -> Self { Self::Io(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: OpenError) -> Self { Self::DylibOpen(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: InitThreadsFailedError) -> Self { Self::InitThreadsFailed(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: DisplayOpenFailedError) -> Self { Self::DisplayOpenFailed(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: ConnectionError) -> Self { Self::Connection(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: X11Error) -> Self { Self::X11(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: HandlerError) -> Self { Self::Handler(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: calloop::Error) -> Self { Self::Calloop(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: RequestFailed) -> Self { Self::RequestFromMainThreadFailed(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: FatalError) -> Self { match value { FatalError::Connection(e) => Self::Connection(e), @@ -169,25 +169,25 @@ impl From for Error { } #[cfg(feature = "opengl")] -impl From for Error { +impl From for PlatformError { fn from(value: crate::wrappers::xlib::XLibError) -> Self { Self::XLib(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: ParseError) -> Self { Self::Parse(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: GetPropertyError) -> Self { Self::GetProperty(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: ConnectError) -> Self { Self::Connect(value) } @@ -195,7 +195,7 @@ impl From for Error { // X11rb aggregate error types -impl From for Error { +impl From for PlatformError { fn from(value: ReplyOrIdError) -> Self { match value { ReplyOrIdError::IdsExhausted => Self::IdsExhausted, @@ -205,7 +205,7 @@ impl From for Error { } } -impl From for Error { +impl From for PlatformError { fn from(value: ReplyError) -> Self { match value { ReplyError::ConnectionError(e) => Self::Connection(e), @@ -215,7 +215,7 @@ impl From for Error { } #[cfg(feature = "opengl")] -impl From for Error { +impl From for PlatformError { fn from(value: super::gl::CreationFailedError) -> Self { Self::Gl(value) } diff --git a/src/platform/x11/event_loop.rs b/src/platform/x11/event_loop.rs index fa966477..c7c03f83 100644 --- a/src/platform/x11/event_loop.rs +++ b/src/platform/x11/event_loop.rs @@ -60,7 +60,7 @@ pub(crate) struct EventLoop { drag_n_drop: DragNDropState, xkb_state: Option, - run_error: Option, + run_error: Option, response_sender: mpsc::Sender, main_thread: Option, @@ -72,14 +72,18 @@ impl EventLoop { request_receiver: calloop::channel::Channel, response_sender: mpsc::Sender, main_thread: Option, inner: &mut calloop::EventLoop<'static, Self>, - ) -> Result { + ) -> Result { let loop_handle = inner.handle(); Self::setup_fallback_frame_timer(&loop_handle)?; loop_handle .insert_source( - Generic::new_with_error(window.connection.conn.clone(), Interest::READ, Mode::Edge), + Generic::new_with_error( + Arc::clone(&window.connection.conn), + Interest::READ, + Mode::Edge, + ), |_, _, e| e.handle_connection_event_ready(), ) .map_err(|e| e.error)?; @@ -128,12 +132,15 @@ impl EventLoop { // being queued up. let now = Instant::now(); - let next_deadline = if previous_deadline + FRAME_INTERVAL >= now { - now + FRAME_INTERVAL - } else { - previous_deadline + FRAME_INTERVAL + + let Some(next_deadline) = previous_deadline.checked_add(FRAME_INTERVAL) else { + return TimeoutAction::ToDuration(FRAME_INTERVAL); }; + if next_deadline >= now { + return TimeoutAction::ToDuration(FRAME_INTERVAL); + } + TimeoutAction::ToInstant(next_deadline) } @@ -239,14 +246,14 @@ impl EventLoop { self.loop_signal.wakeup(); } - fn trigger_fatal_error(&mut self, error: Error) { + fn trigger_fatal_error(&mut self, error: PlatformError) { if self.run_error.is_none() { self.run_error = Some(error); } self.stop_now(); } - fn handle_request(&mut self, req: WindowThreadRequest) -> Result<(), Error> { + fn handle_request(&mut self, req: WindowThreadRequest) -> Result<(), PlatformError> { match req { WindowThreadRequest::Resize(new_size) => { let scale_factor = self.window.scaling_factor.get(); @@ -315,7 +322,7 @@ impl EventLoop { Ok(()) } - pub fn run(mut self, mut inner: calloop::EventLoop) -> Result<(), Error> { + pub fn run(mut self, mut inner: calloop::EventLoop) -> Result<(), PlatformError> { inner.run(None, &mut self, Self::handle_idle)?; self.handle_event(Event::Window(WindowEvent::WillClose)); diff --git a/src/platform/x11/mod.rs b/src/platform/x11/mod.rs index 3ce949d0..f7a50789 100644 --- a/src/platform/x11/mod.rs +++ b/src/platform/x11/mod.rs @@ -24,8 +24,8 @@ mod visibility_tree; mod window_shared; mod window_thread; -pub use error::{CookieExt as _, Error}; -pub(crate) type Result = std::result::Result; +pub use error::{CookieExt as _, PlatformError}; +pub(crate) type Result = std::result::Result; use crate::platform::x11::window_shared::WindowInner; use crate::wrappers::xlib::XlibXcbConnection; @@ -80,7 +80,7 @@ impl ParentWindowHandle { NonZeroU32::new(h.window.try_into()?).ok_or(ParentWindowHandleError::NullId)? } RawWindowHandle::Xcb(h) => h.window, - h => Err(ParentWindowHandleError::UnsupportedWindowHandleType(h))?, + h => return Err(ParentWindowHandleError::UnsupportedWindowHandleType(h)), }; Ok(Self { window_id }) diff --git a/src/platform/x11/visual_info.rs b/src/platform/x11/visual_info.rs index 439958f0..2682d63d 100644 --- a/src/platform/x11/visual_info.rs +++ b/src/platform/x11/visual_info.rs @@ -35,7 +35,7 @@ impl WindowVisualConfig { } pub fn find_best_visual_config(connection: &X11Connection) -> Result { - match find_visual_for_depth(connection.screen(), 32) { + match find_visual_for_depth(connection.default_screen(), 32) { None => Ok(Self::copy_from_parent()), Some(visual_id) => Ok(Self { #[cfg(feature = "opengl")] @@ -65,7 +65,7 @@ fn create_color_map(connection: &X11Connection, visual_id: Visualid) -> Result, ) -> Result { let mut ev_loop = calloop::EventLoop::try_new()?; - let inner = WindowInner::create(options, &ev_loop, shared.clone())?; + let inner = WindowInner::create(options, &ev_loop, Arc::clone(&shared))?; shared.init(&inner); @@ -317,7 +318,10 @@ impl WindowThread { pub fn run(self) { if let Err(e) = self.event_loop.run(self.ev_loop) { - self.shared.final_error.lock().unwrap().replace(e.to_string()); + // Ignore a poisoned mutex, we just fully override this value anyway. + let mut guard = self.shared.final_error.lock().unwrap_or_else(|g| g.into_inner()); + + guard.replace(e.to_string()); } } } @@ -329,7 +333,7 @@ fn result_channel() -> (WindowResultSender, WindowResultReceiver) { struct WindowResultSender(mpsc::SyncSender); impl WindowResultSender { - pub fn send_error(self, error: Error) { + pub fn send_error(self, error: PlatformError) { if let Err(err) = self.0.send(WindowOpenResult::Error(format!("{}", error))) { crate::error!("Window creation failed: {}", error); crate::warn!("Failed to send error to main thread: {}", err); @@ -351,10 +355,10 @@ impl WindowResultSender { struct WindowResultReceiver(mpsc::Receiver); impl WindowResultReceiver { pub fn receive(self) -> Result { - let result = self.0.recv().map_err(|_| Error::MainThreadRecvResult)?; + let result = self.0.recv().map_err(|_| PlatformError::MainThreadRecvResult)?; match result { - WindowOpenResult::Error(e) => Err(Error::CreationFailed(e)), + WindowOpenResult::Error(e) => Err(PlatformError::CreationFailed(e)), WindowOpenResult::Success { loop_signal } => Ok(loop_signal), } } diff --git a/src/platform/x11/xcb_connection.rs b/src/platform/x11/xcb_connection.rs index bbe1854f..2c0a2c11 100644 --- a/src/platform/x11/xcb_connection.rs +++ b/src/platform/x11/xcb_connection.rs @@ -59,12 +59,12 @@ pub struct X11Connection { impl X11Connection { pub fn new() -> Result { let conn = XlibXcbConnection::open()?; - let screen = conn.default_screen(); + let screen = conn.default_screen_index(); let xcb_conn = conn.xcb_connection(); let atoms = Atoms::new(xcb_conn)?.reply()?; let resources = resource_manager::new_from_default(xcb_conn)?; - let cursor_handle = CursorHandle::new(xcb_conn, screen as usize, &resources)?.reply()?; + let cursor_handle = CursorHandle::new(xcb_conn, screen.into(), &resources)?.reply()?; Ok(Self { conn: Arc::new(conn), @@ -92,20 +92,15 @@ impl X11Connection { match cursor_cache.entry(cursor) { Entry::Occupied(entry) => Ok(*entry.get()), Entry::Vacant(entry) => { - let cursor = cursor::get_xcursor( - &self.conn, - self.conn.default_screen() as usize, - &self.cursor_handle, - cursor, - )?; + let cursor = cursor::get_xcursor(&self.conn, &self.cursor_handle, cursor)?; entry.insert(cursor); Ok(cursor) } } } - pub fn screen(&self) -> &Screen { - &self.conn.setup().roots[self.conn.default_screen() as usize] + pub fn default_screen(&self) -> &Screen { + self.conn.default_screen() } pub fn get_property( @@ -117,7 +112,7 @@ impl X11Connection { pub fn register_tree_structure_events( &self, ) -> core::result::Result, ConnectionError> { - let root = self.screen().root; + let root = self.default_screen().root; self.conn.change_window_attributes( root, diff --git a/src/platform/x11/xcb_connection/get_property.rs b/src/platform/x11/xcb_connection/get_property.rs index 6bd487ff..0639fc01 100644 --- a/src/platform/x11/xcb_connection/get_property.rs +++ b/src/platform/x11/xcb_connection/get_property.rs @@ -37,12 +37,11 @@ Copies of those licenses can be respectively found at: */ +use bytemuck::Pod; use std::error::Error; use std::ffi::c_int; use std::fmt; use std::mem; - -use bytemuck::Pod; use x11rb::errors::{ConnectionError, ReplyError}; use x11rb::protocol::xproto::{self, ConnectionExt}; use x11rb::xcb_ffi::XCBConnection; @@ -53,6 +52,7 @@ pub enum GetPropertyError { ReplyError(ReplyError), TypeMismatch(xproto::Atom), FormatMismatch(c_int), + Overflow, } impl fmt::Display for GetPropertyError { @@ -62,6 +62,9 @@ impl fmt::Display for GetPropertyError { GetPropertyError::FormatMismatch(err) => write!(f, "format mismatch: {err}"), GetPropertyError::ConnectionError(e) => e.fmt(f), GetPropertyError::ReplyError(e) => e.fmt(f), + GetPropertyError::Overflow => { + f.write_str("Overflow while trying to read property value") + } } } } @@ -176,7 +179,7 @@ impl<'a, T: Pod> PropIterator<'a, T> { } // Append the data to the output. - if mem::size_of::() == 1 && mem::align_of::() == 1 { + if size_of::() == 1 && align_of::() == 1 { // We can just do a bytewise append. data.extend_from_slice(bytemuck::cast_slice(&reply.value)); } else { @@ -188,7 +191,11 @@ impl<'a, T: Pod> PropIterator<'a, T> { } // Check `bytes_after` to see if there are more windows to fetch. - self.offset += PROPERTY_BUFFER_SIZE; + let Some(new_offset) = self.offset.checked_add(PROPERTY_BUFFER_SIZE) else { + return Err(GetPropertyError::Overflow); + }; + self.offset = new_offset; + Ok(reply.bytes_after != 0) } } diff --git a/src/platform/x11/xcb_window.rs b/src/platform/x11/xcb_window.rs index 95086067..252c07dc 100644 --- a/src/platform/x11/xcb_window.rs +++ b/src/platform/x11/xcb_window.rs @@ -32,7 +32,7 @@ impl XcbWindow { connection.conn.create_window( visual_info.visual_depth, window_id.get(), - parent_id.map_or(connection.screen().root, NonZeroU32::get), + parent_id.map_or(connection.default_screen().root, NonZeroU32::get), 0, // x coordinate of the new window 0, // y coordinate of the new window size.width, // window width diff --git a/src/tracing.rs b/src/tracing.rs index 414afea1..5b822b1d 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,9 +1,7 @@ #[cfg(feature = "tracing")] -#[allow(unused)] pub use tracing::{error, warn}; #[cfg(not(feature = "tracing"))] -#[allow(unused)] mod tracing_impl { macro_rules! __warn { ($($f:tt)*) => { diff --git a/src/wrappers/appkit/view.rs b/src/wrappers/appkit/view.rs index acf507c9..bed2b212 100644 --- a/src/wrappers/appkit/view.rs +++ b/src/wrappers/appkit/view.rs @@ -42,8 +42,8 @@ impl Deref for View { impl View { pub fn new( frame: CGRect, inner: V, - init: impl FnOnce(ViewRef) -> Result<(), crate::platform::Error>, - ) -> Result>, crate::platform::Error> { + init: impl FnOnce(ViewRef) -> Result<(), crate::platform::PlatformError>, + ) -> Result>, crate::platform::PlatformError> { // SAFETY: We don't access this reference after this function let class = unsafe { implementation::create_view_class::() }; diff --git a/src/wrappers/glx.rs b/src/wrappers/glx.rs index 7f16d13f..34e39312 100644 --- a/src/wrappers/glx.rs +++ b/src/wrappers/glx.rs @@ -69,7 +69,7 @@ impl Glx { let result = unsafe { (self.inner.glXChooseFBConfig)( connection.as_raw(), - connection.default_screen_index(), + connection.default_screen_index().into(), fb_attribs.as_ptr(), &mut nelements, ) diff --git a/src/wrappers/win32/window.rs b/src/wrappers/win32/window.rs index 26f94dd9..c1fc065b 100644 --- a/src/wrappers/win32/window.rs +++ b/src/wrappers/win32/window.rs @@ -35,7 +35,9 @@ pub trait WindowImpl: 'static { /// [`handle_message`] to be called immediately. Implementations must be ready for that. /// /// If this returns an error, the window creation is canceled. - fn after_create(&self, window: HWnd) -> core::result::Result<(), crate::platform::Error>; + fn after_create( + &self, window: HWnd, + ) -> core::result::Result<(), crate::platform::PlatformError>; unsafe fn handle_message( &self, window: HWnd, message_code: u32, w_param: WPARAM, l_param: LPARAM, ) -> Option; diff --git a/src/wrappers/win32/window/data.rs b/src/wrappers/win32/window/data.rs index fc7f0f79..6c133d72 100644 --- a/src/wrappers/win32/window/data.rs +++ b/src/wrappers/win32/window/data.rs @@ -35,7 +35,9 @@ impl WindowData { handler(&this) } - pub fn initialize(&self, window: HWnd) -> core::result::Result<(), crate::platform::Error> { + pub fn initialize( + &self, window: HWnd, + ) -> core::result::Result<(), crate::platform::PlatformError> { let Some(initializer) = self.initializer.take() else { panic!("WindowData is already initialized"); }; diff --git a/src/wrappers/xlib/xlib_connection.rs b/src/wrappers/xlib/xlib_connection.rs index 95fcabb2..fe4ccdc7 100644 --- a/src/wrappers/xlib/xlib_connection.rs +++ b/src/wrappers/xlib/xlib_connection.rs @@ -16,7 +16,7 @@ use x11_dl::xlib_xcb::{XEventQueueOwner, Xlib_xcb}; pub struct XlibConnection { display: NonNull, xlib: Box, - default_screen: c_int, + default_screen: ScreenIndex, } // SAFETY: Xlib functions should be thread-safe, since we initialize it with XInitThreads below @@ -37,9 +37,9 @@ impl XlibConnection { let Some(display) = NonNull::new(ptr) else { return Err(DisplayOpenFailedError.into()) }; - let mut this = Self { display, xlib, default_screen: 0 }; + let mut this = Self { display, xlib, default_screen: ScreenIndex(0) }; - this.default_screen = this.fetch_default_screen(); + this.default_screen = ScreenIndex::new(this.fetch_default_screen()); Ok(this) } @@ -55,7 +55,7 @@ impl XlibConnection { } /// Returns the index of the default screen for this X server. - pub fn default_screen_index(&self) -> c_int { + pub fn default_screen_index(&self) -> ScreenIndex { self.default_screen } @@ -75,6 +75,34 @@ impl XlibConnection { } } +#[derive(Copy, Clone)] +pub struct ScreenIndex(c_int); + +impl ScreenIndex { + pub fn new(value: c_int) -> Self { + if let Err(e) = usize::try_from(value) { + panic!("Default screen index {value} could not be used: {e}"); + } + + Self(value) + } +} + +impl From for usize { + #[inline] + fn from(value: ScreenIndex) -> Self { + // This will not panic or overflow, we checked it in the constructor + value.0 as usize + } +} + +impl From for c_int { + #[inline] + fn from(value: ScreenIndex) -> Self { + value.0 + } +} + #[cfg(feature = "opengl")] impl XlibConnection { pub fn xlib(&self) -> &Xlib { diff --git a/src/wrappers/xlib/xlib_xcb.rs b/src/wrappers/xlib/xlib_xcb.rs index e50015f4..0b6d8633 100644 --- a/src/wrappers/xlib/xlib_xcb.rs +++ b/src/wrappers/xlib/xlib_xcb.rs @@ -1,11 +1,14 @@ use crate::platform::*; use crate::wrappers::xlib::xlib_connection::XlibConnection; +use crate::wrappers::xlib::ScreenIndex; use raw_window_handle::{DisplayHandle, XcbDisplayHandle, XlibDisplayHandle}; use std::ops::Deref; use std::os::fd::{AsFd, BorrowedFd}; use std::os::raw::c_int; use std::ptr::NonNull; use x11_dl::xlib_xcb::Xlib_xcb; +use x11rb::connection::Connection; +use x11rb::protocol::xproto::Screen; use x11rb::xcb_ffi::XCBConnection; /// A Xlib/XCB connection object. @@ -45,13 +48,25 @@ impl XlibXcbConnection { let xcb_connection = unsafe { XCBConnection::from_raw_xcb_connection(xcb_connection, false)? }; + let default_screen_index: usize = xlib_connection.default_screen_index().into(); + if xcb_connection.setup().roots.get(default_screen_index).is_none() { + panic!("No screen found for default_screen index {default_screen_index}"); + } + Ok(Self { xcb_connection, xlib_connection }) } - pub fn default_screen(&self) -> c_int { + pub fn default_screen_index(&self) -> ScreenIndex { self.xlib_connection.default_screen_index() } + pub fn default_screen(&self) -> &Screen { + let screen_index: usize = self.default_screen_index().into(); + let Some(screen) = self.setup().roots.get(screen_index) else { unreachable!() }; + + screen + } + pub fn xcb_connection(&self) -> &XCBConnection { &self.xcb_connection } @@ -63,7 +78,8 @@ impl XlibXcbConnection { pub fn xlib_display_handle(&self) -> DisplayHandle<'_> { let raw_connection = self.xlib_connection.as_raw().cast(); let Some(raw_connection) = NonNull::new(raw_connection) else { unreachable!() }; - let handle = XlibDisplayHandle::new(Some(raw_connection), self.default_screen()); + let handle = + XlibDisplayHandle::new(Some(raw_connection), self.default_screen_index().into()); unsafe { DisplayHandle::borrow_raw(handle.into()) } } @@ -71,7 +87,8 @@ impl XlibXcbConnection { pub fn xcb_display_handle(&self) -> DisplayHandle<'_> { let raw_connection = self.xcb_connection.get_raw_xcb_connection(); let Some(raw_connection) = NonNull::new(raw_connection) else { unreachable!() }; - let handle = XcbDisplayHandle::new(Some(raw_connection), self.default_screen()); + let handle = + XcbDisplayHandle::new(Some(raw_connection), self.default_screen_index().into()); unsafe { DisplayHandle::borrow_raw(handle.into()) } } From 328b93d6bb191b583b3aad93df8a0fa6f5572d40 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 03:04:00 +0200 Subject: [PATCH 2/9] More clippy fixes --- Cargo.toml | 5 ++- src/context.rs | 4 +-- src/error.rs | 1 + src/event.rs | 31 ++++++++++--------- src/mouse_cursor.rs | 1 + src/platform/x11/keyboard.rs | 2 +- src/platform/x11/visibility_tree.rs | 4 +-- src/platform/x11/xcb_connection.rs | 1 - .../x11/xcb_connection/get_property.rs | 8 ++--- src/settings.rs | 2 +- src/tracing.rs | 1 - src/window.rs | 12 +++---- src/wrappers.rs | 6 ++-- src/wrappers/xkbcommon.rs | 2 +- src/wrappers/xlib/xlib_connection.rs | 2 +- src/wrappers/xlib/xlib_xcb.rs | 1 - 16 files changed, 40 insertions(+), 43 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6f2f1e7..08b43564 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ xkbcommon-dl = { version = "0.4.2", features = ["x11"] } x11-dl = { version = "2.21.0" } calloop = "0.14.4" percent-encoding = "2.3.2" -bytemuck = "1.25.0" +bytemuck = { version = "1.25.0", features = ["extern_crate_alloc"] } [target.'cfg(target_os="windows")'.dependencies] windows = { version = "0.62.2", features = [ @@ -107,7 +107,7 @@ clone-on-ref-ptr = "warn" dbg-macro = "warn" default-union-representation = "deny" deref-by-slicing = "warn" -docs-paragraphs-missing-punctuation = "warn" +doc-paragraphs-missing-punctuation = "warn" empty-drop = "warn" empty-enum-variants-with-brackets = "warn" empty-structs-with-brackets = "warn" @@ -120,7 +120,6 @@ get-unwrap = "warn" indexing-slicing = "warn" integer-division = "warn" lossy-float-literal = "warn" -non-ascii-idents = "deny" non-zero-suggestions = "warn" print-stderr = "warn" print-stdout = "warn" diff --git a/src/context.rs b/src/context.rs index 691bd123..5c1ca9ca 100644 --- a/src/context.rs +++ b/src/context.rs @@ -114,8 +114,8 @@ impl HasDisplayHandle for WindowContext { /// # Platform compatibility notes /// /// Depending on the platform, the [`PlatformHandle::window_handle`] method may return -/// [`HandleError::Unavailable`] if called from a thread other than the main thread. (Even if the -/// window is still alive and well) +/// [`HandleError::Unavailable`] if called from a thread other than the main thread (Even if the +/// window is still alive and well). #[derive(Clone)] pub struct PlatformHandle { inner: platform::PlatformHandle, diff --git a/src/error.rs b/src/error.rs index e376b6f9..b6200ac1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,6 +9,7 @@ use std::fmt::{Debug, Display, Formatter}; /// not possible on e.g. Windows or macOS. /// /// This is the general Baseview error type. +#[expect(clippy::error_impl_error, reason = "This is fine for the global error type")] pub struct Error { inner: crate::platform::PlatformError, } diff --git a/src/event.rs b/src/event.rs index f6b68256..438f0904 100644 --- a/src/event.rs +++ b/src/event.rs @@ -15,20 +15,21 @@ pub enum MouseButton { /// A scroll movement. #[derive(Debug, Clone, Copy, PartialEq)] +#[expect(clippy::exhaustive_enums, reason = "We don't expect new scroll types anytime soon")] pub enum ScrollDelta { - /// A line-based scroll movement + /// A line-based scroll movement. Lines { - /// The number of horizontal lines scrolled + /// The number of horizontal lines scrolled. x: f32, - /// The number of vertical lines scrolled + /// The number of vertical lines scrolled. y: f32, }, - /// A pixel-based scroll movement + /// A pixel-based scroll movement. Pixels { - /// The number of horizontal pixels scrolled + /// The number of horizontal pixels scrolled. x: f32, - /// The number of vertical pixels scrolled + /// The number of vertical pixels scrolled. y: f32, }, } @@ -36,9 +37,9 @@ pub enum ScrollDelta { #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub enum MouseEvent { - /// The mouse cursor was moved + /// The mouse cursor was moved. CursorMoved { - /// The logical coordinates of the mouse position + /// The logical coordinates of the mouse position. position: PhysicalPosition, /// The modifiers that were held down just before the event. modifiers: Modifiers, @@ -79,31 +80,31 @@ pub enum MouseEvent { CursorLeft, DragEntered { - /// The logical coordinates of the mouse position + /// The logical coordinates of the mouse position. position: PhysicalPosition, /// The modifiers that were held down just before the event. modifiers: Modifiers, - /// Data being dragged + /// Data being dragged. data: DropData, }, DragMoved { - /// The logical coordinates of the mouse position + /// The logical coordinates of the mouse position. position: PhysicalPosition, /// The modifiers that were held down just before the event. modifiers: Modifiers, - /// Data being dragged + /// Data being dragged. data: DropData, }, DragLeft, DragDropped { - /// The logical coordinates of the mouse position + /// The logical coordinates of the mouse position. position: PhysicalPosition, /// The modifiers that were held down just before the event. modifiers: Modifiers, - /// Data being dragged + /// Data being dragged. data: DropData, }, } @@ -161,6 +162,6 @@ pub enum EventStatus { /// plugin window is in focus. Ignored, /// We are prepared to handle the data in the drag and dropping will - /// result in [DropEffect] + /// result in [DropEffect]. AcceptDrop(DropEffect), } diff --git a/src/mouse_cursor.rs b/src/mouse_cursor.rs index 754e0297..5db7ac3c 100644 --- a/src/mouse_cursor.rs +++ b/src/mouse_cursor.rs @@ -1,3 +1,4 @@ +#[expect(clippy::exhaustive_enums, reason = "TODO: next major version")] #[derive(Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Hash, Default)] pub enum MouseCursor { #[default] diff --git a/src/platform/x11/keyboard.rs b/src/platform/x11/keyboard.rs index 8cb1f912..b18facda 100644 --- a/src/platform/x11/keyboard.rs +++ b/src/platform/x11/keyboard.rs @@ -16,7 +16,7 @@ // - collect functions from various files // - update imports, paths etc -//! X11 keyboard handling +//! X11 keyboard handling. use x11rb::protocol::xproto::{KeyButMask, KeyPressEvent, KeyReleaseEvent}; diff --git a/src/platform/x11/visibility_tree.rs b/src/platform/x11/visibility_tree.rs index 64eb88df..ef51d32a 100644 --- a/src/platform/x11/visibility_tree.rs +++ b/src/platform/x11/visibility_tree.rs @@ -100,7 +100,7 @@ impl AncestorVisibilityState { self.ancestry.parent_id() } - /// Returns `true` if this operation made our own window visible + /// Returns `true` if this operation made our own window visible. pub fn window_mapped(&self, window_id: Window) -> bool { if !self.ancestry.set_mapped(window_id, true) { return false; @@ -214,7 +214,7 @@ impl AncestorVisibilityState { } } -/// Returns Ok(None) on BadWindow +/// Returns Ok(None) on BadWindow. fn fetch_window_info( connection: &XCBConnection, window: Window, ) -> Result, ReplyError> { diff --git a/src/platform/x11/xcb_connection.rs b/src/platform/x11/xcb_connection.rs index 2c0a2c11..eab70899 100644 --- a/src/platform/x11/xcb_connection.rs +++ b/src/platform/x11/xcb_connection.rs @@ -5,7 +5,6 @@ use crate::MouseCursor; use std::cell::RefCell; use std::collections::hash_map::{Entry, HashMap}; use std::sync::Arc; -use x11rb::connection::Connection; use x11rb::cookie::VoidCookie; use x11rb::cursor::Handle as CursorHandle; use x11rb::errors::ConnectionError; diff --git a/src/platform/x11/xcb_connection/get_property.rs b/src/platform/x11/xcb_connection/get_property.rs index 0639fc01..d61c08e4 100644 --- a/src/platform/x11/xcb_connection/get_property.rs +++ b/src/platform/x11/xcb_connection/get_property.rs @@ -183,11 +183,9 @@ impl<'a, T: Pod> PropIterator<'a, T> { // We can just do a bytewise append. data.extend_from_slice(bytemuck::cast_slice(&reply.value)); } else { - let old_len = data.len(); - let added_len = reply.value.len() / mem::size_of::(); - - data.resize(old_len + added_len, T::zeroed()); - bytemuck::cast_slice_mut::(&mut data[old_len..]).copy_from_slice(&reply.value); + // Reply may not be properly aligned, but we can afford to use an intermediary vec here + let mut reply = bytemuck::allocation::pod_collect_to_vec(&reply.value); + data.append(&mut reply); } // Check `bytes_after` to see if there are more windows to fetch. diff --git a/src/settings.rs b/src/settings.rs index 65ff592b..671f1760 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -4,7 +4,7 @@ use crate::platform; use dpi::{LogicalSize, Size}; use raw_window_handle::HasWindowHandle; -/// Settings used when creating a new window +/// Settings used when creating a new window. #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub struct WindowSettings { diff --git a/src/tracing.rs b/src/tracing.rs index 5b822b1d..06495922 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -6,7 +6,6 @@ mod tracing_impl { macro_rules! __warn { ($($f:tt)*) => { { - #[allow(unused, dead_code)] let _ = ($($f)*); } }; diff --git a/src/window.rs b/src/window.rs index ebb51a9c..b2fe41c9 100644 --- a/src/window.rs +++ b/src/window.rs @@ -48,8 +48,8 @@ impl Window { /// create the associated [`WindowHandler`]. /// /// This function creates the window but does not open or show it. - /// You must use the [`show`](Self::show) method to actually open it. - /// (unless you use [`run_until_closed`](Self::run_until_closed), which does it automatically) + /// You must use the [`show`](Self::show) method to actually open it + /// (unless you use [`run_until_closed`](Self::run_until_closed), which does it automatically). #[inline] pub fn create( options: WindowSettings, @@ -63,8 +63,8 @@ impl Window { /// to a potential system that is hosting the window (e.g. in a plug-in setting). /// /// This function creates the window but does not open or show it. - /// You must use the [`show`](Self::show) method to actually open it. - /// (unless you use [`run_until_closed`](Self::run_until_closed), which does it automatically) + /// You must use the [`show`](Self::show) method to actually open it + /// (unless you use [`run_until_closed`](Self::run_until_closed), which does it automatically). /// /// Calling this function with [`None`] for the `host` value is equivalent to calling /// [`create`](Self::create). @@ -236,9 +236,9 @@ pub(crate) struct WindowInitializer { /// which minimizes errors that may occur due to rounding. #[derive(Debug, Copy, Clone)] pub struct WindowSize { - /// The window's size in physical pixels + /// The window's size in physical pixels. pub physical: PhysicalSize, - /// The window's size in logical pixels + /// The window's size in logical pixels. pub logical: LogicalSize, /// The backing scale factor of the window. /// diff --git a/src/wrappers.rs b/src/wrappers.rs index 01483e1e..7de9a42d 100644 --- a/src/wrappers.rs +++ b/src/wrappers.rs @@ -1,4 +1,4 @@ -#![allow(unsafe_code)] +#![allow(unsafe_code, reason = "This is where the unsafe code lives")] //! A set of safe wrappers around C or platform APIs. //! @@ -11,11 +11,11 @@ //! However, all of these APIs should always be sound (i.e. no UB can be triggered by safe code). //! Otherwise, this should be considered a bug and reported accordingly. -/// Wrappers and utilities around Xlib. (provided by x11_dl) +/// Wrappers and utilities around Xlib (provided by x11_dl). #[cfg(target_os = "linux")] pub mod xlib; -/// Wrappers and utilities around xkbcommon. (provided by xkbcommon_dl) +/// Wrappers and utilities around xkbcommon (provided by xkbcommon_dl). #[cfg(target_os = "linux")] pub mod xkbcommon; diff --git a/src/wrappers/xkbcommon.rs b/src/wrappers/xkbcommon.rs index a6a9c1de..88ff5a63 100644 --- a/src/wrappers/xkbcommon.rs +++ b/src/wrappers/xkbcommon.rs @@ -1,7 +1,7 @@ use xkbcommon_dl as xkbc; pub(crate) type Keycode = xkbcommon_dl::xkb_keycode_t; -/// A xkbcommon state object +/// A xkbcommon state object. pub struct XkbcommonState { state: *mut xkbc::xkb_state, xkb_common: &'static xkbc::XkbCommon, diff --git a/src/wrappers/xlib/xlib_connection.rs b/src/wrappers/xlib/xlib_connection.rs index fe4ccdc7..b1f831fc 100644 --- a/src/wrappers/xlib/xlib_connection.rs +++ b/src/wrappers/xlib/xlib_connection.rs @@ -64,7 +64,7 @@ impl XlibConnection { unsafe { CStr::from_ptr(ptr) } } - /// Safe wrapper for XDefaultScreen + /// Safe wrapper for XDefaultScreen. fn fetch_default_screen(&self) -> c_int { // SAFETY: This type ensures the display pointer is always valid. unsafe { (self.xlib.XDefaultScreen)(self.display.as_ptr()) } diff --git a/src/wrappers/xlib/xlib_xcb.rs b/src/wrappers/xlib/xlib_xcb.rs index 0b6d8633..3fb374e8 100644 --- a/src/wrappers/xlib/xlib_xcb.rs +++ b/src/wrappers/xlib/xlib_xcb.rs @@ -4,7 +4,6 @@ use crate::wrappers::xlib::ScreenIndex; use raw_window_handle::{DisplayHandle, XcbDisplayHandle, XlibDisplayHandle}; use std::ops::Deref; use std::os::fd::{AsFd, BorrowedFd}; -use std::os::raw::c_int; use std::ptr::NonNull; use x11_dl::xlib_xcb::Xlib_xcb; use x11rb::connection::Connection; From 6c8127dd9e26f879c82a1b83f1e2978ca7edcef5 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 03:41:00 +0200 Subject: [PATCH 3/9] More clippy fixes --- src/gl.rs | 4 ++++ src/host.rs | 11 ++++++----- src/platform/macos/cursor.rs | 12 ++++++------ src/platform/macos/error.rs | 16 ++++++++-------- src/platform/macos/gl.rs | 11 +++++++++-- src/platform/macos/keyboard.rs | 2 +- src/platform/macos/mod.rs | 4 ++-- src/platform/macos/view.rs | 10 +++++----- src/tracing.rs | 6 +++++- 9 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/gl.rs b/src/gl.rs index 431421d6..9c34b608 100644 --- a/src/gl.rs +++ b/src/gl.rs @@ -37,6 +37,10 @@ impl Default for GlConfig { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[expect( + clippy::exhaustive_enums, + reason = "We don't expect to add new profiles until a new major version" +)] pub enum Profile { Compatibility, Core, diff --git a/src/host.rs b/src/host.rs index dea4d32c..980a3e8c 100644 --- a/src/host.rs +++ b/src/host.rs @@ -88,17 +88,18 @@ impl Host { /// /// This is only useful on X11. On Window and macOS, this is a no-op. #[inline] - pub fn with_main_thread(mut self, main_thread: impl HostMainThreadCaller) -> Self { + pub fn with_main_thread(self, main_thread: impl HostMainThreadCaller) -> Self { #[cfg(target_os = "linux")] { - self.main_thread = Some(Box::new(main_thread)); + let mut this = self; + this.main_thread = Some(Box::new(main_thread)); + this } #[cfg(not(target_os = "linux"))] { let _ = main_thread; + self } - - self } /// Sets the [`HostCallbacks`] handler to be used. @@ -110,7 +111,7 @@ impl Host { self } - #[cfg(target_os = "windows")] + #[cfg(any(target_os = "macos", target_os = "windows"))] pub(crate) fn notify_destroyed(&self) { let Some(callbacks) = &self.callbacks else { return }; let Ok(mut callbacks) = callbacks.try_borrow_mut() else { return }; diff --git a/src/platform/macos/cursor.rs b/src/platform/macos/cursor.rs index d02e54e7..c4ec551c 100644 --- a/src/platform/macos/cursor.rs +++ b/src/platform/macos/cursor.rs @@ -25,19 +25,19 @@ impl From for Cursor { Cursor::Native(NSCursor::operationNotAllowedCursor) } MouseCursor::Crosshair => Cursor::Native(NSCursor::crosshairCursor), - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::EResize => Cursor::Native(NSCursor::resizeRightCursor), - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::NResize => Cursor::Native(NSCursor::resizeUpCursor), - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::WResize => Cursor::Native(NSCursor::resizeLeftCursor), - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::SResize => Cursor::Native(NSCursor::resizeDownCursor), - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::EwResize | MouseCursor::ColResize => { Cursor::Native(NSCursor::resizeLeftRightCursor) } - #[allow(deprecated)] + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::NsResize | MouseCursor::RowResize => { Cursor::Native(NSCursor::resizeUpDownCursor) } diff --git a/src/platform/macos/error.rs b/src/platform/macos/error.rs index 4c21517c..7d0672b2 100644 --- a/src/platform/macos/error.rs +++ b/src/platform/macos/error.rs @@ -2,34 +2,34 @@ use crate::HandlerError; use std::fmt::Display; #[derive(Debug)] -pub enum Error { +pub enum PlatformError { Handler(HandlerError), #[cfg(feature = "opengl")] GlError(super::gl::GlError), } -impl Display for Error { +impl Display for PlatformError { fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { #[cfg(feature = "opengl")] - Error::GlError(e) => e.fmt(fmt), - Error::Handler(e) => e.fmt(fmt), + PlatformError::GlError(e) => e.fmt(fmt), + PlatformError::Handler(e) => e.fmt(fmt), } } } -impl std::error::Error for Error { +impl std::error::Error for PlatformError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Handler(e) => Some(e.source()), + PlatformError::Handler(e) => Some(e.source()), #[cfg(feature = "opengl")] _ => None, } } } -impl From for Error { +impl From for PlatformError { fn from(e: HandlerError) -> Self { - Error::Handler(e) + PlatformError::Handler(e) } } diff --git a/src/platform/macos/gl.rs b/src/platform/macos/gl.rs index ce691e7c..98254f2f 100644 --- a/src/platform/macos/gl.rs +++ b/src/platform/macos/gl.rs @@ -1,4 +1,4 @@ -#![allow(deprecated)] // OpenGL is deprecated on macOS +#![expect(deprecated, reason = "OpenGL is deprecated on macOS")] use crate::gl::{GlConfig, Profile}; use crate::platform::*; @@ -75,10 +75,17 @@ impl GlContext { .into()); }; + let Some(color_size) = (config.red_bits as u32) + .checked_add(config.blue_bits as u32) + .and_then(|c| c.checked_add(config.green_bits as u32)) + else { + panic!("Overflow when computing color size") + }; + #[rustfmt::skip] let mut attrs = vec![ NSOpenGLPFAOpenGLProfile, version, - NSOpenGLPFAColorSize, (config.red_bits + config.blue_bits + config.green_bits) as u32, + NSOpenGLPFAColorSize, color_size, NSOpenGLPFAAlphaSize, config.alpha_bits as u32, NSOpenGLPFADepthSize, config.depth_bits as u32, NSOpenGLPFAStencilSize, config.stencil_bits as u32, diff --git a/src/platform/macos/keyboard.rs b/src/platform/macos/keyboard.rs index 92804bac..414a3aaf 100644 --- a/src/platform/macos/keyboard.rs +++ b/src/platform/macos/keyboard.rs @@ -39,7 +39,7 @@ pub(crate) struct KeyboardState { /// Convert a macOS platform key code (keyCode field of NSEvent). /// /// The primary source for this mapping is: -/// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values +/// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values. /// /// It should also match up with CODE_MAP_MAC bindings in /// NativeKeyToDOMCodeName.h. diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 18d3b3e3..89df2630 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -9,7 +9,7 @@ use crate::platform::macos::view::BaseviewView; use crate::wrappers::appkit::{extract_raw_window_handle, ParentWindowHandleError, View}; pub use context::WindowContext; use dispatch2::MainThreadBound; -pub use error::Error; +pub use error::PlatformError; use objc2::__framework_prelude::Retained; use objc2::rc::Weak; use objc2::{MainThreadMarker, MainThreadOnly}; @@ -18,7 +18,7 @@ use raw_window_handle::{DisplayHandle, HasWindowHandle}; use std::fmt; use std::fmt::Formatter; pub use window::*; -pub(crate) type Result = std::result::Result; +pub(crate) type Result = std::result::Result; #[cfg(feature = "opengl")] pub mod gl; diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index 3b484889..d9f2bf7a 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -1,4 +1,4 @@ -#![allow(deprecated)] // Allow use of NSFilenamesPboardType for now +#![expect(deprecated, reason = "Allow use of NSFilenamesPboardType for now")] use super::keyboard::{make_modifiers, KeyboardState}; use super::window::WindowSharedState; @@ -17,7 +17,7 @@ use dpi::{LogicalPosition, LogicalSize, Size}; use objc2::__framework_prelude::Retained; use objc2::rc::Weak; use objc2::runtime::{NSObjectProtocol, ProtocolObject}; -use objc2::{msg_send, AllocAnyThread, MainThreadMarker}; +use objc2::{msg_send, AllocAnyThread, ClassType, MainThreadMarker}; use objc2_app_kit::{ NSApplication, NSDragOperation, NSDraggingInfo, NSEvent, NSFilenamesPboardType, NSTrackingArea, NSTrackingAreaOptions, NSView, NSWindow, @@ -94,7 +94,7 @@ impl BaseviewView { let inner = BaseviewView { mtm, - state: state.clone(), + state: Rc::clone(&state), keyboard_state: KeyboardState::new(), frame_timer: None.into(), @@ -372,7 +372,7 @@ impl ViewImpl for BaseviewView { /// collapse, so the override pass-through is equivalent to the /// default implementation. fn hit_test(this: ViewRef<'_, Self>, point: NSPoint) -> Option<&NSView> { - let superclass = this.view.class().superclass().unwrap(); + let superclass = NSView::class(); // SAFETY: Our superclass is NSView let super_result: Option<&NSView> = @@ -670,7 +670,7 @@ impl ViewImpl for BaseviewView { /// Info: /// https://developer.apple.com/documentation/appkit/nstrackingarea /// https://developer.apple.com/documentation/appkit/nstrackingarea/options -/// https://developer.apple.com/documentation/appkit/nstrackingareaoptions +/// https://developer.apple.com/documentation/appkit/nstrackingareaoptions. fn new_tracking_area(this: &NSView) -> Retained { let options = NSTrackingAreaOptions::MouseEnteredAndExited | NSTrackingAreaOptions::MouseMoved diff --git a/src/tracing.rs b/src/tracing.rs index 06495922..7fbb6717 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,5 +1,8 @@ #[cfg(feature = "tracing")] -pub use tracing::{error, warn}; +pub use tracing::warn; + +#[cfg(all(feature = "tracing", not(target_os = "macos")))] +pub use tracing::error; #[cfg(not(feature = "tracing"))] mod tracing_impl { @@ -12,6 +15,7 @@ mod tracing_impl { } pub(crate) use __warn as warn; + #[cfg(target_os = "macos")] pub(crate) use __warn as error; } From 151b9f88e578051184bf63cc17507ba691a7846d Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 05:33:07 +0200 Subject: [PATCH 4/9] More clippy fixes --- Cargo.toml | 1 - src/platform/win/drop_target.rs | 13 +++++----- src/platform/win/error.rs | 26 ++++++++++---------- src/platform/win/gl.rs | 6 ++--- src/platform/win/hook.rs | 2 ++ src/platform/win/keyboard.rs | 8 ++++++- src/platform/win/mod.rs | 4 ++-- src/platform/win/window.rs | 37 +++++++++++++++-------------- src/platform/win/window_state.rs | 6 ++--- src/wrappers.rs | 2 +- src/wrappers/win32/dpi.rs | 8 +++---- src/wrappers/win32/window/handle.rs | 2 +- src/wrappers/win32/window/wgl.rs | 3 ++- 13 files changed, 64 insertions(+), 54 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08b43564..def39a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,6 @@ workspace = true [workspace.lints.clippy] missing-safety-doc = "allow" -allow-attributes = "deny" allow-attributes-without-reason = "warn" arithmetic-side-effects = "warn" clone-on-ref-ptr = "warn" diff --git a/src/platform/win/drop_target.rs b/src/platform/win/drop_target.rs index 98c65e33..44312648 100644 --- a/src/platform/win/drop_target.rs +++ b/src/platform/win/drop_target.rs @@ -1,3 +1,5 @@ +#![expect(clippy::indexing_slicing, reason = "To be refactored later")] + use dpi::PhysicalPosition; use std::cell::{Cell, RefCell}; use std::ffi::OsString; @@ -38,8 +40,7 @@ impl DropTarget { } } - #[allow(non_snake_case)] - fn on_event(&self, pdwEffect: Option<*mut DROPEFFECT>, event: MouseEvent) { + fn on_event(&self, pdw_effect: Option<*mut DROPEFFECT>, event: MouseEvent) { let Some(window_data_ptr) = self.hwnd.get_userdata_ptr() else { return; }; @@ -59,8 +60,8 @@ impl DropTarget { _ => DROPEFFECT_NONE, }; - if let Some(pdwEffect) = pdwEffect { - unsafe { pdwEffect.write(effect) }; + if let Some(pdw_effect) = pdw_effect { + unsafe { pdw_effect.write(effect) }; } } @@ -99,7 +100,7 @@ impl DropTarget { for i in 0..item_count { let characters = DragQueryFileW(hdrop, i, null_mut(), 0); - let buffer_size = characters as usize + 1; + let buffer_size = (characters as usize).saturating_add(1); let mut buffer = vec![0u16; buffer_size]; DragQueryFileW(hdrop, i, buffer.as_mut_ptr().cast(), buffer_size as u32); @@ -112,7 +113,7 @@ impl DropTarget { } } -#[allow(non_snake_case)] +#[allow(non_snake_case, reason = "To match trait")] impl IDropTarget_Impl for DropTarget_Impl { fn DragEnter( &self, pdataobj: Ref, grfkeystate: MODIFIERKEYS_FLAGS, pt: &POINTL, diff --git a/src/platform/win/error.rs b/src/platform/win/error.rs index 5353373e..adbf71f6 100644 --- a/src/platform/win/error.rs +++ b/src/platform/win/error.rs @@ -1,42 +1,42 @@ use crate::HandlerError; use std::fmt::Display; -pub type Result = std::result::Result; +pub type Result = std::result::Result; #[derive(Debug)] -pub enum Error { +pub enum PlatformError { Win32(windows_core::Error), ResizeFailed, Handler(HandlerError), } -impl From for Error { +impl From for PlatformError { fn from(value: windows_core::Error) -> Self { - Error::Win32(value) + PlatformError::Win32(value) } } -impl From for Error { +impl From for PlatformError { fn from(value: HandlerError) -> Self { - Error::Handler(value) + PlatformError::Handler(value) } } -impl Display for Error { +impl Display for PlatformError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Error::Win32(e) => Display::fmt(e, f), - Error::Handler(e) => Display::fmt(e, f), - Error::ResizeFailed => f.write_str("Window resize request failed."), + PlatformError::Win32(e) => Display::fmt(e, f), + PlatformError::Handler(e) => Display::fmt(e, f), + PlatformError::ResizeFailed => f.write_str("Window resize request failed."), } } } -impl std::error::Error for Error { +impl std::error::Error for PlatformError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Win32(e) => Some(e), - Error::Handler(e) => Some(e.source()), + PlatformError::Win32(e) => Some(e), + PlatformError::Handler(e) => Some(e.source()), _ => None, } } diff --git a/src/platform/win/gl.rs b/src/platform/win/gl.rs index 5d125d1a..6b25edff 100644 --- a/src/platform/win/gl.rs +++ b/src/platform/win/gl.rs @@ -56,12 +56,12 @@ impl GlContextInner { Ok(Self { hdc, wgl_ctx, gl_library }) } - pub unsafe fn make_current(&self) -> Result<(), super::Error> { + pub unsafe fn make_current(&self) -> Result<(), super::PlatformError> { self.wgl_ctx.make_current(&self.hdc)?; Ok(()) } - pub unsafe fn make_not_current(&self) -> Result<(), super::Error> { + pub unsafe fn make_not_current(&self) -> Result<(), super::PlatformError> { self.wgl_ctx.make_not_current()?; Ok(()) } @@ -81,7 +81,7 @@ impl GlContextInner { core::ptr::null() } - pub fn swap_buffers(&self) -> Result<(), super::Error> { + pub fn swap_buffers(&self) -> Result<(), super::PlatformError> { self.hdc.swap_buffers()?; Ok(()) } diff --git a/src/platform/win/hook.rs b/src/platform/win/hook.rs index f74af7cc..5c491862 100644 --- a/src/platform/win/hook.rs +++ b/src/platform/win/hook.rs @@ -1,3 +1,5 @@ +#![expect(clippy::unwrap_used, reason = "To be refactored later")] + use std::{ collections::HashSet, ffi::c_int, diff --git a/src/platform/win/keyboard.rs b/src/platform/win/keyboard.rs index 6d044b1a..03411513 100644 --- a/src/platform/win/keyboard.rs +++ b/src/platform/win/keyboard.rs @@ -15,6 +15,12 @@ // Baseview modifications to druid code: // - update imports, paths etc +#![expect( + clippy::indexing_slicing, + clippy::arithmetic_side_effects, + reason = "Let's not touch this for now" +)] + //! Key event handling. use std::cmp::Ordering; @@ -598,7 +604,7 @@ impl KeyboardState { key_state[VK_LCONTROL as usize] = if has_altgr { 0x80 } else { 0 }; key_state[VK_MENU as usize] = if has_altgr { 0x80 } else { 0 }; key_state[VK_RMENU as usize] = if has_altgr { 0x80 } else { 0 }; - #[allow(clippy::iter_overeager_cloned)] + for vk in PRINTABLE_VKS.iter().cloned().flatten() { let ret = ToUnicodeEx( vk.into(), diff --git a/src/platform/win/mod.rs b/src/platform/win/mod.rs index 9f650ef8..8381bb30 100644 --- a/src/platform/win/mod.rs +++ b/src/platform/win/mod.rs @@ -7,7 +7,7 @@ mod window_state; use crate::wrappers::win32::h_instance::HInstance; use crate::wrappers::win32::window::HWnd; -pub use error::{Error, Result}; +pub use error::{PlatformError, Result}; use raw_window_handle::{ DisplayHandle, HandleError, HasWindowHandle, RawWindowHandle, Win32WindowHandle, }; @@ -68,7 +68,7 @@ impl ParentWindowHandle { h => return Err(ParentWindowHandleError::UnsupportedWindowHandleType(h)), }; - let parent = NonNull::new(parent.get() as _).unwrap(); + let Some(parent) = NonNull::new(parent.get() as _) else { unreachable!() }; Ok(Self { handle: unsafe { HWnd::from_raw(parent) } }) } diff --git a/src/platform/win/window.rs b/src/platform/win/window.rs index 7d200702..985220f8 100644 --- a/src/platform/win/window.rs +++ b/src/platform/win/window.rs @@ -27,13 +27,11 @@ use crate::wrappers::win32::{ }; use crate::{Event, MouseButton, MouseEvent, ScrollDelta, WindowEvent, WindowSize}; -#[allow(non_snake_case)] -fn HIWORD(wparam: WPARAM) -> u16 { +fn hi_word(wparam: WPARAM) -> u16 { ((wparam >> 16) & 0xffff) as u16 } -#[allow(non_snake_case)] -fn LOWORD(lparam: LPARAM) -> u16 { +fn lo_word(lparam: LPARAM) -> u16 { (lparam & 0xffff) as u16 } @@ -137,7 +135,7 @@ impl WindowHandle { let Some(mut init) = self.init.take() else { return Ok(()) }; init.settings.parent = Some(new_parent.into()); - let window = BaseviewWindow::create(self.state.clone(), init)?; + let window = BaseviewWindow::create(Rc::clone(&self.state), init)?; self.hwnd.set(Some(window)); return Ok(()); @@ -164,7 +162,7 @@ impl WindowHandle { None => { let Some(init) = self.init.take() else { return Ok(()) }; - let window = BaseviewWindow::create(self.state.clone(), init)?; + let window = BaseviewWindow::create(Rc::clone(&self.state), init)?; self.hwnd.set(Some(window)); return Ok(()); @@ -225,13 +223,13 @@ impl BaseviewWindow { let window_size = shared_state.current_size.get(); let initializer = { - let shared_state = shared_state.clone(); + let shared_state = Rc::clone(&shared_state); move |hwnd: HWnd| { let window_state = Rc::new(WindowState::new( hwnd, shared_state.user32.clone(), - shared_state.clone(), + Rc::clone(&shared_state), )); BaseviewWindow { @@ -344,8 +342,7 @@ impl WindowImpl for BaseviewWindow { #[cfg(feature = "opengl")] if let Some(gl_config) = self.gl_config.clone() { - let gl_context = gl::GlContextInner::create(window, gl_config) - .expect("Could not create OpenGL context"); + let gl_context = gl::GlContextInner::create(window, gl_config)?; let Ok(()) = self.window_state.gl_context.set(Rc::new(gl_context)) else { unreachable!(); @@ -354,7 +351,11 @@ impl WindowImpl for BaseviewWindow { let handler = { let context = crate::WindowContext::new(Rc::clone(&self.window_state)); - self.handler_builder.take().unwrap().build(context)? + let Some(handler_builder) = self.handler_builder.take() else { + unreachable!(); + }; + + handler_builder.build(context)? }; let Ok(()) = self.handler.set(handler) else { unreachable!() }; @@ -374,6 +375,7 @@ impl WindowImpl for BaseviewWindow { /// Our custom `wnd_proc` handler. If the result contains a value, then this is returned after /// handling any deferred tasks. otherwise the default window procedure is invoked. +#[allow(clippy::unwrap_used, reason = "Refactor this in a later PR")] // TODO unsafe fn wnd_proc_inner( window: HWnd, msg: u32, wparam: WPARAM, lparam: LPARAM, window_bv: &BaseviewWindow, ) -> Option { @@ -437,9 +439,8 @@ unsafe fn wnd_proc_inner( | WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => { let mut mouse_button_counter = window_state.mouse_button_counter.get(); - #[allow(non_snake_case)] - fn GET_XBUTTON_WPARAM(wparam: WPARAM) -> u16 { - HIWORD(wparam) + fn get_xbutton_wparam(wparam: WPARAM) -> u16 { + hi_word(wparam) } const XBUTTON1: u16 = 0x1; @@ -449,7 +450,7 @@ unsafe fn wnd_proc_inner( WM_LBUTTONDOWN | WM_LBUTTONUP => Some(MouseButton::Left), WM_MBUTTONDOWN | WM_MBUTTONUP => Some(MouseButton::Middle), WM_RBUTTONDOWN | WM_RBUTTONUP => Some(MouseButton::Right), - WM_XBUTTONDOWN | WM_XBUTTONUP => match GET_XBUTTON_WPARAM(wparam) { + WM_XBUTTONDOWN | WM_XBUTTONUP => match get_xbutton_wparam(wparam) { XBUTTON1 => Some(MouseButton::Back), XBUTTON2 => Some(MouseButton::Forward), _ => None, @@ -637,7 +638,7 @@ unsafe fn wnd_proc_inner( // If WM_SETCURSOR returns `None`, WM_SETCURSOR continues to get handled by the outer window(s), // If it returns `Some(1)`, the current window decides what the cursor is WM_SETCURSOR => { - let low_word = LOWORD(lparam) as u32; + let low_word = lo_word(lparam) as u32; let mouse_in_window = low_word == HTCLIENT; if mouse_in_window { // Here we need to set the cursor back to what the state says, since it can have changed when outside the window @@ -706,12 +707,12 @@ impl WindowHandle { }); } - let window = BaseviewWindow::create(shared_state.clone(), init)?; + let window = BaseviewWindow::create(Rc::clone(&shared_state), init)?; Ok(WindowHandle { hwnd: Some(window).into(), state: shared_state, init: None.into() }) } } pub fn copy_to_clipboard(_data: &str) { - todo!() + unimplemented!() } diff --git a/src/platform/win/window_state.rs b/src/platform/win/window_state.rs index b8e739de..2f96f697 100644 --- a/src/platform/win/window_state.rs +++ b/src/platform/win/window_state.rs @@ -75,12 +75,12 @@ impl WindowState { HWnd::get_focused_window() == self.hwnd.as_raw() } - pub fn focus(&self) -> Result<(), super::Error> { + pub fn focus(&self) -> Result<(), super::PlatformError> { self.hwnd.set_focus()?; Ok(()) } - pub fn resize(&self, size: Size) -> Result<(), super::Error> { + pub fn resize(&self, size: Size) -> Result<(), super::PlatformError> { // `self.window_info` will be modified in response to the `WM_SIZE` event that // follows the `SetWindowPos()` call let dpi = self.shared.current_dpi.get(); @@ -90,7 +90,7 @@ impl WindowState { Ok(()) } - pub fn set_mouse_cursor(&self, mouse_cursor: MouseCursor) -> Result<(), super::Error> { + pub fn set_mouse_cursor(&self, mouse_cursor: MouseCursor) -> Result<(), super::PlatformError> { self.cursor_icon.set(mouse_cursor); if let Ok(cursor) = SystemCursor::load(mouse_cursor) { cursor.set() diff --git a/src/wrappers.rs b/src/wrappers.rs index 7de9a42d..8db647b8 100644 --- a/src/wrappers.rs +++ b/src/wrappers.rs @@ -23,7 +23,7 @@ pub mod xkbcommon; #[cfg(all(target_os = "linux", feature = "opengl"))] pub mod glx; -/// Wrappers and utilities around the Win32 API +/// Wrappers and utilities around the Win32 API. #[cfg(target_os = "windows")] pub mod win32; diff --git a/src/wrappers/win32/dpi.rs b/src/wrappers/win32/dpi.rs index 4bc1cf3c..8c687ee8 100644 --- a/src/wrappers/win32/dpi.rs +++ b/src/wrappers/win32/dpi.rs @@ -75,10 +75,10 @@ impl<'a> DpiAwarenessContext<'a> { let result = self.client_area_to_nc_area(Rect::EMPTY, style, dpi)?; Ok(Rect(RECT { - left: rect.0.left - result.0.left, - top: rect.0.top - result.0.top, - bottom: rect.0.bottom - result.0.bottom, - right: rect.0.right - result.0.right, + left: rect.0.left.saturating_sub(result.0.left), + top: rect.0.top.saturating_sub(result.0.top), + bottom: rect.0.bottom.saturating_sub(result.0.bottom), + right: rect.0.right.saturating_sub(result.0.right), })) } } diff --git a/src/wrappers/win32/window/handle.rs b/src/wrappers/win32/window/handle.rs index 6010a458..efbbb5ba 100644 --- a/src/wrappers/win32/window/handle.rs +++ b/src/wrappers/win32/window/handle.rs @@ -161,7 +161,7 @@ impl HWnd { self.resize_nc_and_activate(rect.size()) } - /// Returns true if the window was previously visible, false otherwise + /// Returns true if the window was previously visible, false otherwise. pub fn show_and_activate(&self) -> bool { let result = unsafe { ShowWindow(self.as_raw(), SW_SHOW) }; diff --git a/src/wrappers/win32/window/wgl.rs b/src/wrappers/win32/window/wgl.rs index 90e4c612..08fd556a 100644 --- a/src/wrappers/win32/window/wgl.rs +++ b/src/wrappers/win32/window/wgl.rs @@ -1,4 +1,4 @@ -#![allow(non_snake_case)] +#![expect(non_snake_case, reason = "For Win32 constants")] use crate::gl::{GlConfig, Profile}; use crate::warn; @@ -100,6 +100,7 @@ type WglChoosePixelFormatARB = // See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_create_context.txt type WglCreateContextAttribsARB = unsafe extern "system" fn(HDC, HGLRC, *const i32) -> HGLRC; +#[allow(non_snake_case, reason = "To match the OpenGL API")] pub struct WglExtra { wglCreateContextAttribsARB: Option, wglChoosePixelFormatARB: Option, From f8ac0c76d536f63a5eaf14abbd7af5f66b1a4c6f Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 05:40:46 +0200 Subject: [PATCH 5/9] More clippy fixes --- src/tracing.rs | 8 +++----- src/wrappers.rs | 2 +- src/wrappers/glx.rs | 6 +++--- src/wrappers/xlib/error_handler.rs | 4 ++-- src/wrappers/xlib/xlib_connection.rs | 7 ++++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/tracing.rs b/src/tracing.rs index 7fbb6717..4540129a 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,8 +1,7 @@ -#[cfg(feature = "tracing")] -pub use tracing::warn; +#![allow(unused, reason = "Some platform may not use all macros")] -#[cfg(all(feature = "tracing", not(target_os = "macos")))] -pub use tracing::error; +#[cfg(feature = "tracing")] +pub use tracing::{error, warn}; #[cfg(not(feature = "tracing"))] mod tracing_impl { @@ -15,7 +14,6 @@ mod tracing_impl { } pub(crate) use __warn as warn; - #[cfg(target_os = "macos")] pub(crate) use __warn as error; } diff --git a/src/wrappers.rs b/src/wrappers.rs index 8db647b8..570c0588 100644 --- a/src/wrappers.rs +++ b/src/wrappers.rs @@ -19,7 +19,7 @@ pub mod xlib; #[cfg(target_os = "linux")] pub mod xkbcommon; -/// Wrappers and utilities around GLX +/// Wrappers and utilities around GLX. #[cfg(all(target_os = "linux", feature = "opengl"))] pub mod glx; diff --git a/src/wrappers/glx.rs b/src/wrappers/glx.rs index 34e39312..6368ca74 100644 --- a/src/wrappers/glx.rs +++ b/src/wrappers/glx.rs @@ -10,7 +10,7 @@ use x11_dl::glx::{arb::*, *}; use x11_dl::xlib; use x11_dl::xlib::XVisualInfo; -/// See https://www.khronos.org/registry/OpenGL/extensions/ARB/GLX_ARB_create_context.txt +/// See https://www.khronos.org/registry/OpenGL/extensions/ARB/GLX_ARB_create_context.txt. type GlXCreateContextAttribsARB = unsafe extern "C" fn( dpy: *mut xlib::Display, fbc: GLXFBConfig, @@ -19,11 +19,11 @@ type GlXCreateContextAttribsARB = unsafe extern "C" fn( attribs: *const c_int, ) -> GLXContext; -/// See https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_swap_control.txt +/// See https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_swap_control.txt. type GlXSwapIntervalEXT = unsafe extern "C" fn(dpy: *mut xlib::Display, drawable: GLXDrawable, interval: i32); -/// See https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_framebuffer_sRGB.txt +/// See https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_framebuffer_sRGB.txt. const GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB: i32 = 0x20B2; pub struct Glx { diff --git a/src/wrappers/xlib/error_handler.rs b/src/wrappers/xlib/error_handler.rs index 6261248a..2afd163d 100644 --- a/src/wrappers/xlib/error_handler.rs +++ b/src/wrappers/xlib/error_handler.rs @@ -14,14 +14,14 @@ thread_local! { static CURRENT_X11_ERROR: Cell> = const { Cell::new(None) }; } -/// A helper struct for safe X11 error handling +/// A helper struct for safe X11 error handling. pub struct XErrorHandler<'a> { conn: &'a XlibConnection, error: &'a Cell>, } impl<'a> XErrorHandler<'a> { - /// Syncs and checks if any previous X11 calls from the given display returned an error + /// Syncs and checks if any previous X11 calls from the given display returned an error. pub fn check(&self) -> Result<(), XLibError> { // Flush all possible previous errors self.conn.sync(); diff --git a/src/wrappers/xlib/xlib_connection.rs b/src/wrappers/xlib/xlib_connection.rs index b1f831fc..afdffd0b 100644 --- a/src/wrappers/xlib/xlib_connection.rs +++ b/src/wrappers/xlib/xlib_connection.rs @@ -109,7 +109,7 @@ impl XlibConnection { &self.xlib } - /// Calls XSync(0) + /// Calls XSync(0). pub fn sync(&self) { // SAFETY: This type ensures the display pointer is always valid. unsafe { (self.xlib.XSync)(self.display.as_ptr(), 0) }; @@ -121,7 +121,7 @@ impl XlibConnection { } // PANIC: we just checked above that buf.len > 0 - let buf_len = buf.len() - 1; + let Some(buf_len) = buf.len().checked_sub(1) else { unreachable!() }; let Ok(buf_len) = buf_len.try_into() else { // Buffers should never get that big, something went horribly wrong. return c""; @@ -139,7 +139,8 @@ impl XlibConnection { }; // PANIC: we checked above that buf.len > 0 - *buf.last_mut().unwrap() = 0; + let Some(last_byte) = buf.last_mut() else { unreachable!() }; + *last_byte = 0; // SAFETY: whatever XGetErrorText did or not, we guaranteed there is a nul byte at the end of the buffer unsafe { CStr::from_ptr(buf.as_mut_ptr().cast()) } From 5ce5dd6d9e717177a184e293c50cdfd318fc605b Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 05:44:54 +0200 Subject: [PATCH 6/9] More clippy fixes --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 1a4362ac..26992857 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub use mouse_cursor::MouseCursor; pub use settings::*; pub use window::*; +#[allow(unused, reason = "")] pub(crate) use tracing::*; mod utils; From 46f1e8c23653365fc4a9ba3f124327dee0d4c409 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 05:52:38 +0200 Subject: [PATCH 7/9] Keep lints to main crate for now --- Cargo.toml | 5 +---- examples/open_parented/Cargo.toml | 3 --- examples/open_window/Cargo.toml | 2 -- examples/plugin_clack/Cargo.toml | 3 --- examples/render_femtovg/Cargo.toml | 2 -- examples/render_wgpu/Cargo.toml | 3 --- 6 files changed, 1 insertion(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index def39a29..acc7bdcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,10 +94,7 @@ objc2-app-kit = { version = "0.3.2", default-features = false, features = [ [workspace] members = ["examples/open_parented", "examples/open_window", "examples/plugin_clack", "examples/render_femtovg", "examples/render_wgpu"] -[lints] -workspace = true - -[workspace.lints.clippy] +[lints.clippy] missing-safety-doc = "allow" allow-attributes-without-reason = "warn" diff --git a/examples/open_parented/Cargo.toml b/examples/open_parented/Cargo.toml index a87bf274..2569efda 100644 --- a/examples/open_parented/Cargo.toml +++ b/examples/open_parented/Cargo.toml @@ -7,6 +7,3 @@ publish = false [dependencies] baseview = { path = "../.." } softbuffer = "0.4.8" - -[lints] -workspace = true diff --git a/examples/open_window/Cargo.toml b/examples/open_window/Cargo.toml index 50750950..682fc044 100644 --- a/examples/open_window/Cargo.toml +++ b/examples/open_window/Cargo.toml @@ -9,5 +9,3 @@ baseview = { path = "../.." } softbuffer = "0.4.8" rtrb = "0.3.4" -[lints] -workspace = true diff --git a/examples/plugin_clack/Cargo.toml b/examples/plugin_clack/Cargo.toml index b6f40883..32cf7676 100644 --- a/examples/plugin_clack/Cargo.toml +++ b/examples/plugin_clack/Cargo.toml @@ -13,6 +13,3 @@ baseview = { path = "../..", features = ["opengl"] } softbuffer = "0.4.8" raw-window-handle = "0.6.2" -[lints] -workspace = true - diff --git a/examples/render_femtovg/Cargo.toml b/examples/render_femtovg/Cargo.toml index 6796f172..01bb10c0 100644 --- a/examples/render_femtovg/Cargo.toml +++ b/examples/render_femtovg/Cargo.toml @@ -9,5 +9,3 @@ baseview = { path = "../..", features = ["opengl", "tracing"] } femtovg = "0.25.1" tracing-subscriber = { workspace = true } -[lints] -workspace = true diff --git a/examples/render_wgpu/Cargo.toml b/examples/render_wgpu/Cargo.toml index 493adb9f..1485adb6 100644 --- a/examples/render_wgpu/Cargo.toml +++ b/examples/render_wgpu/Cargo.toml @@ -10,6 +10,3 @@ wgpu = "30.0.0" env_logger = "0.11.11" log = "0.4.33" pollster = "0.4.0" - -[lints] -workspace = true From f7404d17a311eb052a14c7c85cebee353534f72f Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 18 Aug 2026 08:41:21 +0200 Subject: [PATCH 8/9] cleanup --- src/lib.rs | 2 +- src/platform/x11/visibility_tree.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 26992857..737c1d91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub use mouse_cursor::MouseCursor; pub use settings::*; pub use window::*; -#[allow(unused, reason = "")] +#[allow(unused, reason = "Some platforms may not use all exports from this mod")] pub(crate) use tracing::*; mod utils; diff --git a/src/platform/x11/visibility_tree.rs b/src/platform/x11/visibility_tree.rs index ef51d32a..d44545b4 100644 --- a/src/platform/x11/visibility_tree.rs +++ b/src/platform/x11/visibility_tree.rs @@ -5,13 +5,11 @@ use x11rb::protocol::ErrorKind; use x11rb::x11_utils::X11Error; use x11rb::xcb_ffi::XCBConnection; -#[cfg_attr(debug_assertions, derive(Debug))] pub struct AncestorVisibilityState { ancestry: AncestryList, own_window_viewable: Cell, } -#[cfg_attr(debug_assertions, derive(Debug))] struct AncestryList { inner: RefCell>, } From 35f14382bc55974d4951f8cfbd77046e813df511 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Wed, 19 Aug 2026 05:21:06 +0200 Subject: [PATCH 9/9] Cleanup --- examples/open_window/Cargo.toml | 1 - examples/plugin_clack/src/audio.rs | 4 +--- examples/render_femtovg/Cargo.toml | 1 - src/platform/macos/cursor.rs | 7 +------ 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/examples/open_window/Cargo.toml b/examples/open_window/Cargo.toml index 682fc044..34ad3b83 100644 --- a/examples/open_window/Cargo.toml +++ b/examples/open_window/Cargo.toml @@ -8,4 +8,3 @@ publish = false baseview = { path = "../.." } softbuffer = "0.4.8" rtrb = "0.3.4" - diff --git a/examples/plugin_clack/src/audio.rs b/examples/plugin_clack/src/audio.rs index 2b91aae1..b3e34ee4 100644 --- a/examples/plugin_clack/src/audio.rs +++ b/examples/plugin_clack/src/audio.rs @@ -15,9 +15,7 @@ impl<'a> PluginAudioProcessor<'a, (), ExamplePluginMainThread<'a>> for ExamplePl &mut self, _process: Process, mut audio: Audio, _events: Events, ) -> Result { for mut port in audio.port_pairs() { - let Some(channels) = port.channels()?.into_f32() else { - panic!("Expected f32 channels"); - }; + let channels = port.channels()?.into_f32().expect("Expected f32 channels"); for channel_pair in channels { match channel_pair { diff --git a/examples/render_femtovg/Cargo.toml b/examples/render_femtovg/Cargo.toml index 01bb10c0..72b19485 100644 --- a/examples/render_femtovg/Cargo.toml +++ b/examples/render_femtovg/Cargo.toml @@ -8,4 +8,3 @@ publish = false baseview = { path = "../..", features = ["opengl", "tracing"] } femtovg = "0.25.1" tracing-subscriber = { workspace = true } - diff --git a/src/platform/macos/cursor.rs b/src/platform/macos/cursor.rs index c4ec551c..263cbcb5 100644 --- a/src/platform/macos/cursor.rs +++ b/src/platform/macos/cursor.rs @@ -12,6 +12,7 @@ pub enum Cursor { } impl From for Cursor { + #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] fn from(cursor: MouseCursor) -> Self { match cursor { MouseCursor::Default => Cursor::Native(NSCursor::arrowCursor), @@ -25,19 +26,13 @@ impl From for Cursor { Cursor::Native(NSCursor::operationNotAllowedCursor) } MouseCursor::Crosshair => Cursor::Native(NSCursor::crosshairCursor), - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::EResize => Cursor::Native(NSCursor::resizeRightCursor), - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::NResize => Cursor::Native(NSCursor::resizeUpCursor), - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::WResize => Cursor::Native(NSCursor::resizeLeftCursor), - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::SResize => Cursor::Native(NSCursor::resizeDownCursor), - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::EwResize | MouseCursor::ColResize => { Cursor::Native(NSCursor::resizeLeftRightCursor) } - #[expect(deprecated, reason = "TODO: resize curosrs are deprecated")] MouseCursor::NsResize | MouseCursor::RowResize => { Cursor::Native(NSCursor::resizeUpDownCursor) }