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 <qohosplatformwindow.h>
11#include <qohosutils.h>
12#include <qpa/qwindowsysteminterface_p.h>
13#include <render/qohosview.h>
14#include <set>
15#include <tuple>
16
18
19namespace
20{
21
22using WindowSystemEventType = QWindowSystemInterfacePrivate::EventType;
23using WindowSystemEvent = QWindowSystemInterfacePrivate::WindowSystemEvent;
24using ExposeEvent = QWindowSystemInterfacePrivate::ExposeEvent;
25using ApplicationStateChangedEvent = QWindowSystemInterfacePrivate::ApplicationStateChangedEvent;
26
32
33class ApplicationStateTracker final : public QWindowSystemEventHandler
34{
35public:
36 bool sendEvent(WindowSystemEvent *event) override;
37
38private:
39 ProcessEventResult processExposeEvent(ExposeEvent *event);
40 ProcessEventResult processApplicationStateChangedEvent(ApplicationStateChangedEvent *event);
41
42 void startTrackingViewIfNeeded(QOhosView *view);
43 void tryUpdateApplicationState();
44
45 std::set<QOhosView *> m_trackedViews;
46 std::set<QOhosView *> m_visibleViews;
47
48 QOhosOptional<Qt::ApplicationState> m_lastReceivedApplicationState;
49 QOhosOptional<Qt::ApplicationState> m_lastSentApplicationState;
50 QObject m_signalReceiver;
51};
52
54{
55 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(window);
56 return platformWindow != nullptr
57 ? platformWindow->ownedViewOrNull()
58 : nullptr;
59}
60
61ProcessEventResult ApplicationStateTracker::processExposeEvent(ExposeEvent *evt)
62{
63 auto *view = evt->window != nullptr
64 ? mapQWindowToViewOrNull(evt->window)
65 : nullptr;
66
67 if (view == nullptr)
69
70 startTrackingViewIfNeeded(view);
71
72 if (evt->isExposed)
73 std::ignore = m_visibleViews.insert(view);
74 else
75 std::ignore = m_visibleViews.erase(view);
76
78}
79
80ProcessEventResult ApplicationStateTracker::processApplicationStateChangedEvent(ApplicationStateChangedEvent *evt)
81{
82 m_lastReceivedApplicationState = evt->newState;
84}
85
86bool ApplicationStateTracker::sendEvent(WindowSystemEvent *event)
87{
88 QOhosOptional<ProcessEventResult> processEventResult;
89 switch (event->type) {
90 case WindowSystemEventType::Expose:
91 processEventResult = processExposeEvent(static_cast<ExposeEvent *>(event));
92 break;
93 case WindowSystemEventType::ApplicationStateChanged:
94 processEventResult = processApplicationStateChangedEvent(static_cast<ApplicationStateChangedEvent *>(event));
95 break;
96 default:
97 break;
98 }
99
100 bool processEvent = processEventResult != ProcessEventResult::Ignore;
101 if (processEvent)
102 QGuiApplicationPrivate::processWindowSystemEvent(event);
103
104 bool hasPendingEvents = QWindowSystemInterfacePrivate::windowSystemEventsQueued();
105 if (!hasPendingEvents)
106 tryUpdateApplicationState();
107
108 return processEvent;
109}
110
111void ApplicationStateTracker::tryUpdateApplicationState()
112{
113 const bool allWindowsHidden = m_visibleViews.empty();
114
115 // Trust the OHOS ability lifecycle for active/inactive (a foreground app is
116 // active even without a focused window); visibility only refines to Hidden.
117 const Qt::ApplicationState lifecycleState =
118 m_lastReceivedApplicationState.has_value()
119 ? m_lastReceivedApplicationState.value()
120 : Qt::ApplicationActive;
121
122 const auto updatedApplicationState =
123 lifecycleState == Qt::ApplicationSuspended
124 ? Qt::ApplicationSuspended
125 : allWindowsHidden
126 ? Qt::ApplicationHidden
127 : lifecycleState == Qt::ApplicationActive
128 ? Qt::ApplicationActive
129 : Qt::ApplicationInactive;
130
131 if (m_lastSentApplicationState == updatedApplicationState)
132 return;
133
134 m_lastSentApplicationState = updatedApplicationState;
135 ApplicationStateChangedEvent eventToSend{updatedApplicationState};
136 QGuiApplicationPrivate::processWindowSystemEvent(&eventToSend);
137}
138
139void ApplicationStateTracker::startTrackingViewIfNeeded(QOhosView *viewToTrack)
140{
141 bool added;
142 std::tie(std::ignore, added) = m_trackedViews.insert(viewToTrack);
143 if (added) {
144 QObject::connect(
145 viewToTrack, &QOhosView::destroyed,
146 &m_signalReceiver, [this, viewToTrack](QObject *) {
147 std::ignore = m_trackedViews.erase(viewToTrack);
148 std::ignore = m_visibleViews.erase(viewToTrack);
149 });
150 }
151}
152
153}
154
156{
157 return std::make_shared<ApplicationStateTracker>();
158}
159
160QT_END_NAMESPACE
bool sendEvent(WindowSystemEvent *event) override
Combined button and popup list for selecting options.
QOhosView * mapQWindowToViewOrNull(QWindow *window)
std::shared_ptr< QWindowSystemEventHandler > makeApplicationStateTracker()