Skip to content

Commit 6364826

Browse files
Window: fit the screen the window reopens on; the header bar is inside on Wayland
Review of 1.0.1 found three gaps in the first-size fit: - On X11 the window was fitted to the primary monitor, but the window-state plugin then moved it back to its saved place, which can be on a smaller screen (a docked laptop closed on its 1366x768 panel), so the composer sat under the panel again. The fit now reads the plugin's saved record and picks the monitor the plugin restores to, with the plugin's own rule (a corner of the saved rectangle on a monitor, the place before maximizing for a maximized window); without one, the primary monitor. A window left low or far right is then moved inside that screen's work area right after the plugin's move. - On Wayland the smallest screen forced a maximized window on every screen, which the user could not undo (the plugin only ever maximizes). The window now fits every screen and opens maximized only when none of them holds the 520x640 minimum. - GTK's header bar is inside the size the window asks for on Wayland (1.0.0's 1380x920 window measured 920 px with it on Plasma; Weston reports 1380x920 geometry with 873 px of content), so the 48 px title bar room was taken twice: 1229x643 on 1366x768 left about 596 px of content. The room now applies only on X11, where the window manager's frame is outside; Wayland gets 1229x691. The Wayland or X11 display comes from GDK, as tao decides on its header bar (the AppImage runs on X11). 16 window_size tests, including the docked laptop, a 200% screen beside a large one, the 1.0.0 grown record and the work-area move. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 45b0d53 commit 6364826

4 files changed

Lines changed: 686 additions & 88 deletions

File tree

‎Cargo.lock‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src-tauri/Cargo.toml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ tauri-build = { version = "2", features = [] }
1818
[dependencies]
1919
shadowcode-core = { path = "../native/core" }
2020
anyhow = "1"
21+
serde = { version = "1", features = ["derive"] }
2122
serde_json = "1"
2223
tokio = { version = "1", features = ["signal"] }
2324
tauri = { version = "2", features = [] }
@@ -31,6 +32,9 @@ tauri-plugin-window-state = "2"
3132
# a click on desktop); the same crate the plugin already uses.
3233
[target.'cfg(target_os = "linux")'.dependencies]
3334
notify-rust = "4"
35+
# Whether GTK opened a Wayland or an X11 display (the window's first size);
36+
# the same crate tao already uses.
37+
gdk = "0.18"
3438

3539
[features]
3640
default = ["custom-protocol"]

‎src-tauri/src/main.rs‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,8 @@ fn run() -> Result<()> {
419419
.plugin(tauri_plugin_opener::init())
420420
.plugin(tauri_plugin_notification::init());
421421
if !isolated {
422-
// Remembers where the window was and whether it was maximized, not its
423-
// size (see `window_size::REMEMBERED`).
422+
// Remembers whether the window was maximized or full screen and, on
423+
// X11, where it was, but not its size (see `window_size::REMEMBERED`).
424424
builder = builder.plugin(window_size::state_plugin());
425425
}
426426
let preview_ports = PreviewPorts::default();
@@ -478,11 +478,14 @@ fn run() -> Result<()> {
478478
.context("Window configuration missing")?
479479
.clone();
480480
// A screen smaller than the configured window (1366x768) gets a
481-
// window that fits it, title bar and panel included.
482-
if let Some(screen) = window_size::opening_screen(app) {
483-
window_size::fit_config(&mut config, screen);
481+
// window that fits it, title bar and panel included: the screen
482+
// the window-state plugin moves it back to on X11, every screen
483+
// on Wayland.
484+
let opening = window_size::opening_on(app, !isolated);
485+
if let Some(opening) = &opening {
486+
window_size::fit_config(&mut config, opening);
484487
}
485-
tauri::WebviewWindowBuilder::from_config(app, &config)?
488+
let window = tauri::WebviewWindowBuilder::from_config(app, &config)?
486489
.data_directory(webview_data)
487490
.on_navigation(move |url| {
488491
// WebKitGTK asks for every frame, so this also admits the
@@ -497,6 +500,17 @@ fn run() -> Result<()> {
497500
&& url.port() == Some(5174))
498501
})
499502
.build()?;
503+
// Building the window queued the plugin's move back to where it
504+
// was (X11); this move follows it and keeps the fitted window
505+
// inside that screen's work area.
506+
let inside = opening
507+
.filter(|_| !config.maximized)
508+
.and_then(|opening| opening.inside_work_area((config.width, config.height)));
509+
if let Some((x, y)) = inside {
510+
if let (Ok(x), Ok(y)) = (i32::try_from(x), i32::try_from(y)) {
511+
let _ = window.set_position(tauri::PhysicalPosition::new(x, y));
512+
}
513+
}
500514
let handle = app.handle().clone();
501515
tauri::async_runtime::spawn(async move {
502516
loop {

0 commit comments

Comments
 (0)