Closed Bug 1700211 Opened 10 months ago Closed 10 months ago

1px flickering white line in fullscreen when full-screen-api.macos.shiftToolbar is true

Categories

(Core :: Widget: Cocoa, defect, P1)

defect

Tracking

()

VERIFIED FIXED
89 Branch
Tracking Status
firefox89 --- verified

People

(Reporter: bugzilla, Assigned: bugzilla)

References

Details

Attachments

(3 files)

Bug 1699506 introduced the pref full-screen-api.macos.shiftToolbar. When true, the toolbar shifts down when the user mouses to the top of the screen in fullscreen mode. It does this by using the NSTitlebarAccessoryViewController API. The pref is false by default because it draws a 1px flickering white line at the top of the window.

QA found in bug 1699506 comment 14 that only macOS 11+ gets the flickering line. mstange found that the line is only drawn when the Firefox window is drawn with the regular Aqua appearance. If widget.macos.respect-system-appearance is true and the system is in Dark mode (and thus Firefox is drawn with the Aqua Dark appearance), the line is not drawn. I suspect this issue is closely related to bug 1578634, so I'm marking that as a dependency.

The strange things here are:

  • Without the NSTitlebarAccessoryViewController, the white line is not drawn in full screen mode. It's only drawn for normal windows.
  • With NSTitlebarAccessoryViewController, the white line is drawn in full screen mode, but not consistently. It is drawn during some window server composites but not during others. It only shows up in parts of the screen that the window server decided to repaint during the "bad" composites.

In https://phabricator.services.mozilla.com/D106847#inline-602190, Markus and I found that the white line is likely a NSTitlebarSeparatorView attached to a NSTitlebarAccessoryClipView. Neither are present when the NSTitlebarAccessoryViewController is not attached. Here's the view hierarchy dump:

<NSThemeFrame: 0x132d1fc00>  frame: {{0, 0}, {3008, 1667}}
    <NSVisualEffectView: 0x102aab000>  frame: {{0, 0}, {3008, 1667}}
    <NSView: 0x133673000>  frame: {{0, 0}, {3008, 1667}}
        ChildView 0x136fba400, gecko child 0x136fb9000, frame {{0, 0}, {3008, 1667}}  frame: {{0, 0}, {3008, 1667}}
            <ViewRegionContainerView: 0x136fba800>  frame: {{0, 0}, {3008, 1667}}
                <NonDraggableView: 0x13cb46c00>  frame: {{106, 0}, {257, 32.5}}
                <NonDraggableView: 0x13d05dc00>  frame: {{106, 32.5}, {225, 0.5}}
                <NonDraggableView: 0x13d05ec00>  frame: {{0, 33}, {133, 40}}
                <NonDraggableView: 0x13d05d400>  frame: {{250, 33}, {2469, 40}}
                <NonDraggableView: 0x13d05b000>  frame: {{2836, 33}, {128, 40}}
                <NonDraggableView: 0x13d05b400>  frame: {{2967, 33}, {41, 40}}
                <NonDraggableView: 0x13d05d800>  frame: {{0, 73}, {3008, 1594}}
            <ViewRegionContainerView: 0x136fbac00>  frame: {{0, 0}, {3008, 1667}}
            <PixelHostingView: 0x136fbc400>  frame: {{0, 0}, {3008, 1667}}
    <NSTitlebarContainerView: 0x13366fc00>  frame: {{0, 1639}, {3008, 28}}
        <NSTitlebarView: 0x133677000>  frame: {{0, 0}, {3008, 28}}
            <NSVisualEffectView: 0x1174cc800>  frame: {{0, 0}, {3008, 28}}
            <NSView: 0x133671c00>  frame: {{0, 0}, {3008, 28}}
            <NSTextField: 0x133676400>  frame: {{1450, 7}, {108, 16}}
            <NSView: 0x133853800>  frame: {{0, 0}, {3008, 0}}
                <NSTitlebarAccessoryClipView: 0x13384fc00>  frame: {{0, 0}, {3008, 0}}
                    <NSView: 0x13384e400>  frame: {{0, 0}, {3008, 28}}
                    <NSTitlebarSeparatorView: 0x13384dc00>  frame: {{0, -1}, {3008, 1}}
            <_NSThemeCloseWidget: 0x133668800>  frame: {{12, 3.5}, {14, 16}}
            <_NSThemeZoomWidget: 0x133669c00>  frame: {{52, 3.5}, {14, 16}}
            <_NSThemeWidget: 0x13366a000>  frame: {{32, 3.5}, {14, 16}}
        <_NSTitlebarDecorationView: 0x133668400>  frame: {{0, 0}, {3008, 28}}

I just did the same dump with respect-system-appearance: true in Dark mode, when the white line is not visible. It's exactly the same, including the 1px height pf the NSTitlebarSeparatorView.

fwiw, it looks like this is probably the purpose of the NSTitlebarAccessoryClipView:

To persistently show a portion of the accessory view, set this property to a value greater than 0. For example, if you have a fixed height accessory view, you can set fullScreenMinHeight to view.frame.size.height to show the view regardless of whether the menu bar is hidden. Note that the view's height is never actually changed when it is hidden or revealed; instead, it is automatically clipped by an internal clip view.

from https://developer.apple.com/documentation/appkit/nstitlebaraccessoryviewcontroller/1397782-fullscreenminheight?language=objc

Attached file standalone testcase

This standalone testcase reproduces the bug. It looks like the combination of fullscreen + NSWindowStyleMaskFullSizeContentView + titlebarAppearsTransparent + NSTitlebarAccessoryViewController is all that's needed.

In the test app, there are two NSWindows during fullscreen: the toolbar overlay window, and the regular window. The accessory view is in the toolbar overlay window. You get different NSView and CALayer tree dumps when you click the blue view and when you click the black view.
The flickering line is where the NSTitlebarSeparatorView is located in the overlay window.

In Big-Sur, NSWindow has a new titlebarSeparatorStyle property. Setting it to NSTitlebarSeparatorStyleNone on the original window does not help. However, setting it to NSTitlebarSeparatorStyleNone on the overlay window does help! Here's what fixes it in the standalone app:

- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
  NSLog(@"view %@ is moving to window %@", self, newWindow);
  if (newWindow) {
    if (@available(macOS 11.0, *)) {
      newWindow.titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone;
    }
  }
}

Ok, so the next steps here are:

  1. File a bug with Apple:
    1. Reduce the testcase as much as possible
    2. Write up a Feedback report, and submit it with the testcase.
  2. Fix the line in Firefox:
    1. Our titlebar accessory view controller currently contains a plain NSView. Replace this with a new subclass of NSView, e.g. MOZTitlebarAccessoryView.
    2. Add SDK-ifdefed API declarations for the titlebarSeparatorStyle property and the NSTitlebarSeparatorStyle enum.
    3. Implement viewWillMoveToWindow on MOZTitlebarAccessoryView as in comment 5.
No longer depends on: 1578634

(In reply to Markus Stange [:mstange] from comment #6)

2. Write up a Feedback report, and submit it with the testcase.

Filed as FB9056136.

Assignee: nobody → htwyford
Status: NEW → ASSIGNED

I think there are three bugs on the macOS side here:

  1. On windows that have titlebarAppearsTransparent set to YES, the titlebar separator should never be drawn - the value of titlebarSeparatorStyle shouldn't matter.
  2. The floating full screen titlebar window should adopt the titlebarSeparatorStyle that was specified on the original window.
  3. When the separator is drawn on the floating full screen titlebar window, it's drawn as a glitchy white line.
Attachment #9211932 - Attachment description: Bug 1700211 - Set titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone on NSTitlebarAccessoryViewController to eliminate flickering line. r?mstange! → Bug 1700211 - Set titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone on the floating full screen titlebar NSWindow to eliminate flickering line. r?mstange!
Pushed by htwyford@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/9abe385b83a5
Set titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone on the floating full screen titlebar NSWindow to eliminate flickering line. r=mstange
Status: ASSIGNED → RESOLVED
Closed: 10 months ago
Resolution: --- → FIXED
Target Milestone: --- → 89 Branch

We can no longer reproduce the issue using Firefox 89.0a1 (20210401155139) on macOS 11.2.3 M1 and Intel platforms. We tested with native fullscreen on and off. The white line is no longer displayed on the top of the browser while in fullscreen and position mouse to activate the shifting toolbar.

Status: RESOLVED → VERIFIED

I don't understand, how is this fixed? I still have this problem?

(In reply to mohammad22012003 from comment #13)

I don't understand, how is this fixed? I still have this problem?

Can you please share the information from about:support? Also, what version of macOS are you on?

Flags: needinfo?(mohammad22012003)
Attached file My about:support info
(In reply to Harry Twyford [:harry] from comment #14)
> (In reply to mohammad22012003 from comment #13)
> > I don't understand, how is this fixed? I still have this problem?
> 
> Can you please share the information from about:support? Also, what version of macOS are you on?

Thank you for trying to help! I also have to say, I also have the same problem on my Macbook Air (M1), so it's not only on my main iMac.

My about:support information

You're running Firefox 88, but this bug is fixed for Firefox 89. Did you manually enable the full-screen-api.macos.shiftToolbar pref? It wasn't supposed to be enabled by default for macOS 11+ until Firefox 89.

(In reply to Harry Twyford [:harry] from comment #16)

You're running Firefox 88, but this bug is fixed for Firefox 89. Did you manually enable the full-screen-api.macos.shiftToolbar pref? It wasn't supposed to be enabled by default for macOS 11+ until Firefox 89.

Oh ok I understand now. I am still very disoriented by this environment. I indeed did turn it on manually. But thank you very much, guess I have to wait for F89. :)

Flags: needinfo?(mohammad22012003)
You need to log in before you can comment on or make changes to this bug.