1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qapplication_p.h"
43 #include "qcolormap.h"
44 #include "qpixmapcache.h"
45 #if defined(Q_OS_BLACKBERRY)
46 #include "qeventdispatcher_blackberry_qpa_p.h"
47 #else
48 #if !defined(QT_NO_GLIB)
49 #include "qeventdispatcher_glib_qpa_p.h"
50 #endif
51 #include "qeventdispatcher_qpa_p.h"
52 #endif
53 #ifndef QT_NO_CURSOR
54 #include "private/qcursor_p.h"
55 #endif
56 
57 #include "private/qwidget_p.h"
58 #include "private/qevent_p.h"
59 
60 #include "qgenericpluginfactory_qpa.h"
61 #include "qplatformintegrationfactory_qpa_p.h"
62 #include <qdesktopwidget.h>
63 
64 #include <qinputcontext.h>
65 #include <QPlatformCursor>
66 #include <qdebug.h>
67 #include <QWindowSystemInterface>
68 #include "qwindowsysteminterface_qpa_p.h"
69 #include <QPlatformIntegration>
70 
71 #include "qdesktopwidget_qpa_p.h"
72 
73 QT_BEGIN_NAMESPACE
74 
75 static QString appName;
76 static QString appFont;
77 
78 QWidget *qt_button_down = 0;                     // widget got last button-down
79 
80 static bool app_do_modal = false;
81 extern QWidgetList *qt_modal_stack;              // stack of modal widgets
82 
83 int qt_last_x = 0;
84 int qt_last_y = 0;
85 QPointer<QWidget> qt_last_mouse_receiver = 0;
86 
87 static Qt::MouseButtons buttons = Qt::NoButton;
88 static ulong mousePressTime;
89 static Qt::MouseButton mousePressButton = Qt::NoButton;
90 static int mousePressX;
91 static int mousePressY;
92 static int mouse_double_click_distance = 5;
93 
processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e)94 void QApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
95 {
96     switch(e->type) {
97     case QWindowSystemInterfacePrivate::Mouse:
98         QApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
99         break;
100     case QWindowSystemInterfacePrivate::Wheel:
101         QApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
102         break;
103     case QWindowSystemInterfacePrivate::Key:
104         QApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
105         break;
106     case QWindowSystemInterfacePrivate::Touch:
107         QApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
108         break;
109     case QWindowSystemInterfacePrivate::GeometryChange:
110         QApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
111         break;
112     case QWindowSystemInterfacePrivate::Enter:
113         QApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
114         break;
115     case QWindowSystemInterfacePrivate::Leave:
116         QApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
117         break;
118     case QWindowSystemInterfacePrivate::ActivatedWindow:
119         QApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
120         break;
121     case QWindowSystemInterfacePrivate::WindowStateChanged:
122         QApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
123         break;
124     case QWindowSystemInterfacePrivate::Close:
125         QApplicationPrivate::processCloseEvent(
126                 static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
127         break;
128     case QWindowSystemInterfacePrivate::ScreenCountChange:
129         QApplicationPrivate::reportScreenCount(
130                 static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
131         break;
132     case QWindowSystemInterfacePrivate::ScreenGeometry:
133         QApplicationPrivate::reportGeometryChange(
134                 static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
135         break;
136     case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
137         QApplicationPrivate::reportAvailableGeometryChange(
138                 static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
139         break;
140     case QWindowSystemInterfacePrivate::LocaleChange:
141         QApplicationPrivate::reportLocaleChange();
142         break;
143     case QWindowSystemInterfacePrivate::PlatformPanel:
144         QApplicationPrivate::processPlatformPanelEvent(
145                 static_cast<QWindowSystemInterfacePrivate::PlatformPanelEvent *>(e));
146         break;
147     default:
148         qWarning() << "Unknown user input event type:" << e->type;
149         break;
150     }
151 }
152 
processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent * wse)153 void QApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
154 {
155     if (wse->tlw.isNull())
156        return;
157 
158     QWidget *tlw = wse->tlw.data();
159     if (!tlw->isWindow())
160         return;
161 
162     QWindowStateChangeEvent e(tlw->windowState());
163     tlw->setWindowState(wse->newState);
164     QApplication::sendSpontaneousEvent(tlw, &e);
165 }
166 
appName() const167 QString QApplicationPrivate::appName() const
168 {
169     return QT_PREPEND_NAMESPACE(appName);
170 }
171 
createEventDispatcher()172 void QApplicationPrivate::createEventDispatcher()
173 {
174     Q_Q(QApplication);
175 #if defined(Q_OS_BLACKBERRY)
176     eventDispatcher = new QEventDispatcherBlackberryQPA(q);
177 #else
178 #if !defined(QT_NO_GLIB)
179     if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
180         eventDispatcher = new QPAEventDispatcherGlib(q);
181     else
182 #endif
183     eventDispatcher = new QEventDispatcherQPA(q);
184 #endif
185 }
186 
qt_try_modal(QWidget * widget,QEvent::Type type)187 static bool qt_try_modal(QWidget *widget, QEvent::Type type)
188 {
189     QWidget * top = 0;
190 
191     if (QApplicationPrivate::tryModalHelper(widget, &top))
192         return true;
193 
194     bool block_event  = false;
195     bool paint_event = false;
196 
197     switch (type) {
198 #if 0
199     case QEvent::Focus:
200         if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
201             break;
202         // drop through
203 #endif
204     case QEvent::MouseButtonPress:                        // disallow mouse/key events
205     case QEvent::MouseButtonRelease:
206     case QEvent::MouseMove:
207     case QEvent::KeyPress:
208     case QEvent::KeyRelease:
209     case QEvent::PlatformPanel:
210         block_event         = true;
211         break;
212     default:
213         break;
214     }
215 
216     if ((block_event || paint_event) && top->parentWidget() == 0)
217         top->raise();
218 
219     return !block_event;
220 }
221 
222 
223 
enterModal_sys(QWidget * widget)224 void QApplicationPrivate::enterModal_sys(QWidget *widget)
225 {
226     if (!qt_modal_stack)
227         qt_modal_stack = new QWidgetList;
228     qt_modal_stack->insert(0, widget);
229     app_do_modal = true;
230 }
231 
leaveModal_sys(QWidget * widget)232 void QApplicationPrivate::leaveModal_sys(QWidget *widget )
233 {
234     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
235         if (qt_modal_stack->isEmpty()) {
236             delete qt_modal_stack;
237             qt_modal_stack = 0;
238         }
239     }
240     app_do_modal = qt_modal_stack != 0;
241 }
242 
modalState()243 bool QApplicationPrivate::modalState()
244 {
245     return app_do_modal;
246 }
247 
closePopup(QWidget * popup)248 void QApplicationPrivate::closePopup(QWidget *popup)
249 {
250     Q_Q(QApplication);
251     if (!popupWidgets)
252         return;
253     popupWidgets->removeAll(popup);
254 
255 //###
256 //     if (popup == qt_popup_down) {
257 //         qt_button_down = 0;
258 //         qt_popup_down = 0;
259 //     }
260 
261     if (QApplicationPrivate::popupWidgets->count() == 0) {                // this was the last popup
262         delete QApplicationPrivate::popupWidgets;
263         QApplicationPrivate::popupWidgets = 0;
264 
265         //### replay mouse event?
266 
267         //### transfer/release mouse grab
268 
269         //### transfer/release keyboard grab
270 
271         //give back focus
272 
273         if (active_window) {
274             if (QWidget *fw = active_window->focusWidget()) {
275                 if (fw != QApplication::focusWidget()) {
276                     fw->setFocus(Qt::PopupFocusReason);
277                 } else {
278                     QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
279                     q->sendEvent(fw, &e);
280                 }
281             }
282         }
283 
284     } else {
285         // A popup was closed, so the previous popup gets the focus.
286 
287         QWidget* aw = QApplicationPrivate::popupWidgets->last();
288         if (QWidget *fw = aw->focusWidget())
289             fw->setFocus(Qt::PopupFocusReason);
290 
291         //### regrab the keyboard and mouse in case 'popup' lost the grab
292 
293 
294     }
295 
296 }
297 
298 static int openPopupCount = 0;
openPopup(QWidget * popup)299 void QApplicationPrivate::openPopup(QWidget *popup)
300 {
301     openPopupCount++;
302     if (!popupWidgets) {                        // create list
303         popupWidgets = new QWidgetList;
304 
305         /* only grab if you are the first/parent popup */
306         //####   ->grabMouse(popup,true);
307         //####   ->grabKeyboard(popup,true);
308         //### popupGrabOk = true;
309     }
310     popupWidgets->append(popup);                // add to end of list
311 
312     // popups are not focus-handled by the window system (the first
313     // popup grabbed the keyboard), so we have to do that manually: A
314     // new popup gets the focus
315     if (popup->focusWidget()) {
316         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
317     } else if (popupWidgets->count() == 1) { // this was the first popup
318         if (QWidget *fw = QApplication::focusWidget()) {
319             QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
320             QApplication::sendEvent(fw, &e);
321         }
322     }
323 }
324 
initializeMultitouch_sys()325 void QApplicationPrivate::initializeMultitouch_sys()
326 {
327 }
328 
cleanupMultitouch_sys()329 void QApplicationPrivate::cleanupMultitouch_sys()
330 {
331 }
332 
initializeWidgetPaletteHash()333 void QApplicationPrivate::initializeWidgetPaletteHash()
334 {
335 }
336 
setCursorFlashTime(int msecs)337 void QApplication::setCursorFlashTime(int msecs)
338 {
339     QApplicationPrivate::cursor_flash_time = msecs;
340 }
341 
cursorFlashTime()342 int QApplication::cursorFlashTime()
343 {
344     return QApplicationPrivate::cursor_flash_time;
345 }
346 
setDoubleClickInterval(int ms)347 void QApplication::setDoubleClickInterval(int ms)
348 {
349     QApplicationPrivate::mouse_double_click_time = ms;
350 }
351 
doubleClickInterval()352 int QApplication::doubleClickInterval()
353 {
354     return QApplicationPrivate::mouse_double_click_time;
355 }
356 
setKeyboardInputInterval(int ms)357 void QApplication::setKeyboardInputInterval(int ms)
358 {
359     QApplicationPrivate::keyboard_input_time = ms;
360 }
361 
keyboardInputInterval()362 int QApplication::keyboardInputInterval()
363 {
364     return QApplicationPrivate::keyboard_input_time;
365 }
366 
367 #ifndef QT_NO_WHEELEVENT
setWheelScrollLines(int lines)368 void QApplication::setWheelScrollLines(int lines)
369 {
370     QApplicationPrivate::wheel_scroll_lines = lines;
371 }
372 
wheelScrollLines()373 int QApplication::wheelScrollLines()
374 {
375     return QApplicationPrivate::wheel_scroll_lines;
376 }
377 #endif
378 
setEffectEnabled(Qt::UIEffect effect,bool enable)379 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
380 {
381     switch (effect) {
382     case Qt::UI_AnimateMenu:
383         QApplicationPrivate::animate_menu = enable;
384         break;
385     case Qt::UI_FadeMenu:
386         if (enable)
387             QApplicationPrivate::animate_menu = true;
388         QApplicationPrivate::fade_menu = enable;
389         break;
390     case Qt::UI_AnimateCombo:
391         QApplicationPrivate::animate_combo = enable;
392         break;
393     case Qt::UI_AnimateTooltip:
394         QApplicationPrivate::animate_tooltip = enable;
395         break;
396     case Qt::UI_FadeTooltip:
397         if (enable)
398             QApplicationPrivate::animate_tooltip = true;
399         QApplicationPrivate::fade_tooltip = enable;
400         break;
401     case Qt::UI_AnimateToolBox:
402         QApplicationPrivate::animate_toolbox = enable;
403         break;
404     default:
405         QApplicationPrivate::animate_ui = enable;
406         break;
407     }
408 }
409 
isEffectEnabled(Qt::UIEffect effect)410 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
411 {
412     if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
413         return false;
414 
415     switch(effect) {
416     case Qt::UI_AnimateMenu:
417         return QApplicationPrivate::animate_menu;
418     case Qt::UI_FadeMenu:
419         return QApplicationPrivate::fade_menu;
420     case Qt::UI_AnimateCombo:
421         return QApplicationPrivate::animate_combo;
422     case Qt::UI_AnimateTooltip:
423         return QApplicationPrivate::animate_tooltip;
424     case Qt::UI_FadeTooltip:
425         return QApplicationPrivate::fade_tooltip;
426     case Qt::UI_AnimateToolBox:
427         return QApplicationPrivate::animate_toolbox;
428     default:
429         return QApplicationPrivate::animate_ui;
430     }
431 }
432 
433 #ifndef QT_NO_CURSOR
setOverrideCursor(const QCursor & cursor)434 void QApplication::setOverrideCursor(const QCursor &cursor)
435 {
436     qApp->d_func()->cursor_list.prepend(cursor);
437     qt_qpa_set_cursor(0, false);
438 }
439 
restoreOverrideCursor()440 void QApplication::restoreOverrideCursor()
441 {
442     if (qApp->d_func()->cursor_list.isEmpty())
443         return;
444     qApp->d_func()->cursor_list.removeFirst();
445     qt_qpa_set_cursor(0, false);
446 }
447 
448 #endif// QT_NO_CURSOR
449 
topLevelAt(const QPoint & pos)450 QWidget *QApplication::topLevelAt(const QPoint &pos)
451 {
452     QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
453 
454     QList<QPlatformScreen *> screens = pi->screens();
455     QList<QPlatformScreen *>::const_iterator screen = screens.constBegin();
456     QList<QPlatformScreen *>::const_iterator end = screens.constEnd();
457 
458     // The first screen in a virtual environment should know about all top levels
459     if (pi->isVirtualDesktop()) {
460         QWidget *w = (*screen)->topLevelAt(pos);
461         return w;
462     }
463 
464     while (screen != end) {
465         if ((*screen)->geometry().contains(pos))
466             return (*screen)->topLevelAt(pos);
467         ++screen;
468     }
469     return 0;
470 }
471 
beep()472 void QApplication::beep()
473 {
474 }
475 
alert(QWidget *,int)476 void QApplication::alert(QWidget *, int)
477 {
478 }
479 
480 /*!
481     \internal
482 */
platformNativeInterface()483 QPlatformNativeInterface *QApplication::platformNativeInterface()
484 {
485     QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
486     return pi ? pi->nativeInterface() : 0;
487 }
488 
init_platform(const QString & name,const QString & platformPluginPath)489 static void init_platform(const QString &name, const QString &platformPluginPath)
490 {
491     QApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
492     if (!QApplicationPrivate::platform_integration) {
493         QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
494         QString fatalMessage =
495             QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
496         foreach(QString key, keys) {
497             fatalMessage.append(key + QString::fromLatin1("\n"));
498         }
499         qFatal("%s", fatalMessage.toLocal8Bit().constData());
500 
501     }
502 
503 }
504 
505 
cleanup_platform()506 static void cleanup_platform()
507 {
508     delete QApplicationPrivate::platform_integration;
509     QApplicationPrivate::platform_integration = 0;
510 }
511 
init_plugins(const QList<QByteArray> pluginList)512 static void init_plugins(const QList<QByteArray> pluginList)
513 {
514     for (int i = 0; i < pluginList.count(); ++i) {
515         QByteArray pluginSpec = pluginList.at(i);
516         qDebug() << "init_plugins" << i << pluginSpec;
517         int colonPos = pluginSpec.indexOf(':');
518         QObject *plugin;
519         if (colonPos < 0)
520             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
521         else
522             plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
523                                                    QLatin1String(pluginSpec.mid(colonPos+1)));
524         qDebug() << "	created" << plugin;
525     }
526 }
527 
528 #ifndef QT_NO_QWS_INPUTMETHODS
529 class QDummyInputContext : public QInputContext
530 {
531 public:
QDummyInputContext(QObject * parent=0)532     explicit QDummyInputContext(QObject* parent = 0) : QInputContext(parent) {}
~QDummyInputContext()533     ~QDummyInputContext() {}
identifierName()534     QString identifierName() { return QString(); }
language()535     QString language() { return QString(); }
536 
reset()537     void reset() {}
isComposing() const538     bool isComposing() const { return false; }
539 
540 };
541 #endif // QT_NO_QWS_INPUTMETHODS
542 
qt_init(QApplicationPrivate * priv,int type)543 void qt_init(QApplicationPrivate *priv, int type)
544 {
545     Q_UNUSED(type);
546 
547     qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
548     char *p;
549     char **argv = priv->argv;
550     int argc = priv->argc;
551 
552     if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
553         p = strrchr(argv[0], '/');
554         appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
555     }
556 
557     QList<QByteArray> pluginList;
558     QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
559     QByteArray platformName;
560 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
561     platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
562 #endif
563     QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
564     if (!platformNameEnv.isEmpty()) {
565         platformName = platformNameEnv;
566     }
567 
568     // Get command line params
569 
570     int j = argc ? 1 : 0;
571     for (int i=1; i<argc; i++) {
572         if (argv[i] && *argv[i] != '-') {
573             argv[j++] = argv[i];
574             continue;
575         }
576         QByteArray arg = argv[i];
577         if (arg == "-fn" || arg == "-font") {
578             if (++i < argc)
579                 appFont = QString::fromLocal8Bit(argv[i]);
580         } else if (arg == "-platformpluginpath") {
581             if (++i < argc)
582                 platformPluginPath = QLatin1String(argv[i]);
583         } else if (arg == "-platform") {
584             if (++i < argc)
585                 platformName = argv[i];
586         } else if (arg == "-plugin") {
587             if (++i < argc)
588                 pluginList << argv[i];
589         } else {
590             argv[j++] = argv[i];
591         }
592     }
593 
594     if (j < priv->argc) {
595         priv->argv[j] = 0;
596         priv->argc = j;
597     }
598 
599 #if 0
600     QByteArray pluginEnv = qgetenv("QT_QPA_PLUGINS");
601     if (!pluginEnv.isEmpty()) {
602         pluginList.append(pluginEnv.split(';'));
603     }
604 #endif
605 
606     init_platform(QLatin1String(platformName), platformPluginPath);
607     init_plugins(pluginList);
608 
609     QColormap::initialize();
610     QFont::initialize();
611 #ifndef QT_NO_CURSOR
612 //    QCursorData::initialize();
613 #endif
614 
615     qApp->setObjectName(appName);
616 
617 #ifndef QT_NO_QWS_INPUTMETHODS
618         qApp->setInputContext(new QDummyInputContext(qApp));
619 #endif
620 }
621 
qt_cleanup()622 void qt_cleanup()
623 {
624     cleanup_platform();
625 
626     QPixmapCache::clear();
627 #ifndef QT_NO_CURSOR
628     QCursorData::cleanup();
629 #endif
630     QFont::cleanup();
631     QColormap::cleanup();
632     delete QApplicationPrivate::inputContext;
633     QApplicationPrivate::inputContext = 0;
634 
635     QApplicationPrivate::active_window = 0; //### this should not be necessary
636 }
637 
638 
639 #ifdef QT3_SUPPORT
setMainWidget(QWidget * mainWidget)640 void QApplication::setMainWidget(QWidget *mainWidget)
641 {
642     QApplicationPrivate::main_widget = mainWidget;
643     if (QApplicationPrivate::main_widget && windowIcon().isNull()
644         && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
645         setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
646 }
647 #endif
648 
processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent * e)649 void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
650 {
651     static QWeakPointer<QWidget> implicit_mouse_grabber;
652 
653     QEvent::Type type;
654     // move first
655     Qt::MouseButtons stateChange = e->buttons ^ buttons;
656     if (e->globalPos != QPoint(qt_last_x, qt_last_y) && (stateChange != Qt::NoButton)) {
657         QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
658                 new QWindowSystemInterfacePrivate::MouseEvent(e->widget.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
659         QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
660         stateChange = Qt::NoButton;
661     }
662 
663     QWidget * tlw = e->widget.data();
664 
665     QPoint localPoint = e->localPos;
666     QPoint globalPoint = e->globalPos;
667     QWidget *mouseWindow = tlw;
668 
669     Qt::MouseButton button = Qt::NoButton;
670 
671 
672     if (qt_last_x != globalPoint.x() || qt_last_y != globalPoint.y()) {
673         type = QEvent::MouseMove;
674         qt_last_x = globalPoint.x();
675         qt_last_y = globalPoint.y();
676         if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
677             qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
678             mousePressButton = Qt::NoButton;
679     }
680     else { // check to see if a new button has been pressed/released
681         for (int check = Qt::LeftButton;
682              check <= Qt::XButton2;
683              check = check << 1) {
684             if (check & stateChange) {
685                 button = Qt::MouseButton(check);
686                 break;
687             }
688         }
689         if (button == Qt::NoButton) {
690             // Ignore mouse events that don't change the current state
691             return;
692         }
693         buttons = e->buttons;
694         if (button & e->buttons) {
695             if ((e->timestamp - mousePressTime) < static_cast<ulong>(QApplication::doubleClickInterval()) && button == mousePressButton) {
696                 type = QEvent::MouseButtonDblClick;
697                 mousePressButton = Qt::NoButton;
698             }
699             else {
700                 type = QEvent::MouseButtonPress;
701                 mousePressTime = e->timestamp;
702                 mousePressButton = button;
703                 mousePressX = qt_last_x;
704                 mousePressY = qt_last_y;
705             }
706         }
707         else
708             type = QEvent::MouseButtonRelease;
709     }
710 
711     if (self->inPopupMode()) {
712         //popup mouse handling is magical...
713         mouseWindow = qApp->activePopupWidget();
714 
715         implicit_mouse_grabber.clear();
716         //### how should popup mode and implicit mouse grab interact?
717 
718     } else if (tlw && app_do_modal && !qt_try_modal(tlw, QEvent::MouseButtonRelease) ) {
719         //even if we're blocked by modality, we should deliver the mouse release event..
720         //### this code is not completely correct: multiple buttons can be pressed simultaneously
721         if (!(implicit_mouse_grabber && buttons == Qt::NoButton)) {
722             //qDebug() << "modal blocked mouse event to" << tlw;
723             return;
724         }
725     }
726 
727     // find the tlw if we didn't get it from the plugin
728     if (!mouseWindow) {
729         mouseWindow = QApplication::topLevelAt(globalPoint);
730     }
731 
732     if (!mouseWindow && !implicit_mouse_grabber)
733         mouseWindow = QApplication::desktop();
734 
735     if (mouseWindow && mouseWindow != tlw) {
736         //we did not get a sensible localPoint from the window system, so let's calculate it
737         localPoint = mouseWindow->mapFromGlobal(globalPoint);
738     }
739 
740     // which child should have it?
741     QWidget *mouseWidget = mouseWindow;
742     if (mouseWindow) {
743         QWidget *w =  mouseWindow->childAt(localPoint);
744         if (w) {
745             mouseWidget = w;
746         }
747     }
748 
749     //handle implicit mouse grab
750     if (type == QEvent::MouseButtonPress && !implicit_mouse_grabber) {
751         implicit_mouse_grabber = mouseWidget;
752 
753         Q_ASSERT(mouseWindow);
754         mouseWindow->activateWindow(); //focus
755     } else if (implicit_mouse_grabber) {
756         mouseWidget = implicit_mouse_grabber.data();
757         mouseWindow = mouseWidget->window();
758         if (mouseWindow != tlw)
759             localPoint = mouseWindow->mapFromGlobal(globalPoint);
760     }
761 
762     Q_ASSERT(mouseWidget);
763 
764     //localPoint is local to mouseWindow, but it needs to be local to mouseWidget
765     localPoint = mouseWidget->mapFrom(mouseWindow, localPoint);
766 
767     if (buttons == Qt::NoButton) {
768         //qDebug() << "resetting mouse grabber";
769         implicit_mouse_grabber.clear();
770     }
771 
772     if (mouseWidget != qt_last_mouse_receiver) {
773         dispatchEnterLeave(mouseWidget, qt_last_mouse_receiver);
774         qt_last_mouse_receiver = mouseWidget;
775     }
776 
777     // Remember, we might enter a modal event loop when sending the event,
778     // so think carefully before adding code below this point.
779 
780 
781     QMouseEvent ev(type, localPoint, globalPoint, button, buttons, QApplication::keyboardModifiers());
782 
783     QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
784     foreach (QWeakPointer<QPlatformCursor> cursor, cursors) {
785         if (cursor)
786             cursor.data()->pointerEvent(ev);
787     }
788 
789     // qDebug() << "sending mouse event" << ev.type() << localPoint << globalPoint << ev.button() << ev.buttons() << mouseWidget << "mouse grabber" << implicit_mouse_grabber;
790 
791     int oldOpenPopupCount = openPopupCount;
792     QApplication::sendSpontaneousEvent(mouseWidget, &ev);
793 
794 #ifndef QT_NO_CONTEXTMENU
795     if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
796         QContextMenuEvent e(QContextMenuEvent::Mouse, localPoint, globalPoint, QApplication::keyboardModifiers());
797         QApplication::sendSpontaneousEvent(mouseWidget, &e);
798     }
799 #endif // QT_NO_CONTEXTMENU
800 }
801 
processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent * e)802 void QApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e)
803 {
804     if (!e->widget)
805         return;
806 
807     if (app_do_modal && !qt_try_modal(e->widget.data(), QEvent::PlatformPanel)) {
808         // a modal window is blocking this window, don't allow events through
809         return;
810     }
811 
812     QEvent ev(QEvent::PlatformPanel);
813     QApplication::sendSpontaneousEvent(e->widget.data(), &ev);
814 }
815 
816 //### there's a lot of duplicated logic here -- refactoring required!
817 
processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent * e)818 void QApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
819 {
820 
821     if (!e->widget)
822         return;
823 
824 //    QPoint localPoint = ev.pos();
825     QPoint globalPoint = e->globalPos;
826 //    bool trustLocalPoint = !!tlw; //is there something the local point can be local to?
827     QWidget *mouseWidget;
828 
829     qt_last_x = globalPoint.x();
830     qt_last_y = globalPoint.y();
831 
832      QWidget *mouseWindow = e->widget.data();
833 
834      // find the tlw if we didn't get it from the plugin
835      if (!mouseWindow) {
836          mouseWindow = QApplication::topLevelAt(globalPoint);
837      }
838 
839      if (!mouseWindow)
840          return;
841 
842      mouseWidget = mouseWindow;
843 
844      if (app_do_modal && !qt_try_modal(mouseWindow, QEvent::Wheel) ) {
845          qDebug() << "modal blocked wheel event" << mouseWindow;
846          return;
847      }
848      QPoint p = mouseWindow->mapFromGlobal(globalPoint);
849      QWidget *w = mouseWindow->childAt(p);
850      if (w) {
851          mouseWidget = w;
852          p = mouseWidget->mapFromGlobal(globalPoint);
853      }
854 
855      QWheelEvent ev(p, globalPoint, e->delta, buttons, QApplication::keyboardModifiers(),
856                    e->orient);
857      QApplication::sendSpontaneousEvent(mouseWidget, &ev);
858 }
859 
860 
861 
862 // Remember, Qt convention is:  keyboard state is state *before*
863 
processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent * e)864 void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
865 {
866     QWidget *focusW = 0;
867     if (self->inPopupMode()) {
868         QWidget *popupW = qApp->activePopupWidget();
869         focusW = popupW->focusWidget() ? popupW->focusWidget() : popupW;
870     }
871     if (!focusW)
872         focusW = QApplication::focusWidget();
873     if (!focusW) {
874         focusW = e->widget.data();
875     }
876     if (!focusW)
877         focusW = QApplication::activeWindow();
878 
879     //qDebug() << "handleKeyEvent" << hex << e->key() << e->modifiers() << e->text() << "widget" << focusW;
880 
881     if (!focusW)
882         return;
883     if (app_do_modal && !qt_try_modal(focusW, e->keyType))
884         return;
885 
886     if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
887         QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
888                        e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
889         QApplication::sendSpontaneousEvent(focusW, &ev);
890     } else {
891         QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
892         QApplication::sendSpontaneousEvent(focusW, &ev);
893     }
894 }
895 
processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent * e)896 void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
897 {
898     if (!e->enter)
899         return;
900 
901     QApplicationPrivate::dispatchEnterLeave(e->enter.data(),0);
902     qt_last_mouse_receiver = e->enter.data();
903 }
904 
processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent * e)905 void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
906 {
907     if (!e->leave)
908         return;
909 
910     QApplicationPrivate::dispatchEnterLeave(0,qt_last_mouse_receiver);
911 
912     if (e->leave.data() && !e->leave.data()->isAncestorOf(qt_last_mouse_receiver)) //(???) this should not happen
913         QApplicationPrivate::dispatchEnterLeave(0, e->leave.data());
914     qt_last_mouse_receiver = 0;
915 
916 }
917 
processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent * e)918 void QApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
919 {
920     QApplication::setActiveWindow(e->activated.data());
921 }
922 
processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent * e)923 void QApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
924 {
925     if (e->tlw.isNull())
926        return;
927     QWidget *tlw = e->tlw.data();
928     if (!tlw->isWindow())
929         return; //geo of native child widgets is controlled by lighthouse
930                 //so we already have sent the events; besides this new rect
931                 //is not mapped to parent
932 
933     QRect newRect = e->newGeometry;
934     QRect cr(tlw->geometry());
935     bool isResize = cr.size() != newRect.size();
936     bool isMove = cr.topLeft() != newRect.topLeft();
937     tlw->data->crect = newRect;
938     if (isResize) {
939         QResizeEvent e(tlw->data->crect.size(), cr.size());
940         QApplication::sendSpontaneousEvent(tlw, &e);
941         tlw->update();
942     }
943 
944     if (isMove) {
945         //### frame geometry
946         QMoveEvent e(tlw->data->crect.topLeft(), cr.topLeft());
947         QApplication::sendSpontaneousEvent(tlw, &e);
948     }
949 }
950 
processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent * e)951 void QApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
952 {
953     if (e->topLevel.isNull()) {
954         //qDebug() << "QApplicationPrivate::processCloseEvent NULL";
955         return;
956     }
957     e->topLevel.data()->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
958 }
959 
processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent * e)960 void QApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
961 {
962     translateRawTouchEvent(e->widget.data(), e->devType, e->points);
963 }
964 
reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent * e)965 void QApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e)
966 {
967     // This operation only makes sense after the QApplication constructor runs
968     if (QCoreApplication::startingUp())
969         return;
970 
971     QApplication::desktop()->d_func()->updateScreenList();
972     // signal anything listening for creation or deletion of screens
973     QDesktopWidget *desktop = QApplication::desktop();
974     emit desktop->screenCountChanged(e->count);
975 }
976 
reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent * e)977 void QApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
978 {
979     // This operation only makes sense after the QApplication constructor runs
980     if (QCoreApplication::startingUp())
981         return;
982 
983     QApplication::desktop()->d_func()->updateScreenList();
984 
985     // signal anything listening for screen geometry changes
986     QDesktopWidget *desktop = QApplication::desktop();
987     emit desktop->resized(e->index);
988 
989     // make sure maximized and fullscreen windows are updated
990     QWidgetList list = QApplication::topLevelWidgets();
991     for (int i = list.size() - 1; i >= 0; --i) {
992         QWidget *w = list.at(i);
993         if (w->isFullScreen())
994             w->d_func()->setFullScreenSize_helper();
995         else if (w->isMaximized())
996             w->d_func()->setMaxWindowState_helper();
997     }
998 }
999 
reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent * e)1000 void QApplicationPrivate::reportAvailableGeometryChange(
1001         QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
1002 {
1003     // This operation only makes sense after the QApplication constructor runs
1004     if (QCoreApplication::startingUp())
1005         return;
1006 
1007     QApplication::desktop()->d_func()->updateScreenList();
1008 
1009     // signal anything listening for screen geometry changes
1010     QDesktopWidget *desktop = QApplication::desktop();
1011     emit desktop->workAreaResized(e->index);
1012 
1013     // make sure maximized and fullscreen windows are updated
1014     QWidgetList list = QApplication::topLevelWidgets();
1015     for (int i = list.size() - 1; i >= 0; --i) {
1016         QWidget *w = list.at(i);
1017         if (w->isFullScreen())
1018             w->d_func()->setFullScreenSize_helper();
1019         else if (w->isMaximized())
1020             w->d_func()->setMaxWindowState_helper();
1021     }
1022 }
1023 
reportLocaleChange()1024 void QApplicationPrivate::reportLocaleChange()
1025 {
1026     QApplication::sendSpontaneousEvent( qApp, new QEvent( QEvent::LocaleChange ) );
1027 }
1028 
1029 QT_END_NAMESPACE
1030