Move setWindowIcon() up to QGuiApplication.

[ChangeLog][QtGui][QWindow]QWindow::icon() now defaults to the application
icon, which can be set with QGuiApplication::setWindowIcon().

Change-Id: Id1974e5cda81775e515c14b294f67fb99351c6c9
Reviewed-by: Albert Astals Cid <albert.astals@canonical.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
This commit is contained in:
David Faure 2014-02-01 14:17:51 +01:00 committed by The Qt Project
parent bf82245baf
commit f42bd772f8
8 changed files with 115 additions and 29 deletions

View File

@ -133,6 +133,8 @@ enum ApplicationResourceFlags
static unsigned applicationResourceFlags = 0;
QIcon *QGuiApplicationPrivate::app_icon = 0;
QString *QGuiApplicationPrivate::platform_name = 0;
QString *QGuiApplicationPrivate::displayName = 0;
@ -523,6 +525,8 @@ QGuiApplication::~QGuiApplication()
d->cursor_list.clear();
#endif
delete QGuiApplicationPrivate::app_icon;
QGuiApplicationPrivate::app_icon = 0;
delete QGuiApplicationPrivate::platform_name;
QGuiApplicationPrivate::platform_name = 0;
delete QGuiApplicationPrivate::displayName;
@ -2596,6 +2600,35 @@ void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
{
}
/*!
\property QGuiApplication::windowIcon
\brief the default window icon
\sa QWindow::setIcon(), {Setting the Application Icon}
*/
QIcon QGuiApplication::windowIcon()
{
return QGuiApplicationPrivate::app_icon ? *QGuiApplicationPrivate::app_icon : QIcon();
}
void QGuiApplication::setWindowIcon(const QIcon &icon)
{
if (!QGuiApplicationPrivate::app_icon)
QGuiApplicationPrivate::app_icon = new QIcon();
*QGuiApplicationPrivate::app_icon = icon;
if (QGuiApplicationPrivate::is_app_running && !QGuiApplicationPrivate::is_app_closing)
QGuiApplicationPrivate::self->notifyWindowIconChanged();
}
void QGuiApplicationPrivate::notifyWindowIconChanged()
{
QEvent ev(QEvent::ApplicationWindowIconChange);
const QWindowList list = QGuiApplication::topLevelWindows();
for (int i = 0; i < list.size(); ++i)
QCoreApplication::sendEvent(list.at(i), &ev);
}
/*!
\property QGuiApplication::quitOnLastWindowClosed

View File

@ -73,6 +73,7 @@ class QStyleHints;
class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
{
Q_OBJECT
Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
Q_PROPERTY(QString platformName READ platformName STORED false)
@ -93,6 +94,9 @@ public:
static QWindowList topLevelWindows();
static QWindow *topLevelAt(const QPoint &pos);
static void setWindowIcon(const QIcon &icon);
static QIcon windowIcon();
static QString platformName();
static QWindow *modalWindow();

View File

@ -187,6 +187,7 @@ public:
static QGuiApplicationPrivate *instance() { return self; }
static QIcon *app_icon;
static QString *platform_name;
static QString *displayName;
@ -282,6 +283,8 @@ public:
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
virtual void notifyWindowIconChanged();
static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
static void setApplicationState(Qt::ApplicationState state);

View File

@ -776,6 +776,8 @@ void QWindow::setIcon(const QIcon &icon)
d->windowIcon = icon;
if (d->platformWindow)
d->platformWindow->setWindowIcon(icon);
QEvent e(QEvent::WindowIconChange);
QCoreApplication::sendEvent(this, &e);
}
/*!
@ -786,6 +788,8 @@ void QWindow::setIcon(const QIcon &icon)
QIcon QWindow::icon() const
{
Q_D(const QWindow);
if (d->windowIcon.isNull())
return QGuiApplication::windowIcon();
return d->windowIcon;
}
@ -1940,6 +1944,10 @@ bool QWindow::event(QEvent *ev)
hideEvent(static_cast<QHideEvent *>(ev));
break;
case QEvent::ApplicationWindowIconChange:
setIcon(icon());
break;
case QEvent::WindowStateChange: {
Q_D(QWindow);
emit windowStateChanged(d->windowState);

View File

@ -377,7 +377,6 @@ QPalette *QApplicationPrivate::set_pal = 0; // default palette set by pro
QFont *QApplicationPrivate::sys_font = 0; // default system font
QFont *QApplicationPrivate::set_font = 0; // default font set by programmer
QIcon *QApplicationPrivate::app_icon = 0;
QWidget *QApplicationPrivate::main_widget = 0; // main application widget
QWidget *QApplicationPrivate::focus_widget = 0; // has keyboard input focus
QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
@ -730,8 +729,6 @@ QApplication::~QApplication()
delete QApplicationPrivate::app_style;
QApplicationPrivate::app_style = 0;
delete QApplicationPrivate::app_icon;
QApplicationPrivate::app_icon = 0;
#ifndef QT_NO_DRAGANDDROP
if (qt_is_gui_used)
@ -1561,6 +1558,7 @@ QString QApplicationPrivate::desktopStyleKey()
return QString();
}
#if QT_VERSION < 0x060000 // remove these forwarders in Qt 6
/*!
\property QApplication::windowIcon
\brief the default window icon
@ -1569,23 +1567,32 @@ QString QApplicationPrivate::desktopStyleKey()
*/
QIcon QApplication::windowIcon()
{
return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
return QGuiApplication::windowIcon();
}
void QApplication::setWindowIcon(const QIcon &icon)
{
if (!QApplicationPrivate::app_icon)
QApplicationPrivate::app_icon = new QIcon();
*QApplicationPrivate::app_icon = icon;
if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
QEvent e(QEvent::ApplicationWindowIconChange);
QWidgetList all = QApplication::allWidgets();
for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
QWidget *w = *it;
if (w->isWindow())
sendEvent(w, &e);
}
QGuiApplication::setWindowIcon(icon);
}
#endif
void QApplicationPrivate::notifyWindowIconChanged()
{
QEvent ev(QEvent::ApplicationWindowIconChange);
const QWidgetList list = QApplication::topLevelWidgets();
QWindowList windowList = QGuiApplication::topLevelWindows();
// send to all top-level QWidgets
for (int i = 0; i < list.size(); ++i) {
QWidget *w = list.at(i);
windowList.removeOne(w->windowHandle());
QCoreApplication::sendEvent(w, &ev);
}
// in case there are any plain QWindows in this QApplication-using
// application, also send the notification to them
for (int i = 0; i < windowList.size(); ++i)
QCoreApplication::sendEvent(windowList.at(i), &ev);
}
/*!

View File

@ -126,10 +126,10 @@ public:
static void setFont(const QFont &, const char* className = 0);
static QFontMetrics fontMetrics();
#if QT_VERSION < 0x060000 // remove these forwarders in Qt 6
static void setWindowIcon(const QIcon &icon);
static QIcon windowIcon();
#endif
static QWidgetList allWidgets();
static QWidgetList topLevelWidgets();

View File

@ -137,6 +137,8 @@ public:
void createEventDispatcher();
static void dispatchEnterLeave(QWidget *enter, QWidget *leave, const QPointF &globalPosF);
void notifyWindowIconChanged() Q_DECL_OVERRIDE;
//modality
bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const Q_DECL_OVERRIDE;
static bool isBlockedByModal(QWidget *widget);
@ -198,7 +200,6 @@ public:
static QWidget *focus_widget;
static QWidget *hidden_focus_widget;
static QWidget *active_window;
static QIcon *app_icon;
#ifndef QT_NO_WHEELEVENT
static int wheel_scroll_lines;
#endif

View File

@ -5345,17 +5345,17 @@ void tst_QWidget::setFocus()
}
}
class EventSpy : public QObject
template<class T> class EventSpy : public QObject
{
public:
EventSpy(QWidget *widget, QEvent::Type event)
EventSpy(T *widget, QEvent::Type event)
: m_widget(widget), eventToSpy(event), m_count(0)
{
if (m_widget)
m_widget->installEventFilter(this);
}
QWidget *widget() const { return m_widget; }
T *widget() const { return m_widget; }
int count() const { return m_count; }
void clear() { m_count = 0; }
@ -5368,7 +5368,7 @@ protected:
}
private:
QWidget *m_widget;
T *m_widget;
QEvent::Type eventToSpy;
int m_count;
};
@ -5483,7 +5483,7 @@ void tst_QWidget::setCursor()
// test if CursorChange is sent
{
QWidget widget;
EventSpy spy(&widget, QEvent::CursorChange);
EventSpy<QWidget> spy(&widget, QEvent::CursorChange);
QCOMPARE(spy.count(), 0);
widget.setCursor(QCursor(Qt::WaitCursor));
QCOMPARE(spy.count(), 1);
@ -5505,7 +5505,7 @@ void tst_QWidget::setToolTip()
widget.setWindowTitle(widget.objectName());
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
EventSpy spy(&widget, QEvent::ToolTipChange);
EventSpy<QWidget> spy(&widget, QEvent::ToolTipChange);
QCOMPARE(spy.count(), 0);
QCOMPARE(widget.toolTip(), QString());
@ -5527,8 +5527,8 @@ void tst_QWidget::setToolTip()
QFrame *frame = new QFrame(popup.data());
frame->setGeometry(0, 0, 50, 50);
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
EventSpy spy1(frame, QEvent::ToolTip);
EventSpy spy2(popup.data(), QEvent::ToolTip);
EventSpy<QWidget> spy1(frame, QEvent::ToolTip);
EventSpy<QWidget> spy2(popup.data(), QEvent::ToolTip);
frame->setMouseTracking(pass == 0 ? false : true);
frame->setToolTip(QLatin1String("TOOLTIP FRAME"));
popup->setToolTip(QLatin1String("TOOLTIP POPUP"));
@ -5550,7 +5550,8 @@ void tst_QWidget::setToolTip()
void tst_QWidget::testWindowIconChangeEventPropagation()
{
typedef QSharedPointer<EventSpy> EventSpyPtr;
typedef QSharedPointer<EventSpy<QWidget> > EventSpyPtr;
typedef QSharedPointer<EventSpy<QWindow> > WindowEventSpyPtr;
// Create widget hierarchy.
QWidget topLevelWidget;
QWidget topLevelChild(&topLevelWidget);
@ -5563,12 +5564,27 @@ void tst_QWidget::testWindowIconChangeEventPropagation()
<< &dialog << &dialogChild;
QCOMPARE(widgets.count(), 4);
topLevelWidget.show();
dialog.show();
QWindowList windows;
windows << topLevelWidget.windowHandle() << dialog.windowHandle();
QWindow otherWindow;
windows << &otherWindow;
const int lastWidgetWindow = 1; // 0 and 1 are qwidgetwindow, 2 is a pure qwindow
// Create spy lists.
QList <EventSpyPtr> applicationEventSpies;
QList <EventSpyPtr> widgetEventSpies;
foreach (QWidget *widget, widgets) {
applicationEventSpies.append(EventSpyPtr(new EventSpy(widget, QEvent::ApplicationWindowIconChange)));
widgetEventSpies.append(EventSpyPtr(new EventSpy(widget, QEvent::WindowIconChange)));
applicationEventSpies.append(EventSpyPtr(new EventSpy<QWidget>(widget, QEvent::ApplicationWindowIconChange)));
widgetEventSpies.append(EventSpyPtr(new EventSpy<QWidget>(widget, QEvent::WindowIconChange)));
}
QList <WindowEventSpyPtr> appWindowEventSpies;
QList <WindowEventSpyPtr> windowEventSpies;
foreach (QWindow *window, windows) {
appWindowEventSpies.append(WindowEventSpyPtr(new EventSpy<QWindow>(window, QEvent::ApplicationWindowIconChange)));
windowEventSpies.append(WindowEventSpyPtr(new EventSpy<QWindow>(window, QEvent::WindowIconChange)));
}
// QApplication::setWindowIcon
@ -5592,6 +5608,20 @@ void tst_QWidget::testWindowIconChangeEventPropagation()
QCOMPARE(spy->count(), 1);
spy->clear();
}
for (int i = 0; i < windows.count(); ++i) {
// Check QEvent::ApplicationWindowIconChange (sent to QWindow)
// QWidgetWindows don't get this event, since the widget takes care of changing the icon
WindowEventSpyPtr spy = appWindowEventSpies.at(i);
QWindow *window = spy->widget();
QCOMPARE(spy->count(), i > lastWidgetWindow ? 1 : 0);
QCOMPARE(window->icon(), windowIcon);
spy->clear();
// Check QEvent::WindowIconChange (sent to QWindow)
spy = windowEventSpies.at(i);
QCOMPARE(spy->count(), 1);
spy->clear();
}
// Set icon on a top-level widget.
topLevelWidget.setWindowIcon(QIcon());