From 5178773f11cae5f4fcb144a06ee075af62f93a99 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 4 Aug 2016 13:52:59 +0200 Subject: xcb: Add qt.qpa.input.events and guard mouse event logs too Make mouse behave like touch and scrolling does: only do high frequency qCDebugs when the category is enabled. Switch over mouse, touch and scroll event logging to a new sub-category: qt.qpa.input.events. This way qt.qpa.input in itself behaves sanely on xcb, similarly to f.ex. eglfs, giving only the basic, but important info. Change-Id: I8dd588e72ae9d1c66096489fa3c5291f6d318ca0 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.cpp | 12 +++++++---- src/plugins/platforms/xcb/qxcbconnection.h | 1 + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 27 ++++++++++++------------ src/plugins/platforms/xcb/qxcbwindow.cpp | 11 ++++++---- 4 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 29a2cfb57a..c533a2a5f5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -101,6 +101,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input") Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices") +Q_LOGGING_CATEGORY(lcQpaXInputEvents, "qt.qpa.input.events") Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") // this event type was added in libxcb 1.10, @@ -1107,7 +1108,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) // the rest we need to manage ourselves m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); m_buttons |= translateMouseButton(ev->detail); - qCDebug(lcQpaXInput, "legacy mouse press, button %d state %X", ev->detail, static_cast(m_buttons)); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); } case XCB_BUTTON_RELEASE: { @@ -1115,15 +1117,17 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) m_keyboard->updateXKBStateFromCore(ev->state); m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); m_buttons &= ~translateMouseButton(ev->detail); - qCDebug(lcQpaXInput, "legacy mouse release, button %d state %X", ev->detail, static_cast(m_buttons)); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); } case XCB_MOTION_NOTIFY: { xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; m_keyboard->updateXKBStateFromCore(ev->state); m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); - qCDebug(lcQpaXInput, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, - ev->detail, static_cast(m_buttons)); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, + ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 501da1ce7b..e7c3722c2e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -79,6 +79,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQpaXInput) Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputDevices) +Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputEvents) Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) class QXcbVirtualDesktop; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 025dde3dbb..d098a86b88 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -555,8 +555,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) case XI_TouchBegin: case XI_TouchUpdate: case XI_TouchEnd: - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); @@ -613,8 +613,8 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo double value; if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) continue; - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, " valuator %20s value %lf from range %lf -> %lf", atomName(vci->label).constData(), value, vci->min, vci->max ); if (vci->label == atom(QXcbAtom::RelX)) { nx = valuatorNormalized(value, vci); @@ -741,8 +741,8 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo touchPoint.area = QRectF(x - w/2, y - h/2, w, h); touchPoint.normalPosition = QPointF(nx, ny); - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << " area " << touchPoint.area << " pressure " << touchPoint.pressure; QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, dev->touchPoints.values()); if (touchPoint.state == Qt::TouchPointReleased) @@ -874,8 +874,8 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int scrollingDevice.lastScrollPosition.setY(vci->value); } } - if (lcQpaXInput().isDebugEnabled() && lastScrollPosition != scrollingDevice.lastScrollPosition) - qCDebug(lcQpaXInput, "scrolling device %d moved from (%f, %f) to (%f, %f)", scrollingDevice.deviceId, + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled() && lastScrollPosition != scrollingDevice.lastScrollPosition)) + qCDebug(lcQpaXInputEvents, "scrolling device %d moved from (%f, %f) to (%f, %f)", scrollingDevice.deviceId, lastScrollPosition.x(), lastScrollPosition.y(), scrollingDevice.lastScrollPosition.x(), scrollingDevice.lastScrollPosition.y()); @@ -1108,9 +1108,10 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q } // TODO maybe have a hash of tabletData->deviceId to device data so we can // look up the tablet name here, and distinguish multiple tablets - qCDebug(lcQpaXInput, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d", - tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], - ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d", + tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], + ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool); } XFree(data); } @@ -1181,8 +1182,8 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event) } } - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d time %d " + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %d type %d seq %d detail %d time %d " "pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time, fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y), diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index b5cde141f1..247e420f5d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2419,7 +2419,7 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource } const char *sourceName = 0; - if (lcQpaXInput().isDebugEnabled()) { + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) { const QMetaObject *metaObject = qt_getEnumMetaObject(source); const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source))); sourceName = me.valueToKey(source); @@ -2427,17 +2427,20 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource switch (ev->evtype) { case XI_ButtonPress: - qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, true); handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_ButtonRelease: - qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, false); handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_Motion: - qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source); break; default: -- cgit v1.2.3 From cc517d7cd983d9444e9690353ea7ca7ee30740ef Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 15 Aug 2016 13:14:05 +0200 Subject: QWindowsServices::openUrl(): Don't convert URLs with fragments/queries to local files Pass the URL instead. Task-number: QTBUG-55300 Change-Id: I4ce9171db5c1a9e07b17911729b165c115329664 Reviewed-by: Thiago Macieira --- src/plugins/platforms/windows/qwindowsservices.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index ae63ac46ae..1d23a9d9b9 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -51,8 +51,9 @@ enum { debug = 0 }; static inline bool shellExecute(const QUrl &url) { #ifndef Q_OS_WINCE - const QString nativeFilePath = - url.isLocalFile() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded); + const QString nativeFilePath = url.isLocalFile() && !url.hasFragment() && !url.hasQuery() + ? QDir::toNativeSeparators(url.toLocalFile()) + : url.toString(QUrl::FullyEncoded); const quintptr result = reinterpret_cast(ShellExecute(0, 0, reinterpret_cast(nativeFilePath.utf16()), -- cgit v1.2.3 From 2b0e52757c9dedd95ca676e72c7d00adcdffc3dd Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Tue, 16 Aug 2016 16:54:16 +0200 Subject: Disable switchable widget compositing when using XCB in Parallels VM The Parallels 3D hardware acceleration does not seem to play nice with Qt Creator when switching between tabs that have OpenGL Qt Quick Content and those that have just raster widget content. QWidgetBackingstore has the ability to switch how content is flushed depending on if the SwitchableWidgetComposition capability is available. Previously for XCB it was always enabled, but should be disabled when using the GLX integration for the Parallels VM. Change-Id: I42e41456e0873f6780f5d0333dbfaaf8fcce4a5e Task-number: QTCREATORBUG-16742 Reviewed-by: Laszlo Agocs --- .../xcb/gl_integrations/qxcbglintegration.h | 1 + .../gl_integrations/xcb_glx/qxcbglxintegration.cpp | 21 +++++++++++++++++++++ .../gl_integrations/xcb_glx/qxcbglxintegration.h | 1 + src/plugins/platforms/xcb/qxcbintegration.cpp | 3 ++- 4 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h index 74c117582a..e023833826 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h @@ -54,6 +54,7 @@ public: virtual bool initialize(QXcbConnection *connection) = 0; virtual bool supportsThreadedOpenGL() const { return false; } + virtual bool supportsSwitchableWidgetComposition() const { return true; } virtual bool handleXcbEvent(xcb_generic_event_t *event, uint responseType); virtual QXcbWindow *createWindow(QWindow *window) const = 0; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index 55d0ff38b7..d49739159a 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -218,5 +218,26 @@ bool QXcbGlxIntegration::supportsThreadedOpenGL() const return QGLXContext::supportsThreading(); } +bool QXcbGlxIntegration::supportsSwitchableWidgetComposition() const +{ + static bool vendorChecked = false; + static bool isSwitchableWidgetCompositionAvailable = true; + if (!vendorChecked) { + vendorChecked = true; + Display *display = glXGetCurrentDisplay(); +#ifdef XCB_USE_XLIB + if (!display) + display = static_cast(m_connection->xlib_display()); +#endif + const char *glxvendor = glXGetClientString(display, GLX_VENDOR); + if (glxvendor) { + if (!strcmp(glxvendor, "Parallels Inc")) + isSwitchableWidgetCompositionAvailable = false; + } + } + + return isSwitchableWidgetCompositionAvailable; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.h index 4366d07b42..7212fcf3ed 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.h @@ -54,6 +54,7 @@ public: QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; virtual bool supportsThreadedOpenGL() const Q_DECL_OVERRIDE; + virtual bool supportsSwitchableWidgetComposition() const Q_DECL_OVERRIDE; private: QXcbConnection *m_connection; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 94e17a2983..513498ee5f 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -254,7 +254,8 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const case ForeignWindows: return true; case SyncState: return true; case RasterGLSurface: return true; - case SwitchableWidgetComposition: return true; + case SwitchableWidgetComposition: return m_connections.at(0)->glIntegration() + && m_connections.at(0)->glIntegration()->supportsSwitchableWidgetComposition(); default: return QPlatformIntegration::hasCapability(cap); } } -- cgit v1.2.3 From ec7fee968f5f1a842b7d2fe670de1d517ecca308 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 17 Aug 2016 11:45:59 +0200 Subject: Support stretch when using DirectWrite font engine The DirectWrite font we get when converting the GDI font does not respect the stretch we have set, as this is an attribute of the text layout in DirectWrite and not the font description. To compensate for this, we scale advances and glyphs in the engine if the stretch is different from 100%. [ChangeLog][QtGui][Windows] Fixed stretch when combined with either no or vertical hinting preference or a device pixel ratio different from 1. Task-number: QTBUG-54494 Change-Id: Icc06d1457191782d1a281c99da2da3081a82c542 Reviewed-by: Lars Knoll Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsfontenginedirectwrite.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index c5831dd2e1..04a08d892a 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -351,8 +351,9 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn glyphIndices.size(), glyphMetrics.data()); if (SUCCEEDED(hr)) { + qreal stretch = fontDef.stretch / 100.0; for (int i = 0; i < glyphs->numGlyphs; ++i) - glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth); + glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth * stretch); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { for (int i = 0; i < glyphs->numGlyphs; ++i) glyphs->advances[i] = glyphs->advances[i].round(); @@ -509,7 +510,7 @@ bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, - const QTransform &xform) + const QTransform &originalTransform) { UINT16 glyphIndex = t; FLOAT glyphAdvance = 0; @@ -528,6 +529,10 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, glyphRun.bidiLevel = 0; glyphRun.glyphOffsets = &glyphOffset; + QTransform xform = originalTransform; + if (fontDef.stretch != 100) + xform.scale(fontDef.stretch / 100.0, 1.0); + DWRITE_MATRIX transform; transform.dx = subPixelPosition.toReal(); transform.dy = 0; @@ -664,10 +669,15 @@ QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyN glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, - const QTransform &matrix, + const QTransform &originalTransform, GlyphFormat format) { Q_UNUSED(format); + + QTransform matrix = originalTransform; + if (fontDef.stretch != 100) + matrix.scale(fontDef.stretch / 100.0, 1.0); + glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance UINT16 glyphIndex = glyph; -- cgit v1.2.3 From 9b491616f8353be243c5e5e98c864d09a25b99ea Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 15 Jul 2016 11:51:36 -0700 Subject: Cocoa QPA Menus: Propagate enabled state downwards NSMenu has autoenableItems set to true by default, and we keep it this way in Qt. This means that NSMenuItem's enabled property is basically ignored and therefore QCocoaMenuItem::syncModalState() is wrong. What is also wrong, is syncModalState()'s name in both QCocoaMenuItem and QCocoaMenu. Indeed, this function's role should be to ensure that the enabled state is properly propagated down the menu hierarchy, whether the reason is being in the context of a modal dialog or the parent menu having been disabled by the app. Notice that the latter case is specially needed when a menubar menu is explicitly disabled. Therefore, we introduce a separate flag for the parent enabled state in order to avoid polluting the app-set enabled state flag. This is done in both QCocoaMenu and QCocoaMenuItem. In the case of QCocoaMenuItem, these two flags define whether an NSMenuItem is enabled state conjointly, and set from -[QCocoaMenuDelegate validateMenuItem:]. The rest of the logic remains as before. Similar logic is used in QCocoaMenu::isEnabled(). In addition, the presence of the second flag allows us to show disabled submenus in the same fashion native Cocoa applications do. This means, the submenu item itself remains enabled, allowing to show the submenu popup where all its menu items will appear disabled. Bonus change: merged all the bool flags into a bitfield and made the compiler happy about the ivar reordering in QCocoaMenu and QCocoaMenuItem's constructor. Task-number: QTBUG-54698 Task-number: QTBUG-55121 Change-Id: Ie156cb3aa57a519103908ad4605f7b43c57e5aef Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoamenu.h | 9 +++--- src/plugins/platforms/cocoa/qcocoamenu.mm | 37 ++++++++++++++--------- src/plugins/platforms/cocoa/qcocoamenubar.mm | 2 +- src/plugins/platforms/cocoa/qcocoamenuitem.h | 17 ++++++----- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 42 ++++++++++++++++++--------- 5 files changed, 66 insertions(+), 41 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 98b0eb9c54..fed981bb19 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -65,7 +65,7 @@ public: void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE; - void syncModalState(bool modal); + void propagateEnabledState(bool enabled); void setIcon(const QIcon &icon) Q_DECL_OVERRIDE { Q_UNUSED(icon) } @@ -98,9 +98,10 @@ private: NSMenu *m_nativeMenu; NSMenuItem *m_attachedItem; quintptr m_tag; - bool m_enabled; - bool m_visible; - bool m_isOpen; + bool m_enabled:1; + bool m_parentEnabled:1; + bool m_visible:1; + bool m_isOpen:1; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 155abcc7ea..2be6c0335b 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -154,10 +154,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { - if (![menuItem tag]) + QCocoaMenuItem *cocoaItem = reinterpret_cast(menuItem.tag); + if (!cocoaItem) return YES; - QCocoaMenuItem* cocoaItem = reinterpret_cast([menuItem tag]); return cocoaItem->isEnabled(); } @@ -255,6 +255,7 @@ QCocoaMenu::QCocoaMenu() : m_attachedItem(0), m_tag(0), m_enabled(true), + m_parentEnabled(true), m_visible(true), m_isOpen(false) { @@ -330,6 +331,8 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) else if (isOpen() && item->nsItem()) // Someone's adding new items after aboutToShow() was emitted item->menu()->setAttachedItem(item->nsItem()); + item->setParentEnabled(isEnabled()); + if (item->isMerged()) return; @@ -374,6 +377,9 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) if (cocoaItem->menuParent() == this) cocoaItem->setMenuParent(0); + // Ignore any parent enabled state + cocoaItem->setParentEnabled(true); + m_menuItems.removeOne(cocoaItem); if (!cocoaItem->isMerged()) { if (m_nativeMenu != [cocoaItem->nsItem() menu]) { @@ -464,13 +470,17 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) void QCocoaMenu::setEnabled(bool enabled) { + if (m_enabled == enabled) + return; m_enabled = enabled; - syncModalState(!m_enabled); + const bool wasParentEnabled = m_parentEnabled; + propagateEnabledState(m_enabled); + m_parentEnabled = wasParentEnabled; // Reset to the parent value } bool QCocoaMenu::isEnabled() const { - return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled; + return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled && m_parentEnabled; } void QCocoaMenu::setVisible(bool visible) @@ -604,20 +614,19 @@ QList QCocoaMenu::merged() const return result; } -void QCocoaMenu::syncModalState(bool modal) +void QCocoaMenu::propagateEnabledState(bool enabled) { - QMacAutoReleasePool pool; + QMacAutoReleasePool pool; // FIXME Is this still needed for Creator? See 6a0bb4206a2928b83648 - if (!m_enabled) - modal = true; + m_parentEnabled = enabled; + if (!m_enabled && enabled) // Some ancestor was enabled, but this menu is not + return; foreach (QCocoaMenuItem *item, m_menuItems) { - if (item->menu()) { // recurse into submenus - item->menu()->syncModalState(modal); - continue; - } - - item->syncModalState(modal); + if (QCocoaMenu *menu = item->menu()) + menu->propagateEnabledState(enabled); + else + item->setParentEnabled(enabled); } } diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 9b03ea17c4..3523182e6d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -321,7 +321,7 @@ void QCocoaMenuBar::updateMenuBarImmediately() menu->setMenuParent(mb); // force a sync? mb->syncMenu(menu); - menu->syncModalState(disableForModal); + menu->propagateEnabledState(!disableForModal); } QCocoaMenuLoader *loader = getMenuLoader(); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 5f7215596c..fd0d670f7b 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -97,10 +97,10 @@ public: NSMenuItem *sync(); void syncMerged(); - void syncModalState(bool modal); + void setParentEnabled(bool enabled); inline bool isMerged() const { return m_merged; } - inline bool isEnabled() const { return m_enabled; } + inline bool isEnabled() const { return m_enabled && m_parentEnabled; } inline bool isSeparator() const { return m_isSeparator; } QCocoaMenu *menu() const { return m_menu; } @@ -113,20 +113,21 @@ private: NSMenuItem *m_native; NSView *m_itemView; QString m_text; - bool m_textSynced; QIcon m_icon; QPointer m_menu; - bool m_isVisible; - bool m_enabled; - bool m_isSeparator; QFont m_font; MenuRole m_role; MenuRole m_detectedRole; QKeySequence m_shortcut; - bool m_checked; - bool m_merged; quintptr m_tag; int m_iconSize; + bool m_textSynced:1; + bool m_isVisible:1; + bool m_enabled:1; + bool m_parentEnabled:1; + bool m_isSeparator:1; + bool m_checked:1; + bool m_merged:1; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 49f3da48c2..2d4073956a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -88,16 +88,17 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) QCocoaMenuItem::QCocoaMenuItem() : m_native(NULL), m_itemView(nil), - m_textSynced(false), m_menu(NULL), + m_role(NoRole), + m_tag(0), + m_iconSize(16), + m_textSynced(false), m_isVisible(true), m_enabled(true), + m_parentEnabled(true), m_isSeparator(false), - m_role(NoRole), m_checked(false), - m_merged(false), - m_tag(0), - m_iconSize(16) + m_merged(false) { } @@ -133,15 +134,23 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) if (menu == m_menu) return; - if (m_menu) { - if (m_menu->menuParent() == this) - m_menu->setMenuParent(0); + if (m_menu && m_menu->menuParent() == this) { + m_menu->setMenuParent(0); + // Free the menu from its parent's influence + m_menu->propagateEnabledState(true); + if (m_native && m_menu->attachedItem() == m_native) + m_menu->setAttachedItem(nil); } QMacAutoReleasePool pool; m_menu = static_cast(menu); if (m_menu) { + if (m_native) { + // Skip automatic menu item validation + m_native.action = nil; + } m_menu->setMenuParent(this); + m_menu->propagateEnabledState(isEnabled()); } else { // we previously had a menu, but no longer // clear out our item so the nexy sync() call builds a new one @@ -184,7 +193,11 @@ void QCocoaMenuItem::setChecked(bool isChecked) void QCocoaMenuItem::setEnabled(bool enabled) { - m_enabled = enabled; + if (m_enabled != enabled) { + m_enabled = enabled; + if (m_menu) + m_menu->propagateEnabledState(isEnabled()); + } } void QCocoaMenuItem::setNativeContents(WId item) @@ -392,12 +405,13 @@ void QCocoaMenuItem::syncMerged() [m_native setHidden: !m_isVisible]; } -void QCocoaMenuItem::syncModalState(bool modal) +void QCocoaMenuItem::setParentEnabled(bool enabled) { - if (modal) - [m_native setEnabled:NO]; - else - [m_native setEnabled:YES]; + if (m_parentEnabled != enabled) { + m_parentEnabled = enabled; + if (m_menu) + m_menu->propagateEnabledState(isEnabled()); + } } QPlatformMenuItem::MenuRole QCocoaMenuItem::effectiveRole() const -- cgit v1.2.3 From b13ff07f1dd25414e507aebd2a7d6d55bc93e6cd Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 16 Aug 2016 14:03:53 -0700 Subject: QCocoaInputContext: Fix wrong memory release As per Core Foundation ownership conventions, we should release 'source', which is a copy, and not 'langRef', which is a reference. This has shown to lead to crashes in some occasions. Change-Id: I2e59b8d62aac13bc60dc013c1ea621850132c719 Task-number: QTBUG-48772 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoainputcontext.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index 7d01826ffe..93b1153cf9 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -131,8 +131,8 @@ void QCocoaInputContext::updateLocale() m_locale = locale; emitLocaleChanged(); } - CFRelease(langRef); } + CFRelease(source); } QT_END_NAMESPACE -- cgit v1.2.3 From 0f6ace8118c72781e6c4c68c3dc98a2937fedf35 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Aug 2016 14:22:46 +0200 Subject: winrt: Fix crash when managing multiple top-level windows When a window gets removed, the active focus window needs to be set to 0 instead of the the current window. Otherwise QGuiApplicationPrivate::focus_window is set to an invalid pointer and crashes when dereferenced. Change-Id: I258b95e447de4cbfb7f19955079c2545a738e03f Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index c1118cd0b8..703627a6c5 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -782,7 +782,7 @@ void QWinRTScreen::removeWindow(QWindow *window) if (!d->visibleWindows.removeAll(window)) return; if (wasTopWindow) - QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); + QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); #if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) -- cgit v1.2.3 From a75cfa60d7f15513218f7719410b09f708a2940e Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Aug 2016 15:43:11 +0200 Subject: winrt: Fix crashes for visible window management First, offscreen windows/surfaces should not be tracked in the visible window list. Secondly when destroying a window, it is not guaranteed that it had been removed first, hence enforce it to guarantee that the visibleWindows list stays correct and does not hold invalid weak pointers to non existing windows. Change-Id: I7027ecd010b8bcb3d05e3f5d460662e883e42e50 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 4 +++- src/plugins/platforms/winrt/qwinrtwindow.cpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 703627a6c5..77185f1bb9 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -760,7 +760,7 @@ void QWinRTScreen::addWindow(QWindow *window) { Q_D(QWinRTScreen); qCDebug(lcQpaWindows) << __FUNCTION__ << window; - if (window == topWindow()) + if (window == topWindow() || window->surfaceClass() == QSurface::Offscreen) return; d->visibleWindows.prepend(window); @@ -804,6 +804,8 @@ void QWinRTScreen::lower(QWindow *window) const bool wasTopWindow = window == topWindow(); if (wasTopWindow && d->visibleWindows.size() == 1) return; + if (window->surfaceClass() == QSurface::Offscreen) + return; d->visibleWindows.removeAll(window); d->visibleWindows.append(window); if (wasTopWindow) diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 3bd0cd3ad7..cc50aaa8d1 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -189,6 +189,8 @@ QWinRTWindow::~QWinRTWindow() }); RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down"); + d->screen->removeWindow(window()); + if (!d->surface) return; -- cgit v1.2.3 From 4531ae8d699d06197d8485702fc48214c5e4dda8 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Aug 2016 15:40:59 +0200 Subject: winrt: only update window title for top level widgets Previously we always updated the window title, independently whether the window was visible / the toplevel one. This can also cause troubles when setting the title during initialization. Change-Id: I02ec0f0e385fa490f641ce83a6cb27717a31620f Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 8 ++------ src/plugins/platforms/winrt/qwinrtscreen.h | 2 +- src/plugins/platforms/winrt/qwinrtwindow.cpp | 4 +++- 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 77185f1bb9..dd2ebee3d5 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -764,6 +764,7 @@ void QWinRTScreen::addWindow(QWindow *window) return; d->visibleWindows.prepend(window); + updateWindowTitle(window->title()); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); @@ -813,15 +814,10 @@ void QWinRTScreen::lower(QWindow *window) handleExpose(); } -void QWinRTScreen::updateWindowTitle() +void QWinRTScreen::updateWindowTitle(const QString &title) { Q_D(QWinRTScreen); - QWindow *window = topWindow(); - if (!window) - return; - - const QString title = window->title(); HStringReference titleRef(reinterpret_cast(title.utf16()), title.length()); HRESULT hr = d->view->put_Title(titleRef.Get()); RETURN_VOID_IF_FAILED("Unable to set window title"); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index a5c1d24d51..ff1ff32ce9 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -106,7 +106,7 @@ public: void raise(QWindow *window); void lower(QWindow *window); - void updateWindowTitle(); + void updateWindowTitle(const QString &title); ABI::Windows::UI::Core::ICoreWindow *coreWindow() const; ABI::Windows::UI::Xaml::IDependencyObject *canvas() const; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index cc50aaa8d1..be55ded7cd 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -282,7 +282,9 @@ void QWinRTWindow::setWindowTitle(const QString &title) { Q_D(QWinRTWindow); d->windowTitle = title; - d->screen->updateWindowTitle(); + + if (d->screen->topWindow() == window()) + d->screen->updateWindowTitle(title); } void QWinRTWindow::raise() -- cgit v1.2.3 From 916a8c44c4a9ba639e89660226d14d51ed44feaa Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 13 Aug 2016 17:54:46 +0200 Subject: Revert "Cocoa: make dialogs emit the "selected" signals" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit dfa8854cf7e00705e0122cf7022ff1ea4f8e5a74 and removes all "selected" signal emissions from the Cocoa platform dialogs. Even though it fixed the new QML dialogs that were relying on the "selected" signals, it lead to duplicate signals with QColorDialog, QFileDialog, and QFontDialog. We'll fix the new QML dialogs to not rely on the selected signals, but handle it on accept the same way than QtWidgets and QtQuick Dialogs do, so there is no need to repeat the signals in all platform plugins. Task-number: QTBUG-55299 Change-Id: I35e08cee92a4454544497b027ed10abad6c26673 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm | 2 -- src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 9 --------- src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm | 1 - 3 files changed, 12 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 85468009f3..0319d4ca6d 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -177,8 +177,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); { Q_UNUSED(notification); [self updateQtColor]; - if (mHelper) - emit mHelper->colorSelected(mQtColor); } - (void)windowWillClose:(NSNotification *)notification diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 475e6c7afb..4eb35f5495 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -582,15 +582,6 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted) QCocoaMenuBar::resetKnownMenuItemsToQt(); if (accepted) { emit accept(); - - QString filter = selectedNameFilter(); - if (filter.isEmpty()) - emit filterSelected(filter); - - QList files = selectedFiles(); - emit filesSelected(files); - if (files.count() == 1) - emit fileSelected(files.first()); } else { emit reject(); } diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index dfda22d376..dc7dfb788f 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -365,7 +365,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); emit mHelper->reject(); } else { emit mHelper->accept(); - emit mHelper->fontSelected(mHelper->currentFont()); } } } -- cgit v1.2.3 From b8c1efcb887a2aa313fd843aa16a5be84d4189e6 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 17 Aug 2016 13:03:59 +0200 Subject: DirectWrite: Fix calculating bounding box of glyphs We don't support vertical text layouts in Qt, so the vertical advance should always be 0 (like it is in other engines). Since we were setting this, we would calculate the bounding box of strings in the DirectWrite engine as if the layouts were diagonal, adding up both the horizontal and vertical advances. [ChangeLog][QtGui][Windows] Fixed height of text bounding box when using no or vertical hinting preference, or when the device pixel ratio is different from 1. Task-number: QTBUG-51024 Change-Id: I329917eb8da71fdfdffe9651ca8f0f48d26b6a60 Reviewed-by: Lars Knoll Reviewed-by: Friedemann Kleint Reviewed-by: Konstantin Ritt --- src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 04a08d892a..f2758f6d90 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -436,7 +436,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g) width, height, advanceWidth, - advanceHeight); + 0); } else { qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__); } -- cgit v1.2.3 From d13d81eb01a84bb8fd599ceac5ffcf19fca2f91e Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 8 Jun 2015 14:35:22 +0300 Subject: Fix QWidget::setWindowRole() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce QXcbWindowFunctions::setWmWindowRole() and call it either from the implementation of QWidget::setWindowRole() or after the creation of the corresponding QWidgetWindow. Change-Id: I143450f4673dd707bb491c1d0f0e8b61d564283d Task-number: QTBUG-45484 Reviewed-by: Laszlo Agocs Reviewed-by: Ivan Čukić --- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 3 +++ src/plugins/platforms/xcb/qxcbwindow.cpp | 21 +++++++++++++++++++++ src/plugins/platforms/xcb/qxcbwindow.h | 2 ++ 3 files changed, 26 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 96239a0f20..09e7ecf3a3 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -350,6 +350,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) return QFunctionPointer(QXcbWindowFunctions::SetWmWindowType(QXcbWindow::setWmWindowTypeStatic)); + if (function == QXcbWindowFunctions::setWmWindowRoleIdentifier()) + return QFunctionPointer(QXcbWindowFunctions::SetWmWindowRole(QXcbWindow::setWmWindowRoleStatic)); + if (function == QXcbWindowFunctions::setWmWindowIconTextIdentifier()) return QFunctionPointer(QXcbWindowFunctions::SetWmWindowIconText(QXcbWindow::setWindowIconTextStatic)); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 247e420f5d..da5020168f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -284,6 +284,7 @@ static QWindow *childWindowAt(QWindow *win, const QPoint &p) } static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; +static const char *wm_window_role_property_id = "_q_xcb_wm_window_role"; QXcbWindow::QXcbWindow(QWindow *window) : QPlatformWindow(window) @@ -610,6 +611,11 @@ void QXcbWindow::create() setOpacity(opacity); if (window()->isTopLevel()) setWindowIcon(window()->icon()); + + if (window()->dynamicPropertyNames().contains(wm_window_role_property_id)) { + QByteArray wmWindowRole = window()->property(wm_window_role_property_id).toByteArray(); + setWmWindowRole(wmWindowRole); + } } QXcbWindow::~QXcbWindow() @@ -1733,6 +1739,14 @@ void QXcbWindow::setWindowIconTextStatic(QWindow *window, const QString &text) static_cast(window->handle())->setWindowIconText(text); } +void QXcbWindow::setWmWindowRoleStatic(QWindow *window, const QByteArray &role) +{ + if (window->handle()) + static_cast(window->handle())->setWmWindowRole(role); + else + window->setProperty(wm_window_role_property_id, role); +} + uint QXcbWindow::visualIdStatic(QWindow *window) { if (window && window->handle()) @@ -1898,6 +1912,13 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W xcb_flush(xcb_connection()); } +void QXcbWindow::setWmWindowRole(const QByteArray &role) +{ + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + atom(QXcbAtom::WM_WINDOW_ROLE), XCB_ATOM_STRING, 8, + role.size(), role.constData())); +} + void QXcbWindow::setParentRelativeBackPixmapStatic(QWindow *window) { if (window->handle()) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 4673f3dd33..b8bcf4428a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -145,10 +145,12 @@ public: void updateNetWmUserTime(xcb_timestamp_t timestamp); static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); + static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); static uint visualIdStatic(QWindow *window); QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags); + void setWmWindowRole(const QByteArray &role); static void setWindowIconTextStatic(QWindow *window, const QString &text); -- cgit v1.2.3 From 4d07042c70c0d2f60ef35760a8211362de58a879 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 23 Aug 2016 10:37:54 +0200 Subject: winrt: Fix crash when clearing mimedata Some autotests clear the clipboard by invoking setMimeData() with a null QMimeData argument. Change-Id: I4a9d3dfd41b2c52964e272fc1362162f47fd8cda Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtclipboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index 4e71490902..c385018239 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -143,7 +143,7 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) return; #ifndef Q_OS_WINPHONE - const QString text = data->text(); + const QString text = data ? data->text() : QString(); HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() { HRESULT hr; ComPtr package; -- cgit v1.2.3 From acfc1cc362ab8e9a40b49194275a1335b0d54788 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Tue, 23 Aug 2016 11:50:35 -0700 Subject: Fix warning: 'UITextInputTextFontKey' is deprecated first deprecated in iOS 8.0 - Use NSFontAttributeName instead Change-Id: I763efc498644ac234a712ebcefd07111b4444c98 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostextresponder.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 0cf505930f..4bef968de1 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -908,7 +908,7 @@ UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()]; if (!uifont) return [NSDictionary dictionary]; - return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey]; + return [NSDictionary dictionaryWithObject:uifont forKey:NSFontAttributeName]; } - (NSDictionary *)markedTextStyle -- cgit v1.2.3 From e41263b61af6bcd16ead9ba50466958a813879ac Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 24 Aug 2016 12:35:50 +0200 Subject: fix build with qt-xcb and another installed qt in a system location amends fc1092cf, necessary because of (the earlier) a28364bc1. Change-Id: I5c86bcb27854994e59228fd205c799396464554d Reviewed-by: Jake Petroules --- .../platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri | 2 ++ src/plugins/platforms/xcb/xcb_qpa_lib.pro | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri index c2d3849d8e..68cb91ff3d 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri @@ -3,6 +3,8 @@ QT += core-private gui-private platformsupport-private xcb_qpa_lib-private INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD/../ +load(qt_build_paths) + # needed by Xcursor ... contains(QT_CONFIG, xcb-xlib) { DEFINES += XCB_USE_XLIB diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index db9ea32cd8..9ca8872cb2 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -38,6 +38,8 @@ HEADERS = \ qxcbxsettings.h \ qxcbsystemtraytracker.h +load(qt_build_paths) + DEFINES += QT_BUILD_XCB_PLUGIN # needed by Xcursor ... contains(QT_CONFIG, xcb-xlib) { -- cgit v1.2.3 From 5f895fe0e212428bae76c65f3b6eaa8a036c7672 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 25 Aug 2016 09:59:06 +0200 Subject: winrt: Check validity of options shared pointer QErrorMessage autotests managed to create a scenario where the options are not initialized yet, causing a crash later on. Change-Id: Iabad6f181f2bfdc81a9c73f0e67c8ba70753fec6 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp index bad15126d4..42fe030b23 100644 --- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp @@ -108,6 +108,9 @@ bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModa Q_D(QWinRTMessageDialogHelper); QSharedPointer options = this->options(); + if (!options.data()) + return false; + const QString informativeText = options->informativeText(); const QString title = options->windowTitle(); const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText); -- cgit v1.2.3 From ea4aa5b7225c4fcd2f9d556d3bfda61d92d6b0a1 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 25 Aug 2016 15:03:41 +0200 Subject: winrt: store mimedata in clipboard In addition to setting the clipboard, we also need to store the mimedata being passed. Otherwise requesting the mimedata returns a different object, causing comparisons to fail. Change-Id: I2ffea76e78be091cb98426e387619ac6788ea270 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtclipboard.cpp | 18 ++++++++++++++++-- src/plugins/platforms/winrt/qwinrtclipboard.h | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index c385018239..1fb90a8fb7 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -56,6 +56,7 @@ typedef IEventHandler ContentChangedHandler; QT_BEGIN_NAMESPACE QWinRTClipboard::QWinRTClipboard() + : m_mimeData(Q_NULLPTR) { #ifndef Q_OS_WINPHONE QEventDispatcherWinRT::runOnXamlThread([this]() { @@ -100,9 +101,16 @@ QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode) const wchar_t *textStr = result.GetRawBuffer(&size); QString text = QString::fromWCharArray(textStr, size); text.replace(QStringLiteral("\r\n"), QStringLiteral("\n")); - m_mimeData.setText(text); - return &m_mimeData; + if (m_mimeData) { + if (m_mimeData->text() == text) + return m_mimeData; + delete m_mimeData; + } + m_mimeData = new QMimeData(); + m_mimeData->setText(text); + + return m_mimeData; #else // Q_OS_WINPHONE return QPlatformClipboard::mimeData(mode); #endif // Q_OS_WINPHONE @@ -143,6 +151,12 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) return; #ifndef Q_OS_WINPHONE + const bool newData = !m_mimeData || m_mimeData != data; + if (newData) { + if (m_mimeData) + delete m_mimeData; + m_mimeData = data; + } const QString text = data ? data->text() : QString(); HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() { HRESULT hr; diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.h b/src/plugins/platforms/winrt/qwinrtclipboard.h index 1fb10bdfc0..fc3d50ce59 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.h +++ b/src/plugins/platforms/winrt/qwinrtclipboard.h @@ -70,7 +70,7 @@ private: #ifndef Q_OS_WINPHONE Microsoft::WRL::ComPtr m_nativeClipBoard; #endif - QMimeData m_mimeData; + QMimeData *m_mimeData; }; QT_END_NAMESPACE -- cgit v1.2.3 From c0a513d55fff9c3bfe4159bb4800a5050f766957 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 25 Aug 2016 15:05:56 +0200 Subject: winrt: avoid duplicate signal emit emitChanged() will be invoked when the system notifies the application about a clipboard change. Hence, there is no need to call it previously and cause two signals on the same change to be emitted. Change-Id: I99605c9a71054e0610006dbeaaa90c5fb2f46755 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtclipboard.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index 1fb90a8fb7..14443f380c 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -175,7 +175,6 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) return S_OK; }); RETURN_VOID_IF_FAILED("Could not set clipboard text."); - emitChanged(mode); #else // Q_OS_WINPHONE QPlatformClipboard::setMimeData(data, mode); #endif // Q_OS_WINPHONE -- cgit v1.2.3