mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-02-24 00:37:43 +11:00
Handle removed wl_outputs (#719)
* Move the event managent to the closure In preparation of more events not relating to the SeatManager being captured. * Handle wl_output remove events In some cases, wl_outputs can be removed without the compositor notifying the surfaces using leave/enter events. This breaks the DPI and resize stuff since the windows' list of monitors were not updated. Now, wl_output removals are handled and windows are updated accordingly. * Add changelog entry for disappearing wl_outputs * Clearer changelog message for wl_output removal changes
This commit is contained in:
parent
04ca2cf9f4
commit
92873b06ed
3 changed files with 66 additions and 40 deletions
|
@ -8,6 +8,7 @@
|
||||||
- On X11, fixed a segfault when using virtual monitors with XRandR.
|
- On X11, fixed a segfault when using virtual monitors with XRandR.
|
||||||
- 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.
|
||||||
|
|
||||||
# Version 0.18.0 (2018-11-07)
|
# Version 0.18.0 (2018-11-07)
|
||||||
|
|
||||||
|
|
|
@ -123,11 +123,26 @@ 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,
|
||||||
move |event, registry| {
|
move |event, registry| {
|
||||||
seat_manager.receive(event, registry)
|
match event {
|
||||||
|
GlobalEvent::New { id, ref interface, version } => {
|
||||||
|
if interface == "wl_seat" {
|
||||||
|
seat_manager.add_seat(id, version, registry)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GlobalEvent::Removed { id, ref interface } => {
|
||||||
|
if interface == "wl_seat" {
|
||||||
|
seat_manager.remove_seat(id)
|
||||||
|
} else if interface == "wl_output" {
|
||||||
|
cb_store.lock().unwrap().remove_output(id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
|
@ -286,47 +301,38 @@ struct SeatManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeatManager {
|
impl SeatManager {
|
||||||
fn receive(&mut self, evt: GlobalEvent, registry: Proxy<wl_registry::WlRegistry>) {
|
fn add_seat(&mut self, id: u32, version: u32, registry: Proxy<wl_registry::WlRegistry>) {
|
||||||
use self::wl_registry::RequestsTrait as RegistryRequests;
|
use self::wl_registry::RequestsTrait as RegistryRequests;
|
||||||
use self::wl_seat::RequestsTrait as SeatRequests;
|
use std::cmp::min;
|
||||||
match evt {
|
|
||||||
GlobalEvent::New {
|
|
||||||
id,
|
|
||||||
ref interface,
|
|
||||||
version,
|
|
||||||
} if interface == "wl_seat" =>
|
|
||||||
{
|
|
||||||
use std::cmp::min;
|
|
||||||
|
|
||||||
let mut seat_data = SeatData {
|
let mut seat_data = SeatData {
|
||||||
sink: self.sink.clone(),
|
sink: self.sink.clone(),
|
||||||
store: self.store.clone(),
|
store: self.store.clone(),
|
||||||
pointer: None,
|
pointer: None,
|
||||||
keyboard: None,
|
keyboard: None,
|
||||||
touch: None,
|
touch: None,
|
||||||
events_loop_proxy: self.events_loop_proxy.clone(),
|
events_loop_proxy: self.events_loop_proxy.clone(),
|
||||||
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
||||||
};
|
};
|
||||||
let seat = registry
|
let seat = registry
|
||||||
.bind(min(version, 5), id, move |seat| {
|
.bind(min(version, 5), id, move |seat| {
|
||||||
seat.implement(move |event, seat| {
|
seat.implement(move |event, seat| {
|
||||||
seat_data.receive(event, seat)
|
seat_data.receive(event, seat)
|
||||||
}, ())
|
}, ())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.store.lock().unwrap().new_seat(&seat);
|
self.store.lock().unwrap().new_seat(&seat);
|
||||||
self.seats.lock().unwrap().push((id, seat));
|
self.seats.lock().unwrap().push((id, seat));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_seat(&mut self, id: u32) {
|
||||||
|
use self::wl_seat::RequestsTrait as SeatRequests;
|
||||||
|
let mut seats = self.seats.lock().unwrap();
|
||||||
|
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
|
||||||
|
let (_, seat) = seats.swap_remove(idx);
|
||||||
|
if seat.version() >= 5 {
|
||||||
|
seat.release();
|
||||||
}
|
}
|
||||||
GlobalEvent::Removed { id, ref interface } if interface == "wl_seat" => {
|
|
||||||
let mut seats = self.seats.lock().unwrap();
|
|
||||||
if let Some(idx) = seats.iter().position(|&(i, _)| i == id) {
|
|
||||||
let (_, seat) = seats.swap_remove(idx);
|
|
||||||
if seat.version() >= 5 {
|
|
||||||
seat.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ 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();
|
||||||
|
|
||||||
|
@ -330,7 +331,8 @@ struct InternalWindow {
|
||||||
kill_switch: Arc<Mutex<bool>>,
|
kill_switch: Arc<Mutex<bool>>,
|
||||||
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 {
|
||||||
|
@ -376,6 +378,18 @@ 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) {
|
||||||
|
@ -456,4 +470,9 @@ impl MonitorList {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn output_disappeared(&mut self, id: u32) -> i32 {
|
||||||
|
self.monitors.retain(|m| m.get_native_identifier() != id);
|
||||||
|
self.compute_hidpi_factor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue