So, in my last little post, I mentioned how I messed with a WinForms DPI Scaling bug on a trip. Considerable time has passed since I wrote that post. And now that I think about it, the decisions I made there went more and more terrible.
ALL POSTS IN THIS SERIES (Note that the Psychic part of the series name is a reference to the term coined by Raymond Chen, Psychic Debugging.)
**DISCLAIMER: This post is more personal diary than technical. A technical summary will be posted at the end of the series.
Before we get back into the events, a small interlude: Notice how I clearly still had a lot of energy at the events of the end of the first post in this series. Sure, the issue lived rent-free in my head and I was a bit neurotic, but clearly I could still function normally.
A few days ago, I also made another short, trivial post about how excited I was about high school academics. Well, at that point, I still had enough energy.
Guess what, now I don't. It's always so hard to anticipate this hard crash at the end when you're out of energy, and that's mainly what I want y'all to take away from this entire series. I'm stating it up front here, since it's easier for y'all to see a pattern right now. (And me lacking energy is exactly why I'm writing this blog instead of studying more math right now, because I know that something engaging enough to not bore me out that still saves me energy will set me up for a long day tomorrow.)
A quick review
In the last post we introduced a DPI scaling problem I said in the last post,
... and will the fix prove to be correct? Find out in the next post of this series!
A little review of what happened there: There's a WinForms-based framework that enables High-DPI Scaling manually via the Win32 API, opts out of AutoScale behavior, and manually assigns a font object to each control by taking properties from MessageBoxFont and scaling the size by the appropriate DPI factor. Rescaling of all fonts is done on events such as Form.Resize and Form.LocationChanged and SystemEvents.DisplaySettingsChanged because Form.DpiChanged apparently was not firing. But in the code to scale the font by the scale factor of the current screen the window is on (by using MonitorFromWindow and then an shcore function), somehow they had to divide by the DPI scale of the initial screen; so, I suspected that getting rid of the hack by switching all font sizing to GraphicsUnit.Pixel from Points would fix the issue.
So let's answer the question in the last post. Did my proposal fix the issue? Unfortunately, no. While the fix did allow me to get rid of the font size scaling workaround, the original reported problems (mentioned in the original post; roughly, when moving a window across monitors, the font sizing sometimes scaly,es twice) in my first post were not fixed.
Repeated rumination, except about the future
That afternoon, we happened to go to Arches National Park again. I got the response from the ticket author that the issue was still reproducible on my fix branch just after we went in the national park, near the visitor center when my little sister was getting sworn in as a Junior Ranger. From there, we were planning to climb near delicate arch. But to be frank, I couldn't quite enjoy the climb for obvious reasons. I kept wondering, wondering, and wondering, and just couldn't seem to have a singular idea.
After the hike with mom, some logistics issues for driving (between my parents), and some other stuff later, we went to Skyline trail. I had to squint hard before I realized how it was supposed to be a skyline. But for now, I'm a lot more relaxed about my issues, as I can't recall thinking about that issue at the moment.
And then, it was the best part of the evening: Sand Dune Arch. There, watching my sister play, and having my own body almost merge with the silky smooth sand, was the ultimate relaxation. Still, since sister was playing a lot near the sand, I didn't want us to go back to the hotel too late, so I was kind of in a hurry (so that I could spend the next morning waking up early debugging). (Un)luckily, my parents also wanted to go to sleep early, so it was only natural that we all started hurrying up and getting my sister to not stay in the sand for long.
Late at night, while other people were taking a shower, I started suspecting that something in the Toga's font scaling logic was at fault. So I added a couple of debug statements before going to sleep. I reminded myself, At least I'm still getting ideas and making progress.
Yet, as I slept on the floor (because I wanted to; more solitude, no need to share beds) of the hotel, the possibility that this was a mystery beyond investigation kept coming back to me.
The next morning, we drove out of Moab. At the morning email check, it turns out that Toga was scaling everything correctly for WinForms, but somehow either Win32 or WinForms is again double-scaling the font size. At an extremely belated breakfast time, I walked downstairs; not knowing what type of font scaling issue it could be, I kept probing Google Gemini, with no usable or actionable results.
Canyonlands National Park was also a great spot—the open landscapes from the (Windows—see what I did here?) vistas and the spectacularly shaped tops of rocks were simply breathtaking. I took a break from thinking about DPI scaling as I walked on a long loop containing many trails—including Wall Stree Trail—at one point, I misread a sign and walked an extra mile on the horse trail :)
So anyways. Eventually, we had to go to a department store that evening to get some stuff. I tried doing Duolingo Music on the car to see what it was like (since my sister was obsessed with it; hint: very poor), but then dad angrily shooed me off the car to "help" mom shop, but both mom and I knew it was just a tactic to get mom to hurry up. So she didn't need help, and I ended up standing relatively close to the exit of the market, but just inside the building enough so that dad would not see me.
And from here, despite being really stressed by whatever the heck was going on, I started thinking about DPI scaling again.
The breakthrough
Well... I thought that if the system had to be double-scaling some font size that I'm not aware of, then it probably would happen in a unified location like WM_DPICHANGED rather than hooking into each individual event for window geometry changes and Display Settings like we did. But also, the fact that it was only intermittently although quite commonly reproducible on the reporter's computer probably means that there's a race condition.
So what's going on here is that somehow, I think, when Windows handles a DPI change, it is rescaling based on our already scaled font size. But since everything is normal in situations without multiple different screens, it must be that we need to handle our own font size reassignment after Windows' shenanignas, whatever it may be. So that means we should hook into a unified Windows DPI changed event to process our own custom rescaling, rather than detecting window geometry change ourselves. This would've been a good cleanup regardless, so it's obviously going to be worth it.
But of course, how do I hook into a generic DPI Change event when somehow Form.DpiChanged wasn't firing? Well, since Win32 APIs are the deepest Windows-level DPIs, they must work! And indeed WM_DPICHANGED did. On my system, when I changed display settings for the screen, it also ran before all of Toga's custom processing, further solidyfing my point that doing all the font rescaling after Win32's shenanigans have happened is, indeed, stable.
Conclusion
So honestly, even without the pressures of DPI debugging, I was already going through a lot of different things on this trip. So now, I sent my debug code with only a print statement in DPICHANGED to the bug reporter, just to see how it goes on their end. And, will my hypothesis be correct? Let's find out in the next post!
2 comments:
Hi John you're the goat
ur palash right?
Post a Comment