Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosapplicationstatetracker.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qohosapplicationstatetracker.h>
5
6#include <QtCore/private/qohoslogger_p.h>
7#include <QtGui/private/qguiapplication_p.h>
8#include <QtGui/qwindow.h>
9#include <memory>
10#include <optional>
11#include <qohosplatformwindow.h>
12#include <qohosutils.h>
13#include <qpa/qwindowsysteminterface_p.h>
14#include <render/qohosview.h>
15#include <set>
16#include <tuple>
17
19
20namespace
21{
22
23using WindowSystemEventType = QWindowSystemInterfacePrivate::EventType;
24using WindowSystemEvent = QWindowSystemInterfacePrivate::WindowSystemEvent;
25using ExposeEvent = QWindowSystemInterfacePrivate::ExposeEvent;
26using ApplicationStateChangedEvent = QWindowSystemInterfacePrivate::ApplicationStateChangedEvent;
27
33
34class ApplicationStateTracker final : public QWindowSystemEventHandler
35{
36public:
37 bool sendEvent(WindowSystemEvent *event) override;
38
39private:
40 ProcessEventResult processExposeEvent(ExposeEvent *event);
41 ProcessEventResult processApplicationStateChangedEvent(ApplicationStateChangedEvent *event);
42
43 void startTrackingViewIfNeeded(QOhosView *view);
44 void tryUpdateApplicationState();
45
46 std::set<QOhosView *> m_trackedViews;
47 std::set<QOhosView *> m_visibleViews;
48
49 std::optional<Qt::ApplicationState> m_lastReceivedApplicationState;
50 std::optional<Qt::ApplicationState> m_lastSentApplicationState;
51 QObject m_signalReceiver;
52};
53
55{
56 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(window);
57 return platformWindow != nullptr
58 ? platformWindow->ownedViewOrNull()
59 : nullptr;
60}
61
62ProcessEventResult ApplicationStateTracker::processExposeEvent(ExposeEvent *evt)
63{
64 auto *view = evt->window != nullptr
65 ? mapQWindowToViewOrNull(evt->window)
66 : nullptr;
67
68 if (view == nullptr)
70
71 startTrackingViewIfNeeded(view);
72
73 if (evt->isExposed)
74 std::ignore = m_visibleViews.insert(view);
75 else
76 std::ignore = m_visibleViews.erase(view);
77
79}
80
81ProcessEventResult ApplicationStateTracker::processApplicationStateChangedEvent(ApplicationStateChangedEvent *evt)
82{
83 m_lastReceivedApplicationState = evt->newState;
85}
86
87bool ApplicationStateTracker::sendEvent(WindowSystemEvent *event)
88{
89 std::optional<ProcessEventResult> processEventResult;
90 switch (event->type) {
91 case WindowSystemEventType::Expose:
92 processEventResult = processExposeEvent(static_cast<ExposeEvent *>(event));
93 break;
94 case WindowSystemEventType::ApplicationStateChanged:
95 processEventResult = processApplicationStateChangedEvent(static_cast<ApplicationStateChangedEvent *>(event));
96 break;
97 default:
98 break;
99 }
100
101 bool processEvent = processEventResult != ProcessEventResult::Ignore;
102 if (processEvent)
103 QGuiApplicationPrivate::processWindowSystemEvent(event);
104
105 bool hasPendingEvents = QWindowSystemInterfacePrivate::windowSystemEventsQueued();
106 if (!hasPendingEvents)
107 tryUpdateApplicationState();
108
109 return processEvent;
110}
111
112void ApplicationStateTracker::tryUpdateApplicationState()
113{
114 const bool hasAnyTrackedWindow = !m_trackedViews.empty();
115 const bool allWindowsHidden = hasAnyTrackedWindow && m_visibleViews.empty();
116
117 // Trust the OHOS ability lifecycle for active/inactive (a foreground app is
118 // active even without a focused window); visibility only refines to Hidden.
119 const Qt::ApplicationState lifecycleState =
120 m_lastReceivedApplicationState.has_value()
121 ? m_lastReceivedApplicationState.value()
122 : Qt::ApplicationActive;
123
124 const auto updatedApplicationState =
125 lifecycleState == Qt::ApplicationSuspended
126 ? Qt::ApplicationSuspended
127 : allWindowsHidden
128 ? Qt::ApplicationHidden
129 : lifecycleState == Qt::ApplicationActive
130 ? Qt::ApplicationActive
131 : Qt::ApplicationInactive;
132
133 if (m_lastSentApplicationState == updatedApplicationState)
134 return;
135
136 m_lastSentApplicationState = updatedApplicationState;
137 ApplicationStateChangedEvent eventToSend{updatedApplicationState};
138 QGuiApplicationPrivate::processWindowSystemEvent(&eventToSend);
139}
140
141void ApplicationStateTracker::startTrackingViewIfNeeded(QOhosView *viewToTrack)
142{
143 bool added;
144 std::tie(std::ignore, added) = m_trackedViews.insert(viewToTrack);
145 if (added) {
146 QObject::connect(
147 viewToTrack, &QOhosView::destroyed,
148 &m_signalReceiver, [this, viewToTrack](QObject *) {
149 std::ignore = m_trackedViews.erase(viewToTrack);
150 std::ignore = m_visibleViews.erase(viewToTrack);
151 });
152 }
153}
154
155}
156
158{
159 return std::make_shared<ApplicationStateTracker>();
160}
161
162QT_END_NAMESPACE
bool sendEvent(WindowSystemEvent *event) override
Combined button and popup list for selecting options.
QOhosView * mapQWindowToViewOrNull(QWindow *window)
std::shared_ptr< QWindowSystemEventHandler > makeApplicationStateTracker()