From 2998bbf7db988a4f7c7dd2edce45ee9d9ea57a09 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 29 Dec 2023 22:04:27 -0800 Subject: [PATCH] On X11, cache the XRandR extension version --- src/platform_impl/linux/x11/monitor.rs | 8 ++++---- src/platform_impl/linux/x11/xdisplay.rs | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/platform_impl/linux/x11/monitor.rs b/src/platform_impl/linux/x11/monitor.rs index 17ea959eec..738744da6c 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -234,7 +234,8 @@ impl XConnection { fn query_monitor_list(&self) -> Result, X11Error> { let root = self.default_root(); - let resources = ScreenResources::from_connection(self.xcb_connection(), root)?; + let resources = + ScreenResources::from_connection(self.xcb_connection(), root, self.randr_version())?; // Pipeline all of the get-crtc requests. let mut crtc_cookies = Vec::with_capacity(resources.crtcs().len()); @@ -343,10 +344,9 @@ impl ScreenResources { pub(crate) fn from_connection( conn: &impl x11rb::connection::Connection, root: &x11rb::protocol::xproto::Screen, + (major_version, minor_version): (u32, u32), ) -> Result { - let version = conn.randr_query_version(1, 3)?.reply()?; - - if (version.major_version == 1 && version.minor_version >= 3) || version.major_version > 1 { + if (major_version == 1 && minor_version >= 3) || major_version > 1 { let reply = conn .randr_get_screen_resources_current(root.root)? .reply()?; diff --git a/src/platform_impl/linux/x11/xdisplay.rs b/src/platform_impl/linux/x11/xdisplay.rs index e4978f3814..02fb5ecd09 100644 --- a/src/platform_impl/linux/x11/xdisplay.rs +++ b/src/platform_impl/linux/x11/xdisplay.rs @@ -11,7 +11,12 @@ use std::{ use crate::window::CursorIcon; use super::{atoms::Atoms, ffi, monitor::MonitorHandle}; -use x11rb::{connection::Connection, protocol::xproto, resource_manager, xcb_ffi::XCBConnection}; +use x11rb::{ + connection::Connection, + protocol::{randr::ConnectionExt as _, xproto}, + resource_manager, + xcb_ffi::XCBConnection, +}; /// A connection to an X server. pub(crate) struct XConnection { @@ -47,6 +52,9 @@ pub(crate) struct XConnection { /// The resource database. database: RwLock, + /// RandR version. + randr_version: (u32, u32), + pub latest_error: Mutex>, pub cursor_cache: Mutex, ffi::Cursor>>, } @@ -104,6 +112,13 @@ impl XConnection { let database = resource_manager::new_from_default(&xcb) .map_err(|e| XNotSupported::XcbConversionError(Arc::new(e)))?; + // Load the RandR version. + let randr_version = xcb + .randr_query_version(1, 3) + .expect("failed to request XRandR version") + .reply() + .expect("failed to query XRandR version"); + Ok(XConnection { xlib, xcursor, @@ -117,6 +132,7 @@ impl XConnection { monitor_handles: Mutex::new(None), database: RwLock::new(database), cursor_cache: Default::default(), + randr_version: (randr_version.major_version, randr_version.minor_version), }) } @@ -131,6 +147,11 @@ impl XConnection { } } + #[inline] + pub fn randr_version(&self) -> (u32, u32) { + self.randr_version + } + /// Get the underlying XCB connection. #[inline] pub fn xcb_connection(&self) -> &XCBConnection {