mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
eframe: apply ViewportBuilder::with_monitor on the glow backend (#8302)
## Problem `ViewportBuilder::with_monitor(idx)` is a **no-op on the glow backend**. A window built with `.with_monitor(...)` opens on the default monitor, not fullscreen — while the exact same code works on wgpu. The monitor → `Fullscreen::Borderless(Some(monitor))` resolution only lives in `egui_winit::create_window`, which the **wgpu** backend uses. The **glow** backend builds its windows straight from `egui_winit::create_winit_window_attributes` at two sites in `glow_integration.rs` — the initial window and per-viewport deferred windows — so the monitor is never applied there. ## Repro A multi-viewport app on the glow renderer with any viewport built via `ViewportBuilder::default().with_monitor(1)` opens that window on monitor 0, un-fullscreen. Switching to the wgpu renderer places it correctly. Seen on a 3-monitor GNOME/Wayland setup where the main window and secondary viewports all need to land borderless-fullscreen on specific outputs. ## Fix Extract the resolution into a public `apply_monitor_to_window_attributes` in `egui-winit` and call it from `create_window` (unchanged behaviour) plus both glow window-creation sites, so `with_monitor` behaves the same on glow and wgpu. No public API change beyond the new helper; no behaviour change on wgpu. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
@@ -1971,12 +1971,33 @@ pub fn create_window(
|
||||
) -> Result<Window, winit::error::OsError> {
|
||||
profiling::function_scope!();
|
||||
|
||||
let mut window_attributes = create_winit_window_attributes(egui_ctx, viewport_builder.clone());
|
||||
let window_attributes = apply_monitor_to_window_attributes(
|
||||
create_winit_window_attributes(egui_ctx, viewport_builder.clone()),
|
||||
viewport_builder,
|
||||
event_loop,
|
||||
);
|
||||
|
||||
// Resolve target monitor index → MonitorHandle, so the window is created
|
||||
// directly in borderless fullscreen on the requested output. This is the
|
||||
// only reliable way to target a specific monitor under Wayland, and also
|
||||
// avoids the Mutter race where OuterPosition is ignored pre-mapping.
|
||||
let window = event_loop.create_window(window_attributes)?;
|
||||
apply_viewport_builder_to_window(egui_ctx, &window, viewport_builder);
|
||||
Ok(window)
|
||||
}
|
||||
|
||||
/// Apply [`ViewportBuilder::with_monitor`] to freshly-built [`winit::window::WindowAttributes`].
|
||||
///
|
||||
/// Resolve the target monitor index → `MonitorHandle` and request borderless
|
||||
/// fullscreen on that output, so the window is created directly on the right
|
||||
/// monitor. This is the only reliable way to target a specific monitor under
|
||||
/// Wayland, and also avoids the Mutter race where `OuterPosition` is ignored
|
||||
/// pre-mapping.
|
||||
///
|
||||
/// Must be called by every backend that builds its own window from
|
||||
/// [`create_winit_window_attributes`] (the glow backend and per-viewport window
|
||||
/// creation do this) — otherwise `with_monitor` silently does nothing there.
|
||||
pub fn apply_monitor_to_window_attributes(
|
||||
mut window_attributes: winit::window::WindowAttributes,
|
||||
viewport_builder: &ViewportBuilder,
|
||||
event_loop: &ActiveEventLoop,
|
||||
) -> winit::window::WindowAttributes {
|
||||
if let Some(idx) = viewport_builder.monitor {
|
||||
if let Some(monitor) = event_loop.available_monitors().nth(idx) {
|
||||
window_attributes = window_attributes
|
||||
@@ -1988,10 +2009,7 @@ pub fn create_window(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let window = event_loop.create_window(window_attributes)?;
|
||||
apply_viewport_builder_to_window(egui_ctx, &window, viewport_builder);
|
||||
Ok(window)
|
||||
window_attributes
|
||||
}
|
||||
|
||||
pub fn create_winit_window_attributes(
|
||||
|
||||
Reference in New Issue
Block a user