summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-05-30 14:16:43 +0200
committerLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-05-30 14:41:14 +0200
commite277d144259ce4e440cf789c83ba095b4c4d06a6 (patch)
treec51d4bf7d45f602c108c33eab60daee28fe7477f /src/widgets
parentef8e5af1d219dd749ea306230cfd097cc2595cb4 (diff)
Add focus and modal dialog support.
Reviewed-by: Samuel Rødal
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/kernel/qapplication.cpp6
-rw-r--r--src/widgets/kernel/qapplication_p.h1
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp42
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp5
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa.cpp11
5 files changed, 48 insertions, 17 deletions
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());