Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changes/linux-content-fixed-overlay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": minor
---

On Linux, add a full-window `gtk::Fixed` overlay layer to each window (alongside the default vertical `gtk::Box`), exposed via `WindowExtUnix::content_fixed()`. A runtime can build positioned child webviews into this `gtk::Fixed` so they overlay the window and honor their bounds, instead of stacking beside the default box (GTK divides a vertical box among its children, which breaks multi-webview positioning — tauri-apps/tauri#10420). The default box stays the overlay's main child, so single-webview windows are unchanged.
8 changes: 8 additions & 0 deletions src/platform/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ pub trait WindowExtUnix {
/// Returns `None` if the default vertical `gtk::Box` creation was disabled by [`WindowBuilderExtUnix::with_default_vbox`].
fn default_vbox(&self) -> Option<&gtk::Box>;

/// Returns the full-window `gtk::Fixed` overlay layer that hosts positioned
/// child webviews. `None` when the default `gtk::Box` creation is disabled.
fn content_fixed(&self) -> Option<&gtk::Fixed>;

/// Whether to show the window icon in the taskbar or not.
fn set_skip_taskbar(&self, skip: bool) -> Result<(), ExternalError>;

Expand All @@ -97,6 +101,10 @@ impl WindowExtUnix for Window {
self.window.default_vbox.as_ref()
}

fn content_fixed(&self) -> Option<&gtk::Fixed> {
self.window.content_fixed.as_ref()
}

fn set_skip_taskbar(&self, skip: bool) -> Result<(), ExternalError> {
self.window.set_skip_taskbar(skip)
}
Expand Down
27 changes: 23 additions & 4 deletions src/platform_impl/linux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct Window {
/// Gtk application window.
pub(crate) window: gtk::ApplicationWindow,
pub(crate) default_vbox: Option<gtk::Box>,
/// Full-window `gtk::Fixed` overlay layer for positioned child webviews, so a
/// runtime can place them over the window instead of stacking them beside the
/// default box. `None` when the default `gtk::Box` creation is disabled.
pub(crate) content_fixed: Option<gtk::Fixed>,
/// Window requests sender
pub(crate) window_requests_tx: glib::Sender<(WindowId, WindowRequest)>,
scale_factor: Rc<AtomicI32>,
Expand Down Expand Up @@ -152,12 +156,25 @@ impl Window {
}
}

let default_vbox = if pl_attribs.default_vbox {
let (default_vbox, content_fixed) = if pl_attribs.default_vbox {
let box_ = gtk::Box::new(gtk::Orientation::Vertical, 0);
window.add(&box_);
Some(box_)
// Wrap the content in a `gtk::Overlay` so positioned child webviews can be
// placed over the window rather than stacking beside the default box — GTK
// divides a vertical box among its children, which breaks multi-webview
// positioning (tauri-apps/tauri#10420). The default box stays the overlay's
// main child, so single-webview windows are unchanged; a pass-through
// `gtk::Fixed` overlay layer hosts positioned child webviews.
let overlay = gtk::Overlay::new();
window.add(&overlay);
overlay.add(&box_);
let fixed = gtk::Fixed::new();
fixed.set_halign(gtk::Align::Fill);
fixed.set_valign(gtk::Align::Fill);
overlay.add_overlay(&fixed);
overlay.set_overlay_pass_through(&fixed, true);
(Some(box_), Some(fixed))
} else {
None
(None, None)
};

// Rest attributes
Expand Down Expand Up @@ -262,6 +279,7 @@ impl Window {
window_id,
window,
default_vbox,
content_fixed,
window_requests_tx,
draw_tx,
scale_factor,
Expand Down Expand Up @@ -405,6 +423,7 @@ impl Window {
window_id,
window,
default_vbox: None,
content_fixed: None,
window_requests_tx,
draw_tx,
scale_factor,
Expand Down