diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioseventdispatcher.mm | 39 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 56 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbnativeinterface.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 12 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 13 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 2 | ||||
-rw-r--r-- | src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp | 115 | ||||
-rw-r--r-- | src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h | 1 | ||||
-rw-r--r-- | src/plugins/printsupport/cups/qcupsprintengine.cpp | 32 | ||||
-rw-r--r-- | src/plugins/printsupport/cups/qcupsprintengine_p.h | 1 | ||||
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac.mm | 85 | ||||
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac_p_p.h | 7 | ||||
-rw-r--r-- | src/plugins/styles/windowsvista/qwindowsvistastyle.cpp | 49 | ||||
-rw-r--r-- | src/plugins/styles/windowsvista/qwindowsxpstyle.cpp | 23 |
15 files changed, 253 insertions, 186 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 7ea3d130f7..98b9f7c9ba 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -198,7 +198,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); static QString strippedText(QString s) { - s.remove( QString::fromLatin1("...") ); + s.remove(QLatin1String("...")); return QPlatformTheme::removeMnemonics(s).trimmed(); } diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index de2c30cdfb..a6f6a7aac9 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -228,7 +228,7 @@ extern "C" int qt_main_wrapper(int argc, char *argv[]) } } - qEventDispatcherDebug() << "Running UIApplicationMain"; qIndent(); + qCDebug(lcEventDispatcher) << "Running UIApplicationMain"; return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); } } @@ -263,7 +263,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline() int exitCode = main(argc, argv); delete[] argv; - qEventDispatcherDebug() << "Returned from main with exit code " << exitCode; + qCDebug(lcEventDispatcher) << "Returned from main with exit code " << exitCode; if (Q_UNLIKELY(debugStackUsage)) userMainStack.printUsage(); @@ -322,7 +322,7 @@ static bool rootLevelRunLoopIntegration() + (void)applicationDidFinishLaunching:(NSNotification *)notification { - qCDebug(lcQpaApplication) << "Application launched with options" << notification.userInfo; + qCDebug(lcEventDispatcher) << "Application launched with options" << notification.userInfo; if (!isQtApplication()) return; @@ -331,7 +331,7 @@ static bool rootLevelRunLoopIntegration() // We schedule the main-redirection for the next run-loop pass, so that we // can return from this function and let UIApplicationMain finish its job. // This results in running Qt's application eventloop as a nested runloop. - qCDebug(lcQpaApplication) << "Scheduling main() on next run-loop pass"; + qCDebug(lcEventDispatcher) << "Scheduling main() on next run-loop pass"; CFRunLoopTimerRef userMainTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, ^(CFRunLoopTimerRef) { user_main_trampoline(); }); CFRunLoopAddTimer(CFRunLoopGetMain(), userMainTimer, kCFRunLoopCommonModes); @@ -339,10 +339,10 @@ static bool rootLevelRunLoopIntegration() return; } + switch (setjmp(processEventEnterJumpPoint)) { case kJumpPointSetSuccessfully: - qCDebug(lcQpaApplication) << "Running main() on separate stack"; qIndent(); - + qCDebug(lcEventDispatcher) << "Running main() on separate stack"; // Redirect the stack pointer to the start of the reserved stack. This ensures // that when we longjmp out of the event dispatcher and continue execution, the // 'Qt main' call-stack will not be smashed, as it lives in a part of the stack @@ -360,7 +360,7 @@ static bool rootLevelRunLoopIntegration() case kJumpedFromEventDispatcherProcessEvents: // We've returned from the longjmp in the event dispatcher, // and the stack has been restored to its old self. - qUnIndent(); qCDebug(lcQpaApplication) << "Returned from processEvents"; + qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to exec"; if (Q_UNLIKELY(debugStackUsage)) userMainStack.printUsage(); @@ -396,18 +396,18 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80); applicationAboutToTerminate = true; switch (setjmp(applicationWillTerminateJumpPoint)) { case kJumpPointSetSuccessfully: - qEventDispatcherDebug() << "Exiting qApp with SIGTERM exit code"; qIndent(); + qCDebug(lcEventDispatcher) << "Exiting qApp with SIGTERM exit code"; qApp->exit(kApplicationWillTerminateExitCode); // The runloop will not exit when the application is about to terminate, // so we'll never see the exit activity and have a chance to return from // QEventLoop::exec(). We initiate the return manually as a workaround. - qEventDispatcherDebug() << "Manually triggering return from event loop exec"; + qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec"; static_cast<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec(); break; case kJumpedFromUserMainTrampoline: // The user's main has returned, so we're ready to let iOS terminate the application - qUnIndent(); qEventDispatcherDebug() << "kJumpedFromUserMainTrampoline, allowing iOS to terminate"; + qCDebug(lcEventDispatcher) << "kJumpedFromUserMainTrampoline, allowing iOS to terminate"; break; default: qFatal("Unexpected jump result in event loop integration"); @@ -434,13 +434,15 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo return QEventDispatcherCoreFoundation::processEvents(flags); if (applicationAboutToTerminate) { - qEventDispatcherDebug() << "Detected QEventLoop exec after application termination"; + qCDebug(lcEventDispatcher) << "Detected QEventLoop exec after application termination"; // Re-issue exit, and return immediately qApp->exit(kApplicationWillTerminateExitCode); return false; } if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) { + qCDebug(lcEventDispatcher) << "Processing events with flags" << flags; + ++m_processEventLevel; m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes); @@ -449,7 +451,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo // is asked to exit, so that we can return from QEventLoop::exec(). switch (setjmp(processEventExitJumpPoint)) { case kJumpPointSetSuccessfully: - qEventDispatcherDebug() << "QEventLoop exec detected, jumping back to native runloop"; + qCDebug(lcEventDispatcher) << "QEventLoop exec detected, jumping back to system runloop ↵"; longjmp(processEventEnterJumpPoint, kJumpedFromEventDispatcherProcessEvents); break; case kJumpedFromEventLoopExecInterrupt: @@ -457,7 +459,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo // signal), and we jumped back though processEventExitJumpPoint. We return from processEvents, // which will emit aboutToQuit if it's QApplication's event loop, and then return to the user's // main, which can do whatever it wants, including calling exec() on the application again. - qEventDispatcherDebug() << "kJumpedFromEventLoopExecInterrupt, returning with eventsProcessed = true"; + qCDebug(lcEventDispatcher) << "⇢ System runloop exited, returning with eventsProcessed = true"; return true; default: qFatal("Unexpected jump result in event loop integration"); @@ -485,9 +487,8 @@ bool QIOSEventDispatcher::processPostedEvents() if (!QEventDispatcherCoreFoundation::processPostedEvents()) return false; - qEventDispatcherDebug() << "Sending window system events for " << m_processEvents.flags; qIndent(); + qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags; QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags); - qUnIndent(); return true; } @@ -497,10 +498,8 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); - if (m_processEventLevel == 1 && !currentEventLoop()->isRunning()) { - qEventDispatcherDebug() << "Root runloop level exited"; + if (m_processEventLevel == 1 && !currentEventLoop()->isRunning()) interruptEventLoopExec(); - } } void QIOSEventDispatcher::interruptEventLoopExec() @@ -516,12 +515,12 @@ void QIOSEventDispatcher::interruptEventLoopExec() // processEvents, instead of back in didFinishLaunchingWithOptions. switch (setjmp(processEventEnterJumpPoint)) { case kJumpPointSetSuccessfully: - qEventDispatcherDebug() << "Jumping back to processEvents"; + qCDebug(lcEventDispatcher) << "Jumping into processEvents due to system runloop exit ⇢"; longjmp(processEventExitJumpPoint, kJumpedFromEventLoopExecInterrupt); break; case kJumpedFromEventDispatcherProcessEvents: // QEventLoop was re-executed - qEventDispatcherDebug() << "kJumpedFromEventDispatcherProcessEvents"; + qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to re-exec"; break; default: qFatal("Unexpected jump result in event loop integration"); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index d989761297..22d90d6ac2 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -673,4 +673,60 @@ void *QXcbNativeInterface::handlerNativeResourceForBackingStore(const QByteArray return nullptr; } +static void dumpNativeWindowsRecursion(const QXcbConnection *connection, xcb_window_t window, + int level, QTextStream &str) +{ + if (level) + str << QByteArray(2 * level, ' '); + + xcb_connection_t *conn = connection->xcb_connection(); + auto geomReply = Q_XCB_REPLY(xcb_get_geometry, conn, window); + if (!geomReply) + return; + const QRect geom(geomReply->x, geomReply->y, geomReply->width, geomReply->height); + if (!geom.isValid() || (geom.width() <= 3 && geom.height() <= 3)) + return; // Skip helper/dummy windows. + str << "0x"; + const int oldFieldWidth = str.fieldWidth(); + const QChar oldPadChar =str.padChar(); + str.setFieldWidth(8); + str.setPadChar(QLatin1Char('0')); + str << hex << window; + str.setFieldWidth(oldFieldWidth); + str.setPadChar(oldPadChar); + str << dec << " \"" + << QXcbWindow::windowTitle(connection, window) << "\" " + << geom.width() << 'x' << geom.height() << forcesign << geom.x() << geom.y() + << noforcesign << '\n'; + + auto reply = Q_XCB_REPLY(xcb_query_tree, conn, window); + if (reply) { + const int count = xcb_query_tree_children_length(reply.get()); + const xcb_window_t *children = xcb_query_tree_children(reply.get()); + for (int i = 0; i < count; ++i) + dumpNativeWindowsRecursion(connection, children[i], level + 1, str); + } +} + +QString QXcbNativeInterface::dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const +{ + QString result; + QTextStream str(&result); + if (root) { + dumpNativeWindowsRecursion(connection, xcb_window_t(root), 0, str); + } else { + for (const QXcbScreen *screen : connection->screens()) { + str << "Screen: \"" << screen->name() << "\"\n"; + dumpNativeWindowsRecursion(connection, screen->root(), 0, str); + str << '\n'; + } + } + return result; +} + +QString QXcbNativeInterface::dumpNativeWindows(WId root) const +{ + return dumpConnectionNativeWindows(QXcbIntegration::instance()->defaultConnection(), root); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index fb0db727aa..6a752c68ca 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -127,6 +127,8 @@ public: Q_INVOKABLE bool systrayVisualHasAlphaChannel(); Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window); Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window); + Q_INVOKABLE QString dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const; + Q_INVOKABLE QString dumpNativeWindows(WId root = 0) const; void addHandler(QXcbNativeInterfaceHandler *handler); void removeHandler(QXcbNativeInterfaceHandler *handler); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index e3d9bc7a3d..49bf5181cc 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -91,16 +91,8 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) { xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply.get())); - if (windowManager != XCB_WINDOW_NONE) { - auto windowManagerReply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), - false, windowManager, - atom(QXcbAtom::_NET_WM_NAME), - atom(QXcbAtom::UTF8_STRING), 0, 1024); - if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { - m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply.get()), - xcb_get_property_value_length(windowManagerReply.get())); - } - } + if (windowManager != XCB_WINDOW_NONE) + m_windowManagerName = QXcbWindow::windowTitle(connection, windowManager); } const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 44b337f555..5b05a230e4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2849,5 +2849,18 @@ QXcbScreen *QXcbWindow::xcbScreen() const return static_cast<QXcbScreen *>(screen()); } +QString QXcbWindow::windowTitle(const QXcbConnection *conn, xcb_window_t window) +{ + const xcb_atom_t utf8Atom = conn->atom(QXcbAtom::UTF8_STRING); + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, conn->xcb_connection(), + false, window, conn->atom(QXcbAtom::_NET_WM_NAME), + utf8Atom, 0, 1024); + if (reply && reply->format == 8 && reply->type == utf8Atom) { + const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get())); + return QString::fromUtf8(name); + } + return QString(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f506d7dd6f..957c4e9cbd 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -184,6 +184,8 @@ public: virtual void create(); virtual void destroy(); + static QString windowTitle(const QXcbConnection *conn, xcb_window_t window); + public Q_SLOTS: void updateSyncRequestCounter(); diff --git a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp b/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp index c51223186e..1a24015ce5 100644 --- a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp +++ b/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp @@ -147,61 +147,7 @@ void QFlatpakFileDialog::initializeDialog() setDirectory(options()->initialDirectory()); } -bool QFlatpakFileDialog::defaultNameFilterDisables() const -{ - return false; -} - -void QFlatpakFileDialog::setDirectory(const QUrl &directory) -{ - Q_D(QFlatpakFileDialog); - - d->directory = directory.path(); -} - -QUrl QFlatpakFileDialog::directory() const -{ - Q_D(const QFlatpakFileDialog); - - return d->directory; -} - -void QFlatpakFileDialog::selectFile(const QUrl &filename) -{ - Q_D(QFlatpakFileDialog); - - d->selectedFiles << filename.path(); -} - -QList<QUrl> QFlatpakFileDialog::selectedFiles() const -{ - Q_D(const QFlatpakFileDialog); - - QList<QUrl> files; - for (const QString &file : d->selectedFiles) { - files << QUrl(file); - } - return files; -} - -void QFlatpakFileDialog::setFilter() -{ - // TODO -} - -void QFlatpakFileDialog::selectNameFilter(const QString &filter) -{ - Q_UNUSED(filter); - // TODO -} - -QString QFlatpakFileDialog::selectedNameFilter() const -{ - // TODO - return QString(); -} - -void QFlatpakFileDialog::exec() +void QFlatpakFileDialog::openPortal() { Q_D(const QFlatpakFileDialog); @@ -305,7 +251,64 @@ void QFlatpakFileDialog::exec() SLOT(gotResponse(uint,QVariantMap))); } }); +} +bool QFlatpakFileDialog::defaultNameFilterDisables() const +{ + return false; +} + +void QFlatpakFileDialog::setDirectory(const QUrl &directory) +{ + Q_D(QFlatpakFileDialog); + + d->directory = directory.path(); +} + +QUrl QFlatpakFileDialog::directory() const +{ + Q_D(const QFlatpakFileDialog); + + return d->directory; +} + +void QFlatpakFileDialog::selectFile(const QUrl &filename) +{ + Q_D(QFlatpakFileDialog); + + d->selectedFiles << filename.path(); +} + +QList<QUrl> QFlatpakFileDialog::selectedFiles() const +{ + Q_D(const QFlatpakFileDialog); + + QList<QUrl> files; + for (const QString &file : d->selectedFiles) { + files << QUrl(file); + } + return files; +} + +void QFlatpakFileDialog::setFilter() +{ + // TODO +} + +void QFlatpakFileDialog::selectNameFilter(const QString &filter) +{ + Q_UNUSED(filter); + // TODO +} + +QString QFlatpakFileDialog::selectedNameFilter() const +{ + // TODO + return QString(); +} + +void QFlatpakFileDialog::exec() +{ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected QEventLoop loop; loop.connect(this, SIGNAL(accept()), SLOT(quit())); @@ -327,6 +330,8 @@ bool QFlatpakFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality wi d->modal = windowModality != Qt::NonModal; d->winId = parent ? parent->winId() : 0; + openPortal(); + return true; } diff --git a/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h b/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h index 8f65d07e62..f3e195faa0 100644 --- a/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h +++ b/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h @@ -90,6 +90,7 @@ private Q_SLOTS: private: void initializeDialog(); + void openPortal(); QScopedPointer<QFlatpakFileDialogPrivate> d_ptr; }; diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index 763f676e41..bd0d641e79 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -250,38 +250,6 @@ void QCupsPrintEnginePrivate::closePrintDevice() } } -void QCupsPrintEnginePrivate::setupDefaultPrinter() -{ - // Should never have reached here if no plugin available, but check just in case - QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); - if (!ps) - return; - - // Get default printer id, if no default then use the first available - // TODO Find way to remove printerName from base class? - printerName = ps->defaultPrintDeviceId(); - if (printerName.isEmpty()) { - QStringList list = ps->availablePrintDeviceIds(); - if (list.size() > 0) - printerName = list.at(0); - } - - // Should never have reached here if no printers available, but check just in case - if (printerName.isEmpty()) - return; - - m_printDevice = ps->createPrintDevice(printerName); - if (!m_printDevice.isValid()) - return; - - // Setup the printer defaults - duplex = m_printDevice.defaultDuplexMode(); - grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale; - // CUPS server always supports collation, even if individual m_printDevice doesn't - collate = true; - setPageSize(m_printDevice.defaultPageSize()); -} - void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter) { // Don't waste time if same printer name diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index c99c48c7ea..d5363bb8cc 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -93,7 +93,6 @@ public: private: Q_DISABLE_COPY(QCupsPrintEnginePrivate) - void setupDefaultPrinter(); void changePrinter(const QString &newPrinter); void setPageSize(const QPageSize &pageSize); diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 1041187407..10fe3f6f0e 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -237,6 +237,19 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QIndeterminateProgressIndicator); @end +@interface QT_MANGLE_NAMESPACE(QVerticalSplitView) : NSSplitView +- (BOOL)isVertical; +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QVerticalSplitView); + +@implementation QVerticalSplitView +- (BOOL)isVertical +{ + return YES; +} +@end + QT_BEGIN_NAMESPACE // The following constants are used for adjusting the size @@ -2002,6 +2015,15 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const // at construction time, and it cannot be changed later. bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; break; + case SplitView_Horizontal: + bv = [[NSSplitView alloc] init]; + break; + case SplitView_Vertical: + bv = [[QVerticalSplitView alloc] init]; + break; + case TextField: + bv = [[NSTextField alloc] init]; + break; default: break; } @@ -2076,7 +2098,7 @@ NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const return cell; } -void QMacStylePrivate::drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, DrawRectBlock drawRectBlock) const +void QMacStylePrivate::drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, __attribute__((noescape)) DrawRectBlock drawRectBlock) const { QPoint offset; if (widget == CocoaControl(Button_PopupButton, QStyleHelper::SizeSmall)) @@ -3444,35 +3466,21 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai case PE_FrameLineEdit: if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { if (frame->state & State_Sunken) { - QColor baseColor(frame->palette.background().color()); - HIThemeFrameDrawInfo fdi; - fdi.version = qt_mac_hitheme_version; - fdi.state = tds; - int frame_size; - fdi.kind = frame->features & QStyleOptionFrame::Rounded ? kHIThemeFrameTextFieldRound : - kHIThemeFrameTextFieldSquare; - frame_size = qt_mac_aqua_get_metric(EditTextFrameOutset); - if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled)) - fdi.state = kThemeStateInactive; - else if (fdi.state == kThemeStatePressed) - // This pressed state doesn't make sense for a line edit frame. - // And Yosemite agrees with us. Otherwise it starts showing yellow pixels. - fdi.state = kThemeStateActive; - fdi.isFocused = (frame->state & State_HasFocus); - int lw = frame->lineWidth; - if (lw <= 0) - lw = proxy()->pixelMetric(PM_DefaultFrameWidth, frame, w); - { //clear to base color - p->save(); - p->setPen(QPen(baseColor, lw)); - p->setBrush(Qt::NoBrush); - p->drawRect(frame->rect); - p->restore(); - } - const auto frameMargins = QMargins(frame_size, frame_size, frame_size, frame_size); - const CGRect cgRect = frame->rect.marginsRemoved(frameMargins).toCGRect(); - - HIThemeDrawFrame(&cgRect, &fdi, cg, kHIThemeOrientationNormal); + const bool isEnabled = opt->state & State_Enabled; + const bool isReadOnly = opt->state & State_ReadOnly; + const bool isRounded = frame->features & QStyleOptionFrame::Rounded; + const auto cs = d->effectiveAquaSizeConstrain(opt, w, CT_LineEdit); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::TextField, cs); + auto *tf = static_cast<NSTextField *>(d->cocoaControl(cw)); + tf.enabled = isEnabled; + tf.editable = !isReadOnly; + tf.bezeled = YES; + static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel; + tf.frame = opt->rect.toCGRect(); + d->drawNSViewInRect(cw, tf, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) { + Q_UNUSED(ctx); + [tf.cell drawWithFrame:rect inView:tf]; + }); } else { QCommonStyle::drawPrimitive(pe, opt, p, w); } @@ -4498,13 +4506,16 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter break; } case CE_Splitter: - if (opt->rect.width() > 1 && opt->rect.height() > 1){ - HIThemeSplitterDrawInfo sdi; - sdi.version = qt_mac_hitheme_version; - sdi.state = tds; - sdi.adornment = kHIThemeSplitterAdornmentMetal; - CGRect cgRect = opt->rect.toCGRect(); - HIThemeDrawPaneSplitter(&cgRect, &sdi, cg, kHIThemeOrientationNormal); + if (opt->rect.width() > 1 && opt->rect.height() > 1) { + const bool isVertical = !(opt->state & QStyle::State_Horizontal); + // Qt refers to the layout orientation, while Cocoa refers to the divider's. + const auto ct = isVertical ? QMacStylePrivate::SplitView_Horizontal : QMacStylePrivate::SplitView_Vertical; + const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); + auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw)); + sv.frame = opt->rect.toCGRect(); + d->drawNSViewInRect(cw, sv, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) { + [sv drawDividerInRect:rect]; + }); } else { QPen oldPen = p->pen(); p->setPen(opt->palette.dark().color()); diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index cf2609e9ec..00dc8a9b53 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -200,7 +200,10 @@ public: Scroller_Vertical, Slider_Horizontal, Slider_Vertical, - Stepper // QSpinBox buttons + SplitView_Horizontal, + SplitView_Vertical, + Stepper, // QSpinBox buttons + TextField }; typedef QPair<CocoaControlType, QStyleHelper::WidgetSizePolicy> CocoaControl; @@ -270,7 +273,7 @@ public: void setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const; - void drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, DrawRectBlock drawRectBlock = nil) const; + void drawNSViewInRect(CocoaControl widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, __attribute__((noescape)) DrawRectBlock drawRectBlock = nil) const; void resolveCurrentNSView(QWindow *window) const; void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index 078875033f..6add110249 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -990,7 +990,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, TP_DROPDOWNBUTTON); if (theme.isValid()) { - const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1); if (!size.isEmpty()) { mbiw = qRound(size.width()); mbih = qRound(size.height()); @@ -1513,7 +1513,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle if (d->transitionsEnabled() && canAnimate(option)) { - if (control == CC_ScrollBar || control == CC_SpinBox ) { + if (control == CC_ScrollBar || control == CC_SpinBox || control == CC_ComboBox) { QObject *styleObject = option->styleObject; // Can be widget or qquickitem @@ -1643,12 +1643,28 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle } else { if (sub & SC_ComboBoxFrame) { - QStyleOptionButton btn; - btn.QStyleOption::operator=(*option); - btn.rect = option->rect.adjusted(-1, -1, 1, 1); - if (sub & SC_ComboBoxArrow) - btn.features = QStyleOptionButton::HasMenu; - proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget); + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = option->rect; + theme.partId = CP_READONLY; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else if (cmb->state & State_Sunken || cmb->state & State_On) + theme.stateId = CBXS_PRESSED; + else if (cmb->state & State_MouseOver) + theme.stateId = CBXS_HOT; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); + } + if (sub & SC_ComboBoxArrow) { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); + theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); } } } @@ -2123,15 +2139,12 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt #if QT_CONFIG(combobox) case CC_ComboBox: if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - int x = cb->rect.x(), - y = cb->rect.y(), - wi = cb->rect.width(), - he = cb->rect.height(); - int xpos = x; - int margin = cb->frame ? 3 : 0; - int bmarg = cb->frame ? 2 : 0; - int arrowButtonWidth = bmarg + 16; - xpos += wi - arrowButtonWidth; + const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); + const int margin = cb->frame ? 3 : 0; + const int bmarg = cb->frame ? 2 : 0; + const int arrowWidth = qRound(QStyleHelper::dpiScaled(16)); + const int arrowButtonWidth = bmarg + arrowWidth; + const int xpos = x + wi - arrowButtonWidth; switch (subControl) { case SC_ComboBoxFrame: @@ -2141,7 +2154,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt rect.setRect(xpos, y , arrowButtonWidth, he); break; case SC_ComboBoxEditField: - rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin); + rect.setRect(x + margin, y + margin, wi - 2 * margin - arrowWidth, he - 2 * margin); break; case SC_ComboBoxListBoxPopup: rect = cb->rect; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index cf344c8f88..ff27cab98a 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -887,6 +887,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa PROPERTYORIGIN origin = PO_NOTFOUND; GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin); GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize); + borderSize *= additionalDevicePixelRatio; // Clip away border region if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) { @@ -996,7 +997,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa } if (addBorderContentClipping) - painter->setClipRegion(extraClip, Qt::IntersectClip); + painter->setClipRegion(scaleRegion(extraClip, 1.0 / additionalDevicePixelRatio), Qt::IntersectClip); if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) { if (!haveCachedPixmap) @@ -1479,11 +1480,12 @@ case PE_Frame: // GetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize); // Inner white border - p->setPen(QPen(option->palette.base().color(), 1)); - p->drawRect(option->rect.adjusted(1, 1, -2, -2)); + p->setPen(QPen(option->palette.base().color(), 0)); + p->drawRect(QRectF(option->rect).adjusted(QStyleHelper::dpiScaled(0.5), QStyleHelper::dpiScaled(0.5), + QStyleHelper::dpiScaled(-1), QStyleHelper::dpiScaled(-1))); // Outer dark border - p->setPen(QPen(bordercolor, 1)); - p->drawRect(option->rect.adjusted(0, 0, -1, -1)); + p->setPen(QPen(bordercolor, 0)); + p->drawRect(QRectF(option->rect).adjusted(0, 0, QStyleHelper::dpiScaled(-0.5), QStyleHelper::dpiScaled(-0.5))); p->setPen(oldPen); return; } else if (fillType == BT_NONE) { @@ -3511,9 +3513,8 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl case CC_ComboBox: if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height(); - int xpos = x; - xpos += wi - 1 - 16; + const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height(); + const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16)); switch (subControl) { case SC_ComboBoxFrame: @@ -3521,11 +3522,13 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl break; case SC_ComboBoxArrow: - rect = QRect(xpos, y+1, 16, he-2); + rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1)), + qRound(QStyleHelper::dpiScaled(16)), he - qRound(QStyleHelper::dpiScaled(2))); break; case SC_ComboBoxEditField: - rect = QRect(x+2, y+2, wi-3-16, he-4); + rect = QRect(x + qRound(QStyleHelper::dpiScaled(2)), y + qRound(QStyleHelper::dpiScaled(2)), + wi - qRound(QStyleHelper::dpiScaled(3 + 16)), he - qRound(QStyleHelper::dpiScaled(4))); break; case SC_ComboBoxListBoxPopup: |