diff options
author | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-05-30 14:16:43 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-05-30 14:41:14 +0200 |
commit | e277d144259ce4e440cf789c83ba095b4c4d06a6 (patch) | |
tree | c51d4bf7d45f602c108c33eab60daee28fe7477f /src | |
parent | ef8e5af1d219dd749ea306230cfd097cc2595cb4 (diff) |
Add focus and modal dialog support.
Reviewed-by: Samuel Rødal
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication_p.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication_qpa.cpp | 42 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_qpa.cpp | 5 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_qpa.cpp | 11 |
7 files changed, 56 insertions, 17 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index d837fb0800..cbf4a9455b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -583,7 +583,10 @@ void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Le void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e) { + QWindow *previous = QGuiApplicationPrivate::active_window; QGuiApplicationPrivate::active_window = e->activated.data(); + if (self) + self->notifyActiveWindowChange(previous); } void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e) @@ -721,6 +724,10 @@ void QGuiApplicationPrivate::notifyLayoutDirectionChange() { } +void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *) +{ +} + /*! \property QGuiApplication::layoutDirection \brief the default layout direction for this application diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 80aa5a525a..2d0f16c2f4 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -70,6 +70,7 @@ public: void createEventDispatcher(); virtual void notifyLayoutDirectionChange(); + virtual void notifyActiveWindowChange(QWindow *previous); static int keyboard_input_time; static int mouse_double_click_time; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 15cad61594..13a4eca745 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -536,7 +536,8 @@ QDesktopWidget *qt_desktopWidget = 0; // root window widgets #if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD) QClipboard *qt_clipboard = 0; // global clipboard object #endif -QWidgetList * qt_modal_stack=0; // stack of modal widgets +QWidgetList * qt_modal_stack = 0; // stack of modal widgets +bool app_do_modal = false; /*! \internal @@ -2422,7 +2423,6 @@ void QApplicationPrivate::notifyLayoutDirectionChange() } } - /*! \fn Qt::WindowsVersion QApplication::winVersion() @@ -2790,7 +2790,6 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget) if (QApplication::activePopupWidget() == widget) return false; -#if 0 for (int i = 0; i < qt_modal_stack->size(); ++i) { QWidget *modalWidget = qt_modal_stack->at(i); @@ -2869,7 +2868,6 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget) break; } } -#endif return false; } diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index ad649f6555..40308db870 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -304,6 +304,7 @@ public: ~QApplicationPrivate(); virtual void notifyLayoutDirectionChange(); + virtual void notifyActiveWindowChange(QWindow *); #if defined(Q_WS_X11) #ifndef QT_NO_SETTINGS diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 4ed8eda460..0210c1474e 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -71,6 +71,8 @@ QT_BEGIN_NAMESPACE static QString appName; static QString appFont; +extern bool app_do_modal; +extern QWidgetList *qt_modal_stack; QString QApplicationPrivate::appName() const { @@ -82,7 +84,7 @@ void QApplicationPrivate::createEventDispatcher() QGuiApplicationPrivate::createEventDispatcher(); } -static bool qt_try_modal(QWidget *widget, QEvent::Type type) +bool qt_try_modal(QWidget *widget, QEvent::Type type) { QWidget * top = 0; @@ -116,21 +118,16 @@ static bool qt_try_modal(QWidget *widget, QEvent::Type type) return !block_event; } - - -void QApplicationPrivate::enterModal_sys(QWidget *) +void QApplicationPrivate::enterModal_sys(QWidget *widget) { -#if 0 if (!qt_modal_stack) qt_modal_stack = new QWidgetList; qt_modal_stack->insert(0, widget); app_do_modal = true; -#endif } -void QApplicationPrivate::leaveModal_sys(QWidget *) +void QApplicationPrivate::leaveModal_sys(QWidget *widget) { -#if 0 if (qt_modal_stack && qt_modal_stack->removeAll(widget)) { if (qt_modal_stack->isEmpty()) { delete qt_modal_stack; @@ -138,15 +135,36 @@ void QApplicationPrivate::leaveModal_sys(QWidget *) } } app_do_modal = qt_modal_stack != 0; -#endif } bool QApplicationPrivate::modalState() { - return false; -#if 0 return app_do_modal; -#endif +} + +QWidget *qt_tlw_for_window(QWindow *wnd) +{ + if (wnd) + foreach (QWidget *tlw, qApp->topLevelWidgets()) + if (tlw->windowHandle() == wnd) + return tlw; + return 0; +} + +void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) +{ + Q_UNUSED(previous); + Q_Q(QApplication); + QWindow *wnd = QGuiApplicationPrivate::active_window; + QWidget *tlw = qt_tlw_for_window(wnd); + if (!tlw) + return; + if (modalState() + && !qt_try_modal(tlw, QEvent::MouseButtonRelease) + && q->activeWindow()) + q->activeWindow()->activateWindow(); + else + q->setActiveWindow(tlw); } void QApplicationPrivate::closePopup(QWidget *popup) diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 2120e40c57..99db2f5295 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -740,8 +740,11 @@ QWindow *QWidget::windowHandle() const { Q_D(const QWidget); QTLWExtra *extra = d->maybeTopData(); - if (extra && extra->window) + if (extra) { + if (!extra->window) + const_cast<QWidgetPrivate *>(d)->createTLSysExtra(); return extra->window; + } return 0; } diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 4bee0f2523..38156d30e0 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -52,6 +52,7 @@ QWidget *qt_button_down = 0; // widget got last button-down static QWidget *qt_popup_down = 0; // popup that contains the pressed widget extern int openPopupCount; static bool replayPopupMouseEvent = false; +extern bool qt_try_modal(QWidget *widget, QEvent::Type type); QWidgetWindow::QWidgetWindow(QWidget *widget) : m_widget(widget) @@ -203,6 +204,10 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) return; } + // modal event handling + if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type())) + return; + // which child should have it? QWidget *widget = m_widget->childAt(event->pos()); QPoint mapped = event->pos(); @@ -237,6 +242,9 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) void QWidgetWindow::handleKeyEvent(QKeyEvent *event) { + if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type())) + return; + QWidget *widget = m_widget->focusWidget(); if (!widget) @@ -264,6 +272,9 @@ void QWidgetWindow::handleCloseEvent(QCloseEvent *) void QWidgetWindow::handleWheelEvent(QWheelEvent *event) { + if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type())) + return; + // which child should have it? QWidget *widget = m_widget->childAt(event->pos()); |