mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
Use smithay-client-toolkit's dpi handling. (#724)
* Use smithay-client-toolkit's dpi handling. * Add CHANGELOG entry.
This commit is contained in:
parent
cb0a085968
commit
fd349f1822
|
@ -10,6 +10,7 @@
|
||||||
- Derive `Ord` and `PartialOrd` for `VirtualKeyCode` enum.
|
- Derive `Ord` and `PartialOrd` for `VirtualKeyCode` enum.
|
||||||
- On Windows, fix issue where hovering or dropping a non file item would create a panic.
|
- On Windows, fix issue where hovering or dropping a non file item would create a panic.
|
||||||
- On Wayland, fix resizing and DPI calculation when a `wl_output` is removed without sending a `leave` event to the `wl_surface`, such as disconnecting a monitor from a laptop.
|
- On Wayland, fix resizing and DPI calculation when a `wl_output` is removed without sending a `leave` event to the `wl_surface`, such as disconnecting a monitor from a laptop.
|
||||||
|
- On Wayland, DPI calculation is handled by smithay-client-toolkit.
|
||||||
- On X11, `WindowBuilder::with_min_dimensions` and `WindowBuilder::with_max_dimensions` now correctly account for DPI.
|
- On X11, `WindowBuilder::with_min_dimensions` and `WindowBuilder::with_max_dimensions` now correctly account for DPI.
|
||||||
|
|
||||||
# Version 0.18.0 (2018-11-07)
|
# Version 0.18.0 (2018-11-07)
|
||||||
|
|
|
@ -63,7 +63,7 @@ features = [
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
|
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
|
||||||
wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] }
|
wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] }
|
||||||
smithay-client-toolkit = "0.4"
|
smithay-client-toolkit = "0.4.3"
|
||||||
x11-dl = "2.18.3"
|
x11-dl = "2.18.3"
|
||||||
parking_lot = "0.6"
|
parking_lot = "0.6"
|
||||||
percent-encoding = "1.0"
|
percent-encoding = "1.0"
|
||||||
|
|
|
@ -123,8 +123,6 @@ impl EventsLoop {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let cb_store = store.clone();
|
|
||||||
|
|
||||||
let env = Environment::from_display_with_cb(
|
let env = Environment::from_display_with_cb(
|
||||||
&display,
|
&display,
|
||||||
&mut event_queue,
|
&mut event_queue,
|
||||||
|
@ -138,8 +136,6 @@ impl EventsLoop {
|
||||||
GlobalEvent::Removed { id, ref interface } => {
|
GlobalEvent::Removed { id, ref interface } => {
|
||||||
if interface == "wl_seat" {
|
if interface == "wl_seat" {
|
||||||
seat_manager.remove_seat(id)
|
seat_manager.remove_seat(id)
|
||||||
} else if interface == "wl_output" {
|
|
||||||
cb_store.lock().unwrap().remove_output(id);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ use dpi::{LogicalPosition, LogicalSize};
|
||||||
use platform::{MonitorId as PlatformMonitorId, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
use platform::{MonitorId as PlatformMonitorId, PlatformSpecificWindowBuilderAttributes as PlAttributes};
|
||||||
use window::MonitorId as RootMonitorId;
|
use window::MonitorId as RootMonitorId;
|
||||||
|
|
||||||
|
use sctk::surface::{get_dpi_factor, get_outputs};
|
||||||
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow};
|
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow};
|
||||||
use sctk::reexports::client::{Display, Proxy};
|
use sctk::reexports::client::{Display, Proxy};
|
||||||
use sctk::reexports::client::protocol::{wl_seat, wl_surface, wl_output};
|
use sctk::reexports::client::protocol::{wl_seat, wl_surface};
|
||||||
use sctk::reexports::client::protocol::wl_compositor::RequestsTrait as CompositorRequests;
|
|
||||||
use sctk::reexports::client::protocol::wl_surface::RequestsTrait as SurfaceRequests;
|
use sctk::reexports::client::protocol::wl_surface::RequestsTrait as SurfaceRequests;
|
||||||
use sctk::output::OutputMgr;
|
use sctk::output::OutputMgr;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ use platform::platform::wayland::event_loop::{get_available_monitors, get_primar
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
surface: Proxy<wl_surface::WlSurface>,
|
surface: Proxy<wl_surface::WlSurface>,
|
||||||
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
||||||
monitors: Arc<Mutex<MonitorList>>, // Monitors this window is currently on
|
|
||||||
outputs: OutputMgr, // Access to info for all monitors
|
outputs: OutputMgr, // Access to info for all monitors
|
||||||
size: Arc<Mutex<(u32, u32)>>,
|
size: Arc<Mutex<(u32, u32)>>,
|
||||||
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
||||||
|
@ -33,39 +32,11 @@ impl Window {
|
||||||
// Create the window
|
// Create the window
|
||||||
let size = Arc::new(Mutex::new((width, height)));
|
let size = Arc::new(Mutex::new((width, height)));
|
||||||
|
|
||||||
// monitor tracking
|
let window_store = evlp.store.clone();
|
||||||
let monitor_list = Arc::new(Mutex::new(MonitorList::new()));
|
let surface = evlp.env.create_surface(move |dpi, surface| {
|
||||||
|
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
||||||
let surface = evlp.env.compositor.create_surface(|surface| {
|
surface.set_buffer_scale(dpi);
|
||||||
let list = monitor_list.clone();
|
});
|
||||||
let omgr = evlp.env.outputs.clone();
|
|
||||||
let window_store = evlp.store.clone();
|
|
||||||
surface.implement(move |event, surface| match event {
|
|
||||||
wl_surface::Event::Enter { output } => {
|
|
||||||
let dpi_change = list.lock().unwrap().add_output(MonitorId {
|
|
||||||
proxy: output,
|
|
||||||
mgr: omgr.clone(),
|
|
||||||
});
|
|
||||||
if let Some(dpi) = dpi_change {
|
|
||||||
if surface.version() >= 3 {
|
|
||||||
// without version 3 we can't be dpi aware
|
|
||||||
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
|
||||||
surface.set_buffer_scale(dpi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
wl_surface::Event::Leave { output } => {
|
|
||||||
let dpi_change = list.lock().unwrap().del_output(&output);
|
|
||||||
if let Some(dpi) = dpi_change {
|
|
||||||
if surface.version() >= 3 {
|
|
||||||
// without version 3 we can't be dpi aware
|
|
||||||
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
|
||||||
surface.set_buffer_scale(dpi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, ())
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
let window_store = evlp.store.clone();
|
let window_store = evlp.store.clone();
|
||||||
let my_surface = surface.clone();
|
let my_surface = surface.clone();
|
||||||
|
@ -148,7 +119,6 @@ impl Window {
|
||||||
frame: Arc::downgrade(&frame),
|
frame: Arc::downgrade(&frame),
|
||||||
current_dpi: 1,
|
current_dpi: 1,
|
||||||
new_dpi: None,
|
new_dpi: None,
|
||||||
monitors: monitor_list.clone(),
|
|
||||||
});
|
});
|
||||||
evlp.evq.borrow_mut().sync_roundtrip().unwrap();
|
evlp.evq.borrow_mut().sync_roundtrip().unwrap();
|
||||||
|
|
||||||
|
@ -156,7 +126,6 @@ impl Window {
|
||||||
display: evlp.display.clone(),
|
display: evlp.display.clone(),
|
||||||
surface: surface,
|
surface: surface,
|
||||||
frame: frame,
|
frame: frame,
|
||||||
monitors: monitor_list,
|
|
||||||
outputs: evlp.env.outputs.clone(),
|
outputs: evlp.env.outputs.clone(),
|
||||||
size: size,
|
size: size,
|
||||||
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
||||||
|
@ -236,7 +205,7 @@ impl Window {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hidpi_factor(&self) -> i32 {
|
pub fn hidpi_factor(&self) -> i32 {
|
||||||
self.monitors.lock().unwrap().compute_hidpi_factor()
|
get_dpi_factor(&self.surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_decorations(&self, decorate: bool) {
|
pub fn set_decorations(&self, decorate: bool) {
|
||||||
|
@ -295,10 +264,11 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_monitor(&self) -> MonitorId {
|
pub fn get_current_monitor(&self) -> MonitorId {
|
||||||
// we don't know how much each monitor sees us so...
|
let output = get_outputs(&self.surface).last().unwrap().clone();
|
||||||
// just return the most recent one ?
|
MonitorId {
|
||||||
let guard = self.monitors.lock().unwrap();
|
proxy: output,
|
||||||
guard.monitors.last().unwrap().clone()
|
mgr: self.outputs.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
|
pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
|
||||||
|
@ -332,7 +302,6 @@ struct InternalWindow {
|
||||||
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
||||||
current_dpi: i32,
|
current_dpi: i32,
|
||||||
new_dpi: Option<i32>,
|
new_dpi: Option<i32>,
|
||||||
monitors: Arc<Mutex<MonitorList>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowStore {
|
pub struct WindowStore {
|
||||||
|
@ -378,18 +347,6 @@ impl WindowStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_output(&mut self, output: u32) {
|
|
||||||
for window in &mut self.windows {
|
|
||||||
let dpi = window.monitors.lock().unwrap().output_disappeared(output);
|
|
||||||
if window.surface.version() >= 3 {
|
|
||||||
// without version 3 we can't be dpi aware
|
|
||||||
window.new_dpi = Some(dpi);
|
|
||||||
window.surface.set_buffer_scale(dpi);
|
|
||||||
window.need_refresh = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dpi_change(&mut self, surface: &Proxy<wl_surface::WlSurface>, new: i32) {
|
fn dpi_change(&mut self, surface: &Proxy<wl_surface::WlSurface>, new: i32) {
|
||||||
for window in &mut self.windows {
|
for window in &mut self.windows {
|
||||||
if surface.equals(&window.surface) {
|
if surface.equals(&window.surface) {
|
||||||
|
@ -424,55 +381,3 @@ impl WindowStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Monitor list with some covenience method to compute DPI
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct MonitorList {
|
|
||||||
monitors: Vec<MonitorId>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MonitorList {
|
|
||||||
fn new() -> MonitorList {
|
|
||||||
MonitorList {
|
|
||||||
monitors: Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_hidpi_factor(&self) -> i32 {
|
|
||||||
let mut factor = 1;
|
|
||||||
for monitor_id in &self.monitors {
|
|
||||||
let monitor_dpi = monitor_id.get_hidpi_factor();
|
|
||||||
if monitor_dpi > factor { factor = monitor_dpi; }
|
|
||||||
}
|
|
||||||
factor
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_output(&mut self, monitor: MonitorId) -> Option<i32> {
|
|
||||||
let old_dpi = self.compute_hidpi_factor();
|
|
||||||
let monitor_dpi = monitor.get_hidpi_factor();
|
|
||||||
self.monitors.push(monitor);
|
|
||||||
if monitor_dpi > old_dpi {
|
|
||||||
Some(monitor_dpi)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn del_output(&mut self, output: &Proxy<wl_output::WlOutput>) -> Option<i32> {
|
|
||||||
let old_dpi = self.compute_hidpi_factor();
|
|
||||||
self.monitors.retain(|m| !m.proxy.equals(output));
|
|
||||||
let new_dpi = self.compute_hidpi_factor();
|
|
||||||
if new_dpi != old_dpi {
|
|
||||||
Some(new_dpi)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_disappeared(&mut self, id: u32) -> i32 {
|
|
||||||
self.monitors.retain(|m| m.get_native_identifier() != id);
|
|
||||||
self.compute_hidpi_factor()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue