Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/fix-macos-initial-window-position.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-runtime-wry": patch:bug
"tauri": patch:bug
---

Fix initial window position when positioning it to another monitor.
58 changes: 46 additions & 12 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,25 @@ impl From<Position> for PositionWrapper {
}
}

#[cfg(desktop)]
fn find_monitor_for_position(
monitors: impl Iterator<Item = MonitorHandle>,
window_position: TaoPosition,
) -> Option<MonitorHandle> {
monitors.into_iter().find(|m| {
let monitor_pos = m.position();
let monitor_size = m.size();

// type annotations required for 32bit targets.
let window_position = window_position.to_physical::<i32>(m.scale_factor());

monitor_pos.x <= window_position.x
&& window_position.x < monitor_pos.x + monitor_size.width as i32
&& monitor_pos.y <= window_position.y
&& window_position.y < monitor_pos.y + monitor_size.height as i32
})
}

#[derive(Debug, Clone)]
pub struct UserAttentionTypeWrapper(pub TaoUserAttentionType);

Expand Down Expand Up @@ -4489,18 +4508,7 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
#[cfg(desktop)]
if window_builder.prevent_overflow.is_some() || window_builder.center {
let monitor = if let Some(window_position) = &window_builder.inner.window.position {
event_loop.available_monitors().find(|m| {
let monitor_pos = m.position();
let monitor_size = m.size();

// type annotations required for 32bit targets.
let window_position = window_position.to_physical::<i32>(m.scale_factor());

monitor_pos.x <= window_position.x
&& window_position.x < monitor_pos.x + monitor_size.width as i32
&& monitor_pos.y <= window_position.y
&& window_position.y < monitor_pos.y + monitor_size.height as i32
})
find_monitor_for_position(event_loop.available_monitors(), *window_position)
} else {
event_loop.primary_monitor()
};
Expand Down Expand Up @@ -4567,12 +4575,38 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
}
};

#[cfg(any(target_os = "macos", target_os = "linux"))]
let (initial_position, is_fullscreen) = (
window_builder.inner.window.position,
window_builder.inner.window.fullscreen.is_some(),
);

// If fullscreen is requested with an explicit position, resolve the target
// monitor up front so the window is created fullscreen on that display.
#[cfg(any(target_os = "macos", target_os = "linux"))]
if let (true, Some(position)) = (is_fullscreen, initial_position) {
if let Some(target_monitor) =
find_monitor_for_position(event_loop.available_monitors(), position)
{
window_builder.inner.window.fullscreen = Some(Fullscreen::Borderless(Some(target_monitor)));
}
}

let window = window_builder
.inner
.build(event_loop)
.inspect_err(|e| log::error!("Error creating window: {e:?}"))
.map_err(|_| Error::CreateWindow)?;

// On macOS, `with_position` uses the content origin; the title bar is added
// above it. `set_outer_position` is needed for precise window placement.
#[cfg(target_os = "macos")]
if !is_fullscreen {
if let Some(position) = initial_position {
window.set_outer_position(position);
}
}

#[cfg(feature = "tracing")]
{
drop(window_create_span);
Expand Down
Loading