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.09k stars 2.57k forks source link

[bug] document.visibilityState broken #10592

Open ConnorKrammer opened 3 months ago

ConnorKrammer commented 3 months ago

Describe the bug

I cannot seem to get the browser visibilitychange event to fire by any means, and whether maximized or minimized, document.visibilityState always has the value "visible". This is on Windows 10.

There is some prior history for this issue. #6864 describes the lack of visibilitychange event when hiding the window behind another window, but describes the event as firing when the window is minimized and maximized. The more recent #9524 again confirms that it fires when minimized or maximized. (The author of that issue believed it should also fire when a window gains or loses focus, but that just seems to originate in confusion about what page visibility represents.) #9246 appears to change webview visibility on minimize/maximize, and then #9465 reverts it.

This seems to trace back to this WebView2 issue. As described in this comment, the issue—at least at the time—was because "Minimizing a window in WPF does not inherently change the Visibility property of its child controls." If this is the case, though, then I'm not sure how the first two issues above ever recorded visibilitychange events on minimize and maximize.

It seems that window occlusion has never caused the document visibility state to change in Tauri, but there has been a regression causing it to no longer update upon minimize/maximize either. document.visibilityState simply never appears to change anymore, and always reports itself visible.

Reproduction

Nothing in particular is needed to reproduce this; just cargo create-tauri-app to create a template program and run it. You can examine the document visibility state in the web inspector.

Expected behavior

The visibilitychange event should fire when document.visibilityState changes. This should occur whenever the document is either revealed or hidden to the user: when switching between minimized and maximized, when showing or hiding the parent tab, or when the edges of the screen and foreground windows occlude or un-occlude the document.

Full tauri info output

[✔] Environment
    - OS: Windows 10.0.19045 X64
    ✔ WebView2: 127.0.2651.98
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.80.0 (051478957 2024-07-21)
    ✔ cargo: 1.80.0 (376290515 2024-07-16)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (environment override by RUSTUP_TOOLCHAIN)
    - node: 18.12.1
    - npm: 8.19.2

[-] Packages
    - tauri [RUST]: 2.0.0-rc.2
    - tauri-build [RUST]: 2.0.0-rc.2
    - wry [RUST]: 0.41.0
    - tao [RUST]: 0.28.1
    - tauri-cli [RUST]: 2.0.0-rc.3
    - @tauri-apps/api : not installed!
    - @tauri-apps/cli [NPM]: 2.0.0-rc.3

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../src

Stack trace

No response

Additional context

No response

Legend-Master commented 3 months ago

I don't know if it ever worked before, but currently, I can't think of a good way of doing it, the last attempt I made in #9246 caused flickering on restore/show (and also doesn't include reacting to window occlusions)

I was thinking about maybe emitting those events ourselves instead of using the webview2's SetIsVisible, but that wouldn't enable the browser to optimize for not visible, e.g. making the animations stop

It's really a shame that this is part of the web API but not easily doable with webview2 >.<

About #9524, I think he's on macOS, and the webview being used is different, also I don't think losing focus will change the visibility to hidden on all major browsers (I could be wrong, never tried it on a mac before)

ConnorKrammer commented 3 months ago

About https://github.com/tauri-apps/tauri/issues/9524, I think he's on macOS, and the webview being used is different, also I don't think losing focus will change the visibility to hidden on all major browsers (I could be wrong, never tried it on a mac before)

Yep, you're correct about this: browsers don't (or at least, aren't supposed to) change the document visibility state upon losing focus, because losing focus by itself doesn't change whether the document is visible or not. You can see how the page visibility spec describes proper behaviour here.

The most complete possible adherence to the spec is actually somewhat involved, because it accounts for anything which can affect a user's ability to observe a page, such as window occlusion and whether assistive technologies are attached to the document (because an occluded window with a screen reader attached to it is still "visible" to the user). Not all browsers are necessarily compliant to that degree; Firefox for example has a bug open for implementing occlusion support. In the discussion on that page you can see some analysis of how Chromium implements that feature, and it's not trivial. Frustratingly, I believe we'd literally be getting all of that prior work for free if WebView2 wasn't getting in the way.

A fix on WebView2's side would be the most ideal outcome, but I don't really get the sense anyone working on it has this as a priority. Barring that, if we could figure out how to handle minimize and maximize without the flicker issue, that would handle the most important case, making the feature work evenly in Tauri across platforms and at least putting us at parity with Firefox, if not Chrome.