[feat] frontend: dynamic resize, based on content #12420
Open
Description
Describe the problem
If you want to have dynamic sized window, so based on the content, it's quite difficult to achieve this. It would be nice, if there would be a easy to make this possible.
Describe the solution you'd like
It would be nice, if you could build windows with a settings like .fit_size_to_content()
tauri::WebviewWindowBuilder::new(
app,
WINDOW_LABEL,
tauri::WebviewUrl::App("/dashboard".into()),
)
.title("Motion Minute - Actionbar")
.center()
.fit_size_to_content()
.build()?;
Alternatives considered
My current workaround for my Svelte project is to have a AutoSize component:
<script lang="ts">
import {onMount, onDestroy, tick} from 'svelte';
import {getCurrentWindow, PhysicalSize} from '@tauri-apps/api/window';
import {type} from "@tauri-apps/plugin-os"
import type { Snippet } from 'svelte';
import {debug} from "@tauri-apps/plugin-log";
interface Props {
ready: boolean;
children: Snippet;
[key: string]: unknown;
}
let {ready = true, children, ...rest}: Props = $props();
let container: HTMLDivElement | null = $state(null);
async function resizeWindow() {
const currentWindow = getCurrentWindow();
await debug("resizeWindow called");
if (container && ready) {
await tick();
let rect = container.getBoundingClientRect()
const factor = window.devicePixelRatio;
const width: number = Math.ceil(rect.width * factor);
const height: number = Math.ceil(rect.height * factor);
let topPadding = await currentWindow.isDecorated() && type() === 'macos' ? 55 : 0
let size = new PhysicalSize(width, height + topPadding);
let current = await currentWindow.outerSize()
await debug(`size before ${current.width}x${current.height}`)
await debug(`size after ${width}x${height + topPadding}`)
await currentWindow.setSize(size);
await tick();
await currentWindow.center();
await currentWindow.show();
await currentWindow.setFocus();
}
}
let observer: ResizeObserver;
onMount(async () => {
observer = new ResizeObserver(async () => {
await resizeWindow();
});
if (container) observer.observe(container);
});
onDestroy(() => {
debug("unmount observer");
if (observer) observer.disconnect();
});
</script>
<div {...rest} bind:this={container}>
{@render children?.()}
</div>
This seems to work, but not always. Maybe there exist a better workaround for this.
Additional context
No response