summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h13
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm78
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm115
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm11
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp7
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp30
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp37
16 files changed, 204 insertions, 137 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 18673a3667..fa05626d18 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -57,7 +57,11 @@ public:
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+#ifndef QT_NO_OPENGL
QImage toImage() const Q_DECL_OVERRIDE;
+#else
+ QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds.
+#endif
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index f98ddbb14f..c021a551a7 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -428,14 +428,18 @@ void QCocoaIntegration::updateScreens()
}
siblings << screen;
}
+
+ // Set virtual siblings list. All screens in mScreens are siblings, because we ignored the
+ // mirrors. Note that some of the screens we update the siblings list for here may be deleted
+ // below, but update anyway to keep the to-be-deleted screens out of the siblings list.
+ foreach (QCocoaScreen* screen, mScreens)
+ screen->setVirtualSiblings(siblings);
+
// Now the leftovers in remainingScreens are no longer current, so we can delete them.
foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(screen);
destroyScreen(screen);
}
- // All screens in mScreens are siblings, because we ignored the mirrors.
- foreach (QCocoaScreen* screen, mScreens)
- screen->setVirtualSiblings(siblings);
}
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 64299c6cd2..64eeabcc2d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -81,8 +81,6 @@ public:
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
- inline NSMenuItem *nsMenuItem() const
- { return m_nativeItem; }
inline bool isVisible() const { return m_visible; }
@@ -91,11 +89,9 @@ public:
QList<QCocoaMenuItem *> items() const;
QList<QCocoaMenuItem *> merged() const;
- void setMenuBar(QCocoaMenuBar *menuBar);
- QCocoaMenuBar *menuBar() const;
- void setContainingMenuItem(QCocoaMenuItem *menuItem);
- QCocoaMenuItem *containingMenuItem() const;
+ void setAttachedItem(NSMenuItem *item);
+ NSMenuItem *attachedItem() const;
private:
QCocoaMenuItem *itemOrNull(int index) const;
@@ -103,13 +99,10 @@ private:
QList<QCocoaMenuItem *> m_menuItems;
NSMenu *m_nativeMenu;
- NSMenuItem *m_nativeItem;
- NSObject *m_delegate;
+ NSMenuItem *m_attachedItem;
bool m_enabled;
bool m_visible;
quintptr m_tag;
- QCocoaMenuBar *m_menuBar;
- QCocoaMenuItem *m_containingMenuItem;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 8c576c7cbe..3fc98c071f 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -102,6 +102,28 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
return self;
}
+- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
+{
+ Q_ASSERT(m_menu->nsMenu() == menu);
+ return m_menu->items().count();
+}
+
+- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
+{
+ Q_UNUSED(index);
+ Q_ASSERT(m_menu->nsMenu() == menu);
+ if (shouldCancel) {
+ // TODO detach all submenus
+ return NO;
+ }
+
+ QCocoaMenuItem *menuItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
+ if (m_menu->items().contains(menuItem)) {
+ if (QCocoaMenu *itemSubmenu = menuItem->menu())
+ itemSubmenu->setAttachedItem(item);
+ }
+ return YES;
+}
- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
{
@@ -234,20 +256,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
+ m_attachedItem(0),
m_enabled(true),
m_visible(true),
- m_tag(0),
- m_menuBar(0),
- m_containingMenuItem(0)
+ m_tag(0)
{
QMacAutoReleasePool pool;
- m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
- m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES];
- m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate;
- [m_nativeItem setSubmenu:m_nativeMenu];
+ m_nativeMenu.delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
}
QCocoaMenu::~QCocoaMenu()
@@ -257,14 +275,11 @@ QCocoaMenu::~QCocoaMenu()
SET_COCOA_MENU_ANCESTOR(item, 0);
}
- if (m_containingMenuItem)
- m_containingMenuItem->clearMenu(this);
-
QMacAutoReleasePool pool;
- [m_nativeItem setSubmenu:nil];
+ NSObject *delegate = m_nativeMenu.delegate;
+ m_nativeMenu.delegate = nil;
+ [delegate release];
[m_nativeMenu release];
- [m_delegate release];
- [m_nativeItem release];
}
void QCocoaMenu::setText(const QString &text)
@@ -272,7 +287,6 @@ void QCocoaMenu::setText(const QString &text)
QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:QCFString::toNSString(stripped)];
- [m_nativeItem setTitle:QCFString::toNSString(stripped)];
}
void QCocoaMenu::setMinimumWidth(int width)
@@ -313,17 +327,13 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{
- [item->nsItem() setTarget:m_delegate];
+ item->nsItem().target = m_nativeMenu.delegate;
if (!item->menu())
[item->nsItem() setAction:@selector(itemFired:)];
if (item->isMerged())
return;
- if ([item->nsItem() menu]) {
- qWarning("Menu item is already in a menu, remove it from the other menu first before inserting");
- return;
- }
// if the item we're inserting before is merged, skip along until
// we find a non-merged real item to insert ahead of.
while (beforeItem && beforeItem->isMerged()) {
@@ -451,12 +461,11 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
- return [m_nativeItem isEnabled];
+ return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled;
}
void QCocoaMenu::setVisible(bool visible)
{
- [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];
m_visible = visible;
}
@@ -593,8 +602,6 @@ void QCocoaMenu::syncModalState(bool modal)
if (!m_enabled)
modal = true;
- [m_nativeItem setEnabled:!modal];
-
foreach (QCocoaMenuItem *item, m_menuItems) {
if (item->menu()) { // recurse into submenus
item->menu()->syncModalState(modal);
@@ -605,25 +612,24 @@ void QCocoaMenu::syncModalState(bool modal)
}
}
-void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar)
+void QCocoaMenu::setAttachedItem(NSMenuItem *item)
{
- m_menuBar = menuBar;
- SET_COCOA_MENU_ANCESTOR(this, menuBar);
-}
+ if (item == m_attachedItem)
+ return;
-QCocoaMenuBar *QCocoaMenu::menuBar() const
-{
- return m_menuBar;
-}
+ if (m_attachedItem)
+ m_attachedItem.submenu = nil;
+
+ m_attachedItem = item;
+
+ if (m_attachedItem)
+ m_attachedItem.submenu = m_nativeMenu;
-void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
-{
- m_containingMenuItem = menuItem;
}
-QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
+NSMenuItem *QCocoaMenu::attachedItem() const
{
- return m_containingMenuItem;
+ return m_attachedItem;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 0521bcd430..7ce2059450 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -77,10 +77,10 @@ private:
static QCocoaMenuBar *findGlobalMenubar();
bool shouldDisable(QCocoaWindow *active) const;
- void insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu);
- void removeNativeMenu(QCocoaMenu *menu);
- QList<QCocoaMenu*> m_menus;
+ NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const;
+
+ QList<QPointer<QCocoaMenu> > m_menus;
NSMenu *m_nativeMenu;
QCocoaWindow *m_window;
};
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index c9a42e9d8e..e8b3823012 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -57,7 +57,6 @@ static inline QCocoaMenuLoader *getMenuLoader()
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
-
QCocoaMenuBar::QCocoaMenuBar() :
m_window(0)
{
@@ -74,11 +73,20 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
+ foreach (QCocoaMenu *menu, m_menus) {
+ if (!menu)
+ continue;
+ NSMenuItem *item = nativeItemForMenu(menu);
+ if (menu->attachedItem() == item)
+ menu->setAttachedItem(nil);
+ }
+
[m_nativeMenu release];
static_menubars.removeOne(this);
if (m_window && m_window->menubar() == this) {
m_window->setMenubar(0);
+
// Delete the children first so they do not cause
// the native menu items to be hidden after
// the menu bar was updated
@@ -87,24 +95,6 @@ QCocoaMenuBar::~QCocoaMenuBar()
}
}
-void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu)
-{
- QMacAutoReleasePool pool;
-
- if (beforeMenu) {
- NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()];
- [m_nativeMenu insertItem: menu->nsMenuItem() atIndex: nativeIndex];
- } else {
- [m_nativeMenu addItem: menu->nsMenuItem()];
- }
-
- menu->setMenuBar(this);
- syncMenu(static_cast<QPlatformMenu *>(menu));
- if (menu->isVisible()) {
- [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
- }
-}
-
void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before)
{
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@@ -113,31 +103,40 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before;
#endif
- if (m_menus.contains(menu)) {
+ if (m_menus.contains(QPointer<QCocoaMenu>(menu))) {
qWarning("This menu already belongs to the menubar, remove it first");
return;
}
- if (beforeMenu && !m_menus.contains(beforeMenu)) {
+ if (beforeMenu && !m_menus.contains(QPointer<QCocoaMenu>(beforeMenu))) {
qWarning("The before menu does not belong to the menubar");
return;
}
- m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu);
- if (!menu->menuBar())
- insertNativeMenu(menu, beforeMenu);
- if (m_window && m_window->window()->isActive())
- updateMenuBarImmediately();
-}
+ int insertionIndex = beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size();
+ m_menus.insert(insertionIndex, menu);
+
+ {
+ QMacAutoReleasePool pool;
+ NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
+ item.tag = reinterpret_cast<NSInteger>(menu);
+
+ if (beforeMenu) {
+ // QMenuBar::toNSMenu() exposes the native menubar and
+ // the user could have inserted its own items in there.
+ // Same remark applies to removeMenu().
+ NSMenuItem *beforeItem = nativeItemForMenu(beforeMenu);
+ NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem];
+ [m_nativeMenu insertItem:item atIndex:nativeIndex];
+ } else {
+ [m_nativeMenu addItem:item];
+ }
+ }
-void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu)
-{
- QMacAutoReleasePool pool;
+ syncMenu(menu);
- if (menu->menuBar() == this)
- menu->setMenuBar(0);
- NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
- [m_nativeMenu removeItemAtIndex: realIndex];
+ if (m_window && m_window->window()->isActive())
+ updateMenuBarImmediately();
}
void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
@@ -147,8 +146,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
qWarning("Trying to remove a menu that does not belong to the menubar");
return;
}
+
+ NSMenuItem *item = nativeItemForMenu(menu);
+ if (menu->attachedItem() == item)
+ menu->setAttachedItem(nil);
m_menus.removeOne(menu);
- removeNativeMenu(menu);
+
+ QMacAutoReleasePool pool;
+
+ // See remark in insertMenu().
+ NSInteger nativeIndex = [m_nativeMenu indexOfItem:item];
+ [m_nativeMenu removeItemAtIndex:nativeIndex];
}
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
@@ -170,7 +178,16 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
break;
}
}
- [cocoaMenu->nsMenuItem() setHidden:shouldHide];
+
+ nativeItemForMenu(cocoaMenu).hidden = shouldHide;
+}
+
+NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const
+{
+ if (!menu)
+ return nil;
+
+ return [m_nativeMenu itemWithTag:reinterpret_cast<NSInteger>(menu)];
}
void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
@@ -297,24 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw;
#endif
bool disableForModal = mb->shouldDisable(cw);
- // force a sync?
- foreach (QCocoaMenu *m, mb->m_menus) {
- mb->syncMenu(m);
- m->syncModalState(disableForModal);
- }
- // reparent shared menu items if necessary.
- // We browse the list in reverse order to be sure that the next items are redrawn before the current ones,
- // in this way we are sure that "beforeMenu" (see below) is part of the native menu before "m" is redraw
- for (int i = mb->m_menus.size() - 1; i >= 0; i--) {
- QCocoaMenu *m = mb->m_menus.at(i);
- QCocoaMenuBar *menuBar = m->menuBar();
- if (menuBar != mb) {
- QCocoaMenu *beforeMenu = i < (mb->m_menus.size() - 1) ? mb->m_menus.at(i + 1) : 0;
- if (menuBar)
- menuBar->removeNativeMenu(m);
- mb->insertNativeMenu(m, beforeMenu);
- }
+ foreach (QCocoaMenu *menu, mb->m_menus) {
+ if (!menu)
+ continue;
+ NSMenuItem *item = mb->nativeItemForMenu(menu);
+ menu->setAttachedItem(item);
+ SET_COCOA_MENU_ANCESTOR(menu, mb);
+ // force a sync?
+ mb->syncMenu(menu);
+ menu->syncModalState(disableForModal);
}
QCocoaMenuLoader *loader = getMenuLoader();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 0d6f67959b..bba9ce3963 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -93,7 +93,6 @@ public:
inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; }
- void clearMenu(QCocoaMenu *menu);
MenuRole effectiveRole() const;
private:
@@ -105,7 +104,7 @@ private:
QString m_text;
bool m_textSynced;
QIcon m_icon;
- QCocoaMenu *m_menu;
+ QPointer<QCocoaMenu> m_menu;
bool m_isVisible;
bool m_enabled;
bool m_isSeparator;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 9e4f0b9ad1..de0271ce4d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -142,15 +142,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) {
if (COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
- if (m_menu->containingMenuItem() == this)
- m_menu->setContainingMenuItem(0);
}
QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this);
- m_menu->setContainingMenuItem(this);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
@@ -159,12 +156,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
}
}
-void QCocoaMenuItem::clearMenu(QCocoaMenu *menu)
-{
- if (menu == m_menu)
- m_menu = 0;
-}
-
void QCocoaMenuItem::setVisible(bool isVisible)
{
m_isVisible = isVisible;
@@ -226,14 +217,6 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native = nil;
}
- if (m_menu) {
- if (m_native != m_menu->nsMenuItem()) {
- [m_native release];
- m_native = [m_menu->nsMenuItem() retain];
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
- }
- }
-
if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil;
QCocoaMenuLoader *loader = getMenuLoader();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index eb65f7e061..b501358acc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -414,6 +414,7 @@ QCocoaWindow::~QCocoaWindow()
#endif
QMacAutoReleasePool pool;
+ [m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
if (m_isNSWindowChild) {
@@ -1004,7 +1005,15 @@ void QCocoaWindow::raise()
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
- [m_nsWindow orderFront: m_nsWindow];
+ {
+ // Clean up autoreleased temp objects from orderFront immediately.
+ // Failure to do so has been observed to cause leaks also beyond any outer
+ // autorelease pool (for example around a complete QWindow
+ // construct-show-raise-hide-delete cyle), counter to expected autoreleasepool
+ // behavior.
+ QMacAutoReleasePool pool;
+ [m_nsWindow orderFront: m_nsWindow];
+ }
static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS");
if (raiseProcess) {
ProcessSerialNumber psn;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 48de7d56f8..5b2370b69d 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -1253,7 +1253,12 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
{
QList<int> result;
- const KeyboardLayoutItem &kbItem = keyLayout[e->nativeVirtualKey()];
+
+ const quint32 nativeVirtualKey = e->nativeVirtualKey();
+ if (nativeVirtualKey > 255)
+ return result;
+
+ const KeyboardLayoutItem &kbItem = keyLayout[nativeVirtualKey];
if (!kbItem.exists)
return result;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 4c4d553b2d..47e68ae0af 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -39,8 +39,10 @@
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
#include "qwinrtcursor.h"
+#include "qwinrtwindow.h"
#include <private/qeventdispatcher_winrt_p.h>
+#include <QtCore/QLoggingCategory>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
@@ -469,6 +471,7 @@ QWinRTScreen::QWinRTScreen()
: d_ptr(new QWinRTScreenPrivate)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__;
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
@@ -553,6 +556,7 @@ QWinRTScreen::QWinRTScreen()
QWinRTScreen::~QWinRTScreen()
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this;
// Unregister callbacks
HRESULT hr;
@@ -631,6 +635,12 @@ QDpi QWinRTScreen::logicalDpi() const
return QDpi(d->logicalDpi, d->logicalDpi);
}
+qreal QWinRTScreen::pixelDensity() const
+{
+ Q_D(const QWinRTScreen);
+ return qRound(d->logicalDpi / 96);
+}
+
qreal QWinRTScreen::scaleFactor() const
{
Q_D(const QWinRTScreen);
@@ -697,6 +707,8 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const
void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window << visible;
+
const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask;
if (!window || (windowType != Qt::Window && windowType != Qt::Dialog))
return;
@@ -768,6 +780,7 @@ QWindow *QWinRTScreen::topWindow() const
void QWinRTScreen::addWindow(QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window;
if (window == topWindow())
return;
@@ -785,6 +798,7 @@ void QWinRTScreen::addWindow(QWindow *window)
void QWinRTScreen::removeWindow(QWindow *window)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window;
#ifdef Q_OS_WINPHONE
if (window->visibility() == QWindow::Minimized)
@@ -1131,6 +1145,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
d->logicalSize = QSizeF(size.Width, size.Height);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalSize;
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
@@ -1140,6 +1155,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__;
CoreWindowActivationState activationState;
args->get_WindowActivationState(&activationState);
@@ -1159,6 +1175,8 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
+
foreach (QWindow *w, QGuiApplication::topLevelWindows())
QWindowSystemInterface::handleCloseEvent(w);
return S_OK;
@@ -1170,6 +1188,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
boolean visible;
HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
RETURN_OK_IF_FAILED("Failed to get visibility.");
+ qCDebug(lcQpaWindows) << __FUNCTION__ << visible;
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
if (visible)
handleExpose();
@@ -1179,7 +1198,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
{
Q_D(QWinRTScreen);
-
+ qCDebug(lcQpaWindows) << __FUNCTION__;
DisplayOrientations displayOrientation;
HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation);
RETURN_OK_IF_FAILED("Failed to get current orientations.");
@@ -1187,7 +1206,8 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (d->orientation != newOrientation) {
d->orientation = newOrientation;
-#ifdef Q_OS_WINPHONE
+ qCDebug(lcQpaWindows) << " New orientation:" << newOrientation;
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
onSizeChanged(nullptr, nullptr);
#endif
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
@@ -1211,6 +1231,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
d->scaleFactor = qreal(resolutionScale) / 100;
#endif
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor;
+
RETURN_OK_IF_FAILED("Failed to get scale factor");
FLOAT dpi;
@@ -1225,6 +1247,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_RawDpiY(&dpi);
RETURN_OK_IF_FAILED("Failed to get y raw DPI.");
d->physicalDpi.second = dpi ? dpi : 96.0;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Logical DPI:" << d->logicalDpi
+ << "Physical DPI:" << d->physicalDpi;
return S_OK;
}
@@ -1232,12 +1256,14 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
#ifdef Q_OS_WINPHONE
HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr);
return S_OK;
}
HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *)
{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr);
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 0043b2cfa3..ac9db9bfef 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -93,6 +93,7 @@ public:
QImage::Format format() const Q_DECL_OVERRIDE;
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
qreal scaleFactor() const;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers keyboardModifiers() const;
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 9409de2406..ea20ef7a04 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -429,6 +429,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t enter;
enter.response_type = XCB_CLIENT_MESSAGE;
+ enter.sequence = 0;
enter.window = target;
enter.format = 32;
enter.type = atom(QXcbAtom::XdndEnter);
@@ -457,6 +458,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t move;
move.response_type = XCB_CLIENT_MESSAGE;
+ move.sequence = 0;
move.window = target;
move.format = 32;
move.type = atom(QXcbAtom::XdndPosition);
@@ -485,6 +487,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
xcb_client_message_event_t drop;
drop.response_type = XCB_CLIENT_MESSAGE;
+ drop.sequence = 0;
drop.window = current_target;
drop.format = 32;
drop.type = atom(QXcbAtom::XdndDrop);
@@ -746,6 +749,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
xcb_client_message_event_t response;
response.response_type = XCB_CLIENT_MESSAGE;
+ response.sequence = 0;
response.window = xdnd_dragsource;
response.format = 32;
response.type = atom(QXcbAtom::XdndStatus);
@@ -892,6 +896,7 @@ void QXcbDrag::send_leave()
xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE;
+ leave.sequence = 0;
leave.window = current_target;
leave.format = 32;
leave.type = atom(QXcbAtom::XdndLeave);
@@ -962,6 +967,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
xcb_client_message_event_t finished;
finished.response_type = XCB_CLIENT_MESSAGE;
+ finished.sequence = 0;
finished.window = xdnd_dragsource;
finished.format = 32;
finished.type = atom(QXcbAtom::XdndFinished);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 18b0667390..67a9b2f190 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -367,6 +367,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const
ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 8;
ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN);
+ ev.sequence = 0;
ev.window = rootWindow;
int sent = 0;
int length = message.length() + 1; // include NUL byte
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index cfed556ec9..5522af86de 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -100,9 +100,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne
void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
{
xcb_client_message_event_t trayRequest;
- memset(&trayRequest, 0, sizeof(trayRequest));
trayRequest.response_type = XCB_CLIENT_MESSAGE;
trayRequest.format = 32;
+ trayRequest.sequence = 0;
trayRequest.window = m_trayWindow;
trayRequest.type = m_trayAtom;
trayRequest.data.data32[0] = XCB_CURRENT_TIME;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 42e7d5da2c..13eecbfb4f 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1111,21 +1111,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
void QXcbWindow::setNetWmStates(NetWmStates states)
{
QVector<xcb_atom_t> atoms;
- if (states & NetWmStateAbove)
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
+ XCB_ATOM_ATOM, 0, 1024);
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
+ const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply));
+ atoms.resize(reply->value_len);
+ memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
+ }
+
+ free(reply);
+
+ if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
- if (states & NetWmStateBelow)
+ if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
- if (states & NetWmStateFullScreen)
+ if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
- if (states & NetWmStateMaximizedHorz)
+ if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
- if (states & NetWmStateMaximizedVert)
+ if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
- if (states & NetWmStateModal)
+ if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL));
- if (states & NetWmStateStaysOnTop)
+ if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
- if (states & NetWmStateDemandsAttention)
+ if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
if (atoms.isEmpty()) {
@@ -1245,6 +1261,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_WM_STATE);
event.data.data32[0] = set ? 1 : 0;
@@ -1286,6 +1303,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::WM_CHANGE_STATE);
event.data.data32[0] = XCB_WM_STATE_ICONIC;
@@ -1690,6 +1708,7 @@ void QXcbWindow::requestActivateWindow()
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
event.data.data32[0] = 1;
@@ -2636,6 +2655,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = moveResize;
+ xev.sequence = 0;
xev.window = xcb_window();
xev.format = 32;
const QPoint globalPos = window()->mapToGlobal(pos);
@@ -2664,6 +2684,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message,
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
+ event.sequence = 0;
event.window = window;
event.type = atom(QXcbAtom::_XEMBED);
event.data.data32[0] = connection()->time();