Skip to content

[MacCatalyst] Get correct window associated with the Popup#1409

Merged
pictos merged 5 commits intoCommunityToolkit:mainfrom
babenkovitaliy:MultiWindowPopup
Sep 18, 2023
Merged

[MacCatalyst] Get correct window associated with the Popup#1409
pictos merged 5 commits intoCommunityToolkit:mainfrom
babenkovitaliy:MultiWindowPopup

Conversation

@babenkovitaliy
Copy link
Copy Markdown
Contributor

This PR solves an issue with where a MacCatalyst application has multi-windows enabled, but when creating a popup, it opens up to a random window instead of the correct one.

Description of Change

There is an issue with this line of code:
var rootViewController = WindowStateManager.Default.GetCurrentUIViewController() ?? throw new InvalidOperationException($"{nameof(PageHandler.ViewController)} cannot be null.");

It assumes that the application will be in a single-window state (e.g. Shell app). However, with MacOS, apps can also be multi-window applications.

This fix looks through all windows, locates its "View" (e.g. ContentPage), then compares it against the Parent View of the Popup. If it matches, then that is where the popup will display. Previously, it displayed on whatever window this method returned: WindowStateManager.Default.GetCurrentUIViewController()

Linked Issues

PR Checklist

Additional information

With these code changes, the existing demo app still works without issues. When it comes to creating a demo for this fix, this would require a massive rewrite of the demo app, since the main UI is coded as a Shell app (single window).

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

babenkovitaliy commented Sep 14, 2023

@microsoft-github-policy-service agree

@TheCodeTraveler
Copy link
Copy Markdown
Collaborator

Love this! @pictos - Does this introduce any breaking changes to Popup?

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

Love this! @pictos - Does this introduce any breaking changes to Popup?

Nope. None so far. No method signature changes (e.g. parameters, return types).

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

Oh sorry. Just noticed that you tagged someone else

Copy link
Copy Markdown
Member

@pictos pictos left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @babenkovitaliy, I was thinking here... We know what's the Popup.Parent, and it should be a Page, can't we get the information on that Page instead of looking up all available ViewControllers? Since we have a loop inside a loop it could be a O(n²)

Comment thread src/CommunityToolkit.Maui.Core/Views/Popup/MauiPopup.macios.cs Outdated
@pictos
Copy link
Copy Markdown
Member

pictos commented Sep 14, 2023

Love this! @pictos - Does this introduce any breaking changes to Popup?

From my review it doesn't have any break-change

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

babenkovitaliy commented Sep 15, 2023

Thanks for the PR @babenkovitaliy, I was thinking here... We know what's the Popup.Parent, and it should be a Page, can't we get the information on that Page instead of looking up all available ViewControllers? Since we have a loop inside a loop it could be a O(n²)

I tried doing that.

  • The Popup.Parent is a "Virtual View" - meaning that it is not native to a specific platform - there are no properties that point it to an associated native UIView. So that makes this task impossible.
  • IIRC, there was a method that was able to create a UIViewController from a View, but it created a new instance of it instead of referencing the one that is currently in runtime. So that makes this task impossible.
  • That is when I had to go in reverse - I took a Virtual view from Popup.Parent and tried to see if the Native Window had a UIViewController that had a reference to the Virtual View. Thankfully, I found a property under UIWindow.RootViewController called CurrentView. That was the only place that referenced the Virtual View inside a Native View. That is the reason I went with this route.

TLDR: Virtual Windows, Views, ViewControllers etc. know nothing about Native UIWindows, UIViews and UIViewControllers. However, Native UIWindows, UIViews and UIViewControllers do reference that Virtual Windows, ViewControllers and Views.

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree

@pictos
Copy link
Copy Markdown
Member

pictos commented Sep 15, 2023

The Popup.Parent is a "Virtual View" - meaning that it is not native to a specific platform - there are no properties that point it to an associated native UIView. So that makes this task impossible.

You can do something like

var pagehandler = VirtualView.Parent.Handler as PageHandler;
var viewController = pagehandler.ViewController;

and we're sure it's a PageHandler because we force it to be on the SetElement method

@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

The Popup.Parent is a "Virtual View" - meaning that it is not native to a specific platform - there are no properties that point it to an associated native UIView. So that makes this task impossible.

You can do something like

var pagehandler = VirtualView.Parent.Handler as PageHandler;
var viewController = pagehandler.ViewController;

and we're sure it's a PageHandler because we force it to be on the SetElement method

I'll try to look into this and update the PR if this indeed will work. This would be a much better solution. The small catch is that I may have to tackle this sometime this weekend.

Use PageHandler to get native UIViewController associated with the popup.
@babenkovitaliy
Copy link
Copy Markdown
Contributor Author

Alright. I have made the changes. I have tested out in a separate app I built where I referenced the compiled DLL files. The Popups work nicely now.

Fun, but controversial sidenote: I never realized how much I got spoiled by Visual Studio for Windows IDE. The rebase process is so much more nicer when using the GUI vs the command line (when you are not familiar with the command line). Since I was using Visual Studio for Mac, the GUI rebase process is more painful, so I had to switch over to command line. Ashamed to admit that it took me longer than it should have.

@pictos
Copy link
Copy Markdown
Member

pictos commented Sep 17, 2023

@babenkovitaliy if I told you how many times I missed up my branches using rebase, on both GUI and command line, you would not believe it kkkkk.

Thanks for the update and glad that worked as expected (:

@bijington
Copy link
Copy Markdown
Contributor

These changes look good. Thanks @babenkovitaliy and @pictos

Is it good to merge?

@pictos pictos enabled auto-merge (squash) September 18, 2023 13:34
@pictos
Copy link
Copy Markdown
Member

pictos commented Sep 18, 2023

Yes, it's. Enabled the auto-merge

@maonaoda
Copy link
Copy Markdown

maonaoda commented Oct 13, 2023

However, due to this change, the background color of the popup has become extremely light.

After:
image

Before:
image

@github-actions github-actions Bot locked and limited conversation to collaborators Nov 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Popup Does Not Support Multi-Window

6 participants