maui icon indicating copy to clipboard operation
maui copied to clipboard

Mac Catalyst window separator line being moved under certain circumstances

Open beeradmoore opened this issue 1 year ago • 12 comments

Description

So this one is odd and took me some time to narrow down in a repro project to narrow it down.

The short of it is there is a horizontal line on a window that separates the window title area (where close/max/min buttons are) and the content of a ContentPage. Putting a CollectionView (and seems ONLY a CollectionView) on a ContentPage that replaces the default Window.Page property this horizontal line will be moved to the top of the CollectionView.

Demo project has the following main changes from a file -> new project

  • Disabled all styles
  • Deleted shell

Using Mac Catalyst desktop idom (UIDeviceFamily=6) does not change the issue.

App class will create a new Window, this Window sets its Page to MainPage via its constructor. MainPage has a single button which replaces the Page property of the root window with a new TestPage object with the following code.

App.Current.Windows[0].Page = new TestPage();

NOTE: Using new TestPage() instead of new MainPage() when creating the Window in App causes the issue to not occur. It only happens if we replace the Page of our root Window.

Inside the TestPage we have the following layout.

<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,*">
    <VerticalStackLayout Grid.Column="0" Grid.Row="0">
        <Label Text="Test Label" FontSize="22" />
    </VerticalStackLayout>

    <Grid Grid.Row="1" Grid.Column="1" RowDefinitions="44,*">
        <BoxView Grid.Row="0" BackgroundColor="Red" />
        <CollectionView Grid.Row="1" BackgroundColor="Blue" />
    </Grid>
</Grid>

Up the top we have a VerticalStackLayout and a Label. We just need something to size content above the CollectionView so it can be seen. Under that we have a Grid which has a red BoxView followed by a blue CollectionView.

Changing the first RowDefinitions to be anything but Auto for the first row (eg, * or 50) will cause the issue to not occur. I feel this has something to do with a certain measure not happening.

Changing CollectionView to another type (I tried a ListView) means the problem will also not occur.

The horizontal line in question will appear between the red and blew areas of the page. Here is an example.

Image

If you resize the window, or do any of the things mentioned above for the issue to not occur then the page will look like this.

Image

An interesting observation I alluded to before is that the horizontal line is the separator from the window title bar. Here is a gif of me resizing, so you can see it jump in real time.

(EDIT: macOS 15.4 resizing no longer caused the horizontal line to move)

Image

I tested this on Windows, iOS, and Android, none of them showed the issue.

Steps to Reproduce

  1. See the repro project
  2. Run on Mac Catalyst
  3. Click the button to go to the test page
  4. Observe the window separator line not where it should be

Link to public reproduction project repository

https://github.com/beeradmoore/maui-issue-CollectionViewHorizontalLine

Version with bug

9.0.21 SR2.1 (EDIT: Updated sample to 9.0.50, problem still persists)

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

macOS

Affected platform versions

macOS Sequoia 15.2

EDIT: macOS 15.4 no longer has the line adjust go back to were it should be resizing the window.

Did you find any workaround?

Manually set the height of the content above a CollectionView. But considering this is the problem there will be other problems where that won't be acceptable.

Relevant log output

N/A

beeradmoore avatar Dec 16 '24 03:12 beeradmoore

I've noticed the same issue since upgrading to .net 9 - it essentially breaks the UI of any mac catalyst app which contains a CollectionView (which is a very wide range of apps).

piersdeseilligny avatar Jan 02 '25 13:01 piersdeseilligny

Just confirming this is still happening in MAUI 9.0.50

beeradmoore avatar Mar 25 '25 03:03 beeradmoore

Another update on this. I have narrowed the line itself (I think) down to whatever this view is. in WindowViewController.cs.

If I change that line to

platformTitleBar.TitleVisibility = UITitlebarTitleVisibility.Hidden;

The line never appears (neither does the titlebar). This is not a workaround at all. Also if you change the SeparatorStyle to have a shadow,

platformTitleBar.SeparatorStyle = UITitlebarSeparatorStyle.Shadow;

you can see that the the that is misplaced gets the shadow. Further conforming this is probably the view. I am just not sure why it is getting sized wrong.

I assume it is intended that _iTitleBarRef never has its inner value set to anything that isn't null. Because of this _contentWrapperTopConstraint.Constant = titleBarHeight; is always 0. Setting it to random numbers (eg,. 40 for nice size, 200 for silly size) does not make the problem go away.

The UITitleBar does not have Bounds or Frame properties so I am unsure what is setting its height.

The frame set in UpdateContentWrapperContentFrame does not change its height between the view working and not working so also probably unrelated.

Hey @tj-devel709, I can see you have done commits in this file. Is there any chance you'd know what would be causing this, or know who could be pinged who would?

beeradmoore avatar Mar 26 '25 03:03 beeradmoore

Re-visiting this I noticed the horizontal line no longer fixes itself when I resize the window. That was with MAUI 9.0.50 and Xcode 16.3. I downgraded to Xcode 16.2 and it did not resolve the issue. The only thing I can think of is macOS 15.4.1 (or is MacCatalyst workload v18.2.9180)

Bumping back to the latest things, Xcode 16.3 and MAUI 9.0.60.

Though workloads are being weird again.

> dotnet workload list  

Workload version: 9.0.203

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
android                    35.0.39/9.0.100        SDK 9.0.200        
ios                        18.2.9180/9.0.100      SDK 9.0.200        
maccatalyst                18.2.9180/9.0.100      SDK 9.0.200        
macos                      15.1.9163/9.0.100      SDK 9.0.200        
maui                       9.0.20/9.0.100         SDK 9.0.200        
maui-maccatalyst           9.0.20/9.0.100         SDK 9.0.200        
wasm-tools                 9.0.2/9.0.100          SDK 9.0.200     

But this does not change if I do update per instructions

dotnet workload install maccatalyst --version 9.0.203

EDIT: I just nuked my entire .NET install. Removed all runtimes and SDKs with the dotnet uninstall tool, nuked ~/.dotnet/, nuked /usr/local/share/dotnet/, (forgot to nuke ~/.nuget/)

Installed my base stuff

sudo dotnet workload install ios maccatalyst android maui

and now

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
android                    35.0.61/9.0.100        SDK 9.0.200        
ios                        18.4.9288/9.0.100      SDK 9.0.200        
maccatalyst                18.4.9288/9.0.100      SDK 9.0.200        
maui                       9.0.14/9.0.100         SDK 9.0.200    

I could see in the pre-nuke stage that Rider was using Mac Catalyst 18.2.9180, and I can confirm now it is using 18.4.9288.

The result is resizing still does not fix it.

Changing RowDefinitions to be anything but Auto also does not fix it. So the issue is seemingly worse than it was before.

beeradmoore avatar Apr 24 '25 00:04 beeradmoore

Just hit this one too - a vertical line cuts right through the full page width just above a CollectionView on MacCatalyst. It looks awful if the CollectionView isn't a direct child of the page. Interestingly, AFAICT, the opactity of the line isn't affected by the fade animation between pages - it's full black until the animation completes and then it disappears. Testing with dotnet sdk 9.0.203, MAUI 9.0.60.

jeremy-visionaid avatar May 13 '25 09:05 jeremy-visionaid

FWIW, I also tried the CollectionView2 handler but the issue persists

jeremy-visionaid avatar May 13 '25 10:05 jeremy-visionaid

As a workaround, I find that placing the CollectionView in a VerticalStackLayout moves the horizontal line back to the top of the page/window. Not much of a workaround for most people though, since it breaks scrolling the collection.

jeremy-visionaid avatar Jun 16 '25 03:06 jeremy-visionaid

I was able to confirm that with my sample above, even after updating MAUI to v9.0.80.

<Grid Grid.Row="1" Grid.Column="1" RowDefinitions="44,*">
    <BoxView Grid.Row="0" BackgroundColor="Red" />
    <VerticalStackLayout Grid.Row="1" BackgroundColor="Green">
        <CollectionView BackgroundColor="Blue">
            <CollectionView.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>First Item</x:String>
                    <x:String>Second Item</x:String>
                    <x:String>Third Item</x:String>
                </x:Array>
            </CollectionView.ItemsSource>
        </CollectionView>
    </VerticalStackLayout>
</Grid>

However, in my production app this does not work. The rows inside the CollectionView never show.

What is odd about the above is that the CollectionView vertical space will only be as long as the 3 rows. I would have expected to see all blue and no green (even if I added VerticalOptions=Fill) but that was never the case. If that is true I then think we have hit another bug with CollectionView not working inside a VerticalStackLayout.

beeradmoore avatar Jun 16 '25 06:06 beeradmoore

Some observations from different versions:

8.0.100 template: 2 pixel black line beneath nav bar 8.0.100 CollectionView: 2 pixel black line beneath nav bar 8.0.100 VerticalStackLayout + CollectionView: 1 pixel black line above nav bar and 1 below 9.0.80 template: Sometime 1 above and/or 1 below depending on resize/scroll 9.0.80 CollectionView: 1 pixel black line beneath nav bar 9.0.80 VerticalStackLayout + CollectionView: 1 pixel black line above nav bar

So, seems 9 is slightly better than 8, but I'd expect no black lines in any situation.

jeremy-visionaid avatar Jun 16 '25 08:06 jeremy-visionaid

OK, I think this is the same thing as this upstream issue:

https://developer.apple.com/forums/thread/717560

And I also find that the separator line cuts through page transition transparency.

Setting UITitlebar.SeparatorStyle to UITitlebarSeparatorStyle.None gets rid of the line.

https://developer.apple.com/documentation/uikit/uititlebarseparatorstyle/automatic?changes=latest__9&language=objc

This could probably be refined a bit, but disabling it entirely is better than it cutting through the middle of a page IMHO:

    static void SetTitlebarSeparatorStyle(UITitlebarSeparatorStyle style)
    {
        foreach (UIWindowScene windowScene in UIApplication.SharedApplication.ConnectedScenes.OfType<UIWindowScene>())
        {
            if (windowScene.Titlebar is UITitlebar titlebar)
                titlebar.SeparatorStyle = style;
        }
    }

jeremy-visionaid avatar Jun 17 '25 02:06 jeremy-visionaid

Setting it do none gets rid of the line until you drag the window.

From my above comments I was wondering how I was setting that. Checking my local source I was just editing and rebuilding MAUI. Pulling latest code I was unable to build because apparently node is a requirement. After getting that working I was able to play with it some more.

platformTitleBar.TitleVisibility = UITitlebarTitleVisibility.Visible;

Image

platformTitleBar.TitleVisibility = UITitlebarTitleVisibility.Hidden;

Image

IMO hiding it is not good because it the titlebar itself is now gone completely.

EDIT:

I was not setting it as

platformTitleBar.TitleVisibility = newTitleBar is null ? UITitlebarTitleVisibility.Visible : UITitlebarTitleVisibility.Hidden;

but instead

platformTitleBar.TitleVisibility = UITitlebarTitleVisibility.Hidden;

By using your two lines

platformTitleBar.SeparatorStyle = UITitlebarSeparatorStyle.None;
platformTitleBar.TitleVisibility = newTitleBar is null ? UITitlebarTitleVisibility.Visible : UITitlebarTitleVisibility.Hidden;

Now my sandbox app does this

Main window

Image

Main window on move

Image

Test window

Image

Test window on move

Image

beeradmoore avatar Jun 17 '25 03:06 beeradmoore

Oh interesting, thanks, I couldn't repro the behavior on move at first. The above images look a bit diferent to the one in your repo though. Mind posting the code for the Test window samples here to make sure I'm recreating it correctly?

When I try applying it to Maui.Controls.Sample.Sandbox with my PR applied, I observe a black line immediately under the title when the window is moved (not under the test label), but it disappears again on mouse over.

I notice something similar in Maui.Controls.Sample - The black line under the nav bar is thicker once the window is moved (and again thins to normal on mouse over). But then if you go to the Platform Specifics -> TitleBar and fiddle with some settings, then the line under the nav bar no longer thickens on move again.

jeremy-visionaid avatar Jun 17 '25 08:06 jeremy-visionaid

@beeradmoore A quick test in Swift this morning:

#if targetEnvironment(macCatalyst)
        let scene = UIApplication.shared.connectedScenes.first
        guard let windowScene = (scene as? UIWindowScene) else { return }
        windowScene.titlebar?.separatorStyle = .none
        windowScene.titlebar?.toolbar = nil
//        windowScene.titlebar?.titleVisibility = .hidden
#endif

Since I can repro in a basic Swift app, I'd say that the separator appearing on the window being moved is an upstream UIKit issue. I can't see an API call that can affect that short of perhaps replacing the titlebar with a custom one. I'm happy to just live with it, but we could/should open a support ticket on Apple

jeremy-visionaid avatar Jun 17 '25 21:06 jeremy-visionaid

Mind posting the code for the Test window samples here to make sure I'm recreating it correctly?

I had created/changed these MainPage.xaml/.xaml.cs and TestPage.xaml/.xaml.cs within src/Controls/samples/Controls.Sample.Sandbox/. Those 4 files are in this zip. The difference between ours could be because I navigate to the second page rather than putting the code on the first page?

Archive.zip

Someone reported it to Apple according to your earlier forum post (https://feedbackassistant.apple.com/feedback/1168135), I am unable to see it so I am unsure if that is permissions issue. I am also unsure if that is the correct place where people should report data.

I think the line appearing on move may be intended, but that the underlying issue of the line being pushed down into content area is still a bug, possibly in MAUI and/or XamMacOS.

IMO I think we should see if we can reproduce the issue in a .NET Mac Catalyst app.

  • If we can then try reproduce it in any of the native languages, if so then we report that.
  • If we can't then maybe it is a MAUI issue. It may also expose more information as to why it happens with CollectionView but not a ListView.

beeradmoore avatar Jun 17 '25 22:06 beeradmoore

Someone reported it to Apple according to your earlier forum post (https://feedbackassistant.apple.com/feedback/1168135)

I think there are a few related problems here, all potentially upstream UIKit things.

  1. The separator is somtimes in the wrong place
  2. The separator is unaffected by transparency
  3. The separator reappears when moving the window even when it is set to hidden

The first problem may or may not be a MAUI problem, The second and third problems are definitely UIKit problems, but I can't say whether they are intentional.

I think the forum post is about the transparency and the placement. AFAICT it doesn't mention about the reappearance, but I'll open a new one for that now.

jeremy-visionaid avatar Jun 17 '25 22:06 jeremy-visionaid

OK. Here's a new upstream issue for the reappearance on move: https://feedbackassistant.apple.com/feedback/18161892

We'll see what Apple says...

jeremy-visionaid avatar Jun 17 '25 22:06 jeremy-visionaid

For me second and third problems don't impact me as I will have a standard titlebar. I think they are a lot less of a problem if the first one was resolved. Your app may have different requirements though.

I would love to see first issue resolved, but if that is not possible then hiding it in a similar way to your PR is a good workaround.

Also fun fact about the line: it changes colour depending what it is on top of. We have it going over a video and it goes light.

Image

EDIT: Screenshot does not show it 👀 (now I question all of my above screenshots and their accuracy to what I see). Here is a photo.

Image

beeradmoore avatar Jun 17 '25 22:06 beeradmoore

OK. Here's a new upstream issue for the reappearance on move: https://feedbackassistant.apple.com/feedback/18161892

We'll see what Apple says...

Confirming that the above is permissions/privacy issue, trying to go to that for me says "Feedback Not Found".

EDIT: Also thanks for taking the time to report it upstream! The rest of us MAUI MacCatalyst devs appreciate it.

Image

beeradmoore avatar Jun 17 '25 22:06 beeradmoore

For me second and third problems don't impact me as I will have a standard titlebar. I think they are a lot less of a problem if the first one was resolved. Your app may have different requirements though.

Oh, I have a standard title bar, but the separator cuts through pretty much any page where there's CollectionView (about half of all pages) and it looks awful without the workaround in place 😬

Confirming that the above is permissions/privacy issue, trying to go to that for me says "Feedback Not Found".

I'll be sure to post back with their response here 👍

Thanks also for your initial investigation and findings - it definitely helped speed things up for me!

jeremy-visionaid avatar Jun 17 '25 22:06 jeremy-visionaid

So .NET 9 iOS/MacOS was just updated to support Xcode 16.4. I bumped all of my SDK versions and this line appears to be gone now 👀

For reference here is my setup,

App itself is using Microsoft.Maui.Controls 9.0.80.

> dotnet --list-sdks
9.0.301 [/usr/local/share/dotnet/sdk]

> dotnet --list-runtimes
Microsoft.AspNetCore.App 9.0.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

> dotnet workload list

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
android                    35.0.78/9.0.100        SDK 9.0.300        
ios                        18.5.9199/9.0.100      SDK 9.0.300        
maccatalyst                18.5.9199/9.0.100      SDK 9.0.300        
maui                       9.0.51/9.0.100         SDK 9.0.300 

> xcodes list
...
16.4 (16F6) (Installed, Selected)
...
Image

EDIT: I am not able to replicate when building MAUI from source with the reverted code in WindowViewController. I confirmed I didn't remove it with your workaround as UITitlebarTitleVisibility is not found in my own project.

beeradmoore avatar Jun 18 '25 00:06 beeradmoore

Ok, ignore that. It is still somewhat broken. I was going directly to the broken page in my app. According to my initial testing going straight to the page does not have the issue (unsure why I had the issue in this case).

I have updated my repro (maui-issue-CollectionViewHorizontalLine) to have latest MAUI and to use NavigationPage for navigation. It was originally replacing the main page with App.Current.Windows[0].Page. Navigating from MainPage to TestPage the horizontal line will appear and then reset itself back to the top bar where it belongs.

Still weird, still broken, just not as broken (at least in this case) as it was.

EDIT: I tried to downgrade to Xcode 16.3 (via Xcodes) to test again but the app won't build.

0>Xamarin.Shared.Sdk.targets(2338,3): Error : This version of .NET for MacCatalyst (18.5.9199) requires Xcode 16.4. The current version of Xcode is 16.3. Either install Xcode 16.4, or use a different version of .NET for MacCatalyst. See https://aka.ms/xcode-requirement for more information.

I downgraded .NET 9 macios to 18.4.9288 but I am seeing the same thing as I am with Xcode 16.4 and 18.5.9199. I don't know why my actual app now works, its code has not changed.

beeradmoore avatar Jun 18 '25 01:06 beeradmoore

Nearly 2 months later, absolutely no response from Apple, and not fixed in Sequoia 15.6.

jeremy-visionaid avatar Aug 08 '25 10:08 jeremy-visionaid

Oh, I might have just stumbled across an interesting workaround... If you enable multi-window support, then the separator line is always drawn in the right place!

https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/window?view=net-maui-9.0#ipados-and-macos-configuration

jeremy-visionaid avatar Aug 13 '25 01:08 jeremy-visionaid

@beeradmoore I've confirmed that the multi-window support workaround also works for your sample 👍

jeremy-visionaid avatar Aug 13 '25 01:08 jeremy-visionaid

I'm glad you found a solution.

We have since moved away from MAUI for our desktop apps. I don't think I need to list reasons why, I'm sure we can all guess.

beeradmoore avatar Aug 13 '25 03:08 beeradmoore

I've been seeing the same issue. I hadn't noticed it was the line moving though. it just seemed like a line appearging at the top of a collectionView.

But here is the confirmation

Image

Confirmed jeremy-visionaid's work around from June 17 is working for me

KevThompson2020 avatar Aug 19 '25 09:08 KevThompson2020