[macOS] Fix position of sheets when using unifiedTitleAndToolBarOnMac

Modal sheets are supposed to appear below the toolbar if a toolbar
exists, or below the title bar if a toolbar doesn't exist.
In the unified title and toolbar mode, sheets should to appear
directly below the toolbar, if the toolbar is positioned at the
top of the window.

Code-wise we achieve that by calling setUnifiedTitleAndToolBarOnMac on
a QMainWindow, which results in adjusting the top content border of
the NSWindow via [NSWindow setContentBorderThickness:forEdge], which
Cocoa uses to position a modal sheet (the sheet top edge is aligned
with the top edge of the content view + the Y border thickness
value).

The issue is that because NSWindow.titlebarAppearsTransparent is set
to YES, for sheet presentation purposes, Cocoa considers the content
view to begin at the position of the top left corner of the
frame (where the title bar is), and thus sheets appear somewhere
in the middle of the unified toolbar.

To fix that we need to account for the title bar height in the
border thickness value.
Compute the title bar height from the window frame height - window
content view height, and add it to the top border thickness value.

Amends 8ac9addd94

Change-Id: Icf85c513035cc3710b438e60eb14dc04c5bbaced
Fixes: QTBUG-65451
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Alexandru Croitor 2018-09-28 17:37:58 +02:00
parent 7146c9075c
commit 836a2fb887

View File

@ -1714,6 +1714,14 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
[window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
window.titlebarAppearsTransparent = YES;
// Setting titlebarAppearsTransparent to YES means that the border thickness has to account
// for the title bar height as well, otherwise sheets will not be presented at the correct
// position, which should be (title bar height + top content border size).
const NSRect frameRect = window.frame;
const NSRect contentRect = [window contentRectForFrameRect:frameRect];
const CGFloat titlebarHeight = frameRect.size.height - contentRect.size.height;
effectiveTopContentBorderThickness += titlebarHeight;
[window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];