summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm24
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.cpp3
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h1
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp26
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp53
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp63
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h2
31 files changed, 199 insertions, 62 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 6f99dc458a..e4b52b9454 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -56,8 +56,11 @@ class QCocoaNativeInterface : public QPlatformNativeInterface
public:
QCocoaNativeInterface();
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+ static void *cglContextForContext(QOpenGLContext *context);
+
public Q_SLOTS:
void onAppFocusWindowChanged(QWindow *window);
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index e5040080ed..7f37b971d7 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -65,6 +65,17 @@ QCocoaNativeInterface::QCocoaNativeInterface()
{
}
+void *QCocoaNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
+{
+ if (!context)
+ return 0;
+
+ if (resourceString.toLower() == "cglcontextobj")
+ return cglContextForContext(context);
+
+ return 0;
+}
+
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
if (!window->handle()) {
@@ -109,4 +120,17 @@ void QCocoaNativeInterface::onAppFocusWindowChanged(QWindow *window)
QCocoaMenuBar::updateMenuBarImmediately();
}
+void *QCocoaNativeInterface::cglContextForContext(QOpenGLContext* context)
+{
+ if (context) {
+ QCocoaGLContext *cocoaGLContext = static_cast<QCocoaGLContext *>(context->handle());
+ if (cocoaGLContext) {
+ NSOpenGLContext *nsOpenGLContext = cocoaGLContext->nsOpenGLContext();
+ if (nsOpenGLContext)
+ return [nsOpenGLContext CGLContextObj];
+ }
+ }
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 4a146767d5..014db378e7 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -98,7 +98,7 @@ public:
void setGeometry(const QRect &rect);
void setCocoaGeometry(const QRect &rect);
void setVisible(bool visible);
- Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ void setWindowFlags(Qt::WindowFlags flags);
Qt::WindowState setWindowState(Qt::WindowState state);
void setWindowTitle(const QString &title);
void setWindowFilePath(const QString &filePath);
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 26161b106e..f4a4936c28 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -387,7 +387,7 @@ void QCocoaWindow::setWindowShadow(Qt::WindowFlags flags)
[m_nsWindow setHasShadow:(keepShadow ? YES : NO)];
}
-Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
+void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (m_nsWindow) {
NSUInteger styleMask = windowStyleMask(flags);
@@ -398,7 +398,6 @@ Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
}
m_windowFlags = flags;
- return m_windowFlags;
}
Qt::WindowState QCocoaWindow::setWindowState(Qt::WindowState state)
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
index 8b108eeaa2..630e4fd7a2 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
@@ -140,7 +140,7 @@ void QDirectFbWindow::setVisible(bool visible)
QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
}
-Qt::WindowFlags QDirectFbWindow::setWindowFlags(Qt::WindowFlags flags)
+void QDirectFbWindow::setWindowFlags(Qt::WindowFlags flags)
{
switch (flags & Qt::WindowType_Mask) {
case Qt::ToolTip: {
@@ -154,7 +154,6 @@ Qt::WindowFlags QDirectFbWindow::setWindowFlags(Qt::WindowFlags flags)
}
m_dfbWindow->SetStackingClass(m_dfbWindow.data(), flags & Qt::WindowStaysOnTopHint ? DWSC_UPPER : DWSC_MIDDLE);
- return flags;
}
void QDirectFbWindow::raise()
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.h b/src/plugins/platforms/directfb/qdirectfbwindow.h
index cedd140809..3edee7c6b2 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.h
@@ -60,7 +60,7 @@ public:
void setVisible(bool visible);
- Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ void setWindowFlags(Qt::WindowFlags flags);
bool setKeyboardGrabEnabled(bool grab);
bool setMouseGrabEnabled(bool grab);
void raise();
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index ed3ea49d44..9007af7f70 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -88,7 +88,7 @@ QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
if (result != 0) {
qFatal("QQNX: failed to query buffer pointer, errno=%d", errno);
}
- if (dataPtr == NULL) {
+ if (dataPtr == 0) {
qFatal("QQNX: buffer pointer is NULL, errno=%d", errno);
}
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.h b/src/plugins/platforms/qnx/qqnxbuffer.h
index 7788778a4a..d5adeb8d8b 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.h
+++ b/src/plugins/platforms/qnx/qqnxbuffer.h
@@ -57,8 +57,8 @@ public:
virtual ~QQnxBuffer();
screen_buffer_t nativeBuffer() const { return m_buffer; }
- const QImage *image() const { return (m_buffer != NULL) ? &m_image : NULL; }
- QImage *image() { return (m_buffer != NULL) ? &m_image : NULL; }
+ const QImage *image() const { return (m_buffer != 0) ? &m_image : 0; }
+ QImage *image() { return (m_buffer != 0) ? &m_image : 0; }
QRect rect() const { return m_image.rect(); }
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 72a967d5e5..30ca8a5c48 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -571,7 +571,7 @@ spannable_string_t *toSpannableString(const QString &text)
spannable_string_t *pString = reinterpret_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
pString->str = (wchar_t *)malloc(sizeof(wchar_t) * text.length() + 1);
pString->length = text.length();
- pString->spans = NULL;
+ pString->spans = 0;
pString->spans_count = 0;
const QChar *pData = text.constData();
@@ -601,7 +601,7 @@ static bool s_imfInitFailed = false;
static bool imfAvailable()
{
- static bool s_imfDisabled = getenv("DISABLE_IMF") != NULL;
+ static bool s_imfDisabled = getenv("DISABLE_IMF") != 0;
static bool s_imfReady = false;
if ( s_imfInitFailed || s_imfDisabled) {
@@ -611,7 +611,7 @@ static bool imfAvailable()
return true;
}
- if ( p_imf_client_init == NULL ) {
+ if ( p_imf_client_init == 0 ) {
void *handle = dlopen("libinput_client.so.1", 0);
if ( handle ) {
p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init");
@@ -632,8 +632,8 @@ static bool imfAvailable()
s_imfReady = true;
}
else {
- p_ictrl_open_session = NULL;
- p_ictrl_dispatch_event = NULL;
+ p_ictrl_open_session = 0;
+ p_ictrl_dispatch_event = 0;
s_imfDisabled = true;
qCritical() << Q_FUNC_INFO << "libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled.";
return false;
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 6a092f01a0..593bec8458 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -524,7 +524,7 @@ void QQnxScreen::newWindowCreated(void *window)
{
Q_ASSERT(thread() == QThread::currentThread());
const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
- screen_display_t display = NULL;
+ screen_display_t display = 0;
if (screen_get_window_property_pv(windowHandle, SCREEN_PROPERTY_DISPLAY, (void**)&display) != 0) {
qWarning("QQnx: Failed to get screen for window, errno=%d", errno);
return;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 621440ed53..d8712bf569 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -462,7 +462,7 @@ void QQnxScreenEventHandler::handleCreateEvent(screen_event_t event)
void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
{
- screen_display_t nativeDisplay = NULL;
+ screen_display_t nativeDisplay = 0;
if (screen_get_event_property_pv(event, SCREEN_PROPERTY_DISPLAY, (void **)&nativeDisplay) != 0) {
qWarning("QQnx: failed to query display property, errno=%d", errno);
return;
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index 4618b90f81..ab912927bb 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -130,7 +130,7 @@ bool QQnxVirtualKeyboardPps::connect()
m_decoder = new pps_decoder_t;
pps_encoder_initialize(m_encoder, false);
- pps_decoder_initialize(m_decoder, NULL);
+ pps_decoder_initialize(m_decoder, 0);
errno = 0;
m_fd = ::open(ms_PPSPath, O_RDWR);
@@ -197,7 +197,7 @@ void QQnxVirtualKeyboardPps::ppsDataReady()
m_buffer[nread] = 0;
pps_decoder_parse_pps_str(m_decoder, m_buffer);
- pps_decoder_push(m_decoder, NULL);
+ pps_decoder_push(m_decoder, 0);
#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
pps_decoder_dump_tree(m_decoder, stderr);
#endif
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 6eb3bdee10..73f963b6b8 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -104,6 +104,7 @@ enum WindowsEventType // Simplify event types
InputMethodRequest = InputMethodEventFlag + 6,
ThemeChanged = ThemingEventFlag + 1,
DisplayChangedEvent = 437,
+ SettingChangedEvent = DisplayChangedEvent + 1,
UnknownEvent = 542
};
@@ -184,6 +185,11 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::FocusInEvent;
case WM_KILLFOCUS:
return QtWindows::FocusOutEvent;
+ // Among other things, WM_SETTINGCHANGE happens when the taskbar is moved
+ // and therefore the "working area" changes.
+ // http://msdn.microsoft.com/en-us/library/ms695534(v=vs.85).aspx
+ case WM_SETTINGCHANGE:
+ return QtWindows::SettingChangedEvent;
case WM_DISPLAYCHANGE:
return QtWindows::DisplayChangedEvent;
case WM_THEMECHANGED:
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 0dade2c49b..98c17deba9 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -331,6 +331,11 @@ bool QWindowsContext::useRTLExtensions() const
return d->m_keyMapper.useRTLExtensions();
}
+QList<int> QWindowsContext::possibleKeys(const QKeyEvent *e) const
+{
+ return d->m_keyMapper.possibleKeys(e);
+}
+
void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx)
{
d->m_creationContext = ctx;
@@ -749,6 +754,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
#endif
case QtWindows::DisplayChangedEvent:
return d->m_screenManager.handleDisplayChange(wParam, lParam);
+ case QtWindows::SettingChangedEvent:
+ return d->m_screenManager.handleScreenChanges();
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 3f08a742f8..450d6c8f4b 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -60,6 +60,7 @@ class QWindowsMimeConverter;
struct QWindowCreationContext;
struct QWindowsContextPrivate;
class QPoint;
+class QKeyEvent;
#ifndef Q_OS_WINCE
struct QWindowsUser32DLL
@@ -170,6 +171,7 @@ public:
unsigned systemInfo() const;
bool useRTLExtensions() const;
+ QList<int> possibleKeys(const QKeyEvent *e) const;
QWindowsMimeConverter &mimeConverter() const;
QWindowsScreenManager &screenManager();
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 8b3d6749a0..11fd740009 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -560,12 +560,8 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
// Find the word in the surrounding text.
QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText);
bounds.setPosition(pos);
- if (bounds.isAtBoundary()) {
- if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons())
- bounds.toPreviousBoundary();
- } else {
+ if (bounds.position() > 0 && !(bounds.boundaryReasons() & QTextBoundaryFinder::StartOfItem))
bounds.toPreviousBoundary();
- }
const int startPos = bounds.position();
bounds.toNextBoundary();
const int endPos = bounds.position();
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 463e01246b..1f26ec5bab 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -447,6 +447,11 @@ Qt::KeyboardModifiers QWindowsIntegration::queryKeyboardModifiers() const
return QWindowsKeyMapper::queryKeyboardModifiers();
}
+QList<int> QWindowsIntegration::possibleKeys(const QKeyEvent *e) const
+{
+ return d->m_context.possibleKeys(e);
+}
+
QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
{
return &d->m_nativeInterface;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index fe095cf5d3..49780566dd 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -81,6 +81,7 @@ public:
virtual QVariant styleHint(StyleHint hint) const;
virtual Qt::KeyboardModifiers queryKeyboardModifiers() const;
+ virtual QList<int> possibleKeys(const QKeyEvent *e) const;
static QWindowsIntegration *instance();
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 322d66836a..b57a27acb4 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -1119,4 +1119,30 @@ Qt::KeyboardModifiers QWindowsKeyMapper::queryKeyboardModifiers()
return modifiers;
}
+QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
+{
+ QList<int> result;
+
+ KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
+ if (!kbItem)
+ return result;
+
+ quint32 baseKey = kbItem->qtKey[0];
+ Qt::KeyboardModifiers keyMods = e->modifiers();
+ if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) {
+ result << int(Qt::Key_Enter + keyMods);
+ return result;
+ }
+ result << int(baseKey + keyMods); // The base key is _always_ valid, of course
+
+ for (int i = 1; i < 9; ++i) {
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ quint32 key = kbItem->qtKey[i];
+ if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
+ result << int(key + (keyMods & ~neededMods));
+ }
+
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
index 3a13deb0b6..7b3f18a42d 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.h
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
+class QKeyEvent;
class QWindow;
struct KeyboardLayoutItem;
@@ -70,6 +71,7 @@ public:
void setKeyGrabber(QWindow *w) { m_keyGrabber = w; }
static Qt::KeyboardModifiers queryKeyboardModifiers();
+ QList<int> possibleKeys(const QKeyEvent *e) const;
private:
bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab);
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 05a6893aad..0717a8ec60 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -372,7 +372,7 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData,
ones and propagates resolution changes to QWindowSystemInterface.
*/
-void QWindowsScreenManager::handleScreenChanges()
+bool QWindowsScreenManager::handleScreenChanges()
{
// Look for changed monitors, add new ones
const WindowsScreenDataList newDataList = monitorData();
@@ -396,6 +396,7 @@ void QWindowsScreenManager::handleScreenChanges()
delete m_screens.takeAt(i);
} // not found
} // for existing screens
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 49b62632fc..dfd85f9be4 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -129,7 +129,7 @@ public:
delete m_screens.takeLast();
}
- void handleScreenChanges();
+ bool handleScreenChanges();
bool handleDisplayChange(WPARAM wParam, LPARAM lParam);
const WindowsScreenList &screens() const { return m_screens; }
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 2335870ea7..f3830eb962 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1178,7 +1178,7 @@ void QWindowsWindow::setWindowTitle(const QString &title)
SetWindowText(m_data.hwnd, (const wchar_t*)title.utf16());
}
-Qt::WindowFlags QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
+void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (QWindowsContext::verboseWindows)
qDebug() << '>' << __FUNCTION__ << this << window() << "\n from: "
@@ -1202,7 +1202,6 @@ Qt::WindowFlags QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
qDebug() << '<' << __FUNCTION__ << "\n returns: "
<< QWindowsWindow::debugWindowFlags(m_data.flags)
<< " geometry " << oldGeometry << "->" << newGeometry;
- return m_data.flags;
}
QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 4b1792859f..3b7666cf32 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -159,7 +159,7 @@ public:
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;
- virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ virtual void setWindowFlags(Qt::WindowFlags flags);
virtual Qt::WindowState setWindowState(Qt::WindowState state);
HWND handle() const { return m_data.hwnd; }
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index f021ab8b4a..142a8dfcde 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -300,6 +300,9 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
m_timestamp[mode] = XCB_CURRENT_TIME;
}
+ if (connection()->time() == XCB_CURRENT_TIME)
+ connection()->setTime(connection()->getTimestamp());
+
if (data) {
newOwner = owner();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 401739f7d5..ad9fb1d19c 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -864,6 +864,59 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_flush(xcb_connection());
}
+namespace
+{
+ class PropertyNotifyEvent {
+ public:
+ PropertyNotifyEvent(xcb_window_t win, xcb_atom_t property)
+ : window(win), type(XCB_PROPERTY_NOTIFY), atom(property) {}
+ xcb_window_t window;
+ int type;
+ xcb_atom_t atom;
+ bool checkEvent(xcb_generic_event_t *event) const {
+ if (!event)
+ return false;
+ if ((event->response_type & ~0x80) != type) {
+ return false;
+ } else {
+ xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ if ((pn->window == window) && (pn->atom == atom))
+ return true;
+ }
+ return false;
+ }
+ };
+}
+
+xcb_timestamp_t QXcbConnection::getTimestamp()
+{
+ // send a dummy event to myself to get the timestamp from X server.
+ xcb_window_t rootWindow = screens().at(primaryScreen())->root();
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, rootWindow, atom(QXcbAtom::CLIP_TEMPORARY),
+ XCB_ATOM_INTEGER, 32, 0, NULL);
+
+ connection()->flush();
+ PropertyNotifyEvent checker(rootWindow, atom(QXcbAtom::CLIP_TEMPORARY));
+
+ xcb_generic_event_t *event = 0;
+ // lets keep this inside a loop to avoid a possible race condition, where
+ // reader thread has not yet had the time to acquire the mutex in order
+ // to add the new set of events to its event queue
+ while (true) {
+ connection()->sync();
+ if (event = checkEvent(checker))
+ break;
+ }
+
+ xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_timestamp_t timestamp = pn->time;
+ free(event);
+
+ xcb_delete_property(xcb_connection(), rootWindow, atom(QXcbAtom::CLIP_TEMPORARY));
+
+ return timestamp;
+}
+
void QXcbConnection::processXcbEvents()
{
QXcbEventArray *eventqueue = m_reader->lock();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 08dd304b3d..8a6c418788 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -319,7 +319,6 @@ public:
QByteArray atomName(xcb_atom_t atom);
const char *displayName() const { return m_displayName.constData(); }
-
xcb_connection_t *xcb_connection() const { return m_connection; }
const xcb_setup_t *setup() const { return m_setup; }
const xcb_format_t *formatForDepth(uint8_t depth) const;
@@ -380,6 +379,8 @@ public:
bool hasXRandr() const { return has_randr_extension; }
bool hasInputShape() const { return has_input_shape; }
+ xcb_timestamp_t getTimestamp();
+
private slots:
void processXcbEvents();
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 1a2de82fd3..5d887cd06d 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -53,6 +53,7 @@
#include <qguiapplication.h>
#include <qrect.h>
#include <qpainter.h>
+#include <qtimer.h>
#include <qpa/qwindowsysteminterface.h>
@@ -140,8 +141,7 @@ QXcbDrag::QXcbDrag(QXcbConnection *c) : QXcbObject(c)
init();
heartbeat = -1;
-
- transaction_expiry_timer = -1;
+ cleanup_timer = -1;
}
QXcbDrag::~QXcbDrag()
@@ -510,17 +510,21 @@ void QXcbDrag::drop(const QMouseEvent *event)
if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
-
Transaction t = {
connection()->time(),
current_target,
current_proxy_target,
(w ? w->window() : 0),
-// current_embedding_widget,
- currentDrag()
+// current_embeddig_widget,
+ currentDrag(),
+ QTime::currentTime()
};
transactions.append(t);
- restartDropExpiryTimer();
+
+ // timer is needed only for drops that came from other processes.
+ if (!t.targetWindow && cleanup_timer == -1) {
+ cleanup_timer = startTimer(XdndDropTransactionTimeout);
+ }
if (w) {
handleDrop(w->window(), &drop);
@@ -563,16 +567,6 @@ xcb_atom_t QXcbDrag::toXdndAction(Qt::DropAction a) const
}
}
-// timer used to discard old XdndDrop transactions
-enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
-
-void QXcbDrag::restartDropExpiryTimer()
-{
- if (transaction_expiry_timer != -1)
- killTimer(transaction_expiry_timer);
- transaction_expiry_timer = startTimer(XdndDropTransactionTimeout);
-}
-
int QXcbDrag::findTransactionByWindow(xcb_window_t window)
{
int at = -1;
@@ -771,8 +765,6 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
response.data.data32[3] = 0; // w, h
response.data.data32[4] = toXdndAction(qt_response.acceptedAction()); // action
-
-
if (answerRect.left() < 0)
answerRect.setLeft(0);
if (answerRect.right() > 4096)
@@ -1015,7 +1007,6 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
if (l[0]) {
int at = findTransactionByWindow(l[0]);
if (at != -1) {
- restartDropExpiryTimer();
Transaction t = transactions.takeAt(at);
// QDragManager *manager = QDragManager::self();
@@ -1044,12 +1035,13 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
// current_proxy_target = proxy_target;
// current_embedding_widget = embedding_widget;
// manager->object = currentObject;
+ } else {
+ qWarning("QXcbDrag::handleFinished - drop data has expired");
}
}
waiting_for_status = false;
}
-
void QXcbDrag::timerEvent(QTimerEvent* e)
{
if (e->timerId() == heartbeat && source_sameanswer.isNull()) {
@@ -1057,19 +1049,35 @@ void QXcbDrag::timerEvent(QTimerEvent* e)
QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
move(&me);
- } else if (e->timerId() == transaction_expiry_timer) {
+ } else if (e->timerId() == cleanup_timer) {
+ bool stopTimer = true;
for (int i = 0; i < transactions.count(); ++i) {
const Transaction &t = transactions.at(i);
if (t.targetWindow) {
- // dnd within the same process, don't delete these
+ // dnd within the same process, don't delete, these are taken care of
+ // in handleFinished()
continue;
}
- t.drag->deleteLater();
- transactions.removeAt(i--);
- }
+ QTime currentTime = QTime::currentTime();
+ int delta = t.time.msecsTo(currentTime);
+ if (delta > XdndDropTransactionTimeout) {
+ /* delete transactions which are older than XdndDropTransactionTimeout. It could mean
+ one of these:
+ - client has crashed and as a result we have never received XdndFinished
+ - showing dialog box on drop event where user's response takes more time than XdndDropTransactionTimeout (QTBUG-14493)
+ - dnd takes unusually long time to process data
+ */
+ t.drag->deleteLater();
+ transactions.removeAt(i--);
+ } else {
+ stopTimer = false;
+ }
- killTimer(transaction_expiry_timer);
- transaction_expiry_timer = -1;
+ }
+ if (stopTimer && cleanup_timer != -1) {
+ killTimer(cleanup_timer);
+ cleanup_timer = -1;
+ }
}
}
@@ -1123,7 +1131,6 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
QDrag *transactionDrag = 0;
if (at >= 0) {
- restartDropExpiryTimer();
transactionDrag = transactions.at(at).drag;
} else if (at == -2) {
transactionDrag = currentDrag();
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 99c1e2d78f..41d15505ce 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -52,7 +52,7 @@
#include <qsharedpointer.h>
#include <qpointer.h>
#include <qvector.h>
-
+#include <qdatetime.h>
#include <qpixmap.h>
#include <qbackingstore.h>
@@ -146,6 +146,10 @@ private:
// timer used when target wants "continuous" move messages (eg. scroll)
int heartbeat;
+ // 10 minute timer used to discard old XdndDrop transactions
+ enum { XdndDropTransactionTimeout = 600000 };
+ int cleanup_timer;
+
QVector<xcb_atom_t> drag_types;
struct Transaction
@@ -156,6 +160,7 @@ private:
QWindow *targetWindow;
// QWidget *embedding_widget;
QDrag *drag;
+ QTime time;
};
QList<Transaction> transactions;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 64cb9afcc6..cefe1a7786 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -740,7 +740,7 @@ void QXcbWindow::setNetWmStates(NetWmStates states)
xcb_flush(xcb_connection());
}
-Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
@@ -763,8 +763,6 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
-
- return flags;
}
void QXcbWindow::setMotifWindowFlags(Qt::WindowFlags flags)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index ab18b502be..e2f62401dc 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -81,7 +81,7 @@ public:
QMargins frameMargins() const;
void setVisible(bool visible);
- Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ void setWindowFlags(Qt::WindowFlags flags);
Qt::WindowState setWindowState(Qt::WindowState state);
WId winId() const;
void setParent(const QPlatformWindow *window);