1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qapplication_p.h"
43 #include "qcolormap.h"
45 #include "qpixmapcache.h"
47 #include "private/qcursor_p.h"
51 #include "private/qwidget_p.h"
52 #include "private/qevent_p.h"
54 #include <qpa/qplatformintegrationfactory_p.h>
55 #include <qdesktopwidget.h>
56 #include <qpa/qplatformcursor.h>
57 #include <qpa/qplatformtheme.h>
60 #include <qpa/qwindowsysteminterface.h>
61 #include <qpa/qwindowsysteminterface_p.h>
62 #include <qpa/qplatformintegration.h>
64 #include "qdesktopwidget_qpa_p.h"
65 #include "qwidgetwindow_qpa_p.h"
69 # include <QtCore/qt_windows.h> // for qt_win_display_dc()
74 static QString appFont;
75 static bool popupGrabOk = false;
76 static QPointer<QWidget> autoGrabber;
77 extern QWidget *qt_button_down;
78 extern QWidget *qt_popup_down;
79 extern bool qt_replay_popup_mouse_event;
80 int openPopupCount = 0;
82 void QApplicationPrivate::createEventDispatcher()
84 QGuiApplicationPrivate::createEventDispatcher();
87 bool qt_try_modal(QWidget *widget, QEvent::Type type)
91 if (QApplicationPrivate::tryModalHelper(widget, &top))
94 bool block_event = false;
95 bool paint_event = false;
100 if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
104 case QEvent::MouseButtonPress: // disallow mouse/key events
105 case QEvent::MouseButtonRelease:
106 case QEvent::MouseMove:
107 case QEvent::KeyPress:
108 case QEvent::KeyRelease:
115 if ((block_event || paint_event) && top->parentWidget() == 0)
121 bool QApplicationPrivate::modalState()
123 return !self->modalWindowList.isEmpty();
126 QWidget *qt_tlw_for_window(QWindow *wnd)
129 foreach (QWidget *tlw, qApp->topLevelWidgets())
130 if (tlw->windowHandle() == wnd)
135 void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
138 QWindow *wnd = QGuiApplicationPrivate::focus_window;
139 if (inPopupMode()) // some delayed focus event to ignore
141 QWidget *tlw = qt_tlw_for_window(wnd);
142 QApplication::setActiveWindow(tlw);
145 void QApplicationPrivate::handleAutomaticMouseGrab(QWidget *widget, QMouseEvent *e)
147 // Grab the mouse automatically for current window when any button is pressed,
148 // unless there is an active mousegrabber or mouse is being grabbed for a popup.
149 if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) {
150 if (e->buttons() == Qt::NoButton) {
151 // No buttons remain pressed, so release the grab unless grab has been acquired
152 // for some other reason in the meantime.
153 if (autoGrabber && !QWidget::mouseGrabber() && !popupGrabOk)
154 qt_widget_private(autoGrabber)->stealMouseGrab(false);
157 // Some buttons are pressed, grab mouse input for current window,
158 // unless there is already an active grab.
159 if (!autoGrabber && !QWidget::mouseGrabber() && !popupGrabOk) {
160 autoGrabber = widget->window();
161 qt_widget_private(autoGrabber)->stealMouseGrab(true);
167 static void ungrabKeyboardForPopup(QWidget *popup)
169 if (QWidget::keyboardGrabber())
170 qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true);
172 qt_widget_private(popup)->stealKeyboardGrab(false);
175 static void ungrabMouseForPopup(QWidget *popup)
177 if (QWidget::mouseGrabber())
178 qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true);
180 qt_widget_private(popup)->stealMouseGrab(false);
183 static void grabForPopup(QWidget *popup)
185 Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
186 popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true);
189 qt_widget_private(autoGrabber)->stealMouseGrab(false);
191 popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true);
193 // transfer grab back to the keyboard grabber if any
194 ungrabKeyboardForPopup(popup);
199 void QApplicationPrivate::closePopup(QWidget *popup)
203 popupWidgets->removeAll(popup);
205 if (popup == qt_popup_down) {
210 if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
211 delete QApplicationPrivate::popupWidgets;
212 QApplicationPrivate::popupWidgets = 0;
217 if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX,
218 QGuiApplicationPrivate::mousePressY))
219 || popup->testAttribute(Qt::WA_NoMouseReplay)) {
220 // mouse release event or inside
221 qt_replay_popup_mouse_event = false;
222 } else { // mouse press event
223 QGuiApplicationPrivate::mousePressTime -= 10000; // avoid double click
224 qt_replay_popup_mouse_event = true;
227 // transfer grab back to mouse grabber if any, otherwise release the grab
228 ungrabMouseForPopup(popup);
230 // transfer grab back to keyboard grabber if any, otherwise release the grab
231 ungrabKeyboardForPopup(popup);
235 if (QWidget *fw = active_window->focusWidget()) {
236 if (fw != QApplication::focusWidget()) {
237 fw->setFocus(Qt::PopupFocusReason);
239 QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
240 QCoreApplication::sendEvent(fw, &e);
246 // A popup was closed, so the previous popup gets the focus.
247 QWidget* aw = QApplicationPrivate::popupWidgets->last();
248 if (QWidget *fw = aw->focusWidget())
249 fw->setFocus(Qt::PopupFocusReason);
251 if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
257 void QApplicationPrivate::openPopup(QWidget *popup)
260 if (!popupWidgets) // create list
261 popupWidgets = new QWidgetList;
262 popupWidgets->append(popup); // add to end of list
264 if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
267 // popups are not focus-handled by the window system (the first
268 // popup grabbed the keyboard), so we have to do that manually: A
269 // new popup gets the focus
270 if (popup->focusWidget()) {
271 popup->focusWidget()->setFocus(Qt::PopupFocusReason);
272 } else if (popupWidgets->count() == 1) { // this was the first popup
273 if (QWidget *fw = QApplication::focusWidget()) {
274 QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
275 QApplication::sendEvent(fw, &e);
280 void QApplicationPrivate::initializeMultitouch_sys()
284 void QApplicationPrivate::cleanupMultitouch_sys()
288 static void setPossiblePalette(const QPalette *palette, const char *className)
292 QApplicationPrivate::setPalette_helper(*palette, className, false);
296 void QApplicationPrivate::initializeWidgetPaletteHash()
298 QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
301 setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton");
302 setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton");
303 setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView");
304 setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView");
305 setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPelette), "QMessageBoxLabel");
306 setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar");
307 setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel");
308 setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox");
309 setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuPalette), "QMenu");
310 setPossiblePalette(platformTheme->palette(QPlatformTheme::MenuBarPalette), "QMenuBar");
311 setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextEdit");
312 setPossiblePalette(platformTheme->palette(QPlatformTheme::TextEditPalette), "QTextControl");
313 setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit");
316 void QApplicationPrivate::initializeWidgetFontHash()
318 const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
321 FontHash *fontHash = qt_app_fonts_hash();
322 if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
323 fontHash->insert(QByteArrayLiteral("QMenu"), *font);
324 if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont))
325 fontHash->insert(QByteArrayLiteral("QMenuBar"), *font);
326 if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont))
327 fontHash->insert(QByteArrayLiteral("QMenuItem"), *font);
328 if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont))
329 fontHash->insert(QByteArrayLiteral("QMessageBox"), *font);
330 if (const QFont *font = theme->font(QPlatformTheme::LabelFont))
331 fontHash->insert(QByteArrayLiteral("QLabel"), *font);
332 if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont))
333 fontHash->insert(QByteArrayLiteral("QTipLabel"), *font);
334 if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont))
335 fontHash->insert(QByteArrayLiteral("QTitleBar"), *font);
336 if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont))
337 fontHash->insert(QByteArrayLiteral("QStatusBar"), *font);
338 if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont))
339 fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font);
340 if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont))
341 fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font);
342 if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont))
343 fontHash->insert(QByteArrayLiteral("QPushButton"), *font);
344 if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont))
345 fontHash->insert(QByteArrayLiteral("QToolButton"), *font);
346 if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont))
347 fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font);
348 if (const QFont *font = theme->font(QPlatformTheme::ListViewFont))
349 fontHash->insert(QByteArrayLiteral("QListViewFont"), *font);
350 if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont))
351 fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font);
352 if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont))
353 fontHash->insert(QByteArrayLiteral("QListBox"), *font);
354 if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont))
355 fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font);
356 if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont))
357 fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font);
358 if (const QFont *font = theme->font(QPlatformTheme::SmallFont))
359 fontHash->insert(QByteArrayLiteral("QSmallFont"), *font);
360 if (const QFont *font = theme->font(QPlatformTheme::MiniFont))
361 fontHash->insert(QByteArrayLiteral("QMiniFont"), *font);
364 #ifndef QT_NO_WHEELEVENT
365 void QApplication::setWheelScrollLines(int lines)
367 QApplicationPrivate::wheel_scroll_lines = lines;
370 int QApplication::wheelScrollLines()
372 return QApplicationPrivate::wheel_scroll_lines;
376 static inline int uiEffectToFlag(Qt::UIEffect effect)
380 return QPlatformTheme::GeneralUiEffect;
381 case Qt::UI_AnimateMenu:
382 return QPlatformTheme::AnimateMenuUiEffect;
383 case Qt::UI_FadeMenu:
384 return QPlatformTheme::FadeMenuUiEffect;
385 case Qt::UI_AnimateCombo:
386 return QPlatformTheme::AnimateComboUiEffect;
387 case Qt::UI_AnimateTooltip:
388 return QPlatformTheme::AnimateTooltipUiEffect;
389 case Qt::UI_FadeTooltip:
390 return QPlatformTheme::FadeTooltipUiEffect;
391 case Qt::UI_AnimateToolBox:
392 return QPlatformTheme::AnimateToolBoxUiEffect;
397 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
399 int effectFlags = uiEffectToFlag(effect);
401 if (effectFlags & QPlatformTheme::FadeMenuUiEffect)
402 effectFlags |= QPlatformTheme::AnimateMenuUiEffect;
403 if (effectFlags & QPlatformTheme::FadeTooltipUiEffect)
404 effectFlags |= QPlatformTheme::AnimateTooltipUiEffect;
405 QApplicationPrivate::enabledAnimations |= effectFlags;
407 QApplicationPrivate::enabledAnimations &= ~effectFlags;
411 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
413 return QColormap::instance().depth() >= 16
414 && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect)
415 && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect));
419 QWidget *QApplication::topLevelAt(const QPoint &pos)
421 QList<QScreen *> screens = QGuiApplication::screens();
422 QList<QScreen *>::const_iterator screen = screens.constBegin();
423 QList<QScreen *>::const_iterator end = screens.constEnd();
425 while (screen != end) {
426 if ((*screen)->geometry().contains(pos)) {
427 QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos));
428 return w ? w->widget() : 0;
435 void QApplication::beep()
439 void QApplication::alert(QWidget *, int)
443 void qt_init(QApplicationPrivate *priv, int type)
448 QColormap::initialize();
450 if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
451 QToolTip::setPalette(*toolTipPalette);
452 QApplicationPrivate::initializeWidgetFontHash();
457 static HDC displayDC = 0; // display device context
459 Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC
461 Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
463 displayDC = GetDC(0);
470 QPixmapCache::clear();
471 QColormap::cleanup();
473 QApplicationPrivate::active_window = 0; //### this should not be necessary
476 ReleaseDC(0, displayDC);