summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/plugins/platforms/cocoa/qcocoasystemtrayicon.mm96
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/icons.qrc11
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray16x16.pngbin0 -> 101 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray18x18.pngbin0 -> 108 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray25x15.pngbin0 -> 109 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray32x32.pngbin0 -> 117 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray36x36.pngbin0 -> 151 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray50x30.pngbin0 -> 167 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/macsystray64x64.pngbin0 -> 204 bytes
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/main.cpp88
-rw-r--r--tests/manual/cocoa/qsystemtrayicon/qsystemtrayicon.pro7
11 files changed, 170 insertions, 32 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 83c960d931..e449fd37d6 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -187,6 +187,14 @@ void QCocoaSystemTrayIcon::cleanup()
m_sys = 0;
}
+static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); }
+static QList<QSize> sortByHeight(const QList<QSize> sizes)
+{
+ QList<QSize> sorted = sizes;
+ std::sort(sorted.begin(), sorted.end(), heightCompareFunction);
+ return sorted;
+}
+
void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
{
if (!m_sys)
@@ -196,16 +204,62 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
+ // The reccomended maximum title bar icon height is 18 points
+ // (device independent pixels). The menu height on past and
+ // current OS X versions is 22 points. Provide some future-proofing
+ // by deriving the icon height from the menu height.
+ const int padding = 4;
+ const int menuHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
+ const int maxImageHeight = menuHeight - padding;
+
+ // Select pixmap based on the device pixel height. Ideally we would use
+ // the devicePixelRatio of the target screen, but that value is not
+ // known until draw time. Use qApp->devicePixelRatio, which returns the
+ // devicePixelRatio for the "best" screen on the system.
+ qreal devicePixelRatio = qApp->devicePixelRatio();
+ const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
+ const QIcon::Mode mode = menuVisible ? QIcon::Selected : QIcon::Normal;
+ QSize selectedSize;
+ Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
+ // Select a pixmap based on the height. We want the largest pixmap
+ // with a height smaller or equal to maxPixmapHeight. The pixmap
+ // may rectangular; assume it has a reasonable size. If there is
+ // not suitable pixmap use the smallest one the icon can provide.
+ if (size.height() <= maxPixmapHeight) {
+ selectedSize = size;
+ } else {
+ if (!selectedSize.isValid())
+ selectedSize = size;
+ break;
+ }
+ }
- QPixmap pm = m_sys->item->icon.pixmap(QSize(scale, scale),
- menuVisible ? QIcon::Selected : QIcon::Normal);
- if (pm.isNull()) {
- pm = QPixmap(scale, scale);
- pm.fill(Qt::transparent);
+ QPixmap pixmap = icon.pixmap(selectedSize, mode);
+
+ // Draw a low-resolution icon if there is not enough pixels for a retina
+ // icon. This prevents showing a small icon on retina displays.
+ if (devicePixelRatio > 1.0 && selectedSize.height() < maxPixmapHeight / 2)
+ devicePixelRatio = 1.0;
+
+ // Scale large pixmaps to fit the available menu bar area.
+ if (pixmap.height() > maxPixmapHeight)
+ pixmap = pixmap.scaledToHeight(maxPixmapHeight, Qt::SmoothTransformation);
+
+ // The icon will be stretched over the full height of the menu bar
+ // therefore we create a second pixmap which has the full height
+ QSize fullHeightSize(!pixmap.isNull() ? pixmap.width():
+ menuHeight * devicePixelRatio,
+ menuHeight * devicePixelRatio);
+ QPixmap fullHeightPixmap(fullHeightSize);
+ fullHeightPixmap.fill(Qt::transparent);
+ if (!pixmap.isNull()) {
+ QPainter p(&fullHeightPixmap);
+ QRect r = pixmap.rect();
+ r.moveCenter(fullHeightPixmap.rect().center());
+ p.drawPixmap(r, pixmap);
}
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pm));
+
+ NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(fullHeightPixmap));
[(NSImageView*)[[m_sys->item item] view] setImage: nsimage];
[nsimage release];
}
@@ -327,18 +381,7 @@ QT_END_NAMESPACE
Q_UNUSED(notification);
down = NO;
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-
- QPixmap pm = parent->icon.pixmap(QSize(scale, scale), QIcon::Normal);
- if (pm.isNull()) {
- pm = QPixmap(scale, scale);
- pm.fill(Qt::transparent);
- }
- NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage(pm));
- [self setImage: nsaltimage];
- [nsaltimage release];
-
+ parent->systray->updateIcon(parent->icon);
parent->menuVisible = false;
[self setNeedsDisplay:YES];
@@ -350,18 +393,7 @@ QT_END_NAMESPACE
int clickCount = [mouseEvent clickCount];
[self setNeedsDisplay:YES];
- CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- const short scale = hgt - 4;
-
- QPixmap pm = parent->icon.pixmap(QSize(scale, scale),
- parent->menuVisible ? QIcon::Selected : QIcon::Normal);
- if (pm.isNull()) {
- pm = QPixmap(scale, scale);
- pm.fill(Qt::transparent);
- }
- NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage(pm));
- [self setImage: nsaltimage];
- [nsaltimage release];
+ parent->systray->updateIcon(parent->icon);
if (clickCount == 2) {
[self menuTrackingDone:nil];
diff --git a/tests/manual/cocoa/qsystemtrayicon/icons.qrc b/tests/manual/cocoa/qsystemtrayicon/icons.qrc
new file mode 100644
index 0000000000..2486dcab34
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/icons.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="/">
+ <file>macsystray18x18.png</file>
+ <file>macsystray36x36.png</file>
+ <file>macsystray25x15.png</file>
+ <file>macsystray50x30.png</file>
+ <file>macsystray16x16.png</file>
+ <file>macsystray32x32.png</file>
+ <file>macsystray64x64.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray16x16.png b/tests/manual/cocoa/qsystemtrayicon/macsystray16x16.png
new file mode 100644
index 0000000000..e6930f16c6
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray16x16.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray18x18.png b/tests/manual/cocoa/qsystemtrayicon/macsystray18x18.png
new file mode 100644
index 0000000000..4316516d85
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray18x18.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray25x15.png b/tests/manual/cocoa/qsystemtrayicon/macsystray25x15.png
new file mode 100644
index 0000000000..c1a98b898c
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray25x15.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray32x32.png b/tests/manual/cocoa/qsystemtrayicon/macsystray32x32.png
new file mode 100644
index 0000000000..35f0f28ae7
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray32x32.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray36x36.png b/tests/manual/cocoa/qsystemtrayicon/macsystray36x36.png
new file mode 100644
index 0000000000..d2c6df066c
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray36x36.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray50x30.png b/tests/manual/cocoa/qsystemtrayicon/macsystray50x30.png
new file mode 100644
index 0000000000..afea90b7fe
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray50x30.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/macsystray64x64.png b/tests/manual/cocoa/qsystemtrayicon/macsystray64x64.png
new file mode 100644
index 0000000000..b2a126d78f
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/macsystray64x64.png
Binary files differ
diff --git a/tests/manual/cocoa/qsystemtrayicon/main.cpp b/tests/manual/cocoa/qsystemtrayicon/main.cpp
new file mode 100644
index 0000000000..9b3fc2bd13
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/main.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtWidgets>
+
+int main(int argc, char**argv)
+{
+ QApplication app(argc, argv);
+
+ QWidget window;
+ window.show();
+
+ QSystemTrayIcon systrayIcon(&window);
+
+
+ enum Iconset { Square, // square icons, reccomended size (18 device-independent pixels or less)
+ Rectangular, // rectangular icons, good size
+ PowerOfTwo, // standard pow-2 icons, not optimized for the OS X menu bar
+ Small, // Not enough pixels
+ UnreasonablyLarge // please do something reasonable with my unreasonably large pixmap
+ };
+
+ // Select icon set and load images
+ Iconset iconset = Square;
+ QIcon icon;
+ switch (iconset) {
+ case Square:
+ icon.addFile(":/macsystray36x36.png");
+ icon.addFile(":/macsystray18x18.png");
+ break;
+ case Rectangular:
+ icon.addFile(":/macsystray50x30.png");
+ icon.addFile(":/macsystray25x15.png");
+ break;
+ case PowerOfTwo:
+ icon.addFile(":/macsystray16x16.png");
+ icon.addFile(":/macsystray32x32.png");
+ icon.addFile(":/macsystray64x64.png");
+ break;
+ case Small:
+ icon.addFile(":/macsystray16x16.png");
+ case UnreasonablyLarge:
+ icon.addFile(":/macsystray64x64.png");
+ break;
+ }
+
+ systrayIcon.setIcon(icon);
+ systrayIcon.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/cocoa/qsystemtrayicon/qsystemtrayicon.pro b/tests/manual/cocoa/qsystemtrayicon/qsystemtrayicon.pro
new file mode 100644
index 0000000000..459ebafa38
--- /dev/null
+++ b/tests/manual/cocoa/qsystemtrayicon/qsystemtrayicon.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = qsystemtrayicon
+INCLUDEPATH += .
+QT += widgets
+
+SOURCES += main.cpp
+RESOURCES += icons.qrc