Sunday, February 4, 2024

Month 2 - Week 4 - Working on Event Reporting in Linux

 This week has been rather extensive. There was a lot of work involved with not just this class, but my other class as well. I wanted to pour in more time to get this specific bug we'll be talking about fixed and working correctly, however, I was not able to devote as much time as I would've liked. This is primarily because I had to spend a lot of time in the other class working on final assignments. So the majority of my time was spent ensuring that those assignments were handled and that they were turned in on time. As a result, the progress on this bug which I will be discussing in particular is rather slow, but I was able to make enough progress to be able to sufficiently know how to fix it next week.

To give a brief description of the bug, I want to put the key focus on the type of bug that we're dealing with. So whenever an average developer creates a window using our library, they tend to want to keep track of certain events that occur with that window. If you move a window, resize it, or maximize, or minimize it, you preferably want an event to be reported so that way the developer can create certain functionalities that can occur upon any of these events happening. So something I wanted to focus on was trying to determine why this bug occurred. A brief description of the bug is rather simple, if the user maximizes the window and then minimizes the maximized window, no minimize event is reported. It sounds simple on the surface but is actually much harder once you look into the nitty-gritty of it all.

One of the main issues in particular revolves around how these events are determined. I would also like to note that this bug is only occurring on Linux under the X11 library. Whenever an event occurs, the underlying architecture will report over to GWindow to handle it. This carries a couple properties, the main one in particular being the actual property return value. There are a lot of values this variable can be, but there are a few in particular that point to whatever is happening to the window. For instance, if the property value were equal to 384, then we can determine whatever happened to the window resulted in the window's property going to the max vertical height, this would normally mean a resize, maximize, or minimize event.

The first step that needed to be taken was trying to determine why the event wasn't being detected. There were a couple theories that I had, mostly revolving around the conditional logic of how the minimization event was being detected. I eventually concluded that none of the actual conditional logic was the problem. From my findings, it was a preliminary check that was acting up. So the whole reason the minimization event wasn't happening was due to that. The specific preliminary check that I'm referencing is a check that tries to determine if the window has changed all. It checks if there's anything different about the window's property, and by looking at it, if there's no difference, it will break out and report nothing. This is rather problematic though, because a minimization event doesn't inherently change the window. Whoever initially wrote the condition for this if statement also thought the same thing, as there is an additional condition applied to it, ensuring that the window isn't being minimized. However, this is where we face the actual bug.

Whenever a window is maximized and then minimized, the property return value does not report a minimized event. It reports a burst of 4-5 events, all being 384, or 384 with the last being 491 (I may be wrong as it's been a few days since I viewed the exact number). For simplicity, 384 is a property vertical max event, and 491 is unknown. None of these events are reporting the proper property hidden event code. This causes a problem. Since the property return value is no longer returning property hidden, and the window doesn't change due to it only being minimized, this if statement above executes and exits the function without reporting a single event.

There are a couple of things we could do to try and check for a minimize event during a maximize. One of the main checks is seeing if the previous event that was reported is a maximize event. If the previous event was a maximize event, and the property return value is 384, then we could report that a minimize event has occurred. We could also flip this condition to check if the previous event was a minimize event, so that way if you bring the window back up after minimizing, it reports a maximize. This is where the main problem occurs though, because I've already done this code, the window, due to the fact it reports these events in a burst of 4-5 events, we face the issue of it reporting multiple minimize and maximize events. So that leads us to figure out how to lessen that.

To clarify, in its current state, we do have minimize and maximize events reporting properly. The issue we currently have is that it's reporting them multiple times. We only want these events to report once, if it's reporting these events repeatedly, it can cause issues for whatever functionality might be blinded to these events. Since this library is used mostly for game development, you don't want to burst of minimize and maximize events being reported, there could be functionality tied to that game that may break behavior if it's being spammed with events like this. So this is why we need to figure out how to lessen it to just one event being reported.

One of the possible fixes is to use a bitmask or an array that tracks the burst of events, specifically, the property return value. Let's frame it like this. If the window is minimized while it's also maximized, we'll receive the burst of events, around 4-5. If we capture these numbers, and then check if they're equal to 384 or 491, we can tick a bit in the bitmask. We can then check if the bitmask equals 0x11110 or 0x11111. The reason for the two checks is if we only get four events and not five, we will have the last bit be 0, otherwise, they'll all be 1.


This is merely pseudo code, but it does show the idea of how this could work. By doing these checks, and then using the bitmask as a way to track how many times these events are reported, we can use the bitmask as a condition for the minimize and maximize. It would also force the event to be reported only once. This bitmask wouldn't be used anywhere else in the code and would be tracked only for this specific event. However, a change like this will require discussion with Lari and will have to be approved as this introduces more variables, and could have possible side-effects that I may be overlooking. Currently, this is where I am for this bug, but I feel I'm getting closer to fixing it. I feel if I'm allowed another week to tinker with it, I'll be able to get a solution made.

Edit (2/5/2024): I'm going to add a small correction to this blog post as I felt it was needed to correctly explain the bitmask. I made a mistake in my explanation of it and failed to represent the data accurately, this is due to most of my experience with bit manipulation revolving around color. To better explain the actual values, they would need to be displayed in proper binary. So instead of 0x11110 and 0x11111, it would be `0001 1110` or `0001 1111`. The pseudo-code would also be different compared to what was originally shown.


This should hopefully show more accurately what the code is checking for. Here we are checking if the bitmask is equal to `0x0001E` or `0x0001F`, which are just 30 and 31, or `0001 1110` and `0001 1111` respectfully. So this code should actually be more accurate to what the final code would look like.

No comments:

Post a Comment