Skip to content

Commit

Permalink
improve x11 startup times
Browse files Browse the repository at this point in the history
related issue: #5802

requesting `GetScreenResourcesCurrent` instead of `GetScreenResources`
brings startup times down from 1.5 seconds to 30 microseconds on my
machine (measured with dumb printlns).

according to some findings `GetScreenResourcesCurrent` may return
nothing, so i kept `GetScreenResources` there as a fallback, just in
case, although I'm not 100% sure that it's necessary. see:
- https://github.com/qt/qtbase/blob/c234700c836777d08db6229fdc997cc7c99e45fb/src/plugins/platforms/xcb/qxcbscreen.cpp#L963
- https://github.com/qt/qtbase/blob/c234700c836777d08db6229fdc997cc7c99e45fb/src/plugins/platforms/xcb/qxcbconnection_screens.cpp#L390

also worth to note that i3 does not rely on
`xcb_randr_get_screen_resources`, but only on
`xcb_randr_get_screen_resources_current`, see:
- https://github.com/search?q=repo%3Ai3%2Fi3%20get_screen_resources&type=code
  • Loading branch information
blukai committed Aug 10, 2024
1 parent 56a27e9 commit f5a3290
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions window/src/os/x11/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ use x11::xlib;
use xcb::x::Atom;
use xcb::{dri2, Raw, Xid};

enum ScreenResources {
Current(xcb::randr::GetScreenResourcesCurrentReply),
All(xcb::randr::GetScreenResourcesReply),
}

impl ScreenResources {
fn outputs(&self) -> &[xcb::randr::Output] {
match self {
Self::Current(cur) => cur.outputs(),
Self::All(all) => all.outputs(),
}
}

fn config_timestamp(&self) -> xcb::x::Timestamp {
match self {
Self::Current(cur) => cur.config_timestamp(),
Self::All(all) => all.config_timestamp(),
}
}

pub fn modes(&self) -> &[xcb::randr::ModeInfo] {
match self {
Self::Current(cur) => cur.modes(),
Self::All(all) => all.modes(),
}
}
}

pub struct XConnection {
pub conn: xcb::Connection,
default_dpi: RefCell<f64>,
Expand Down Expand Up @@ -236,9 +264,24 @@ impl ConnectionOps for XConnection {

let config = config::configuration();

let res = self
.send_and_wait_request(&xcb::randr::GetScreenResources { window: self.root })
.context("get_screen_resources")?;
// NOTE: GetScreenResourcesCurrent is fast, but may sometimes return nothing. In this case,
// fallback to slow GetScreenResources.
//
// references:
// - https://github.com/qt/qtbase/blob/c234700c836777d08db6229fdc997cc7c99e45fb/src/plugins/platforms/xcb/qxcbscreen.cpp#L963
// - https://github.com/qt/qtbase/blob/c234700c836777d08db6229fdc997cc7c99e45fb/src/plugins/platforms/xcb/qxcbconnection_screens.cpp#L390
//
// related issue: https://github.com/wez/wezterm/issues/5802
let res = match self
.send_and_wait_request(&xcb::randr::GetScreenResourcesCurrent { window: self.root })
.context("get_screen_resources_current")
{
Ok(cur) if cur.outputs().len() > 0 => ScreenResources::Current(cur),
_ => ScreenResources::All(
self.send_and_wait_request(&xcb::randr::GetScreenResources { window: self.root })
.context("get_screen_resources")?,
),
};

let mut virtual_rect: ScreenRect = euclid::rect(0, 0, 0, 0);
let mut by_name = HashMap::new();
Expand Down

0 comments on commit f5a3290

Please sign in to comment.