Skip to content

[feat] frontend: dynamic resize, based on content #12420

Open
@don41382

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

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions