summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp15
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h1
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm29
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm12
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp6
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp17
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h2
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp3
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglwindow.cpp1
-rw-r--r--src/plugins/platforms/platforms.pro4
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxrootwindow.cpp31
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp16
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp68
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h3
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp116
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h13
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp43
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp4
33 files changed, 307 insertions, 152 deletions
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
index 4d741807d0..9d6d4003f7 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
@@ -46,6 +46,8 @@
#include <QtCore/qdebug.h>
#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/private/qopenglcontext_p.h>
+
QT_BEGIN_NAMESPACE
QAndroidOpenGLContext::QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
@@ -75,4 +77,17 @@ void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
}
}
+bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ bool ret = QEglFSContext::makeCurrent(surface);
+
+ const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ if (rendererString != 0 && qstrncmp(rendererString, "Android Emulator", 16) == 0) {
+ QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
+ ctx_d->workaround_missingPrecisionQualifiers = true;
+ }
+
+ return ret;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
index c4c5a430ad..c419ae8392 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
@@ -58,6 +58,7 @@ public:
EGLenum eglApi = EGL_OPENGL_ES_API);
void swapBuffers(QPlatformSurface *surface);
+ bool makeCurrent(QPlatformSurface *surface);
private:
const QAndroidPlatformIntegration *m_platformIntegration;
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index b1a2231ff5..2eac8d248c 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -69,7 +69,6 @@ void QAndroidOpenGLPlatformWindow::invalidateSurface()
{
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
QWindowSystemInterface::flushWindowSystemEvents();
- QEglFSWindow::invalidateSurface();
m_window = 0;
m_surface = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 2ac9a5dac9..9a661ffe5a 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -594,6 +594,7 @@ void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
if (info.session) {
[NSApp endModalSession:info.session];
info.session = 0;
+ [(NSWindow*) info.nswindow release];
}
}
currentModalSessionCached = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 7224ee2ff8..59fda96dff 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -84,6 +84,8 @@ public:
inline NSMenuItem *nsMenuItem() const
{ return m_nativeItem; }
+ inline bool isVisible() const { return m_visible; }
+
virtual QPlatformMenuItem *menuItemAt(int position) const;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const;
@@ -100,6 +102,7 @@ private:
NSMenuItem *m_nativeItem;
NSObject *m_delegate;
bool m_enabled;
+ bool m_visible;
quintptr m_tag;
QCocoaMenuBar *m_menuBar;
};
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index bd406ee176..f9e033d21b 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -216,6 +216,7 @@ QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
m_enabled(true),
+ m_visible(true),
m_tag(0),
m_menuBar(0)
{
@@ -421,6 +422,7 @@ void QCocoaMenu::setEnabled(bool enabled)
void QCocoaMenu::setVisible(bool visible)
{
[m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];
+ m_visible = visible;
}
void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item)
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 8d1ca88b8e..ddfa9fff96 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -149,15 +149,17 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items())
cocoaMenu->syncMenuItem(item);
- // If the NSMenu has no visble items, or only separators, we should hide it
- // on the menubar. This can happen after syncing the menu items since they
- // can be moved to other menus.
BOOL shouldHide = YES;
- for (NSMenuItem *item in [cocoaMenu->nsMenu() itemArray])
- if (![item isSeparatorItem] && ![item isHidden]) {
- shouldHide = NO;
- break;
- }
+ if (cocoaMenu->isVisible()) {
+ // If the NSMenu has no visble items, or only separators, we should hide it
+ // on the menubar. This can happen after syncing the menu items since they
+ // can be moved to other menus.
+ for (NSMenuItem *item in [cocoaMenu->nsMenu() itemArray])
+ if (![item isSeparatorItem] && ![item isHidden]) {
+ shouldHide = NO;
+ break;
+ }
+ }
[cocoaMenu->nsMenuItem() setHidden:shouldHide];
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 057eb7e144..86f12e0e5f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -267,7 +267,6 @@ void QCocoaWindow::setGeometry(const QRect &rect)
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::setGeometry" << this << rect;
#endif
- QPlatformWindow::setGeometry(rect);
setCocoaGeometry(rect);
}
@@ -275,8 +274,10 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
{
QCocoaAutoReleasePool pool;
- if (m_contentViewIsEmbedded)
+ if (m_contentViewIsEmbedded) {
+ QPlatformWindow::setGeometry(rect);
return;
+ }
if (m_nsWindow) {
NSRect bounds = qt_mac_flipRect(rect, window());
@@ -284,6 +285,8 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
} else {
[m_contentView setFrame : NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
}
+
+ // will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
}
void QCocoaWindow::setVisible(bool visible)
@@ -420,11 +423,13 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
if (type == Qt::ToolTip)
windowLevel = NSScreenSaverWindowLevel;
- // A window should be in at least the same level as its parent.
- const QWindow * const transientParent = window()->transientParent();
- const QCocoaWindow * const transientParentWindow = transientParent ? static_cast<QCocoaWindow *>(transientParent->handle()) : 0;
- if (transientParentWindow)
- windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel);
+ // Any "special" window should be in at least the same level as its parent.
+ if (type != Qt::Window) {
+ const QWindow * const transientParent = window()->transientParent();
+ const QCocoaWindow * const transientParentWindow = transientParent ? static_cast<QCocoaWindow *>(transientParent->handle()) : 0;
+ if (transientParentWindow)
+ windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel);
+ }
return windowLevel;
}
@@ -481,6 +486,9 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
[m_nsWindow setStyleMask:styleMask];
[m_nsWindow setLevel:level];
setWindowShadow(flags);
+ if (!(styleMask & NSBorderlessWindowMask)) {
+ setWindowTitle(window()->title());
+ }
}
m_windowFlags = flags;
@@ -999,7 +1007,12 @@ qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- return qreal([[m_contentView window] backingScaleFactor]);
+ NSWindow* window = [m_contentView window];
+ if (window) {
+ return qreal([window backingScaleFactor]);
+ } else {
+ return 1.0;
+ }
} else
#endif
{
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 66a1b95ad8..4505f8b8cf 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -285,6 +285,10 @@ static QTouchDevice *touchDevice = 0;
Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
Qt::WindowMinimized : Qt::WindowNoState;
[self notifyWindowStateChanged:newState];
+ // NSWindowDidOrderOnScreenAndFinishAnimatingNotification is private API, and not
+ // emitted in 10.6, so we bring back the old behavior for that case alone.
+ if (newState == Qt::WindowNoState && QSysInfo::QSysInfo::MacintoshVersion == QSysInfo::MV_10_6)
+ m_platformWindow->exposeWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
@@ -872,13 +876,13 @@ static QTouchDevice *touchDevice = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) {
NSEventPhase phase = [theEvent phase];
- if (phase == NSEventPhaseBegan) {
+ if (phase == NSEventPhaseBegan || phase == NSEventPhaseNone) {
currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
}
QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers);
- if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
+ if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled || phase == NSEventPhaseNone) {
currentWheelModifiers = Qt::NoModifier;
}
} else
@@ -967,7 +971,7 @@ static QTouchDevice *touchDevice = 0;
if (m_sendKeyEvent && m_composingText.isEmpty())
QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers,
- nativeScanCode, nativeVirtualKey, nativeModifiers, text);
+ nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]);
m_sendKeyEvent = false;
}
@@ -1036,7 +1040,7 @@ static QTouchDevice *touchDevice = 0;
timestamp,
(lastKnownModifiers & mac_mask) ? QEvent::KeyRelease : QEvent::KeyPress,
modifier_key_symbols[i].qt_code,
- qmodifiers);
+ qmodifiers ^ [QNSView convertKeyModifiers:mac_mask]);
}
}
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
index 1898cde886..e09154bb59 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -79,6 +79,9 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
makeCurrent();
+ QRectF sr = window->screen()->geometry();
+ glViewport(0, 0, sr.width(), sr.height());
+
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglBackingStore::flush %p", window);
#endif
@@ -120,7 +123,6 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
};
QRectF r = window->geometry();
- QRectF sr = window->screen()->geometry();
GLfloat x1 = (r.left() / sr.width()) * 2 - 1;
GLfloat x2 = (r.right() / sr.width()) * 2 - 1;
@@ -192,8 +194,6 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPo
void QEglFSBackingStore::makeCurrent()
{
- // needed to prevent QOpenGLContext::makeCurrent() from failing
- window()->setSurfaceType(QSurface::OpenGLSurface);
(static_cast<QEglFSWindow *>(window()->handle()))->create();
m_context->makeCurrent(window());
}
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 98c54e0ee0..28ce8c8a33 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -53,12 +53,12 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
: QPlatformWindow(w)
, m_surface(0)
, m_window(0)
+ , has_window(false)
{
- static int serialNo = 0;
- m_winid = ++serialNo;
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_winid));
+ qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_window));
#endif
+ w->setSurfaceType(QSurface::OpenGLSurface);
}
QEglFSWindow::~QEglFSWindow()
@@ -68,7 +68,7 @@ QEglFSWindow::~QEglFSWindow()
void QEglFSWindow::create()
{
- if (m_window)
+ if (has_window)
return;
setWindowState(Qt::WindowFullScreen);
@@ -90,7 +90,7 @@ void QEglFSWindow::create()
void QEglFSWindow::invalidateSurface()
{
// Native surface has been deleted behind our backs
- m_window = 0;
+ has_window = false;
if (m_surface != 0) {
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
eglDestroySurface(display, m_surface);
@@ -103,6 +103,7 @@ void QEglFSWindow::resetSurface()
EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display();
m_window = QEglFSHooks::hooks()->createNativeWindow(QEglFSHooks::hooks()->screenSize(), m_format);
+ has_window = true;
m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL);
if (m_surface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
@@ -119,9 +120,9 @@ void QEglFSWindow::destroy()
m_surface = 0;
}
- if (m_window) {
+ if (has_window) {
QEglFSHooks::hooks()->destroyNativeWindow(m_window);
- m_window = 0;
+ has_window = false;
}
}
@@ -141,7 +142,7 @@ void QEglFSWindow::setWindowState(Qt::WindowState)
WId QEglFSWindow::winId() const
{
- return m_winid;
+ return WId(m_window);
}
QSurfaceFormat QEglFSWindow::format() const
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 67a64973ce..0997f80e74 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -73,9 +73,9 @@ protected:
EGLNativeWindowType m_window;
private:
- WId m_winid;
EGLConfig m_config;
QSurfaceFormat m_format;
+ bool has_window;
};
QT_END_NAMESPACE
#endif // QEGLFSWINDOW_H
diff --git a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp
index cb245f2e5c..db6e5d94da 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp
@@ -80,9 +80,6 @@ void QMinimalEglBackingStore::flush(QWindow *window, const QRegion &region, cons
void QMinimalEglBackingStore::beginPaint(const QRegion &)
{
- // needed to prevent QOpenGLContext::makeCurrent() from failing
- window()->setSurfaceType(QSurface::OpenGLSurface);
-
m_context->makeCurrent(window());
m_device = new QOpenGLPaintDevice(window()->size());
}
diff --git a/src/plugins/platforms/minimalegl/qminimaleglwindow.cpp b/src/plugins/platforms/minimalegl/qminimaleglwindow.cpp
index 13640b73d6..956b5470e5 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglwindow.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglwindow.cpp
@@ -58,6 +58,7 @@ QMinimalEglWindow::QMinimalEglWindow(QWindow *w)
if (w->geometry() != screenGeometry) {
QWindowSystemInterface::handleGeometryChange(w, screenGeometry);
}
+ w->setSurfaceType(QSurface::OpenGLSurface);
}
void QMinimalEglWindow::setGeometry(const QRect &)
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 92664826ab..377ca32e64 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -2,7 +2,9 @@ TEMPLATE = subdirs
android:!android-no-sdk: SUBDIRS += android
-SUBDIRS += minimal offscreen
+SUBDIRS += minimal
+
+!win32|contains(QT_CONFIG, freetype):SUBDIRS += offscreen
contains(QT_CONFIG, xcb) {
SUBDIRS += xcb
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index d94d3c092a..e723e32301 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -221,9 +221,14 @@ bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event)
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowMinimized);
+#if defined(Q_OS_BLACKBERRY_TABLET)
+ m_navigatorEventHandler->handleWindowGroupActivated(id);
+#endif
break;
case NAVIGATOR_WINDOW_INVISIBLE:
+#if defined(Q_OS_BLACKBERRY_TABLET)
m_navigatorEventHandler->handleWindowGroupDeactivated(id);
+#endif
break;
}
diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
index ff5866d1b7..b3f5c87176 100644
--- a/src/plugins/platforms/qnx/qqnxrootwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
@@ -188,35 +188,8 @@ void QQnxRootWindow::makeTranslucent()
int result;
errno = 0;
- result = screen_destroy_window_buffers(m_window);
- if (result != 0) {
- qFatal("QQnxRootWindow: failed to destroy window buffer, errno=%d", errno);
- }
-
- QRect geometry = m_screen->geometry();
- errno = 0;
- int val[2];
- val[0] = geometry.width();
- val[1] = geometry.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
- if (result != 0) {
- qFatal("QQnxRootWindow: failed to set window buffer size, errno=%d", errno);
- }
-
- errno = 0;
- result = screen_create_window_buffers(m_window, 1);
- if (result != 0) {
- qFatal("QQNX: failed to create window buffer, errno=%d", errno);
- }
-
- // Install an alpha channel on the root window.
- //
- // This is necessary in order to avoid interfering with any particular
- // toplevel widget's QQnxWindow window instance from showing transparent
- // if it desires.
- errno = 0;
- val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
+ const int val = SCREEN_TRANSPARENCY_DISCARD;
+ result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val);
if (result != 0) {
qFatal("QQnxRootWindow: failed to set window transparency, errno=%d", errno);
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 5aa1c970fd..fb8e8075ad 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -418,15 +418,27 @@ QQnxBuffer &QQnxWindow::renderBuffer()
// Get all buffers available for rendering
errno = 0;
screen_buffer_t buffers[MAX_BUFFER_COUNT];
- const int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
+ int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
if (result != 0)
qFatal("QQnxWindow: failed to query window buffers, errno=%d", errno);
- // Wrap each buffer
+ // Wrap each buffer and clear
for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
m_buffers[i] = QQnxBuffer(buffers[i]);
+
+ // Clear Buffer
+ errno = 0;
+ int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
+ result = screen_fill(m_screen->nativeContext(), buffers[i], bg);
+ if (result != 0)
+ qFatal("QQnxWindow: failed to clear window buffer, errno=%d", errno);
}
+ errno = 0;
+ result = screen_flush_blits(m_screen->nativeContext(), 0);
+ if (result != 0)
+ qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+
// Use the first available render buffer
m_currentBufferIndex = 0;
m_previousBufferIndex = -1;
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index ae48887a80..238817e85c 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -88,6 +88,7 @@ enum WindowsEventType // Simplify event types
CursorEvent = MouseEventFlag + 3,
TouchEvent = TouchEventFlag + 1,
NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1,
+ NonClientHitTest = NonClientEventFlag + 2,
KeyEvent = KeyEventFlag + 1,
KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1,
@@ -142,6 +143,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::ResizeEvent;
case WM_NCCALCSIZE:
return QtWindows::CalculateSize;
+#ifndef Q_OS_WINCE
+ case WM_NCHITTEST:
+ return QtWindows::NonClientHitTest;
+#endif // !Q_OS_WINCE
case WM_GETMINMAXINFO:
return QtWindows::QuerySizeHints;
case WM_KEYDOWN: // keyboard event
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 7c6e82d0dc..5114e9d524 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -819,7 +819,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;// maybe available on some SDKs revisit WM_NCCALCSIZE
case QtWindows::CalculateSize:
return QWindowsGeometryHint::handleCalculateSize(platformWindow->customMargins(), msg, result);
-#endif
+ case QtWindows::NonClientHitTest:
+ return platformWindow->handleNonClientHitTest(QPoint(msg.pt.x, msg.pt.y), result);
+#endif // !Q_OS_WINCE
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
case QtWindows::NonClientMouseEvent:
@@ -853,10 +855,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::CloseEvent:
QWindowSystemInterface::handleCloseEvent(platformWindow->window());
return true;
- case QtWindows::ThemeChanged: // ### fixme: Compress these events?
+ case QtWindows::ThemeChanged: {
+ // Switch from Aero to Classic changes margins.
+ const Qt::WindowFlags flags = platformWindow->window()->flags();
+ if ((flags & Qt::WindowType_Mask) != Qt::Desktop && !(flags & Qt::FramelessWindowHint))
+ platformWindow->setFlag(QWindowsWindow::FrameDirty);
if (QWindowsTheme *theme = QWindowsTheme::instance())
theme->windowsThemeChanged(platformWindow->window());
return true;
+ }
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
if (platformWindow->testFlag(QWindowsWindow::BlockedByModal))
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 33bed61398..27a7044868 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -2103,7 +2103,7 @@ QPlatformDialogHelper *createHelper(QPlatformTheme::DialogType type)
|| QSysInfo::windowsVersion() <= QSysInfo::WV_2003) {
return new QWindowsXpFileDialogHelper();
}
- if (QSysInfo::windowsVersion() > QSysInfo::WV_XP)
+ if (QSysInfo::windowsVersion() > QSysInfo::WV_2003)
return new QWindowsFileDialogHelper();
#else
return new QWindowsFileDialogHelper();
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index fc2ba454df..754d7a0288 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -395,6 +395,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return true;
case MultipleWindows:
return true;
+ case ForeignWindows:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index f616972aa0..530ebc38b7 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -98,35 +98,39 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
QWindowsScreenData data;
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ data.name = QString::fromWCharArray(info.szDevice);
+ if (data.name == QLatin1String("WinDisc")) {
+ data.flags |= QWindowsScreenData::LockScreen;
+ } else {
#ifdef Q_OS_WINCE
- //Windows CE, just supports one Display and expects to get only DISPLAY,
- //instead of DISPLAY0 and so on, which are passed by info.szDevice
- HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+ //Windows CE, just supports one Display and expects to get only DISPLAY,
+ //instead of DISPLAY0 and so on, which are passed by info.szDevice
+ HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
#else
- HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL);
+ HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL);
#endif
- if (hdc) {
- data.dpi = deviceDPI(hdc);
- data.depth = GetDeviceCaps(hdc, BITSPIXEL);
- data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
- data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
- const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
- if (refreshRate > 1) // 0,1 means heardware default.
- data.refreshRateHz = refreshRate;
- DeleteDC(hdc);
- } else {
- qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
- __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
- data.dpi.first);
- }
+ if (hdc) {
+ data.dpi = deviceDPI(hdc);
+ data.depth = GetDeviceCaps(hdc, BITSPIXEL);
+ data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+ data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
+ const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
+ if (refreshRate > 1) // 0,1 means hardware default.
+ data.refreshRateHz = refreshRate;
+ DeleteDC(hdc);
+ } else {
+ qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
+ __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
+ data.dpi.first);
+ } // CreateDC() failed
+ } // not lock screen
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
data.orientation = data.geometry.height() > data.geometry.width() ?
Qt::PortraitOrientation : Qt::LandscapeOrientation;
// EnumDisplayMonitors (as opposed to EnumDisplayDevices) enumerates only
// virtual desktop screens.
- data.name = QString::fromWCharArray(info.szDevice);
- data.flags = QWindowsScreenData::VirtualDesktop;
+ data.flags |= QWindowsScreenData::VirtualDesktop;
if (info.dwFlags & MONITORINFOF_PRIMARY) {
data.flags |= QWindowsScreenData::PrimaryScreen;
// QPlatformIntegration::screenAdded() documentation specifies that first
@@ -162,6 +166,8 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
nospace << " primary";
if (d.flags & QWindowsScreenData::VirtualDesktop)
nospace << " virtual desktop";
+ if (d.flags & QWindowsScreenData::LockScreen)
+ nospace << " lock screen";
return dbg;
}
@@ -392,7 +398,8 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData,
bool QWindowsScreenManager::handleScreenChanges()
{
// Look for changed monitors, add new ones
- const WindowsScreenDataList newDataList = monitorData();
+ WindowsScreenDataList newDataList = monitorData();
+ const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
foreach (const QWindowsScreenData &newData, newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
@@ -405,14 +412,17 @@ bool QWindowsScreenManager::handleScreenChanges()
qDebug() << "New Monitor: " << newData;
} // exists
} // for new screens.
- // Remove deleted ones.
- for (int i = m_screens.size() - 1; i >= 0; --i) {
- if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
- if (QWindowsContext::verboseWindows)
- qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
- delete m_screens.takeAt(i);
- } // not found
- } // for existing screens
+ // Remove deleted ones but keep main monitors if we get only the
+ // temporary lock screen to avoid window recreation (QTBUG-33062).
+ if (!lockScreen) {
+ for (int i = m_screens.size() - 1; i >= 0; --i) {
+ if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
+ if (QWindowsContext::verboseWindows)
+ qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
+ delete m_screens.takeAt(i);
+ } // not found
+ } // for existing screens
+ } // not lock screen
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 216973125b..930814a17d 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -59,7 +59,8 @@ struct QWindowsScreenData
enum Flags
{
PrimaryScreen = 0x1,
- VirtualDesktop = 0x2
+ VirtualDesktop = 0x2,
+ LockScreen = 0x4 // Temporary screen existing during user change, etc.
};
QWindowsScreenData();
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 844e46eec5..0fcd20f7bb 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -226,7 +226,6 @@ static inline QPalette menuPalette(const QPalette &systemPalette)
const QColor menuColor(getSysColor(COLOR_MENU));
const QColor menuTextColor(getSysColor(COLOR_MENUTEXT));
const QColor disabled(getSysColor(COLOR_GRAYTEXT));
- const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
// we might need a special color group for the result.
result.setColor(QPalette::Active, QPalette::Button, menuColor);
result.setColor(QPalette::Active, QPalette::Text, menuTextColor);
@@ -235,6 +234,7 @@ static inline QPalette menuPalette(const QPalette &systemPalette)
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
#ifndef Q_OS_WINCE
+ const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
result.setColor(QPalette::Disabled, QPalette::Highlight,
getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT));
#else
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 6549b9da3e..ace18ddf5b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -485,6 +485,18 @@ QWindowsWindow::WindowData
qDebug().nospace() << "Created desktop window " << w << result.hwnd;
return result;
}
+ if ((flags & Qt::WindowType_Mask) == Qt::ForeignWindow) {
+ result.hwnd = reinterpret_cast<HWND>(w->winId());
+ Q_ASSERT(result.hwnd);
+ const LONG_PTR style = GetWindowLongPtr(result.hwnd, GWL_STYLE);
+ const LONG_PTR exStyle = GetWindowLongPtr(result.hwnd, GWL_EXSTYLE);
+ result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd));
+ result.frame = QWindowsGeometryHint::frame(style, exStyle);
+ result.embedded = false;
+ if (QWindowsContext::verboseWindows)
+ qDebug() << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
+ return result;
+ }
const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
@@ -894,7 +906,7 @@ void QWindowsWindow::destroyWindow()
}
}
#endif // !Q_OS_WINCE
- if (m_data.hwnd != GetDesktopWindow())
+ if (m_data.hwnd != GetDesktopWindow() && window()->type() != Qt::ForeignWindow)
DestroyWindow(m_data.hwnd);
context->removeWindow(m_data.hwnd);
m_data.hwnd = 0;
@@ -1408,14 +1420,27 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
handleHidden();
QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now.
break;
- case Qt::WindowNoState:
+ case Qt::WindowNoState: {
// QTBUG-17548: We send expose events when receiving WM_Paint, but for
- // layered windows, we won't receive any WM_Paint.
- if (GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) {
- fireExpose(QRegion(0, 0, window()->width(), window()->height()));
- if (!QWindowsContext::instance()->asyncExpose())
- QWindowSystemInterface::flushWindowSystemEvents();
+ // layered windows and transient children, we won't receive any WM_Paint.
+ QWindow *w = window();
+ bool exposeEventsSent = false;
+ if (isLayered()) {
+ fireExpose(QRegion(0, 0, w->width(), w->height()));
+ exposeEventsSent = true;
}
+ foreach (QWindow *child, QGuiApplication::allWindows()) {
+ if (child != w && child->isVisible() && child->transientParent() == w) {
+ QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(child);
+ if (platformWindow->isLayered()) {
+ platformWindow->fireExpose(QRegion(0, 0, child->width(), child->height()));
+ exposeEventsSent = true;
+ }
+ }
+ }
+ if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
break;
default:
break;
@@ -1796,8 +1821,50 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
if (QWindowsContext::verboseWindows)
qDebug() << __FUNCTION__ << window() << *mmi;
}
+
+bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const
+{
+ // QTBUG-32663, suppress resize cursor for fixed size windows.
+ const QWindow *w = window();
+ if (!w->isTopLevel() // Task 105852, minimized windows need to respond to user input.
+ || (m_windowState != Qt::WindowNoState && m_windowState != Qt::WindowActive)
+ || (m_data.flags & Qt::FramelessWindowHint)) {
+ return false;
+ }
+ const QSize minimumSize = w->minimumSize();
+ if (minimumSize.isEmpty())
+ return false;
+ const QSize maximumSize = w->maximumSize();
+ const bool fixedWidth = minimumSize.width() == maximumSize.width();
+ const bool fixedHeight = minimumSize.height() == maximumSize.height();
+ if (!fixedWidth && !fixedHeight)
+ return false;
+ const QPoint localPos = w->mapFromGlobal(globalPos);
+ const QSize size = w->size();
+ if (fixedHeight) {
+ if (localPos.y() >= size.height()) {
+ *result = HTBORDER; // Unspecified border, no resize cursor.
+ return true;
+ }
+ if (localPos.y() < 0) {
+ const QMargins margins = frameMargins();
+ const int topResizeBarPos = margins.left() - margins.top();
+ if (localPos.y() < topResizeBarPos) {
+ *result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
+ return true;
+ }
+ }
+ }
+ if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
+ *result = HTBORDER; // Unspecified border, no resize cursor.
+ return true;
+ }
+ return false;
+}
+
#endif // !Q_OS_WINCE
+#ifndef QT_NO_CURSOR
// Return the default cursor (Arrow) from QWindowsCursor's cache.
static inline QWindowsWindowCursor defaultCursor(const QWindow *w)
{
@@ -1808,6 +1875,24 @@ static inline QWindowsWindowCursor defaultCursor(const QWindow *w)
return QWindowsWindowCursor(Qt::ArrowCursor);
}
+// Check whether to apply a new cursor. Either the window in question is
+// currently under mouse, or it is the parent of the window under mouse and
+// there is no other window with an explicitly set cursor in-between.
+static inline bool applyNewCursor(const QWindow *w)
+{
+ const QWindow *underMouse = QWindowsContext::instance()->windowUnderMouse();
+ if (underMouse == w)
+ return true;
+ for (const QWindow *p = underMouse; p ; p = p->parent()) {
+ if (p == w)
+ return true;
+ if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
+ return false;
+ }
+ return false;
+}
+#endif // !QT_NO_CURSOR
+
/*!
\brief Applies to cursor property set on the window to the global cursor.
@@ -1829,23 +1914,6 @@ void QWindowsWindow::applyCursor()
#endif
}
-// Check whether to apply a new cursor. Either the window in question is
-// currently under mouse, or it is the parent of the window under mouse and
-// there is no other window with an explicitly set cursor in-between.
-static inline bool applyNewCursor(const QWindow *w)
-{
- const QWindow *underMouse = QWindowsContext::instance()->windowUnderMouse();
- if (underMouse == w)
- return true;
- for (const QWindow *p = underMouse; p ; p = p->parent()) {
- if (p == w)
- return true;
- if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
- return false;
- }
- return false;
-}
-
void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
{
#ifndef QT_NO_CURSOR
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 996542f92a..afcfa8b821 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -229,12 +229,14 @@ public:
static inline void setUserDataOf(HWND hwnd, void *ud);
static bool setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity);
+ bool isLayered() const;
HDC getDC();
void releaseDC();
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO
void getSizeHints(MINMAXINFO *mmi) const;
-#endif
+ bool handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const;
+#endif // !Q_OS_WINCE
#ifndef QT_NO_CURSOR
QWindowsWindowCursor cursor() const { return m_cursor; }
@@ -374,6 +376,15 @@ inline void QWindowsWindow::destroyIcon()
}
}
+inline bool QWindowsWindow::isLayered() const
+{
+#ifndef Q_OS_WINCE
+ return GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED;
+#else
+ return false;
+#endif
+}
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QMargins)
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1f2485db0d..dc677cd3be 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -306,6 +306,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
+ if (!platformWindow) {
+ qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
+ return;
+ }
QVector<QRect> rects = clipped.rects();
for (int i = 0; i < rects.size(); ++i)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 01af23377e..2ce34ea8f2 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -989,8 +989,11 @@ void QXcbEventReader::run()
emit eventPending();
}
+ m_mutex.lock();
for (int i = 0; i < m_events.size(); ++i)
free(m_events.at(i));
+ m_events.clear();
+ m_mutex.unlock();
}
void QXcbEventReader::addEvent(xcb_generic_event_t *event)
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 991c82eaaa..799bb387e1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -309,8 +309,6 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
case XI_TouchUpdate:
if (touchPoint.area.center() != QPoint(x, y))
touchPoint.state = Qt::TouchPointMoved;
- else
- touchPoint.state = Qt::TouchPointStationary;
break;
case XI_TouchEnd:
touchPoint.state = Qt::TouchPointReleased;
@@ -323,9 +321,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
#endif
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values());
- // If a touchpoint was released, we can forget it, because the ID won't be reused.
if (touchPoint.state == Qt::TouchPointReleased)
+ // If a touchpoint was released, we can forget it, because the ID won't be reused.
m_touchPoints.remove(touchPoint.id);
+ else
+ // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent
+ // with this touch point if the next XI2 event is about a different touch point.
+ touchPoint.state = Qt::TouchPointStationary;
}
}
#endif
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 38cbfaf183..d1729ed168 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -723,14 +723,14 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
if (connection()->hasXKB()) {
- xkb_state_component newState;
- newState = xkb_state_update_mask(xkb_state,
- state->baseMods,
- state->latchedMods,
- state->lockedMods,
- state->baseGroup,
- state->latchedGroup,
- state->lockedGroup);
+ const xkb_state_component newState
+ = xkb_state_update_mask(xkb_state,
+ state->baseMods,
+ state->latchedMods,
+ state->lockedMods,
+ state->baseGroup,
+ state->latchedGroup,
+ state->lockedGroup);
if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
@@ -744,17 +744,22 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
if (!m_config)
return;
- quint32 modsDepressed, modsLatched, modsLocked;
- modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
- modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
- modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
-
- quint32 xkbMask = xkbModMask(state);
- xkb_state_component newState;
- newState = xkb_state_update_mask(xkb_state,
- modsDepressed & xkbMask,
- modsLatched & xkbMask,
- modsLocked & xkbMask,
+ const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
+ const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
+ const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
+ const quint32 xkbMask = xkbModMask(state);
+
+ const quint32 latched = modsLatched & xkbMask;
+ const quint32 locked = modsLocked & xkbMask;
+ quint32 depressed = modsDepressed & xkbMask;
+ // set modifiers in depressed if they don't appear in any of the final masks
+ depressed |= ~(depressed | latched | locked) & xkbMask;
+
+ const xkb_state_component newState
+ = xkb_state_update_mask(xkb_state,
+ depressed,
+ latched,
+ locked,
0,
0,
(state >> 13) & 3); // bits 13 and 14 report the state keyboard group
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 0325338a13..028cd9ab72 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1302,6 +1302,9 @@ QRect QXcbWindow::windowToWmGeometry(QRect r) const
r.translate(m_frameMargins.left(), m_frameMargins.top());
} else if (!frameInclusive && m_gravity == XCB_GRAVITY_NORTH_WEST) {
r.translate(-m_frameMargins.left(), -m_frameMargins.top());
+ } else if (!frameInclusive && m_gravity == XCB_GRAVITY_CENTER) {
+ r.translate(-(m_frameMargins.left() - m_frameMargins.right())/2,
+ -(m_frameMargins.top() - m_frameMargins.bottom())/2);
}
return r;
}
@@ -1641,7 +1644,8 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
{
- if (window() != QGuiApplication::focusWindow()) {
+ const bool isWheel = event->detail >= 4 && event->detail <= 7;
+ if (!isWheel && window() != QGuiApplication::focusWindow()) {
QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
if (!(w->flags() & Qt::WindowDoesNotAcceptFocus))
w->requestActivate();
@@ -1663,7 +1667,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
- if (event->detail >= 4 && event->detail <= 7) {
+ if (isWheel) {
// Logic borrowed from qapplication_x11.cpp
int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
bool hor = (((event->detail == 4 || event->detail == 5)
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index c106bd00f8..1423c6262d 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -221,6 +221,7 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(screen->xcb_connection(),atom_cookie,&error);
if (error) {
qWarning() << Q_FUNC_INFO << "Failed to find XSETTINGS_S atom";
+ free(error);
return;
}
xcb_atom_t selection_owner_atom = atom_reply->atom;
@@ -233,14 +234,15 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_get_selection_owner_reply(screen->xcb_connection(), selection_cookie, &error);
if (error) {
qWarning() << Q_FUNC_INFO << "Failed to get selection owner for XSETTINGS_S atom";
+ free(error);
return;
}
d_ptr->x_settings_window = selection_result->owner;
+ free(selection_result);
if (!d_ptr->x_settings_window) {
return;
}
- free(selection_result);
const uint32_t event = XCB_CW_EVENT_MASK;
const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE };