tauri-apps / tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
https://tauri.app
Apache License 2.0
84.85k stars 2.56k forks source link

[bug][macOS] After exiting the fullscreen, read window still is fullscreen #4519

Open mantou132 opened 2 years ago

mantou132 commented 2 years ago

Describe the bug

After exiting the fullscreen, below to the code print true

tauri::WindowEvent::Resized(_) => {
   println!("is_fullscreen {:?}", event.window().is_fullscreen());
}
Screen Shot 2022-06-30 at 01 58 20

Similarly, JS API does not meet expectations:

await window.__TAURI__?.window.getCurrent().isFullscreen()

Reproduction

  1. clone https://github.com/mantou132/tauri-app-test
  2. cargo tauri dev
  3. enter fullscreen and exiting fullscreen
  4. view console

Expected behavior

print:

is_fullscreen Ok(true)
is_fullscreen Ok(false)

Platform and versions

Environment
  › OS: Mac OS 12.4.0 X64
  › Node.js: 18.3.0
  › npm: 8.11.0
  › pnpm: 6.11.0
  › yarn: 1.22.15
  › rustup: 1.24.3
  › rustc: 1.63.0-nightly
  › cargo: 1.63.0-nightly
  › Rust toolchain: nightly-x86_64-apple-darwin 

Packages
  › @tauri-apps/cli [NPM]: 1.0.0
  › @tauri-apps/api [NPM]: 1.0.0-rc.7

Stack trace

No response

Additional context

No response

mantou132 commented 2 years ago
tauri::WindowEvent::Resized(size) => {
    let monitor = event.window().current_monitor().unwrap().unwrap();
    let screen = monitor.size();
    println!("{:?}, {:?}", size, screen);
    if size == screen {
        println!("{}", true);
    } else {
        println!("{}", false);
    }
}

This code result meets expectations

lucasfernog commented 2 years ago

This happens because the resized event is emitted before macOS notifies tao that the window has been changed to fullscreen. Maybe we could immediately set the new fullscreen state in tao @amrbashir @wusyong

mvrlin commented 2 years ago
tauri::WindowEvent::Resized(size) => {
    let monitor = event.window().current_monitor().unwrap().unwrap();
    let screen = monitor.size();
    println!("{:?}, {:?}", size, screen);
    if size == screen {
        println!("{}", true);
    } else {
        println!("{}", false);
    }
}

This code result meets expectations

@mantou132 Doesn't work on new MBP with notch :(

mvrlin commented 2 years ago

This code works, but it's really not a good solution.

// main.rs

tauri::Builder::default()
    .on_window_event(|event| match event.event() {
        tauri::WindowEvent::Resized(_) => {
            event.window().emit_all("resize", "").unwrap();
        }
         _ => {}
    })
    // .setup
import { appWindow } from '@tauri-apps/api/window'

let isFullscreen = false
let resizeTimeout = 0

appWindow.listen('resize', async () => {
    await new Promise((resolve) => {
        window.clearTimeout(resizeTimeout)
        resizeTimeout = window.setTimeout(resolve, 6e2)
    })

    // set the value
    isFullscreen = await appWindow.isFullscreen()
})
mantou132 commented 2 years ago

@mvrlin now need listen WindowEvent::Moved(_) https://github.com/mantou132/nesbox/blob/dev/packages/tauriapp/src/main.rs#L48

mvrlin commented 2 years ago

@lucasfernog can you fix the delay?

lucasfernog commented 2 years ago

Which delay @mvrlin ? We need to fix this issue directly :)

mvrlin commented 2 years ago

@lucasfernog By delay I meant update fullscreen state before the resize event 😀

stevebauman commented 1 year ago

I was able to resolve this in my own Vue app by storing the previous value of isFullscreen and simply setting my local value to false if the previous value was true, indicating that fullscreen was exited:

import { appWindow } from '@tauri-apps/api/window';
import { onMounted, ref } from "@nuxtjs/composition-api";

export default {
    setup() {
        const isFullscreen = ref(false);
        const previousIsFullscreen = ref(false);

        const updateFullscreen = async () => {
            previousIsFullscreen.value = isFullscreen.value;

            previousIsFullscreen.value === true
                ? (isFullscreen.value = false)
                : (isFullscreen.value = await appWindow.isFullscreen());
        };

        appWindow.onResized(_.debounce(updateFullscreen, 500));

        onMounted(updateFullscreen);

        return { appWindow, isFullscreen };
    },
};
mvrlin commented 1 year ago

@stevebauman you are doing the same thing as me, you are calling a function after 500ms. The goal was to make Tauri resolve the Promise when the system event actually happened.