From 385ba6bf3a37ebf462cacdfb46501b7e6170570f Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz Date: Wed, 27 Mar 2024 19:20:40 +0100 Subject: [PATCH] wip --- src/x11/visual_info.rs | 2 +- src/x11/window.rs | 25 +++++++++++++------------ src/x11/xcb_connection.rs | 13 +++++++++---- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/x11/visual_info.rs b/src/x11/visual_info.rs index 602b2f0..3f1be38 100644 --- a/src/x11/visual_info.rs +++ b/src/x11/visual_info.rs @@ -63,7 +63,7 @@ impl WindowVisualConfig { // For this 32-bit depth to work, you also need to define a color map and set a border // pixel: https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c#n818 -pub fn create_color_map( +fn create_color_map( connection: &XcbConnection, visual_id: Visualid, ) -> Result> { let colormap = connection.conn.generate_id()?; diff --git a/src/x11/window.rs b/src/x11/window.rs index 86af03c..7658d7e 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -1,3 +1,4 @@ +use std::cell::Cell; use std::error::Error; use std::ffi::c_void; use std::os::fd::AsRawFd; @@ -101,11 +102,11 @@ struct WindowInner { window_id: XWindow, window_info: WindowInfo, visual_id: Visualid, - mouse_cursor: MouseCursor, + mouse_cursor: Cell, frame_interval: Duration, event_loop_running: bool, - close_requested: bool, + close_requested: Cell, new_physical_size: Option, parent_handle: Option, @@ -115,7 +116,7 @@ struct WindowInner { } pub struct Window<'a> { - inner: &'a mut WindowInner, + inner: &'a WindowInner, } // Hack to allow sending a RawWindowHandle between threads. Do not make public @@ -284,11 +285,11 @@ impl<'a> Window<'a> { window_id, window_info, visual_id: visual_info.visual_id, - mouse_cursor: MouseCursor::default(), + mouse_cursor: Cell::new(MouseCursor::default()), frame_interval: Duration::from_millis(15), event_loop_running: false, - close_requested: false, + close_requested: Cell::new(false), new_physical_size: None, parent_handle, @@ -312,8 +313,8 @@ impl<'a> Window<'a> { Ok(()) } - pub fn set_mouse_cursor(&mut self, mouse_cursor: MouseCursor) { - if self.inner.mouse_cursor == mouse_cursor { + pub fn set_mouse_cursor(&self, mouse_cursor: MouseCursor) { + if self.inner.mouse_cursor.get() == mouse_cursor { return; } @@ -327,11 +328,11 @@ impl<'a> Window<'a> { let _ = self.inner.xcb_connection.conn.flush(); } - self.inner.mouse_cursor = mouse_cursor; + self.inner.mouse_cursor.set(mouse_cursor); } pub fn close(&mut self) { - self.inner.close_requested = true; + self.inner.close_requested.set(true); } pub fn has_focus(&mut self) -> bool { @@ -444,14 +445,14 @@ impl WindowInner { if let Some(parent_handle) = &self.parent_handle { if parent_handle.parent_did_drop() { self.handle_must_close(handler); - self.close_requested = false; + self.close_requested.set(false); } } // Check if the user has requested the window to close - if self.close_requested { + if self.close_requested.get() { self.handle_must_close(handler); - self.close_requested = false; + self.close_requested.set(false); } } diff --git a/src/x11/xcb_connection.rs b/src/x11/xcb_connection.rs index b7ca188..518ed54 100644 --- a/src/x11/xcb_connection.rs +++ b/src/x11/xcb_connection.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use std::collections::hash_map::{Entry, HashMap}; use std::error::Error; @@ -30,7 +31,7 @@ pub struct XcbConnection { pub(crate) atoms: Atoms, pub(crate) resources: resource_manager::Database, pub(crate) cursor_handle: CursorHandle, - pub(super) cursor_cache: HashMap, + pub(super) cursor_cache: RefCell>, } impl XcbConnection { @@ -56,7 +57,7 @@ impl XcbConnection { atoms, resources, cursor_handle, - cursor_cache: HashMap::new(), + cursor_cache: RefCell::new(HashMap::new()), }) } @@ -103,8 +104,12 @@ impl XcbConnection { } #[inline] - pub fn get_cursor(&mut self, cursor: MouseCursor) -> Result> { - match self.cursor_cache.entry(cursor) { + pub fn get_cursor(&self, cursor: MouseCursor) -> Result> { + // PANIC: this function is the only point where we access the cache, and we never call + // external functions that may make a reentrant call to this function + let mut cursor_cache = self.cursor_cache.borrow_mut(); + + match cursor_cache.entry(cursor) { Entry::Occupied(entry) => Ok(*entry.get()), Entry::Vacant(entry) => { let cursor =