diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-09-29 18:02:54 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-05 12:49:29 +0200 |
commit | 11070a090a9cc77d02315a3cb39eaf628bd9bfe7 (patch) | |
tree | f9ea6781a9694e991136ffb78fb1f1382cbe2c92 /src | |
parent | 253497b7446c7d723aa3bdd7152e25d6852f2604 (diff) |
Added QWindow::isActive() and focus in / out events.
Renamed QGuiApplication::activeWindow() to
QGuiApplication::focusWindow(), implemented QWindow::isActive() as a
style hint, and added focus in / out events.
Change-Id: I71866e76c5a817def3e17bcc20a4fc32081a0e7a
Reviewed-on: http://codereview.qt-project.org/5811
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.h | 4 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 72 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.h | 12 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication_qpa.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_qpa.cpp | 6 |
7 files changed, 107 insertions, 13 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index bfa60fa657..986fc5c11d 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -114,7 +114,7 @@ QClipboard *QGuiApplicationPrivate::qt_clipboard = 0; QList<QScreen *> QGuiApplicationPrivate::screen_list; QWindowList QGuiApplicationPrivate::window_list; -QWindow *QGuiApplicationPrivate::active_window = 0; +QWindow *QGuiApplicationPrivate::focus_window = 0; Q_GLOBAL_STATIC(QMutex, applicationFontMutex) QFont *QGuiApplicationPrivate::app_font = 0; @@ -181,9 +181,9 @@ QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags self = this; } -QWindow *QGuiApplication::activeWindow() +QWindow *QGuiApplication::focusWindow() { - return QGuiApplicationPrivate::active_window; + return QGuiApplicationPrivate::focus_window; } QWindowList QGuiApplication::topLevelWindows() @@ -678,8 +678,20 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate if (!e->activated) return; - QWindow *previous = QGuiApplicationPrivate::active_window; - QGuiApplicationPrivate::active_window = e->activated.data(); + QWindow *previous = QGuiApplicationPrivate::focus_window; + QGuiApplicationPrivate::focus_window = e->activated.data(); + + if (previous == QGuiApplicationPrivate::focus_window) + return; + + if (previous) { + QFocusEvent focusOut(QEvent::FocusOut); + QCoreApplication::sendSpontaneousEvent(previous, &focusOut); + } + + QFocusEvent focusIn(QEvent::FocusIn); + QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn); + if (self) self->notifyActiveWindowChange(previous); } diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 7b8590233e..80c71dfa2a 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -85,7 +85,9 @@ public: static QWindowList topLevelWindows(); static QWindow *topLevelAt(const QPoint &pos); - static QWindow *activeWindow(); + static QT_DEPRECATED QWindow *activeWindow() { return focusWindow(); } + static QWindow *focusWindow(); + static QScreen *primaryScreen(); static QList<QScreen *> screens(); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 7ee95b777f..ccaf1292ae 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -161,7 +161,7 @@ public: static QPalette *app_pal; static QWindowList window_list; - static QWindow *active_window; + static QWindow *focus_window; #ifndef QT_NO_CURSOR QList<QCursor> cursor_list; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 489a7498f4..b1c26a39f1 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -95,8 +95,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent) QWindow::~QWindow() { - if (QGuiApplicationPrivate::active_window == this) - QGuiApplicationPrivate::active_window = 0; + if (QGuiApplicationPrivate::focus_window == this) + QGuiApplicationPrivate::focus_window = 0; QGuiApplicationPrivate::window_list.removeAll(this); destroy(); } @@ -320,9 +320,32 @@ void QWindow::setOpacity(qreal level) void QWindow::requestActivateWindow() { Q_D(QWindow); - QGuiApplicationPrivate::active_window = this; - if (d->platformWindow) { + if (d->platformWindow) d->platformWindow->requestActivateWindow(); +} + +/*! + Returns true if the window should appear active from a style perspective. + + This is the case for the window that has input focus as well as windows + that are in the same parent / transient parent chain as the focus window. + + To get the window that currently has focus, use QGuiApplication::focusWindow(). +*/ +bool QWindow::isActive() const +{ + Q_D(const QWindow); + if (!d->platformWindow) + return false; + + QWindow *focus = QGuiApplication::focusWindow(); + if (focus == this) + return true; + + if (!parent() && !transientParent()) { + return isAncestorOf(focus); + } else { + return (parent() && parent()->isActive()) || (transientParent() && transientParent()->isActive()); } } @@ -335,7 +358,7 @@ Qt::WindowState QWindow::windowState() const void QWindow::setWindowState(Qt::WindowState state) { if (state == Qt::WindowActive) { - requestActivateWindow(); + qWarning() << "QWindow::setWindowState does not accept Qt::WindowActive"; return; } @@ -361,6 +384,29 @@ QWindow *QWindow::transientParent() const return d->transientParent.data(); } +/*! + \enum QWindow::AncestorMode + + This enum is used to control whether or not transient parents + should be considered ancestors. + + \value ExcludeTransients Transient parents are not considered ancestors. + \value IncludeTransients Transient parents are considered ancestors. +*/ + +/*! + Returns true if the window is an ancestor of the given child. If mode is + IncludeTransients transient parents are also considered ancestors. +*/ +bool QWindow::isAncestorOf(const QWindow *child, AncestorMode mode) const +{ + if (child->parent() == this || (mode == IncludeTransients && child->transientParent() == this)) + return true; + + return (child->parent() && isAncestorOf(child->parent(), mode)) + || (mode == IncludeTransients && child->transientParent() && isAncestorOf(child->transientParent(), mode)); +} + QSize QWindow::minimumSize() const { Q_D(const QWindow); @@ -670,6 +716,14 @@ bool QWindow::event(QEvent *event) keyReleaseEvent(static_cast<QKeyEvent *>(event)); break; + case QEvent::FocusIn: + focusInEvent(static_cast<QFocusEvent *>(event)); + break; + + case QEvent::FocusOut: + focusOutEvent(static_cast<QFocusEvent *>(event)); + break; + #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: wheelEvent(static_cast<QWheelEvent*>(event)); @@ -710,6 +764,14 @@ void QWindow::keyReleaseEvent(QKeyEvent *) { } +void QWindow::focusInEvent(QFocusEvent *) +{ +} + +void QWindow::focusOutEvent(QFocusEvent *) +{ +} + void QWindow::inputMethodEvent(QInputMethodEvent *) { } diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index fefece1e9e..499582e348 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -60,6 +60,7 @@ QT_MODULE(Gui) class QWindowPrivate; class QExposeEvent; +class QFocusEvent; class QMoveEvent; class QResizeEvent; class QShowEvent; @@ -123,12 +124,21 @@ public: void setOpacity(qreal level); void requestActivateWindow(); + bool isActive() const; + Qt::WindowState windowState() const; void setWindowState(Qt::WindowState state); void setTransientParent(QWindow *parent); QWindow *transientParent() const; + enum AncestorMode { + ExcludeTransients, + IncludeTransients + }; + + bool isAncestorOf(const QWindow *child, AncestorMode mode = IncludeTransients) const; + QSize minimumSize() const; QSize maximumSize() const; QSize baseSize() const; @@ -205,6 +215,8 @@ protected: virtual void exposeEvent(QExposeEvent *); virtual void resizeEvent(QResizeEvent *); virtual void moveEvent(QMoveEvent *); + virtual void focusInEvent(QFocusEvent *); + virtual void focusOutEvent(QFocusEvent *); virtual void showEvent(QShowEvent *); virtual void hideEvent(QHideEvent *); diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 29ac94bfb1..8732a194e8 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -157,7 +157,7 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) { Q_UNUSED(previous); Q_Q(QApplication); - QWindow *wnd = QGuiApplicationPrivate::active_window; + QWindow *wnd = QGuiApplicationPrivate::focus_window; if (inPopupMode()) // some delayed focus event to ignore return; QWidget *tlw = qt_tlw_for_window(wnd); diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index ee5cd7482e..2265fb55fb 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -79,6 +79,12 @@ bool QWidgetWindow::event(QEvent *event) handleEnterLeaveEvent(event); return true; + // these should not be sent to QWidget, the corresponding events + // are sent by QApplicationPrivate::notifyActiveWindowChange() + case QEvent::FocusIn: + case QEvent::FocusOut: + return false; + case QEvent::KeyPress: case QEvent::KeyRelease: handleKeyEvent(static_cast<QKeyEvent *>(event)); |