summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2013-04-10 13:55:50 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-19 20:10:46 +0200
commitda01deb0ac01b37656e021b9d5d696c5de7b0afb (patch)
tree6a689d5cddc689bc83c6a74c8dc5ef0f48359b64
parent926086b9e37d45d09d5ce7d632a07583b40a8f70 (diff)
Implement alertion state for windows.
Add QWindow::alert() and QPlatformWindow::setAlertState(). Add logic to clear alertion state when the window becomes active. The platform plugins then only need to implement a setter and a cheap getter and need not handle activation. Prototypically implement X11 and Windows. Task-number: QTBUG-30416 Change-Id: Ia70c4722d812462a21f4034b7d52735c9f2bc49c Reviewed-by: Jerome Pasion <jerome.pasion@digia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
-rw-r--r--src/gui/kernel/qguiapplication.cpp5
-rw-r--r--src/gui/kernel/qplatformwindow.cpp26
-rw-r--r--src/gui/kernel/qplatformwindow.h3
-rw-r--r--src/gui/kernel/qwindow.cpp30
-rw-r--r--src/gui/kernel/qwindow.h3
-rw-r--r--src/gui/kernel/qwindow_p.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h5
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp12
11 files changed, 114 insertions, 3 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b05ba28e48..fba516c135 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1592,6 +1592,11 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
if (previous == newFocus)
return;
+ if (newFocus)
+ if (QPlatformWindow *platformWindow = newFocus->handle())
+ if (platformWindow->isAlertState())
+ platformWindow->setAlertState(false);
+
QObject *previousFocusObject = previous ? previous->focusObject() : 0;
if (previous) {
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index bfb6ab5a68..1e8ac60cca 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -463,6 +463,32 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
}
/*!
+ Reimplement this method to set whether the window demands attention
+ (for example, by flashing the taskbar icon) depending on \a enabled.
+
+ \sa isAlertState()
+ \since 5.1
+*/
+
+void QPlatformWindow::setAlertState(bool enable)
+{
+ Q_UNUSED(enable)
+}
+
+/*!
+ Reimplement this method return whether the window is in
+ an alert state.
+
+ \sa setAlertState()
+ \since 5.1
+*/
+
+bool QPlatformWindow::isAlertState() const
+{
+ return false;
+}
+
+/*!
Helper function to get initial geometry on windowing systems which do not
do smart positioning and also do not provide a means of centering a
transient window w.r.t. its parent. For example this is useful on Windows
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 7ade461890..7dfbae036f 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -128,6 +128,9 @@ public:
virtual void setFrameStrutEventsEnabled(bool enabled);
virtual bool frameStrutEventsEnabled() const;
+ virtual void setAlertState(bool enabled);
+ virtual bool isAlertState() const;
+
static QRect initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 2307df37ac..8c9bc575bd 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -58,6 +58,7 @@
#include <private/qevent_p.h>
+#include <QtCore/QTimer>
#include <QtCore/QDebug>
#include <QStyleHints>
@@ -2150,6 +2151,33 @@ QWindow *QWindow::fromWinId(WId id)
return window;
}
+/*!
+ Causes an alert to be shown for \a msec miliseconds. If \a msec is \c 0 (the
+ default), then the alert is shown indefinitely until the window becomes
+ active again.
+
+ In alert state, the window indicates that it demands attention, for example by
+ flashing or bouncing the taskbar entry.
+
+ \since 5.1
+*/
+
+void QWindow::alert(int msec)
+{
+ Q_D(QWindow);
+ if (!d->platformWindow || d->platformWindow->isAlertState())
+ return;
+ d->platformWindow->setAlertState(true);
+ if (d->platformWindow->isAlertState() && msec)
+ QTimer::singleShot(msec, this, SLOT(_q_clearAlert()));
+}
+
+void QWindowPrivate::_q_clearAlert()
+{
+ if (platformWindow && platformWindow->isAlertState())
+ platformWindow->setAlertState(false);
+}
+
#ifndef QT_NO_CURSOR
/*!
\brief set the cursor shape for this window
@@ -2233,3 +2261,5 @@ void QWindowPrivate::applyCursor()
#endif // QT_NO_CURSOR
QT_END_NAMESPACE
+
+#include "moc_qwindow.cpp"
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 1b63e185f8..9b1ed2c702 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -290,6 +290,8 @@ public Q_SLOTS:
Q_REVISION(1) void setMaximumWidth(int w);
Q_REVISION(1) void setMaximumHeight(int h);
+ void alert(int msec);
+
Q_SIGNALS:
void screenChanged(QScreen *screen);
void modalityChanged(Qt::WindowModality modality);
@@ -346,6 +348,7 @@ protected:
QWindow(QWindowPrivate &dd, QWindow *parent);
private:
+ Q_PRIVATE_SLOT(d_func(), void _q_clearAlert())
QPlatformSurface *surfaceHandle() const;
Q_DISABLE_COPY(QWindow)
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index e32d45acca..ea2cb722ab 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -125,6 +125,7 @@ public:
virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; }
void updateVisibility();
+ void _q_clearAlert();
QWindow::SurfaceType surfaceType;
Qt::WindowFlags windowFlags;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 9b2b67619d..2a5e08cf41 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1802,6 +1802,19 @@ QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwex
}
#ifndef Q_OS_WINCE
+void QWindowsWindow::setAlertState(bool enabled)
+{
+ if (isAlertState() == enabled)
+ return;
+ if (enabled) {
+ alertWindow(0);
+ setFlag(AlertState);
+ } else {
+ stopAlertWindow();
+ clearFlag(AlertState);
+ }
+}
+
void QWindowsWindow::alertWindow(int durationMs)
{
DWORD timeOutMs = GetCaretBlinkTime();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 1148440f05..2117ca50b8 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -132,7 +132,8 @@ public:
SynchronousGeometryChangeEvent = 0x400,
WithinSetStyle = 0x800,
WithinDestroy = 0x1000,
- TouchRegistered = 0x2000
+ TouchRegistered = 0x2000,
+ AlertState = 0x4000
};
struct WindowData
@@ -255,6 +256,8 @@ public:
void setWindowIcon(const QIcon &icon);
#ifndef Q_OS_WINCE
+ void setAlertState(bool enabled);
+ bool isAlertState() const { return testFlag(AlertState); }
void alertWindow(int durationMs = 0);
void stopAlertWindow();
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5af6a9ec9d..68ccbfb8c0 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -189,6 +189,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_usingSyncProtocol(false)
, m_deferredActivation(false)
, m_embedded(false)
+ , m_alertState(false)
, m_netWmUserTimeWindow(XCB_NONE)
, m_dirtyFrameMargins(false)
#if defined(XCB_USE_EGL)
@@ -2047,4 +2048,17 @@ void QXcbWindow::setMask(const QRegion &region)
#endif // !QT_NO_SHAPE
+void QXcbWindow::setAlertState(bool enabled)
+{
+ if (m_alertState == enabled)
+ return;
+ const NetWmStates oldState = netWmStates();
+ m_alertState = enabled;
+ if (enabled) {
+ setNetWmStates(oldState | NetWmStateDemandsAttention);
+ } else {
+ setNetWmStates(oldState & ~NetWmStateDemandsAttention);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index f4bd2d96ff..300596845e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE
class QXcbScreen;
class QXcbEGLSurface;
class QIcon;
-
class QXcbWindow : public QXcbObject, public QPlatformWindow
{
public:
@@ -120,6 +119,9 @@ public:
void setMask(const QRegion &region);
#endif // !QT_NO_SHAPE
+ void setAlertState(bool enabled);
+ bool isAlertState() const { return m_alertState; }
+
xcb_window_t xcb_window() const { return m_window; }
uint depth() const { return m_depth; }
QImage::Format imageFormat() const { return m_imageFormat; }
@@ -194,6 +196,7 @@ private:
bool m_deferredExpose;
bool m_configureNotifyPending;
bool m_embedded;
+ bool m_alertState;
xcb_window_t m_netWmUserTimeWindow;
QSurfaceFormat m_format;
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 54eb443c43..0d929f367b 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -55,6 +55,7 @@
#include <qdesktopwidget.h>
#include <qpa/qplatformcursor.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformwindow.h>
#include <qdebug.h>
#include <qpa/qwindowsysteminterface.h>
@@ -410,8 +411,17 @@ void QApplication::beep()
{
}
-void QApplication::alert(QWidget *, int)
+void QApplication::alert(QWidget *widget, int duration)
{
+ if (widget) {
+ if (widget->window()->isActiveWindow()&& !widget->window()->windowState() & Qt::WindowMinimized)
+ return;
+ if (QWindow *window= QApplicationPrivate::windowForWidget(widget))
+ window->alert(duration);
+ } else {
+ foreach (QWidget *topLevel, topLevelWidgets())
+ QApplication::alert(topLevel, duration);
+ }
}
void qt_init(QApplicationPrivate *priv, int type)