Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stage Manager: snap windows from recent apps #895

Merged
merged 2 commits into from
Sep 8, 2022
Merged

Stage Manager: snap windows from recent apps #895

merged 2 commits into from
Sep 8, 2022

Conversation

decodism
Copy link
Contributor

Fixes #853

@decodism decodism marked this pull request as draft August 29, 2022 17:34
@decodism decodism marked this pull request as ready for review August 29, 2022 22:12
Copy link
Owner

@rxhanson rxhanson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just one comment to talk through.

if StageUtil.stageCapable() && StageUtil.stageEnabled() && StageUtil.stagePresent(windowInfo) {
// In case the window is in Stage Manager recent apps
var prevWindowInfo: CGWindowInfo?
while prevWindowInfo?.id != resultWindowInfo.id {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like I'm missing something here with this while loop. It appears to me that it is unnecessary, but perhaps you can elaborate on what it's doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can only drag the foreground window of a scene from the recent apps. This loop is used to find this window.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Sorry to keep pushing on this, but when I test this out, I never get a different value for the resultWindowInfo (there's no iteration in the while loop because it gets the same value twice and exits, and it's not straightforward to me how it would obtain different values in any different scenario). Even if I remove this block entirely, I can still drag & snap the windows from recent apps because it appears to get the correct windowId. Perhaps there is an edge case that I'm not hitting that would justify having this?

The reason why this caught my attention in the first place is because 1) while loops that don't have an intuitive exit are too easy to end up in an infinite loop (if not now, maybe with other additional refactoring later), and 2) I pretty much never force unwrap optionals. Both of these scenarios are potential for application crashes, and even if your code here was straightforward to me, I would have still suggested removing both of those. In other apps I've written, places where I was certain there was no chance of a force unwrap causing a crash, still caused a crash due to some very tricky memory management from macOS that had released memory I thought wouldn't get released. One could argue that a crash is desirable in certain scenarios, but I rarely have those scenarios - I'd almost always want the app to still chug along even if there's something like this that isn't quite right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to clarify: in the case where a background window of a scene from the recent apps is dragged (by the part that sticks out behind the other windows of the scene), it won't be that window but the foreground window of the scene that will be dragged. Returning the window under the cursor is therefore not enough, it is necessary to find the window in the foreground of the scene. To do so, we can search for the first window (because they are already sorted by layer) that intersects the window under the cursor. However, the window in the foreground does not necessarily intersect the window under the cursor depending on their positioning. It's therefore not enough either, it is necessary to go up the first windows that intersect. We know that it is no longer possible to go up when we find the same window twice.
As for the loop itself, it seems safe to me. What would you suggest?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification, I understand now. As for the while loop, I'm good with it as-is. I appreciate that you've continued the work on Stage Manager!

@rxhanson rxhanson merged commit 706d3ec into rxhanson:master Sep 8, 2022
@rxhanson
Copy link
Owner

@decodism There is a crash that appears to be related to the FallbackAccessibilityElement, and at the moment I don't quite understand it. If you don't mind taking a look, that would be great. Here's the issue: #989

@rxhanson
Copy link
Owner

And here's the analyzed crash report:
AnalyzedCrashReport.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Miniature windows from Stage Manager cannot be snapped
2 participants