tauri-apps / tauri

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

[bug] visibilitychange event not fired #9524

Open david-mkl opened 7 months ago

david-mkl commented 7 months ago

Describe the bug

The visibilitychange event does not fire when the application loses/gains focus (for example, the user switches to a different application). The event does fire when the window is minimized or maximized.

(I am aware of https://github.com/tauri-apps/tauri/issues/6864, but it appears that issue was closed/merged so I am not sure if it fully addressed the issue).

Reproduction

Attach a listener to the visibilitychange event and log out the event.

document.addEventListener("visibilitychange", (event) => {
  console.log("changed!", event);
});

The event will not fire when the user switches to another application, but will be fired if the application is minimized or maximized.

Expected behavior

No response

Full tauri info output

[✔] Environment
    - OS: Mac OS 14.1.1 X64
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.76.0 (07dca489a 2024-02-04)
    ✔ cargo: 1.76.0 (c84b36747 2024-01-18)
    ✔ rustup: 1.26.0 (5af9b9484 2023-04-05)
    ✔ Rust toolchain: stable-aarch64-apple-darwin (default)
    - node: 21.6.2
    - npm: 10.2.4

[-] Packages
    - tauri [RUST]: 2.0.0-beta.15
    - tauri-build [RUST]: 2.0.0-beta.12
    - wry [RUST]: 0.39.1
    - tao [RUST]: 0.27.0
    - @tauri-apps/api [NPM]: 2.0.0-beta.6
    - @tauri-apps/cli [NPM]: 2.0.0-beta.11

[-] App
    - build-type: bundle
    - CSP: default-src 'self'; media-src 'self' asset: https://asset.localhost; connect-src ipc: http://ipc.localhost
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/
    - framework: React
    - bundler: Vite


### Stack trace

_No response_

### Additional context

_No response_
david-mkl commented 7 months ago

Here's my workaround for now. You can use the window Focused event on the rust side, then emit that to the frontend. For example

// ....
.on_window_event(|window, event| {
    match event {
        tauri::WindowEvent::Focused(focus) => {
            let app = window.app_handle();
            app.emit("visibilitychanged", focus).unwrap()
        },
        _ => (),
    }
})
// ....

Then on the frontend (for example with React)

useEffect(() => {
  const listener = listen<boolean>("visibilitychanged", (event) => {
    console.log(event)
  })

  return () => {
    listener.then((f) => f())
  }
}, [])