From ad1bd1563f3f65d0f7b65687af2ade42f7f9f3d9 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 28 Mar 2012 15:26:17 +0200 Subject: Implement window modality in QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWindow already has windowModality() and setWindowModality() as part of its API from commit 516f4e283ba4626d7239630397ef867ab0366071. Platform plugins can use this already to setup modality hints on windows that they create, but it's not enough to implement modality fully. QGuiApplication gets a modalWindow() static method, which is similar to QApplication::activeModalWidget() in that it returns the last modal window to be shown. The modal window "stack" moves from QApplicationPrivate to QGuiApplicationPrivate. The enterModal*() and leaveModal*() functions in QApplicationPrivate are removed and replaced by QGuiApplicationPrivate::showModalWindow() and hideModalWindow(), which are called by QWindow::setVisible() just before calling QPlatformWindow::setVisible(). The virtual QGuiApplicationPrivate::isWindowBlocked() will tell us if a window is blocked by a modal window (and tell which modal window for any interested callers). The default implementation works on the QWindow level. QApplicationPrivate reimplements isWindowBlocked() and adds popup and WA_GroupLeader support. QGuiApplication uses the state set from isWindowBlocked() to block user-input events: mouse press, mouse move, mouse release, wheel, key presses, key releases, enter/leave events, close events, and touch begin, update, and end events. Note also that the modality helper functions in QtWidgets and QApplicationPrivate are left in place and working as they always have. The behavior of QWidget in the presence of modal windows/dialogs should not change. Change-Id: I2c89e6026d40160387787a6e009ae1fdc12dfd69 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll Reviewed-by: Samuel Rødal Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qapplication.cpp | 171 ++++++++++++++------------------ src/widgets/kernel/qapplication_p.h | 9 +- src/widgets/kernel/qapplication_qpa.cpp | 23 +---- src/widgets/kernel/qwidget.cpp | 23 +---- 4 files changed, 82 insertions(+), 144 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index a8b1fa6d1c..c560dba1b7 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -440,8 +440,6 @@ FontHash *qt_app_fonts_hash() QWidgetList *QApplicationPrivate::popupWidgets = 0; // has keyboard input focus QDesktopWidget *qt_desktopWidget = 0; // root window widgets -QWidgetList * qt_modal_stack = 0; // stack of modal widgets -bool app_do_modal = false; /*! \internal @@ -755,7 +753,8 @@ QWidget *QApplication::activePopupWidget() QWidget *QApplication::activeModalWidget() { - return qt_modal_stack && !qt_modal_stack->isEmpty() ? qt_modal_stack->first() : 0; + QWidgetWindow *widgetWindow = qobject_cast(modalWindow()); + return widgetWindow ? widgetWindow->widget() : 0; } /*! @@ -2315,31 +2314,52 @@ Q_WIDGETS_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop) bool QApplicationPrivate::isBlockedByModal(QWidget *widget) { widget = widget->window(); - if (!modalState()) + return self->isWindowBlocked(widget->windowHandle()); +} + +bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const +{ + QWindow *unused = 0; + if (!blockingWindow) + blockingWindow = &unused; + + if (modalWindowList.isEmpty()) { + *blockingWindow = 0; return false; - if (QApplication::activePopupWidget() == widget) + } + QWidget *popupWidget = QApplication::activePopupWidget(); + QWindow *popupWindow = popupWidget ? popupWidget->windowHandle() : 0; + if (popupWindow == window) { + *blockingWindow = 0; return false; + } - for (int i = 0; i < qt_modal_stack->size(); ++i) { - QWidget *modalWidget = qt_modal_stack->at(i); + for (int i = 0; i < modalWindowList.count(); ++i) { + QWindow *modalWindow = modalWindowList.at(i); { - // check if the active modal widget is our widget or a parent of our widget - QWidget *w = widget; + // check if the modal window is our window or a (transient) parent of our window + QWindow *w = window; while (w) { - if (w == modalWidget) + if (w == modalWindow) { + *blockingWindow = 0; return false; - w = w->parentWidget(); + } + QWindow *p = w->parent(); + if (!p) + p = w->transientParent(); + w = p; } } - Qt::WindowModality windowModality = modalWidget->windowModality(); + Qt::WindowModality windowModality = modalWindow->windowModality(); + QWidgetWindow *modalWidgetWindow = qobject_cast(modalWindow); if (windowModality == Qt::NonModal) { // determine the modality type if it hasn't been set on the - // modalWidget, this normally happens when waiting for a - // native dialog. use WindowModal if we are the child of a - // group leader; otherwise use ApplicationModal. - QWidget *m = modalWidget; + // modalWindow's widget, this normally happens when waiting for a + // native dialog. use WindowModal if we are the child of a group + // leader; otherwise use ApplicationModal. + QWidget *m = modalWidgetWindow ? modalWidgetWindow->widget() : 0; while (m && !m->testAttribute(Qt::WA_GroupLeader)) { m = m->parentWidget(); if (m) @@ -2352,97 +2372,58 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget) switch (windowModality) { case Qt::ApplicationModal: - { - QWidget *groupLeaderForWidget = widget; - while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader)) - groupLeaderForWidget = groupLeaderForWidget->parentWidget(); - - if (groupLeaderForWidget) { - // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children - QWidget *m = modalWidget; - while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader)) - m = m->parentWidget(); - if (m == groupLeaderForWidget) - return true; - } else if (modalWidget != widget) { + { + QWidgetWindow *widgetWindow = qobject_cast(window); + QWidget *groupLeaderForWidget = widgetWindow ? widgetWindow->widget() : 0; + while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader)) + groupLeaderForWidget = groupLeaderForWidget->parentWidget(); + + if (groupLeaderForWidget) { + // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children + QWidget *m = modalWidgetWindow ? modalWidgetWindow->widget() : 0; + while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader)) + m = m->parentWidget(); + if (m == groupLeaderForWidget) { + *blockingWindow = m->windowHandle(); return true; } - break; + } else if (modalWindow != window) { + *blockingWindow = modalWindow; + return true; } + break; + } case Qt::WindowModal: - { - QWidget *w = widget; + { + QWindow *w = window; + do { + QWindow *m = modalWindow; do { - QWidget *m = modalWidget; - do { - if (m == w) - return true; - m = m->parentWidget(); - if (m) - m = m->window(); - } while (m); - w = w->parentWidget(); - if (w) - w = w->window(); - } while (w); - break; - } + if (m == w) { + *blockingWindow = m; + return true; + } + QWindow *p = m->parent(); + if (!p) + p = m->transientParent(); + m = p; + } while (m); + QWindow *p = w->parent(); + if (!p) + p = w->transientParent(); + w = p; + } while (w); + break; + } default: - Q_ASSERT_X(false, "QApplication", "internal error, a modal widget cannot be modeless"); + Q_ASSERT_X(false, "QApplication", "internal error, a modal window cannot be modeless"); break; } } + *blockingWindow = 0; return false; } -/*!\internal - */ -void QApplicationPrivate::enterModal(QWidget *widget) -{ - QSet blocked; - QList windows = QApplication::topLevelWidgets(); - for (int i = 0; i < windows.count(); ++i) { - QWidget *window = windows.at(i); - if (window->windowType() != Qt::Tool && isBlockedByModal(window)) - blocked.insert(window); - } - - enterModal_sys(widget); - - windows = QApplication::topLevelWidgets(); - QEvent e(QEvent::WindowBlocked); - for (int i = 0; i < windows.count(); ++i) { - QWidget *window = windows.at(i); - if (!blocked.contains(window) && window->windowType() != Qt::Tool && isBlockedByModal(window)) - QApplication::sendEvent(window, &e); - } -} - -/*!\internal - */ -void QApplicationPrivate::leaveModal(QWidget *widget) -{ - QSet blocked; - QList windows = QApplication::topLevelWidgets(); - for (int i = 0; i < windows.count(); ++i) { - QWidget *window = windows.at(i); - if (window->windowType() != Qt::Tool && isBlockedByModal(window)) - blocked.insert(window); - } - - leaveModal_sys(widget); - - windows = QApplication::topLevelWidgets(); - QEvent e(QEvent::WindowUnblocked); - for (int i = 0; i < windows.count(); ++i) { - QWidget *window = windows.at(i); - if(blocked.contains(window) && window->windowType() != Qt::Tool && !isBlockedByModal(window)) - QApplication::sendEvent(window, &e); - } -} - - - /*!\internal Called from qapplication_\e{platform}.cpp, returns true diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 74af3bca6d..8f67a29d84 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -198,10 +198,7 @@ public: static void dispatchEnterLeave(QWidget *enter, QWidget *leave); //modality - static void enterModal(QWidget*); - static void leaveModal(QWidget*); - static void enterModal_sys(QWidget*); - static void leaveModal_sys(QWidget*); + Q_DECL_OVERRIDE bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const; static bool isBlockedByModal(QWidget *widget); static bool modalState(); static bool tryModalHelper(QWidget *widget, QWidget **rettop = 0); @@ -279,10 +276,6 @@ public: static bool widgetCount; // Coupled with -widgetcount switch static bool load_testability; // Coupled with -testability switch -#ifdef Q_WS_MAC - static bool native_modal_dialog_active; -#endif - static void setSystemPalette(const QPalette &pal); static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash); static void initializeWidgetPaletteHash(); diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index bcea2676bc..92b831101f 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -75,8 +75,6 @@ QT_BEGIN_NAMESPACE static QString appName; static QString appFont; static bool popupGrabOk; -extern bool app_do_modal; -extern QWidgetList *qt_modal_stack; extern QWidget *qt_button_down; extern QWidget *qt_popup_down; extern bool qt_replay_popup_mouse_event; @@ -126,28 +124,9 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type) return !block_event; } -void QApplicationPrivate::enterModal_sys(QWidget *widget) -{ - if (!qt_modal_stack) - qt_modal_stack = new QWidgetList; - qt_modal_stack->insert(0, widget); - app_do_modal = true; -} - -void QApplicationPrivate::leaveModal_sys(QWidget *widget) -{ - if (qt_modal_stack && qt_modal_stack->removeAll(widget)) { - if (qt_modal_stack->isEmpty()) { - delete qt_modal_stack; - qt_modal_stack = 0; - } - } - app_do_modal = qt_modal_stack != 0; -} - bool QApplicationPrivate::modalState() { - return app_do_modal; + return !self->modalWindowList.isEmpty(); } QWidget *qt_tlw_for_window(QWindow *wnd) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index cccde764ad..70839e705f 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7080,12 +7080,6 @@ void QWidgetPrivate::show_helper() QShowEvent showEvent; QApplication::sendEvent(q, &showEvent); - if (!isEmbedded && q->isModal() && q->isWindow()) - // QApplicationPrivate::enterModal *before* show, otherwise the initial - // stacking might be wrong - QApplicationPrivate::enterModal(q); - - show_sys(); if (!isEmbedded && q->windowType() == Qt::Popup) @@ -7141,12 +7135,6 @@ void QWidgetPrivate::hide_helper() if (!isEmbedded && (q->windowType() == Qt::Popup)) qApp->d_func()->closePopup(q); - // Move test modal here. Otherwise, a modal dialog could get - // destroyed and we lose all access to its parent because we haven't - // left modality. (Eg. modal Progress Dialog) - if (!isEmbedded && q->isModal() && q->isWindow()) - QApplicationPrivate::leaveModal(q); - #if defined(Q_WS_WIN) if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget() && !q->parentWidget()->isHidden() && q->isActiveWindow()) @@ -10047,9 +10035,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) break; case Qt::WA_ShowModal: if (!on) { - if (isVisible()) - QApplicationPrivate::leaveModal(this); - // reset modality type to Modeless when clearing WA_ShowModal + // reset modality type to NonModal when clearing WA_ShowModal data->window_modality = Qt::NonModal; } else if (data->window_modality == Qt::NonModal) { // determine the modality type if it hasn't been set prior @@ -10067,10 +10053,9 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) data->window_modality = (w && w->testAttribute(Qt::WA_GroupLeader)) ? Qt::WindowModal : Qt::ApplicationModal; - // Some window managers does not allow us to enter modal after the - // window is showing. Therefore, to be consistent, we cannot call - // QApplicationPrivate::enterModal(this) here. The window must be - // hidden before changing modality. + // Some window managers do not allow us to enter modality after the + // window is visible.The window must be hidden before changing the + // windowModality property and then reshown. } if (testAttribute(Qt::WA_WState_Created)) { // don't call setModal_sys() before create_sys() -- cgit v1.2.3 From 9839474e19dbef4b5b79abeaecebbf6e7bd6aed2 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 30 Mar 2012 09:53:12 +0200 Subject: QWidget: allow modal top-levels to have WA_DontShowOnScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a modal top-level widget has WA_DontShowOnScreen set, we need to call QGuiApplicationPrivate::showModalWindow() and hideModalWindow() ourselves, since we will not be calling QWindow::setVisible() (which would normally do the call for us). Change-Id: I1b22dd177c5956a2290f3ee031c95ab50d88f153 Reviewed-by: Friedemann Kleint Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qwidget_qpa.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 3d23b04ddf..4fe7ad6dc7 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -441,8 +441,15 @@ void QWidgetPrivate::show_sys() { Q_Q(QWidget); q->setAttribute(Qt::WA_Mapped); + + QWindow *window = q->windowHandle(); + if (q->testAttribute(Qt::WA_DontShowOnScreen)) { invalidateBuffer(q->rect()); + if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { + // add our window to the modal window list + QGuiApplicationPrivate::showModalWindow(window); + } return; } @@ -451,7 +458,6 @@ void QWidgetPrivate::show_sys() if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow)) return; - QWindow *window = q->windowHandle(); if (window) { QRect geomRect = q->geometry(); if (q->isWindow()) { @@ -473,9 +479,7 @@ void QWidgetPrivate::show_sys() } invalidateBuffer(q->rect()); - - if (window) - window->setVisible(true); + window->setVisible(true); } } @@ -484,6 +488,17 @@ void QWidgetPrivate::hide_sys() { Q_Q(QWidget); q->setAttribute(Qt::WA_Mapped, false); + + QWindow *window = q->windowHandle(); + + if (q->testAttribute(Qt::WA_DontShowOnScreen) + && q->isWindow() + && q->windowModality() != Qt::NonModal + && window) { + // remove our window from the modal window list + QGuiApplicationPrivate::hideModalWindow(window); + } + deactivateWidgetCleanup(); if (!q->isWindow()) { QWidget *p = q->parentWidget(); @@ -492,9 +507,9 @@ void QWidgetPrivate::hide_sys() } return; } - if (QWindow *window = q->windowHandle()) { - window->setVisible(false); - } + + if (window) + window->setVisible(false); } void QWidgetPrivate::setMaxWindowState_helper() -- cgit v1.2.3 From ce84af7c9b57f7f8cef5d57c5486b1409e13bcdd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 11 Apr 2012 12:07:59 +0200 Subject: Propagate window state changes to QWidget. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the state in QWidgetWindow and send an event to the widget unless the code is triggered by QWidget::setWindowState(). Change-Id: Ibf2f4e730384e41636841b9216eecfdff35b7bcb Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidgetwindow_qpa.cpp | 34 +++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 6dbd3c1f77..3cccc52311 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -454,10 +454,38 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event { // QWindow does currently not know 'active'. Qt::WindowStates eventState = event->oldState(); - if (m_widget->windowState() & Qt::WindowActive) + Qt::WindowStates widgetState = m_widget->windowState(); + if (widgetState & Qt::WindowActive) eventState |= Qt::WindowActive; - QWindowStateChangeEvent widgetEvent(eventState); - QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent); + + // Determine the new widget state, remember maximized/full screen + // during minimized. + switch (windowState()) { + case Qt::WindowNoState: + widgetState &= ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen); + break; + case Qt::WindowMinimized: + widgetState |= Qt::WindowMinimized; + break; + case Qt::WindowMaximized: + widgetState &= ~Qt::WindowFullScreen; + widgetState |= Qt::WindowMaximized; + break; + case Qt::WindowFullScreen: + widgetState &= ~Qt::WindowMaximized; + widgetState |= Qt::WindowFullScreen; + break; + case Qt::WindowActive: // Not handled by QWindow + break; + } + + // Sent event if the state changed (that is, it is not triggered by + // QWidget::setWindowState(), which also sends an event to the widget). + if (widgetState != m_widget->data->window_state) { + m_widget->data->window_state = widgetState; + QWindowStateChangeEvent widgetEvent(eventState); + QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent); + } } bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) -- cgit v1.2.3 From ee5bd5349bb8d781524307627b205676726d09a7 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 12 Apr 2012 02:04:07 +1000 Subject: Remove Qt 5 to-do comment that will not be addressed. The suggested behavioural change had the potential to break existing code, so the change won't be made for Qt 5. Task-number: QTBUG-25119 Change-Id: Ie03271d12b21a800c998e073eeb9ca1cd03ffe19 Reviewed-by: Lars Knoll --- src/widgets/kernel/qwidget.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 70839e705f..f02a67d9ea 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6730,7 +6730,6 @@ void QWidget::setContentsMargins(int left, int top, int right, int bottom) else updateGeometry(); - // ### Qt 5: compat, remove if (isVisible()) { update(); QResizeEvent e(data->crect.size(), data->crect.size()); -- cgit v1.2.3 From dd2429551ed6fee49f092001c58b953e72d139c3 Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 11 Apr 2012 19:42:54 -0700 Subject: Remove QWidget::setWindowHandle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's unused. The window (QWidgetWindow) is created and managed implicitly by QWidget. Change-Id: I28ee3f120a99c877f318e1abd7d73c9f3e542d03 Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidget.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 78b693c78d..64042ccc36 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -607,7 +607,6 @@ public: QBackingStore *backingStore() const; - void setWindowHandle(QWindow *window); QWindow *windowHandle() const; friend class QDesktopScreenWidget; -- cgit v1.2.3 From 93c960876af2aebc265ffe3ddc12a24325fc512e Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 11 Apr 2012 19:31:39 -0700 Subject: Remove redundant platformNativeInterface() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platformNativeInterface() is already defined in QGuiApplication. Change-Id: Ice720fb6f7e4b01c4627219d66a5a3c8980a79a5 Reviewed-by: Samuel Rødal --- src/widgets/kernel/qapplication.h | 2 -- src/widgets/kernel/qapplication_qpa.cpp | 6 ------ 2 files changed, 8 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index 3e11db0863..31d228ddd5 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -175,8 +175,6 @@ public: static bool isEffectEnabled(Qt::UIEffect); static void setEffectEnabled(Qt::UIEffect, bool enable = true); - static QPlatformNativeInterface *platformNativeInterface(); - #ifndef QT_NO_SESSIONMANAGER // session management bool isSessionRestored() const; diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 92b831101f..fa84e86f29 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -437,12 +437,6 @@ void QApplication::alert(QWidget *, int) { } -QPlatformNativeInterface *QApplication::platformNativeInterface() -{ - QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); - return pi->nativeInterface(); -} - void qt_init(QApplicationPrivate *priv, int type) { Q_UNUSED(priv); -- cgit v1.2.3 From e583ce4103e925ec7ef832d2c9e88979bc04d56c Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 11 Apr 2012 22:38:15 -0700 Subject: remove references to qws from backingstore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backingstore code is already hard to read as-is. Let's simplify things by removing qws code. Change-Id: Ibefd3ea17d29970d1f7348461959fdc5b01c1f42 Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidgetbackingstore.cpp | 46 +----------------------------- src/widgets/kernel/qwidgetbackingstore_p.h | 11 ------- 2 files changed, 1 insertion(+), 56 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index b331356e66..ef4483195e 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -57,11 +57,6 @@ #include #include -#ifdef Q_WS_QWS -#include -#include -#endif - QT_BEGIN_NAMESPACE extern QRegion qt_dirtyRegion(QWidget *); @@ -153,13 +148,6 @@ static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped) { -#ifdef Q_WS_QWS - Q_UNUSED(widget); - Q_UNUSED(unclipped); - static QWSYellowSurface surface(true); - surface.setDelay(msec); - surface.flush(widget, toBePainted, QPoint()); -#else QRegion paintRegion = toBePainted; QRect widgetRect = widget->rect(); @@ -224,7 +212,6 @@ void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePa ::usleep(1000 * msec); #endif #endif // Q_WS_WIN -#endif // Q_WS_QWS } bool QWidgetBackingStore::flushPaint(QWidget *widget, const QRegion &rgn) @@ -633,7 +620,7 @@ void QWidgetBackingStore::markDirtyOnScreen(const QRegion ®ion, QWidget *widg if (!widget || widget->d_func()->paintOnScreen() || region.isEmpty()) return; -#if defined(Q_WS_QWS) || defined(Q_WS_MAC) +#if defined(Q_WS_MAC) if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) dirtyOnScreen += region.translated(topLevelOffset); return; @@ -751,11 +738,6 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) QPoint toplevelOffset = pw->mapTo(tlw, QPoint()); QWidgetPrivate *pd = pw->d_func(); QRect clipR(pd->clipRect()); -#ifdef Q_WS_QWS - QWidgetBackingStore *wbs = x->backingStore.data(); - QWSWindowSurface *surface = static_cast(wbs->windowSurface); - clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect()); -#endif const QRect newRect(rect.translated(dx, dy)); QRect destRect = rect.intersected(clipR); if (destRect.isValid()) @@ -839,26 +821,6 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) bool accelerateScroll = accelEnv && isOpaque && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft()))); -#if defined(Q_WS_QWS) - QWSWindowSurface *surface; - surface = static_cast(wbs->windowSurface); - - if (accelerateScroll && !surface->isBuffered()) { - const QRegion surfaceClip = surface->clipRegion(); - const QRegion outsideClip = QRegion(rect) - surfaceClip; - if (!outsideClip.isEmpty()) { - const QVector clipped = (surfaceClip & rect).rects(); - if (clipped.size() < 8) { - for (int i = 0; i < clipped.size(); ++i) - this->scrollRect(clipped.at(i), dx, dy); - return; - } else { - accelerateScroll = false; - } - } - } -#endif // Q_WS_QWS - if (!accelerateScroll) { if (overlapped) { QRegion region(scrollRect); @@ -869,12 +831,6 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) } } else { const QPoint toplevelOffset = q->mapTo(tlw, QPoint()); -#ifdef Q_WS_QWS - QWSWindowSurface *surface = static_cast(wbs->windowSurface); - const QRegion clip = surface->clipRegion().translated(-toplevelOffset) & scrollRect; - const QRect clipBoundingRect = clip.boundingRect(); - scrollRect &= clipBoundingRect; -#endif const QRect destRect = scrollRect.translated(dx, dy) & scrollRect; const QRect sourceRect = destRect.translated(-dx, -dy); diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 7befdbeb78..56c2547d3e 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -87,9 +87,6 @@ public: { return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync && !fullUpdatePending -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - && !hasDirtyWindowDecoration() -#endif ); } @@ -130,10 +127,6 @@ private: void removeDirtyWidget(QWidget *w); -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - bool hasDirtyWindowDecoration() const; - void paintWindowDecoration(); -#endif void updateLists(QWidget *widget); inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) @@ -199,11 +192,7 @@ private: inline QRect topLevelRect() const { -#ifdef Q_WS_QWS - return tlw->frameGeometry(); -#else return tlw->data->crect; -#endif } inline void appendDirtyOnScreenWidget(QWidget *widget) -- cgit v1.2.3 From 40a1e8eccf42dad9ff70ad54658abcfc9bf896ae Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 11 Apr 2012 22:42:41 -0700 Subject: Remove hasDirtyFromPreviousSync from backingstore. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's always false (used to be some qws specific variable). Change-Id: I3dc185dba4c778797f180410ce8d293336ecfd9c Reviewed-by: Samuel Rødal --- src/widgets/kernel/qwidgetbackingstore.cpp | 6 +----- src/widgets/kernel/qwidgetbackingstore_p.h | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index ef4483195e..f9361cc357 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -696,8 +696,7 @@ void QWidgetBackingStore::updateLists(QWidget *cur) } QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel) - : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false) - , fullUpdatePending(0) + : tlw(topLevel), dirtyOnScreenWidgets(0), fullUpdatePending(0) { store = tlw->backingStore(); Q_ASSERT(store); @@ -982,9 +981,6 @@ void QWidgetBackingStore::sync() if (updatesDisabled) return; - if (hasDirtyFromPreviousSync) - dirty += dirtyFromPreviousSync; - // Contains everything that needs repaint. QRegion toClean(dirty); diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 56c2547d3e..7c350932ea 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -85,9 +85,7 @@ public: inline bool isDirty() const { - return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync - && !fullUpdatePending - ); + return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !fullUpdatePending); } // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). @@ -105,7 +103,6 @@ private: QVector *dirtyOnScreenWidgets; QList staticWidgets; QBackingStore *store; - uint hasDirtyFromPreviousSync : 1; uint fullUpdatePending : 1; QPoint tlwOffset; -- cgit v1.2.3 From 83fc52e3b4005d946c731577f8f49becae948c39 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 2 Apr 2012 11:59:04 +0200 Subject: widgets: Fix painting to a fully transparent top level widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWS used to have a line to change the composite mode from SourceOver to Source for the top level widget. This wasn't used with QPA and I removed the internal DontSetCompositionMode in qtbase. It turns out that the QWS way is the most efficient one to initialize the background of the widget. The alternative is to have the QPlatformBackingStore::beginPaint always clear the entire to be painted area and then paint the background of the widget. The difference of painting each pixel once or twice is noticable on embedded platforms and in the range of one to two fps. Reproduce the issue with: echo "QWidget {background: transparent}" > style.css ./examples/widgets/wiggly/wiggly -stylesheet style.css Task-number: QTBUG-24526 Change-Id: Ica4c980bb3bf6eb87ddb5b510ac7493292d01543 Reviewed-by: Samuel Rødal Reviewed-by: Girish Ramakrishnan --- src/widgets/kernel/qwidget.cpp | 12 +++++++++++- src/widgets/kernel/qwidget_p.h | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f02a67d9ea..662c9b7403 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2137,7 +2137,15 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { const QBrush bg = q->palette().brush(QPalette::Window); - fillRegion(painter, rgn, bg); + if (!(flags & DontSetCompositionMode)) { + //copy alpha straight in + QPainter::CompositionMode oldMode = painter->compositionMode(); + painter->setCompositionMode(QPainter::CompositionMode_Source); + fillRegion(painter, rgn, bg); + painter->setCompositionMode(oldMode); + } else { + fillRegion(painter, rgn, bg); + } } if (q->autoFillBackground()) @@ -5229,6 +5237,8 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, else flags |= DontSubtractOpaqueChildren; + flags |= DontSetCompositionMode; + if (target->devType() == QInternal::Printer) { QPainter p(target); render_helper(&p, targetOffset, paintRegion, renderFlags); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 8107b6ca74..d3fcdce6a8 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -284,7 +284,8 @@ public: DrawInvisible = 0x08, DontSubtractOpaqueChildren = 0x10, DontDrawOpaqueChildren = 0x20, - DontDrawNativeChildren = 0x40 + DontDrawNativeChildren = 0x40, + DontSetCompositionMode = 0x80 }; enum CloseMode { -- cgit v1.2.3