Comments (18)
I regularly encounter this when developing, it even seems to happen more frequently now than compared to a few months ago. However, I have never had the issue when launching the binaries. When running from source I don't have a way to reproduce it reliably, either, but rerunning a couple of times usually does the trick.
Once the issue has occured, nothing except restarting seems to help.
I'm not proficient in web development or Anki's webview code, so I have no idea how to go about debugging. Sending the file in mediarsv.py
seems successful to me and reloading in Chrome DevTools does nothing to the missing css.
If you want me to try anything just let me know.
from anki.
Does running with ./scripts/runopt make a difference to how often it happens? Wondering if it's a race condition
Does the css file show up in the list of page resources when viewing the buggy page with the devtools?
from anki.
Does running with ./scripts/runopt make a difference to how often it happens? Wondering if it's a race condition
That will be hard to quantify, but I just gave it a go and immediately encountered the issue.
Does the css file show up in the list of page resources when viewing the buggy page with the devtools?
No, there's no css at all, but I just realised, if I inspect the bottom toolbar page, there is not only toolbar-bottom.css
, but also toolbar.css
and webview.css
.
from anki.
The top area should have toolbar.css and webview.css when viewing the Sources tab:
Neither of those are showing up, but they show up in the requests with ANKIDEV? Is _onHeight() being called for the top toolbar? Does commenting out acceptNavigationRequest make any difference? Any difference when loading a profile directly vs opening up the profiles screen first?
from anki.
Neither of those are showing up, but they show up in the requests with ANKIDEV?
Exactly:
Is _onHeight() being called for the top toolbar?
It gets called the same number of times, twice for loading the main page. Only the arguments differ (not surprising, I assume).
Broken (one example, height is not uniform here):
Ok:
Does commenting out acceptNavigationRequest make any difference?
Where do I do that? I tried returning immediately in webview.py/acceptNavigationRequest()
, that didn't make a difference.
Any difference when loading a profile directly vs opening up the profiles screen first?
It seems that way. I got the issue the first time I ran with a profile name, but not once in my countless trials after that, even when I started switching the profile at runtime.
It never takes more than a few trials to trigger the issue when I run without the p paramter, so I think it could be called statistically significant.
from anki.
The (no domain) section has two entries, but I'm only seeing one. Do you see only one entry when the problem doesn't occur? I wonder what the colour represents? Was the same text returned both times? If you comment out the .redraw() line in the deck browser, does that fix it? Maybe we're loading the HTML, then loading it again before the first load finishes, resulting in a partially loaded page.
from anki.
Indeed, the violet entry only seems to occur when the CSS is missing. The two files show different ports then.
According to this answer, violet means CSS and grey means HTML. Curious.
<!doctype html>
<html class="">
<head>
<title>top toolbar</title>
<base href="http://127.0.0.1:55000/"><link rel="stylesheet" type="text/css" href="http://127.0.0.1:55000/_anki/css/webview.css"><style>
body { zoom: 1; background: #f0f0f0; direction: ltr; font-size:12px;font-family:"Segoe UI"; }
button { font-family:"Segoe UI"; }
:focus { outline: 1px solid #0078d7; }
:root { --window-bg: #f0f0f0 }
:root[class*=night-mode] { --window-bg: #f0f0f0 }
</style><link rel="stylesheet" type="text/css" href="http://127.0.0.1:55000/_anki/css/toolbar.css"><script src="http://127.0.0.1:55000/_anki/js/webview.js"></script>
<script src="http://127.0.0.1:55000/_anki/js/webview.js"></script>
<script src="http://127.0.0.1:55000/_anki/js/vendor/jquery.min.js"></script>
<script src="http://127.0.0.1:55000/_anki/js/toolbar.js"></script>
</head>
<body class="isWin">
<center id=outer>
<table id=header width=100%>
<tr>
<td class=tdcenter align=center><a class=hitem tabindex="-1" aria-label="Decks" title="Shortcut key: D" id="decks" href=# onclick="return pycmd('decks')">Decks</a>
<a class=hitem tabindex="-1" aria-label="Add" title="Shortcut key: A" id="add" href=# onclick="return pycmd('add')">Add</a>
<a class=hitem tabindex="-1" aria-label="Browse" title="Shortcut key: B" id="browse" href=# onclick="return pycmd('browse')">Browse</a>
<a class=hitem tabindex="-1" aria-label="Stats" title="Shortcut key: T" id="stats" href=# onclick="return pycmd('stats')">Stats</a>
<a class=hitem tabindex="-1" aria-label="Sync" title="Shortcut key: Y" id="sync" href=# onclick="return pycmd('sync')">Sync
<img id=sync-spinner src='/_anki/imgs/refresh.svg'>
</a></td>
</tr></table>
</center>
</body>
</html>
<!doctype html>
<html class="">
<head>
<title>top toolbar</title>
<base href="http://127.0.0.1:54822/"><link rel="stylesheet" type="text/css" href="http://127.0.0.1:54822/_anki/css/webview.css"><style>
body { zoom: 1; background: #f0f0f0; direction: ltr; font-size:12px;font-family:"Segoe UI"; }
button { font-family:"Segoe UI"; }
:focus { outline: 1px solid #0078d7; }
:root { --window-bg: #f0f0f0 }
:root[class*=night-mode] { --window-bg: #f0f0f0 }
</style><link rel="stylesheet" type="text/css" href="http://127.0.0.1:54822/_anki/css/toolbar.css"><script src="http://127.0.0.1:54822/_anki/js/webview.js"></script>
<script src="http://127.0.0.1:54822/_anki/js/webview.js"></script>
<script src="http://127.0.0.1:54822/_anki/js/vendor/jquery.min.js"></script>
<script src="http://127.0.0.1:54822/_anki/js/toolbar.js"></script>
</head>
<body class="isWin">
<center id=outer>
<table id=header width=100%>
<tr>
<td class=tdcenter align=center><a class=hitem tabindex="-1" aria-label="Decks" title="Shortcut key: D" id="decks" href=# onclick="return pycmd('decks')">Decks</a>
<a class=hitem tabindex="-1" aria-label="Add" title="Shortcut key: A" id="add" href=# onclick="return pycmd('add')">Add</a>
<a class=hitem tabindex="-1" aria-label="Browse" title="Shortcut key: B" id="browse" href=# onclick="return pycmd('browse')">Browse</a>
<a class=hitem tabindex="-1" aria-label="Stats" title="Shortcut key: T" id="stats" href=# onclick="return pycmd('stats')">Stats</a>
<a class=hitem tabindex="-1" aria-label="Sync" title="Shortcut key: Y" id="sync" href=# onclick="return pycmd('sync')">Sync
<img id=sync-spinner src='/_anki/imgs/refresh.svg'>
</a></td>
</tr></table>
</center>
</body>
</html>
Commenting out the redraw line doesn't help.
from anki.
I'd expect the port numbers to change over multiple program invocations, but are you saying they were different in the first and second request in a single Anki session? Does setting the env var ANKI_API_PORT to 40000 change the behaviour at all?
from anki.
Yes, those are the files from a single Anki session. At least I thought that. Now when I try that again, the second file looks like this:
:root{--text-fg: black;--window-bg: #ececec;--frame-bg: white;--border: #aaa;--medium-border: #b6b6b6;--faint-border: #e7e7e7;--link: #00a;--review-count: #0a0;--new-count: #00a;--learn-count: #c35617;--zero-count: #ddd;--slightly-grey-text: #333;--highlight-bg: #77ccff;--highlight-fg: black;--disabled: #777;--flag1-fg: #c35617;--flag2-fg: #ffb347;--flag3-fg: #0a0;--flag4-fg: #77ccff;--flag1-bg: #ffaaaa;--flag2-bg: #ffb347;--flag3-bg: #82e0aa;--flag4-bg: #85c1e9;--buried-fg: #aaaa33;--suspended-fg: #dd0;--suspended-bg: #ffffb2;--marked-bg: #cce;--tooltip-bg: #fcfcfc}:root[class*=night-mode]{--text-fg: white;--window-bg: #2f2f31;--frame-bg: #3a3a3a;--border: #777;--medium-border: #444;--faint-border: #29292b;--link: #77ccff;--review-count: #5ccc00;--new-count: #77ccff;--learn-count: #ff935b;--zero-count: #444;--slightly-grey-text: #ccc;--highlight-bg: #77ccff;--highlight-fg: white;--disabled: #777;--flag1-fg: #ffaaaa;--flag2-fg: #ffb347;--flag3-fg: #82e0aa;--flag4-fg: #85c1e9;--flag1-bg: #aa5555;--flag2-bg: #aa6337;--flag3-bg: #33a055;--flag4-bg: #3581a9;--buried-fg: #777733;--suspended-fg: #ffffb2;--suspended-bg: #aaaa33;--marked-bg: #77c;--tooltip-bg: #272727}*{box-sizing:border-box}body{font-family:Helvetica,Arial;color:var(--text-fg);background:var(--window-bg);margin:1em}a{color:var(--link);text-decoration:none}.isWin button{font-size:12px}.isMac button{font-size:13px}.isLin button{font-size:14px;-webkit-appearance:none;border-radius:3px;padding:5px;border:1px solid var(--border)}.nightMode button{-webkit-appearance:none;color:var(--text-fg);background:linear-gradient(0deg, #555555 0%, #656565 100%);box-shadow:0 0 3px #222;border:1px solid #646464;border-radius:2px;padding:10px;padding-top:3px;padding-bottom:3px}.nightMode button:hover{background:#656565}.isMac.nightMode.macos-dark-mode button:not(.linkb){background:#656565;box-shadow:0 1px 2px #222;border-top-color:#848484;border-top-width:.5px;border-bottom:0;border-left:0;border-right:0;padding-top:2px;padding-bottom:2px;padding-left:15px;padding-right:15px;color:#e5e5e5}*{box-sizing:content-box}body{margin:2em;overscroll-behavior:none}h1{margin-bottom:.2em}.nightMode::-webkit-scrollbar{background:var(--window-bg)}.nightMode::-webkit-scrollbar:horizontal{height:12px}.nightMode::-webkit-scrollbar:vertical{width:12px}.nightMode::-webkit-scrollbar-thumb{background:#656565;border-radius:8px}.nightMode::-webkit-scrollbar-thumb:horizontal{min-width:50px}.nightMode::-webkit-scrollbar-thumb:vertical{min-height:50px}
The two files look the same in Chrome, but I think Chrome is getting confused because they have the same name and always opens the first. What I've posted here is what I see when I download the files and open them in Notepad.
Now I'm wondering if I made a mistake yesterday. That would explain why one is coloured violet because it really contains CSS whereas the other one with the same name contains HTML.
I assume ANKI_API_PORT is an environment variable? Setting it doesn't seem to make a difference.
from anki.
When you say "download the files", do you mean you are surfing to localhost:xxxxx/_anki/css/... something? What I'm more interested in is the two entries in the (no domain) section. Maybe this is a bug in Qt's setHtml() call. Does the following patch make a difference?
diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py
index 9f3177a6e..ad5d79e51 100644
--- a/qt/aqt/mediasrv.py
+++ b/qt/aqt/mediasrv.py
@@ -98,6 +98,9 @@ class MediaServer(threading.Thread):
@app.route("/<path:pathin>", methods=["GET", "POST"])
def allroutes(pathin: str) -> Response:
+ if pathin == "_anki/toolbar.html":
+ return handle_toolbar()
+
try:
directory, path = _redirectWebExports(pathin)
except TypeError:
@@ -300,3 +303,42 @@ def handle_post(path: str) -> Response:
)
return response
+
+def handle_toolbar() -> Response:
+ from aqt import mw
+ server = mw.serverURL()
+ return flask.make_response(f"""
+<!doctype html>
+<html class="night-mode">
+<head>
+<title>top toolbar</title>
+<base href="{server}"><link rel="stylesheet" type="text/css" href="{server}_anki/css/webview.css"><style>
+body {{ zoom: 1; background: #2f2f31; direction: ltr; font-size:15px;font-family:"Helvetica"; }}
+
+button {{ -webkit-appearance: none; background: #fff; border: 1px solid #ccc;
+border-radius:5px; font-family: Helvetica }}
+:root {{ --window-bg: #2f2f31 }}
+:root[class*=night-mode] {{ --window-bg: #2f2f31 }}
+ </style><link rel="stylesheet" type="text/css" href="{server}_anki/css/toolbar.css"><script src="{server}_anki/js/webview.js"></script>
+<script src="{server}_anki/js/webview.js"></script>
+<script src="{server}_anki/js/vendor/jquery.min.js"></script>
+<script src="{server}_anki/js/toolbar.js"></script>
+</head>
+
+<body class="isMac nightMode night_mode">
+<center id=outer>
+<table id=header width=100%>
+<tr>
+<td class=tdcenter align=center><a class=hitem tabindex="-1" aria-label="Decks" title="Shortcut key: D" id="decks" href=# onclick="return pycmd('decks')">Decks</a>
+<a class=hitem tabindex="-1" aria-label="Add" title="Shortcut key: A" id="add" href=# onclick="return pycmd('add')">Add</a>
+<a class=hitem tabindex="-1" aria-label="Browse" title="Shortcut key: B" id="browse" href=# onclick="return pycmd('browse')">Browse</a>
+<a class=hitem tabindex="-1" aria-label="Stats" title="Shortcut key: T" id="stats" href=# onclick="return pycmd('stats')">Stats</a>
+
+<a class=hitem tabindex="-1" aria-label="Sync" title="Shortcut key: Y" id="sync" href=# onclick="return pycmd('sync')">Sync
+<img id=sync-spinner src='/_anki/imgs/refresh.svg'>
+</a></td>
+</tr></table>
+</center>
+</body>
+</html>
+""")
\ No newline at end of file
diff --git a/qt/aqt/toolbar.py b/qt/aqt/toolbar.py
index 5e3c7505b..210869b24 100644
--- a/qt/aqt/toolbar.py
+++ b/qt/aqt/toolbar.py
@@ -44,12 +44,8 @@ class Toolbar:
web_context = web_context or TopToolbar(self)
link_handler = link_handler or self._linkHandler
self.web.set_bridge_command(link_handler, web_context)
- self.web.stdHtml(
- self._body % self._centerLinks(),
- css=["css/toolbar.css"],
- js=["js/webview.js", "js/vendor/jquery.min.js", "js/toolbar.js"],
- context=web_context,
- )
+ self.web.set_open_links_externally(False)
+ self.web.load_url(QUrl(f"{self.mw.serverURL()}_anki/toolbar.html"))
self.web.adjustHeightToFit()
def redraw(self) -> None:
from anki.
When you say "download the files", do you mean you are surfing to localhost:xxxxx/_anki/css/... something? What I'm more interested in is the two entries in the (no domain) section.
Yes, I was talking about these two entries. You can open them in Chrome or download them. Now, in Chrome it looks like they contain the same data, but as I said above, that seems to be a bug in Chrome for files with the same name and the actual content of the second file is different as can be seen in the downloaded file.
self.web.load_url(QUrl(f"{self.mw.serverURL()}_anki/toolbar.html"))
Should be self.web.load(...)
I think.
With the patch, instead of just the CSS the whole toolbar is missing sometimes.
from anki.
load_url() should be present in the latest main
One more thing to try:
diff --git a/qt/aqt/main.py b/qt/aqt/main.py
index f8d09ff1d..edd03722e 100644
--- a/qt/aqt/main.py
+++ b/qt/aqt/main.py
@@ -143,7 +143,6 @@ class AnkiQt(QMainWindow):
try:
self.setupUI()
self.setupAddons(args)
- self.finish_ui_setup()
except:
showInfo(tr(TR.QT_MISC_ERROR_DURING_STARTUP, val=traceback.format_exc()))
sys.exit(1)
@@ -161,6 +160,7 @@ class AnkiQt(QMainWindow):
fn = self.setupProfile
def on_window_init() -> None:
+ self.finish_ui_setup()
fn()
gui_hooks.main_window_did_init()
If that doesn't help, does changing 10 to 500 make a difference?
from anki.
What 10? The other thing didn't work.
from anki.
Directly below on_window_init() is a 10ms timer
from anki.
Looks like that did the trick. 😮
As always, it's hard to tell with such a flaky issue, so I'll try some more later.
from anki.
So the issue occured only once with the timer set to 500 ms and I tried a lot of times. I also tried with the timer set to 1 ms and couldn't repdruce the issue at all, though I didn't try that quite as often. (Starting to think I have to log the trials and analyse them statiscally...)
That would indicate a race condition, wouldn't it?
from anki.
Yeah, I suspect it's a bug in Qt :-( To confirm, that's a 1ms timer w/ the finish_ui_setup() call inside on_window_init()?
from anki.
This one:
diff --git a/qt/aqt/main.py b/qt/aqt/main.py
index f8d09ff1..6035a07b 100644
--- a/qt/aqt/main.py
+++ b/qt/aqt/main.py
@@ -164,7 +164,7 @@ class AnkiQt(QMainWindow):
fn()
gui_hooks.main_window_did_init()
- self.progress.timer(10, on_window_init, False, requiresCollection=False)
+ self.progress.timer(1, on_window_init, False, requiresCollection=False)
def setupUI(self) -> None:
self.col = None
from anki.
Related Issues (20)
- How to create Image Occlusion via guiAddCards from anki connect.
- Global styles were lost in SvelteKit transition HOT 3
- Based on AI large models, it only takes two steps to easily batch generate Anki picture notes!
- Anki does not proceed to next card when reviewing a deck HOT 1
- Anki does not close reliably on MacOS HOT 1
- FSRS “ignore before reviews” display blank in Qt5
- Background Images are eliminated by using the option Check Media HOT 1
- (FSRS) Use median in calculating cost and remove outliers HOT 1
- Add Deck Hide/Unhide HOT 3
- Anki for desktop crashes when you delete a card you are on HOT 2
- Support for python scripting while app is open HOT 1
- Combining cloze and type:cloze not working on the same card
- Polygon tool in I/O is broken HOT 1
- Bug: UI interactable before it's updated (Anki Desktop 24.04.1 Windows 11) HOT 3
- How to make web pages extensible by add-ons? HOT 7
- Nested clozes cause exponentially growing html HOT 1
- Mw.reset() update the deck label when it has been deleted
- Favor clipboard image when there's no surrounding text HOT 1
- Scalability for all Images
- Documentation for set_due_date in pylib/anki/base.py is out of date.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from anki.