Drop multiple QtWebEngine's in a single window

Currently, the Anki main window is rendered by 3 QtWebEngine pages.

Issues like Text is cut off point out that QT is not very nice when it updates and constantly breaks ints interface in some platform.

An alternative would be every Anki window to be rendered by a single QtWebEngine page, i.e., all purely Javascript/HTML in a single QtWebEngine page.

This way, Anki would move out from QT widgets and would depend solely on Javascript/HTML to render its interface.

2 Likes

Once the work on libanki is finished, I’d like to turn my attention to the UI side of things. Qt does cause many problems, but a lot of Anki and Anki add-ons currently depend on it, so if we go down that path it will be a large undertaking.

3 Likes

Just chiming in to voice that switching away from Qt would completely dwarf the 2.0 → 2.1 migration in terms of add-on support (even worse of course for switching to web technologies across the full stack, which some people were chatting about on Discord recently).

Any major step like this would require incredibly careful deliberation as it would basically eliminate a decade of add-on development work and knowledge in one fell swoop.

Should we get to a point where a major technology migration like this is on the table, it would be incredibly important for add-on authors to receive notice way ahead of time. Looking at the 2.0 → 2.1 migration, we’re talking in terms of years instead of months. If this is even a remote possibility, as an add-on author I need to know about it now in order to adjust and not waste hundreds of hours on working with technologies that will break my add-on in a year.

I realize that this topic is about a more incremental change, but even just switching away from Qt widgets to unified QtWebEngine views for Anki’s UI already entails rewriting hundreds of add-ons. So the same still applies here, even if to a smaller degree.

3 Likes

Instead of removing the actual QT interface (front-end), a new front-end (Javascript) could be written using the new Rust back-end. This way, such new front-end could be used on Desktop/Android/iOS by properly wrapping it around web engines in each platform.

This way, Anki could have the same front-end and back-end in all platforms. Which would also make possible to have (Javascript) addons which work in all platforms.

Also, another advantage of a Javascript interface would be unit testing it. Using frameworks as puppeteer, we can easily automate the testing of the interface as I did for this pull request: https://github.com/ankitects/anki/pull/604 - Created the AnkiMediaQueue for JavaScript media support

1 Like

I’m not sure I fully understand what you’re envisioning by saying:

Instead of removing the actual QT interface (front-end), a new front-end (Javascript) could be written using the new Rust back-end.

If you mean having two alternate front-ends (FE) on desktop, one with the current technology stack (JS/Python/Qt), and one JS-only, then to me that would be functionally the same as switching away from Qt. A coexistence of two FEs is simply not tenable in the long run, and one of them will eventually win out in terms of development focus.

If instead you mean retaining the current PyQt stack in order to provide the web view for the new JS FE, then I don’t see how that would address any of the issues we’re currently facing with Qt. We’d still have to deal with the headaches created by hardware acceleration and QtWebEngine’s problems in general.

Though getting back to the overarching thought, a JS front-end / Rust back-end was what I was alluding to in the previous post. (Full stack switch to JS was a misnomer there. By that I just meant the scenario where both Qt and all its supporting Python code would be replaced by JS.)

I realize that having the same FE/BE on all platforms is the fabled cross-platform panacea. But I’ve yet to see this work well in practice for any app of significant complexity. Quite a few major development teams that were early adopters of ideas like this have since abandoned that approach e.g. AirBnB with React Native, or DropBox with their custom C++ core. As it turns out, while you do write less platform-specific code, you still have to deal with platform-specific bugs and performance issues (not too dissimilar from Qt, just the with additional headaches of mobile platforms). So creating one “universal” code base ends up being almost as much work as working with each platform’s native technologies.

Straying away for a moment from the dev perspective and all the concerns I have for the add-on dev community, even just as a user I’d hate to see Anki Desktop, AnkiMobile, and AnkiDroid entirely switch to non-native frontends. Users already lament that 2.1 is much slower than 2.0 in any UI interaction that largely depends on web views. Now imagine this for Anki desktop as a whole – how janky the browser would be, how annoying the delays would be for each dialog to render its own little web view.

There’s a reason why users will often state their disdain for Electron – there just aren’t many examples of performant Electron apps out there. VS Code might just be the only one I know of, but that required the full development force of Microsoft to forge something usable out of the technology stack. Just compare it to the dreadful performance of Atom (which funnily enough is now also under Microsoft’s umbrella). I fear that, if Anki were ever to switch to a full JS front end, we’d have more of an Atom situation than a VS Code situation on our hands.

This scenario is worse still for AnkiDroid and AnkiMobile of course. Both mobile apps are very performant for the workloads they’re commonly facing, and I know that AnkiDroid has made some great new performance wins recently. I would hate to see that performance lost in favor of chasing after that pipe dream of unification.

Also, from a UI/UX standpoint, both Anki Desktop, AnkiDroid, and AnkiMobile behave exactly as you would expect them to do on each platform. Android users don’t have to deal with inconsistent interactions that might make sense on iOS and vice versa. And desktop users don’t have to suffer because of concessions made to the fact that the same stack is also used on mobile or on the web. App unification more often than not means settling for the lowest common denominator, and that leads you to an app that doesn’t look or work properly on any platform.

Moving back to the development side of things: Qt might have its faults, but it’s super quick and easy to use for creating UIs, and the results also basically look native to each platform with next to no additional work required. Same with Python: It might not be the most performant language out there, but it’s very easy to grasp and successfully use for add-on development. One of the reasons why Anki’s add-on ecosystem is so rich for Anki’s relative size is because these technologies are so approachable. The basic Python syntax you might learn in high school or programming 101 can already get you quite far, and tools like Qt designer make it super easy to create your first add-on UI.

Compared to that, the learning track for JS/CSS is much more arduous and lined with pitfalls, especially when stacked with whatever framework the fabled unified FE would end up using (be it React, Vue, Svelte, or others).

I also greatly dread the inconsistency that completely leaving widget/component design to add-on authors would introduce. Not only does Qt help with making Anki look native to the platform, it also makes add-ons look native to Anki (starting with the basic look of widgets right up to night mode / theming support). To achieve the same with whatever JS framework you have in mind would mean that Anki would have to provide ready-made UI components that could be used by add-ons. Once again a case where you’d end up duplicating work that’s already served on a platter with a widget toolkit like Qt.

Speaking about Qt: While I think it’s very cool what you did in your PR, I have to point out that there’s nothing preventing us from implementing automated UI tests for Qt. Qutebrowser, which basically has a nearly identical Qt/Python technolgy stack, has been doing so successfully for years now using pytest-qt.

2 Likes

I have not used modern JS/UI frameworks enough at this stage to even know if such a change would be practical or beneficial, so there’s no grand plan to move away from Qt at this point. My goals at the moment are much more limited in scope - I want to get a better feel for the tech, and address Anki’s current webview use, as building HTML from strings is awkward and error prone, and I suspect it could be more ergonomically done in JS using a UI framework.

Is there the remote possibility of a move away from Qt in the long term? It’s not impossible to imagine. If work on the existing webviews goes really well, it may make sense to look into an alternative UI prototype, to get a feel for how it might work outside the existing contexts webviews are used in. Such things would take months and be out in the open if they did happen, and a transition would take a long time.

You make some fair criticisms of JS, and I’m somewhat skeptical about a shared UI as well. Not all is rosy in Qt land either though - the compatibility issues are a constant headache, Qt 6 is likely to break things, and the company’s recent behaviour has me a little worried about its long term future.

3 Likes