diff --git a/CHANGELOG.md b/CHANGELOG.md index 6605956a..1e6012c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ - **Breaking:** On Wayland, Theme trait and its support types are dropped. - On Wayland, bump `smithay-client-toolkit` to 0.15. - On Wayland, implement `request_user_attention` with `xdg_activation_v1`. - +- On X11, emit missing `WindowEvent::ScaleFactorChanged` when the only monitor gets reconnected. # 0.25.0 (2021-05-15) diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 65ed4d9f..2f1d6b77 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -1164,57 +1164,56 @@ impl EventProcessor { if let Some(prev_list) = prev_list { let new_list = wt.xconn.available_monitors(); for new_monitor in new_list { - prev_list + // Previous list may be empty, in case of disconnecting and + // reconnecting the only one monitor. We still need to emit events in + // this case. + let maybe_prev_scale_factor = prev_list .iter() .find(|prev_monitor| prev_monitor.name == new_monitor.name) - .map(|prev_monitor| { - if new_monitor.scale_factor != prev_monitor.scale_factor { - for (window_id, window) in wt.windows.borrow().iter() { - if let Some(window) = window.upgrade() { - // Check if the window is on this monitor - let monitor = window.current_monitor(); - if monitor.name == new_monitor.name { - let (width, height) = - window.inner_size_physical(); - let (new_width, new_height) = window - .adjust_for_dpi( - prev_monitor.scale_factor, - new_monitor.scale_factor, - width, - height, - &*window.shared_state.lock(), - ); + .map(|prev_monitor| prev_monitor.scale_factor); + if Some(new_monitor.scale_factor) != maybe_prev_scale_factor { + for (window_id, window) in wt.windows.borrow().iter() { + if let Some(window) = window.upgrade() { + // Check if the window is on this monitor + let monitor = window.current_monitor(); + if monitor.name == new_monitor.name { + let (width, height) = window.inner_size_physical(); + let (new_width, new_height) = window.adjust_for_dpi( + // If there all monitors are closed before, scale + // factor would be already changed to 1.0. + maybe_prev_scale_factor.unwrap_or(1.0), + new_monitor.scale_factor, + width, + height, + &*window.shared_state.lock(), + ); - let window_id = crate::window::WindowId( - crate::platform_impl::platform::WindowId::X( - *window_id, - ), - ); - let old_inner_size = - PhysicalSize::new(width, height); - let mut new_inner_size = - PhysicalSize::new(new_width, new_height); + let window_id = crate::window::WindowId( + crate::platform_impl::platform::WindowId::X( + *window_id, + ), + ); + let old_inner_size = PhysicalSize::new(width, height); + let mut new_inner_size = + PhysicalSize::new(new_width, new_height); - callback(Event::WindowEvent { - window_id, - event: WindowEvent::ScaleFactorChanged { - scale_factor: new_monitor.scale_factor, - new_inner_size: &mut new_inner_size, - }, - }); + callback(Event::WindowEvent { + window_id, + event: WindowEvent::ScaleFactorChanged { + scale_factor: new_monitor.scale_factor, + new_inner_size: &mut new_inner_size, + }, + }); - if new_inner_size != old_inner_size { - let (new_width, new_height) = - new_inner_size.into(); - window.set_inner_size_physical( - new_width, new_height, - ); - } - } + if new_inner_size != old_inner_size { + let (new_width, new_height) = new_inner_size.into(); + window + .set_inner_size_physical(new_width, new_height); } } } - }); + } + } } } }