diff options
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 31 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiostextresponder.mm | 52 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosviewcontroller.mm | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontengine.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontengine.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsinputcontext.cpp | 19 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsinputcontext.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsmime.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 19 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 6 |
13 files changed, 108 insertions, 57 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 6a4f7ed8ee..ca92103826 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -44,6 +44,8 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window) QCocoaBackingStore::~QCocoaBackingStore() { + if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle())) + [cocoaWindow->m_qtView clearBackingStore:this]; } QPaintDevice *QCocoaBackingStore::paintDevice() diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 05ab8ae2c7..14a61554a3 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -51,8 +51,7 @@ QT_END_NAMESPACE Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); @interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> { - QImage m_backingStore; - qreal m_pixelRatio; + QCocoaBackingStore* m_backingStore; QPoint m_backingStoreOffset; CGImageRef m_maskImage; uchar *m_maskData; @@ -86,6 +85,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)setQCocoaGLContext:(QCocoaGLContext *)context; #endif - (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset; +- (void)clearBackingStore:(QCocoaBackingStore *)backingStore; - (void)setMaskRegion:(const QRegion *)region; - (void)invalidateWindowShadowIfNeeded; - (void)drawRect:(NSRect)dirtyRect; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index edcbd16dca..4db55c1b73 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -134,7 +134,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; { self = [super initWithFrame : NSMakeRect(0,0, 300,300)]; if (self) { - m_pixelRatio = 1.; + m_backingStore = 0; m_maskImage = 0; m_shouldInvalidateWindowShadow = false; m_window = 0; @@ -376,7 +376,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; if (!m_platformWindow->m_inSetGeometry) QWindowSystemInterface::flushWindowSystemEvents(); else - m_backingStore = QImage(); + m_backingStore = 0; } } @@ -481,12 +481,16 @@ QT_WARNING_POP - (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset { - m_backingStore = backingStore->toImage(); - m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio(); - m_backingStoreOffset = offset * m_pixelRatio; - foreach (QRect rect, region.rects()) { + m_backingStore = backingStore; + m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); + foreach (QRect rect, region.rects()) [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; - } +} + +- (void)clearBackingStore:(QCocoaBackingStore *)backingStore +{ + if (backingStore == m_backingStore) + m_backingStore = 0; } - (BOOL) hasMask @@ -549,7 +553,7 @@ QT_WARNING_POP if (m_platformWindow->m_drawContentBorderGradient) NSDrawWindowBackground(dirtyRect); - if (m_backingStore.isNull()) + if (!m_backingStore) return; // Calculate source and target rects. The target rect is the dirtyRect: @@ -557,10 +561,11 @@ QT_WARNING_POP // The backing store source rect will be larger on retina displays. // Scale dirtyRect by the device pixel ratio: - CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio, - dirtyRect.origin.y * m_pixelRatio, - dirtyRect.size.width * m_pixelRatio, - dirtyRect.size.height * m_pixelRatio); + const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio(); + CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio, + dirtyRect.origin.y * devicePixelRatio, + dirtyRect.size.width * devicePixelRatio, + dirtyRect.size.height * devicePixelRatio); NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort]; @@ -586,7 +591,7 @@ QT_WARNING_POP dirtyBackingRect.size.width, dirtyBackingRect.size.height ); - CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore); + CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore->toImage()); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); // Optimization: Copy frame buffer content instead of blending for diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index e2c61e1161..e4917593db 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -344,6 +344,46 @@ // ------------------------------------------------------------------------- +- (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers +{ + QKeyEvent press(QEvent::KeyPress, key, modifiers); + QKeyEvent release(QEvent::KeyRelease, key, modifiers); + [self sendEventToFocusObject:press]; + [self sendEventToFocusObject:release]; +} + +- (void)cut:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_X modifiers:Qt::ControlModifier]; +} + +- (void)copy:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_C modifiers:Qt::ControlModifier]; +} + +- (void)paste:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_V modifiers:Qt::ControlModifier]; +} + +- (void)selectAll:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_A modifiers:Qt::ControlModifier]; +} + +- (void)delete:(id)sender +{ + Q_UNUSED(sender); + [self sendKeyPressRelease:Qt::Key_Delete modifiers:Qt::ControlModifier]; +} + +// ------------------------------------------------------------------------- + - (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties { // As documented, we should not report textWillChange/textDidChange unless the text @@ -560,7 +600,7 @@ if (cursorPos != int(r.location + r.length) || cursorPos != anchorPos) { attrs = QList<QInputMethodEvent::Attribute>(); - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, cursorPos, (cursorPos - anchorPos), 0); + attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, qMin(cursorPos, anchorPos), qAbs(cursorPos - anchorPos), 0); e = QInputMethodEvent(m_markedText, attrs); [self sendEventToFocusObject:e]; } @@ -678,10 +718,7 @@ return; if ([text isEqualToString:@"\n"]) { - QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); - QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier); - [self sendEventToFocusObject:press]; - [self sendEventToFocusObject:release]; + [self sendKeyPressRelease:Qt::Key_Return modifiers:Qt::NoModifier]; if (self.returnKeyType == UIReturnKeyDone || self.returnKeyType == UIReturnKeyGo || self.returnKeyType == UIReturnKeySend || self.returnKeyType == UIReturnKeySearch) @@ -700,10 +737,7 @@ // Since we're posting im events directly to the focus object, we should do the // same for key events. Otherwise they might end up in a different place or out // of sync with im events. - QKeyEvent press(QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier); - QKeyEvent release(QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier); - [self sendEventToFocusObject:press]; - [self sendEventToFocusObject:release]; + [self sendKeyPressRelease:Qt::Key_Backspace modifiers:Qt::NoModifier]; } @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 4ea5fc7de1..be89521c04 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -190,8 +190,9 @@ - (void)setBounds:(CGRect)newBounds { + Q_UNUSED(newBounds); CGRect transformedWindowBounds = [self convertRect:self.window.bounds fromView:self.window]; - [super setBounds:CGRectMake(0, 0, CGRectGetWidth(newBounds), CGRectGetHeight(transformedWindowBounds))]; + [super setBounds:CGRectMake(0, 0, CGRectGetWidth(transformedWindowBounds), CGRectGetHeight(transformedWindowBounds))]; } - (void)setCenter:(CGPoint)newCenter diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 16b9118e81..3685197430 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -181,9 +181,8 @@ void QWindowsFontEngine::getCMap() bool symb = false; if (ttf) { cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p'))); - int size = 0; cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), - cmapTable.size(), &symb, &size); + cmapTable.size(), &symb, &cmapSize); } if (!cmap) { ttf = false; @@ -218,16 +217,16 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa QStringIterator it(str, str + numChars); while (it.hasNext()) { const uint uc = it.next(); - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); + glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); if(!glyphs->glyphs[glyph_pos] && uc < 0x100) - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000); + glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000); ++glyph_pos; } } else if (ttf) { QStringIterator it(str, str + numChars); while (it.hasNext()) { const uint uc = it.next(); - glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); + glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); ++glyph_pos; } } else { @@ -275,6 +274,7 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, hasOutline(0), lw(0), cmap(0), + cmapSize(0), lbearing(SHRT_MIN), rbearing(SHRT_MIN), x_height(-1), @@ -346,11 +346,11 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const #if !defined(Q_OS_WINCE) if (symbol) { - glyph = getTrueTypeGlyphIndex(cmap, ucs4); + glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4); if (glyph == 0 && ucs4 < 0x100) - glyph = getTrueTypeGlyphIndex(cmap, ucs4 + 0xf000); + glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000); } else if (ttf) { - glyph = getTrueTypeGlyphIndex(cmap, ucs4); + glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4); #else if (tm.tmFirstChar > 60000) { glyph = ucs4; diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 6df69c34db..409b44264e 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -146,6 +146,7 @@ private: TEXTMETRIC tm; int lw; const unsigned char *cmap; + int cmapSize; QByteArray cmapTable; mutable qreal lbearing; mutable qreal rbearing; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 485b876fc7..554a6c8b4c 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -199,18 +199,27 @@ void QWindowsInputContext::reset() doneContext(); } -void QWindowsInputContext::setFocusObject(QObject *object) +void QWindowsInputContext::setFocusObject(QObject *) { // ### fixme: On Windows 8.1, it has been observed that the Input context // remains active when this happens resulting in a lock-up. Consecutive // key events still have VK_PROCESSKEY set and are thus ignored. if (m_compositionContext.isComposing) - imeNotifyCancelComposition(m_compositionContext.hwnd); + reset(); + updateEnabled(); +} +void QWindowsInputContext::updateEnabled() +{ + if (!QGuiApplication::focusObject()) + return; const QWindow *window = QGuiApplication::focusWindow(); - if (object && window && window->handle()) { + if (window && window->handle()) { QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window); - if (inputMethodAccepted()) { + const bool accepted = inputMethodAccepted(); + if (QWindowsContext::verbose > 1) + qCDebug(lcQpaInputMethods) << __FUNCTION__ << window << "accepted=" << accepted; + if (accepted) { // Re-enable IME by associating default context saved on first disabling. if (platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) { ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext); @@ -234,6 +243,8 @@ void QWindowsInputContext::setFocusObject(QObject *object) void QWindowsInputContext::update(Qt::InputMethodQueries queries) { + if (queries & Qt::ImEnabled) + updateEnabled(); QPlatformInputContext::update(queries); } diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index 83a39989f6..110986c20c 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -87,6 +87,7 @@ private: void doneContext(); void startContextComposition(); void endContextComposition(); + void updateEnabled(); const DWORD m_WM_MSIME_MOUSE; static HIMC m_defaultContext; diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index f86ab9fee3..622352e987 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -990,12 +990,11 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co { QVector<FORMATETC> formatetcs; if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) { - //add DIBV5 if image has alpha channel + //add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656). QImage image = qvariant_cast<QImage>(mimeData->imageData()); if (!image.isNull() && image.hasAlphaChannel()) formatetcs += setCf(CF_DIBV5); formatetcs += setCf(CF_DIB); - formatetcs += setCf(CF_PNG); // QTBUG-86848, Paste into GIMP queries for PNG. } return formatetcs; } @@ -1024,11 +1023,7 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi const QImage image = qvariant_cast<QImage>(mimeData->imageData()); if (image.isNull()) return false; - // QTBUG-11463, deny CF_DIB support for images with alpha to prevent loss of - // transparency in conversion. - return cf == CF_DIBV5 - || (cf == CF_DIB && !image.hasAlphaChannel()) - || cf == int(CF_PNG); + return cf == CF_DIBV5 || (cf == CF_DIB) || cf == int(CF_PNG); } bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1b5d7b87bc..f9b34334df 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1045,8 +1045,8 @@ void QWindowsWindow::setDropSiteEnabled(bool dropEnabled) RegisterDragDrop(m_data.hwnd, m_dropTarget); CoLockObjectExternal(m_dropTarget, true, true); } else { - m_dropTarget->Release(); CoLockObjectExternal(m_dropTarget, false, true); + m_dropTarget->Release(); RevokeDragDrop(m_data.hwnd); m_dropTarget = 0; } diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 6ca369326b..7a5480a8a5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -967,15 +967,6 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q xXIGenericDeviceEvent *xiEvent = static_cast<xXIGenericDeviceEvent *>(event); xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(xiEvent); -#ifdef XCB_USE_XINPUT22 - // Synthesize mouse events since otherwise there are no mouse events from - // the pen on the XI 2.2+ path. - if (xi2MouseEvents() && eventListener) - eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event)); -#else - Q_UNUSED(eventListener); -#endif - switch (xiEvent->evtype) { case XI_ButtonPress: { Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); @@ -1058,6 +1049,16 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q handled = false; break; } + +#ifdef XCB_USE_XINPUT22 + // Synthesize mouse events since otherwise there are no mouse events from + // the pen on the XI 2.2+ path. + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event)); +#else + Q_UNUSED(eventListener); +#endif + return handled; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index f9a85cdf44..1ff052f2c0 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2208,17 +2208,17 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) switch (ev->evtype) { case XI_ButtonPress: - qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button); + qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time); conn->setButton(button, true); handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); break; case XI_ButtonRelease: - qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button); + qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time); conn->setButton(button, false); handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); break; case XI_Motion: - qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y); + qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time); handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); break; default: |