Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

Commit

Permalink
Refactor the attempt to surpress Application state changes when focus…
Browse files Browse the repository at this point in the history
… switches between app surfaces
  • Loading branch information
Gerry Boland committed Oct 12, 2016
1 parent 4c7f8f4 commit 65b14dc
Showing 1 changed file with 21 additions and 25 deletions.
46 changes: 21 additions & 25 deletions src/ubuntumirclient/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <qpa/qwindowsysteminterface.h>
#include <QMutexLocker>
#include <QSize>
#include <QAtomicInt>
#include <QtMath>
#include <private/qeglconvenience_p.h>
#include <private/qguiapplication_p.h>
Expand Down Expand Up @@ -401,7 +400,6 @@ class UbuntuSurface
QSurfaceFormat format() const { return mFormat; }

bool mNeedsExposeCatchup;
QAtomicInt mPendingFocusGainedEvents;

QString persistentSurfaceId();

Expand Down Expand Up @@ -566,14 +564,6 @@ void UbuntuSurface::postEvent(const MirEvent *event)
QMutexLocker lock(&mTargetSizeMutex);
mTargetSize.rwidth() = width;
mTargetSize.rheight() = height;
} else if (mir_event_type_surface == eventType) {
auto surfaceEvent = mir_event_get_surface_event(event);
if (mir_surface_attrib_focus == mir_surface_event_get_attribute(surfaceEvent)) {
const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
if (focused) {
mPendingFocusGainedEvents++;
}
}
}

mInput->postEvent(mPlatformWindow, event);
Expand Down Expand Up @@ -661,28 +651,34 @@ void UbuntuWindow::handleSurfaceExposeChange(bool exposed)

void UbuntuWindow::handleSurfaceFocusChanged(bool focused)
{
qCDebug(ubuntumirclient, "handleSurfaceFocusChanged(window=%p, focused=%d, pending=%d)", window(), focused, mSurface->mPendingFocusGainedEvents.load());
qCDebug(ubuntumirclient, "handleSurfaceFocusChanged(window=%p, focused=%d)", window(), focused);

// Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue
// so that we don't deactivate windows prematurely.
if (focused) {
mSurface->mPendingFocusGainedEvents--;
QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
// Check if Mir previously sent an unfocus event to another Window, and if so, remove it from the queue
// as Qt is happier if focus just transferred
auto *queuedActiveWindowEvent =
static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>
(QWindowSystemInterfacePrivate::peekWindowSystemEvent(QWindowSystemInterfacePrivate::ActivatedWindow));

if (queuedActiveWindowEvent && !queuedActiveWindowEvent->activated) {
QWindowSystemInterfacePrivate::removeWindowSystemEvent(queuedActiveWindowEvent);
}

// NB: Since processing of system events is queued, never check qGuiApp->applicationState()
// as it might be outdated. Always call handleApplicationStateChanged() with the latest
// state regardless.
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
// Similarly, check if an ApplicationInactive event is in the queue, and remove it if so.
auto *queuedApplicationStateEvent =
static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>
(QWindowSystemInterfacePrivate::peekWindowSystemEvent(QWindowSystemInterfacePrivate::ApplicationStateChanged));

// Flush events so that we update QGuiApplicationPrivate::focus_window immediately
QWindowSystemInterface::flushWindowSystemEvents();
if (queuedApplicationStateEvent && queuedApplicationStateEvent->newState == Qt::ApplicationInactive) {
QWindowSystemInterfacePrivate::removeWindowSystemEvent(queuedApplicationStateEvent);
} else {
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
}

} else if (mSurface->mPendingFocusGainedEvents == 0 && window() == QGuiApplicationPrivate::focus_window) {
QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
} else {
QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);

// Flush events so that we update QGuiApplicationPrivate::focus_window immediately
QWindowSystemInterface::flushWindowSystemEvents();
}
}

Expand Down

0 comments on commit 65b14dc

Please sign in to comment.