~gerboland/qtubuntu/active-decision-refactor

« back to all changes in this revision

Viewing changes to src/ubuntumirclient/window.cpp

  • Committer: Bileto Bot
  • Author(s): Nick Dedekind
  • Date: 2016-09-28 10:51:37 UTC
  • mfrom: (342.1.4 qtubuntu)
  • Revision ID: ci-train-bot@canonical.com-20160928105137-97rqdqh6zfb5ts56
Moved focus handling to UbuntuWindow to ensure focus optimization supports multiple windows rather than being application global. (LP: #1623861)

Approved by: Daniel d'Andrada, Unity8 CI Bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <qpa/qwindowsysteminterface.h>
28
28
#include <QMutexLocker>
29
29
#include <QSize>
 
30
#include <QAtomicInt>
30
31
#include <QtMath>
31
32
#include <private/qeglconvenience_p.h>
 
33
#include <private/qguiapplication_p.h>
32
34
 
33
35
// Platform API
34
36
#include <ubuntu/application/instance.h>
179
181
            //NOTE: We cannot have a parentless popup -
180
182
            //try using the last surface to receive input as that will most likely be
181
183
            //the one that caused this popup to be created
182
 
            parent = input->lastFocusedWindow();
 
184
            parent = input->lastInputWindow();
183
185
        }
184
186
        if (parent) {
185
187
            auto pos = geom.topLeft();
399
401
    QSurfaceFormat format() const { return mFormat; }
400
402
 
401
403
    bool mNeedsExposeCatchup;
 
404
    QAtomicInt mPendingFocusGainedEvents;
402
405
 
403
406
    QString persistentSurfaceId();
404
407
 
549
552
 
550
553
void UbuntuSurface::postEvent(const MirEvent *event)
551
554
{
552
 
    if (mir_event_type_resize == mir_event_get_type(event)) {
 
555
    const auto eventType = mir_event_get_type(event);
 
556
    if (mir_event_type_resize == eventType) {
553
557
        // TODO: The current event queue just accumulates all resize events;
554
558
        // It would be nicer if we could update just one event if that event has not been dispatched.
555
559
        // As a workaround, we use the width/height as an identifier of this latest event
562
566
        QMutexLocker lock(&mTargetSizeMutex);
563
567
        mTargetSize.rwidth() = width;
564
568
        mTargetSize.rheight() = height;
 
569
    } else if (mir_event_type_surface == eventType) {
 
570
        auto surfaceEvent = mir_event_get_surface_event(event);
 
571
        if (mir_surface_attrib_focus == mir_surface_event_get_attribute(surfaceEvent)) {
 
572
            const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
 
573
            if (focused) {
 
574
                mPendingFocusGainedEvents++;
 
575
            }
 
576
        }
565
577
    }
566
578
 
567
579
    mInput->postEvent(mPlatformWindow, event);
647
659
    QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
648
660
}
649
661
 
650
 
void UbuntuWindow::handleSurfaceFocused()
 
662
void UbuntuWindow::handleSurfaceFocusChanged(bool focused)
651
663
{
652
 
    qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window());
653
 
 
 
664
    qCDebug(ubuntumirclient, "handleSurfaceFocusChanged(window=%p, focused=%d, pending=%d)", window(), focused, mSurface->mPendingFocusGainedEvents.load());
 
665
 
 
666
    // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue
 
667
    // so that we don't deactivate windows prematurely.
 
668
    if (focused) {
 
669
        mSurface->mPendingFocusGainedEvents--;
 
670
        QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
 
671
 
 
672
        // NB: Since processing of system events is queued, never check qGuiApp->applicationState()
 
673
        //     as it might be outdated. Always call handleApplicationStateChanged() with the latest
 
674
        //     state regardless.
 
675
        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
 
676
 
 
677
        // Flush events so that we update QGuiApplicationPrivate::focus_window immediately
 
678
        QWindowSystemInterface::flushWindowSystemEvents();
 
679
 
 
680
    } else if (mSurface->mPendingFocusGainedEvents == 0 && window() == QGuiApplicationPrivate::focus_window) {
 
681
        QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
 
682
        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
 
683
 
 
684
        // Flush events so that we update QGuiApplicationPrivate::focus_window immediately
 
685
        QWindowSystemInterface::flushWindowSystemEvents();
 
686
    }
654
687
}
655
688
 
656
689
void UbuntuWindow::handleSurfaceVisibilityChanged(bool visible)