summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm11
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.h21
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm286
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm16
-rw-r--r--src/plugins/platforms/cocoa/qnsview_dragging.mm4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp4
-rw-r--r--src/plugins/platforms/ios/kernel.pro6
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.h46
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.mm103
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.h3
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.mm30
-rw-r--r--src/plugins/platforms/platforms.pro4
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp2
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h3
22 files changed, 327 insertions, 275 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index e0d623fc4c..c10ada1ada 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -335,24 +335,8 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit
NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot)
{
NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y());
- NSImage *nsimage;
- if (pixmap.devicePixelRatio() > 1.0) {
- QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio();
- QPixmap scaledPixmap = pixmap.scaled(layoutSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- scaledPixmap.setDevicePixelRatio(1.0);
- nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(scaledPixmap));
- CGImageRef cgImage = qt_mac_toCGImage(pixmap.toImage());
- NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
- [nsimage addRepresentation:imageRep];
- [imageRep release];
- CGImageRelease(cgImage);
- } else {
- nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- }
-
- NSCursor *nsCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot: hotSpot];
- [nsimage release];
- return nsCursor;
+ auto *image = [NSImage imageFromQImage:pixmap.toImage()];
+ return [[NSCursor alloc] initWithImage:image hotSpot:hotSpot];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 95808b8a11..b4a16ab912 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -130,9 +130,8 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPoint hotSpot = m_drag->hotSpot();
QPixmap pm = dragPixmap(m_drag, hotSpot);
- QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
- NSImage *nsimage = qt_mac_create_nsimage(pm);
- [nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
+ NSImage *dragImage = [NSImage imageFromQImage:pm.toImage()];
+ Q_ASSERT(dragImage);
QMacPasteboard dragBoard(CFStringRef(NSPasteboardNameDrag), QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
@@ -142,12 +141,12 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSWindow *theWindow = [m_lastEvent window];
Q_ASSERT(theWindow);
event_location.x -= hotSpot.x();
- CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
+ CGFloat flippedY = dragImage.size.height - hotSpot.y();
event_location.y -= flippedY;
NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSPasteboardNameDrag];
- [theWindow dragImage:nsimage
+ [theWindow dragImage:dragImage
at:event_location
offset:mouseOffset_unused
event:m_lastEvent
@@ -155,8 +154,6 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
source:m_lastView
slideBack:YES];
- [nsimage release];
-
m_drag = nullptr;
return m_executed_drop_action;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 6db4bdb9fd..ccb6e20071 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -554,7 +554,7 @@ NSOpenGLContext *QCocoaGLContext::nativeContext() const
QFunctionPointer QCocoaGLContext::getProcAddress(const char *procName)
{
- return (QFunctionPointer)dlsym(RTLD_DEFAULT, procName);
+ return (QFunctionPointer)dlsym(RTLD_NEXT, procName);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index b2698b05fe..1fb250317d 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -482,14 +482,7 @@ QList<QCocoaWindow *> *QCocoaIntegration::popupWindowStack()
void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const
{
- NSImage *image = nil;
- if (!icon.isNull()) {
- NSSize size = [[[NSApplication sharedApplication] dockTile] size];
- QPixmap pixmap = icon.pixmap(size.width, size.height);
- image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- }
- [[NSApplication sharedApplication] setApplicationIconImage:image];
- [image release];
+ NSApp.applicationIconImage = [NSImage imageFromQIcon:icon];
}
void QCocoaIntegration::beep() const
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index ef9b2659d2..a2100a6369 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -340,13 +340,7 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand;
}
- NSImage *img = nil;
- if (!m_icon.isNull()) {
- img = qt_mac_create_nsimage(m_icon, m_iconSize);
- img.size = CGSizeMake(m_iconSize, m_iconSize);
- }
- m_native.image = img;
- [img release];
+ m_native.image = [NSImage imageFromQIcon:m_icon withSize:m_iconSize];
m_native.state = m_checked ? NSOnState : NSOffState;
return m_native;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
index 738c40aba6..7999438ca5 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
@@ -49,14 +49,23 @@
#include "QtCore/qstring.h"
#include "QtGui/qpa/qplatformsystemtrayicon.h"
-QT_BEGIN_NAMESPACE
+#include "qcocoamenu.h"
+
+QT_FORWARD_DECLARE_CLASS(QCocoaSystemTrayIcon);
+
+@interface QT_MANGLE_NAMESPACE(QStatusItemDelegate) : NSObject <NSUserNotificationCenterDelegate>
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)platformSystemTray;
+@property (nonatomic, assign) QCocoaSystemTrayIcon *platformSystemTray;
+@end
-class QSystemTrayIconSys;
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QStatusItemDelegate);
+
+QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon
{
public:
- QCocoaSystemTrayIcon() : m_sys(nullptr) {}
+ QCocoaSystemTrayIcon() {}
void init() override;
void cleanup() override;
@@ -70,8 +79,12 @@ public:
bool isSystemTrayAvailable() const override;
bool supportsMessages() const override;
+ void statusItemClicked();
+
private:
- QSystemTrayIconSys *m_sys;
+ NSStatusItem *m_statusItem = nullptr;
+ QStatusItemDelegate *m_delegate = nullptr;
+ QCocoaMenu *m_menu = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 559188aa5f..8e7c86a0ef 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -92,67 +92,46 @@
#import <AppKit/AppKit.h>
-QT_USE_NAMESPACE
-
-@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate>
-@property (nonatomic, assign) QCocoaMenu *menu;
-@property (nonatomic, assign) QIcon icon;
-@property (nonatomic, readonly) NSStatusItem *item;
-@property (nonatomic, readonly) QRectF geometry;
-- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)systray;
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton;
-- (void)doubleClickSelector:(id)sender;
-@end
+QT_BEGIN_NAMESPACE
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
+void QCocoaSystemTrayIcon::init()
+{
+ m_statusItem = [[NSStatusBar.systemStatusBar statusItemWithLength:NSSquareStatusItemLength] retain];
-@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView
-@property (nonatomic, assign) BOOL down;
-@property (nonatomic, assign) QNSStatusItem *parent;
-@end
+ m_delegate = [[QStatusItemDelegate alloc] initWithSysTray:this];
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
+ m_statusItem.button.target = m_delegate;
+ m_statusItem.button.action = @selector(statusItemClicked);
+ [m_statusItem.button sendActionOn:NSEventMaskLeftMouseUp | NSEventMaskRightMouseUp | NSEventMaskOtherMouseUp];
+}
-QT_BEGIN_NAMESPACE
-class QSystemTrayIconSys
+void QCocoaSystemTrayIcon::cleanup()
{
-public:
- QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) {
- item = [[QNSStatusItem alloc] initWithSysTray:sys];
- NSUserNotificationCenter.defaultUserNotificationCenter.delegate = item;
- }
- ~QSystemTrayIconSys() {
- [[[item item] view] setHidden: YES];
- NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
- if (center.delegate == item)
- center.delegate = nil;
- [item release];
- }
- QNSStatusItem *item;
-};
+ NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
+ if (center.delegate == m_delegate)
+ center.delegate = nil;
-void QCocoaSystemTrayIcon::init()
-{
- if (!m_sys)
- m_sys = new QSystemTrayIconSys(this);
+ [NSStatusBar.systemStatusBar removeStatusItem:m_statusItem];
+ [m_statusItem release];
+ m_statusItem = nil;
+
+ [m_delegate release];
+ m_delegate = nil;
+
+ m_menu = nullptr;
}
QRect QCocoaSystemTrayIcon::geometry() const
{
- if (!m_sys)
+ if (!m_statusItem)
return QRect();
- const QRectF geom = [m_sys->item geometry];
- if (!geom.isNull())
- return geom.toRect();
- else
- return QRect();
-}
+ if (NSWindow *window = m_statusItem.button.window) {
+ if (QCocoaScreen *screen = QCocoaScreen::get(window.screen))
+ return screen->mapFromNative(window.frame).toRect();
+ }
-void QCocoaSystemTrayIcon::cleanup()
-{
- delete m_sys;
- m_sys = nullptr;
+ return QRect();
}
static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); }
@@ -165,17 +144,15 @@ static QList<QSize> sortByHeight(const QList<QSize> &sizes)
void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- m_sys->item.icon = icon;
-
- // The reccomended maximum title bar icon height is 18 points
+ // The recommended 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 = [[NSStatusBar systemStatusBar] thickness];
+ const int menuHeight = NSStatusBar.systemStatusBar.thickness;
const int maxImageHeight = menuHeight - padding;
// Select pixmap based on the device pixel height. Ideally we would use
@@ -228,30 +205,28 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
p.drawPixmap(r, pixmap);
}
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(fullHeightPixmap));
+ auto *nsimage = [NSImage imageFromQImage:fullHeightPixmap.toImage()];
[nsimage setTemplate:icon.isMask()];
- [(NSImageView*)[[m_sys->item item] view] setImage: nsimage];
- [nsimage release];
+ m_statusItem.button.image = nsimage;
+ m_statusItem.button.imageScaling = NSImageScaleProportionallyDown;
}
void QCocoaSystemTrayIcon::updateMenu(QPlatformMenu *menu)
{
- if (!m_sys)
- return;
-
- m_sys->item.menu = static_cast<QCocoaMenu *>(menu);
- if (menu && [m_sys->item.menu->nsMenu() numberOfItems] > 0) {
- [[m_sys->item item] setHighlightMode:YES];
- } else {
- [[m_sys->item item] setHighlightMode:NO];
- }
+ // We don't set the menu property of the NSStatusItem here,
+ // as that would prevent us from receiving the action for the
+ // click, and we wouldn't be able to emit the activated signal.
+ // Instead we show the menu manually when the status item is
+ // clicked.
+ m_menu = static_cast<QCocoaMenu *>(menu);
}
void QCocoaSystemTrayIcon::updateToolTip(const QString &toolTip)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- [[[m_sys->item item] view] setToolTip:toolTip.toNSString()];
+
+ m_statusItem.button.toolTip = toolTip.toNSString();
}
bool QCocoaSystemTrayIcon::isSystemTrayAvailable() const
@@ -267,180 +242,83 @@ bool QCocoaSystemTrayIcon::supportsMessages() const
void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message,
const QIcon& icon, MessageIcon, int msecs)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- NSUserNotification *notification = [[NSUserNotification alloc] init];
- notification.title = [NSString stringWithUTF8String:title.toUtf8().data()];
- notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()];
-
- if (!icon.isNull()) {
- auto *nsimage = qt_mac_create_nsimage(icon);
- [nsimage setTemplate:icon.isMask()];
- notification.contentImage = [nsimage autorelease];
- }
+ auto *notification = [[NSUserNotification alloc] init];
+ notification.title = title.toNSString();
+ notification.informativeText = message.toNSString();
+ notification.contentImage = [NSImage imageFromQIcon:icon];
NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
- center.delegate = m_sys->item;
- [center deliverNotification:notification];
+ center.delegate = m_delegate;
+
+ [center deliverNotification:[notification autorelease]];
+
if (msecs) {
NSTimeInterval timeout = msecs / 1000.0;
[center performSelector:@selector(removeDeliveredNotification:) withObject:notification afterDelay:timeout];
}
- [notification release];
}
-QT_END_NAMESPACE
-@implementation NSStatusItem (Qt)
-@end
-
-@implementation QNSImageView
-- (instancetype)initWithParent:(QNSStatusItem *)myParent {
- self = [super init];
- self.parent = myParent;
- self.down = NO;
- return self;
-}
-
-- (void)menuTrackingDone:(NSNotification *)__unused notification
+void QCocoaSystemTrayIcon::statusItemClicked()
{
- self.down = NO;
+ auto *mouseEvent = NSApp.currentEvent;
- [self setNeedsDisplay:YES];
-}
+ auto activationReason = QPlatformSystemTrayIcon::Unknown;
-- (void)mousePressed:(NSEvent *)mouseEvent
-{
- self.down = YES;
- int clickCount = [mouseEvent clickCount];
- [self setNeedsDisplay:YES];
-
- if (clickCount == 2) {
- [self menuTrackingDone:nil];
- [self.parent doubleClickSelector:self];
+ if (mouseEvent.clickCount == 2) {
+ activationReason = QPlatformSystemTrayIcon::DoubleClick;
} else {
- [self.parent triggerSelector:self button:cocoaButton2QtButton(mouseEvent)];
+ auto mouseButton = cocoaButton2QtButton(mouseEvent);
+ if (mouseButton == Qt::MidButton)
+ activationReason = QPlatformSystemTrayIcon::MiddleClick;
+ else if (mouseButton == Qt::RightButton)
+ activationReason = QPlatformSystemTrayIcon::Context;
+ else
+ activationReason = QPlatformSystemTrayIcon::Trigger;
}
-}
-
-- (void)mouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent];
-}
-- (void)mouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
+ emit activated(activationReason);
-- (void)rightMouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent];
+ if (NSMenu *menu = m_menu ? m_menu->nsMenu() : nil)
+ [m_statusItem popUpStatusItemMenu:menu];
}
-- (void)rightMouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
+QT_END_NAMESPACE
-- (void)otherMouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent];
-}
+@implementation QStatusItemDelegate
-- (void)otherMouseUp:(NSEvent *)mouseEvent
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)platformSystemTray
{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
-
-- (void)drawRect:(NSRect)rect {
- [[self.parent item] drawStatusBarBackgroundInRect:rect withHighlight:self.down];
- [super drawRect:rect];
-}
-@end
-
-@implementation QNSStatusItem {
- QCocoaSystemTrayIcon *systray;
- NSStatusItem *item;
- QNSImageView *imageCell;
-}
+ if ((self = [super init]))
+ self.platformSystemTray = platformSystemTray;
-@synthesize menu = menu;
-@synthesize icon = icon;
-
-- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)sys
-{
- self = [super init];
- if (self) {
- item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
- menu = nullptr;
- systray = sys;
- imageCell = [[QNSImageView alloc] initWithParent:self];
- [item setView: imageCell];
- }
return self;
}
-- (void)dealloc {
- [[NSStatusBar systemStatusBar] removeStatusItem:item];
- [[NSNotificationCenter defaultCenter] removeObserver:imageCell];
- imageCell.parent = nil;
- [imageCell release];
- [item release];
+- (void)dealloc
+{
+ self.platformSystemTray = nullptr;
[super dealloc];
}
-- (NSStatusItem *)item {
- return item;
-}
-
-- (QRectF)geometry {
- if (NSWindow *window = item.view.window) {
- if (QCocoaScreen *screen = QCocoaScreen::get(window.screen))
- return screen->mapFromNative(window.frame);
- }
- return QRectF();
-}
-
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton {
- Q_UNUSED(sender);
- if (!systray)
- return;
-
- if (mouseButton == Qt::MidButton)
- emit systray->activated(QPlatformSystemTrayIcon::MiddleClick);
- else
- emit systray->activated(QPlatformSystemTrayIcon::Trigger);
-
- if (menu) {
- NSMenu *m = menu->nsMenu();
- [[NSNotificationCenter defaultCenter] addObserver:imageCell
- selector:@selector(menuTrackingDone:)
- name:NSMenuDidEndTrackingNotification
- object:m];
- [item popUpStatusItemMenu: m];
- }
-}
-
-- (void)doubleClickSelector:(id)sender {
- Q_UNUSED(sender);
- if (!systray)
- return;
- emit systray->activated(QPlatformSystemTrayIcon::DoubleClick);
+- (void)statusItemClicked
+{
+ self.platformSystemTray->statusItemClicked();
}
-- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
+{
Q_UNUSED(center);
Q_UNUSED(notification);
return YES;
}
-- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
+- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
+{
[center removeDeliveredNotification:notification];
- emit systray->messageClicked();
+ emit self.platformSystemTray->messageClicked();
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 61bf0d4a4e..35b0ec2d40 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -891,14 +891,10 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
QMacAutoReleasePool pool;
- if (icon.isNull()) {
- 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 autorelease]];
- }
+ if (icon.isNull())
+ iconButton.image = [NSWorkspace.sharedWorkspace iconForFile:m_view.window.representedFilename];
+ else
+ iconButton.image = [NSImage imageFromQIcon:icon];
}
void QCocoaWindow::setAlertState(bool enabled)
@@ -1237,7 +1233,9 @@ void QCocoaWindow::windowDidOrderOffScreen()
void QCocoaWindow::windowDidChangeOcclusionState()
{
- if (m_view.window.occlusionState & NSWindowOcclusionStateVisible)
+ bool visible = m_view.window.occlusionState & NSWindowOcclusionStateVisible;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::windowDidChangeOcclusionState" << window() << "is now" << (visible ? "visible" : "occluded");
+ if (visible)
[m_view setNeedsDisplay:YES];
else
handleExposeEvent(QRegion());
diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm
index 650612e7ff..463e3c5579 100644
--- a/src/plugins/platforms/cocoa/qnsview_dragging.mm
+++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm
@@ -150,10 +150,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
break;
}
} else {
- NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
- nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
+ auto *nsimage = [NSImage imageFromQImage:pixmapCursor.toImage()];
nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
- [nsimage release];
}
// Change the cursor
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
index e3145aa0b0..b985386a4e 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
@@ -185,7 +185,9 @@ void QEglFSDeviceIntegration::platformDestroy()
EGLNativeDisplayType QEglFSDeviceIntegration::platformDisplay() const
{
- return EGL_DEFAULT_DISPLAY;
+ bool displayOk;
+ const int defaultDisplay = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEFAULT_DISPLAY", &displayOk);
+ return displayOk ? EGLNativeDisplayType(quintptr(defaultDisplay)) : EGL_DEFAULT_DISPLAY;
}
EGLDisplay QEglFSDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
diff --git a/src/plugins/platforms/ios/kernel.pro b/src/plugins/platforms/ios/kernel.pro
index 01e0105223..c483076856 100644
--- a/src/plugins/platforms/ios/kernel.pro
+++ b/src/plugins/platforms/ios/kernel.pro
@@ -59,13 +59,15 @@ HEADERS = \
qiosmenu.mm \
qiosfiledialog.mm \
qiosmessagedialog.mm \
- qiostextinputoverlay.mm
+ qiostextinputoverlay.mm \
+ qiosdocumentpickercontroller.mm
HEADERS += \
qiosclipboard.h \
qiosmenu.h \
qiosfiledialog.h \
qiosmessagedialog.h \
- qiostextinputoverlay.h
+ qiostextinputoverlay.h \
+ qiosdocumentpickercontroller.h
}
OTHER_FILES = \
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.h b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
new file mode 100644
index 0000000000..dba6f24fc5
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Harald Meyer.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include "qiosfiledialog.h"
+
+@interface QIOSDocumentPickerController : UIDocumentPickerViewController <UIDocumentPickerDelegate, UINavigationControllerDelegate>
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
+@end
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
new file mode 100644
index 0000000000..c1b641e839
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Harald Meyer.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+
+#include "qiosdocumentpickercontroller.h"
+
+@implementation QIOSDocumentPickerController {
+ QIOSFileDialog *m_fileDialog;
+}
+
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
+{
+ NSMutableArray <NSString *> *docTypes = [[[NSMutableArray alloc] init] autorelease];
+ UIDocumentPickerMode importMode;
+ switch (fileDialog->options()->fileMode()) {
+ case QFileDialogOptions::AnyFile:
+ case QFileDialogOptions::ExistingFile:
+ case QFileDialogOptions::ExistingFiles:
+ [docTypes addObject:(__bridge NSString *)kUTTypeContent];
+ [docTypes addObject:(__bridge NSString *)kUTTypeItem];
+ [docTypes addObject:(__bridge NSString *)kUTTypeData];
+ importMode = UIDocumentPickerModeImport;
+ break;
+ case QFileDialogOptions::Directory:
+ case QFileDialogOptions::DirectoryOnly:
+ // Directory picking is not supported because it requires
+ // special handling not possible with the current QFilePicker
+ // implementation.
+
+ Q_UNREACHABLE();
+ }
+
+ if (self = [super initWithDocumentTypes:docTypes inMode:importMode]) {
+ m_fileDialog = fileDialog;
+ self.modalPresentationStyle = UIModalPresentationFormSheet;
+ self.delegate = self;
+
+ if (m_fileDialog->options()->fileMode() == QFileDialogOptions::ExistingFiles)
+ self.allowsMultipleSelection = YES;
+
+ if (@available(ios 13.0, *))
+ self.directoryURL = m_fileDialog->options()->initialDirectory().toNSURL();
+ }
+ return self;
+}
+
+- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls
+{
+ Q_UNUSED(controller);
+
+ QList<QUrl> files;
+ for (NSURL* url in urls)
+ files.append(QUrl::fromNSURL(url));
+
+ m_fileDialog->selectedFilesChanged(files);
+ emit m_fileDialog->accept();
+}
+
+- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
+{
+ Q_UNUSED(controller)
+ emit m_fileDialog->reject();
+}
+
+@end
diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h
index 5cb1b45e20..eab05091ef 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.h
+++ b/src/plugins/platforms/ios/qiosfiledialog.h
@@ -65,7 +65,7 @@ public:
void selectNameFilter(const QString &) override {}
QString selectedNameFilter() const override { return QString(); }
- void selectedFilesChanged(QList<QUrl> selection);
+ void selectedFilesChanged(const QList<QUrl> &selection);
private:
QUrl m_directory;
@@ -74,6 +74,7 @@ private:
UIViewController *m_viewController;
bool showImagePickerDialog(QWindow *parent);
+ bool showNativeDocumentPickerDialog(QWindow *parent);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm
index e8a3f5b30e..edf04016fd 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.mm
+++ b/src/plugins/platforms/ios/qiosfiledialog.mm
@@ -48,6 +48,7 @@
#include "qiosfiledialog.h"
#include "qiosintegration.h"
#include "qiosoptionalplugininterface.h"
+#include "qiosdocumentpickercontroller.h"
QIOSFileDialog::QIOSFileDialog()
: m_viewController(nullptr)
@@ -72,8 +73,12 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window
bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
QString directory = options()->initialDirectory().toLocalFile();
- if (acceptOpen && directory.startsWith(QLatin1String("assets-library:")))
- return showImagePickerDialog(parent);
+ if (acceptOpen) {
+ if (directory.startsWith(QLatin1String("assets-library:")))
+ return showImagePickerDialog(parent);
+ else
+ return showNativeDocumentPickerDialog(parent);
+ }
return false;
}
@@ -102,6 +107,25 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
return true;
}
+bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
+{
+#ifndef Q_OS_TVOS
+ if (options()->fileMode() == QFileDialogOptions::Directory ||
+ options()->fileMode() == QFileDialogOptions::DirectoryOnly)
+ return false;
+
+ m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:this];
+
+ UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
+ : qt_apple_sharedApplication().keyWindow;
+ [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
+
+ return true;
+#else
+ return false;
+#endif
+}
+
void QIOSFileDialog::hide()
{
// QFileDialog will remember the last directory set, and open subsequent dialogs in the same
@@ -123,7 +147,7 @@ QList<QUrl> QIOSFileDialog::selectedFiles() const
return m_selection;
}
-void QIOSFileDialog::selectedFilesChanged(QList<QUrl> selection)
+void QIOSFileDialog::selectedFilesChanged(const QList<QUrl> &selection)
{
m_selection = selection;
emit filesSelected(m_selection);
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index c4f2b30965..23f838a7fe 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -3,9 +3,9 @@ QT_FOR_CONFIG += gui-private
android:!android-embedded: SUBDIRS += android
-!android: SUBDIRS += minimal
+!wasm:!android: SUBDIRS += minimal
-!android:qtConfig(freetype): SUBDIRS += offscreen
+!wasm:!android:qtConfig(freetype): SUBDIRS += offscreen
qtConfig(xcb) {
SUBDIRS += xcb
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
index 4ddd56fd8c..fbf700518e 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -88,7 +88,7 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes); // Populate with default attributes
- attributes.preferLowPowerToHighPerformance = false;
+ attributes.powerPreference = EM_WEBGL_POWER_PREFERENCE_HIGH_PERFORMANCE;
attributes.failIfMajorPerformanceCaveat = false;
attributes.antialias = true;
attributes.enableExtensionsByDefault = true;
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 594db65cfd..f95335f891 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -265,6 +265,8 @@ bool QWasmWindow::isPointOnTitle(QPoint point) const
bool QWasmWindow::isPointOnResizeRegion(QPoint point) const
{
+ if (window()->flags().testFlag(Qt::Popup))
+ return false;
return resizeRegion().contains(point);
}
@@ -402,7 +404,8 @@ void QWasmWindow::requestUpdate()
bool QWasmWindow::hasTitleBar() const
{
- return !(m_windowState & Qt::WindowFullScreen) && (window()->flags().testFlag(Qt::WindowTitleHint) && m_needsCompositor);
+ return !(m_windowState & Qt::WindowFullScreen) && (window()->flags().testFlag(Qt::WindowTitleHint) && m_needsCompositor)
+ && !window()->flags().testFlag(Qt::Popup);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index 79b5ba06e6..ff5c50b702 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -122,6 +122,7 @@ static const char *xcb_atomnames = {
"_NET_WM_STATE_MODAL\0"
"_NET_WM_STATE_STAYS_ON_TOP\0"
"_NET_WM_STATE_DEMANDS_ATTENTION\0"
+ "_NET_WM_STATE_HIDDEN\0"
"_NET_WM_USER_TIME\0"
"_NET_WM_USER_TIME_WINDOW\0"
diff --git a/src/plugins/platforms/xcb/qxcbatom.h b/src/plugins/platforms/xcb/qxcbatom.h
index 233d2eadb7..80b5887395 100644
--- a/src/plugins/platforms/xcb/qxcbatom.h
+++ b/src/plugins/platforms/xcb/qxcbatom.h
@@ -123,6 +123,7 @@ public:
_NET_WM_STATE_MODAL,
_NET_WM_STATE_STAYS_ON_TOP,
_NET_WM_STATE_DEMANDS_ATTENTION,
+ _NET_WM_STATE_HIDDEN,
_NET_WM_USER_TIME,
_NET_WM_USER_TIME_WINDOW,
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5be04a984a..40106bbeaf 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -903,6 +903,8 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
result |= NetWmStateStaysOnTop;
if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
result |= NetWmStateDemandsAttention;
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_HIDDEN)))
+ result |= NetWmStateHidden;
} else {
qCDebug(lcQpaXcb, "getting net wm state (%x), empty\n", m_window);
}
@@ -1074,6 +1076,9 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow()
states |= NetWmStateBelow;
}
+ if (window()->windowStates() & Qt::WindowMinimized)
+ states |= NetWmStateHidden;
+
if (window()->windowStates() & Qt::WindowFullScreen)
states |= NetWmStateFullScreen;
@@ -1107,6 +1112,8 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow()
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
+ if (states & NetWmStateHidden && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_HIDDEN)))
+ atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_HIDDEN));
if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
@@ -2204,10 +2211,16 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
|| (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
}
}
- if (m_minimized)
- newState = Qt::WindowMinimized;
const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+ // within the screen bounds. The canonical example is that minimized windows should be in
+ // the _NET_WM_STATE_HIDDEN state.
+ if (m_minimized && (!connection()->wmSupport()->isSupportedByWM(NetWmStateHidden)
+ || states.testFlag(NetWmStateHidden)))
+ newState = Qt::WindowMinimized;
+
if (states & NetWmStateFullScreen)
newState |= Qt::WindowFullScreen;
if ((states & NetWmStateMaximizedHorz) && (states & NetWmStateMaximizedVert))
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index d6f370eebe..0cdc40f82d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -68,7 +68,8 @@ public:
NetWmStateMaximizedVert = 0x10,
NetWmStateModal = 0x20,
NetWmStateStaysOnTop = 0x40,
- NetWmStateDemandsAttention = 0x80
+ NetWmStateDemandsAttention = 0x80,
+ NetWmStateHidden = 0x100
};
Q_DECLARE_FLAGS(NetWmStates, NetWmState)