On startup the WebEngineView first shows the bundled qrc find-webclient
page and then navigates to the server web client. That cross-origin
navigation moves the view to a new renderer process, and a user script
registered on the view is not reliably delivered to it, so the first
load of the web client comes up without window.NativeShell. jellyfin-web
then falls back to its HTML video player: playback works, but the native
mpv player, MPRIS, and client settings are silently unavailable until
the page is reloaded.
Registering the script on the profile instead makes injection apply to
every load, including the first one. Verified on Linux (Qt 6.11.2,
Wayland): before the change window.jmpInfo was undefined on every cold
start until a reload; after it is present on the first load.
Displays a system tray icon when enabled. Closing the window (clicking the X or Alt+F4) hides the window.
The window can be restored by clicking the icon, or via its context menu. The application can be quit via the context menu or Ctrl+Q.
Default: Disabled
Closes#470
It is really late so I'm calling it here. I wanted to put this out for relevant people to get eyes on, in order to aid in getting the Windows build of v2.0.0 out. Apologies in advance for not following any contrib guidelines or there being messes. I'm leaving in the build scripts I used for now. The build scripts still contain a few hardcoded visual studio related values for now. At the moment when I run the app on a different machine to the dev VM I'm using the qt web view doesn't seem to be rendering.
summary of where this is at:
the whole thing builds
works on my Windows 11 virtual machine
short summary of what I did:
A couple of qt6 updates specific to windows were addressed.
Some build system issues were addressed
did some minor refactoring to sieve out binary build dependencies from generated build files since its a lot easier when you can just delete the build folder to run a clean build
The JMP window would sometimes be blank/black after un-minimizing and
resuming from suspend. Moving the cursor briefly in the window would
then resolve the issue.
Tested on Arch Linux/Plasma 6/Wayland/AMD 6900XT
Probably works for others
- Remove --disable-web-security flag as it's no longer needed
- There are no CORS nor CPS issues
- mpv integration works
- the service worker works
- Bundle JMP web bridge resources in application binary (file:// -> qrc://)
- This keeps installs cleaner and removes the risk of the native
files going missing or using the incorrect paths.
- Using file:// also had some issues with CSP
- The JS assets are combined into a single JS script which is
injected as a user script. This bypasses CSP issues.
- Replace connectivity check and web HTML retrieval JavaScript methods
with C++ methods. This works around CORS issues on the server
selection page.
The old code probably didn't miss any change notifications, but it sent
too many of them. QML won't figure out property changes on its own, and
might recompute property bindings on every change notification. I
suspect this caused "binding loops" and crashes. (I wasn't able to
reproduce them. There is no doubt binding loops happen, and they are
most likely responsible for crashes we are seeing.)
Make change notifications fine-grained for every relevant property. Most
of these are for the web scaling nightmare, and thus are size-dependent.
Some also depend on the web mode (TV vs. desktop), but the commit moves
this dependency into the .qml, which makes this much easier.
The webUrl property remains a bit "dangerous", because the initialScale
parameter takes a snapshot value. Re-reading the webUrl property might
return a different value at runtime, but we do _not_ want to have a
proper change notification, as that would make the WebEngine element
reload the URL. We don't want to reload web-client only because it's
resized. I'm hoping to get rid of the initialScale URL parameter
completely. Currently it's definitely needed.
We frequently have the problem that the debug overlay is cut off on the
bottom. QML doesn't appear to provide anything to auto-fit the text on
the debug overlay (well, maybe it shouldn't anyway). So try other means
of making more space.
Cut off long fields on the right panel (playback status). This
specifically cuts off the transcode URL at 400 characters. 400
characters should be enough to know some of the more basic info, like
source host/API and endpoint. You'll have to get the playback log to get
the full URL.
Scale the font size by the window height, not width. It was scaled by
width for the sake of long strings like log path and playback URL, but
using height seems generally better. Also use Math.round, as the
pixelSize is an integer (and will round down by default).
We could probably use pointSize, but it might be rounded too, and I'm
scared of what that might mean if hidpi is active on various platforms.
It appears this was a mistake. Now the shortcuts are consistent with
input.json, and with the shortcuts for MacOS.
Shift+F11 will always toggle fullscreen and not switch the mode (both in
TV and desktop mode). F11 will always toggle fullscreen and web mode,
like the UI button does.
Now that the web-client is bundled with the binaries in the resources
directory we want to load it from there directly as well.
Since many configuration point the startup URL to
qrc://konvergo/index.html we need to migrate them to a new value.
Instead of putting the full file:// url in this setting I made a
special value called "bundled" instead that will always point to the
latest version of the bundled web-client. This makes any future
migrations unnecessary.
This is implemented in a new function in SettingsComponent as opposed
to just reading the values raw.
This introduces two new pieces of information to the web-client. First
the web client is loaded with initialScale=XX on the query string.
Secondly there is now a system component signal that can be used to see
when the scale should be updated: channel.system.onScaleChanged(XX)
We need to make sure that the maxHeight is calculate by splitting it by
devicePixelRatio since size() in Qt is the *real* size and not the size
/ dpr, so when calculating the different scales, make sure to use dpr
to split max height and get a scaled value.
Also trigger the scale update when switching into fullscreen and back
to windowed mode.
QQuickWebEngineView::setUrl has a particular behavior vs other QML
properties that it doesn't check if the value is the same before
applying a new binding result. This means that if any of the binding
dependency changes ("Screen" in this case), the page will reload.
Since we always ever only want to set the URL once, set the url
property imperatively in Component.onCompleted. This however means
that the maxHeight query parameter will be wrong if the window
is later switched to a screen that would provide a different height.
This should help for #163 and possibly #155.
We take devicePixelRatio into consideration here so that screens with
DPR==1 don't get upscaled from 720 pixels (which doesn't look good).
Related to #10