mirror of
https://github.com/ankitects/anki.git
synced 2026-07-29 00:19:50 -04:00
editor-focus-queue
3767 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
00dcfc3e8b |
feat: lazy-load MathJax on Reviewer (#5171)
## Linked issue (required) * Closes #5172 ## Summary / motivation (required) Loading MathJax makes the reviewer initialization slower, which is relevant for people who don't use MathJax and slower devices (such as phones) ## Steps to reproduce (required, use N/A if not applicable) N/A ## How to test (required) 1. Opened a deck with a card with no MathJax 2. In developer tools' console,, check whether `MathJax` is not defined 3. Answer some cards until a card with MathJax appears -> Check if it is correctly loaded ### Checklist (minimum) - [X] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> ## Before / after behavior (optional) <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) N/A ## Scope - [X] This PR is focused on one change (no unrelated edits). |
||
|
|
e8d368ca23 |
fix: image occlusion masks lost when adding notes (#5155)
## Linked issue (required) Closes #4754 ## Summary / motivation (required) Image occlusion masks could silently go missing from a note at add time. Two separate problems caused this, both timing dependent, which is why the bug was rare and hard to reproduce. **Problem 1: the editor reset races the add (desktop).** Clicking Add on an image occlusion note saved the note, queued the actual add, and reset the mask editor all at once. The reset clears the canvas, and clearing the canvas writes an empty value into the Occlusions field of the same note object the add was about to read. Depending on which message arrived first: the add worked normally (the common case), the note was added with no masks and no warning, or the add was wrongly rejected with "no occlusion created" while the masks were plainly visible. Fix: reset the mask editor only after the add succeeds, matching the ordering the non-legacy TS editor page already uses. This also means a rejected add no longer wipes the masks you drew. **Problem 2: one field's save cancels another's.** All fields committed through a single shared save timer, and scheduling a save cancelled the timer's previous pending action. Mask edits commit the Occlusions field through that timer with a 600 ms debounce, so typing into Header or Back Extra within 600 ms of the last mask edit threw away the pending occlusions write. It was never retried, because later saves saw the store already held the same value and skipped notifying. Every mask drawn since the last committed write was then missing from the added note. Fix: give each field its own timer. This also surfaced a second bug in `ChangeTimer` itself: an action scheduled while `fireImmediately()` was awaiting a previous action was silently discarded when that await finished; fixed by taking the action before running it and letting a concurrent flush wait for the run in flight. ## Steps to reproduce (required, use N/A if not applicable) Problem 2 (reliably reproducible): 1. Add an Image Occlusion note, draw a mask, wait for it to auto-commit (~1s). 2. Draw a second mask. 3. Immediately (within ~600 ms) switch to the fields view and type a character into Header. 4. Wait a second, click Add. 5. Before this fix: the added note is missing the second mask. No warning is shown. Problem 1 (event-loop timing dependent, not reliably reproducible by hand): 1. Add an Image Occlusion note, paste an image, draw one or more masks. 2. Click Add. 3. Before this fix: rarely, the note is added with an empty Occlusions field and no warning, or Add is rejected with "no occlusion created" while masks are visible on screen. ## How to test (required) ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details - `ts/tests/e2e/io-mask-save-race.spec.ts` reproduces problem 2 with real mouse drawing and real keystrokes at the real 600 ms timing. Fails on current `main` (payload contains 1 cloze instead of 2, consistently across repeated runs) and passes with this change. - `ts/lib/editable/change-timer.test.ts` covers the discarded-action case in `ChangeTimer` and fails without the fix. - Full Playwright e2e suite (`just test-e2e`) passes repeatedly across fresh profiles. - `just fmt`, `just lint`, and the vitest suite are clean. - Problem 1 has no reliable automated test: the outcome depends on how the Qt event loop interleaves two webChannel messages and a background task. I verified the mechanism with a scripted headless Anki that drives the real `AddCards` flow and delivers the racing write inside the vulnerable window, and confirmed by inspection that after this change the empty write can no longer be issued while an add is in flight. ## Before / after behavior (optional) Before: masks could be silently dropped from a newly added note (problem 2, common), or the note could be added completely empty of masks / spuriously rejected (problem 1, rare). After: neither race is possible; a rejected add also no longer clears the masks you've drawn, so you can fix the note and retry instead of redrawing. ## Risk / compatibility / migration (optional) Low risk. Both fixes are ordering/scoping changes with no behavior change outside the affected race windows. No schema, API, or migration changes. ## UI evidence (required for visual changes; otherwise N/A) N/A (no visual/UI changes). ## Scope - [x] This PR is focused on one change (no unrelated edits). This PR contains two fixes rather than one. I considered splitting them, but both are root causes of the same reported bug (#4754) discovered during the same investigation, they are already isolated into two separate commits for review, and neither is a complete fix for the issue on its own. Happy to split into two PRs if you'd prefer. --------- Co-authored-by: llama <gh@siid.sh> |
||
|
|
db98bb675a |
feat: Experimental options in preferences (#5057)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) <!-- Fixes #123 / Closes #123 / Refs #123 --> closes #4871 ## How to test (required) Find "Labs" as a new option in the preferences ### Checklist (minimum) - [X] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> I've implemented the "Labs" feature in a web-view as I presume we are moving away from QT and Currently these options have no function. Before we can add the functionality we should try and come up with the pattern that we should use to register new flags. ## UI evidence (required for visual changes; otherwise N/A) <img width="746" height="736" alt="image" src="https://github.com/user-attachments/assets/28c4fd28-a593-4599-b43e-c2c23881251e" /> <img width="746" height="736" alt="image" src="https://github.com/user-attachments/assets/c1cd69f9-3d8d-4866-a784-030b4274b4e7" /> ## Scope - [X] This PR is focused on one change (no unrelated edits). |
||
|
|
9863b2f142 |
fix: Work around race issue with activeWindow() in request handlers (#5136)
## Linked issue
Reported on
[Discord](https://discord.com/channels/368267295601983490/373169624797282304/1524169568862601287).
## Summary / motivation
We call `QApplication.activeWindow()` in several mediasrv request
handlers to get a parent for Qt dialogs or do asynchronous operations,
but it returns None on some systems, apparently due to race issues.
```
Anki 26.05 (
|
||
|
|
3c9f2f7dff |
fix: clean up FindDuplicatesDialog's webview on close to prevent theme-change crash (#5143)
## Linked issue (required) Fixes #5140 ## Summary / motivation (required) `FindDuplicatesDialog` never called `AnkiWebView.cleanup()` on close, unlike the other dialogs that embed a webview (`EmptyCardsDialog`, `CardInfoDialog`, `NewDeckStats`), which all do. Without it, the webview's `on_theme_did_change` stays registered in `gui_hooks.theme_did_change` after Qt destroys the underlying C++ widget, so a theme change shortly after close crashes with `RuntimeError: wrapped C/C++ object of type FindDupesWebView has been deleted`. ## Steps to reproduce 1. Open Find Duplicates (Notes menu → Find Duplicates). 2. Close the dialog. 3. Trigger a theme change (toggle system light/dark mode). 4. Anki crashes with the RuntimeError above. ## How to test Reproduced the crash via the steps above. No automated test included - this change just applies the same `.cleanup()` call the three sibling dialogs already make in their `finished`/`reject` handler. `./ninja check` passes. ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. (same pattern as EmptyCardsDialog/CardInfoDialog/NewDeckStats - see above) ## Before / after behavior Before: closing Find Duplicates then triggering a theme change could crash Anki. After: the dialog cleans up its webview like its sibling dialogs, so the same theme change no longer touches a deleted object. ## Risk / compatibility / migration None - additive cleanup call, same pattern already used elsewhere in the codebase. ## UI evidence N/A - no visual change. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
77d61d7c38 |
chore: Update Briefcase (#5138)
## Linked issue Related to fixes submitted upstream in #4765 ## Summary / motivation Bump Briefcase and update the templates for some changes: - The option to create a Windows desktop shortcut is shown in the page where the installation path is set instead of its own page. - The minimum Windows build number is set in pyproject.toml and enforced both at build time and install time. - The MSI installer shows required disk space. ## How to test Run `./tools/ninja installer:package` on Windows and give the installer a quick test. |
||
|
|
25e21d6619 |
fix: Do not modify collection if preferences haven't changed (#5135)
## Linked issue Fixes #5128 ## Summary / motivation Avoid marking the collection as modified if the preferences screen is closed without making changes to collection settings. ## Steps to reproduce (before) 1. Open the preferences screen and close it without making changes. 2. Notice _Edit > Undo Preferences_ is active. ## How to test (after) 1. Open the preferences screen and close it without making changes. 2. Notice _Edit > Undo_ is inactive. |
||
|
|
a8ba664e99 |
fix(ci): fix flaky e2e editor tests caused by premature webServer readiness (#5116)
## Linked issue (required) Fixes #5108 ## Summary / motivation (required) `/favicon.ico` responds as soon as mediasrv's HTTP thread starts, before the profile's collection finishes loading, `setupMediaServer()` runs synchronously in `AnkiQt.__init__`, while `setupProfile()` is deferred via a `QTimer`. Playwright's `webServer.url` readiness check polled `/favicon.ico`, so the first e2e test to run in a given CI run could race the async profile load and time out waiting for `.note-editor`, an intermittent false negative, not a real editor bug. This adds `GET /_anki/readyz`, which only returns 200 once `aqt.mw.col` is open (503 otherwise — Playwright's webServer keeps polling on non-2xx/3xx responses), and points `playwright.config.ts`'s `webServer.url` at it instead of `/favicon.ico`. ## Steps to reproduce (required, use N/A if not applicable) 1. Run `just test-e2e` repeatedly on a loaded machine (or add artificial delay to profile loading). 2. Occasionally, the first test in `context-switching.spec.ts` times out at `fixtures.ts:37` (`waitForSelector(".note-editor")`) because Playwright started the test run before the collection had finished opening. 3. See CI failure: https://github.com/ankitects/anki/actions/runs/28748635969/job/85243844164 ## How to test (required) - Ran `just test-e2e` locally and confirmed the suite passes. - Verified `/_anki/readyz` returns 503 immediately after mediasrv starts and 200 once the profile/collection finishes loading, by curling it during `qt/tests/launch_anki_for_e2e.py` startup. - No new test was added — this is a fix to test *infrastructure* (the readiness gate), not to editor behavior; existing e2e specs are the regression coverage. ## Before / after behavior (optional) Before: e2e run could fail intermittently on the first test with a `.note-editor` timeout, unrelated to the change under test. After: `webServer` only accepts traffic once the collection is open, so no test races the profile-load window. ## Risk / compatibility / migration (optional) Low risk. `/_anki/readyz` is a new, isolated, read-only route used only by the e2e harness; no existing behavior changes. |
||
|
|
643187a050 |
Shift editor control to TypeScript (#4029)
Closes https://github.com/ankitects/anki/issues/3830 --------- Co-authored-by: Fernando Lins <fernandolins@users.noreply.github.com> |
||
|
|
f99cfb66cb |
ci: Increase mpv timeout in test (#5098)
Closes #5097 |
||
|
|
7060797747 |
fix: follow Anki's language preference in webview and native form controls (#4935)
## Linked issue (required) Fixes #4823 ## Summary / motivation Webview form controls (e.g. `<input type="date">` picker) were rendered in the operating system's language instead of the language selected in Anki's preferences. The webview never receives Anki's chosen language, so its locale fell back to the system default. This change calls `QLocale.setDefault` passing Anki's resolved language in `setupLangAndBackend()` (`qt/aqt/__init__.py`), right after the language is applied, so locale aware controls follow the user's chosen language, as suggested in issue body. `setupLangAndBackend()` runs during Anki startup and is responsible for setting some language-related Qt state, such as QTranslator, therefore adding the QLocale default setting there is consistent with the existing responsibilities of the function. <img width="2070" height="1574" alt="image" src="https://github.com/user-attachments/assets/40c4a50d-1d39-48ac-b62b-e5db335e69db" /> ## Steps to reproduce 1. Set the operating system language to something other than current Anki lang (my OS is in portuguese) 2. Launch Anki, (e.g. `./run -l en -p teste`, -l is the language parameter) 3. Open a screen with a web date field (e.g. card type edit screen and add `<input type="date">`). 4. The picker's date format render in the system language, not in Anki's language. ## How to test 1. Launch Anki 2. Add > "Cards..." > Add a script like the one bellow to card type template field ```html <input type="date"> <pre id="loc"></pre> <script> document.getElementById('loc').textContent = "navigator.language = " + navigator.language + "\n" + "Intl locale = " + new Intl.DateTimeFormat().resolvedOptions().locale + "\n" + "toLocaleDateString = " + new Date().toLocaleDateString() + "\n" + "month name = " + new Intl.DateTimeFormat(undefined,{month:'long'}).format(new Date()); </script> ``` 3. Check if side preview language matches Anki's language. **You can also check QLocale language in debug console (ctrl+shift+;)** ```py import platform, anki.lang from aqt.qt import QLocale, QSysInfo from anki.utils import version_with_build print("Anki version :", version_with_build()) print("OS :", QSysInfo.prettyProductName(), platform.machine()) print("Anki lang :", anki.lang.current_lang) print("OS language :", QLocale.system().name()) print("QLocale def :", QLocale().name()) print("QLocale is equal to anki lang?", QLocale().name() == QLocale(anki.lang.current_lang).name()) ``` **Debug console script to check if all selectable languages in pylib/anki/lang.py:22-80 resolve to a valid QLocale** ```py import anki.lang from aqt.qt import QLocale # when the language is not valid, QLocale constructor falls back to QLocale.Language.C https://doc.qt.io/qt-6/qlocale.html print("fallback=", QLocale("not a valid language").name()) bad = [] for name, code in anki.lang.langs: disk = anki.lang.lang_to_disk_lang(code) qt_lang = disk.replace("-", "_") loc = QLocale(qt_lang) if loc.language() == QLocale.Language.C: # fallback bad.append((name, code, qt_lang)) print(f"{code:<8} -> {qt_lang:<7} -> {loc.name():<8} {loc.language().name}") n = len(anki.lang.langs) print(f"\ntotal={n} ok={n - len(bad)} fell_back_to_C={len(bad)}") print("FAILURES:", bad if bad else "none — all selectable langs resolve to a valid QLocale") ``` <img width="986" height="667" alt="image" src="https://github.com/user-attachments/assets/83a3bfee-1024-406e-a395-cdba30c61100" /> <img width="726" height="664" alt="image" src="https://github.com/user-attachments/assets/06ea79fe-a4e6-44e1-96b3-2baff8be1f96" /> ### Checklist - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior change This is a trivial change (3 lines) in the Qt layer, and I chose not to add a test for two reasons: - Consistency: other Qt layer related stuff in setupLangAndBackend (such as QTranslator) is not currently tested, and nothing in the existing suite calls this function directly. - I could not find a place where a new test would be a natural fit. I considered adding something to test_i18n.py, but it did not seem aligned with the other tests ## Before (Anki language: Russian, system language: Brazilian Portuguese) <img width="1022" height="408" alt="image" src="https://github.com/user-attachments/assets/62f0af94-c7aa-461f-9a06-f3e42924d459" /> ## After (Anki language: Russian, system language: Brazilian Portuguese) <img width="1027" height="368" alt="image" src="https://github.com/user-attachments/assets/ac11c152-be16-431e-92f0-c7240a25ddda" /> ## Risk / compatibility / migration (optional) Low risk; The fix sets the app-wide default QLocale (via QLocale.setDefault) once at startup, to the language Anki already resolves. Language changes already require a restart (there's even a pop up asking for it), so there is no stale-locale edge. ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
35de142312 |
fix: Skip MpvManager test on Linux (#5094)
Missed a Linux failure in https://github.com/ankitects/anki/pull/5087#pullrequestreview-4617027286 |
||
|
|
b90c8ab120 |
test: strengthen audio playback coverage (#5087)
## Linked issue Refs #5016 ## Summary / motivation Adds follow-up test coverage for audio playback after #5066. This strengthens the previous basic sound tests by covering additional edge cases in `anki.sound` and by adding a real mpv playback smoke test. The goal is to catch regressions where the mpv binary exists and responds to `--version`, but fails to actually load/decode/play an audio file in Anki's automated environment. Coverage added: - `SoundOrVideoTag.path()` with filenames containing directory separators - `hooks.media_file_filter` application in sound tag path resolution - case-insensitive audio extension detection - rejection of filenames without extensions - `_packagedCmd()` preference for `anki_audio` only on macOS/Windows - generated WAV playback through mpv in headless mode ## Steps to reproduce 1. Have a broken or incompatible mpv/`anki_audio` binary available. 2. Run the sound-related Python tests. 3. Without a playback smoke test, `mpv --version` may pass even if mpv cannot load/play an audio file. ## How to test Run: ```sh just test-py ``` Both passed locally. The mpv smoke test generates a minimal WAV file and runs mpv with headless/null audio-video output, so it validates decoding/playback without requiring audio hardware. ## Before / after behavior Before: coverage verified that mpv existed and responded to `--version`, but did not prove it could play/decode an audio file. After: tests verify that mpv can load and play a generated WAV file in an automated headless mode. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
52f9bfb6f9 |
test: add basic tests for sound module and mpv binary (closes #5016) (#5066)
Closes #5016 ## Summary - Adds `pylib/tests/test_sound.py` covering `anki/sound.py`: `SoundOrVideoTag.path()`, `strip_av_refs()`, and `AV_REF_RE` matching - Adds `qt/tests/test_sound.py` covering `aqt/sound.py`: audio file extension detection and mpv binary smoke test (skipped on platforms without a bundled binary) ## How to test ``` just test-py --coverage ``` Feel free to suggest additional tests if this isn't comprehensive enough. |
||
|
|
b29d32c86d |
fix: Additional support for newlines in search (#5045)
## Linked issue (required) Fixes #5046. This is an expansion upon this PR: https://github.com/ankitects/anki/pull/4336 (original issue: https://github.com/ankitects/anki/issues/4215) ## Summary / motivation (required) The previous PR only replaced `\n`. This did not work correctly on some OS/environments (for example, on Windows 11). This PR expands the replacement behavior to `\r\n` and `\r`. ## Steps to reproduce On Windows 11: Add this to an existing card's field: `THIS<BR>IS<BR>AN<BR>EXAMPLE`, then copy paste the rendered HTML to the browser search bar and press enter. Before: no search results. After: the search should behave as expected. ## How to test (required) ### Checklist (minimum) - [ ] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details ## UI evidence (required for visual changes; otherwise N/A) N/A ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com> |
||
|
|
36213cb1a9 |
fix: set minimum height for deck options (#5062)
## Linked issue (required) Fixes #5061 ## Summary / motivation (required) This PR resolves a sizing issue with the options view on Hyprland and possibly other Wayland-based tiling window managers. ### Changes: **Minimum Height Constraint:** Adds `self.setMinimumHeight(500)` to `DeckOptionsDialog._setup_ui()`. This ensures that even when the webview is temporarily hidden on load (`self.web.hide_while_preserving_layout()`), tiling window managers do not collapse the dialog to an unusable height. ## Steps to reproduce (required, use N/A if not applicable) See #5061 ## How to test (required) ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. (The existing dialog geometry helpers cover this, and all Pytest/Aqt checks pass). ### Details Tested manually on a Linux setup running Hyprland: 1. **Minimum Size:** When opening the deck options, the window respects the minimum size constraints and opens at a readable size. <img width="1395" height="1375" alt="image" src="https://github.com/user-attachments/assets/963e9c46-ef7b-42f1-8b54-3a7f9a1473ce" /> ## Before / after behavior (optional) * **Before:** Window opened collapsed into a tiny horizontal box on tiling compositors under Wayland, and user-resized geometries were lost on Save/Cancel close events. <img width="1403" height="626" alt="image" src="https://github.com/user-attachments/assets/5cd02070-4563-4d73-9526-b86c8345649e" /> * **After:** Window is reliably opened at least 500px high, and user size adjustments are correctly saved on all close operations. <img width="1395" height="1375" alt="image" src="https://github.com/user-attachments/assets/963e9c46-ef7b-42f1-8b54-3a7f9a1473ce" /> ## Risk / compatibility / migration (optional) Low risk. A minimum height of 500px easily fits on all standard modern screens (including small laptops). The number may also be changed if this seems too large. ## UI evidence (required for visual changes; otherwise N/A) See screenshots above ## Scope - [x] This PR is focused on one change (no unrelated edits). |
||
|
|
77a523ac27 |
chore: Disable MSI compression on debug build (#5063)
This disables MSI installer compression in debug mode for faster local builds. |
||
|
|
3650ad8396 |
fix: Dont close deck config screen when optimizing all presets (#4981)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) <!-- Fixes #123 / Closes #123 / Refs #123 --> ## Summary / motivation (required) closes https://github.com/ankitects/anki/issues/4978 <!-- What this PR does and why. For larger changes, add enough context for reviewers. --> ## Steps to reproduce (required, use N/A if not applicable) <!-- Steps to reproduce: how to trigger the bug in the broken state (the "before"). - Mainly for bugfixes; - For bugs: numbered steps before the fix. For non-bugs: write N/A. - use N/A for features, refactors, docs, chore, etc. --> 1. press "optimize all presets" 2. the window will save the current settings and cloze after it is done. ## How to test (required) <!--- How to test: how you verified the change (checks, unit tests, manual steps, edge cases — the "after" or general validation). ---> after pressing optimize all presets, you should be prompted if you want to save. After confirming you want to save, the window will remain open when the process completes. ### Checklist (minimum) - [X] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> ## Before / after behavior (optional) <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <!-- Screenshot or short video --> ## Scope - [X] This PR is focused on one change (no unrelated edits). |
||
|
|
7188bf3056 |
fix: Do not block install if registry points to a deleted old elevated install (#5054)
## Linked issue
Closes #5053
## Summary
The MSI installer checks for old elevated installs (pre-2.1.64) via the
Windows registry and asks the user to manually uninstall the old version
(as it requires elevation). There are however cases where the registry
value exists but the path is missing (e.g. if the user manually removes
the Anki folder without running uninstall.exe). This makes it so that
uninstall.exe is confirmed to exist in the folder.
Template change:
|
||
|
|
ff8e4f6e7a |
fix: move add_dynamic_styling_and_props_then_show to _on_load_finished (#4993)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) <!-- Fixes #123 / Closes #123 / Refs #123 --> Fixes #4992 ## Summary / motivation (required) <!-- What this PR does and why. For larger changes, add enough context for reviewers. --> This prevents the webview refreshing from affecting the styling of the page. ## Steps to reproduce (required, use N/A if not applicable) <!-- Steps to reproduce: how to trigger the bug in the broken state (the "before"). - Mainly for bugfixes; - For bugs: numbered steps before the fix. For non-bugs: write N/A. - use N/A for features, refactors, docs, chore, etc. --> 1. Load an anki webview 2. Refresh it (Using the ankiview web inspector addon or otherwise) 3. The body will have none of the classes on it and none of the other styling will be applied ## How to test (required) <!--- How to test: how you verified the change (checks, unit tests, manual steps, edge cases — the "after" or general validation). ---> Follow the reproduction steps and the classes should be the same as before ### Checklist (minimum) - [X] I ran `./ninja check` or an equivalent relevant check locally. - [ ] I added or updated tests when the change is non-trivial or behavior changed. ### Details <!-- Commands, manual steps, edge cases, and what you observed --> ## Before / after behavior (optional) <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> Before (After a refresh): <img width="644" height="103" alt="image" src="https://github.com/user-attachments/assets/888c1794-ed1a-447f-8b14-6cc631a1a1d3" /> After (After a refresh): <img width="644" height="103" alt="image" src="https://github.com/user-attachments/assets/49a7d6af-0292-4907-8faa-258d94190663" /> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <!-- Screenshot or short video --> ## Scope - [X] This PR is focused on one change (no unrelated edits). |
||
|
|
8f39ce82d5 |
chore: Sync with the 26.05 branch (#5041)
This syncs security fixes and translation/version updates from the 26.05 branch. Related: #5039 --------- Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com> Co-authored-by: Damien Elmes <gpg@ankiweb.net> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> |
||
|
|
3b705a1b9b |
fix: All-users MSI installation failing to detect existing installation (#5038)
## Linked issue
Closes #5037
## Summary
#4908 introduced a subtle issue for all-users MSI installations: it was
causing the installer to search for existing per-user installations
_only_, regardless of the user's choice. The fix is to set
`Schedule="afterInstallInitialize"` on the `MajorUpgrade` element so
that the search is done after the user's choice is resolved:
https://docs.firegiant.com/wix/schema/wxs/majorupgrade/
See template fix:
|
||
|
|
0d7b3fdd96 |
feat: Remove the uv launcher and old packaging code (#5019)
## Linked issue Closes #4556 Closes #4557 Closes #4144 Closes #4151 Closes #4152 Closes #4153 Closes #4229 Closes #4356 Closes #4401 Closes #4403 Closes #4519 Closes #4523 Closes #4390 Closes #4414 Closes #4484 ## Summary / motivation After 4 months of exploring Briefcase for packaging, we're confident it solves most problems with the uv launcher with less complexity and at a lower maintenance cost, especially with the parallel work on the release CI, which we already used to make 5 releases. This also removes platform-specific packaging/signing code used to produce macOS dmg files and Windows NSIS installers, which is now largely handled by Briefcase and the release CI. The custom install scripts for Linux are mostly preserved under qt/installer/linux-template and used in the Briefcase build. ## How to test - [ ] No build problems. - [ ] The `tools/build-installer` scripts still work. - [ ] No CI/release workflow issues. - [ ] No user-visible changes in dev environment and Briefcase build. |
||
|
|
8ea145eb78 |
fix: Do not pass "--no-ytdl" to mpv on Intel Mac (#5015)
Fix audio broken on Intel Macs because our new mpv build doesn't recognize the `--no-ytdl` option. |
||
|
|
76741b8b89 |
fix: Bump minimum required macOS version (#5010)
## Linked issue Closes #5009 ## Summary Bump the minimum macOS version for the Briefcase build to 13.0 as according to match Qt requirements. |
||
|
|
80cf76e4f9 |
fix: Do not block MSI install if registry points to a deleted older installation (#4998)
## Linked issue
Closes #4997
## Summary
The MSI installer checks the Windows registry for older NSIS-based
installations and tries to run their uninstall.exe. If the registry
value is found but the uninstall file is missing for any reason, the
installer used to fail.
See template change:
|
||
|
|
fb0215a2c1 |
Prototype unified Mintlify docs site (#4882)
## Summary - add a generated `docs-site/` Mintlify proof of concept for a unified Anki docs site - migrate the desktop manual, AnkiMobile docs, FAQs, add-on docs, translation docs, release notes, legacy docs, and repo-local Sphinx/MyST developer docs into the POC tree - add a migration helper that preserves mdBook ordering, handles common MDX incompatibilities, and regenerates the landing-page-inspired Mintlify styling - apply minimal styling based on the current Anki landing page: Anki logo, Hanken Grotesk, blue primary color, subtle surfaces, and compact nav treatment ## Validation - `uv run --with ty ty check tools/mintlify_poc_migrate.py` - `source ~/.nvm/nvm.sh && nvm use 22.15.0 && mint validate` - previewed locally with `mint dev --port 3000` and checked the home page/developer docs in browser ## Notes This is intentionally a draft POC. It does not remove the existing Sphinx or mdBook docs flows yet; it demonstrates what bringing the sources into this repo and building from a single Mintlify root could look like. --------- Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com> Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com> Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
08a0780417 |
fix: Preserve .tar.zst suffix of Linux release zip (#4961)
## Linked issue Closes #4960 ## Steps to reproduce (before) The latest beta zips have only ".zst" as the suffix: https://github.com/ankitects/anki/releases/tag/26.05b2 ## How to test (after) Check the artifacts of this GHA run and confirm the suffix is preserved: https://github.com/ankitects/anki/actions/runs/27027272624 |
||
|
|
76c0407ccc |
fix: Repaint UI after answer reveal (#4970)
## Linked issue Closes #4969 ## Summary Add a [QWidget.update()](https://doc.qt.io/qt-6/qwidget.html#update) call for the main webview after the answer is revealed and images are loaded. This should reduce UI glitches, especially on cards with images. ## How to test It's hard to test and reproduce this, because its frequency varies between operating systems and graphics drivers. I've seen improvements on my collection on Windows with the default video driver (Direct3D) while doing my daily reviews today with this change and I'll continue testing over the week. |
||
|
|
0073124811 |
chore: Bump anki-audio to 0.2.1 (#4947)
## Linked issue #4918 #4949 ## Summary Bump anki-audio to 0.2.1 for the macOS hotfix. ## Steps to reproduce (before) Audio playback/recording on macOS was broken (see issue). ## How to test (after) Confirm audio is working now. |
||
|
|
27f8e8c263 |
fix: custom mpv.rb formula not being used (#4950)
## Linked issue Closes #4949 ## Summary It turned out that our mpv.rb formula was never used because of the `bottle do` statement, which was telling brew to use the upstream version. ## Steps to reproduce (before) 1. Download and extract anki-audio==0.2.1: https://pypi.org/project/anki-audio/0.2.1/ 2. Run `./mpv --version` and confirm you see the error in the linked issue. ## How to test (after) 1. Extract the signed artifacts built from this PR: https://github.com/ankitects/anki/actions/runs/26877282940 2. Run `./mpv --version` and confirm no library errors. You might see Gatekeeper warnings here as the binary is not notarized. |
||
|
|
398b51b2ed |
fix: wrong path of mpv libs in anki-audio wheel (#4919)
## Linked issue Closes #4918 ## Summary The anki-audio wheel build script was accidentally using `lib` instead of `libs` for copied mpv libraries. ## Steps to reproduce (before) Follow reproduction steps in the forum report and confirm you see the issue. ## How to test (after) - Build the wheel: `./qt/audio/build.sh`. - Confirm `qt/audio/anki_audio/libs` is created. - Extract `out/wheels/anki_audio-0.2.0-*.whl` and confirm it has the correct structure. - Run mpv in the extracted wheel: `./mpv` and confirm no library errors. |
||
|
|
1822a7c76c |
feat: Bump anki-audio package (#4913)
## Linked issue Closes #4699 ## Summary This bumps `anki-audio` to the newly published 0.2.0 release. ## How to test Confirm audio recording & playback is working by using the record button in the editor. |
||
|
|
e5ea3fb40a |
feat: Allow MSI installer downgrades (#4909)
## Linked issue
Closes #4908
## Summary / motivation
Update the Wix template to allow users to install older versions of the
app, overwriting an existing newer version. See changes in the template:
|
||
|
|
5e46fc4494 |
fix: Validate add-on's zip entries (#4901)
This validates add-on's zip paths to skip things such as UNC paths |
||
|
|
9c72a8b828 |
feat: render sync server messages as rich text (#4560)
## Summary
- Pass `type="rich"` to `showText()` when displaying the sync server
message, enabling HTML rendering via `QTextBrowser.setHtml()`
- Plain-text messages continue to render identically — `setHtml()`
handles plain strings the same as `setPlainText()`
- Allows self-hosted sync servers to send formatted post-sync messages
(e.g. styled statistics, notices with links, tables)
## Context
The `/sync/meta` response includes a `msg` field that is displayed to
the user after sync. The display widget is already a `QTextBrowser`
(which supports Qt rich text/HTML), but `showText()` is called with the
default `type="text"`, routing through `setPlainText()`.
The `showText` helper already has full HTML support — it just needs
`type="rich"`:
```python
# qt/aqt/utils.py
text = QTextBrowser()
text.setOpenExternalLinks(True)
if type == "text":
text.setPlainText(txt) # current path
else:
text.setHtml(txt) # proposed path
```
**Security:** `QTextBrowser` does not execute JavaScript — only static
HTML/CSS. The sync server is explicitly configured and trusted by the
user.
|
||
|
|
6f332d3a6b |
refactor: import some modules lazily (#4831)
## Linked issue A slight improvement related to #4314 ## Summary Import some modules like `jsonschema`, `bs4` and `aqt.mediasrv` lazily to speed up startup a bit. ## Steps to reproduce Run Anki with `-X importtime` passed to Python: ```diff diff --git a/run b/run index 3051345b1..a907b2925 100755 --- a/run +++ b/run @@ -17,4 +17,4 @@ export ANKI_API_PORT=${ANKI_API_PORT-40000} export ANKI_API_HOST=${ANKI_API_HOST-127.0.0.1} ./ninja pylib qt -${PYENV}/bin/python tools/run.py $* +${PYENV}/bin/python -X importtime tools/run.py 2> importtime.txt $* diff --git a/run.bat b/run.bat index aecbf2491..69a721641 100755 --- a/run.bat +++ b/run.bat @@ -12,5 +12,5 @@ set ANKI_API_HOST=127.0.0.1 @if not defined PYENV set PYENV=out\pyenv call tools\ninja pylib qt || exit /b 1 -%PYENV%\Scripts\python tools\run.py %* || exit /b 1 +%PYENV%\Scripts\python -X importtime tools\run.py %* 2> importtime.txt || exit /b 1 popd ``` Then import `importtime.txt` to [https://github.com/kmichel/python-importtime-graph](https://github.com/kmichel/python-importtime-graph) to visualize timings. You should see `jsonschema` and `bs4` are loaded at startup. ## How to test Run profiling again and confirm `jsonschema` and `bs4` are not loaded at startup. `aqt.mediasrv` will still be loaded at startup (because it's immediately used in the main screen) but at a later stage. --------- Co-authored-by: user1823 <92206575+user1823@users.noreply.github.com> |
||
|
|
88ef75f363 |
fix: Limit taskbar pinning fix to launcher builds (#4849)
This just limits the fix added in
|
||
|
|
6d42e37b72 |
fix: app unresponsive after clicking on Help button in modal dialogs (#4897)
## Linked issue Closes #4896 ## Summary On macOS, clicking the Help button in error dialogs shown on top of modal dialogs such as the Filtered deck screen was causing the app to become unresponsive after the recent Qt upgrade. This was fixed by: 1. Setting a parent widget for `QMessageBox`. 2. Limiting the `.disconnect()` calls to the `clicked` signal. ## Steps to reproduce (before) I was not able to reproduce the issue in a dev environment. I had to build and run the Briefcase package. Follow the steps in the [forums](https://forums.ankiweb.net/t/anki-26-05-beta-1/69707/43?u=abdo) and confirm you can reproduce the issue. ## How to test (after) Run the Briefcase package with the changes and follow reproduction steps and confirm the issue is fixed. |
||
|
|
e05a7aace7 |
feat: Install required system dependencies in install.sh (#4895)
## Linked issue Closes #4834 ## Summary This installs required Linux system dependencies in the install.sh script for Debian-based distributions. ## Steps to reproduce (before) No system dependencies are installed automatically. Users have to refer to the [manual](https://docs.ankiweb.net/platform/linux/installing.html#requirements) to find a (partial) list of required packages. ## How to test (after) Build the installer and run install.sh in any supported distro and confirm dependencies are installed. |
||
|
|
a754a9c847 |
feat: Bundle Fcitx plugin (#4886)
## Linked issue Closes #4873 ## Summary Build and package the fcitx5-qt6 plugin. Latest release CI run: https://github.com/ankitects/anki/actions/runs/26294296416 ## How to test 1. Run installer build on Linux: `./ninja installer:build`. 2. Go to the Qt build directory (`out/installer/build/anki/linux/zip/anki/app_packages/PyQt6/Qt6`) and confirm you see the following files: 1. `plugins/platforminputcontexts/libfcitx5platforminputcontextplugin.so` 2. `plugins/dbusaddons/libFcitx5Qt6DBusAddons.so*` |
||
|
|
a140d39329 |
chore(e2e): add Playwright end-to-end test infrastructure (#4864)
## Linked issue Closes #4863 ## Summary / motivation Adds Playwright as the e2e test framework so contributors can write browser-based tests against a real headless Anki instance. There was no automated way to exercise mediasrv pages, SvelteKit routes, or the `/_anki/` RPC surface from a browser, this PR establishes that harness. Key pieces: - `qt/tests/launch_anki_for_e2e.py` — spawns a throwaway Anki instance (temp `ANKI_BASE`, `QT_QPA_PLATFORM=offscreen`). Pre-seeds `prefs21.db` so Anki skips the language picker and profile chooser and goes straight to serving mediasrv. - `playwright.config.ts` — points `webServer` at the launcher; polls `/favicon.ico` as the readiness probe. - `ts/tests/e2e/` — `fixtures.ts` base and a sanity spec that verifies mediasrv is reachable and a SvelteKit page hydrates. - `justfile` — `just test-e2e` recipe; Chromium installed to `out/playwright-browsers/`. - CI — e2e step in `check-linux`; failed-run artifacts uploaded for 7 days. - `docs/e2e-testing.md` — contributor guide covering setup, managed vs reuse-server modes, and writing new tests. ## How to test Build the project once, then run the e2e suite in managed mode (no separate `./run` needed — the launcher is started automatically): ```shell just build just test-e2e ``` ## Before / after behavior (optional) Before: no browser-level test harness existed. After: `just test-e2e` drives a real headless Anki instance via Playwright. ## Risk / compatibility / migration No production code changed. New dev-only files and CI step only. Chromium is installed to `out/playwright-browsers/` (gitignored) and does not affect the regular build. --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
1394540217 |
test: Add tests for build_installer.py (#4868)
## Linked issue Closes #4859 ## Summary Add tests for the build_installer.py script with 100% coverage. ## How to test Run `just test-py --coverage --html` and browse coverage data. |
||
|
|
0519275682 |
fix: border color of browser cells in macOS (#4872)
## Linked issue Closes #4870 ## Summary This fixes the border color of browser cells in macOS not following Anki's theme after Qt 6.10+ ## Steps to reproduce (before) 1. Set Anki's theme from _Anki (`python` in dev environment) > Preferences > Theme_ to be the opposite of your system theme. 2. Open the Browse screen and notice the cell borders have the opposite color of your Anki theme, matching the system theme. ## How to test (after) Notice cell borders are more subtle now. ### Details ## UI evidence Before: <img width="628" height="346" alt="image" src="https://github.com/user-attachments/assets/3b46c9fe-5eb8-4e03-ac93-5429d1768344" /> After: <img width="628" height="346" alt="image" src="https://github.com/user-attachments/assets/aeea6867-ebfe-46cc-8b4a-6f7440da16f4" /> |
||
|
|
c9cd85dd97 |
feat: Distribute compiled sources in Briefcase bundle (#4856)
## Linked issue #4855 ## Summary Compile .pyc files and package them in the Briefcase bundle instead of the .py sources. ## How to test You can run this Powershell script to do a basic benchmark of startup performance on Windows (Requires [py-spy](https://github.com/benfred/py-spy)): ```powershell function Remove-Build { Remove-Item -LiteralPath "./out/installer" -Force -Recurse } function Start-Anki { param ( [Parameter()] [string] $OutputPath ) Start-Process -FilePath "py-spy" -ArgumentList "record --output $OutputPath -- ./out/installer/build/anki/windows/app/src/Anki.exe --safemode" Start-Sleep -Seconds 10 Stop-Process -Name Anki } if ($null -eq (Get-Command "py-spy" -ErrorAction SilentlyContinue)) { Write-Error "py-spy not found. See https://github.com/benfred/py-spy" Exit 1 } git checkout main Remove-Build ./tools/ninja installer:build Start-Anki -OutputPath "main.svg" git checkout briefcase-compile-pyc Remove-Build ./tools/ninja installer:build Start-Anki -OutputPath "pyc.svg" ``` Output is written to `main.svg` and `pyc.svg`. Here's an example run (using default 100 sampling rate): <img width="950" height="559" alt="image" src="https://github.com/user-attachments/assets/5da6a06a-3393-4f0e-80fe-ced735d50c2c" /> <img width="830" height="352" alt="image" src="https://github.com/user-attachments/assets/ca9e5d8d-c3d4-4a0b-bd86-7aa2d6c5cee2" /> |
||
|
|
03b9fc4814 |
ci: Fix Windows ARM packaging failing (#4857)
Fixes a CI failure introduced in #4822 See failing run: https://github.com/ankitects/anki/actions/runs/26009152225/job/76447663427 |
||
|
|
82eeda9d4f |
fix(export): preserve browser focus after note export (#4845)
## Linked issue (required) Fixes #4833 ## Summary / motivation (required) Keep the Browser window focused after exporting selected notes. The export dialog was opened from the Browser, but the background export progress and completion tooltip were still parented to the main window. That could leave the main screen focused after the export completed. This change carries the dialog parent through the export options and uses it for progress, errors, and the completion tooltip. ## Steps to reproduce (required, use N/A if not applicable) 1. Open the Browser. 2. Right-click a note and choose Notes > Export Notes. 3. Click Export, choose a save location, and save. 4. Observe that the main screen receives focus after export completion. ## How to test (required) ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details - Ran `./ninja check` successfully. - Tested behavior on macOS, however I currently don't have a Windows or Linux environment set up to test on right now as I'm on vacation. The change is limited to dialog parenting, so I expect it to work the same across platforms. Would appreciate testing on other platforms if possible. ## Before / after behavior (optional) Before: exporting selected notes from the Browser could focus the main window after completion. After: export progress and completion UI remain parented to the Browser, so focus is returned to the Browser. ## Risk / compatibility / migration (optional) Low risk. The change is limited to export UI parenting and falls back to the main window when no dialog parent is available. ## UI evidence (required for visual changes; otherwise N/A) N/A ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
a2262809c4 |
fix: regex error fix (#4837)
<!-- Title (for the Pull Request title field at the top): Use a short prefix so the change type is obvious. You do not need to repeat it in the body below. Examples: - fix: — bugfix - feat: — feature - refactor: — internal change without user-facing feature - docs: — documentation only - chore: — tooling, CI, deps, build housekeeping - test: — tests only --> ## Linked issue (required) Fixes #4835 ## Summary / motivation (required) <!-- What this PR does and why. For larger changes, add enough context for reviewers. --> Fixes the issue #4835 with a minor change in InvalidRegex error. ## Steps to reproduce (required, use N/A if not applicable) <!-- Steps to reproduce: how to trigger the bug in the broken state (the "before"). - Mainly for bugfixes; - For bugs: numbered steps before the fix. For non-bugs: write N/A. - use N/A for features, refactors, docs, chore, etc. --> 1. Open the browser and do a find & replace. 2. Put b[ in “Find”. 3. Enable the regex option. 4. Confirm. ## How to test (required) <!--- How to test: how you verified the change (checks, unit tests, manual steps, edge cases — the "after" or general validation). ---> Reproduce the fix and verify the regex error is not within the `<pre>` tag. ### Checklist (minimum) - [x] I ran `./ninja check` or an equivalent relevant check locally. - [x] I added or updated tests when the change is non-trivial or behavior changed. ### Details Regex error was return with `<pre>` tags which are removed now so that the text in the error box is displayed correctly. ## Before / after behavior (optional) <img width="372" height="211" alt="image" src="https://github.com/user-attachments/assets/91f53745-301b-4679-b1a5-53fafd628de7" /> <!-- For bugfixes: behavior before vs after. For other types: N/A or a short note. --> ## Risk / compatibility / migration (optional) <!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs --> ## UI evidence (required for visual changes; otherwise N/A) <img width="360" height="226" alt="image" src="https://github.com/user-attachments/assets/3b7b3f23-9f35-423e-9b10-62834e0a0dd6" /> <!-- Screenshot or short video --> ## Scope - [x] This PR is focused on one change (no unrelated edits). --------- Co-authored-by: Abdo <abdo@abdnh.net> |
||
|
|
1f0fc05f93 |
chore(deps): bump the python-minor-patch group across 1 directory with 16 updates (#4829)
Bumps the python-minor-patch group with 16 updates in the / directory: | Package | From | To | | --- | --- | --- | | [pre-commit](https://github.com/pre-commit/pre-commit) | `4.5.1` | `4.6.0` | | [mypy](https://github.com/python/mypy) | `1.16.1` | `1.17.1` | | [ruff](https://github.com/astral-sh/ruff) | `0.12.1` | `0.13.3` | | [wheel](https://github.com/pypa/wheel) | `0.46.3` | `0.47.0` | | [hatchling](https://github.com/pypa/hatch) | `1.27.0` | `1.29.0` | | [types-requests](https://github.com/python/typeshed) | `2.32.4.20250611` | `2.33.0.20260503` | | [types-markdown](https://github.com/python/typeshed) | `3.8.0.20250415` | `3.10.2.20260408` | | [sphinx-book-theme](https://github.com/executablebooks/sphinx-book-theme) | `1.1.4` | `1.2.0` | | [sphinx-autoapi](https://github.com/readthedocs/sphinx-autoapi) | `3.6.0` | `3.8.0` | | [sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid) | `2.0.1` | `2.0.2` | | [markdown](https://github.com/Python-Markdown/markdown) | `3.8.2` | `3.10.2` | | [orjson](https://github.com/ijl/orjson) | `3.10.18` | `3.11.8` | | [typing-extensions](https://github.com/python/typing_extensions) | `4.14.0` | `4.15.0` | | [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) | `4.13.4` | `4.14.3` | | [flask-cors](https://github.com/corydolphin/flask-cors) | `6.0.1` | `6.0.2` | | [jsonschema](https://github.com/python-jsonschema/jsonschema) | `4.24.0` | `4.26.0` | Updates `pre-commit` from 4.5.1 to 4.6.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/pre-commit/pre-commit/releases">pre-commit's releases</a>.</em></p> <blockquote> <h2>pre-commit v4.6.0</h2> <h3>Features</h3> <ul> <li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to be missing to enable easier usage with <code>git</code> 2.54+ git hooks. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> <h3>Fixes</h3> <ul> <li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is required. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md">pre-commit's changelog</a>.</em></p> <blockquote> <h1>4.6.0 - 2026-04-21</h1> <h3>Features</h3> <ul> <li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to be missing to enable easier usage with <code>git</code> 2.54+ git hooks. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> <h3>Fixes</h3> <ul> <li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is required. <ul> <li><a href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a> PR by <a href="https://github.com/asottile"><code>@asottile</code></a>.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
8ee11614e1 |
fix: optimize Briefcase bundle size (#4822)
## Linked issue Closes #4820 ## Summary Optimize size of the Briefcase bundle by removing unused dependency files: - Remove large *.debug.pak/*.debug.bin files included in Qt. - Remove packaging/typing/testing metadata. - Remove app_packages/bin binaries. - Remove miscellaneous unused files in PyQt6/pywin32. - Trim large qtwebengine_locales files by only keeping files for languages we support. - Set MSI compression level in the Wix template to "high". This reduces the size of the Windows MSI by ~30 MB. I was tempted to go further and prune unused Qt modules since the bulk of the app size comes from Qt, but that proved to be error-prone: We can't simply remove modules not imported by Anki as they can be possibly used by add-ons and other modules might have hidden dependencies on them. ## How to test Build the installer and confirm installation works. |