From 11070a090a9cc77d02315a3cb39eaf628bd9bfe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 29 Sep 2011 18:02:54 +0200 Subject: 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 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qguiapplication.cpp | 22 +++++++++--- src/gui/kernel/qguiapplication.h | 4 ++- src/gui/kernel/qguiapplication_p.h | 2 +- src/gui/kernel/qwindow.cpp | 72 +++++++++++++++++++++++++++++++++++--- src/gui/kernel/qwindow.h | 12 +++++++ 5 files changed, 100 insertions(+), 12 deletions(-) (limited to 'src/gui/kernel') 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 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 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 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(event)); break; + case QEvent::FocusIn: + focusInEvent(static_cast(event)); + break; + + case QEvent::FocusOut: + focusOutEvent(static_cast(event)); + break; + #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: wheelEvent(static_cast(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 *); -- cgit v1.2.3