diff options
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/kernel.pri | 7 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 428 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication_qpa.cpp | 493 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget.cpp | 142 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget_p.h (renamed from src/widgets/kernel/qdesktopwidget_qpa_p.h) | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget_qpa.cpp | 193 | ||||
-rw-r--r-- | src/widgets/kernel/qgesturemanager.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qshortcut.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 1112 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_qpa.cpp | 1126 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore_p.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_p.h (renamed from src/widgets/kernel/qwidgetwindow_qpa_p.h) | 6 |
16 files changed, 1676 insertions, 1850 deletions
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 857fe4ac91..a9b8627beb 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -33,8 +33,8 @@ HEADERS += \ kernel/qstandardgestures_p.h \ kernel/qgesturerecognizer.h \ kernel/qgesturemanager_p.h \ - kernel/qdesktopwidget_qpa_p.h \ - kernel/qwidgetwindow_qpa_p.h \ + kernel/qdesktopwidget_p.h \ + kernel/qwidgetwindow_p.h \ kernel/qwindowcontainer_p.h SOURCES += \ @@ -60,9 +60,6 @@ SOURCES += \ kernel/qgesturemanager.cpp \ kernel/qdesktopwidget.cpp \ kernel/qwidgetsvariant.cpp \ - kernel/qapplication_qpa.cpp \ - kernel/qdesktopwidget_qpa.cpp \ - kernel/qwidget_qpa.cpp \ kernel/qwidgetwindow.cpp \ kernel/qwindowcontainer.cpp diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 520fc2db67..cac5e72f39 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -57,6 +57,7 @@ #include "qstyleoption.h" #include "qstylefactory.h" #include "qtextcodec.h" +#include "qtooltip.h" #include "qtranslator.h" #include "qvariant.h" #include "qwidget.h" @@ -67,7 +68,7 @@ #include "private/qstylesheetstyle_p.h" #include "private/qstyle_p.h" #include "qmessagebox.h" -#include "qwidgetwindow_qpa_p.h" +#include "qwidgetwindow_p.h" #include <QtWidgets/qgraphicsproxywidget.h> #include <QtGui/qstylehints.h> #include <QtGui/qinputmethod.h> @@ -77,6 +78,7 @@ #endif #include "private/qkeymapper_p.h" +#include "private/qaccessiblewidgetfactory_p.h" #include <qthread.h> #include <private/qthread_p.h> @@ -96,6 +98,10 @@ #include "qlibrary.h" #endif +#ifdef Q_OS_WIN +#include <QtCore/qt_windows.h> // for qt_win_display_dc() +#endif + #include "qdatetime.h" #ifdef Q_OS_WINCE @@ -187,6 +193,11 @@ QApplicationPrivate::~QApplicationPrivate() self = 0; } +void QApplicationPrivate::createEventDispatcher() +{ + QGuiApplicationPrivate::createEventDispatcher(); +} + /*! \class QApplication \brief The QApplication class manages the GUI application's control @@ -364,6 +375,14 @@ QApplicationPrivate::~QApplicationPrivate() Returns the top-level widget at the given \a point; returns 0 if there is no such widget. */ +QWidget *QApplication::topLevelAt(const QPoint &pos) +{ + if (const QWindow *window = QGuiApplication::topLevelAt(pos)) { + if (const QWidgetWindow *widgetWindow = qobject_cast<const QWidgetWindow *>(window)) + return widgetWindow->widget(); + } + return 0; +} /*! \fn QWidget *QApplication::topLevelAt(int x, int y) @@ -374,12 +393,6 @@ QApplicationPrivate::~QApplicationPrivate() 0 if there is no such widget. */ - -/* - The qt_init() and qt_cleanup() functions are implemented in the - qapplication_xyz.cpp file. -*/ - void qt_init(QApplicationPrivate *priv, int type ); void qt_init_tooltip_palette(); @@ -583,6 +596,11 @@ void QApplicationPrivate::construct() qt_gui_eval_init(application_type); #endif +#ifndef QT_NO_ACCESSIBILITY + // factory for accessible interfaces for widgets shipped with Qt + QAccessible::installFactory(&qAccessibleFactory); +#endif + #ifndef QT_NO_LIBRARY if(load_testability) { QLibrary testLib(QLatin1String("qttestability")); @@ -601,6 +619,26 @@ void QApplicationPrivate::construct() #endif } +void qt_init(QApplicationPrivate *priv, int type) +{ + Q_UNUSED(priv); + Q_UNUSED(type); + + QColormap::initialize(); + + qt_init_tooltip_palette(); + + QApplicationPrivate::initializeWidgetFontHash(); +} + +void qt_init_tooltip_palette() +{ +#ifndef QT_NO_TOOLTIP + if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) + QToolTip::setPalette(*toolTipPalette); +#endif +} + #ifndef QT_NO_STATEMACHINE void qRegisterGuiStateMachine(); void qUnregisterGuiStateMachine(); @@ -657,6 +695,91 @@ void QApplicationPrivate::initialize() is_app_running = true; // no longer starting up } +static void setPossiblePalette(const QPalette *palette, const char *className) +{ + if (palette == 0) + return; + QApplicationPrivate::setPalette_helper(*palette, className, false); +} + +void QApplicationPrivate::initializeWidgetPaletteHash() +{ + QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme(); + if (!platformTheme) + return; + qt_app_palettes_hash()->clear(); + + setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::CheckBoxPalette), "QCheckBox"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl"); + setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit"); +} + +void QApplicationPrivate::initializeWidgetFontHash() +{ + const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); + if (!theme) + return; + FontHash *fontHash = qt_app_fonts_hash(); + fontHash->clear(); + + if (const QFont *font = theme->font(QPlatformTheme::MenuFont)) + fontHash->insert(QByteArrayLiteral("QMenu"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont)) + fontHash->insert(QByteArrayLiteral("QMenuBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont)) + fontHash->insert(QByteArrayLiteral("QMenuItem"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont)) + fontHash->insert(QByteArrayLiteral("QMessageBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::LabelFont)) + fontHash->insert(QByteArrayLiteral("QLabel"), *font); + if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont)) + fontHash->insert(QByteArrayLiteral("QTipLabel"), *font); + if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont)) + fontHash->insert(QByteArrayLiteral("QTitleBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont)) + fontHash->insert(QByteArrayLiteral("QStatusBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont)) + fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font); + if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont)) + fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font); + if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont)) + fontHash->insert(QByteArrayLiteral("QPushButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::CheckBoxFont)) + fontHash->insert(QByteArrayLiteral("QCheckBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::RadioButtonFont)) + fontHash->insert(QByteArrayLiteral("QRadioButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont)) + fontHash->insert(QByteArrayLiteral("QToolButton"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont)) + fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ListViewFont)) + fontHash->insert(QByteArrayLiteral("QListViewFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont)) + fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont)) + fontHash->insert(QByteArrayLiteral("QListBox"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont)) + fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont)) + fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::SmallFont)) + fontHash->insert(QByteArrayLiteral("QSmallFont"), *font); + if (const QFont *font = theme->font(QPlatformTheme::MiniFont)) + fontHash->insert(QByteArrayLiteral("QMiniFont"), *font); +} + /***************************************************************************** Functions returning the active popup and modal widgets. *****************************************************************************/ @@ -780,6 +903,32 @@ QApplication::~QApplication() #endif } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +// #fixme: Remove. +static HDC displayDC = 0; // display device context + +Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC +{ + Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); + if (!displayDC) + displayDC = GetDC(0); + return displayDC; +} +#endif + +void qt_cleanup() +{ + QPixmapCache::clear(); + QColormap::cleanup(); + + QApplicationPrivate::active_window = 0; //### this should not be necessary +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + if (displayDC) { + ReleaseDC(0, displayDC); + displayDC = 0; + } +#endif +} /*! \fn QWidget *QApplication::widgetAt(const QPoint &point) @@ -2086,6 +2235,39 @@ void QApplication::setActiveWindow(QWidget* act) } } +QWidget *qt_tlw_for_window(QWindow *wnd) +{ + // QTBUG-32177, wnd might be a QQuickView embedded via window container. + while (wnd && !wnd->isTopLevel()) { + QWindow *parent = wnd->parent(); + // Don't end up in windows not belonging to this application + if (parent && parent->type() != Qt::ForeignWindow) + wnd = wnd->parent(); + else + break; + } + if (wnd) + foreach (QWidget *tlw, qApp->topLevelWidgets()) + if (tlw->windowHandle() == wnd) + return tlw; + return 0; +} + +void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) +{ + Q_UNUSED(previous); + QWindow *wnd = QGuiApplicationPrivate::focus_window; + if (inPopupMode()) // some delayed focus event to ignore + return; + QWidget *tlw = qt_tlw_for_window(wnd); + QApplication::setActiveWindow(tlw); + // QTBUG-37126, Active X controls may set the focus on native child widgets. + if (wnd && tlw && wnd != tlw->windowHandle()) { + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); + } +} + /*!internal * Helper function that returns the new focus widget, but does not set the focus reason. * Returns 0 if a new focus widget could not be found. @@ -2454,6 +2636,44 @@ bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop) return !isBlockedByModal(widget->window()); } +bool qt_try_modal(QWidget *widget, QEvent::Type type) +{ + QWidget * top = 0; + + if (QApplicationPrivate::tryModalHelper(widget, &top)) + return true; + + bool block_event = false; + + switch (type) { +#if 0 + case QEvent::Focus: + if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus) + break; + // drop through +#endif + case QEvent::MouseButtonPress: // disallow mouse/key events + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + block_event = true; + break; + default: + break; + } + + if (block_event && top && top->parentWidget() == 0) + top->raise(); + + return !block_event; +} + +bool QApplicationPrivate::modalState() +{ + return !self->modalWindowList.isEmpty(); +} + /* \internal */ @@ -3520,7 +3740,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) // deliver the event bool consumed = receiver->event(e); - e->spont = false; + QCoreApplicationPrivate::setEventSpontaneous(e, false); return consumed; } @@ -3529,6 +3749,123 @@ bool QApplicationPrivate::inPopupMode() return QApplicationPrivate::popupWidgets != 0; } +static void ungrabKeyboardForPopup(QWidget *popup) +{ + if (QWidget::keyboardGrabber()) + qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true); + else + qt_widget_private(popup)->stealKeyboardGrab(false); +} + +static void ungrabMouseForPopup(QWidget *popup) +{ + if (QWidget::mouseGrabber()) + qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true); + else + qt_widget_private(popup)->stealMouseGrab(false); +} + +static bool popupGrabOk; + +static void grabForPopup(QWidget *popup) +{ + Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); + popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true); + if (popupGrabOk) { + popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true); + if (!popupGrabOk) { + // transfer grab back to the keyboard grabber if any + ungrabKeyboardForPopup(popup); + } + } +} + +extern QWidget *qt_button_down; +extern QWidget *qt_popup_down; +extern bool qt_replay_popup_mouse_event; + +void QApplicationPrivate::closePopup(QWidget *popup) +{ + if (!popupWidgets) + return; + popupWidgets->removeAll(popup); + + if (popup == qt_popup_down) { + qt_button_down = 0; + qt_popup_down = 0; + } + + if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup + delete QApplicationPrivate::popupWidgets; + QApplicationPrivate::popupWidgets = 0; + + if (popupGrabOk) { + popupGrabOk = false; + + if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX, + QGuiApplicationPrivate::mousePressY)) + || popup->testAttribute(Qt::WA_NoMouseReplay)) { + // mouse release event or inside + qt_replay_popup_mouse_event = false; + } else { // mouse press event + qt_replay_popup_mouse_event = true; + } + + // transfer grab back to mouse grabber if any, otherwise release the grab + ungrabMouseForPopup(popup); + + // transfer grab back to keyboard grabber if any, otherwise release the grab + ungrabKeyboardForPopup(popup); + } + + if (active_window) { + if (QWidget *fw = active_window->focusWidget()) { + if (fw != QApplication::focusWidget()) { + fw->setFocus(Qt::PopupFocusReason); + } else { + QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); + QCoreApplication::sendEvent(fw, &e); + } + } + } + + } else { + // A popup was closed, so the previous popup gets the focus. + QWidget* aw = QApplicationPrivate::popupWidgets->last(); + if (QWidget *fw = aw->focusWidget()) + fw->setFocus(Qt::PopupFocusReason); + + if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard + grabForPopup(aw); + } + +} + +int openPopupCount = 0; + +void QApplicationPrivate::openPopup(QWidget *popup) +{ + openPopupCount++; + if (!popupWidgets) // create list + popupWidgets = new QWidgetList; + popupWidgets->append(popup); // add to end of list + + if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard + grabForPopup(popup); + + // popups are not focus-handled by the window system (the first + // popup grabbed the keyboard), so we have to do that manually: A + // new popup gets the focus + if (popup->focusWidget()) { + popup->focusWidget()->setFocus(Qt::PopupFocusReason); + } else if (popupWidgets->count() == 1) { // this was the first popup + if (QWidget *fw = QApplication::focusWidget()) { + QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); + QApplication::sendEvent(fw, &e); + } + } +} + #ifdef QT_KEYPAD_NAVIGATION /*! Sets the kind of focus navigation Qt should use to \a mode. @@ -3633,6 +3970,18 @@ bool QApplication::keypadNavigationEnabled() window must not be hidden (i.e. not have hide() called on it, but be visible in some sort of way) in order for this to work. */ +void QApplication::alert(QWidget *widget, int duration) +{ + if (widget) { + if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized)) + return; + if (QWindow *window= QApplicationPrivate::windowForWidget(widget)) + window->alert(duration); + } else { + foreach (QWidget *topLevel, topLevelWidgets()) + QApplication::alert(topLevel, duration); + } +} /*! \property QApplication::cursorFlashTime @@ -3723,6 +4072,38 @@ int QApplication::keyboardInputInterval() By default, this property has a value of 3. */ +#ifndef QT_NO_WHEELEVENT +int QApplication::wheelScrollLines() +{ + return QApplicationPrivate::wheel_scroll_lines; +} + +void QApplication::setWheelScrollLines(int lines) +{ + QApplicationPrivate::wheel_scroll_lines = lines; +} +#endif + +static inline int uiEffectToFlag(Qt::UIEffect effect) +{ + switch (effect) { + case Qt::UI_General: + return QPlatformTheme::GeneralUiEffect; + case Qt::UI_AnimateMenu: + return QPlatformTheme::AnimateMenuUiEffect; + case Qt::UI_FadeMenu: + return QPlatformTheme::FadeMenuUiEffect; + case Qt::UI_AnimateCombo: + return QPlatformTheme::AnimateComboUiEffect; + case Qt::UI_AnimateTooltip: + return QPlatformTheme::AnimateTooltipUiEffect; + case Qt::UI_FadeTooltip: + return QPlatformTheme::FadeTooltipUiEffect; + case Qt::UI_AnimateToolBox: + return QPlatformTheme::AnimateToolBoxUiEffect; + } + return 0; +} /*! \fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) @@ -3735,6 +4116,19 @@ int QApplication::keyboardInputInterval() \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware() */ +void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) +{ + int effectFlags = uiEffectToFlag(effect); + if (enable) { + if (effectFlags & QPlatformTheme::FadeMenuUiEffect) + effectFlags |= QPlatformTheme::AnimateMenuUiEffect; + if (effectFlags & QPlatformTheme::FadeTooltipUiEffect) + effectFlags |= QPlatformTheme::AnimateTooltipUiEffect; + QApplicationPrivate::enabledAnimations |= effectFlags; + } else { + QApplicationPrivate::enabledAnimations &= ~effectFlags; + } +} /*! \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect) @@ -3749,6 +4143,12 @@ int QApplication::keyboardInputInterval() \sa setEffectEnabled(), Qt::UIEffect */ +bool QApplication::isEffectEnabled(Qt::UIEffect effect) +{ + return QColormap::instance().depth() >= 16 + && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect) + && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect)); +} /*! \fn void QApplication::beep() @@ -3756,6 +4156,10 @@ int QApplication::keyboardInputInterval() Sounds the bell, using the default volume and sound. The function is \e not available in Qt for Embedded Linux. */ +void QApplication::beep() +{ + QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep"); +} /*! \macro qApp @@ -3868,11 +4272,19 @@ void QApplicationPrivate::initializeMultitouch() initializeMultitouch_sys(); } +void QApplicationPrivate::initializeMultitouch_sys() +{ +} + void QApplicationPrivate::cleanupMultitouch() { cleanupMultitouch_sys(); } +void QApplicationPrivate::cleanupMultitouch_sys() +{ +} + QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos) { int closestTouchPointId = -1; diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index e72fe29bdb..08a450ab32 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -228,7 +228,6 @@ private: friend class QWidget; friend class QWidgetPrivate; friend class QWidgetWindow; - friend class QETWidget; friend class QTranslator; friend class QWidgetAnimator; #ifndef QT_NO_SHORTCUT diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp deleted file mode 100644 index 5893c52e1b..0000000000 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qapplication_p.h" -#include "qcolormap.h" -#include "qpalette.h" -#include "qpixmapcache.h" -#ifndef QT_NO_CURSOR -#include "private/qcursor_p.h" -#endif -#include "qscreen.h" - -#include "private/qwidget_p.h" -#include "private/qevent_p.h" - -#include <qpa/qplatformintegrationfactory_p.h> -#include <qdesktopwidget.h> -#include <qpa/qplatformcursor.h> -#include <qpa/qplatformtheme.h> -#include <qpa/qplatformwindow.h> - -#include <qdebug.h> -#include <qpa/qwindowsysteminterface.h> -#include <qpa/qwindowsysteminterface_p.h> -#include <qpa/qplatformintegration.h> - -#include "qdesktopwidget_qpa_p.h" -#include "qwidgetwindow_qpa_p.h" -#include "qtooltip.h" - -#ifdef Q_OS_WIN -# include <QtCore/qt_windows.h> // for qt_win_display_dc() -#endif - -QT_BEGIN_NAMESPACE - -static QString appFont; -static bool popupGrabOk; -extern QWidget *qt_button_down; -extern QWidget *qt_popup_down; -extern bool qt_replay_popup_mouse_event; -int openPopupCount = 0; -extern QPointer<QWidget> qt_last_mouse_receiver; - -void QApplicationPrivate::createEventDispatcher() -{ - QGuiApplicationPrivate::createEventDispatcher(); -} - -bool qt_try_modal(QWidget *widget, QEvent::Type type) -{ - QWidget * top = 0; - - if (QApplicationPrivate::tryModalHelper(widget, &top)) - return true; - - bool block_event = false; - - switch (type) { -#if 0 - case QEvent::Focus: - if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus) - break; - // drop through -#endif - case QEvent::MouseButtonPress: // disallow mouse/key events - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: - case QEvent::KeyPress: - case QEvent::KeyRelease: - block_event = true; - break; - default: - break; - } - - if (block_event && top && top->parentWidget() == 0) - top->raise(); - - return !block_event; -} - -bool QApplicationPrivate::modalState() -{ - return !self->modalWindowList.isEmpty(); -} - -QWidget *qt_tlw_for_window(QWindow *wnd) -{ - // QTBUG-32177, wnd might be a QQuickView embedded via window container. - while (wnd && !wnd->isTopLevel()) { - QWindow *parent = wnd->parent(); - // Don't end up in windows not belonging to this application - if (parent && parent->type() != Qt::ForeignWindow) - wnd = wnd->parent(); - else - break; - } - if (wnd) - foreach (QWidget *tlw, qApp->topLevelWidgets()) - if (tlw->windowHandle() == wnd) - return tlw; - return 0; -} - -void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) -{ - Q_UNUSED(previous); - QWindow *wnd = QGuiApplicationPrivate::focus_window; - if (inPopupMode()) // some delayed focus event to ignore - return; - QWidget *tlw = qt_tlw_for_window(wnd); - QApplication::setActiveWindow(tlw); -} - -static void ungrabKeyboardForPopup(QWidget *popup) -{ - if (QWidget::keyboardGrabber()) - qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true); - else - qt_widget_private(popup)->stealKeyboardGrab(false); -} - -static void ungrabMouseForPopup(QWidget *popup) -{ - if (QWidget::mouseGrabber()) - qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true); - else - qt_widget_private(popup)->stealMouseGrab(false); -} - -static void grabForPopup(QWidget *popup) -{ - Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); - popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true); - if (popupGrabOk) { - popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true); - if (!popupGrabOk) { - // transfer grab back to the keyboard grabber if any - ungrabKeyboardForPopup(popup); - } - } -} - -void QApplicationPrivate::closePopup(QWidget *popup) -{ - if (!popupWidgets) - return; - popupWidgets->removeAll(popup); - - if (popup == qt_popup_down) { - qt_button_down = 0; - qt_popup_down = 0; - } - - if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup - delete QApplicationPrivate::popupWidgets; - QApplicationPrivate::popupWidgets = 0; - - if (popupGrabOk) { - popupGrabOk = false; - - if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX, - QGuiApplicationPrivate::mousePressY)) - || popup->testAttribute(Qt::WA_NoMouseReplay)) { - // mouse release event or inside - qt_replay_popup_mouse_event = false; - } else { // mouse press event - qt_replay_popup_mouse_event = true; - } - - // transfer grab back to mouse grabber if any, otherwise release the grab - ungrabMouseForPopup(popup); - - // transfer grab back to keyboard grabber if any, otherwise release the grab - ungrabKeyboardForPopup(popup); - } - - if (active_window) { - if (QWidget *fw = active_window->focusWidget()) { - if (fw != QApplication::focusWidget()) { - fw->setFocus(Qt::PopupFocusReason); - } else { - QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); - QCoreApplication::sendEvent(fw, &e); - } - } - } - - } else { - // A popup was closed, so the previous popup gets the focus. - QWidget* aw = QApplicationPrivate::popupWidgets->last(); - if (QWidget *fw = aw->focusWidget()) - fw->setFocus(Qt::PopupFocusReason); - - if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard - grabForPopup(aw); - } - -} - -void QApplicationPrivate::openPopup(QWidget *popup) -{ - openPopupCount++; - if (!popupWidgets) // create list - popupWidgets = new QWidgetList; - popupWidgets->append(popup); // add to end of list - - if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard - grabForPopup(popup); - - // popups are not focus-handled by the window system (the first - // popup grabbed the keyboard), so we have to do that manually: A - // new popup gets the focus - if (popup->focusWidget()) { - popup->focusWidget()->setFocus(Qt::PopupFocusReason); - } else if (popupWidgets->count() == 1) { // this was the first popup - if (QWidget *fw = QApplication::focusWidget()) { - QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); - QApplication::sendEvent(fw, &e); - } - } -} - -void QApplicationPrivate::initializeMultitouch_sys() -{ -} - -void QApplicationPrivate::cleanupMultitouch_sys() -{ -} - -static void setPossiblePalette(const QPalette *palette, const char *className) -{ - if (palette == 0) - return; - QApplicationPrivate::setPalette_helper(*palette, className, false); -} - - -void QApplicationPrivate::initializeWidgetPaletteHash() -{ - QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme(); - if (!platformTheme) - return; - qt_app_palettes_hash()->clear(); - - setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::CheckBoxPalette), "QCheckBox"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl"); - setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit"); -} - -void QApplicationPrivate::initializeWidgetFontHash() -{ - const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); - if (!theme) - return; - FontHash *fontHash = qt_app_fonts_hash(); - fontHash->clear(); - - if (const QFont *font = theme->font(QPlatformTheme::MenuFont)) - fontHash->insert(QByteArrayLiteral("QMenu"), *font); - if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont)) - fontHash->insert(QByteArrayLiteral("QMenuBar"), *font); - if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont)) - fontHash->insert(QByteArrayLiteral("QMenuItem"), *font); - if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont)) - fontHash->insert(QByteArrayLiteral("QMessageBox"), *font); - if (const QFont *font = theme->font(QPlatformTheme::LabelFont)) - fontHash->insert(QByteArrayLiteral("QLabel"), *font); - if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont)) - fontHash->insert(QByteArrayLiteral("QTipLabel"), *font); - if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont)) - fontHash->insert(QByteArrayLiteral("QTitleBar"), *font); - if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont)) - fontHash->insert(QByteArrayLiteral("QStatusBar"), *font); - if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont)) - fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font); - if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont)) - fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font); - if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont)) - fontHash->insert(QByteArrayLiteral("QPushButton"), *font); - if (const QFont *font = theme->font(QPlatformTheme::CheckBoxFont)) - fontHash->insert(QByteArrayLiteral("QCheckBox"), *font); - if (const QFont *font = theme->font(QPlatformTheme::RadioButtonFont)) - fontHash->insert(QByteArrayLiteral("QRadioButton"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont)) - fontHash->insert(QByteArrayLiteral("QToolButton"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont)) - fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ListViewFont)) - fontHash->insert(QByteArrayLiteral("QListViewFont"), *font); - if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont)) - fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont)) - fontHash->insert(QByteArrayLiteral("QListBox"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont)) - fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font); - if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont)) - fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font); - if (const QFont *font = theme->font(QPlatformTheme::SmallFont)) - fontHash->insert(QByteArrayLiteral("QSmallFont"), *font); - if (const QFont *font = theme->font(QPlatformTheme::MiniFont)) - fontHash->insert(QByteArrayLiteral("QMiniFont"), *font); -} - -#ifndef QT_NO_WHEELEVENT -void QApplication::setWheelScrollLines(int lines) -{ - QApplicationPrivate::wheel_scroll_lines = lines; -} - -int QApplication::wheelScrollLines() -{ - return QApplicationPrivate::wheel_scroll_lines; -} -#endif - -static inline int uiEffectToFlag(Qt::UIEffect effect) -{ - switch (effect) { - case Qt::UI_General: - return QPlatformTheme::GeneralUiEffect; - case Qt::UI_AnimateMenu: - return QPlatformTheme::AnimateMenuUiEffect; - case Qt::UI_FadeMenu: - return QPlatformTheme::FadeMenuUiEffect; - case Qt::UI_AnimateCombo: - return QPlatformTheme::AnimateComboUiEffect; - case Qt::UI_AnimateTooltip: - return QPlatformTheme::AnimateTooltipUiEffect; - case Qt::UI_FadeTooltip: - return QPlatformTheme::FadeTooltipUiEffect; - case Qt::UI_AnimateToolBox: - return QPlatformTheme::AnimateToolBoxUiEffect; - } - return 0; -} - -void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) -{ - int effectFlags = uiEffectToFlag(effect); - if (enable) { - if (effectFlags & QPlatformTheme::FadeMenuUiEffect) - effectFlags |= QPlatformTheme::AnimateMenuUiEffect; - if (effectFlags & QPlatformTheme::FadeTooltipUiEffect) - effectFlags |= QPlatformTheme::AnimateTooltipUiEffect; - QApplicationPrivate::enabledAnimations |= effectFlags; - } else { - QApplicationPrivate::enabledAnimations &= ~effectFlags; - } -} - -bool QApplication::isEffectEnabled(Qt::UIEffect effect) -{ - return QColormap::instance().depth() >= 16 - && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect) - && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect)); -} - -QWidget *QApplication::topLevelAt(const QPoint &pos) -{ - QList<QScreen *> screens = QGuiApplication::screens(); - QList<QScreen *>::const_iterator screen = screens.constBegin(); - QList<QScreen *>::const_iterator end = screens.constEnd(); - - while (screen != end) { - if ((*screen)->geometry().contains(pos)) { - QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos)); - return w ? w->widget() : 0; - } - ++screen; - } - return 0; -} - -void QApplication::beep() -{ - QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep"); -} - -void QApplication::alert(QWidget *widget, int duration) -{ - if (widget) { - if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized)) - return; - if (QWindow *window= QApplicationPrivate::windowForWidget(widget)) - window->alert(duration); - } else { - foreach (QWidget *topLevel, topLevelWidgets()) - QApplication::alert(topLevel, duration); - } -} - -void qt_init_tooltip_palette() -{ -#ifndef QT_NO_TOOLTIP - if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) - QToolTip::setPalette(*toolTipPalette); -#endif -} - -void qt_init(QApplicationPrivate *priv, int type) -{ - Q_UNUSED(priv); - Q_UNUSED(type); - - QColormap::initialize(); - - qt_init_tooltip_palette(); - - QApplicationPrivate::initializeWidgetFontHash(); -} - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) -// #fixme: Remove. -static HDC displayDC = 0; // display device context - -Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC -{ - Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); - if (!displayDC) - displayDC = GetDC(0); - return displayDC; -} -#endif - -void qt_cleanup() -{ - QPixmapCache::clear(); - QColormap::cleanup(); - - QApplicationPrivate::active_window = 0; //### this should not be necessary -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - if (displayDC) { - ReleaseDC(0, displayDC); - displayDC = 0; - } -#endif -} - - -QT_END_NAMESPACE diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 649978a912..3975e423a0 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -41,6 +41,8 @@ #include "qglobal.h" #include "qdesktopwidget.h" +#include "qdesktopwidget_p.h" +#include "qscreen.h" #include "qwidget_p.h" QT_BEGIN_NAMESPACE @@ -72,5 +74,145 @@ const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const return rect; } +void QDesktopWidgetPrivate::_q_updateScreens() +{ + Q_Q(QDesktopWidget); + const QList<QScreen *> screenList = QGuiApplication::screens(); + const int targetLength = screenList.length(); + const int oldLength = screens.length(); + int currentLength = oldLength; + + // Add or remove screen widgets as necessary + if(currentLength > targetLength) { + QDesktopScreenWidget *screen; + while (currentLength-- > targetLength) { + screen = screens.takeLast(); + delete screen; + } + } + else if (currentLength < targetLength) { + while (currentLength < targetLength) { + QScreen *qScreen = screenList.at(currentLength); + QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength++); + screenWidget->setGeometry(qScreen->geometry()); + QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + QObject::connect(qScreen, SIGNAL(destroyed()), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + screens.append(screenWidget); + } + } + + QRegion virtualGeometry; + + // update the geometry of each screen widget, determine virtual geometry + // and emit change signals afterwards. + QList<int> changedScreens; + for (int i = 0; i < screens.length(); i++) { + const QRect screenGeometry = screenList.at(i)->geometry(); + if (screenGeometry != screens.at(i)->geometry()) { + screens.at(i)->setGeometry(screenGeometry); + changedScreens.push_back(i); + } + virtualGeometry += screenGeometry; + } + + q->setGeometry(virtualGeometry.boundingRect()); + + if (oldLength != targetLength) + emit q->screenCountChanged(targetLength); + + foreach (int changedScreen, changedScreens) { + emit q->resized(changedScreen); + emit q->workAreaResized(changedScreen); + } +} + +QDesktopWidget::QDesktopWidget() + : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop) +{ + Q_D(QDesktopWidget); + setObjectName(QLatin1String("desktop")); + d->_q_updateScreens(); + connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens())); +} + +QDesktopWidget::~QDesktopWidget() +{ +} + +bool QDesktopWidget::isVirtualDesktop() const +{ + return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1; +} + +int QDesktopWidget::primaryScreen() const +{ + return 0; +} + +int QDesktopWidget::numScreens() const +{ + return qMax(QGuiApplication::screens().size(), 1); +} + +QWidget *QDesktopWidget::screen(int screen) +{ + Q_D(QDesktopWidget); + if (screen < 0 || screen >= d->screens.length()) + return d->screens.at(0); + return d->screens.at(screen); +} + +const QRect QDesktopWidget::availableGeometry(int screenNo) const +{ + QList<QScreen *> screens = QGuiApplication::screens(); + if (screenNo == -1) + screenNo = 0; + if (screenNo < 0 || screenNo >= screens.size()) + return QRect(); + else + return screens.at(screenNo)->availableGeometry(); +} + +const QRect QDesktopWidget::screenGeometry(int screenNo) const +{ + QList<QScreen *> screens = QGuiApplication::screens(); + if (screenNo == -1) + screenNo = 0; + if (screenNo < 0 || screenNo >= screens.size()) + return QRect(); + else + return screens.at(screenNo)->geometry(); +} + +int QDesktopWidget::screenNumber(const QWidget *w) const +{ + if (!w) + return 0; + + QRect frame = w->frameGeometry(); + if (!w->isWindow()) + frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); + const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2; + return screenNumber(midpoint); +} + +int QDesktopWidget::screenNumber(const QPoint &p) const +{ + QList<QScreen *> screens = QGuiApplication::screens(); + + for (int i = 0; i < screens.size(); ++i) + if (screens.at(i)->geometry().contains(p)) + return i; + + return primaryScreen(); //even better would be closest screen +} + +void QDesktopWidget::resizeEvent(QResizeEvent *) +{ +} + QT_END_NAMESPACE +#include "moc_qdesktopwidget.cpp" diff --git a/src/widgets/kernel/qdesktopwidget_qpa_p.h b/src/widgets/kernel/qdesktopwidget_p.h index f461869f1b..160807cf23 100644 --- a/src/widgets/kernel/qdesktopwidget_qpa_p.h +++ b/src/widgets/kernel/qdesktopwidget_p.h @@ -50,8 +50,8 @@ // We mean it. // -#ifndef QDESKTOPWIDGET_QPA_P_H -#define QDESKTOPWIDGET_QPA_P_H +#ifndef QDESKTOPWIDGET_P_H +#define QDESKTOPWIDGET_P_H #include "QDesktopWidget" #include "private/qwidget_p.h" diff --git a/src/widgets/kernel/qdesktopwidget_qpa.cpp b/src/widgets/kernel/qdesktopwidget_qpa.cpp deleted file mode 100644 index 015573dfbe..0000000000 --- a/src/widgets/kernel/qdesktopwidget_qpa.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdesktopwidget.h" -#include "qscreen.h" -#include "private/qapplication_p.h" -#include <QWidget> -#include "private/qwidget_p.h" -#include "private/qdesktopwidget_qpa_p.h" -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -void QDesktopWidgetPrivate::_q_updateScreens() -{ - Q_Q(QDesktopWidget); - const QList<QScreen *> screenList = QGuiApplication::screens(); - const int targetLength = screenList.length(); - const int oldLength = screens.length(); - int currentLength = oldLength; - - // Add or remove screen widgets as necessary - if(currentLength > targetLength) { - QDesktopScreenWidget *screen; - while (currentLength-- > targetLength) { - screen = screens.takeLast(); - delete screen; - } - } - else if (currentLength < targetLength) { - while (currentLength < targetLength) { - QScreen *qScreen = screenList.at(currentLength); - QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget(currentLength++); - screenWidget->setGeometry(qScreen->geometry()); - QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - QObject::connect(qScreen, SIGNAL(destroyed()), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - screens.append(screenWidget); - } - } - - QRegion virtualGeometry; - - // update the geometry of each screen widget, determine virtual geometry - // and emit change signals afterwards. - QList<int> changedScreens; - for (int i = 0; i < screens.length(); i++) { - const QRect screenGeometry = screenList.at(i)->geometry(); - if (screenGeometry != screens.at(i)->geometry()) { - screens.at(i)->setGeometry(screenGeometry); - changedScreens.push_back(i); - } - virtualGeometry += screenGeometry; - } - - q->setGeometry(virtualGeometry.boundingRect()); - - if (oldLength != targetLength) - emit q->screenCountChanged(targetLength); - - foreach (int changedScreen, changedScreens) { - emit q->resized(changedScreen); - emit q->workAreaResized(changedScreen); - } -} - -QDesktopWidget::QDesktopWidget() - : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop) -{ - Q_D(QDesktopWidget); - setObjectName(QLatin1String("desktop")); - d->_q_updateScreens(); - connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens())); -} - -QDesktopWidget::~QDesktopWidget() -{ -} - -bool QDesktopWidget::isVirtualDesktop() const -{ - return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1; -} - -int QDesktopWidget::primaryScreen() const -{ - return 0; -} - -int QDesktopWidget::numScreens() const -{ - return qMax(QGuiApplication::screens().size(), 1); -} - -QWidget *QDesktopWidget::screen(int screen) -{ - Q_D(QDesktopWidget); - if (screen < 0 || screen >= d->screens.length()) - return d->screens.at(0); - return d->screens.at(screen); -} - -const QRect QDesktopWidget::availableGeometry(int screenNo) const -{ - QList<QScreen *> screens = QGuiApplication::screens(); - if (screenNo == -1) - screenNo = 0; - if (screenNo < 0 || screenNo >= screens.size()) - return QRect(); - else - return screens.at(screenNo)->availableGeometry(); -} - -const QRect QDesktopWidget::screenGeometry(int screenNo) const -{ - QList<QScreen *> screens = QGuiApplication::screens(); - if (screenNo == -1) - screenNo = 0; - if (screenNo < 0 || screenNo >= screens.size()) - return QRect(); - else - return screens.at(screenNo)->geometry(); -} - -int QDesktopWidget::screenNumber(const QWidget *w) const -{ - if (!w) - return 0; - - QRect frame = w->frameGeometry(); - if (!w->isWindow()) - frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); - const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2; - return screenNumber(midpoint); -} - -int QDesktopWidget::screenNumber(const QPoint &p) const -{ - QList<QScreen *> screens = QGuiApplication::screens(); - - for (int i = 0; i < screens.size(); ++i) - if (screens.at(i)->geometry().contains(p)) - return i; - - return primaryScreen(); //even better would be closest screen -} - -void QDesktopWidget::resizeEvent(QResizeEvent *) -{ -} - -QT_END_NAMESPACE - -#include "moc_qdesktopwidget.cpp" diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 929e5e2fcf..532cea1f67 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -46,7 +46,7 @@ #include "private/qgraphicsitem_p.h" #include "private/qevent_p.h" #include "private/qapplication_p.h" -#include "private/qwidgetwindow_qpa_p.h" +#include "private/qwidgetwindow_p.h" #include "qgesture.h" #include "qevent.h" #include "qgraphicsitem.h" diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index dcf6aed591..217f0386cb 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -51,7 +51,7 @@ #include <private/qapplication_p.h> #include <private/qshortcutmap_p.h> #include <private/qaction_p.h> -#include <private/qwidgetwindow_qpa_p.h> +#include <private/qwidgetwindow_p.h> QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 7396808442..e692a985eb 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -69,7 +69,7 @@ # include <private/qmainwindowlayout_p.h> #endif #include <qpa/qplatformwindow.h> -#include "private/qwidgetwindow_qpa_p.h" +#include "private/qwidgetwindow_p.h" #include "qpainter.h" #include "qtooltip.h" #include "qwhatsthis.h" @@ -357,6 +357,13 @@ void QWidgetPrivate::scrollChildren(int dx, int dy) } } +void QWidgetPrivate::setWSGeometry() +{ + Q_Q(QWidget); + if (QWindow *window = q->windowHandle()) + window->setGeometry(data.crect); +} + void QWidgetPrivate::updateWidgetTransform(QEvent *event) { Q_Q(QWidget); @@ -1065,7 +1072,11 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) // interpret WindowSystemMenuHint as a close button and we can't change that behavior // we can't just add this in. #ifndef Q_WS_MAC - if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) { + if ((flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) +# ifdef Q_OS_WIN + && type != Qt::Dialog // QTBUG-2027, allow for menu-less dialogs. +# endif + ) { flags |= Qt::WindowSystemMenuHint; #else if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint @@ -1348,6 +1359,155 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) d->updateFrameStrut(); } +void q_createNativeChildrenAndSetParent(const QWidget *parentWidget) +{ + QObjectList children = parentWidget->children(); + for (int i = 0; i < children.size(); i++) { + if (children.at(i)->isWidgetType()) { + const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i)); + if (childWidget) { // should not be necessary + if (childWidget->testAttribute(Qt::WA_NativeWindow)) { + if (!childWidget->internalWinId()) + childWidget->winId(); + if (childWidget->windowHandle()) { + QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle(); + if (childWidget->isWindow()) + childWidget->windowHandle()->setTransientParent(parentWindow); + else + childWidget->windowHandle()->setParent(parentWindow); + } + } else { + q_createNativeChildrenAndSetParent(childWidget); + } + } + } + } + +} + +void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) +{ + Q_Q(QWidget); + + Q_UNUSED(window); + Q_UNUSED(initializeWindow); + Q_UNUSED(destroyOldWindow); + + Qt::WindowFlags flags = data.window_flags; + + if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) + return; // we only care about real toplevels + + QWindow *win = topData()->window; + // topData() ensures the extra is created but does not ensure 'window' is non-null + // in case the extra was already valid. + if (!win) { + createTLSysExtra(); + win = topData()->window; + } + + foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) { + if (!qstrncmp(propertyName, "_q_platform_", 12)) + win->setProperty(propertyName, q->property(propertyName)); + } + +#ifdef Q_OS_OSX + if (q->testAttribute(Qt::WA_ShowWithoutActivating)) + win->setProperty("_q_showWithoutActivating", QVariant(true)); +#endif + win->setFlags(data.window_flags); + fixPosIncludesFrame(); + if (q->testAttribute(Qt::WA_Moved) + || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) + win->setGeometry(q->geometry()); + else + win->resize(q->size()); + if (win->isTopLevel()) + win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0)); + + QSurfaceFormat format = win->requestedFormat(); + if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface + && q->testAttribute(Qt::WA_TranslucentBackground)) { + format.setAlphaBufferSize(8); + } + win->setFormat(format); + + if (QWidget *nativeParent = q->nativeParentWidget()) { + if (nativeParent->windowHandle()) { + if (flags & Qt::Window) { + win->setTransientParent(nativeParent->window()->windowHandle()); + win->setParent(0); + } else { + win->setTransientParent(0); + win->setParent(nativeParent->windowHandle()); + } + } + } + + qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ? + QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive; + win->create(); + // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. + if ((flags & Qt::Desktop) == Qt::Window) + win->handle()->setFrameStrutEventsEnabled(true); + + data.window_flags = win->flags(); + + QBackingStore *store = q->backingStore(); + + if (!store) { + if (win && q->windowType() != Qt::Desktop) { + if (q->isTopLevel()) + q->setBackingStore(new QBackingStore(win)); + } else { + q->setAttribute(Qt::WA_PaintOnScreen, true); + } + } + + setWindowModified_helper(); + WId id = win->winId(); + // See the QPlatformWindow::winId() documentation + Q_ASSERT(id != WId(0)); + setWinId(id); + + // Check children and create windows for them if necessary + q_createNativeChildrenAndSetParent(q); + + if (extra && !extra->mask.isEmpty()) + setMask_sys(extra->mask); + + // If widget is already shown, set window visible, too + if (q->isVisible()) + win->setVisible(true); +} + +#ifdef Q_OS_WIN +static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle"; +#endif + +void QWidgetPrivate::createTLSysExtra() +{ + Q_Q(QWidget); + if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) { + extra->topextra->window = new QWidgetWindow(q); + if (extra->minw || extra->minh) + extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh)); + if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX) + extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh)); + if (extra->topextra->opacity != 255 && q->isWindow()) + extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255)); +#ifdef Q_OS_WIN + // Pass on native parent handle for Widget embedded into Active X. + const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty); + if (activeXNativeParentHandle.isValid()) + extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle); + if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget")) + extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true)); +#endif + } + +} + /*! Destroys the widget. @@ -1612,6 +1772,9 @@ void QWidgetPrivate::createExtra() } } +void QWidgetPrivate::createSysExtra() +{ +} /*! \internal @@ -1642,6 +1805,46 @@ void QWidgetPrivate::deleteExtra() } } +void QWidgetPrivate::deleteSysExtra() +{ +} + +void QWidgetPrivate::deleteTLSysExtra() +{ + if (extra && extra->topextra) { + //the qplatformbackingstore may hold a reference to the window, so the backingstore + //needs to be deleted first. If the backingstore holds GL resources, we need to + // make the context current here, since the platform bs does not have a reference + // to the widget. + +#ifndef QT_NO_OPENGL + if (textureChildSeen && extra->topextra->shareContext) + extra->topextra->shareContext->makeCurrent(extra->topextra->window); +#endif + extra->topextra->backingStoreTracker.destroy(); + delete extra->topextra->backingStore; + extra->topextra->backingStore = 0; +#ifndef QT_NO_OPENGL + if (textureChildSeen && extra->topextra->shareContext) + extra->topextra->shareContext->doneCurrent(); + delete extra->topextra->shareContext; + extra->topextra->shareContext = 0; +#endif + + //the toplevel might have a context with a "qglcontext associated with it. We need to + //delete the qglcontext before we delete the qplatformopenglcontext. + //One unfortunate thing about this is that we potentially create a glContext just to + //delete it straight afterwards. + if (extra->topextra->window) { + extra->topextra->window->destroy(); + } + setWinId(0); + delete extra->topextra->window; + extra->topextra->window = 0; + + } +} + /* Returns \c true if there are widgets above this which overlap with \a rect, which is in parent's coordinate system (same as crect). @@ -2364,6 +2567,27 @@ WId QWidget::effectiveWinId() const return 0; } +/*! + If this is a native widget, return the associated QWindow. + Otherwise return null. + + Native widgets include toplevel widgets, QGLWidget, and child widgets + on which winId() was called. + + \since 5.0 + + \sa winId() +*/ +QWindow *QWidget::windowHandle() const +{ + Q_D(const QWidget); + QTLWExtra *extra = d->maybeTopData(); + if (extra) + return extra->window; + + return 0; +} + #ifndef QT_NO_STYLE_STYLESHEET /*! @@ -2654,6 +2878,13 @@ void QWidget::setWindowModality(Qt::WindowModality windowModality) setAttribute(Qt::WA_SetWindowModality, true); } +void QWidgetPrivate::setModal_sys() +{ + Q_Q(QWidget); + if (q->windowHandle()) + q->windowHandle()->setModality(q->windowModality()); +} + /*! \fn bool QWidget::underMouse() const @@ -2747,6 +2978,17 @@ void QWidget::overrideWindowState(Qt::WindowStates newstate) QApplication::sendEvent(this, &e); } +Qt::WindowState effectiveState(Qt::WindowStates state) +{ + if (state & Qt::WindowMinimized) + return Qt::WindowMinimized; + else if (state & Qt::WindowFullScreen) + return Qt::WindowFullScreen; + else if (state & Qt::WindowMaximized) + return Qt::WindowMaximized; + return Qt::WindowNoState; +} + /*! \fn void QWidget::setWindowState(Qt::WindowStates windowState) @@ -2777,6 +3019,39 @@ void QWidget::overrideWindowState(Qt::WindowStates newstate) \sa Qt::WindowState, windowState() */ +void QWidget::setWindowState(Qt::WindowStates newstate) +{ + Q_D(QWidget); + Qt::WindowStates oldstate = windowState(); + if (oldstate == newstate) + return; + if (isWindow() && !testAttribute(Qt::WA_WState_Created)) + create(); + + data->window_state = newstate; + data->in_set_window_state = 1; + Qt::WindowState newEffectiveState = effectiveState(newstate); + Qt::WindowState oldEffectiveState = effectiveState(oldstate); + if (isWindow() && newEffectiveState != oldEffectiveState) { + // Ensure the initial size is valid, since we store it as normalGeometry below. + if (!testAttribute(Qt::WA_Resized) && !isVisible()) + adjustSize(); + + d->createTLExtra(); + if (oldEffectiveState == Qt::WindowNoState) + d->topData()->normalGeometry = geometry(); + + Q_ASSERT(windowHandle()); + windowHandle()->setWindowState(newEffectiveState); + } + data->in_set_window_state = 0; + + if (newstate & Qt::WindowActive) + activateWindow(); + + QWindowStateChangeEvent e(oldstate); + QApplication::sendEvent(this, &e); +} /*! \property QWidget::fullScreen @@ -3169,6 +3444,10 @@ void QWidget::setAcceptDrops(bool on) } +void QWidgetPrivate::registerDropSite(bool on) +{ + Q_UNUSED(on); +} /*! Disables widget input events if \a disable is true; otherwise @@ -3643,6 +3922,28 @@ bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh) return true; } +void QWidgetPrivate::setConstraints_sys() +{ + Q_Q(QWidget); + if (extra && q->windowHandle()) { + QWindow *win = q->windowHandle(); + QWindowPrivate *winp = qt_window_private(win); + + winp->minimumSize = QSize(extra->minw, extra->minh); + winp->maximumSize = QSize(extra->maxw, extra->maxh); + + if (extra->topextra) { + winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh); + winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch); + } + + if (winp->platformWindow) { + fixPosIncludesFrame(); + winp->platformWindow->propagateSizeHints(); + } + } +} + /*! \overload @@ -4293,6 +4594,10 @@ void QWidgetPrivate::setPalette_helper(const QPalette &palette) updateIsOpaque(); } +void QWidgetPrivate::updateSystemBackground() +{ +} + /*! \property QWidget::font \brief the font currently set for the widget @@ -4629,6 +4934,13 @@ void QWidget::setCursor(const QCursor &cursor) QApplication::sendEvent(this, &event); } +void QWidgetPrivate::setCursor_sys(const QCursor &cursor) +{ + Q_UNUSED(cursor); + Q_Q(QWidget); + qt_qpa_set_cursor(q, false); +} + void QWidget::unsetCursor() { Q_D(QWidget); @@ -4644,6 +4956,62 @@ void QWidget::unsetCursor() QApplication::sendEvent(this, &event); } +void QWidgetPrivate::unsetCursor_sys() +{ + Q_Q(QWidget); + qt_qpa_set_cursor(q, false); +} + +static inline void applyCursor(QWidget *w, QCursor c) +{ + if (QWindow *window = w->windowHandle()) + window->setCursor(c); +} + +static inline void unsetCursor(QWidget *w) +{ + if (QWindow *window = w->windowHandle()) + window->unsetCursor(); +} + +void qt_qpa_set_cursor(QWidget *w, bool force) +{ + if (!w->testAttribute(Qt::WA_WState_Created)) + return; + + static QPointer<QWidget> lastUnderMouse = 0; + if (force) { + lastUnderMouse = w; + } else if (lastUnderMouse) { + const WId lastWinId = lastUnderMouse->effectiveWinId(); + const WId winId = w->effectiveWinId(); + if (lastWinId && lastWinId == winId) + w = lastUnderMouse; + } else if (!w->internalWinId()) { + return; // The mouse is not under this widget, and it's not native, so don't change it. + } + + while (!w->internalWinId() && w->parentWidget() && !w->isWindow() + && !w->testAttribute(Qt::WA_SetCursor)) + w = w->parentWidget(); + + QWidget *nativeParent = w; + if (!w->internalWinId()) + nativeParent = w->nativeParentWidget(); + if (!nativeParent || !nativeParent->internalWinId()) + return; + + if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) { + if (w->isEnabled()) + applyCursor(nativeParent, w->cursor()); + else + // Enforce the windows behavior of clearing the cursor on + // disabled widgets. + unsetCursor(nativeParent); + } else { + unsetCursor(nativeParent); + } +} #endif /*! @@ -5148,9 +5516,17 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP if (renderToTexture) { // This widget renders into a texture which is composed later. We just need to // punch a hole in the backingstore, so the texture will be visible. +#ifndef QT_NO_OPENGL QPainter p(q); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(q->rect(), Qt::transparent); + + if (backingStore) { + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(q->rect(), Qt::transparent); + } else { + // We are not drawing to a backingstore: fall back to QImage + p.drawImage(q->rect(), grabFramebuffer()); + } +#endif } else { //actually send the paint event QPaintEvent e(toBePainted); @@ -5604,6 +5980,17 @@ void QWidgetPrivate::setWindowTitle_helper(const QString &title) setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q)); } +void QWidgetPrivate::setWindowTitle_sys(const QString &caption) +{ + Q_Q(QWidget); + if (!q->isWindow()) + return; + + if (QWindow *window = q->windowHandle()) + window->setTitle(caption); + +} + void QWidgetPrivate::setWindowIconText_helper(const QString &title) { Q_Q(QWidget); @@ -5611,6 +5998,11 @@ void QWidgetPrivate::setWindowIconText_helper(const QString &title) setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q)); } +void QWidgetPrivate::setWindowIconText_sys(const QString &iconText) +{ + Q_UNUSED(iconText); +} + /*! \fn void QWidget::windowIconTextChanged(const QString &iconText) @@ -5719,6 +6111,12 @@ void QWidget::setWindowIcon(const QIcon &icon) emit windowIconChanged(icon); } +void QWidgetPrivate::setWindowIcon_sys() +{ + Q_Q(QWidget); + if (QWindow *window = q->windowHandle()) + window->setIcon(q->windowIcon()); +} /*! \property QWidget::windowIconText @@ -5794,6 +6192,16 @@ void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath) #endif } +void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath) +{ + Q_Q(QWidget); + if (!q->isWindow()) + return; + + if (QWindow *window = q->windowHandle()) + window->setFilePath(filePath); +} + /*! Returns the window's role, or an empty string. @@ -6053,6 +6461,21 @@ void QWidget::setFocus(Qt::FocusReason reason) } } +void QWidgetPrivate::setFocus_sys() +{ + Q_Q(QWidget); + // Embedded native widget may have taken the focus; get it back to toplevel if that is the case + const QWidget *topLevel = q->window(); + if (topLevel->windowType() != Qt::Popup) { + if (QWindow *nativeWindow = q->window()->windowHandle()) { + if (nativeWindow != QGuiApplication::focusWindow() + && q->testAttribute(Qt::WA_WState_Created)) { + nativeWindow->requestActivate(); + } + } + } +} + // updates focus_child on parent widgets to point into this widget void QWidgetPrivate::updateFocusChild() { @@ -6554,6 +6977,31 @@ void QWidget::move(const QPoint &p) QWindowContainer::parentWasMoved(this); } +// move() was invoked with Qt::WA_WState_Created not set (frame geometry +// unknown), that is, crect has a position including the frame. +// If we can determine the frame strut, fix that and clear the flag. +void QWidgetPrivate::fixPosIncludesFrame() +{ + Q_Q(QWidget); + if (QTLWExtra *te = maybeTopData()) { + if (te->posIncludesFrame) { + // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for + // example, in QGraphicsProxyWidget). + if (q->testAttribute(Qt::WA_DontShowOnScreen)) { + te->posIncludesFrame = 0; + } else { + if (q->windowHandle()) { + updateFrameStrut(); + if (!q->data->fstrut_dirty) { + data.crect.translate(te->frameStrut.x(), te->frameStrut.y()); + te->posIncludesFrame = 0; + } + } // windowHandle() + } // !WA_DontShowOnScreen + } // posIncludesFrame + } // QTLWExtra +} + /*! \fn void QWidget::resize(int w, int h) \overload @@ -6595,6 +7043,110 @@ void QWidget::setGeometry(const QRect &r) QWindowContainer::parentWasMoved(this); } +void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) +{ + Q_Q(QWidget); + if (extra) { // any size restrictions? + w = qMin(w,extra->maxw); + h = qMin(h,extra->maxh); + w = qMax(w,extra->minw); + h = qMax(h,extra->minh); + } + + if (q->isWindow() && q->windowHandle()) { + QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); + if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) { + x = 0; + y = 0; + w = q->windowHandle()->width(); + h = q->windowHandle()->height(); + } + } + + QPoint oldp = q->geometry().topLeft(); + QSize olds = q->size(); + QRect r(x, y, w, h); + + bool isResize = olds != r.size(); + isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? + + + // We only care about stuff that changes the geometry, or may + // cause the window manager to change its state + if (r.size() == olds && oldp == r.topLeft()) + return; + + if (!data.in_set_window_state) { + q->data->window_state &= ~Qt::WindowMaximized; + q->data->window_state &= ~Qt::WindowFullScreen; + if (q->isWindow()) + topData()->normalGeometry = QRect(0, 0, -1, -1); + } + + QPoint oldPos = q->pos(); + data.crect = r; + + bool needsShow = false; + + if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { + q->setAttribute(Qt::WA_OutsideWSRange, true); + if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) + hide_sys(); + data.crect = QRect(x, y, w, h); + } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { + q->setAttribute(Qt::WA_OutsideWSRange, false); + needsShow = true; + } + + if (q->isVisible()) { + if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { + if (q->windowHandle()) { + if (q->isWindow()) { + q->windowHandle()->setGeometry(q->geometry()); + } else { + QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); + q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); + } + + if (needsShow) + show_sys(); + } + + if (!q->isWindow()) { + if (renderToTexture) { + QRegion updateRegion(q->geometry()); + updateRegion += QRect(oldPos, olds); + q->parentWidget()->d_func()->invalidateBuffer(updateRegion); + } else if (isMove && !isResize) { + moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); + } else { + invalidateBuffer_resizeHelper(oldPos, olds); + } + } + } + + // generate a move event for QWidgets without window handles. QWidgets with native + // window handles already receive a move event from + // QGuiApplicationPrivate::processGeometryChangeEvent. + if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) { + QMoveEvent e(q->pos(), oldPos); + QApplication::sendEvent(q, &e); + } + if (isResize) { + QResizeEvent e(r.size(), olds); + QApplication::sendEvent(q, &e); + if (q->windowHandle()) + q->update(); + } + } else { // not visible + if (isMove && q->pos() != oldPos) + q->setAttribute(Qt::WA_PendingMoveEvent, true); + if (isResize) + q->setAttribute(Qt::WA_PendingResizeEvent, true); + } + +} + /*! \since 4.2 Saves the current geometry and state for top-level widgets. @@ -7208,6 +7760,62 @@ void QWidgetPrivate::show_helper() data.in_show = false; // reset qws optimization } +void QWidgetPrivate::show_sys() +{ + Q_Q(QWidget); + + QWindow *window = q->windowHandle(); + + if (q->testAttribute(Qt::WA_DontShowOnScreen)) { + invalidateBuffer(q->rect()); + q->setAttribute(Qt::WA_Mapped); + if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { + // add our window to the modal window list + QGuiApplicationPrivate::showModalWindow(window); + } + return; + } + + if (renderToTexture && !q->isWindow()) + QApplication::postEvent(q->parentWidget(), new QUpdateLaterEvent(q->geometry())); + else + QApplication::postEvent(q, new QUpdateLaterEvent(q->rect())); + + if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow)) + return; + + if (window) { + if (q->isWindow()) + fixPosIncludesFrame(); + QRect geomRect = q->geometry(); + if (!q->isWindow()) { + QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint()); + geomRect.moveTopLeft(topLeftOfWindow); + } + const QRect windowRect = window->geometry(); + if (windowRect != geomRect) { + if (q->testAttribute(Qt::WA_Moved) + || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) + window->setGeometry(geomRect); + else + window->resize(geomRect.size()); + } + +#ifndef QT_NO_CURSOR + qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show +#endif + invalidateBuffer(q->rect()); + window->setVisible(true); + // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? + if (window->isTopLevel()) { + const QPoint crectTopLeft = q->data->crect.topLeft(); + const QPoint windowTopLeft = window->geometry().topLeft(); + if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft) + q->data->crect.moveTopLeft(windowTopLeft); + } + } +} + /*! Hides the widget. This function is equivalent to setVisible(false). @@ -7285,6 +7893,39 @@ void QWidgetPrivate::hide_helper() #endif } +void QWidgetPrivate::hide_sys() +{ + Q_Q(QWidget); + + QWindow *window = q->windowHandle(); + + if (q->testAttribute(Qt::WA_DontShowOnScreen)) { + q->setAttribute(Qt::WA_Mapped, false); + if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { + // remove our window from the modal window list + QGuiApplicationPrivate::hideModalWindow(window); + } + // do not return here, if window non-zero, we must hide it + } + + deactivateWidgetCleanup(); + + if (!q->isWindow()) { + QWidget *p = q->parentWidget(); + if (p &&p->isVisible()) { + if (renderToTexture) + p->d_func()->invalidateBuffer(q->geometry()); + else + invalidateBuffer(q->rect()); + } + } else { + invalidateBuffer(q->rect()); + } + + if (window) + window->setVisible(false); +} + /*! \fn bool QWidget::isHidden() const @@ -8213,6 +8854,7 @@ bool QWidget::event(QEvent *event) case QEvent::MacSizeChange: case QEvent::ContentsRectChange: case QEvent::ThemeChange: + case QEvent::ReadOnlyChange: changeEvent(event); break; @@ -8386,7 +9028,7 @@ bool QWidget::event(QEvent *event) QEvent::ModifiedChange, QEvent::MouseTrackingChange, QEvent::ParentChange, QEvent::WindowStateChange, QEvent::LanguageChange, QEvent::LocaleChange, - QEvent::LayoutDirectionChange. + QEvent::LayoutDirectionChange, QEvent::ReadOnlyChange. */ void QWidget::changeEvent(QEvent * event) @@ -9767,6 +10409,88 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) QWindowContainer::parentWasChanged(this); } +void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) +{ + Q_Q(QWidget); + + Qt::WindowFlags oldFlags = data.window_flags; + bool wasCreated = q->testAttribute(Qt::WA_WState_Created); + + int targetScreen = -1; + // Handle a request to move the widget to a particular screen + if (newparent && newparent->windowType() == Qt::Desktop) { + // make sure the widget is created on the same screen as the + // programmer specified desktop widget + + // get the desktop's screen number + targetScreen = newparent->window()->d_func()->topData()->screenIndex; + newparent = 0; + } + + setWinId(0); + + if (parent != newparent) { + QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function??? + if (q->windowHandle()) { + q->windowHandle()->setFlags(f); + QWidget *parentWithWindow = + newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0; + if (parentWithWindow) { + if (f & Qt::Window) { + q->windowHandle()->setTransientParent(parentWithWindow->windowHandle()); + q->windowHandle()->setParent(0); + } else { + q->windowHandle()->setTransientParent(0); + q->windowHandle()->setParent(parentWithWindow->windowHandle()); + } + } else { + q->windowHandle()->setTransientParent(0); + q->windowHandle()->setParent(0); + } + } + } + + if (!newparent) { + f |= Qt::Window; + if (targetScreen == -1) { + if (parent) + targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex; + } + } + + bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide); + + // Reparenting toplevel to child + if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) { + if (extra && extra->hasWindowContainer) + QWindowContainer::toplevelAboutToBeDestroyed(q); + q->destroy(); + } + + adjustFlags(f, q); + data.window_flags = f; + q->setAttribute(Qt::WA_WState_Created, false); + q->setAttribute(Qt::WA_WState_Visible, false); + q->setAttribute(Qt::WA_WState_Hidden, false); + + if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window))) + q->createWinId(); + + if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden) + q->setAttribute(Qt::WA_WState_Hidden); + q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); + + // move the window to the selected screen + if (!newparent && targetScreen != -1) { + if (maybeTopData()) + maybeTopData()->screenIndex = targetScreen; + // only if it is already created + if (q->testAttribute(Qt::WA_WState_Created)) { + q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0)); + } + } +} + /*! Scrolls the widget including its children \a dx pixels to the right and \a dy downward. Both \a dx and \a dy may be negative. @@ -9812,6 +10536,13 @@ void QWidget::scroll(int dx, int dy) d->scroll_sys(dx, dy); } +void QWidgetPrivate::scroll_sys(int dx, int dy) +{ + Q_Q(QWidget); + scrollChildren(dx, dy); + scrollRect(q->rect(), dx, dy); +} + /*! \overload @@ -9846,6 +10577,11 @@ void QWidget::scroll(int dx, int dy, const QRect &r) d->scroll_sys(dx, dy, r); } +void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) +{ + scrollRect(r, dx, dy); +} + /*! Repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden. @@ -10093,7 +10829,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) #ifdef Q_OS_WIN // ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release if (attribute == Qt::WA_PaintOnScreen && on && windowType() != Qt::Desktop && !inherits("QGLWidget")) { - // see qwidget_qpa.cpp, ::paintEngine for details + // see ::paintEngine for details paintEngine(); if (d->noPaintOnScreen) return; @@ -10417,6 +11153,13 @@ void QWidget::setWindowOpacity(qreal opacity) #endif } +void QWidgetPrivate::setWindowOpacity_sys(qreal level) +{ + Q_Q(QWidget); + if (q->windowHandle()) + q->windowHandle()->setOpacity(level); +} + /*! \property QWidget::windowModified \brief whether the document shown in the window has unsaved changes @@ -10586,12 +11329,21 @@ QString QWidget::whatsThis() const \brief the widget's name as seen by assistive technologies - This property is used by accessible clients to identify, find, or announce - the widget for accessible clients. + This is the primary name by which assistive technology such as screen readers + announce this widget. For most widgets setting this property is not required. + For example for QPushButton the button's text will be used. + + It is important to set this property when the widget does not provide any + text. For example a button that only contains an icon needs to set this + property to work with screen readers. + The name should be short and equivalent to the visual information conveyed + by the widget. + + This property has to be \l{Internationalization with Qt}{localized}. By default, this property contains an empty string. - \sa QAccessibleInterface::text() + \sa QWidget::accessibleDescription, QAccessibleInterface::text() */ void QWidget::setAccessibleName(const QString &name) { @@ -10612,9 +11364,16 @@ QString QWidget::accessibleName() const \brief the widget's description as seen by assistive technologies - By default, this property contains an empty string. + The accessible description of a widget should convey what a widget does. + While the \l accessibleName should be a short and consise string (e.g. \gui{Save}), + the description should give more context, such as \gui{Saves the current document}. - \sa QAccessibleInterface::text() + This property has to be \l{Internationalization with Qt}{localized}. + + By default, this property contains an empty string and Qt falls back + to using the tool tip to provide this information. + + \sa QWidget::accessibleName, QAccessibleInterface::text() */ void QWidget::setAccessibleDescription(const QString &description) { @@ -10774,6 +11533,19 @@ void QWidget::raise() QApplication::sendEvent(this, &e); } +void QWidgetPrivate::raise_sys() +{ + Q_Q(QWidget); + if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { + q->windowHandle()->raise(); + } else if (renderToTexture) { + if (QWidget *p = q->parentWidget()) { + setDirtyOpaqueRegion(); + p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + } + } +} + /*! Lowers the widget to the bottom of the parent widget's stack. @@ -10811,6 +11583,17 @@ void QWidget::lower() QApplication::sendEvent(this, &e); } +void QWidgetPrivate::lower_sys() +{ + Q_Q(QWidget); + if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { + Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); + q->windowHandle()->lower(); + } else if (QWidget *p = q->parentWidget()) { + setDirtyOpaqueRegion(); + p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + } +} /*! Places the widget under \a w in the parent widget's stack. @@ -10847,6 +11630,14 @@ void QWidget::stackUnder(QWidget* w) QApplication::sendEvent(this, &e); } +void QWidgetPrivate::stackUnder_sys(QWidget*) +{ + Q_Q(QWidget); + if (QWidget *p = q->parentWidget()) { + setDirtyOpaqueRegion(); + p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + } +} /*! \fn bool QWidget::isTopLevel() const @@ -10907,6 +11698,24 @@ QRect QWidgetPrivate::frameStrut() const return maybeTopData() ? maybeTopData()->frameStrut : QRect(); } +void QWidgetPrivate::updateFrameStrut() +{ + Q_Q(QWidget); + if (q->data->fstrut_dirty) { + if (QTLWExtra *te = maybeTopData()) { + if (te->window) { + if (const QPlatformWindow *pw = te->window->handle()) { + const QMargins margins = pw->frameMargins(); + if (!margins.isNull()) { + te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); + q->data->fstrut_dirty = false; + } + } + } + } + } +} + #ifdef QT_KEYPAD_NAVIGATION /*! \internal @@ -11243,6 +12052,50 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) This function is usually called from the QWidget destructor. */ +void QWidget::destroy(bool destroyWindow, bool destroySubWindows) +{ + Q_D(QWidget); + + d->aboutToDestroy(); + if (!isWindow() && parentWidget()) + parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); + d->deactivateWidgetCleanup(); + + if ((windowType() == Qt::Popup) && qApp) + qApp->d_func()->closePopup(this); + + if (this == QApplicationPrivate::active_window) + QApplication::setActiveWindow(0); + if (QWidget::mouseGrabber() == this) + releaseMouse(); + if (QWidget::keyboardGrabber() == this) + releaseKeyboard(); + + setAttribute(Qt::WA_WState_Created, false); + + if (windowType() != Qt::Desktop) { + if (destroySubWindows) { + QObjectList childList(children()); + for (int i = 0; i < childList.size(); i++) { + QWidget *widget = qobject_cast<QWidget *>(childList.at(i)); + if (widget && widget->testAttribute(Qt::WA_NativeWindow)) { + if (widget->windowHandle()) { + widget->destroy(); + } + } + } + } + if (destroyWindow) { + d->deleteTLSysExtra(); + } else { + if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) { + d->hide_sys(); + } + } + + d->setWinId(0); + } +} /*! \fn QPaintEngine *QWidget::paintEngine() const @@ -11254,6 +12107,30 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) function is called by Qt internally, and the default implementation may not always return a valid pointer. */ +QPaintEngine *QWidget::paintEngine() const +{ + qWarning("QWidget::paintEngine: Should no longer be called"); + +#ifdef Q_OS_WIN + // We set this bit which is checked in setAttribute for + // Qt::WA_PaintOnScreen. We do this to allow these two scenarios: + // + // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to + // Windows which would mean suddenly their widgets stop working. + // + // 2. Users set paint on screen and subclass paintEngine() to + // return 0, in which case we have a "hole" in the backingstore + // allowing use of GDI or DirectX directly. + // + // 1 is WRONG, but to minimize silent failures, we have set this + // bit to ignore the setAttribute call. 2. needs to be + // supported because its our only means of embedding native + // graphics stuff. + const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1; +#endif + + return 0; //##### @@@ +} /*! \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const @@ -11264,6 +12141,21 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa mapFromGlobal(), mapTo(), mapToParent() */ +QPoint QWidget::mapToGlobal(const QPoint &pos) const +{ + int x = pos.x(), y = pos.y(); + const QWidget *w = this; + while (w) { + QWindow *window = w->windowHandle(); + if (window && window->handle()) + return window->mapToGlobal(QPoint(x, y)); + + x += w->data->crect.x(); + y += w->data->crect.y(); + w = w->isWindow() ? 0 : w->parentWidget(); + } + return QPoint(x, y); +} /*! \fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const @@ -11273,6 +12165,75 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa mapToGlobal(), mapFrom(), mapFromParent() */ +QPoint QWidget::mapFromGlobal(const QPoint &pos) const +{ + int x = pos.x(), y = pos.y(); + const QWidget *w = this; + while (w) { + QWindow *window = w->windowHandle(); + if (window && window->handle()) + return window->mapFromGlobal(QPoint(x, y)); + + x -= w->data->crect.x(); + y -= w->data->crect.y(); + w = w->isWindow() ? 0 : w->parentWidget(); + } + return QPoint(x, y); +} + +QWidget *qt_pressGrab = 0; +QWidget *qt_mouseGrb = 0; +static bool mouseGrabWithCursor = false; +static QWidget *keyboardGrb = 0; + +static inline QWindow *grabberWindow(const QWidget *w) +{ + QWindow *window = w->windowHandle(); + if (!window) + if (const QWidget *nativeParent = w->nativeParentWidget()) + window = nativeParent->windowHandle(); + return window; +} + +#ifndef QT_NO_CURSOR +static void grabMouseForWidget(QWidget *widget, const QCursor *cursor = 0) +#else +static void grabMouseForWidget(QWidget *widget) +#endif +{ + if (qt_mouseGrb) + qt_mouseGrb->releaseMouse(); + + mouseGrabWithCursor = false; + if (QWindow *window = grabberWindow(widget)) { +#ifndef QT_NO_CURSOR + if (cursor) { + mouseGrabWithCursor = true; + QGuiApplication::setOverrideCursor(*cursor); + } +#endif // !QT_NO_CURSOR + window->setMouseGrabEnabled(true); + } + + qt_mouseGrb = widget; + qt_pressGrab = 0; +} + +static void releaseMouseGrabOfWidget(QWidget *widget) +{ + if (qt_mouseGrb == widget) { + if (QWindow *window = grabberWindow(widget)) { +#ifndef QT_NO_CURSOR + if (mouseGrabWithCursor) { + QGuiApplication::restoreOverrideCursor(); + mouseGrabWithCursor = false; + } +#endif // !QT_NO_CURSOR + window->setMouseGrabEnabled(false); + } + } + qt_mouseGrb = 0; +} /*! \fn void QWidget::grabMouse() @@ -11303,6 +12264,10 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa releaseMouse(), grabKeyboard(), releaseKeyboard() */ +void QWidget::grabMouse() +{ + grabMouseForWidget(this); +} /*! \fn void QWidget::grabMouse(const QCursor &cursor) @@ -11320,6 +12285,21 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor() */ +#ifndef QT_NO_CURSOR +void QWidget::grabMouse(const QCursor &cursor) +{ + grabMouseForWidget(this, &cursor); +} +#endif + +bool QWidgetPrivate::stealMouseGrab(bool grab) +{ + // This is like a combination of grab/releaseMouse() but with error checking + // and it has no effect on the result of mouseGrabber(). + Q_Q(QWidget); + QWindow *window = grabberWindow(q); + return window ? window->setMouseGrabEnabled(grab) : false; +} /*! \fn void QWidget::releaseMouse() @@ -11328,6 +12308,10 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa grabMouse(), grabKeyboard(), releaseKeyboard() */ +void QWidget::releaseMouse() +{ + releaseMouseGrabOfWidget(this); +} /*! \fn void QWidget::grabKeyboard() @@ -11348,6 +12332,23 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa releaseKeyboard(), grabMouse(), releaseMouse(), focusWidget() */ +void QWidget::grabKeyboard() +{ + if (keyboardGrb) + keyboardGrb->releaseKeyboard(); + if (QWindow *window = grabberWindow(this)) + window->setKeyboardGrabEnabled(true); + keyboardGrb = this; +} + +bool QWidgetPrivate::stealKeyboardGrab(bool grab) +{ + // This is like a combination of grab/releaseKeyboard() but with error + // checking and it has no effect on the result of keyboardGrabber(). + Q_Q(QWidget); + QWindow *window = grabberWindow(q); + return window ? window->setKeyboardGrabEnabled(grab) : false; +} /*! \fn void QWidget::releaseKeyboard() @@ -11356,6 +12357,14 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa grabKeyboard(), grabMouse(), releaseMouse() */ +void QWidget::releaseKeyboard() +{ + if (keyboardGrb == this) { + if (QWindow *window = grabberWindow(this)) + window->setKeyboardGrabEnabled(false); + keyboardGrb = 0; + } +} /*! \fn QWidget *QWidget::mouseGrabber() @@ -11367,6 +12376,12 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa grabMouse(), keyboardGrabber() */ +QWidget *QWidget::mouseGrabber() +{ + if (qt_mouseGrb) + return qt_mouseGrb; + return qt_pressGrab; +} /*! \fn QWidget *QWidget::keyboardGrabber() @@ -11378,6 +12393,10 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa grabMouse(), mouseGrabber() */ +QWidget *QWidget::keyboardGrabber() +{ + return keyboardGrb; +} /*! \fn void QWidget::activateWindow() @@ -11403,6 +12422,13 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \sa isActiveWindow(), window(), show() */ +void QWidget::activateWindow() +{ + QWindow *const wnd = window()->windowHandle(); + + if (wnd) + wnd->requestActivate(); +} /*! \fn int QWidget::metric(PaintDeviceMetric m) const @@ -11412,6 +12438,62 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) \a m is the metric to get. */ +int QWidget::metric(PaintDeviceMetric m) const +{ + Q_D(const QWidget); + + QWindow *topLevelWindow = 0; + QScreen *screen = 0; + if (QWidget *topLevel = window()) + topLevelWindow = topLevel->windowHandle(); + + if (topLevelWindow) { + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); + if (platformScreen) + screen = platformScreen->screen(); + } + if (!screen && QGuiApplication::primaryScreen()) + screen = QGuiApplication::primaryScreen(); + + if (!screen) { + if (m == PdmDpiX || m == PdmDpiY) + return 72; + return QPaintDevice::metric(m); + } + int val; + if (m == PdmWidth) { + val = data->crect.width(); + } else if (m == PdmWidthMM) { + val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width(); + } else if (m == PdmHeight) { + val = data->crect.height(); + } else if (m == PdmHeightMM) { + val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height(); + } else if (m == PdmDepth) { + return screen->depth(); + } else if (m == PdmDpiX) { + if (d->extra && d->extra->customDpiX) + return d->extra->customDpiX; + else if (d->parent) + return static_cast<QWidget *>(d->parent)->metric(m); + return qRound(screen->logicalDotsPerInchX()); + } else if (m == PdmDpiY) { + if (d->extra && d->extra->customDpiY) + return d->extra->customDpiY; + else if (d->parent) + return static_cast<QWidget *>(d->parent)->metric(m); + return qRound(screen->logicalDotsPerInchY()); + } else if (m == PdmPhysicalDpiX) { + return qRound(screen->physicalDotsPerInchX()); + } else if (m == PdmPhysicalDpiY) { + return qRound(screen->physicalDotsPerInchY()); + } else if (m == PdmDevicePixelRatio) { + return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio(); + } else { + val = QPaintDevice::metric(m);// XXX + } + return val; +} /*! Initializes the \a painter pen, background and font to the same as @@ -11517,6 +12599,14 @@ void QWidget::setMask(const QRegion &newMask) #endif } +void QWidgetPrivate::setMask_sys(const QRegion ®ion) +{ + Q_Q(QWidget); + if (const QWindow *window = q->windowHandle()) + if (QPlatformWindow *platformWindow = window->handle()) + platformWindow->setMask(region); +} + /*! \fn void QWidget::setMask(const QBitmap &bitmap) diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 159011b824..9c22ad7c3d 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -694,7 +694,6 @@ private: friend class QPixmap; // for QPixmap::fill() friend class QFontMetrics; friend class QFontInfo; - friend class QETWidget; friend class QLayout; friend class QWidgetItem; friend class QWidgetItemV2; diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 9586d1a8c9..6520832943 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -627,7 +627,7 @@ public: #ifndef QT_NO_OPENGL virtual GLuint textureId() const { return 0; } - + virtual QImage grabFramebuffer() const { return QImage(); } void setRenderToTexture() { renderToTexture = true; setTextureChildSeen(); } void setTextureChildSeen() { @@ -732,7 +732,7 @@ public: // *************************** Platform specific ************************************ #if defined(Q_OS_WIN) - uint noPaintOnScreen : 1; // see qwidget_qpa.cpp ::paintEngine() + uint noPaintOnScreen : 1; // see qwidget.cpp ::paintEngine() #endif #if defined(Q_WS_X11) // <----------------------------------------------------------- X11 Qt::HANDLE picture; diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp deleted file mode 100644 index 5a4bd33672..0000000000 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ /dev/null @@ -1,1126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QtWidgets/qwidget.h" -#include "QtGui/qevent.h" -#include "QtWidgets/qapplication.h" -#include "private/qwidgetbackingstore_p.h" -#include "private/qwidget_p.h" -#include "private/qwidgetwindow_qpa_p.h" -#include "private/qapplication_p.h" -#include "QtWidgets/qdesktopwidget.h" -#include <qpa/qplatformwindow.h> -#include "QtGui/qsurfaceformat.h" -#include <QtGui/qopenglcontext.h> -#include <qpa/qplatformopenglcontext.h> -#include <qpa/qplatformintegration.h> -#include "QtGui/private/qwindow_p.h" -#include "QtGui/private/qguiapplication_p.h" -#include <private/qwindowcontainer_p.h> - -#include <qpa/qplatformcursor.h> -#include <QtGui/QGuiApplication> -#include <QtGui/QScreen> -#include <QtCore/QMargins> - -QT_BEGIN_NAMESPACE - -void q_createNativeChildrenAndSetParent(const QWidget *parentWidget) -{ - QObjectList children = parentWidget->children(); - for (int i = 0; i < children.size(); i++) { - if (children.at(i)->isWidgetType()) { - const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i)); - if (childWidget) { // should not be necessary - if (childWidget->testAttribute(Qt::WA_NativeWindow)) { - if (!childWidget->internalWinId()) - childWidget->winId(); - if (childWidget->windowHandle()) { - QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle(); - if (childWidget->isWindow()) - childWidget->windowHandle()->setTransientParent(parentWindow); - else - childWidget->windowHandle()->setParent(parentWindow); - } - } else { - q_createNativeChildrenAndSetParent(childWidget); - } - } - } - } - -} - -void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) -{ - Q_Q(QWidget); - - Q_UNUSED(window); - Q_UNUSED(initializeWindow); - Q_UNUSED(destroyOldWindow); - - Qt::WindowFlags flags = data.window_flags; - - if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) - return; // we only care about real toplevels - - QWindow *win = topData()->window; - // topData() ensures the extra is created but does not ensure 'window' is non-null - // in case the extra was already valid. - if (!win) { - createTLSysExtra(); - win = topData()->window; - } - - foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) { - if (!qstrncmp(propertyName, "_q_platform_", 12)) - win->setProperty(propertyName, q->property(propertyName)); - } - -#ifdef Q_OS_OSX - if (q->testAttribute(Qt::WA_ShowWithoutActivating)) - win->setProperty("_q_showWithoutActivating", QVariant(true)); -#endif - win->setFlags(data.window_flags); - fixPosIncludesFrame(); - if (q->testAttribute(Qt::WA_Moved) - || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) - win->setGeometry(q->geometry()); - else - win->resize(q->size()); - win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0)); - - QSurfaceFormat format = win->requestedFormat(); - if ((flags & Qt::Window) && win->surfaceType() != QSurface::OpenGLSurface - && q->testAttribute(Qt::WA_TranslucentBackground)) { - format.setAlphaBufferSize(8); - } - win->setFormat(format); - - if (QWidget *nativeParent = q->nativeParentWidget()) { - if (nativeParent->windowHandle()) { - if (flags & Qt::Window) { - win->setTransientParent(nativeParent->window()->windowHandle()); - win->setParent(0); - } else { - win->setTransientParent(0); - win->setParent(nativeParent->windowHandle()); - } - } - } - - qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ? - QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive; - win->create(); - // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. - if ((flags & Qt::Desktop) == Qt::Window) - win->handle()->setFrameStrutEventsEnabled(true); - - data.window_flags = win->flags(); - - QBackingStore *store = q->backingStore(); - - if (!store) { - if (win && q->windowType() != Qt::Desktop) { - if (q->isTopLevel()) - q->setBackingStore(new QBackingStore(win)); - } else { - q->setAttribute(Qt::WA_PaintOnScreen, true); - } - } - - setWindowModified_helper(); - WId id = win->winId(); - // See the QPlatformWindow::winId() documentation - Q_ASSERT(id != WId(0)); - setWinId(id); - - // Check children and create windows for them if necessary - q_createNativeChildrenAndSetParent(q); - - if (extra && !extra->mask.isEmpty()) - setMask_sys(extra->mask); - - // If widget is already shown, set window visible, too - if (q->isVisible()) - win->setVisible(true); -} - -void QWidget::destroy(bool destroyWindow, bool destroySubWindows) -{ - Q_D(QWidget); - - d->aboutToDestroy(); - if (!isWindow() && parentWidget()) - parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); - d->deactivateWidgetCleanup(); - - if ((windowType() == Qt::Popup) && qApp) - qApp->d_func()->closePopup(this); - - if (this == QApplicationPrivate::active_window) - QApplication::setActiveWindow(0); - if (QWidget::mouseGrabber() == this) - releaseMouse(); - if (QWidget::keyboardGrabber() == this) - releaseKeyboard(); - - setAttribute(Qt::WA_WState_Created, false); - - if (windowType() != Qt::Desktop) { - if (destroySubWindows) { - QObjectList childList(children()); - for (int i = 0; i < childList.size(); i++) { - QWidget *widget = qobject_cast<QWidget *>(childList.at(i)); - if (widget && widget->testAttribute(Qt::WA_NativeWindow)) { - if (widget->windowHandle()) { - widget->destroy(); - } - } - } - } - if (destroyWindow) { - d->deleteTLSysExtra(); - } else { - if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) { - d->hide_sys(); - } - } - - d->setWinId(0); - } -} - -void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) -{ - Q_Q(QWidget); - - Qt::WindowFlags oldFlags = data.window_flags; - bool wasCreated = q->testAttribute(Qt::WA_WState_Created); - - int targetScreen = -1; - // Handle a request to move the widget to a particular screen - if (newparent && newparent->windowType() == Qt::Desktop) { - // make sure the widget is created on the same screen as the - // programmer specified desktop widget - - // get the desktop's screen number - targetScreen = newparent->window()->d_func()->topData()->screenIndex; - newparent = 0; - } - - setWinId(0); - - if (parent != newparent) { - QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function??? - if (q->windowHandle()) { - q->windowHandle()->setFlags(f); - QWidget *parentWithWindow = - newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0; - if (parentWithWindow) { - if (f & Qt::Window) { - q->windowHandle()->setTransientParent(parentWithWindow->windowHandle()); - q->windowHandle()->setParent(0); - } else { - q->windowHandle()->setTransientParent(0); - q->windowHandle()->setParent(parentWithWindow->windowHandle()); - } - } else { - q->windowHandle()->setTransientParent(0); - q->windowHandle()->setParent(0); - } - } - } - - if (!newparent) { - f |= Qt::Window; - if (targetScreen == -1) { - if (parent) - targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex; - } - } - - bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide); - - // Reparenting toplevel to child - if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) { - if (extra && extra->hasWindowContainer) - QWindowContainer::toplevelAboutToBeDestroyed(q); - q->destroy(); - } - - adjustFlags(f, q); - data.window_flags = f; - q->setAttribute(Qt::WA_WState_Created, false); - q->setAttribute(Qt::WA_WState_Visible, false); - q->setAttribute(Qt::WA_WState_Hidden, false); - - if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window))) - q->createWinId(); - - if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden) - q->setAttribute(Qt::WA_WState_Hidden); - q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); - - // move the window to the selected screen - if (!newparent && targetScreen != -1) { - if (maybeTopData()) - maybeTopData()->screenIndex = targetScreen; - // only if it is already created - if (q->testAttribute(Qt::WA_WState_Created)) { - q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0)); - } - } -} - -QPoint QWidget::mapToGlobal(const QPoint &pos) const -{ - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && window->handle()) - return window->mapToGlobal(QPoint(x, y)); - - x += w->data->crect.x(); - y += w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); -} - -QPoint QWidget::mapFromGlobal(const QPoint &pos) const -{ - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && window->handle()) - return window->mapFromGlobal(QPoint(x, y)); - - x -= w->data->crect.x(); - y -= w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); -} - -void QWidgetPrivate::updateSystemBackground() {} - -#ifndef QT_NO_CURSOR -void QWidgetPrivate::setCursor_sys(const QCursor &cursor) -{ - Q_UNUSED(cursor); - Q_Q(QWidget); - qt_qpa_set_cursor(q, false); -} - -void QWidgetPrivate::unsetCursor_sys() -{ - Q_Q(QWidget); - qt_qpa_set_cursor(q, false); -} - -#endif //QT_NO_CURSOR - -void QWidgetPrivate::setWindowTitle_sys(const QString &caption) -{ - Q_Q(QWidget); - if (!q->isWindow()) - return; - - if (QWindow *window = q->windowHandle()) - window->setTitle(caption); - -} - -void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath) -{ - Q_Q(QWidget); - if (!q->isWindow()) - return; - - if (QWindow *window = q->windowHandle()) - window->setFilePath(filePath); -} - -void QWidgetPrivate::setWindowIcon_sys() -{ - Q_Q(QWidget); - if (QWindow *window = q->windowHandle()) - window->setIcon(q->windowIcon()); -} - -void QWidgetPrivate::setWindowIconText_sys(const QString &iconText) -{ - Q_UNUSED(iconText); -} - -QWidget *qt_pressGrab = 0; -QWidget *qt_mouseGrb = 0; -static QWidget *keyboardGrb = 0; - -static inline QWindow *grabberWindow(const QWidget *w) -{ - QWindow *window = w->windowHandle(); - if (!window) - if (const QWidget *nativeParent = w->nativeParentWidget()) - window = nativeParent->windowHandle(); - return window; -} - -void QWidget::grabMouse() -{ - if (qt_mouseGrb) - qt_mouseGrb->releaseMouse(); - - if (QWindow *window = grabberWindow(this)) - window->setMouseGrabEnabled(true); - - qt_mouseGrb = this; - qt_pressGrab = 0; -} - -#ifndef QT_NO_CURSOR -void QWidget::grabMouse(const QCursor &cursor) -{ - Q_UNUSED(cursor); - grabMouse(); -} -#endif - -bool QWidgetPrivate::stealMouseGrab(bool grab) -{ - // This is like a combination of grab/releaseMouse() but with error checking - // and it has no effect on the result of mouseGrabber(). - Q_Q(QWidget); - QWindow *window = grabberWindow(q); - return window ? window->setMouseGrabEnabled(grab) : false; -} - -void QWidget::releaseMouse() -{ - if (qt_mouseGrb == this) { - if (QWindow *window = grabberWindow(this)) - window->setMouseGrabEnabled(false); - qt_mouseGrb = 0; - } -} - -void QWidget::grabKeyboard() -{ - if (keyboardGrb) - keyboardGrb->releaseKeyboard(); - if (QWindow *window = grabberWindow(this)) - window->setKeyboardGrabEnabled(true); - keyboardGrb = this; -} - -bool QWidgetPrivate::stealKeyboardGrab(bool grab) -{ - // This is like a combination of grab/releaseKeyboard() but with error - // checking and it has no effect on the result of keyboardGrabber(). - Q_Q(QWidget); - QWindow *window = grabberWindow(q); - return window ? window->setKeyboardGrabEnabled(grab) : false; -} - -void QWidget::releaseKeyboard() -{ - if (keyboardGrb == this) { - if (QWindow *window = grabberWindow(this)) - window->setKeyboardGrabEnabled(false); - keyboardGrb = 0; - } -} - -QWidget *QWidget::mouseGrabber() -{ - if (qt_mouseGrb) - return qt_mouseGrb; - return qt_pressGrab; -} - -QWidget *QWidget::keyboardGrabber() -{ - return keyboardGrb; -} - -void QWidget::activateWindow() -{ - QWindow *const wnd = window()->windowHandle(); - - if (wnd) - wnd->requestActivate(); -} - -// move() was invoked with Qt::WA_WState_Created not set (frame geometry -// unknown), that is, crect has a position including the frame. -// If we can determine the frame strut, fix that and clear the flag. -void QWidgetPrivate::fixPosIncludesFrame() -{ - Q_Q(QWidget); - if (QTLWExtra *te = maybeTopData()) { - if (te->posIncludesFrame) { - // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for - // example, in QGraphicsProxyWidget). - if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - te->posIncludesFrame = 0; - } else { - if (q->windowHandle()) { - updateFrameStrut(); - if (!q->data->fstrut_dirty) { - data.crect.translate(te->frameStrut.x(), te->frameStrut.y()); - te->posIncludesFrame = 0; - } - } // windowHandle() - } // !WA_DontShowOnScreen - } // posIncludesFrame - } // QTLWExtra -} - -void QWidgetPrivate::show_sys() -{ - Q_Q(QWidget); - - QWindow *window = q->windowHandle(); - - if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); - q->setAttribute(Qt::WA_Mapped); - if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { - // add our window to the modal window list - QGuiApplicationPrivate::showModalWindow(window); - } - return; - } - - if (renderToTexture && !q->isWindow()) - QApplication::postEvent(q->parentWidget(), new QUpdateLaterEvent(q->geometry())); - else - QApplication::postEvent(q, new QUpdateLaterEvent(q->rect())); - - if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow)) - return; - - if (window) { - if (q->isWindow()) - fixPosIncludesFrame(); - QRect geomRect = q->geometry(); - if (!q->isWindow()) { - QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint()); - geomRect.moveTopLeft(topLeftOfWindow); - } - const QRect windowRect = window->geometry(); - if (windowRect != geomRect) { - if (q->testAttribute(Qt::WA_Moved) - || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) - window->setGeometry(geomRect); - else - window->resize(geomRect.size()); - } - -#ifndef QT_NO_CURSOR - qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show -#endif - invalidateBuffer(q->rect()); - window->setVisible(true); - // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? - if (window->isTopLevel()) { - const QPoint crectTopLeft = q->data->crect.topLeft(); - const QPoint windowTopLeft = window->geometry().topLeft(); - if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft) - q->data->crect.moveTopLeft(windowTopLeft); - } - } -} - - -void QWidgetPrivate::hide_sys() -{ - Q_Q(QWidget); - - QWindow *window = q->windowHandle(); - - if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - q->setAttribute(Qt::WA_Mapped, false); - if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { - // remove our window from the modal window list - QGuiApplicationPrivate::hideModalWindow(window); - } - // do not return here, if window non-zero, we must hide it - } - - deactivateWidgetCleanup(); - - if (!q->isWindow()) { - QWidget *p = q->parentWidget(); - if (p &&p->isVisible()) { - if (renderToTexture) - p->d_func()->invalidateBuffer(q->geometry()); - else - invalidateBuffer(q->rect()); - } - } else { - invalidateBuffer(q->rect()); - } - - if (window) - window->setVisible(false); -} - -Qt::WindowState effectiveState(Qt::WindowStates state) - { - if (state & Qt::WindowMinimized) - return Qt::WindowMinimized; - else if (state & Qt::WindowFullScreen) - return Qt::WindowFullScreen; - else if (state & Qt::WindowMaximized) - return Qt::WindowMaximized; - return Qt::WindowNoState; - } - -void QWidget::setWindowState(Qt::WindowStates newstate) -{ - Q_D(QWidget); - Qt::WindowStates oldstate = windowState(); - if (oldstate == newstate) - return; - if (isWindow() && !testAttribute(Qt::WA_WState_Created)) - create(); - - data->window_state = newstate; - data->in_set_window_state = 1; - Qt::WindowState newEffectiveState = effectiveState(newstate); - Qt::WindowState oldEffectiveState = effectiveState(oldstate); - if (isWindow() && newEffectiveState != oldEffectiveState) { - // Ensure the initial size is valid, since we store it as normalGeometry below. - if (!testAttribute(Qt::WA_Resized) && !isVisible()) - adjustSize(); - - d->createTLExtra(); - if (oldEffectiveState == Qt::WindowNoState) - d->topData()->normalGeometry = geometry(); - - Q_ASSERT(windowHandle()); - windowHandle()->setWindowState(newEffectiveState); - } - data->in_set_window_state = 0; - - if (newstate & Qt::WindowActive) - activateWindow(); - - QWindowStateChangeEvent e(oldstate); - QApplication::sendEvent(this, &e); -} - -void QWidgetPrivate::setFocus_sys() -{ - Q_Q(QWidget); - // Embedded native widget may have taken the focus; get it back to toplevel if that is the case - const QWidget *topLevel = q->window(); - if (topLevel->windowType() != Qt::Popup) { - if (QWindow *nativeWindow = q->window()->windowHandle()) { - if (nativeWindow != QGuiApplication::focusWindow() - && q->testAttribute(Qt::WA_WState_Created)) { - nativeWindow->requestActivate(); - } - } - } -} - -void QWidgetPrivate::raise_sys() -{ - Q_Q(QWidget); - if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { - q->windowHandle()->raise(); - } else if (renderToTexture) { - if (QWidget *p = q->parentWidget()) { - setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); - } - } -} - -void QWidgetPrivate::lower_sys() -{ - Q_Q(QWidget); - if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { - Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - q->windowHandle()->lower(); - } else if (QWidget *p = q->parentWidget()) { - setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); - } -} - -void QWidgetPrivate::stackUnder_sys(QWidget*) -{ - Q_Q(QWidget); - if (QWidget *p = q->parentWidget()) { - setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); - } -} - -void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) -{ - Q_Q(QWidget); - if (extra) { // any size restrictions? - w = qMin(w,extra->maxw); - h = qMin(h,extra->maxh); - w = qMax(w,extra->minw); - h = qMax(h,extra->minh); - } - - if (q->isWindow() && q->windowHandle()) { - QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); - if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) { - x = 0; - y = 0; - w = q->windowHandle()->width(); - h = q->windowHandle()->height(); - } - } - - QPoint oldp = q->geometry().topLeft(); - QSize olds = q->size(); - QRect r(x, y, w, h); - - bool isResize = olds != r.size(); - isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? - - - // We only care about stuff that changes the geometry, or may - // cause the window manager to change its state - if (r.size() == olds && oldp == r.topLeft()) - return; - - if (!data.in_set_window_state) { - q->data->window_state &= ~Qt::WindowMaximized; - q->data->window_state &= ~Qt::WindowFullScreen; - if (q->isWindow()) - topData()->normalGeometry = QRect(0, 0, -1, -1); - } - - QPoint oldPos = q->pos(); - data.crect = r; - - bool needsShow = false; - - if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { - q->setAttribute(Qt::WA_OutsideWSRange, true); - if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) - hide_sys(); - data.crect = QRect(x, y, w, h); - } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { - q->setAttribute(Qt::WA_OutsideWSRange, false); - needsShow = true; - } - - if (q->isVisible()) { - if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { - if (q->windowHandle()) { - if (q->isWindow()) { - q->windowHandle()->setGeometry(q->geometry()); - } else { - QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); - q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); - } - - if (needsShow) - show_sys(); - } - - if (!q->isWindow()) { - if (renderToTexture) { - QRegion updateRegion(q->geometry()); - updateRegion += QRect(oldPos, olds); - q->parentWidget()->d_func()->invalidateBuffer(updateRegion); - } else if (isMove && !isResize) { - moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); - } else { - invalidateBuffer_resizeHelper(oldPos, olds); - } - } - } - - // generate a move event for QWidgets without window handles. QWidgets with native - // window handles already receive a move event from - // QGuiApplicationPrivate::processGeometryChangeEvent. - if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) { - QMoveEvent e(q->pos(), oldPos); - QApplication::sendEvent(q, &e); - } - if (isResize) { - QResizeEvent e(r.size(), olds); - QApplication::sendEvent(q, &e); - if (q->windowHandle()) - q->update(); - } - } else { // not visible - if (isMove && q->pos() != oldPos) - q->setAttribute(Qt::WA_PendingMoveEvent, true); - if (isResize) - q->setAttribute(Qt::WA_PendingResizeEvent, true); - } - -} - -void QWidgetPrivate::setConstraints_sys() -{ - Q_Q(QWidget); - if (extra && q->windowHandle()) { - QWindow *win = q->windowHandle(); - QWindowPrivate *winp = qt_window_private(win); - - winp->minimumSize = QSize(extra->minw, extra->minh); - winp->maximumSize = QSize(extra->maxw, extra->maxh); - - if (extra->topextra) { - winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh); - winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch); - } - - if (winp->platformWindow) { - fixPosIncludesFrame(); - winp->platformWindow->propagateSizeHints(); - } - } -} - -void QWidgetPrivate::scroll_sys(int dx, int dy) -{ - Q_Q(QWidget); - scrollChildren(dx, dy); - scrollRect(q->rect(), dx, dy); -} - -void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) -{ - scrollRect(r, dx, dy); -} - -int QWidget::metric(PaintDeviceMetric m) const -{ - Q_D(const QWidget); - - QWindow *topLevelWindow = 0; - QScreen *screen = 0; - if (QWidget *topLevel = window()) - topLevelWindow = topLevel->windowHandle(); - - if (topLevelWindow) { - QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); - if (platformScreen) - screen = platformScreen->screen(); - } - if (!screen && QGuiApplication::primaryScreen()) - screen = QGuiApplication::primaryScreen(); - - if (!screen) { - if (m == PdmDpiX || m == PdmDpiY) - return 72; - return QPaintDevice::metric(m); - } - int val; - if (m == PdmWidth) { - val = data->crect.width(); - } else if (m == PdmWidthMM) { - val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width(); - } else if (m == PdmHeight) { - val = data->crect.height(); - } else if (m == PdmHeightMM) { - val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height(); - } else if (m == PdmDepth) { - return screen->depth(); - } else if (m == PdmDpiX) { - if (d->extra && d->extra->customDpiX) - return d->extra->customDpiX; - else if (d->parent) - return static_cast<QWidget *>(d->parent)->metric(m); - return qRound(screen->logicalDotsPerInchX()); - } else if (m == PdmDpiY) { - if (d->extra && d->extra->customDpiY) - return d->extra->customDpiY; - else if (d->parent) - return static_cast<QWidget *>(d->parent)->metric(m); - return qRound(screen->logicalDotsPerInchY()); - } else if (m == PdmPhysicalDpiX) { - return qRound(screen->physicalDotsPerInchX()); - } else if (m == PdmPhysicalDpiY) { - return qRound(screen->physicalDotsPerInchY()); - } else if (m == PdmDevicePixelRatio) { - return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio(); - } else { - val = QPaintDevice::metric(m);// XXX - } - return val; -} - -/*! - If this is a native widget, return the associated QWindow. - Otherwise return null. - - Native widgets include toplevel widgets, QGLWidget, and child widgets - on which winId() was called. - - \since 5.0 - - \sa winId() -*/ -QWindow *QWidget::windowHandle() const -{ - Q_D(const QWidget); - QTLWExtra *extra = d->maybeTopData(); - if (extra) - return extra->window; - - return 0; -} - -void QWidgetPrivate::createSysExtra() -{ -} - -void QWidgetPrivate::deleteSysExtra() -{ - -} - -#ifdef Q_OS_WIN -static const char activeXNativeParentHandleProperty[] = "_q_embedded_native_parent_handle"; -#endif - -void QWidgetPrivate::createTLSysExtra() -{ - Q_Q(QWidget); - if (!extra->topextra->window && (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())) { - extra->topextra->window = new QWidgetWindow(q); - if (extra->minw || extra->minh) - extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh)); - if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX) - extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh)); - if (extra->topextra->opacity != 255 && q->isWindow()) - extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255)); -#ifdef Q_OS_WIN - // Pass on native parent handle for Widget embedded into Active X. - const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty); - if (activeXNativeParentHandle.isValid()) - extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle); - if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget")) - extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true)); -#endif - } - -} - -void QWidgetPrivate::deleteTLSysExtra() -{ - if (extra && extra->topextra) { - //the qplatformbackingstore may hold a reference to the window, so the backingstore - //needs to be deleted first. If the backingstore holds GL resources, we need to - // make the context current here, since the platform bs does not have a reference - // to the widget. - -#ifndef QT_NO_OPENGL - if (textureChildSeen && extra->topextra->shareContext) - extra->topextra->shareContext->makeCurrent(extra->topextra->window); -#endif - extra->topextra->backingStoreTracker.destroy(); - delete extra->topextra->backingStore; - extra->topextra->backingStore = 0; -#ifndef QT_NO_OPENGL - if (textureChildSeen && extra->topextra->shareContext) - extra->topextra->shareContext->doneCurrent(); - delete extra->topextra->shareContext; - extra->topextra->shareContext = 0; -#endif - - //the toplevel might have a context with a "qglcontext associated with it. We need to - //delete the qglcontext before we delete the qplatformopenglcontext. - //One unfortunate thing about this is that we potentially create a glContext just to - //delete it straight afterwards. - if (extra->topextra->window) { - extra->topextra->window->destroy(); - } - setWinId(0); - delete extra->topextra->window; - extra->topextra->window = 0; - - } -} - -void QWidgetPrivate::registerDropSite(bool on) -{ - Q_UNUSED(on); -} - -void QWidgetPrivate::setMask_sys(const QRegion ®ion) -{ - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) { - qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName())); - return; - } - Q_Q(QWidget); - if (const QWindow *window = q->windowHandle()) - if (QPlatformWindow *platformWindow = window->handle()) - platformWindow->setMask(region); -} - -void QWidgetPrivate::updateFrameStrut() -{ - Q_Q(QWidget); - if (q->data->fstrut_dirty) { - if (QTLWExtra *te = maybeTopData()) { - if (te->window) { - if (const QPlatformWindow *pw = te->window->handle()) { - const QMargins margins = pw->frameMargins(); - if (!margins.isNull()) { - te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); - q->data->fstrut_dirty = false; - } - } - } - } - } -} - -void QWidgetPrivate::setWindowOpacity_sys(qreal level) -{ - Q_Q(QWidget); - if (q->windowHandle()) - q->windowHandle()->setOpacity(level); -} - -void QWidgetPrivate::setWSGeometry() -{ - Q_Q(QWidget); - if (QWindow *window = q->windowHandle()) - window->setGeometry(data.crect); -} - -QPaintEngine *QWidget::paintEngine() const -{ - qWarning("QWidget::paintEngine: Should no longer be called"); - -#ifdef Q_OS_WIN - // We set this bit which is checked in setAttribute for - // Qt::WA_PaintOnScreen. We do this to allow these two scenarios: - // - // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to - // Windows which would mean suddenly their widgets stop working. - // - // 2. Users set paint on screen and subclass paintEngine() to - // return 0, in which case we have a "hole" in the backingstore - // allowing use of GDI or DirectX directly. - // - // 1 is WRONG, but to minimize silent failures, we have set this - // bit to ignore the setAttribute call. 2. needs to be - // supported because its our only means of embedding native - // graphics stuff. - const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1; -#endif - - return 0; //##### @@@ -} - -void QWidgetPrivate::setModal_sys() -{ - Q_Q(QWidget); - if (q->windowHandle()) - q->windowHandle()->setModality(q->windowModality()); -} - -#ifndef QT_NO_CURSOR -static inline void applyCursor(QWidget *w, QCursor c) -{ - if (QWindow *window = w->windowHandle()) - window->setCursor(c); -} - -static inline void unsetCursor(QWidget *w) -{ - if (QWindow *window = w->windowHandle()) - window->unsetCursor(); -} - -void qt_qpa_set_cursor(QWidget *w, bool force) -{ - if (!w->testAttribute(Qt::WA_WState_Created)) - return; - - static QPointer<QWidget> lastUnderMouse = 0; - if (force) { - lastUnderMouse = w; - } else if (lastUnderMouse) { - const WId lastWinId = lastUnderMouse->effectiveWinId(); - const WId winId = w->effectiveWinId(); - if (lastWinId && lastWinId == winId) - w = lastUnderMouse; - } else if (!w->internalWinId()) { - return; // The mouse is not under this widget, and it's not native, so don't change it. - } - - while (!w->internalWinId() && w->parentWidget() && !w->isWindow() - && !w->testAttribute(Qt::WA_SetCursor)) - w = w->parentWidget(); - - QWidget *nativeParent = w; - if (!w->internalWinId()) - nativeParent = w->nativeParentWidget(); - if (!nativeParent || !nativeParent->internalWinId()) - return; - - if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) { - if (w->isEnabled()) - applyCursor(nativeParent, w->cursor()); - else - // Enforce the windows behavior of clearing the cursor on - // disabled widgets. - unsetCursor(nativeParent); - } else { - unsetCursor(nativeParent); - } -} -#endif //QT_NO_CURSOR - -QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 473e9deef4..88404ce205 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -294,7 +294,6 @@ private: friend QRegion qt_dirtyRegion(QWidget *); friend class QWidgetPrivate; friend class QWidget; - friend class QETWidget; friend class QBackingStore; }; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index fc328e7af0..9a7017503f 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "private/qwindow_p.h" -#include "qwidgetwindow_qpa_p.h" +#include "qwidgetwindow_p.h" #include "private/qwidget_p.h" #include "private/qapplication_p.h" @@ -443,7 +443,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec() const QPoint localPos = win->mapFromGlobal(event->globalPos()); QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers()); - e->spont = 1; + QCoreApplicationPrivate::setEventSpontaneous(e, true); QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event)); e->setTimestamp(event->timestamp()); QCoreApplication::postEvent(win, e); diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_p.h index 06ba8ea646..be2adddff5 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QWIDGETWINDOW_QPA_P_H -#define QWIDGETWINDOW_QPA_P_H +#ifndef QWIDGETWINDOW_P_H +#define QWIDGETWINDOW_P_H #include <QtGui/qwindow.h> @@ -122,4 +122,4 @@ private: QT_END_NAMESPACE -#endif // QWIDGETWINDOW_QPA_P_H +#endif // QWIDGETWINDOW_P_H |