diff --git a/voxygen/src/run.rs b/voxygen/src/run.rs index 3549e48128..3244b8e3ee 100644 --- a/voxygen/src/run.rs +++ b/voxygen/src/run.rs @@ -39,18 +39,27 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) { } } - // Get events for the ui. - if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) { - global_state.window.send_event(Event::Ui(event)); - } - // iced ui events - // TODO: no clone - if let winit::event::Event::WindowEvent { event, .. } = &event { - let window = &mut global_state.window; - if let Some(event) = - ui::ice::window_event(event, window.scale_factor(), window.modifiers()) - { - window.send_event(Event::IcedUi(event)); + // Don't pass resize events to the ui, `Window` is responsible for: + // - deduplicating them + // - generating resize events for the ui + // - ensuring consistent sizes are passed to the ui and to the renderer + if !matches!(&event, winit::event::Event::WindowEvent { + event: winit::event::WindowEvent::Resized(_), + .. + }) { + // Get events for the ui. + if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) { + global_state.window.send_event(Event::Ui(event)); + } + // iced ui events + // TODO: no clone + if let winit::event::Event::WindowEvent { event, .. } = &event { + let window = &mut global_state.window; + if let Some(event) = + ui::ice::window_event(event, window.scale_factor(), window.modifiers()) + { + window.send_event(Event::IcedUi(event)); + } } } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 409407b06f..0deb749344 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -378,6 +378,9 @@ pub struct Window { pub mouse_y_inversion: bool, fullscreen: FullScreenSettings, modifiers: winit::event::ModifiersState, + // Track if at least one Resized event has occured since the last `fetch_events` call + // Used for deduplication of resizes. + resized: bool, scale_factor: f64, needs_refresh_resize: bool, keypress_map: HashMap, @@ -479,6 +482,7 @@ impl Window { fullscreen: FullScreenSettings::default(), modifiers: Default::default(), scale_factor, + resized: false, needs_refresh_resize: false, keypress_map, remapping_keybindings: None, @@ -539,6 +543,36 @@ impl Window { self.needs_refresh_resize = false; } + // Handle deduplicated resizing that occured + if self.resized { + self.resized = false; + // We don't use the size provided by the event because more resize events could + // have happened since, making the value outdated, so we must query directly + // from the window to prevent errors + let physical = self.window.inner_size(); + + self.renderer + .on_resize(Vec2::new(physical.width, physical.height)); + // TODO: update users of this event with the fact that it is now the physical + // size + let winit::dpi::PhysicalSize { width, height } = physical; + self.events + .push(Event::Resize(Vec2::new(width as u32, height as u32))); + + // Emit event for the UI + let logical_size = Vec2::from(Into::<(f64, f64)>::into( + physical.to_logical::(self.window.scale_factor()), + )); + self.events + .push(Event::Ui(ui::Event::new_resize(logical_size))); + self.events.push(Event::IcedUi(iced::Event::Window( + iced::window::Event::Resized { + width: logical_size.x as u32, + height: logical_size.y as u32, + }, + ))); + } + // Receive any messages sent through the message channel for message in self.message_receiver.try_iter() { self.events.push(Event::ScreenshotMessage(message)) @@ -788,18 +822,7 @@ impl Window { match event { WindowEvent::CloseRequested => self.events.push(Event::Close), WindowEvent::Resized(_) => { - // We don't use the event provided size because since this event - // more could have happened making the value wrong so we query - // directly from the window, this prevents some errors - let physical = self.window.inner_size(); - - self.renderer - .on_resize(Vec2::new(physical.width, physical.height)); - // TODO: update users of this event with the fact that it is now the physical - // size - let winit::dpi::PhysicalSize { width, height } = physical; - self.events - .push(Event::Resize(Vec2::new(width as u32, height as u32))); + self.resized = true; }, WindowEvent::ScaleFactorChanged { scale_factor, .. } => { // TODO: is window resized event emitted? or do we need to handle that here?