erkyrath / lectrote

The IF interpreter in an Electron shell
Other
248 stars 28 forks source link

Windows seem to be wrongly measured at start #83

Closed curiousdannii closed 7 years ago

curiousdannii commented 7 years ago

The status window seems to be wrongly measured when starting (in z3 games at least.) After resizing (or changing the margins) it gets the right size.

hhgg

erkyrath commented 7 years ago

(Ellison mentioned the same symptom.)

After a lot of futzing around with preferences, I can reproduce this on Windows but not on MacOS. Which is strange! Same browser, after all.

Maybe it's a question of the order in which Javascript events are delivered. I will dig into that.

erkyrath commented 7 years ago

Debugging output indicates that the error occurs on MacOS too, but the difference is too small to see. So at least it's not a browser inconsistency. (And I shouldn't put a hacky fix under "if platform=='win32'"...)

erkyrath commented 7 years ago

When the interpreter starts up, it measures the window metrics. It then immediately gets an evhan_doc_resize call via the shrink/expand detector element. This measures the window layout again, and gets different font size results! Why? No idea. Maybe there's a font loading delay? (The browser doesn't have enough information to measure fonts until some background stuff has rendered?)

The resize event handler then fails to act on the updated metrics, because it sees that the window size hasn't changed -- it doesn't look at the rest of the metrics structure.

So, easy fix #1: be more perceptive when checking whether the metrics structure has changed. Then that first resize event goes through and causes the grids to be redrawn correctly.

However, this leaves us with a slight "jiggle" when the window opens. (The delay between the evhan_doc_resize call and its handling, which is 0.2 seconds due to debouncing.) This is better than the original bug, but not great.

Fix #2: maybe use a shorter delay on that first debounce?

erkyrath commented 7 years ago

(I tried delaying the interpreter launch to give fonts time to load. Didn't help.)

erkyrath commented 7 years ago

Ultimately I'd love to know why we get different results the first two times we call measure_window(). I don't see this happening in Quixe running under desktop Chrome.

curiousdannii commented 7 years ago

GiLoad.load_run is running after a DOMContentLoaded event right? Maybe it should be delayed until the load event (which should be almost as fast seeing as it's running locally). But if you already tried delaying it...

erkyrath commented 7 years ago

Yeah. Specifically I tried putting a one-second delay before the GiLoad.load_run() call. The size shift happens after glkote_init() does its work.

erkyrath commented 7 years ago

Specifically, after the first measure_window() call. I was able to work around it by having GlkOte.init call measure_window(), wait a fraction of a second, call it again, and then call the VM's init function. Not sure whether this is worth putting into the glkote library, though.

curiousdannii commented 7 years ago

If you comment out the resize detector does the problem go away? I couldn't see anything in the detector code that should make the metrics change, but it could be very subtle.

erkyrath commented 7 years ago

Good thought, but nope. Without the resize detector, we don't get that initial resize event which causes the jiggle. But it is still true that the font measurements are wrong until the next resize event.

Now, what works -- I just checked -- is to have font samples included in play.html, so they are all cached by the time the doc's ready event fires. This explains why the problem only appears in Lectrote; the usual Quixe setup doesn't try to load fonts dynamically.

I'll see if I can turn that hack into a solid fix.

erkyrath commented 7 years ago

Had to go back to the idea of inserting a brief delay before VM init. I think it works now.

curiousdannii commented 7 years ago

If it is definitely font related, then the Font Loading API would probably help. document.fonts.ready is a promise that resolves when all fonts are loaded. No support in IE yet, but it's only needed for Lectrote anyway. Just suggesting it as it might be cleaner/more reliable than the fix you worker up.