4#include <qohosscreenmanager.h>
8#include <qohosdisplayinfo.h>
9#include <qohosjsutils.h>
10#include <qohosplatformscreen.h>
11#include <qpa/qwindowsysteminterface.h>
20 auto primaryDisplay = jsState.eval<QNapi::Object>(
"@ohos.display.getPrimaryDisplaySync()");
21 return QOhosDisplayInfo::makeFromOhosDisplayObject(jsState, primaryDisplay);
26 QOhosOptional<QNapi::Object> result;
28 result = jsState.eval<QNapi::Object>(
29 "@ohos.display.getDisplayByIdSync(*)", {displayId.value()});
30 }
catch (
const Napi::Error &error) {
31 qOhosPrintfError(
"%s: Failed to retrieve display with id: %f", Q_FUNC_INFO, displayId.value());
42 outputStream <<
"id:" << displayInfo.id.value()
43 <<
"name:" << displayInfo.name
44 <<
"sizePixels:" << displayInfo.sizePixels
48 <<
"dpi:" << displayInfo.dpi;
54 constexpr int virtualDisplayBaseId = 1000;
61 const auto *sourceModeToIgnoreIter = std::find(
62 std::begin(sourceModesToIgnore), std::end(sourceModesToIgnore),
63 displayInfo.sourceMode);
64 bool ignoreBySoureMode = sourceModeToIgnoreIter !=
std::end(sourceModesToIgnore);
66 return displayInfo.sourceMode.hasValue()
68 : displayInfo.id.value() >= virtualDisplayBaseId;
76 auto selfRef = QtOhos::QThreadSafeRef<QOhosScreenManager>(
this);
78 auto displayInfos = QtOhos::evalInJsThreadWithConsumer<std::vector<QOhosDisplayInfo>>(
79 [](QtOhos::JsState &jsState,
auto resultConsumer) {
80 jsState.eval<QNapi::Promise>(
"@ohos.display.getAllDisplay()")
81 .withContext(std::move(resultConsumer))
83 [](
const QtOhos::CallbackInfo &cbInfo,
auto &resultConsumer) {
84 auto displayObjectsArray = cbInfo.getFirstArg<QNapi::Array>(Q_FUNC_INFO);
86 QNapi::getArrayElements<std::vector<QOhosDisplayInfo>, QNapi::Object>(
88 [&](QNapi::Object jsDisplay) {
89 return QOhosDisplayInfo::makeFromOhosDisplayObject(cbInfo.jsState(), jsDisplay);
93 [](
auto &resultConsumer) {
94 qOhosPrintfError(
"%s: Failed to enumerate displays", Q_FUNC_INFO);
102 m_jsScopeData = QtOhos::makeProxyWithJsThreadDeleter(
104 jsState, JsScopeData::CreateInfo{
105 .displayInfos = displayInfos,
106 .displayChangedCb = [selfRef](QtOhos::JsState &jsState, JsDisplayId changedDisplayId) {
107 auto displayObject = tryGetDisplayById(jsState, changedDisplayId);
108 if (!displayObject.hasValue()) {
110 "%s: Failed to retrieve display with id: %f during display changed callback. Ignoring the event...",
111 Q_FUNC_INFO, changedDisplayId.value());
115 auto displayInfo = QOhosDisplayInfo::makeFromOhosDisplayObject(jsState, displayObject.value());
116 selfRef.visitInQtThreadIfAlive([displayInfo](QOhosScreenManager &self) {
117 self.handleDisplayChangedCallbackInQtThread(displayInfo);
120 .displayAddedCb = [selfRef](QtOhos::JsState &jsState, JsDisplayId displayId) {
121 auto displayObject = tryGetDisplayById(jsState, displayId);
122 if (!displayObject.hasValue()) {
124 "%s: Failed to retrieve display with id: %f during display added callback. Ignoring the event ...",
125 Q_FUNC_INFO, displayId.value());
129 auto displayInfo = QOhosDisplayInfo::makeFromOhosDisplayObject(jsState, displayObject.value());
130 selfRef.visitInQtThreadIfAlive([displayInfo](QOhosScreenManager &self) {
131 self.handleDisplayAdded(displayInfo);
134 .displayRemovedCb = [selfRef](QtOhos::JsState &, JsDisplayId displayId) {
135 selfRef.visitInQtThreadIfAlive([displayId](QOhosScreenManager &self) {
136 self.handleDisplayRemoved(displayId);
139 .displayAvailableAreaChangedCb = [selfRef](QtOhos::JsState &, JsDisplayId displayId, QRectF availableArea) {
140 selfRef.visitInQtThreadIfAlive([displayId, availableArea](QOhosScreenManager &self) {
141 self.handleDisplayAvailableAreaChanged(displayId, availableArea);
147 m_primaryDisplayId = primaryDisplayInfo.id;
148 for (
const auto &displayInfo : m_jsScopeData->getRegisteredDisplayInfos())
149 addScreen(displayInfo);
157 if (platformScreen ==
nullptr) {
158 qCWarning(QtForOhos) <<
"Received display 'change' event for unknown display with id:"
159 << displayInfo.id.value();
163 qCDebug(QtForOhos) <<
"DisplayChanged:" << displayInfo;
165 platformScreen->setDisplayInfo(displayInfo);
166 updatePrimaryPlatformScreenIfNeeded();
170 QNapi::Object displayModule,
const std::string &eventName,
171 QOhosConsumer<QtOhos::JsState &, JsDisplayId> handleFunction)
173 m_destroyNotifiers.push_back(
174 QtOhos::registerOnOffMethodsBasedEventHandler(
175 displayModule, eventName,
176 [handleFunction = std::move(handleFunction)](
const QtOhos::CallbackInfo &cbInfo) {
177 auto changedDisplayIdValue = cbInfo.getFirstArg<QNapi::Number>(Q_FUNC_INFO);
178 auto changedDisplayId = JsDisplayId{changedDisplayIdValue};
179 handleFunction(cbInfo.jsState(), changedDisplayId);
186 auto optDisplay = tryGetDisplayById(jsState, displayId);
187 if (!optDisplay.hasValue()) {
189 "%s: Display with id: %f went missing during its registration.",
190 Q_FUNC_INFO, displayId.value());
194 auto availableAreaChangeHandle = QtOhos::registerOnOffMethodsBasedEventHandler(
196 "availableAreaChange",
198 auto availableArea = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
199 auto availableAreaQRectF = QRectF(
200 availableArea.get<QNapi::Number>(
"left"),
201 availableArea.get<QNapi::Number>(
"top"),
202 availableArea.get<QNapi::Number>(
"width"),
203 availableArea.get<QNapi::Number>(
"height"));
204 m_availableAreaChangedCb(cbInfo.jsState(), displayId, availableAreaQRectF);
208 std::tie(std::ignore, added) = m_perDisplayDestroyNotifiers.insert(
209 std::make_pair(displayId, std::move(availableAreaChangeHandle)));
211 qOhosPrintfError(
"Duplicate display added event for display id: %f", displayId.value());
218 if (m_perDisplayDestroyNotifiers.erase(displayId) == 0)
219 qOhosPrintfError(
"Attempted to erase unknown display with id: %f", displayId.value());
227 m_platformScreen = screen.get();
228 QWindowSystemInterface::handleScreenAdded(screen.release());
233 return m_platformScreen;
238 if (m_platformScreen !=
nullptr)
239 QWindowSystemInterface::handleScreenRemoved(m_platformScreen);
243QOhosScreenManager::platformScreenHolderForDisplayIdOrNull(JsDisplayId displayId)
const
245 auto it = m_displays.find(displayId);
246 return it != m_displays.end()
253 auto *platformScreenHolder = platformScreenHolderForDisplayIdOrNull(displayId);
254 return platformScreenHolder !=
nullptr
255 ? platformScreenHolder->platformScreenOrNull()
262 if (platformScreen ==
nullptr)
263 qOhosReportFatalErrorAndAbort(
"Failed to find platform screen for display id: %f", displayId.value());
264 return platformScreen;
269 auto it = m_displays.find(displayInfo.id);
270 if (it != m_displays.end()) {
271 qCWarning(QtForOhos) <<
"Attemting to add display with non unique id:" << displayInfo.id.value()
272 <<
"previous display with that id will be removed";
274 m_displays[displayInfo.id] = std::make_unique<QOhosPlatformScreenHolder>(displayInfo);
279 std::ignore = m_displays.erase(displayId);
285 auto jsScopeData = std::shared_ptr<JsScopeData>(
new JsScopeData(jsState));
286 jsScopeData->initialize(jsState,
std::move(createInfo));
290std::vector<QOhosDisplayInfo>
QOhosScreenManager::JsScopeData::getRegisteredDisplayInfos()
292 return m_registeredDisplayInfos;
301 for (
const auto &displayInfo : createInfo.displayInfos) {
302 if (!shouldIgnoreDisplay(displayInfo) && tryRegisterDisplay(jsState, displayInfo.id)) {
303 m_registeredDisplayInfos.push_back(displayInfo);
306 "%s: Failed to register display (%f) during display initialization.",
308 displayInfo.id.value());
312 auto displayModule = jsState.eval<QNapi::Object>(
"@ohos.display");
313 m_availableAreaChangedCb = std::move(createInfo.displayAvailableAreaChangedCb);
314 registerDisplayCallbackListener(
316 displayCallbackNameChangeEvent,
317 std::move(createInfo.displayChangedCb));
318 registerDisplayCallbackListener(
320 displayCallbackNameAddEvent,
321 [
this, displayAddedCb = std::move(createInfo.displayAddedCb)](QtOhos::JsState &jsState, JsDisplayId displayId) {
322 if (tryRegisterDisplay(jsState, displayId)) {
323 displayAddedCb(jsState, displayId);
326 "%s: Failed to register display (%f) during display added callback.",
331 registerDisplayCallbackListener(
333 displayCallbackNameRemoveEvent,
334 [
this, displayRemovedCb = std::move(createInfo.displayRemovedCb)](QtOhos::JsState &jsState, JsDisplayId displayId) {
335 unregisterDisplay(displayId);
336 displayRemovedCb(jsState, displayId);
343 qCWarning(QtForOhos) <<
"Display add ignored (based on display id):" << displayInfo.id.value();
346 qCWarning(QtForOhos) <<
"Display added:" << displayInfo;
347 addScreen(displayInfo);
348 updatePrimaryPlatformScreenIfNeeded();
353 qCWarning(QtForOhos) <<
"Display removed: id:" << displayId.value();
354 updatePrimaryPlatformScreenIfNeeded();
356 if (m_primaryDisplayId == displayId)
357 qOhosReportFatalErrorAndAbort(
"Primary display removed - this is not supported");
359 removeScreenIfExists(displayId);
363 JsDisplayId jsDisplayId, QRectF availableArea)
365 auto displaysIt = m_displays.find(jsDisplayId);
366 if (displaysIt != m_displays.end()) {
367 auto *platformScreen = displaysIt->second->platformScreenOrNull();
368 if (platformScreen !=
nullptr)
369 platformScreen->setAvailableGeometry(availableArea.toRect());
377 if (m_primaryDisplayId == primaryDisplayInfo.id)
381 <<
"Primary display changed from:" << m_primaryDisplayId.value()
382 <<
"to:" << primaryDisplayInfo.id.value();
385 if (primaryPlatformScreen ==
nullptr) {
388 <<
"Primary screen changed, but it was not registered previously"
389 <<
"adding the screen with display id:" << primaryDisplayInfo.id.value();
390 addScreen(primaryDisplayInfo);
394 m_primaryDisplayId = primaryDisplayInfo.id;
395 QWindowSystemInterface::handlePrimaryScreenChanged(primaryPlatformScreen);
QOhosPlatformScreen * platformScreenForDisplayIdOrNull(QOhosDisplayInfo::JsDisplayId displayId) const
QOhosPlatformScreen * platformScreenForDisplayIdOrFail(QOhosDisplayInfo::JsDisplayId displayId) const
Combined button and popup list for selecting options.
bool shouldIgnoreDisplay(const QOhosDisplayInfo &displayInfo)
QOhosDisplayInfo getDisplayInfoForPrimaryDisplay(QtOhos::JsState &jsState)
const std::string displayCallbackNameAddEvent
const std::string displayCallbackNameRemoveEvent
QOhosOptional< QNapi::Object > tryGetDisplayById(QtOhos::JsState &jsState, QOhosDisplayInfo::JsDisplayId displayId)
QDebug & operator<<(QDebug &outputStream, const QOhosDisplayInfo &displayInfo)
const std::string displayCallbackNameChangeEvent
void runInJsThreadAndWait(const std::function< void(JsState &)> &task)