1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

x11: respect config.dpi_by_screen

Maintain a cache of the positions of the various named screens,
and use that to resolve the screen of the current window, and
from there we can resolve the correct dpi_by_screen screen.

Make dpi and dpi_by_screen config changes generate a resize
event with the updated dpi.

refs: #4096
This commit is contained in:
Wez Furlong 2023-08-05 22:25:06 -07:00
parent f7f253ec28
commit ede7e846f4
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
2 changed files with 77 additions and 2 deletions

View File

@ -63,6 +63,7 @@ pub struct XConnection {
pub(crate) has_randr: bool,
pub(crate) atom_names: RefCell<HashMap<Atom, String>>,
pub(crate) supported: RefCell<HashSet<Atom>>,
pub(crate) screens: RefCell<Option<Screens>>,
}
impl std::ops::Deref for XConnection {
@ -481,6 +482,21 @@ impl XConnection {
}
}
pub(crate) fn get_cached_screens(&self) -> anyhow::Result<Screens> {
{
let screens = self.screens.borrow();
if let Some(cached) = screens.as_ref() {
return Ok(cached.clone());
}
}
let screens = self.screens()?;
self.screens.borrow_mut().replace(screens.clone());
Ok(screens)
}
fn process_xcb_event(&self, event: &xcb::Event) -> anyhow::Result<()> {
match event {
// Following stuff is not obvious at all.
@ -497,6 +513,11 @@ impl XConnection {
xcb::Event::Dri2(dri2::Event::InvalidateBuffers(ev)) => unsafe {
self.rewire_event(ev.as_raw())
},
xcb::Event::RandR(randr) => {
log::trace!("{randr:?}");
// Clear our cache
self.screens.borrow_mut().take();
}
_ => {}
}
@ -651,6 +672,16 @@ impl XConnection {
let root = screen.root();
if has_randr {
conn.check_request(conn.send_request_checked(&xcb::randr::SelectInput {
window: root,
enable: xcb::randr::NotifyMask::SCREEN_CHANGE
| xcb::randr::NotifyMask::PROVIDER_CHANGE
| xcb::randr::NotifyMask::RESOURCE_CHANGE,
}))
.context("XRANDR::SelectInput")?;
}
let xrm =
crate::x11::xrm::parse_root_resource_manager(&conn, root).unwrap_or(HashMap::new());
@ -723,6 +754,7 @@ impl XConnection {
has_randr,
atom_names: RefCell::new(HashMap::new()),
supported: RefCell::new(HashSet::new()),
screens: RefCell::new(None),
});
{

View File

@ -5,7 +5,8 @@ use crate::os::{xkeysyms, Connection, Window};
use crate::{
Appearance, Clipboard, DeadKeyStatus, Dimensions, MouseButtons, MouseCursor, MouseEvent,
MouseEventKind, MousePress, Point, Rect, RequestedWindowGeometry, ResolvedGeometry,
ScreenPoint, WindowDecorations, WindowEvent, WindowEventSender, WindowOps, WindowState,
ScreenPoint, ScreenRect, WindowDecorations, WindowEvent, WindowEventSender, WindowOps,
WindowState,
};
use anyhow::{anyhow, Context as _};
use async_trait::async_trait;
@ -427,7 +428,43 @@ impl XWindowInner {
let conn = self.conn();
self.update_ime_position();
let dpi = conn.default_dpi();
let mut dpi = conn.default_dpi();
if !self.config.dpi_by_screen.is_empty() {
let coords = conn
.send_and_wait_request(&xcb::x::TranslateCoordinates {
src_window: self.window_id,
dst_window: conn.root,
src_x: 0,
src_y: 0,
})
.context("querying window coordinates")?;
let screens = conn.get_cached_screens()?;
let window_rect: ScreenRect = euclid::rect(
coords.dst_x().into(),
coords.dst_y().into(),
width as isize,
height as isize,
);
let screen = screens
.by_name
.values()
.filter_map(|screen| {
screen
.rect
.intersection(&window_rect)
.map(|r| (screen, r.area()))
})
.max_by_key(|s| s.1)
.ok_or_else(|| anyhow::anyhow!("window is not in any screen"))?
.0;
if let Some(value) = self.config.dpi_by_screen.get(&screen.name).copied() {
dpi = value;
} else if let Some(value) = self.config.dpi {
dpi = value;
}
}
if width == self.width && height == self.height && dpi == self.dpi {
// Effectively unchanged; perhaps it was simply moved?
@ -1306,8 +1343,14 @@ impl XWindowInner {
}
fn config_did_change(&mut self, config: &ConfigHandle) {
let dpi_changed =
self.config.dpi != config.dpi || self.config.dpi_by_screen != config.dpi_by_screen;
self.config = config.clone();
let _ = self.adjust_decorations(config.window_decorations);
if dpi_changed {
let _ = self.configure_notify("config reload", self.width, self.height);
}
}
fn net_wm_moveresize(&mut self, x_root: u32, y_root: u32, direction: u32, button: u32) {