summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2017-09-28 15:46:45 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2017-10-03 07:30:26 +0000
commitbccbb52b7a96b3cba4dc5c9977792ed0223d5a83 (patch)
tree29bd67eb30fcc03a4b1978c80bac346d52f4fe25 /src/plugins/platforms/cocoa
parentd89229240918c567c915c1e444d5b60f2f4c958d (diff)
macOS: Tighten up window icon and represented filename handling
Window icons on macOS are tied to document windows, and should not show up unless a represented filename has also been set according to the HIG. We follow this, and no longer create a document button based on the window title if one did no exists. We also fall back to using the filename of the file if a title has not been set, including being able to restore this default title after setting a custom title. The icon is no longer reset to nil after setting a QIcon(), which would remove the icon completely, but instead we restore the default behavior of showing the default filetype icon of the file. Finally, the two callbacks in QNSWindowDelegate dealing with the document icon/title popups and drags have been taught to look for spaces in the represented filename. This allows clients who really want the old behavior of setting an icon without caring about the filename to set the filename to a single space character, which will prevent the dropdowna and drag from occurring. The reason for not tying this behavior to the existence of the file in the filesystem is that being able to represent a file that is yet to be saved is a valid usecase. Task-number: QTBUG-63338 Change-Id: I7d4377c6358226fb6058f8c2b3c28588eec77ce5 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm37
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm12
3 files changed, 32 insertions, 19 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index a93a391358..3230c32133 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -285,8 +285,6 @@ public: // for QNSView
};
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
-
- bool m_hasWindowFilePath;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 217bfb3602..8f5b419f2a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -157,7 +157,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
, m_drawContentBorderGradient(false)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
- , m_hasWindowFilePath(false)
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::QCocoaWindow" << window();
@@ -594,6 +593,11 @@ void QCocoaWindow::setWindowTitle(const QString &title)
QMacAutoReleasePool pool;
m_view.window.title = title.toNSString();
+
+ if (title.isEmpty() && !window()->filePath().isEmpty()) {
+ // Clearing the title should restore the default filename
+ setWindowFilePath(window()->filePath());
+ }
}
void QCocoaWindow::setWindowFilePath(const QString &filePath)
@@ -602,9 +606,14 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
return;
QMacAutoReleasePool pool;
- QFileInfo fi(filePath);
- [m_view.window setRepresentedFilename:fi.exists() ? filePath.toNSString() : @""];
- m_hasWindowFilePath = fi.exists();
+
+ if (window()->title().isNull())
+ [m_view.window setTitleWithRepresentedFilename:filePath.toNSString()];
+ else
+ m_view.window.representedFilename = filePath.toNSString();
+
+ // Changing the file path may affect icon visibility
+ setWindowIcon(window()->icon());
}
void QCocoaWindow::setWindowIcon(const QIcon &icon)
@@ -612,23 +621,21 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
if (!isContentView())
return;
- QMacAutoReleasePool pool;
-
NSButton *iconButton = [m_view.window standardWindowButton:NSWindowDocumentIconButton];
- if (iconButton == nil) {
- if (icon.isNull())
- return;
- NSString *title = window()->title().toNSString();
- [m_view.window setRepresentedURL:[NSURL fileURLWithPath:title]];
- iconButton = [m_view.window standardWindowButton:NSWindowDocumentIconButton];
+ if (!iconButton) {
+ // Window icons are only supported on macOS in combination with a document filePath
+ return;
}
+
+ QMacAutoReleasePool pool;
+
if (icon.isNull()) {
- [iconButton setImage:nil];
+ NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+ [iconButton setImage:[workspace iconForFile:m_view.window.representedFilename]];
} else {
QPixmap pixmap = icon.pixmap(QSize(22, 22));
NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- [iconButton setImage:image];
- [image release];
+ [iconButton setImage:[image autorelease]];
}
}
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 1224d138d9..cdecd86dfb 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -44,6 +44,8 @@
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
+static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
+
@implementation QNSWindowDelegate
- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
@@ -98,7 +100,10 @@
{
Q_UNUSED(window);
Q_UNUSED(menu);
- return m_cocoaWindow && m_cocoaWindow->m_hasWindowFilePath;
+
+ // Only pop up document path if the filename is non-empty. We allow whitespace, to
+ // allow faking a window icon by setting the file path to a single space character.
+ return !whitespaceRegex.exactMatch(m_cocoaWindow->window()->filePath());
}
- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard
@@ -107,6 +112,9 @@
Q_UNUSED(event);
Q_UNUSED(dragImageLocation);
Q_UNUSED(pasteboard);
- return m_cocoaWindow && m_cocoaWindow->m_hasWindowFilePath;
+
+ // Only allow drag if the filename is non-empty. We allow whitespace, to
+ // allow faking a window icon by setting the file path to a single space.
+ return !whitespaceRegex.exactMatch(m_cocoaWindow->window()->filePath());
}
@end