mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 13:50:04 -04:00
Improve multi-viewports across monitors with different scales (#3663)
It required some ugly code in `egui-winit` in order to fix this without breaking sem-ver (I want this to land in a 0.24.1 patch release). I'll clean up in time for 0.25. There is still a font rendering bug when using immediate viewports across multiple viewports, but that's harder to fix.
This commit is contained in:
@@ -18,10 +18,6 @@ use egui::{
|
||||
};
|
||||
#[cfg(feature = "accesskit")]
|
||||
use egui_winit::accesskit_winit;
|
||||
use egui_winit::{
|
||||
apply_viewport_builder_to_new_window, create_winit_window_builder, process_viewport_commands,
|
||||
EventResponse,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
native::{epi_integration::EpiIntegration, winit_integration::create_egui_context},
|
||||
@@ -513,11 +509,13 @@ impl GlowWinitRunning {
|
||||
|
||||
let (raw_input, viewport_ui_cb) = {
|
||||
let mut glutin = self.glutin.borrow_mut();
|
||||
let egui_ctx = glutin.egui_ctx.clone();
|
||||
let viewport = glutin.viewports.get_mut(&viewport_id).unwrap();
|
||||
viewport.update_viewport_info();
|
||||
let window = viewport.window.as_ref().unwrap();
|
||||
egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window);
|
||||
|
||||
let egui_winit = viewport.egui_winit.as_mut().unwrap();
|
||||
egui_winit.update_pixels_per_point(&egui_ctx, window);
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
let viewport_ui_cb = viewport.viewport_ui_cb.clone();
|
||||
|
||||
@@ -744,15 +742,17 @@ impl GlowWinitRunning {
|
||||
return EventResult::Exit;
|
||||
}
|
||||
|
||||
let mut event_response = EventResponse {
|
||||
let mut event_response = egui_winit::EventResponse {
|
||||
consumed: false,
|
||||
repaint: false,
|
||||
};
|
||||
if let Some(viewport_id) = viewport_id {
|
||||
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
|
||||
event_response = self
|
||||
.integration
|
||||
.on_window_event(event, viewport.egui_winit.as_mut().unwrap());
|
||||
if let (Some(window), Some(egui_winit)) =
|
||||
(&viewport.window, &mut viewport.egui_winit)
|
||||
{
|
||||
event_response = self.integration.on_window_event(window, egui_winit, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,7 +823,7 @@ impl GlutinWindowContext {
|
||||
let display_builder = glutin_winit::DisplayBuilder::new()
|
||||
// we might want to expose this option to users in the future. maybe using an env var or using native_options.
|
||||
.with_preference(glutin_winit::ApiPrefence::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150
|
||||
.with_window_builder(Some(create_winit_window_builder(
|
||||
.with_window_builder(Some(egui_winit::create_winit_window_builder(
|
||||
egui_ctx,
|
||||
event_loop,
|
||||
viewport_builder.clone(),
|
||||
@@ -849,7 +849,7 @@ impl GlutinWindowContext {
|
||||
.map_err(|e| crate::Error::NoGlutinConfigs(config_template_builder.build(), e))?
|
||||
};
|
||||
if let Some(window) = &window {
|
||||
apply_viewport_builder_to_new_window(window, &viewport_builder);
|
||||
egui_winit::apply_viewport_builder_to_window(egui_ctx, window, &viewport_builder);
|
||||
}
|
||||
|
||||
let gl_display = gl_config.display();
|
||||
@@ -981,12 +981,18 @@ impl GlutinWindowContext {
|
||||
window
|
||||
} else {
|
||||
log::trace!("Window doesn't exist yet. Creating one now with finalize_window");
|
||||
let window = glutin_winit::finalize_window(
|
||||
let window_builder = egui_winit::create_winit_window_builder(
|
||||
&self.egui_ctx,
|
||||
event_loop,
|
||||
create_winit_window_builder(&self.egui_ctx, event_loop, viewport.builder.clone()),
|
||||
&self.gl_config,
|
||||
)?;
|
||||
apply_viewport_builder_to_new_window(&window, &viewport.builder);
|
||||
viewport.builder.clone(),
|
||||
);
|
||||
let window =
|
||||
glutin_winit::finalize_window(event_loop, window_builder, &self.gl_config)?;
|
||||
egui_winit::apply_viewport_builder_to_window(
|
||||
&self.egui_ctx,
|
||||
&window,
|
||||
&viewport.builder,
|
||||
);
|
||||
viewport.info.minimized = window.is_minimized();
|
||||
viewport.info.maximized = Some(window.is_maximized());
|
||||
viewport.window.insert(Rc::new(window))
|
||||
@@ -1167,19 +1173,6 @@ impl GlutinWindowContext {
|
||||
}
|
||||
}
|
||||
|
||||
impl Viewport {
|
||||
/// Update the stored `ViewportInfo`.
|
||||
fn update_viewport_info(&mut self) {
|
||||
let Some(window) = &self.window else {
|
||||
return;
|
||||
};
|
||||
let Some(egui_winit) = &self.egui_winit else {
|
||||
return;
|
||||
};
|
||||
egui_winit.update_viewport_info(&mut self.info, window);
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_or_update_viewport<'vp>(
|
||||
egu_ctx: &'_ egui::Context,
|
||||
viewports: &'vp mut ViewportIdMap<Viewport>,
|
||||
@@ -1235,7 +1228,7 @@ fn initialize_or_update_viewport<'vp>(
|
||||
viewport.egui_winit = None;
|
||||
} else if let Some(window) = &viewport.window {
|
||||
let is_viewport_focused = focused_viewport == Some(ids.this);
|
||||
process_viewport_commands(
|
||||
egui_winit::process_viewport_commands(
|
||||
egu_ctx,
|
||||
&mut viewport.info,
|
||||
delta_commands,
|
||||
@@ -1294,15 +1287,16 @@ fn render_immediate_viewport(
|
||||
let Some(viewport) = glutin.viewports.get_mut(&ids.this) else {
|
||||
return;
|
||||
};
|
||||
viewport.update_viewport_info();
|
||||
let Some(winit_state) = &mut viewport.egui_winit else {
|
||||
let Some(egui_winit) = &mut viewport.egui_winit else {
|
||||
return;
|
||||
};
|
||||
let Some(window) = &viewport.window else {
|
||||
return;
|
||||
};
|
||||
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window);
|
||||
|
||||
let mut raw_input = winit_state.take_egui_input(window);
|
||||
egui_winit.update_pixels_per_point(egui_ctx, window);
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
raw_input.viewports = glutin
|
||||
.viewports
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user