diff options
Diffstat (limited to 'src/plugins')
30 files changed, 208 insertions, 129 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 15445faca0..d012ede5f9 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -58,7 +58,6 @@ public: private: QImage m_qImage; - CGImageRef m_cgImage; QSize m_requestedSize; }; diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index a90db00d42..cddb960197 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -39,14 +39,11 @@ QT_BEGIN_NAMESPACE QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QPlatformBackingStore(window) - , m_cgImage(0) { } QCocoaBackingStore::~QCocoaBackingStore() { - CGImageRelease(m_cgImage); - m_cgImage = 0; } QPaintDevice *QCocoaBackingStore::paintDevice() @@ -58,9 +55,6 @@ QPaintDevice *QCocoaBackingStore::paintDevice() // either due to a window resize or devicePixelRatio change. QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio; if (m_qImage.size() != effectiveBufferSize) { - CGImageRelease(m_cgImage); - m_cgImage = 0; - QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; m_qImage = QImage(effectiveBufferSize, format); @@ -73,15 +67,6 @@ QPaintDevice *QCocoaBackingStore::paintDevice() void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint &offset) { - // A flush means that qImage has changed. Since CGImages are seen as - // immutable, CoreImage fails to pick up this change for m_cgImage - // (since it usually cached), so we must recreate it. We await doing this - // until one of the views needs it, since, together with calling - // "setNeedsDisplayInRect" instead of "displayRect" we will, in most - // cases, get away with doing this once for every repaint. Also note that - // m_cgImage is only a reference to the data inside m_qImage, it is not a copy. - CGImageRelease(m_cgImage); - m_cgImage = 0; if (!m_qImage.isNull()) { if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle())) [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index ac43ee6d31..a84c0c0f2a 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -630,6 +630,7 @@ QString qt_mac_applicationName() int qt_mac_mainScreenHeight() { + QCocoaAutoReleasePool pool; // The first screen in the screens array is documented // to have the (0,0) origin. NSRect screenFrame = [[[NSScreen screens] firstObject] frame]; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index d3071be636..881b23cd6f 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -33,6 +33,7 @@ #include "qcocoaintegration.h" +#include "qcocoaautoreleasepool.h" #include "qcocoawindow.h" #include "qcocoabackingstore.h" #include "qcocoanativeinterface.h" @@ -136,6 +137,7 @@ void QCocoaScreen::updateGeometry() qreal QCocoaScreen::devicePixelRatio() const { + QCocoaAutoReleasePool pool; NSScreen * screen = osScreen(); return qreal(screen ? [screen backingScaleFactor] : 1.0); } @@ -505,8 +507,6 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const { if (hint == QPlatformIntegration::FontSmoothingGamma) return 2.0; - if (hint == QPlatformIntegration::SynthesizeMouseFromTouchEvents) - return false; return QPlatformIntegration::styleHint(hint); } diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index e6a3ac9c01..fb11efb689 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -217,6 +217,8 @@ QCocoaMenu::QCocoaMenu() : m_menuBar(0), m_containingMenuItem(0) { + QCocoaAutoReleasePool pool; + m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this]; m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"]; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index c68f083a34..5d8082d347 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -145,6 +145,8 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) { + QCocoaAutoReleasePool pool; + QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(menu); Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items()) cocoaMenu->syncMenuItem(item); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 603d5c9910..d6813749a4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -99,6 +99,8 @@ QCocoaMenuItem::QCocoaMenuItem() : QCocoaMenuItem::~QCocoaMenuItem() { + QCocoaAutoReleasePool pool; + if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this) SET_COCOA_MENU_ANCESTOR(m_menu, 0); if (m_merged) { diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index cd885796f5..205a49d25a 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -234,6 +234,7 @@ void QCocoaNativeInterface::registerDraggedTypes(const QStringList &types) void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu) { + QCocoaAutoReleasePool pool; QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu); NSMenu *menu = cocoaPlatformMenu->nsMenu(); [NSApp QT_MANGLE_NAMESPACE(qt_setDockMenu): menu]; diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index 4ef9000d67..65cc9bc38b 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -33,6 +33,7 @@ #include "qcocoasystemsettings.h" +#include "qcocoaautoreleasepool.h" #include "qcocoahelpers.h" #include <QtCore/private/qcore_mac_p.h> @@ -44,6 +45,8 @@ QT_BEGIN_NAMESPACE QColor qt_mac_colorForTheme(ThemeBrush brush) { + QCocoaAutoReleasePool pool; + QCFType<CGColorRef> cgClr = 0; HIThemeBrushCreateCGColor(brush, &cgClr); return qt_mac_toQColor(cgClr); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 5625d19ed7..cfd2eeb837 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -157,7 +157,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; if (!touchDevice) { touchDevice = new QTouchDevice; touchDevice->setType(QTouchDevice::TouchPad); - touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation); QWindowSystemInterface::registerTouchDevice(touchDevice); } } diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 40f0082b9d..992668805f 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -131,16 +131,16 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; self.toolbar = [[[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 100, 44)] autorelease]; self.toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self action:@selector(closeMenu)] autorelease]; UIBarButtonItem *spaceButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:@selector(closeMenu)] autorelease]; UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelMenu)] autorelease]; - [self.toolbar setItems:[NSArray arrayWithObjects:doneButton, spaceButton, cancelButton, nil]]; + UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self action:@selector(closeMenu)] autorelease]; + [self.toolbar setItems:[NSArray arrayWithObjects:cancelButton, spaceButton, doneButton, nil]]; [self setDelegate:self]; [self setDataSource:self]; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index b397b12311..ebd41d482b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1235,6 +1235,11 @@ void QWindowsContext::setAsyncExpose(bool value) d->m_asyncExpose = value; } +QTouchDevice *QWindowsContext::touchDevice() const +{ + return d->m_mouseHandler.touchDevice(); +} + /*! \brief Windows functions for actual windows. diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 7c88ee14ba..870a42946d 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -67,6 +67,7 @@ struct QWindowCreationContext; struct QWindowsContextPrivate; class QPoint; class QKeyEvent; +class QTouchDevice; #ifndef Q_OS_WINCE struct QWindowsUser32DLL @@ -219,6 +220,8 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + QTouchDevice *touchDevice() const; + private: void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w); #ifndef QT_NO_CONTEXTMENU diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 56adae8ffb..287ee4c46e 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -836,7 +836,8 @@ error: static bool addFontToDatabase(const QString &familyName, uchar charSet, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, - int type) + int type, + bool registerAlias) { // the "@family" fonts are just the same as "family". Ignore them. if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_"))) @@ -873,7 +874,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, #endif QString englishName; - if (ttf && localizedName(familyName)) + if (registerAlias && ttf && localizedName(familyName)) englishName = getEnglishName(familyName); QSupportedWritingSystems writingSystems; @@ -942,7 +943,7 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use // anyway - addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type); + addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type, false); // keep on enumerating return 1; @@ -977,7 +978,7 @@ struct PopulateFamiliesContext }; } // namespace -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) { // the "@family" fonts are just the same as "family". Ignore them. const wchar_t *faceNameW = f->elfLogFont.lfFaceName; @@ -987,6 +988,19 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam); if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont) context->seenSystemDefaultFont = true; + + // Register current font's english name as alias + const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + if (ttf && localizedName(faceName)) { + const QString englishName = getEnglishName(faceName); + if (!englishName.isEmpty()) { + QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName); + // Check whether the system default font name is an alias of the current font family name, + // as on Chinese Windows, where the system font "SimSun" is an alias to a font registered under a local name + if (!context->seenSystemDefaultFont && englishName == context->systemDefaultFont) + context->seenSystemDefaultFont = true; + } + } } return 1; // continue } @@ -1344,7 +1358,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, GetTextMetrics(hdc, &textMetrics); addFontToDatabase(familyName, lf.lfCharSet, &textMetrics, &signatures.at(j), - TRUETYPE_FONTTYPE); + TRUETYPE_FONTTYPE, true); SelectObject(hdc, oldobj); DeleteObject(hfont); diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index b8cc28cedc..689e06281f 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -361,7 +361,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd) if (!fo) return false; // This should always match the object. - QWindow *window = qApp->focusWindow(); + QWindow *window = QGuiApplication::focusWindow(); if (!window) return false; qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window; @@ -561,7 +561,7 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) { - QObject *fo = qApp->focusObject(); + QObject *fo = QGuiApplication::focusObject(); if (!fo) return false; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index d9d0e26b80..af7ecd5834 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -227,6 +227,18 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL qCDebug(lcQpaWindows) << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling=" << QWindowsScaling::factor(); + + QTouchDevice *touchDevice = m_context.touchDevice(); + if (touchDevice) { +#ifdef Q_OS_WINCE + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); +#else + if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) { + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); + } +#endif + QWindowSystemInterface::registerTouchDevice(touchDevice); + } } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() @@ -235,9 +247,12 @@ QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() delete m_fontDatabase; } +QWindowsIntegration *QWindowsIntegration::m_instance = Q_NULLPTR; + QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : d(new QWindowsIntegrationPrivate(paramList)) { + m_instance = this; #ifndef QT_NO_CLIPBOARD d->m_clipboard.registerViewer(); #endif @@ -246,6 +261,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : QWindowsIntegration::~QWindowsIntegration() { + m_instance = Q_NULLPTR; } void QWindowsIntegration::initialize() @@ -492,13 +508,6 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co break; case QPlatformIntegration::UseRtlExtensions: return QVariant(d->m_context.useRTLExtensions()); - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: -#ifdef Q_OS_WINCE - // We do not want Qt to synthesize mouse events as Windows also does that. - return false; -#else // Q_OS_WINCE - return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch)); -#endif // !Q_OS_WINCE default: break; } @@ -540,11 +549,6 @@ QPlatformAccessibility *QWindowsIntegration::accessibility() const } #endif -QWindowsIntegration *QWindowsIntegration::instance() -{ - return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration()); -} - unsigned QWindowsIntegration::options() const { return d->m_options; diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 65816b5590..8a2d14f172 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -91,9 +91,9 @@ public: Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; QList<int> possibleKeys(const QKeyEvent *e) const Q_DECL_OVERRIDE; - static QWindowsIntegration *instance(); + static QWindowsIntegration *instance() { return m_instance; } - inline void emitScreenAdded(QPlatformScreen *s) { screenAdded(s); } + inline void emitScreenAdded(QPlatformScreen *s, bool isPrimary = false) { screenAdded(s, isPrimary); } inline void emitDestroyScreen(QPlatformScreen *s) { destroyScreen(s); } unsigned options() const; @@ -104,6 +104,8 @@ public: private: QScopedPointer<QWindowsIntegrationPrivate> d; + + static QWindowsIntegration *m_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index b940dcd62c..b1ced95a71 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -128,7 +128,10 @@ static inline QTouchDevice *createTouchDevice() QTouchDevice *result = new QTouchDevice; result->setType(digitizers & QT_NID_INTEGRATED_TOUCH ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad); - result->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition); + QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition; + if (result->type() == QTouchDevice::TouchPad) + capabilities |= QTouchDevice::MouseEmulation; + result->setCapabilities(capabilities); result->setMaximumTouchPoints(maxTouchPoints); return result; } @@ -150,8 +153,6 @@ QWindowsMouseHandler::QWindowsMouseHandler() : m_leftButtonDown(false), m_previousCaptureWindow(0) { - if (m_touchDevice) - QWindowSystemInterface::registerTouchDevice(m_touchDevice); } Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 059ebf19f6..4ab4ac352e 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -514,7 +514,8 @@ bool QWindowsScreenManager::handleScreenChanges() } else { QWindowsScreen *newScreen = new QWindowsScreen(newData); m_screens.push_back(newScreen); - QWindowsIntegration::instance()->emitScreenAdded(newScreen); + QWindowsIntegration::instance()->emitScreenAdded(newScreen, + newData.flags & QWindowsScreenData::PrimaryScreen); qCDebug(lcQpaWindows) << "New Monitor: " << newData; } // exists } // for new screens. diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index f33e07901a..c42368cc87 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -224,8 +224,6 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) return defaultThemeHint(StartDragVelocity); case QPlatformIntegration::UseRtlExtensions: return false; - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: - return true; case QPlatformIntegration::PasswordMaskCharacter: return defaultThemeHint(PasswordMaskCharacter); case QPlatformIntegration::SetFocusOnTouchRelease: diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp index 891f187238..562b5c154f 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp @@ -100,7 +100,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbEglNativeInterface void *QXcbEglNativeInterfaceHandler::eglDisplay() { - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->defaultConnection()->glIntegration()); return eglIntegration->eglDisplay(); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 3870c104a4..57dcdc8f9c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -80,6 +80,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input") Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices") +Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") #ifdef XCB_USE_XLIB static const char * const xcbConnectionErrors[] = { @@ -143,9 +144,8 @@ QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens, void QXcbConnection::updateScreens() { xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); - int screenNumber = 0; // index of this QScreen in QGuiApplication::screens() int xcbScreenNumber = 0; // screen number in the xcb sense - QSet<QXcbScreen *> activeScreens; + QList<QXcbScreen *> activeScreens; QList<QXcbScreen *> newScreens; QXcbScreen* primaryScreen = NULL; while (it.rem) { @@ -156,6 +156,7 @@ void QXcbConnection::updateScreens() xcb_screen_t *xcbScreen = it.data; QList<QPlatformScreen *> siblings; int outputCount = 0; + int connectedOutputCount = 0; if (has_randr_extension) { xcb_generic_error_t *error = NULL; xcb_randr_get_output_primary_cookie_t primaryCookie = @@ -185,22 +186,18 @@ void QXcbConnection::updateScreens() if (output == NULL) continue; -#ifdef Q_XCB_DEBUG - QString outputName = QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output), - xcb_randr_get_output_info_name_length(output)); -#endif if (output->crtc == XCB_NONE) { -#ifdef Q_XCB_DEBUG - qDebug("Screen output %s is not connected", qPrintable(outputName)); -#endif + qCDebug(lcQpaScreen, "output %s is not connected", qPrintable( + QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output), + xcb_randr_get_output_info_name_length(output)))); continue; } QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen, output); siblings << screen; activeScreens << screen; - ++screenNumber; + ++connectedOutputCount; // There can be multiple outputs per screen, use either // the first or an exact match. An exact match isn't // always available if primary->output is XCB_NONE @@ -209,9 +206,6 @@ void QXcbConnection::updateScreens() if (!primaryScreen || (primary && outputs[i] == primary->output)) { primaryScreen = screen; siblings.prepend(siblings.takeLast()); -#ifdef Q_XCB_DEBUG - qDebug("Primary output is %d: %s", primary->output, qPrintable(outputName)); -#endif } } free(output); @@ -223,16 +217,13 @@ void QXcbConnection::updateScreens() } // If there's no randr extension, or there was some error above, or the screen // doesn't have outputs for some other reason (e.g. on VNC or ssh -X), just assume there is one screen. - if (outputCount == 0) { -#ifdef Q_XCB_DEBUG - qDebug("Found a screen with zero outputs"); -#endif + if (connectedOutputCount == 0) { + qCDebug(lcQpaScreen, "found a screen with zero outputs"); QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen); siblings << screen; activeScreens << screen; if (!primaryScreen) primaryScreen = screen; - ++screenNumber; } foreach (QPlatformScreen* s, siblings) ((QXcbScreen*)s)->setVirtualSiblings(siblings); @@ -240,29 +231,57 @@ void QXcbConnection::updateScreens() ++xcbScreenNumber; } // for each xcb screen - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); - // Now activeScreens is the complete set of screens which are active at this time. - // Delete any existing screens which are not in activeScreens + QXcbIntegration *integration = QXcbIntegration::instance(); + + // Rebuild screen list, ensuring primary screen is always in front, + // both in the QXcbConnection::m_screens list as well as in the + // QGuiApplicationPrivate::screen_list list, which gets updated via + // - screen added: integration->screenAdded() + // - screen removed: integration->destroyScreen + + // Gather screens to delete + QList<QXcbScreen*> screensToDelete; for (int i = m_screens.count() - 1; i >= 0; --i) { if (!activeScreens.contains(m_screens[i])) { - integration->destroyScreen(m_screens.at(i)); - m_screens.removeAt(i); + screensToDelete.append(m_screens.takeAt(i)); } } - // Add any new screens, and make sure the primary screen comes first - // since it is used by QGuiApplication::primaryScreen() + // If there is a new primary screen, add that one first + if (newScreens.contains(primaryScreen)) { + newScreens.removeOne(primaryScreen); + m_screens.prepend(primaryScreen); + qCDebug(lcQpaScreen) << "adding as primary" << primaryScreen; + integration->screenAdded(primaryScreen, true); + } + + // Add the remaining new screens foreach (QXcbScreen* screen, newScreens) { - if (screen == primaryScreen) - m_screens.prepend(screen); - else - m_screens.append(screen); + m_screens.append(screen); + qCDebug(lcQpaScreen) << "adding" << screen; + integration->screenAdded(screen); } - // Now that they are in the right order, emit the added signals for new screens only - foreach (QXcbScreen* screen, m_screens) - if (newScreens.contains(screen)) - integration->screenAdded(screen); + // Delete the old screens, now that the new ones were added + // and we are sure that there is at least one screen available + foreach (QXcbScreen* screen, screensToDelete) { + qCDebug(lcQpaScreen) << "removing" << screen; + integration->destroyScreen(screen); + } + + // Ensure that the primary screen is first in m_screens too + // (in case the assignment of primary was the only change, + // without adding or removing screens) + if (primaryScreen) { + Q_ASSERT(!m_screens.isEmpty()); + if (m_screens.first() != primaryScreen) { + m_screens.removeOne(primaryScreen); + m_screens.prepend(primaryScreen); + } + } + + if (!m_screens.isEmpty()) + qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); } QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) @@ -280,7 +299,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , has_shape_extension(false) , has_randr_extension(false) , has_input_shape(false) - , has_touch_without_mouse_emulation(false) , has_xkb(false) , m_buttons(0) , m_focusWindow(0) @@ -404,7 +422,7 @@ QXcbConnection::~QXcbConnection() delete m_reader; - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); // Delete screens in reverse order to avoid crash in case of multiple screens while (!m_screens.isEmpty()) integration->destroyScreen(m_screens.takeLast()); @@ -794,8 +812,10 @@ void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev) xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev; m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qDebug("xcb: moved mouse to %4d, %4d; button state %X", event->event_x, event->event_y, static_cast<unsigned int>(m_buttons)); +#ifdef Q_XCB_DEBUG + qCDebug(lcQpaXInput, "xcb: moved mouse to %4d, %4d; button state %X", + event->event_x, event->event_y, static_cast<unsigned int>(m_buttons)); +#endif } #ifndef QT_NO_XKB diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 585ff95c19..97c2590708 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -77,6 +77,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQpaXInput) Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputDevices) +Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) class QXcbScreen; class QXcbWindow; @@ -441,7 +442,6 @@ public: bool hasXShape() const { return has_shape_extension; } bool hasXRandr() const { return has_randr_extension; } bool hasInputShape() const { return has_input_shape; } - bool hasTouchWithoutMouseEmulation() const { return has_touch_without_mouse_emulation; } bool hasXKB() const { return has_xkb; } bool supportsThreadedRendering() const { return m_reader->isRunning(); } @@ -611,7 +611,6 @@ private: bool has_shape_extension; bool has_randr_extension; bool has_input_shape; - bool has_touch_without_mouse_emulation; bool has_xkb; Qt::MouseButtons m_buttons; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index e9fb47dabd..d1b3ead11c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -282,14 +282,14 @@ void QXcbConnection::xi2Select(xcb_window_t window) mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; if (!m_touchDevices.isEmpty()) { - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); // If we select for touch events on the master pointer, XInput2 // will not synthesize mouse events. This means Qt must do it, // which is also preferable, since Qt can control better when // to do so. - if (result == Success) - has_touch_without_mouse_emulation = true; + mask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(xDisplay, window, &mask, 1); + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result); } } #endif // XCB_USE_XINPUT22 @@ -424,6 +424,9 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) dev->size.width() > 10000 || dev->size.height() > 10000) dev->size = QSizeF(130, 110); } + if (!isUsingXInput22() || type == QTouchDevice::TouchPad) + caps |= QTouchDevice::MouseEmulation; + if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { dev->qtTouchDevice = new QTouchDevice; dev->qtTouchDevice->setName(QString::fromUtf8(dev->xiDeviceInfo->name)); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 2e9ba0e8c5..258359d20f 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -110,11 +110,15 @@ static bool runningUnderDebugger() #endif } +QXcbIntegration *QXcbIntegration::m_instance = Q_NULLPTR; + QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) : m_services(new QGenericUnixServices) , m_instanceName(0) , m_canGrab(true) { + m_instance = this; + qRegisterMetaType<QXcbWindow*>(); #ifdef XCB_USE_XLIB XInitThreads(); @@ -166,9 +170,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName); for (int i = 0; i < parameters.size() - 1; i += 2) { -#ifdef Q_XCB_DEBUG - qDebug() << "QXcbIntegration: Connecting to additional display: " << parameters.at(i) << parameters.at(i+1); -#endif + qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, display.toLatin1().constData()); } @@ -179,6 +181,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char QXcbIntegration::~QXcbIntegration() { qDeleteAll(m_connections); + m_instance = Q_NULLPTR; } QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const @@ -371,9 +374,6 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const // X11 always has support for windows, but the // window manager could prevent it (e.g. matchbox) return false; - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: - // We do not want Qt to synthesize mouse events if X11 already does it. - return m_connections.at(0)->hasTouchWithoutMouseEmulation(); default: break; } diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 0af9df55aa..4212d53810 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -101,6 +101,9 @@ public: #endif void sync() Q_DECL_OVERRIDE; + + static QXcbIntegration *instance() { return m_instance; } + private: QList<QXcbConnection *> m_connections; @@ -120,6 +123,8 @@ private: mutable QByteArray m_wmClass; const char *m_instanceName; bool m_canGrab; + + static QXcbIntegration *m_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 701ca91b37..6cb238228f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -363,7 +363,7 @@ void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen) void *QXcbNativeInterface::startupId() { - QXcbIntegration* integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration* integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast<void *>(const_cast<char *>(defaultConnection->startupId().constData())); @@ -372,7 +372,7 @@ void *QXcbNativeInterface::startupId() void *QXcbNativeInterface::x11Screen() { - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast<void *>(defaultConnection->primaryScreenNumber()); @@ -381,7 +381,7 @@ void *QXcbNativeInterface::x11Screen() void *QXcbNativeInterface::rootWindow() { - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast<void *>(defaultConnection->rootWindow()); @@ -391,7 +391,7 @@ void *QXcbNativeInterface::rootWindow() void *QXcbNativeInterface::display() { #ifdef XCB_USE_XLIB - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); return defaultConnection->xlib_display(); #else @@ -412,7 +412,7 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) void QXcbNativeInterface::setStartupId(const char *data) { QByteArray startupId(data); - QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) defaultConnection->setStartupId(startupId); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 57a777b682..58a364848a 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -93,25 +93,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, if (dpr_scaling_enabled) m_noFontHinting = true; -#ifdef Q_XCB_DEBUG - qDebug(); - qDebug("Screen output %s of xcb screen %d:", m_outputName.toUtf8().constData(), m_number); - qDebug(" width..........: %lf", m_sizeMillimeters.width()); - qDebug(" height.........: %lf", m_sizeMillimeters.height()); - qDebug(" geometry.......: %d x %d +%d +%d", m_geometry.width(), m_geometry.height(), m_geometry.x(), m_geometry.y()); - qDebug(" virtual width..: %lf", m_virtualSizeMillimeters.width()); - qDebug(" virtual height.: %lf", m_virtualSizeMillimeters.height()); - qDebug(" virtual geom...: %d x %d", m_virtualSize.width(), m_virtualSize.height()); - qDebug(" avail virt geom: %d x %d +%d +%d", m_availableGeometry.width(), m_availableGeometry.height(), m_availableGeometry.x(), m_availableGeometry.y()); - qDebug(" orientation....: %d", m_orientation); - qDebug(" pixel ratio....: %d", m_devicePixelRatio); - qDebug(" depth..........: %d", screen()->root_depth); - qDebug(" white pixel....: %x", screen()->white_pixel); - qDebug(" black pixel....: %x", screen()->black_pixel); - qDebug(" refresh rate...: %d", m_refreshRate); - qDebug(" root ID........: %x", screen()->root); -#endif - QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs( xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL)); @@ -146,10 +127,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, atom(QXcbAtom::UTF8_STRING), 0, 1024), NULL); if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply)); -#ifdef Q_XCB_DEBUG - qDebug(" window manager.: %s", qPrintable(m_windowManagerName)); - qDebug(); -#endif } free(windowManagerReply); @@ -710,4 +687,47 @@ QXcbXSettings *QXcbScreen::xSettings() const return m_xSettings; } +static inline void formatRect(QDebug &debug, const QRect r) +{ + debug << r.width() << 'x' << r.height() + << forcesign << r.x() << r.y() << noforcesign; +} + +static inline void formatSizeF(QDebug &debug, const QSizeF s) +{ + debug << s.width() << 'x' << s.height() << "mm"; +} + +Q_XCB_EXPORT QDebug operator<<(QDebug debug, const QXcbScreen *screen) +{ + const QDebugStateSaver saver(debug); + debug.nospace(); + debug << "QXcbScreen(" << (void *)screen; + if (screen) { + debug << fixed << qSetRealNumberPrecision(1); + debug << ", name=" << screen->name(); + debug << ", geometry="; + formatRect(debug, screen->geometry()); + debug << ", availableGeometry="; + formatRect(debug, screen->availableGeometry()); + debug << ", devicePixelRatio=" << screen->devicePixelRatio(); + debug << ", logicalDpi=" << screen->logicalDpi(); + debug << ", physicalSize="; + formatSizeF(debug, screen->physicalSize()); + // TODO 5.6 if (debug.verbosity() > 2) { + debug << ", screenNumber=" << screen->screenNumber(); + debug << ", virtualSize=" << screen->virtualSize().width() << "x" << screen->virtualSize().height() << " ("; + formatSizeF(debug, screen->virtualSize()); + debug << "), nativeGeometry="; + formatRect(debug, screen->nativeGeometry()); + debug << ", orientation=" << screen->orientation(); + debug << ", depth=" << screen->depth(); + debug << ", refreshRate=" << screen->refreshRate(); + debug << ", root=" << hex << screen->root(); + debug << ", windowManagerName=" << screen->windowManagerName(); + } + debug << ')'; + return debug; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index f327eb31b0..53ad413541 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -50,6 +50,9 @@ QT_BEGIN_NAMESPACE class QXcbConnection; class QXcbCursor; class QXcbXSettings; +#ifndef QT_NO_DEBUG_STREAM +class QDebug; +#endif class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen { @@ -68,6 +71,8 @@ public: int depth() const Q_DECL_OVERRIDE { return m_screen->root_depth; } QImage::Format format() const Q_DECL_OVERRIDE; QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_sizeMillimeters; } + QSize virtualSize() const { return m_virtualSize; } + QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; } QDpi logicalDpi() const Q_DECL_OVERRIDE; qreal devicePixelRatio() const Q_DECL_OVERRIDE; QPlatformCursor *cursor() const Q_DECL_OVERRIDE; @@ -140,6 +145,10 @@ private: QXcbXSettings *m_xSettings; }; +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug, const QXcbScreen *); +#endif + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2253dfecef..222f6c1170 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -462,7 +462,7 @@ void QXcbWindow::create() m_syncValue.hi = 0; m_syncValue.lo = 0; - const QByteArray wmClass = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->wmClass(); + const QByteArray wmClass = QXcbIntegration::instance()->wmClass(); if (!wmClass.isEmpty()) { Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::WM_CLASS), |