mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-02 06:40:06 -04:00
bugfix(x11): crash when querying xsettings prop fails
Don't crash when xsettings query fails with _present_ xsettings. Closes: https://github.com/rust-windowing/winit/issues/3573
This commit is contained in:
@@ -11,6 +11,8 @@ Unreleased` header.
|
|||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- On X11, fix crash due to xsettings query on systems with incomplete xsettings.
|
||||||
|
|
||||||
# 0.29.14
|
# 0.29.14
|
||||||
|
|
||||||
- On X11/Wayland, fix `text` and `text_with_all_modifiers` not being `None` during compose.
|
- On X11/Wayland, fix `text` and `text_with_all_modifiers` not being `None` during compose.
|
||||||
|
|||||||
@@ -891,6 +891,9 @@ pub enum X11Error {
|
|||||||
|
|
||||||
/// Unable to parse xsettings.
|
/// Unable to parse xsettings.
|
||||||
XsettingsParse(xsettings::ParserError),
|
XsettingsParse(xsettings::ParserError),
|
||||||
|
|
||||||
|
/// Failed to get property.
|
||||||
|
GetProperty(util::GetPropertyError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for X11Error {
|
impl fmt::Display for X11Error {
|
||||||
@@ -900,6 +903,7 @@ impl fmt::Display for X11Error {
|
|||||||
X11Error::Connect(e) => write!(f, "X11 connection error: {}", e),
|
X11Error::Connect(e) => write!(f, "X11 connection error: {}", e),
|
||||||
X11Error::Connection(e) => write!(f, "X11 connection error: {}", e),
|
X11Error::Connection(e) => write!(f, "X11 connection error: {}", e),
|
||||||
X11Error::XidsExhausted(e) => write!(f, "XID range exhausted: {}", e),
|
X11Error::XidsExhausted(e) => write!(f, "XID range exhausted: {}", e),
|
||||||
|
X11Error::GetProperty(e) => write!(f, "Failed to get X property {}", e),
|
||||||
X11Error::X11(e) => write!(f, "X11 error: {:?}", e),
|
X11Error::X11(e) => write!(f, "X11 error: {:?}", e),
|
||||||
X11Error::UnexpectedNull(s) => write!(f, "Xlib function returned null: {}", s),
|
X11Error::UnexpectedNull(s) => write!(f, "Xlib function returned null: {}", s),
|
||||||
X11Error::InvalidActivationToken(s) => write!(
|
X11Error::InvalidActivationToken(s) => write!(
|
||||||
@@ -992,6 +996,12 @@ impl From<xsettings::ParserError> for X11Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<util::GetPropertyError> for X11Error {
|
||||||
|
fn from(value: util::GetPropertyError) -> Self {
|
||||||
|
Self::GetProperty(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Type alias for a void cookie.
|
/// Type alias for a void cookie.
|
||||||
type VoidCookie<'a> = x11rb::cookie::VoidCookie<'a, X11rbConnection>;
|
type VoidCookie<'a> = x11rb::cookie::VoidCookie<'a, X11rbConnection>;
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ impl XConnection {
|
|||||||
.get_string("Xft.dpi", "")
|
.get_string("Xft.dpi", "")
|
||||||
.and_then(|s| f64::from_str(s).ok())
|
.and_then(|s| f64::from_str(s).ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_info(
|
pub fn get_output_info(
|
||||||
&self,
|
&self,
|
||||||
resources: &monitor::ScreenResources,
|
resources: &monitor::ScreenResources,
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
use super::*;
|
use std::error::Error;
|
||||||
use bytemuck::{NoUninit, Pod};
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use bytemuck::{NoUninit, Pod};
|
||||||
|
|
||||||
use x11rb::connection::Connection;
|
use x11rb::connection::Connection;
|
||||||
use x11rb::errors::ReplyError;
|
use x11rb::errors::ReplyError;
|
||||||
|
|
||||||
pub type Cardinal = u32;
|
use super::*;
|
||||||
|
|
||||||
pub const CARDINAL_SIZE: usize = mem::size_of::<u32>();
|
pub const CARDINAL_SIZE: usize = mem::size_of::<u32>();
|
||||||
|
|
||||||
|
pub type Cardinal = u32;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum GetPropertyError {
|
pub enum GetPropertyError {
|
||||||
X11rbError(Arc<ReplyError>),
|
X11rbError(Arc<ReplyError>),
|
||||||
@@ -15,12 +20,6 @@ pub enum GetPropertyError {
|
|||||||
FormatMismatch(c_int),
|
FormatMismatch(c_int),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<ReplyError>> From<T> for GetPropertyError {
|
|
||||||
fn from(e: T) -> Self {
|
|
||||||
Self::X11rbError(Arc::new(e.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetPropertyError {
|
impl GetPropertyError {
|
||||||
pub fn is_actual_property_type(&self, t: xproto::Atom) -> bool {
|
pub fn is_actual_property_type(&self, t: xproto::Atom) -> bool {
|
||||||
if let GetPropertyError::TypeMismatch(actual_type) = *self {
|
if let GetPropertyError::TypeMismatch(actual_type) = *self {
|
||||||
@@ -31,6 +30,24 @@ impl GetPropertyError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Into<ReplyError>> From<T> for GetPropertyError {
|
||||||
|
fn from(e: T) -> Self {
|
||||||
|
Self::X11rbError(Arc::new(e.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for GetPropertyError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
GetPropertyError::X11rbError(err) => err.fmt(f),
|
||||||
|
GetPropertyError::TypeMismatch(err) => write!(f, "type mismatch: {err}"),
|
||||||
|
GetPropertyError::FormatMismatch(err) => write!(f, "format mismatch: {err}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for GetPropertyError {}
|
||||||
|
|
||||||
// Number of 32-bit chunks to retrieve per iteration of get_property's inner loop.
|
// Number of 32-bit chunks to retrieve per iteration of get_property's inner loop.
|
||||||
// To test if `get_property` works correctly, set this to 1.
|
// To test if `get_property` works correctly, set this to 1.
|
||||||
const PROPERTY_BUFFER_SIZE: u32 = 1024; // 4k of RAM ought to be enough for anyone!
|
const PROPERTY_BUFFER_SIZE: u32 = 1024; // 4k of RAM ought to be enough for anyone!
|
||||||
|
|||||||
@@ -33,13 +33,11 @@ impl XConnection {
|
|||||||
.reply()?;
|
.reply()?;
|
||||||
|
|
||||||
// Read the _XSETTINGS_SETTINGS property.
|
// Read the _XSETTINGS_SETTINGS property.
|
||||||
let data: Vec<u8> = self
|
let data: Vec<u8> = self.get_property(
|
||||||
.get_property(
|
owner.owner,
|
||||||
owner.owner,
|
atoms[_XSETTINGS_SETTINGS],
|
||||||
atoms[_XSETTINGS_SETTINGS],
|
atoms[_XSETTINGS_SETTINGS],
|
||||||
atoms[_XSETTINGS_SETTINGS],
|
)?;
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Parse the property.
|
// Parse the property.
|
||||||
let dpi_setting = read_settings(&data)?
|
let dpi_setting = read_settings(&data)?
|
||||||
|
|||||||
Reference in New Issue
Block a user