diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 10 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenu.h | 13 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenu.mm | 78 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenubar.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenubar.mm | 115 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenuitem.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenuitem.mm | 17 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 11 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowskeymapper.cpp | 7 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 30 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 37 |
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 ®ion, 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 ®ion) 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(); |