mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 08:07:49 +00:00
fix(settings): keep the settings window inside the work area on Windows and Linux (#558)
* fix(settings): keep the settings window inside the work area on Windows and Linux * fix(settings): subtract the window frame when shrinking to the work area
This commit is contained in:
@@ -752,15 +752,9 @@ pub fn open_settings_window(
|
||||
if let Err(e) = fit_settings_window(&window, &parent) {
|
||||
tracing::warn!("cannot fit settings window: {e}");
|
||||
}
|
||||
// Elsewhere the remembered size is kept and the position follows the parent.
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
if let (Ok(pos), Ok(size), Ok(own), Ok(scale)) =
|
||||
(parent.outer_position(), parent.outer_size(), window.outer_size(), parent.scale_factor())
|
||||
{
|
||||
let (pos, size, own) =
|
||||
(pos.to_logical::<f64>(scale), size.to_logical::<f64>(scale), own.to_logical::<f64>(scale));
|
||||
let at = centered(pos.x, pos.y, size.width, size.height, own.width, own.height);
|
||||
let _ = window.set_position(tauri::LogicalPosition::new(at.0, at.1));
|
||||
if let Err(e) = place_settings_window(&window, &parent) {
|
||||
tracing::warn!("cannot place settings window: {e}");
|
||||
}
|
||||
focus(&window);
|
||||
Ok(())
|
||||
@@ -805,7 +799,45 @@ fn fit_settings_window(window: &WebviewWindow, parent: &WebviewWindow) -> tauri:
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
|
||||
/// Centres the settings window over its owner, inside the owner's monitor work area. The window
|
||||
/// may still be on another display with a different scale, so its size is converted with its own
|
||||
/// scale and its position is given in physical pixels.
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn place_settings_window(window: &WebviewWindow, parent: &WebviewWindow) -> tauri::Result<()> {
|
||||
let Some(monitor) = parent.current_monitor()?.or(parent.primary_monitor()?) else {
|
||||
return Ok(());
|
||||
};
|
||||
let scale = monitor.scale_factor();
|
||||
let area = monitor.work_area();
|
||||
let origin = area.position.to_logical::<f64>(scale);
|
||||
let available = area.size.to_logical::<f64>(scale);
|
||||
let pos = parent.outer_position()?.to_logical::<f64>(scale);
|
||||
let size = parent.outer_size()?.to_logical::<f64>(scale);
|
||||
let own_scale = window.scale_factor()?;
|
||||
let own = window.outer_size()?.to_logical::<f64>(own_scale);
|
||||
let inner = window.inner_size()?.to_logical::<f64>(own_scale);
|
||||
let frame = (own.width - inner.width, own.height - inner.height);
|
||||
let bounds = fit_bounds(
|
||||
(pos.x, pos.y, size.width, size.height),
|
||||
(own.width, own.height),
|
||||
(origin.x, origin.y, available.width, available.height),
|
||||
);
|
||||
window.set_position(tauri::PhysicalPosition::new(
|
||||
(bounds.0 * scale).round() as i32,
|
||||
(bounds.1 * scale).round() as i32,
|
||||
))?;
|
||||
if (bounds.2, bounds.3) != (own.width, own.height) {
|
||||
// Sizes are set on the client area, and even an undecorated window has a resize frame.
|
||||
let (width, height) = ((bounds.2 - frame.0).max(1.0), (bounds.3 - frame.1).max(1.0));
|
||||
window.set_min_size(Some(tauri::LogicalSize::new(
|
||||
SETTINGS_MIN_SIZE.0.min(width),
|
||||
SETTINGS_MIN_SIZE.1.min(height),
|
||||
)))?;
|
||||
window.set_size(tauri::LogicalSize::new(width, height))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fit_bounds(parent: (f64, f64, f64, f64), size: (f64, f64), work: (f64, f64, f64, f64)) -> (f64, f64, f64, f64) {
|
||||
let width = size.0.min(work.2);
|
||||
let height = size.1.min(work.3);
|
||||
@@ -1094,6 +1126,8 @@ mod tests {
|
||||
(0.0, 0.0, 1280.0, 1040.0 / 1.5),
|
||||
(150.0, 0.0, 980.0, 1040.0 / 1.5),
|
||||
),
|
||||
// 3840×2160 at 250% scaling: an owner taller than the work area must not push it off screen.
|
||||
((100.0, 60.0, 1440.0, 900.0), (980.0, 720.0), (0.0, 0.0, 1536.0, 816.0), (330.0, 96.0, 980.0, 720.0)),
|
||||
// Restored geometry from a larger display.
|
||||
((100.0, 50.0, 1440.0, 900.0), (2400.0, 1600.0), (0.0, 24.0, 1920.0, 1016.0), (0.0, 24.0, 1920.0, 1016.0)),
|
||||
// Secondary display with a negative origin and reserved top/left space.
|
||||
|
||||
Reference in New Issue
Block a user