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
qohosview.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 <render/qohosview.h>
5
6#include <QtCore/private/qnapi_p.h>
7#include <QtCore/private/qohoscommon_p.h>
8#include <QtCore/qscopeguard.h>
9#include <QtGui/private/qguiapplication_p.h>
10#include <QtGui/private/qhighdpiscaling_p.h>
11#include <QtGui/private/qwindow_p.h>
12#include <QtGui/qbitmap.h>
13#include <QtGui/qpalette.h>
14#include <ace/xcomponent/native_interface_xcomponent.h>
15#include <arkui/native_type.h>
16#include <functional>
17#include <memory>
18#include <qarkui/window.h>
19#include <qohosdeviceinfo_p.h>
20#include <qohosinputmethodeventhandler.h>
21#include <qohosjsmain.h>
22#include <qohosplatformbackingstore.h>
23#include <qohosplatformintegration.h>
24#include <qohosplatformscreen.h>
25#include <qohosplatformwindow.h>
26#include <qohosqabilityinstancesmanager.h>
27#include <qohosutils.h>
28#include <qpa/qplatformscreen.h>
29#include <qpa/qplatformtheme.h>
30#include <qpa/qwindowsysteminterface.h>
31#include <render/qnativenode.h>
32#include <render/qohoswindowproxy.h>
33#include <render/qwindowproxyregistry.h>
34#include <string>
35#include <tuple>
36#include <vector>
37
39
41
42namespace
43{
44
50
56
58 Qt::WindowModality windowModality)
59{
60 using ModalityType = QOhosWindowProxy::ModalityType;
61
62 switch (windowModality) {
63 case Qt::WindowModality::NonModal:
64 return std::nullopt;
65 case Qt::WindowModality::WindowModal:
66 return ModalityType::WINDOW_MODALITY;
67 case Qt::WindowModality::ApplicationModal:
68 return ModalityType::APPLICATION_MODALITY;
69 }
70
71 qOhosPrintfWarning(
72 "%s: got illegal Qt::WindowModality value (%d), using the default instead",
73 Q_FUNC_INFO, static_cast<int>(windowModality));
74
75 return std::nullopt;
76}
77
78template<typename ...SignalParams>
79std::function<void(SignalParams...)> makeViewConditionalSignalEmitter(
80 QPointer<QOhosView> viewPtr, std::function<bool(QOhosView &)> predicate, void (QOhosView::*signalFuncPtr)(SignalParams ...))
81{
82 return [signalFuncPtr, viewPtr, predicate = std::move(predicate)](SignalParams ...args) {
83 if (viewPtr && predicate(*viewPtr))
84 Q_EMIT (*viewPtr.*signalFuncPtr)(args...);
85 };
86}
87
89{
90public:
92 using AvoidAreaType = QOhosWindowProxy::AvoidAreaType;
93
94 explicit AvoidAreaCache(std::function<AvoidArea(AvoidAreaType)> avoidAreasProvider);
95
96 void put(
97 AvoidAreaType avoidAreaType,
98 const AvoidArea &avoidArea);
99
101
102private:
103 std::function<AvoidArea(AvoidAreaType)> m_avoidAreasProvider;
104 QMap<AvoidAreaType, AvoidArea> m_store;
105};
106
107AvoidAreaCache::AvoidAreaCache(std::function<AvoidArea(AvoidAreaType)> avoidAreasProvider)
109 , m_store()
110{
111}
112
114 QOhosWindowProxy::AvoidAreaType avoidAreaType, const QOhosWindowProxy::AvoidArea &avoidArea)
115{
116 m_store[avoidAreaType] = avoidArea;
117}
118
120 QOhosWindowProxy::AvoidAreaType avoidAreaType)
121{
122 if (m_store.contains(avoidAreaType))
123 return m_store.value(avoidAreaType);
124
125 auto result = m_avoidAreasProvider(avoidAreaType);
126 m_store[avoidAreaType] = result;
127 return result;
128}
129
130void tryUpdateMaximumMarginsFromAvoidArea(QMargins &marginsToUpdate, const QOhosWindowProxy::AvoidArea &avoidArea)
131{
132 if (!avoidArea.visible)
133 return;
134
135 marginsToUpdate.setTop(qMax(marginsToUpdate.top(), avoidArea.topRect.height()));
136 marginsToUpdate.setLeft(qMax(marginsToUpdate.left(), avoidArea.leftRect.width()));
137 marginsToUpdate.setRight(qMax(marginsToUpdate.right(), avoidArea.rightRect.width()));
138 marginsToUpdate.setBottom(qMax(marginsToUpdate.bottom(), avoidArea.bottomRect.height()));
139}
140
142 const QPoint &geometryOrigin, const QRect &frameGeometry)
143{
144 int topFrameMargin = qAbs(frameGeometry.top() - geometryOrigin.y());
145 int sideAndBottomFrameMargin = qAbs(frameGeometry.left() - geometryOrigin.x());
146
147 return {
148 frameGeometry.width() - 2 * sideAndBottomFrameMargin,
149 frameGeometry.height() - topFrameMargin - sideAndBottomFrameMargin
150 };
151}
152
154{
155 auto visibleWindows = QWindowProxyRegistry::instance().queryWindowsWithVisibleSystemWindow();
156 return !visibleWindows.empty()
157 ? visibleWindows.front()
158 : nullptr;
159}
160
162{
163 auto focusedWindows = QWindowProxyRegistry::instance().queryWindowsWithSystemWindowAndFocus();
164 return !focusedWindows.empty()
165 ? focusedWindows.front()
166 : nullptr;
167}
168
170{
171 auto *focusWindow = getFirstTopLevelWindowWithSystemFocusOrNull();
172 auto *firstTopLevelWindow = getFirstTopLevelWindowOrNull();
173
174 auto isValidSyntheticParent = [&](QWindow *w) {
175 return w != nullptr && w != qWindow && w->isVisible();
176 };
177
178 return isValidSyntheticParent(focusWindow)
179 ? focusWindow
180 : isValidSyntheticParent(firstTopLevelWindow)
181 ? firstTopLevelWindow
182 : nullptr;
183}
184
186{
187 using ViewType = QOhosView::ViewType;
188
189 auto *qWindow = platformWindow->window();
190 auto *parent = qWindow->parent();
191 auto *transientParent = qWindow->transientParent();
192
193 auto windowType = qWindow->type();
194
195 QWindow *subWindowTagValue = platformWindow->validSubWindowOfTagValueOrNull();
196
197 static QSet<Qt::WindowType> fallbackToSubWindowWindowTypes{
198 Qt::Popup,
199 Qt::ToolTip,
200 Qt::Dialog,
201 Qt::Tool,
202 };
203
204 bool taggedAsMainWindow = platformWindow->mainWindowTagValueOrFalse();
205 if (taggedAsMainWindow) {
206 return ViewTypeInfo {
207 .viewType = ViewType::MainWindow,
208 .optLogicalParent = nullptr,
209 };
210 }
211
212 bool taggedAsFloatWindow = platformWindow->floatWindowTagValueOrFalse();
213 if (taggedAsFloatWindow) {
214 return ViewTypeInfo {
215 .viewType = ViewType::FloatWindow,
216 .optLogicalParent = nullptr,
217 };
218 }
219
220 bool overrideAsSubWindow = subWindowTagValue != nullptr;
221 if (overrideAsSubWindow) {
222 return ViewTypeInfo {
223 .viewType = ViewType::SubWindow,
224 .optLogicalParent = subWindowTagValue,
225 };
226 }
227
228 if (parent != nullptr) {
229 return ViewTypeInfo {
230 .viewType = ViewType::EmbeddedWindow,
231 .optLogicalParent = parent,
232 };
233 }
234
235 if (transientParent != nullptr) {
236 return ViewTypeInfo {
237 .viewType = ViewType::SubWindow,
238 .optLogicalParent = transientParent,
239 };
240 }
241
242 auto *syntheticParent = syntheticParentForQWindowOrNull(platformWindow->window());
243
244 bool automaticOverrideActive =
245 fallbackToSubWindowWindowTypes.contains(windowType)
246 && syntheticParent != nullptr;
247 if (automaticOverrideActive) {
248 return ViewTypeInfo {
249 .viewType = ViewType::SubWindow,
250 .optLogicalParent = syntheticParent,
251 };
252 }
253
254 return ViewTypeInfo {
255 .viewType = ViewType::MainWindow,
256 .optLogicalParent = nullptr,
257 };
258}
259
260// Reads the QWindow flags, since the platform flags drop the hint on frameless windows.
261// QWidget gives popups and tool tips the hint by default, so they are excluded.
262bool hasMaximizeButtonHintForSubWindow(const QWindow *qWindow)
263{
264 const auto windowType = qWindow->type();
265 return qWindow->flags().testFlag(Qt::WindowMaximizeButtonHint)
266 && windowType != Qt::Popup && windowType != Qt::ToolTip;
267}
268
269QBitmap getCursorBitmap(const QCursor &cursor)
270{
271 return cursor.bitmap();
272}
273
274QBitmap getCursorMask(const QCursor &cursor)
275{
276 return cursor.mask();
277}
278
279QImage createImageFromBitmapAndMask(const QBitmap &bitmap, const QBitmap &mask)
280{
281 const auto maskTransparentColor = QColor(Qt::color0).rgba();
282 const auto transparentColor = QColor(Qt::transparent).rgba();
283
284 QImage image = bitmap.toImage().convertToFormat(QImage::Format_RGBA8888);
285 QImage maskImage = mask.toImage().convertToFormat(QImage::Format_RGB32);
286
287 for (int row = 0; row < image.height(); ++row) {
288 auto *imageData = reinterpret_cast<QRgb *>(image.scanLine(row));
289 auto *maskData = reinterpret_cast<QRgb *>(maskImage.scanLine(row));
290 for (int col = 0; col < image.width(); ++col) {
291 if (maskData[col] == maskTransparentColor)
292 imageData[col] = transparentColor;
293 }
294 }
295
296 return image;
297}
298
300{
301 QBitmap cursorPixels(cursorSize);
302 cursorPixels.fill(Qt::transparent);
303 QBitmap cursorMask(cursorSize);
304 cursorMask.fill(Qt::color0);
305 return QCursor(cursorPixels, cursorMask);
306}
307
308ViewGeometryPersistencePolicy determineViewGeometryPersistencePolicy()
309{
310 using WindowGeometryPersistencePolicy = QOhosPlatformIntegration::WindowGeometryPersistencePolicy;
311
312 auto viewGeometryPersistencePolicy = ViewGeometryPersistencePolicy::Ignore;
313
315 switch (policy) {
316 case WindowGeometryPersistencePolicy::Disabled:
317 viewGeometryPersistencePolicy = ViewGeometryPersistencePolicy::Disabled;
318 break;
319 case WindowGeometryPersistencePolicy::Enabled:
320 viewGeometryPersistencePolicy = ViewGeometryPersistencePolicy::Enabled;
321 break;
322 case WindowGeometryPersistencePolicy::FollowSystemSetting:
323 viewGeometryPersistencePolicy = ViewGeometryPersistencePolicy::FollowSystemSetting;
324 break;
325 }
326
327 return viewGeometryPersistencePolicy;
328}
329
331{
332 using WindowGeometryPersistencePolicy = QOhosPlatformIntegration::WindowGeometryPersistencePolicy;
333
334 bool geometryPersistenceEnabled = false;
336 switch (policy) {
337 case WindowGeometryPersistencePolicy::Disabled:
338 windowProxy->setWindowRectAutoSave(false);
339 break;
340 case WindowGeometryPersistencePolicy::Enabled:
341 windowProxy->setWindowRectAutoSave(true);
342 geometryPersistenceEnabled = windowProxy->isWindowRectAutoSave();
343 break;
344 case WindowGeometryPersistencePolicy::FollowSystemSetting:
345 geometryPersistenceEnabled = windowProxy->isWindowRectAutoSave();
346 break;
347 }
348
349 return geometryPersistenceEnabled
352}
353
355 QWindow *logicalParent, QOhosWindowProxy &windowProxy)
356{
357 auto *screen = logicalParent->screen();
358 auto *ohosPlatformScreen = screen != nullptr
359 ? static_cast<QOhosPlatformScreen *>(screen->handle())
360 : nullptr;
361
362 return ohosPlatformScreen != nullptr
363 ? std::optional(ohosPlatformScreen->displayInfo().id)
364 : windowProxy.tryGetMainWindowJsDisplayId();
365}
366
368{
369 if (window != nullptr) {
370 QWindowPrivate *windowPrivate = qt_window_private(window);
371 QPalette palette = windowPrivate->windowPalette();
372 QColor backgroundColor = palette.color(QPalette::Window);
373 return backgroundColor;
374 }
375 return std::nullopt;
376}
377
378}
379
381{
382 auto optPostSurfaceDrawTask = std::exchange(m_optPostSurfaceDrawTask, {});
383 if (optPostSurfaceDrawTask)
384 optPostSurfaceDrawTask();
385}
386
387std::shared_ptr<QOhosWindowProxy> QOhosView::tryCreateWindowProxyIfNeeded(ViewType viewType, QWindow *optLogicalParent)
388{
389 QWindow *qWindow = m_ownerWindow;
390 QOhosPlatformWindow *window = QOhosPlatformWindow::fromQWindow(qWindow);
391
392 std::shared_ptr<QOhosWindowProxy> result;
393
394 switch (viewType) {
395 case ViewType::MainWindow:
396 {
397 // NOTE: treat windows automatically-created by the platform in a special way
399 if (useAutoStartedMainWindow) {
400 QOhosWindowProxy::ExistingMainWindowCreateInfo createInfo;
401 createInfo.qWindowRef = QtOhos::QObjectThreadSafeRef(qWindow);
402 createInfo.qAbilityInstanceId = QOhosJsThreadGateway::eval([](QOhosJsState &jsState) {
403 return QtOhos::QAbilityInstancesManager::instance(jsState).defaultQAbilityPeer()->instanceId();
404 },
405 Q_FUNC_INFO);
406 result = QOhosWindowProxy::createForExistingMainWindow(createInfo);
407 m_geometryPersistencePolicy = determineViewGeometryPersistencePolicy();
408 } else {
409 QOhosWindowProxy::MainWindowCreateInfo createInfo;
410 createInfo.qWindowRef = QtOhos::QObjectThreadSafeRef(qWindow);
411 createInfo.windowId = window->internalWindowId();
412 createInfo.windowTitle = qWindow->title().toStdString();
413 createInfo.frameGeometry = window->lastRequestedWindowFrameGeometry();
414 createInfo.fullscreen = qWindow->windowState() == Qt::WindowFullScreen;
415 result = QOhosWindowProxy::createMainWindow(createInfo);
416 }
417
418 break;
419 }
420 case ViewType::SubWindow:
421 {
422 auto *targetWindowToBeSubWindowOf = optLogicalParent;
423
424 if (Q_UNLIKELY(targetWindowToBeSubWindowOf == nullptr))
425 qOhosReportFatalErrorAndAbort("Failed to determine valid parent of a SubWindow");
426
427 if (!targetWindowToBeSubWindowOf->isVisible()) {
428 auto *targetParentPlatformWindow = QOhosPlatformWindow::fromQWindowOrNull(targetWindowToBeSubWindowOf);
429 if (targetParentPlatformWindow != nullptr)
430 targetParentPlatformWindow->setVisible(true);
431 else
432 targetWindowToBeSubWindowOf->show();
433 }
434
435 auto *targetWindowToBeSubWindowOfView =
436 QOhosPlatformWindow::fromQWindow(targetWindowToBeSubWindowOf)->ownedViewOrNull();
437
438 const QOhosView *firstViewWithWindow = nullptr;
439 switch (targetWindowToBeSubWindowOfView->viewType()) {
440 case ViewType::MainWindow:
441 case ViewType::SubWindow:
442 case ViewType::FloatWindow:
443 firstViewWithWindow = targetWindowToBeSubWindowOfView;
444 break;
445 case ViewType::EmbeddedWindow:
446 firstViewWithWindow = ancestorViewWithWindowOrNull();
447 break;
448 }
449
450 if (firstViewWithWindow == nullptr)
451 qOhosReportFatalErrorAndAbort("Failed to determine valid parent for this window.");
452
453 auto parentWindowProxy = firstViewWithWindow->m_ohosWindowProxy;
454 if (Q_UNLIKELY(!parentWindowProxy)) {
455 qOhosReportFatalErrorAndAbort(
456 "parentWindowProxy is null but should not be. This is most likely a programming error");
457 }
458
459 QOhosWindowProxy::SubWindowCreateInfo createInfo;
460 createInfo.window = QtOhos::QObjectThreadSafeRef(qWindow);
461 createInfo.windowTitle = qWindow->title().toStdString();
462 createInfo.windowId = window->internalWindowId();
463 createInfo.qAbilityInstanceId = parentWindowProxy->qAbilityInstanceId();
464
466 createInfo.disableWindowFocusableBeforeLoadContentHack = window->windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus);
467 createInfo.modal = qWindow->modality() != Qt::NonModal;
468 // Sub window maximize is supported since API 19, but its maximize button can be
469 // hidden only since API 26, which the fixed-size state needs.
470 constexpr int minApiVersionWithSupportedWindowModesPerWindow = 26;
471 createInfo.maximizeSupported =
472 QOhosDeviceInfo::sdkApiVersion() >= minApiVersionWithSupportedWindowModesPerWindow
473 && hasMaximizeButtonHintForSubWindow(qWindow);
474 createInfo.windowRect = window->lastRequestedWindowFrameGeometry();
475 result = parentWindowProxy->createSubWindow(createInfo);
476
477 break;
478 }
479 case ViewType::EmbeddedWindow:
480 {
481 // NOTE - NativeNode is now always created during view instantiation
482 break;
483 }
484 case ViewType::FloatWindow:
485 {
486 QOhosWindowProxy::FloatWindowCreateInfo createInfo = {
487 .qWindowRef = QtOhos::QObjectThreadSafeRef(qWindow),
488 .internalWindowId = window->internalWindowId(),
489 };
490 result = QOhosWindowProxy::createFloatWindow(createInfo);
491 break;
492 }
493 default:
494 qOhosReportFatalErrorAndAbort("Unsupported view type: %d", viewType);
495
496 }
497
498 if (result != nullptr) {
499 auto viewPtr = QPointer<QOhosView>(this);
500 std::weak_ptr<QOhosWindowProxy> weakWindowProxy = result;
501 auto shouldEmitSignalPredicate = [weakWindowProxy](QOhosView &view) {
502 auto windowProxy = weakWindowProxy.lock();
503 return windowProxy != nullptr && windowProxy.get() == view.m_ohosWindowProxy.get();
504 };
505
506 result->setWindowCallbackReceiver(
507 std::make_unique<QOhosWindowProxy::WindowCallbacks>(
508 QOhosWindowProxy::WindowCallbacks {
509 .onWindowEvent = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowEvent),
510 .onWindowStatusChange = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowStatusChange),
511 .onWindowVisibilityChange = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowVisibilityChange),
512 .onTouchOutside = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowTouchOutside),
513 .onAvoidAreaChange = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::avoidAreaChanged),
514 .onWindowRectChange = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowRectChanged),
515 .onWindowRectChangeInGlobalDisplay = makeViewConditionalSignalEmitter(
516 viewPtr, shouldEmitSignalPredicate, &QOhosView::windowRectChangedInGlobalDisplay),
517 .onWindowDisplayIdChange = makeViewConditionalSignalEmitter(viewPtr, shouldEmitSignalPredicate, &QOhosView::windowDisplayIdChanged),
518 }));
519
520 result->setNonClientAreaMouseWindowCallbackReceiver(
521 this,
522 [viewPtr, shouldEmitSignalPredicate](std::vector<QOhosWindowProxy::NonClientAreaMouseEvent> &&batch) {
523 if (!viewPtr.isNull() && shouldEmitSignalPredicate(*viewPtr)) {
525 inputEventHandler->onNonClientAreaMouseEvents(viewPtr->m_ownerWindow, std::move(batch));
526 }
527 });
528
529 result->setNonClientAreaTouchWindowCallbackReceiver(
530 this,
531 [viewPtr, shouldEmitSignalPredicate](std::vector<QOhosWindowProxy::NonClientAreaTouchEvent> &&batch) {
532 if (!viewPtr.isNull() && shouldEmitSignalPredicate(*viewPtr)) {
534 inputEventHandler->onNonClientAreaTouchEvents(viewPtr->m_ownerWindow, std::move(batch));
535 }
536 });
537
538 if (result->qtIsMainWindow() && result->isFocused().value_or(false)) {
539 // HACK
540 // WINDOW_ACTIVE event should be handled by QOhosFloatingWindow after OHOS system event received.
541 // Until we cannot register this event properly, keep sending it manually here.
542 sendAsyncSyntheticWindowActiveEvent();
543 }
544 }
545
546 return result;
547}
548
549bool QOhosView::isWindowTransparencyRequested() const
550{
551 return m_ownerWindow->requestedFormat().hasAlpha();
552}
553
554QOhosView::QOhosView(QWindow *ownerWindow, QSharedPointer<QNativeNode> nativeNode, QOhosPropertiesProvider windowPropertyProvider)
555 : m_windowPropertiesProvider(windowPropertyProvider)
559 , m_updateData()
560 , m_updatePending(false)
562 , m_requireHandheldDeviceSupport(isHandheldDeviceType())
565{
566 auto avoidAreasProvider = std::make_shared<AvoidAreaCache>([this](AvoidAreaCache::AvoidAreaType avoidAreaType) {
567 return m_ohosWindowProxy != nullptr
568 ? m_ohosWindowProxy->getWindowAvoidArea(avoidAreaType)
569 : AvoidAreaCache::AvoidArea{};
570 });
571
572 connect(
573 this, &QOhosView::avoidAreaChanged,
574 this,
575 [avoidAreasProvider](QOhosWindowProxy::AvoidAreaType avoidAreaType, const QOhosWindowProxy::AvoidArea &avoidArea) {
576 avoidAreasProvider->put(avoidAreaType, avoidArea);
577 });
578
579 m_avoidAreasProvider = [avoidAreasProvider](QOhosWindowProxy::AvoidAreaType type) {
580 return avoidAreasProvider->getStoredOrRetrieveFromWindowProxy(type);
581 };
582
583 connect(
584 m_nativeNode.get(), &QNativeNode::surfaceStatusChanged,
585 this, [this](const std::optional<QSize> &optSurfaceSize) {
586 Q_EMIT surfaceStatusChanged(optSurfaceSize);
587 });
588
589 connect(
592
593 m_nativeNode->setNodeAreaChangeHandler(
594 [this](auto nodeAreaChangeEvent) {
595 Q_EMIT nodeAreaChanged(nodeAreaChangeEvent);
596 });
597
598 m_nativeNode->setNodeVisibilityChangeHandler(
599 [this](bool visible) {
600 if (m_ohosWindowProxy == nullptr)
601 Q_EMIT windowVisibilityChange(visible);
602 });
603
604 std::vector<std::shared_ptr<void>> writeCallbacks = {
605 m_windowPropertiesProvider.addPropertyWriteCallback<double, &QOhosPlatformWindow::windowCornerRadiusProperty>(
606 [this](double windowCornerRadius) {
607 setWindowCornerRadius(windowCornerRadius);
608 }),
609 m_windowPropertiesProvider.addPropertyWriteCallback<bool, &QOhosPlatformWindow::windowPrivacyModeSettingProperty>(
610 [this](bool windowPrivacyModeSetting) {
611 setPrivacyMode(windowPrivacyModeSetting);
612 }),
613 m_windowPropertiesProvider.addPropertyWriteCallback<QColor, &QOhosPlatformWindow::surfaceBackgroundColorProperty>(
614 [this](QColor surfaceBackgroundColor) {
615 setBackgroundColor(surfaceBackgroundColor);
616 }),
617 m_windowPropertiesProvider.addPropertyWriteCallback<bool, &QOhosPlatformWindow::windowKeepScreenOnProperty>(
618 [this](bool keepScreenOn) {
619 setWindowKeepScreenOn(keepScreenOn);
620 }),
621 m_windowPropertiesProvider.addPropertyWriteCallback<bool, &QOhosPlatformWindow::windowFixedSizeStateProperty>(
622 [this](bool fixedSizeStateEnabled) {
623 setFixedSizeStateEnabled(fixedSizeStateEnabled);
624 }),
625 m_windowPropertiesProvider.addPropertyWriteCallback<int, &QOhosPlatformWindow::windowBrightnessProperty>(
626 [this](int brightness) {
627 setBrightness(brightness);
628 }),
629 m_windowPropertiesProvider.addPropertyWriteCallback<int, &QOhosPlatformWindow::windowContrastProperty>(
630 [this](int contrast) {
631 setContrast(contrast);
632 }),
633 m_windowPropertiesProvider.addPropertyWriteCallback<int, &QOhosPlatformWindow::windowSaturationProperty>(
634 [this](int saturation) {
635 setSaturation(saturation);
636 }),
637 m_windowPropertiesProvider.addPropertyWriteCallback<bool, &QOhosPlatformWindow::windowDragResizableProperty>(
638 [this](bool dragResizable) {
639 setWindowDragResizable(dragResizable);
640 }),
641 };
642
643 m_windowPropertiesProviderCallbacksHandle = QtOhos::moveToSharedPtr(std::move(writeCallbacks));
644}
645
647{
648 // This call is necessary in order to avoid receiving callbacks
649 // from the underlying XComponent after we terminate the window.
650 // Not having this resulted in exceptions thrown from the system
651 // because QOhosNativeXComponent reffered to the window object that is null.
652 m_nativeNode.reset();
653}
654
655void QOhosView::setPosition(const QPoint &position)
656{
657 setSystemUpdateProperty(&SystemUpdateData::position, {position, {}});
658}
659
661 const QPoint &position, QOhosDisplayInfo::JsDisplayId jsDisplayId)
662{
663 setSystemUpdateProperty(&SystemUpdateData::position, {position, jsDisplayId});
664 flushSystemPropertyUpdatesImmediate();
665}
666
667void QOhosView::setSize(const QSize &size)
668{
669 setSystemUpdateProperty(&SystemUpdateData::size, size);
670}
671
672void QOhosView::setSizeLimits(const QSize &minSize, const QSize &maxSize)
673{
674 setSystemUpdateProperty(&SystemUpdateData::sizeLimits, std::make_pair(minSize, maxSize));
675}
676
677void QOhosView::setTransparentBackground(bool transparent)
678{
679 setSystemUpdateProperty(&SystemUpdateData::backgroundTransparent, transparent);
680}
681
682void QOhosView::setFocusable(bool focusable)
683{
684 setSystemUpdateProperty(&SystemUpdateData::focusable, focusable);
685}
686
687void QOhosView::setBackgroundColor(const QColor &color)
688{
689 setSystemUpdateProperty(&SystemUpdateData::backgroundColor, color);
690}
691
692void QOhosView::setBrightness(int brightness)
693{
694 setSystemUpdateProperty(&SystemUpdateData::brightness, brightness);
695}
696
697void QOhosView::setContrast(int contrast)
698{
699 setSystemUpdateProperty(&SystemUpdateData::contrast, contrast);
700}
701
702void QOhosView::setSaturation(int saturation)
703{
704 setSystemUpdateProperty(&SystemUpdateData::saturation, saturation);
705}
706
707void QOhosView::setWindowKeepScreenOn(bool keepScreenOn)
708{
709 if (m_ohosWindowProxy != nullptr)
710 m_ohosWindowProxy->setWindowKeepScreenOn(keepScreenOn);
711}
712
713void QOhosView::setFixedSizeStateEnabled(bool enabled)
714{
715 if (m_ohosWindowProxy == nullptr)
716 return;
717
718 const bool systemMaximizable = viewType() == ViewType::MainWindow
719 || (viewType() == ViewType::SubWindow && m_ohosWindowProxy->isSubWindowMaximizeSupported());
720 if (!systemMaximizable)
721 return;
722
724 qOhosPrintfWarning(
725 "%s: fixed size state is not supported while in HandheldDeviceFullScreen mode",
726 Q_FUNC_INFO);
727 return;
728 }
729
730 using SupportWindowMode = QOhosWindowProxy::SupportWindowMode;
731 const auto supportedWindowModes = enabled
732 ? std::set<SupportWindowMode>({SupportWindowMode::FLOATING})
733 : viewType() == ViewType::MainWindow
734 ? std::set<SupportWindowMode>({SupportWindowMode::FULL_SCREEN, SupportWindowMode::FLOATING, SupportWindowMode::SPLIT})
735 : std::set<SupportWindowMode>({SupportWindowMode::FULL_SCREEN, SupportWindowMode::FLOATING});
736
737 m_ohosWindowProxy->setSupportedWindowModes(supportedWindowModes);
738}
739
740void QOhosView::showWindow()
741{
742 auto *ohosPlatformWindow = static_cast<QOhosPlatformWindow *>(m_ownerWindow->handle());
743 m_ohosWindowProxy->showWindow(
744 QOhosWindowProxy::ShowWindowOptions{
745 .focusOnShow = ohosPlatformWindow->shouldShowWindowWithoutActivating()
746 ? std::optional(false)
747 : std::nullopt,
748 });
749}
750
751void QOhosView::sendAsyncSyntheticWindowActiveEvent()
752{
753 QMetaObject::invokeMethod(
754 this,
755 [this]() {
756 QOhosWindowProxy::WindowEvent syntheticWindowActiveEvent = {
757 .type = QOhosWindowProxy::WindowEventType::WINDOW_ACTIVE,
758 };
759 Q_EMIT windowEvent(syntheticWindowActiveEvent);
760 },
761 Qt::QueuedConnection);
762}
763
764void QOhosView::setCursor(const QCursor &cursor)
765{
766 setSystemUpdateProperty(&SystemUpdateData::cursor, cursor);
767}
768
769void QOhosView::setModality(Qt::WindowModality modality)
770{
771 setSystemUpdateProperty(&SystemUpdateData::modality, modality);
772}
773
774void QOhosView::setTitle(const QString &title)
775{
776 setSystemUpdateProperty(&SystemUpdateData::title, title);
777}
778
780{
781 if (m_ohosWindowProxy == nullptr) {
782 m_nativeNode->raise();
783 return;
784 }
785
786 switch (viewType()) {
787 case ViewType::MainWindow:
788 showWindow();
789 break;
790 case ViewType::SubWindow:
791 m_ohosWindowProxy->raiseToAppTop();
792 break;
793 case ViewType::FloatWindow:
794 case ViewType::EmbeddedWindow:
795 break;
796 }
797}
798
800{
801 if (m_ohosWindowProxy != nullptr && m_ownerWindow->isVisible())
802 showWindow();
803 else
804 m_nativeNode->lower();
805}
806
807void QOhosView::updateWindowSize(const QSize &size)
808{
809 if (m_ohosWindowProxy != nullptr)
810 m_ohosWindowProxy->setSize(size);
811 else
812 m_nativeNode->setSize(size);
813}
814
815void QOhosView::updateWindowPosition(const std::pair<QPoint, std::optional<QOhosDisplayInfo::JsDisplayId>> &positionProp)
816{
817 QPoint position;
818 std::optional<QOhosDisplayInfo::JsDisplayId> displayId;
819 std::tie(position, displayId) = positionProp;
820
821 if (m_ohosWindowProxy != nullptr) {
822 m_ohosWindowProxy->moveWindowToGlobalOrGlobalDisplay(position, displayId);
823 } else {
824 m_nativeNode->setPosition(position);
825 }
826}
827
828void QOhosView::updateWindowBackgroundTransparency(bool transparent)
829{
830 if (m_ohosWindowProxy != nullptr) {
831 auto opaqueSystemBackgroundRgb = QGuiApplicationPrivate::platformTheme()
832 ->palette(QPlatformTheme::SystemPalette)
833 ->window()
834 .color()
835 .rgb();
836 m_ohosWindowProxy->setWindowBackgroundColor(
837 transparent
838 ? QColor(Qt::transparent)
839 : tryGetBackgroundColorFromWindow(m_ownerWindow).value_or(
840 QColor(opaqueSystemBackgroundRgb)));
841 }
842}
843
844void QOhosView::updateWindowCursor(const QCursor &cursor)
845{
846 if (m_ohosWindowProxy == nullptr)
847 return;
848
849 if (cursor.shape() == Qt::BitmapCursor || cursor.shape() == Qt::BlankCursor) {
850 auto bitmapCursor =
851 cursor.shape() == Qt::BlankCursor
852 ? makeTransparentBitmapCursor({1, 1})
853 : cursor;
854
855 QImage bitmapCursorImage = bitmapCursor.pixmap().isNull()
856 ? createImageFromBitmapAndMask(getCursorBitmap(bitmapCursor), getCursorMask(bitmapCursor))
857 : bitmapCursor.pixmap().toImage();
858
859 m_ohosWindowProxy->setCustomCursor(bitmapCursorImage, bitmapCursor.hotSpot());
860 } else {
861 m_ohosWindowProxy->setPointerStyleSync(cursor);
862 }
863}
864
865void QOhosView::updateWindowFocusable(bool focusable)
866{
867 if (m_ohosWindowProxy != nullptr)
868 m_ohosWindowProxy->setWindowFocusable(focusable);
869 m_nativeNode->setFocusable(focusable);
870}
871
872void QOhosView::updateWindowBackgroundColor(const QColor &color)
873{
874 m_nativeNode->setBackgroundColor(color);
875}
876
877void QOhosView::updateWindowBrightness(int brightness)
878{
879 m_nativeNode->setBrightness(brightness);
880}
881
882void QOhosView::updateWindowContrast(int contrast)
883{
884 m_nativeNode->setContrast(contrast);
885}
886
887void QOhosView::updateWindowSaturation(int saturation)
888{
889 m_nativeNode->setSaturation(saturation);
890}
891
892void QOhosView::updateWindowTransparentForInput(bool transparentForInput)
893{
894 if (m_ohosWindowProxy != nullptr)
895 m_ohosWindowProxy->setWindowTouchable(!transparentForInput);
896 m_nativeNode->setTransparentForInput(transparentForInput);
897}
898
899void QOhosView::updateWindowSizeLimits(const std::pair<QSize, QSize> &sizeLimits)
900{
901 if (m_ohosWindowProxy != nullptr) {
902 auto windowMargins = QOhosPlatformWindow::fromQWindow(m_ownerWindow)->frameMargins();
903 // HACK: the system reads a minimum size of 0 as "not set" and applies
904 // its default (320x72 vp), so send at least 1.
905 m_ohosWindowProxy->setWindowLimits(
906 sizeLimits.first.grownBy(windowMargins).expandedTo(QSize(1, 1)),
907 sizeLimits.second.grownBy(windowMargins).expandedTo(QSize(1, 1)));
908 }
909}
910
911void QOhosView::updateWindowModality(Qt::WindowModality modality)
912{
913 if (m_ohosWindowProxy != nullptr) {
914 if (viewType() != ViewType::SubWindow) {
915 qCWarning(QtForOhos, "%s: Modality is supported only for sub-windows.", Q_FUNC_INFO);
916 return;
917 }
918 if (modality == Qt::WindowModality::ApplicationModal) {
919 qCWarning(
920 QtForOhos,
921 "%s: Qt::ApplicationModal policy is unsupported by the platform. The window will behave like Qt::WindowModal.",
922 Q_FUNC_INFO);
923 }
924
925 auto ohosModalityType = mapQtWindowModalityToOhosOrDefault(modality);
926 if (ohosModalityType.has_value())
927 m_ohosWindowProxy->setSubWindowModalEnabled(ohosModalityType.value());
928 else
929 m_ohosWindowProxy->setSubWindowModalDisabled();
930 }
931}
932
933void QOhosView::updateWindowTitle(const QString &title)
934{
935 if (m_ohosWindowProxy != nullptr)
936 m_ohosWindowProxy->setTitle(title);
937}
938
939void QOhosView::scheduleSystemUpdateIfNeeded()
940{
941 if (m_updatePending)
942 return;
943 m_updatePending = QMetaObject::invokeMethod(
944 this,
945 [this]() {
946 flushSystemPropertyUpdatesImmediate();
947 },
948 Qt::QueuedConnection);
949}
950
952{
953 return m_ownerWindow;
954}
955
957{
958 auto *platformWindow = QOhosPlatformWindow::fromQWindow(m_ownerWindow);
959
960 auto currentViewTypeInfo = determineViewTypeAndLogicalParent(platformWindow);
961 const bool hadWindowProxy = m_ohosWindowProxy != nullptr;
962 const bool needsWindowProxy = !hadWindowProxy
963 && currentViewTypeInfo.viewType != ViewType::EmbeddedWindow;
964 const bool windowProxyRoleChanged = hadWindowProxy
965 && viewType() != currentViewTypeInfo.viewType;
966
967 if (needsWindowProxy || windowProxyRoleChanged) {
968 auto qOhosWindowProxy = tryCreateWindowProxyIfNeeded(currentViewTypeInfo.viewType, currentViewTypeInfo.optLogicalParent);
969
970 if (qOhosWindowProxy != nullptr
971 && currentViewTypeInfo.viewType == ViewType::SubWindow) {
972 constexpr bool preventSubWindowClose = true;
973 qOhosWindowProxy->setSubWindowCloseHandler(
974 [this]() {
975 if (!m_ownerWindow.isNull()) {
976 qOhosPrintfDebug("onSubWindowCloseHandler: calling close()");
977 QOhosCloseEventContext::runWithCloseRootCauseSet(
978 QOhosCloseEventContext::CloseRootCause::SubWindowClose,
979 [&]() {
980 m_ownerWindow->close();
981 });
982 }
983 },
984 preventSubWindowClose);
985 }
986
987 m_viewType = currentViewTypeInfo.viewType;
988 setOrResetWindowProxy(qOhosWindowProxy, currentViewTypeInfo.optLogicalParent);
989
990 if (qOhosWindowProxy != nullptr) {
991 m_nativeNode->setParent(qOhosWindowProxy->nodeXComponent());
992 m_nativeNode->fillToParent();
993 }
994#if QT_CONFIG(draganddrop)
995 m_nativeNode->enableDropDisallowedBadge();
996#endif
997 } else {
998 syncWindowStateImmediate();
999 }
1000
1001 if (viewType() == ViewType::MainWindow) {
1002 const auto windowStates = m_ownerWindow->windowStates();
1003 if (windowStates.testFlag(Qt::WindowState::WindowFullScreen)) {
1004 // A phone window created fullscreen still shows the system bars, so
1005 // hide them explicitly. On 2-in-1/tablet the window is already
1006 // immersive at creation; re-applying would only make it twitch.
1007 if (hadWindowProxy || QOhosDeviceInfo::isPhone())
1009 } else if (windowStates.testFlag(Qt::WindowState::WindowMaximized)) {
1010 maximize();
1011 } else if (QOhosDeviceInfo::isPhone()
1012 && m_ownerWindow->flags().testFlag(Qt::ExpandedClientAreaHint)) {
1013 applyPhoneWindowChrome();
1014 }
1015 } else if (viewType() == ViewType::SubWindow && m_ohosWindowProxy != nullptr) {
1016 m_ohosWindowProxy->setFollowParentMultiScreenPolicy(true);
1017 }
1018
1019 if (m_ohosWindowProxy != nullptr) {
1020 if (hadWindowProxy)
1022 showWindow();
1023 }
1024
1025 // A sub window ignores maximize requests until it is shown.
1026 if (viewType() == ViewType::SubWindow && m_ohosWindowProxy != nullptr) {
1027 const auto windowStates = m_ownerWindow->windowStates();
1028 if (windowStates.testFlag(Qt::WindowState::WindowFullScreen))
1030 else if (windowStates.testFlag(Qt::WindowState::WindowMaximized))
1031 maximize();
1032 }
1033
1034 auto *surface = surfaceOrNull();
1035 const bool isVulkanWindow =
1036 m_ownerWindow && m_ownerWindow->surfaceType() == QSurface::VulkanSurface;
1037 if (surface != nullptr && !isVulkanWindow)
1039
1040 m_nativeNode->setVisibility(true);
1041
1042 // Mirrors hide(): ArkUI does not report the node visibility change for an
1043 // embedded window, so the view has to.
1044 if (viewType() == ViewType::EmbeddedWindow)
1045 Q_EMIT windowVisibilityChange(true);
1046}
1047
1048void QOhosView::applyPhoneWindowChrome()
1049{
1050 if (m_ohosWindowProxy == nullptr)
1051 return;
1052
1053 // Lay the window out under the system bars when fullscreen or when the
1054 // client area is expanded; only fullscreen also hides the bars.
1055 const bool fullScreen = m_ownerWindow->windowStates().testFlag(Qt::WindowFullScreen);
1056 const bool expanded = m_ownerWindow->flags().testFlag(Qt::ExpandedClientAreaHint);
1057 m_ohosWindowProxy->setWindowLayoutFullScreen(fullScreen || expanded);
1058 m_ohosWindowProxy->setWindowSystemBarEnable(
1059 fullScreen ? QStringList{}
1060 : QStringList{ QStringLiteral("status"), QStringLiteral("navigation") });
1061}
1062
1064{
1065 auto *windowProxy = flushedWindowProxyOrNull();
1066 if (windowProxy == nullptr)
1067 return;
1068
1070 applyPhoneWindowChrome();
1071 return;
1072 }
1073
1074 if (!isMaximizeRequestSupportedOrLogWarning()) {
1075 QOhosPlatformWindow::fromQWindow(m_ownerWindow)->resetRefusedMaximizeState();
1076 return;
1077 }
1078
1079 if (!windowProxy->tryMaximize(QOhosWindowProxy::MaximizePresentation::ENTER_IMMERSIVE))
1080 QOhosPlatformWindow::fromQWindow(m_ownerWindow)->resetRefusedMaximizeState();
1081}
1082
1084{
1085 auto *windowProxy = flushedWindowProxyOrNull();
1086 if (windowProxy == nullptr)
1087 return;
1088
1090 windowProxy->recover();
1091 else
1092 applyPhoneWindowChrome();
1093}
1094
1096{
1097 auto *windowProxy = flushedWindowProxyOrNull();
1098 if (windowProxy != nullptr)
1099 windowProxy->minimize();
1100}
1101
1103{
1104 if (m_ohosWindowProxy != nullptr) {
1105 if (QGuiApplicationPrivate::focus_window) {
1106 const auto *focusPlatformWindow = QOhosPlatformWindow::fromQWindow(QGuiApplicationPrivate::focus_window);
1107 const auto *focusView = focusPlatformWindow->ownedViewOrNull();
1108 if (focusView && focusView != this) {
1109 if (focusView->m_ohosWindowProxy) {
1110 focusView->m_ohosWindowProxy->shiftAppWindowFocus(*m_ohosWindowProxy);
1111 } else {
1112 // If the previously focused window is an EmbeddedWindow.
1113 sendAsyncSyntheticWindowActiveEvent();
1114 }
1115 }
1116 }
1117 } else {
1118 // for EmbeddedWindow
1119 sendAsyncSyntheticWindowActiveEvent();
1120 }
1121}
1122
1124{
1125 auto *windowProxy = flushedWindowProxyOrNull();
1126 if (windowProxy == nullptr)
1127 return;
1128
1129 if (!isMaximizeRequestSupportedOrLogWarning()) {
1130 QOhosPlatformWindow::fromQWindow(m_ownerWindow)->resetRefusedMaximizeState();
1131 return;
1132 }
1133
1134 if (!windowProxy->tryMaximize(QOhosWindowProxy::MaximizePresentation::EXIT_IMMERSIVE))
1135 QOhosPlatformWindow::fromQWindow(m_ownerWindow)->resetRefusedMaximizeState();
1136}
1137
1138std::unique_ptr<QOhosView> QOhosView::createForWindow(QOhosPlatformWindow *window, QOhosPropertiesProvider windowPropertiesProvider)
1139{
1140 auto *qWindow = window->window();
1141 QNativeNode::CreateInfo createInfo;
1142 createInfo.geometry = window->geometry();
1143 createInfo.window = qWindow;
1144 createInfo.backgroundColor = windowPropertiesProvider.tryGetProperty<QColor, &QOhosPlatformWindow::surfaceBackgroundColorProperty>();
1145 createInfo.renderFitPolicyHint = qTransform(
1146 windowPropertiesProvider.tryGetProperty<int, &QOhosPlatformWindow::nativeNodeRenderFitPolicyHintProperty>(),
1147 [](int renderFit) {
1148 return static_cast<::ArkUI_RenderFit>(renderFit);
1149 });
1150
1151 QPlatformWindow *parentPlatformWindow = window->parent();
1152
1153 if (parentPlatformWindow != nullptr) {
1154 auto *parentPlatformWindow = static_cast<QOhosPlatformWindow *>(window->parent());
1155 auto *parentView = parentPlatformWindow->ownedViewOrNull();
1156 createInfo.optParent = parentView != nullptr
1157 ? std::optional(parentView->m_nativeNode.get())
1158 : std::nullopt;
1159 }
1160
1161 auto nativeNode = QSharedPointer<QNativeNode>::create(createInfo);
1162 return std::make_unique<QOhosView>(qWindow, nativeNode, windowPropertiesProvider);
1163}
1164
1166{
1167 QOhosView::ViewGeometry result;
1168 if (m_ohosWindowProxy != nullptr) {
1169 auto windowProperties = m_ohosWindowProxy->getWindowProperties();
1170 result.frameGeometry = windowProperties.windowRect;
1171 // Translate relative coordinates of the window to absolute screen values
1172 result.geometry = windowProperties.drawableRect.translated(windowProperties.windowRect.topLeft());
1173 // HACK:
1174 // "result.geometry" might contain invalid size but (1) it will likely contain proper
1175 // top-left corner coords and (2) "result.frameGeometry" is also valid, so adjust the
1176 // invalidated size based on these two.
1177 result.geometry.setSize(
1178 evaluateGeometrySizeBasedOnFrameGeometry(result.geometry.topLeft(), result.frameGeometry));
1179 result.displayId = windowProperties.displayId;
1180 } else {
1181 result.frameGeometry = m_nativeNode->geometry().toRect();
1182 result.geometry = result.frameGeometry;
1183
1184 const auto *ancestorViewWithWindow = ancestorViewWithWindowOrNull();
1185 result.displayId = ancestorViewWithWindow != nullptr
1186 ? ancestorViewWithWindow->m_ohosWindowProxy->getWindowProperties().displayId
1187 : std::nullopt;
1188 }
1189
1190 return result;
1191}
1192
1193QMargins QOhosView::avoidAreaMargins(QOhosWindowProxy::AvoidAreaType type) const
1194{
1195 auto avoidArea = m_avoidAreasProvider(type);
1196 QMargins margins;
1197 tryUpdateMaximumMarginsFromAvoidArea(margins, avoidArea);
1198 return margins;
1199}
1200
1202{
1203 return m_ohosWindowProxy != nullptr ? m_ohosWindowProxy->getDisplayCutoutRects()
1204 : QList<QRect>();
1205}
1206
1208{
1209 return m_viewType.value_or(ViewType::EmbeddedWindow);
1210}
1211
1213{
1214 auto *platformWindow = QOhosPlatformWindow::fromQWindow(m_ownerWindow);
1215 auto targetWindowGeometry = platformWindow->geometry().marginsAdded(platformWindow->frameMargins());
1216
1217 m_updateData.position.optPendingUpdateRequest = {targetWindowGeometry.topLeft(), {}};
1218 m_updateData.size.optPendingUpdateRequest = targetWindowGeometry.size();
1219 scheduleSystemUpdateIfNeeded();
1220}
1221
1223{
1224 switch (viewType()) {
1225 case ViewType::MainWindow:
1226 hideMainWindow();
1227 break;
1228 case ViewType::FloatWindow:
1229 case ViewType::SubWindow:
1230 {
1231 setOrResetWindowProxy(nullptr, nullptr);
1232 auto syntheticWindowHiddenEvent = QOhosWindowProxy::WindowEvent {
1233 .type = QOhosWindowProxy::WindowEventType::WINDOW_HIDDEN,
1234 };
1235 Q_EMIT windowEvent(syntheticWindowHiddenEvent);
1236 break;
1237 }
1238 case ViewType::EmbeddedWindow:
1239 Q_EMIT windowVisibilityChange(false);
1240 break;
1241 }
1242
1243 m_nativeNode->setVisibility(false);
1244}
1245
1247{
1248 setTransparentBackground(isWindowTransparencyRequested());
1249}
1250
1251void QOhosView::setWindowMask(const QOhosWindowProxy::WindowMask &mask)
1252{
1253 if (m_ohosWindowProxy != nullptr)
1254 m_ohosWindowProxy->setWindowMask(mask);
1255}
1256
1257QOhosSurface *QOhosView::surfaceOrNull() const
1258{
1259 return m_nativeNode->surfaceOrNull();
1260}
1261
1263{
1264 return m_ohosWindowProxy ? m_ohosWindowProxy->abilityObjectRef() : QHarmonyJsObjectRef();
1265}
1266
1268{
1269 return m_ohosWindowProxy ? m_ohosWindowProxy->jsWindowObjectRef() : QHarmonyJsObjectRef();
1270}
1271
1273{
1274 return m_nativeNode->windowId();
1275}
1276
1278{
1279 qCDebug(QtForOhos) << "view:" << this << "setParentOrReparent parentView:" << &parentView;
1280 m_nativeNode->setParent(*parentView.m_nativeNode);
1281 m_viewType.reset();
1282 setOrResetWindowProxy(nullptr, parentView.ownerWindow());
1283}
1284
1286{
1287 if (viewType() != ViewType::EmbeddedWindow) {
1288 qCDebug(QtForOhos) << Q_FUNC_INFO << m_ownerWindow;
1289 return;
1290 }
1291
1292 m_nativeNode->detachFromParentIfPresent();
1293 m_optLogicalParent = nullptr;
1294
1295 if (m_ownerWindow->isVisible() && !m_ohosWindowProxy)
1297}
1298
1300{
1301 m_nativeNode->setVisibility(visible);
1302 m_lastMainWindowHideMethod = WindowHideMethod::NativeNodeVisibility;
1303}
1304
1305void QOhosView::hideMainWindow()
1306{
1307 if (m_ohosWindowProxy == nullptr) {
1309 return;
1310 }
1311
1312 if (m_ohosWindowProxy->tryHideAbility()) {
1313 m_lastMainWindowHideMethod = WindowHideMethod::HideAbility;
1314 return;
1315 }
1316
1317 if (QOhosPlatformWindow::isWindowBeingClosedOrDestroyed(m_ownerWindow)) {
1319 return;
1320 }
1321
1322 m_ohosWindowProxy->minimize();
1323 m_lastMainWindowHideMethod = WindowHideMethod::Minimize;
1324
1325 auto *platformWindow = QOhosPlatformWindow::fromQWindow(m_ownerWindow);
1326 if (!platformWindow->windowStates().testFlag(Qt::WindowMinimized))
1327 ++m_pendingSelfMinimizeEchoes;
1328}
1329
1330void QOhosView::syncWindowStateImmediate(WindowStateSyncReason reason)
1331{
1332 if (m_ohosWindowProxy == nullptr && m_optLogicalParent == nullptr)
1333 return;
1334
1335 std::vector<std::function<void()>> postSurfaceDrawTasks;
1336 auto updatePostSurfaceDrawTask = qScopeGuard([&]() {
1337 if (!postSurfaceDrawTasks.empty()) {
1338 m_optPostSurfaceDrawTask = [postSurfaceDrawTasks = std::move(postSurfaceDrawTasks)]() {
1339 for (const auto &task: postSurfaceDrawTasks)
1340 task();
1341 };
1342 }
1343 });
1344
1345 if (reason == WindowStateSyncReason::ViewTypeChanged && m_ohosWindowProxy
1346 && viewType() == ViewType::MainWindow) {
1347 postSurfaceDrawTasks.emplace_back(
1348 [weakWindowProxy = QtOhos::makeWeakPtr(m_ohosWindowProxy)]() {
1349 auto windowProxy = weakWindowProxy.lock();
1350 if (windowProxy)
1351 windowProxy->removeStartingWindow();
1352 });
1353 }
1354
1355 auto *platformWindow = QOhosPlatformWindow::fromQWindow(m_ownerWindow);
1356
1357 auto targetWindowLimitsToSet =
1358 viewType() == ViewType::EmbeddedWindow
1359 ? std::make_pair(m_ownerWindow->minimumSize(), m_ownerWindow->maximumSize())
1360 : std::make_pair(platformWindow->windowMinimumSize(), platformWindow->windowMaximumSize());
1361
1362 auto windowFlags = QOhosPlatformWindow::platformWindowFlagsForQWindow(m_ownerWindow);
1363 bool focusable = !windowFlags.testFlag(Qt::WindowDoesNotAcceptFocus);
1364
1365 auto submitSystemPropertyUpdate = [](auto &targetProperty, const auto &targetValue) {
1366 targetProperty.optPendingUpdateRequest = targetValue;
1367 };
1368
1369 auto submitOrResetSystemPropertyUpdate = [&submitSystemPropertyUpdate](
1370 auto &targetProperty,
1371 const auto &targetValue,
1372 WindowGeometryPersistenceState windowGeometryPersistenceState) {
1373 if (windowGeometryPersistenceState == WindowGeometryPersistenceState::Enabled)
1374 targetProperty.optPendingUpdateRequest.reset();
1375 else
1376 submitSystemPropertyUpdate(targetProperty, targetValue);
1377 };
1378
1379 submitSystemPropertyUpdate(m_updateData.title, m_ownerWindow->title());
1380
1381 auto windowGeometryPersistenceState =
1382 viewType() == ViewType::MainWindow
1383 && m_geometryPersistencePolicy != ViewGeometryPersistencePolicy::Ignore
1384 ? syncWindowGeometryPersistenceState(m_ohosWindowProxy.get())
1385 : WindowGeometryPersistenceState::Disabled;
1386
1387 auto currentRuntimeDeviceTypeAndMode = queryQOhosRuntimeDeviceAndMode();
1388 bool windowGeometrySyncEnabled = false;
1389 switch (currentRuntimeDeviceTypeAndMode) {
1392 windowGeometrySyncEnabled = true;
1393 break;
1395 windowGeometrySyncEnabled = viewType() != ViewType::MainWindow;
1396 break;
1397 }
1398
1399 std::optional<QOhosDisplayInfo::JsDisplayId> targetDisplayId;
1400 switch (viewType()) {
1401 case ViewType::SubWindow:
1402 if (m_optLogicalParent == nullptr)
1403 qOhosReportFatalErrorAndAbort("%s: logical parent for a subwindow is null", Q_FUNC_INFO);
1404 targetDisplayId = tryGetSubWindowJsDisplayId(m_optLogicalParent, *m_ohosWindowProxy);
1405 break;
1406 case ViewType::MainWindow:
1407 {
1408 targetDisplayId = m_ohosWindowProxy->tryGetMainWindowJsDisplayId();
1409 break;
1410 }
1411 case ViewType::FloatWindow:
1412 case ViewType::EmbeddedWindow:
1413 break;
1414 }
1415
1416 auto targetGeometryToSet = platformWindow->lastRequestedWindowFrameGeometry();
1417
1418 if (windowGeometrySyncEnabled) {
1419 submitSystemPropertyUpdate(m_updateData.sizeLimits, targetWindowLimitsToSet);
1420 submitOrResetSystemPropertyUpdate(
1421 m_updateData.size, targetGeometryToSet.size(), windowGeometryPersistenceState);
1422
1423 if (!qt_window_private(m_ownerWindow)->positionAutomatic) {
1424 submitOrResetSystemPropertyUpdate(
1425 m_updateData.position,
1426 std::make_pair(targetGeometryToSet.topLeft(), targetDisplayId),
1427 windowGeometryPersistenceState);
1428 }
1429 }
1430
1431 submitSystemPropertyUpdate(m_updateData.backgroundTransparent, isWindowTransparencyRequested());
1432
1433 if (currentRuntimeDeviceTypeAndMode == QOhosRuntimeDeviceTypeAndMode::_2in1)
1434 submitSystemPropertyUpdate(m_updateData.focusable, focusable);
1435
1436 if (viewType() == ViewType::SubWindow)
1437 submitSystemPropertyUpdate(m_updateData.modality, m_ownerWindow->modality());
1438
1439 submitSystemPropertyUpdate(
1440 m_updateData.windowMinMaxCloseButtonsState,
1442 .maxButtonShown = windowFlags.testFlag(Qt::WindowMaximizeButtonHint),
1443 .minButtonShown = windowFlags.testFlag(Qt::WindowMinimizeButtonHint),
1444 .closeButtonShown = windowFlags.testFlag(Qt::WindowCloseButtonHint),
1445 });
1446
1447 submitSystemPropertyUpdate(
1448 m_updateData.windowStaysOnTop, windowFlags.testFlag(Qt::WindowStaysOnTopHint));
1449
1450 submitSystemPropertyUpdate(m_updateData.frameless, windowFlags.testFlag(Qt::FramelessWindowHint));
1451
1452 submitSystemPropertyUpdate(
1453 m_updateData.windowTransparentForInput, windowFlags.testFlag(Qt::WindowTransparentForInput));
1454
1455 flushSystemPropertyUpdatesImmediate();
1456
1457 bool disableWindowShadow = windowFlags.testFlag(Qt::WindowType::NoDropShadowWindowHint);
1458 if (disableWindowShadow)
1460
1461 if (!m_ownerWindow->mask().isNull() && m_ohosWindowProxy != nullptr) {
1462 m_ohosWindowProxy->setWindowMask(
1463 QOhosWindowProxy::WindowMask {
1464 .windowMaskRegion = m_ownerWindow->mask(),
1465 },
1466 targetGeometryToSet.size());
1467 }
1468 const auto privacyModeSetting = m_windowPropertiesProvider
1469 .tryGetProperty<bool, &QOhosPlatformWindow::windowPrivacyModeSettingProperty>();
1470 if (privacyModeSetting.has_value())
1471 setPrivacyMode(privacyModeSetting.value());
1472
1473 const auto windowCornerRadius = m_windowPropertiesProvider
1474 .tryGetProperty<double, &QOhosPlatformWindow::windowCornerRadiusProperty>();
1475 if (windowCornerRadius.has_value())
1476 setWindowCornerRadius(windowCornerRadius.value());
1477
1478 const auto keepScreenOn = m_windowPropertiesProvider
1479 .tryGetProperty<bool, &QOhosPlatformWindow::windowKeepScreenOnProperty>();
1480 if (keepScreenOn.has_value())
1481 setWindowKeepScreenOn(keepScreenOn.value());
1482
1483 auto fixedSizeStateEnabled = m_windowPropertiesProvider
1484 .tryGetProperty<bool, &QOhosPlatformWindow::windowFixedSizeStateProperty>();
1485 if (fixedSizeStateEnabled.has_value())
1486 setFixedSizeStateEnabled(fixedSizeStateEnabled.value());
1487
1488 auto windowDragResizable = m_windowPropertiesProvider
1489 .tryGetProperty<bool, &QOhosPlatformWindow::windowDragResizableProperty>();
1490 if (windowDragResizable.has_value())
1491 setWindowDragResizable(windowDragResizable.value());
1492
1493 // NOTE - when position automatic is set we do not control window position
1494 // therefore no window callback about window position change will be sent
1495 // and the screen that given window belongs to needs to be synchronized
1496 bool shouldSynchronizeTargetDisplayIdWithQpa =
1497 qt_window_private(m_ownerWindow)->positionAutomatic
1498 && reason == WindowStateSyncReason::ViewTypeChanged
1499 && m_ohosWindowProxy != nullptr;
1500
1501 if (shouldSynchronizeTargetDisplayIdWithQpa) {
1502 auto optTargetDisplayId = m_ohosWindowProxy->getWindowProperties().displayId;
1503 if (optTargetDisplayId.has_value()) {
1504 QOhosDisplayInfo::JsDisplayId syntheticDisplayIdChangeEvent = optTargetDisplayId.value();
1505 Q_EMIT windowDisplayIdChanged(syntheticDisplayIdChangeEvent);
1506 }
1507 }
1508}
1509
1510void QOhosView::flushSystemPropertyUpdatesImmediate()
1511{
1512 static const auto systemDataPropertyUpdateFuncPairsTuple = makeSystemUpdateDataPropertyUpdateFuncPairsTuple();
1513
1514 QtOhos::tupleForEach(
1515 systemDataPropertyUpdateFuncPairsTuple,
1516 [&](const auto &updateDataMemberPtrUpdateFuncPair) {
1517 auto memberPtr = updateDataMemberPtrUpdateFuncPair.first;
1518 auto updateFuncPtr = updateDataMemberPtrUpdateFuncPair.second;
1519 auto &property = m_updateData.*memberPtr;
1520 auto optUpdateRequest = std::exchange(property.optPendingUpdateRequest, {});
1521 if (optUpdateRequest.has_value())
1522 (this->*updateFuncPtr)(optUpdateRequest.value());
1523 });
1524 m_updatePending = false;
1525}
1526
1527QOhosWindowProxy *QOhosView::flushedWindowProxyOrNull()
1528{
1529 if (m_ohosWindowProxy == nullptr)
1530 return nullptr;
1531
1532 flushSystemPropertyUpdatesImmediate();
1533 return m_ohosWindowProxy.get();
1534}
1535
1536void QOhosView::addForeignWindowChild(QOhosForeignWindow *foreignWindow)
1537{
1538 m_nativeNode->addForeignWindowChild(foreignWindow);
1539}
1540
1542{
1543 auto *surface = m_nativeNode->surfaceOrNull();
1544 return surface != nullptr
1545 ? surface->surfaceResolution()
1546 : std::nullopt;
1547}
1548
1550{
1551 return m_ohosWindowProxy != nullptr
1552 ? m_ohosWindowProxy->getImmersiveModeEnabledState()
1553 : false;
1554}
1555
1557{
1558 if (viewType() == ViewType::SubWindow) {
1559 auto *screen = m_ownerWindow->screen();
1560 return screen != nullptr && m_ownerWindow->geometry().size() == screen->geometry().size();
1561 }
1562
1563 return false;
1564}
1565
1566void QOhosView::updateWindowMinMaxCloseButtonsState(const WindowMinMaxCloseButtonsState &state)
1567{
1568 if (m_ohosWindowProxy != nullptr) {
1569 m_ohosWindowProxy->setWindowTitleButtonVisible(
1570 state.maxButtonShown, state.minButtonShown, state.closeButtonShown);
1571 }
1572}
1573
1574void QOhosView::updateWindowStaysOnTop(bool staysOnTop)
1575{
1576 if (m_ohosWindowProxy != nullptr)
1577 m_ohosWindowProxy->setWindowTopmost(staysOnTop);
1578}
1579
1580void QOhosView::updateWindowFrameless(bool frameless)
1581{
1582 bool supportsFramelessWindow = viewType() == ViewType::MainWindow || viewType() == ViewType::SubWindow;
1583 if (m_ohosWindowProxy != nullptr && supportsFramelessWindow) {
1584 m_ohosWindowProxy->setWindowDecorVisible(!frameless);
1585 m_ohosWindowProxy->setWindowTitleMoveEnabled(!frameless);
1586 }
1587}
1588
1589void QOhosView::setWindowDragResizable(bool dragResizable)
1590{
1591 if (m_ohosWindowProxy != nullptr)
1592 m_ohosWindowProxy->enableDrag(dragResizable);
1593}
1594
1596{
1597 setSystemUpdateProperty(&SystemUpdateData::windowMinMaxCloseButtonsState, state);
1598}
1599
1600void QOhosView::setWindowStaysOnTop(bool staysOnTop)
1601{
1602 setSystemUpdateProperty(&SystemUpdateData::windowStaysOnTop, staysOnTop);
1603}
1604
1605void QOhosView::setFramelessWindow(bool frameless)
1606{
1607 setSystemUpdateProperty(&SystemUpdateData::frameless, frameless);
1608}
1609
1611{
1612 if (m_ohosWindowProxy != nullptr) {
1613 constexpr double windowShadowDisabledRadius = 0.0;
1614 m_ohosWindowProxy->setWindowShadowRadius(windowShadowDisabledRadius);
1615 }
1616}
1617
1618void QOhosView::setWindowCornerRadius(double radius)
1619{
1620 if (m_ohosWindowProxy != nullptr)
1621 m_ohosWindowProxy->setWindowCornerRadius(radius);
1622}
1623
1624void QOhosView::setWindowTransparentForInput(bool transparentForInput)
1625{
1626 setSystemUpdateProperty(&SystemUpdateData::windowTransparentForInput, transparentForInput);
1627}
1628
1630{
1631 if (m_ohosWindowProxy != nullptr)
1632 return m_ohosWindowProxy->startMoving();
1633 return false;
1634}
1635
1636void QOhosView::setPrivacyMode(bool privacyModeEnabled)
1637{
1638 if (m_ohosWindowProxy != nullptr)
1639 m_ohosWindowProxy->setWindowPrivacyMode(privacyModeEnabled);
1640}
1641
1642void QOhosView::startDrag(
1643 const std::vector<QImage> &images, const QPointF &hotspot,
1644 const QMimeData &mimeData, QOhosConsumer<Qt::DropAction> dropActionConsumer)
1645{
1646 m_nativeNode->startDrag(images, hotspot, mimeData, std::move(dropActionConsumer));
1647}
1648
1650{
1651 const auto lastMainWindowHideMethod = std::exchange(m_lastMainWindowHideMethod, {});
1652 if (m_ohosWindowProxy == nullptr || !m_ohosWindowProxy->qtIsMainWindow())
1653 return;
1654
1655 if (!lastMainWindowHideMethod.has_value()) {
1656 m_ohosWindowProxy->restore();
1657 return;
1658 }
1659
1660 switch (lastMainWindowHideMethod.value()) {
1661 case WindowHideMethod::NativeNodeVisibility:
1662 case WindowHideMethod::Minimize:
1663 m_ohosWindowProxy->restore();
1664 break;
1665 case WindowHideMethod::HideAbility:
1666 m_ohosWindowProxy->showAbility();
1667 break;
1668 }
1669}
1670
1672 Qt::WindowStates previousWindowState, Qt::WindowStates currentWindowState)
1673{
1674 auto stateChange = previousWindowState ^ currentWindowState;
1675 if (stateChange.testFlag(Qt::WindowState::WindowMinimized) && !currentWindowState.testFlag(Qt::WindowState::WindowMinimized)) {
1676 if (viewType() == ViewType::MainWindow)
1678 else if (m_ohosWindowProxy)
1679 showWindow();
1680 }
1681
1682 if (stateChange.testFlag(Qt::WindowState::WindowMaximized) && currentWindowState.testFlag(Qt::WindowState::WindowMaximized)) {
1683 maximize();
1684 return;
1685 }
1686
1687 if (stateChange.testFlag(Qt::WindowState::WindowFullScreen) && currentWindowState.testFlag(Qt::WindowState::WindowFullScreen)) {
1689 return;
1690 }
1691
1692 if (stateChange.testFlag(Qt::WindowState::WindowMinimized) && currentWindowState.testFlag(Qt::WindowState::WindowMinimized)) {
1693 minimize();
1694 return;
1695 }
1696
1697 if (!currentWindowState) {
1698 recover();
1699 return;
1700 }
1701}
1702
1704 Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
1705{
1706 const auto flagsChange = previousWindowFlags ^ currentWindowFlags;
1707
1708 bool minMaxCloseButtonStateChanged = (flagsChange & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)) != 0;
1709 bool framelessChanged = (flagsChange & Qt::FramelessWindowHint) != 0;
1710
1711 if (minMaxCloseButtonStateChanged || framelessChanged) {
1713 .maxButtonShown = currentWindowFlags.testFlag(Qt::WindowMaximizeButtonHint),
1714 .minButtonShown = currentWindowFlags.testFlag(Qt::WindowMinimizeButtonHint),
1715 .closeButtonShown = currentWindowFlags.testFlag(Qt::WindowCloseButtonHint),
1716 });
1717 }
1718
1719 bool windowStaysOnTopChanged = (flagsChange & Qt::WindowStaysOnTopHint) != 0;
1720 if (windowStaysOnTopChanged)
1721 setWindowStaysOnTop(currentWindowFlags.testFlag(Qt::WindowStaysOnTopHint));
1722
1723 bool transparentForInputChanged = (flagsChange & Qt::WindowTransparentForInput) != 0;
1724 if (transparentForInputChanged)
1725 setWindowTransparentForInput(currentWindowFlags.testFlag(Qt::WindowTransparentForInput));
1726
1727 if (framelessChanged)
1728 setFramelessWindow(currentWindowFlags.testFlag(Qt::FramelessWindowHint));
1729
1730 bool focusableChanged = (flagsChange & Qt::WindowDoesNotAcceptFocus) != 0;
1731 if (focusableChanged) {
1732 bool windowAcceptsFocus = !currentWindowFlags.testFlag(Qt::WindowDoesNotAcceptFocus);
1733 setFocusable(windowAcceptsFocus);
1734 }
1735
1736 bool disableWindowShadowChanged = (flagsChange & Qt::NoDropShadowWindowHint) != 0;
1737 if (disableWindowShadowChanged && currentWindowFlags.testFlag(Qt::NoDropShadowWindowHint))
1739
1740 bool expandedClientAreaChanged = (flagsChange & Qt::ExpandedClientAreaHint) != 0;
1741 if (expandedClientAreaChanged && QOhosDeviceInfo::isPhone())
1742 applyPhoneWindowChrome();
1743}
1744
1745QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo QOhosView::nodeAreaInfo() const
1746{
1747 return m_nativeNode->nodeAreaInfo();
1748}
1749
1756
1758{
1759 return !(*this == other);
1760}
1761
1762void QOhosView::setOrResetWindowProxy(std::shared_ptr<QOhosWindowProxy> windowProxy, QWindow *optLogicalParent)
1763{
1764 m_ohosWindowProxy.reset();
1765 m_ohosWindowProxy = windowProxy
1766 ? QtOhos::makeSharedPtrWithAttachedExtraData<QOhosWindowProxy>(
1767 windowProxy,
1768 QWindowProxyRegistry::instance().registerQWindowWithWindowProxy(ownerWindow(), *windowProxy))
1769 : nullptr;
1770 m_optLogicalParent = optLogicalParent;
1771 syncWindowStateImmediate(WindowStateSyncReason::ViewTypeChanged);
1772}
1773
1775{
1776 auto *platformWindow = m_optLogicalParent != nullptr
1777 ? QOhosPlatformWindow::fromQWindowOrNull(m_optLogicalParent)
1778 : nullptr;
1779
1780 return platformWindow != nullptr
1781 ? platformWindow->ownedViewOrNull()
1782 : nullptr;
1783}
1784
1785const QOhosView *QOhosView::ancestorViewWithWindowOrNull() const
1786{
1787 const QOhosView *parent = viewParentOrNull();
1788 while (parent != nullptr && !parent->m_ohosWindowProxy)
1789 parent = parent->viewParentOrNull();
1790
1791 return parent != nullptr && parent->m_ohosWindowProxy
1792 ? parent
1793 : nullptr;
1794}
1795
1797{
1798 return m_ohosWindowProxy ? m_ohosWindowProxy->snapshot() : QPixmap();
1799}
1800
1802{
1803 return m_nativeNode->nodeScreenGeometryPixels();
1804}
1805
1807{
1808 return m_nativeNode->nodeParentRelativeGeometryPixels();
1809}
1810
1812{
1813 if (m_pendingSelfMinimizeEchoes <= 0)
1814 return false;
1815
1816 --m_pendingSelfMinimizeEchoes;
1817 return true;
1818}
1819
1820bool QOhosView::isFixedSizeStateEnabled() const
1821{
1822 return m_windowPropertiesProvider
1823 .tryGetProperty<bool, &QOhosPlatformWindow::windowFixedSizeStateProperty>()
1824 .value_or(false);
1825}
1826
1827bool QOhosView::isMaximizeRequestSupportedOrLogWarning() const
1828{
1829 if (viewType() != ViewType::SubWindow)
1830 return true;
1831
1832 if (!m_ohosWindowProxy->isSubWindowMaximizeSupported()) {
1833 qCWarning(QtForOhos) << Q_FUNC_INFO << m_ownerWindow
1834 << "maximize request ignored: the sub window was created without maximize support"
1835 " (requires API 26, Qt::WindowMaximizeButtonHint and free window mode at creation)";
1836 return false;
1837 }
1838
1839 if (isFixedSizeStateEnabled()) {
1840 qCWarning(QtForOhos) << Q_FUNC_INFO << m_ownerWindow
1841 << "maximize request ignored: the sub window has a fixed size";
1842 return false;
1843 }
1844
1845 return true;
1846}
1847
1848QT_END_NAMESPACE
void externalContentClickDetected()
static QOhosPlatformIntegration * instance()
static WindowGeometryPersistencePolicy getMainWindowGeometryPersistencePolicy()
QOhosInputMethodEventHandler * inputMethodEventHandler() const
bool mainWindowTagValueOrFalse() const
bool floatWindowTagValueOrFalse() const
DecorationPreset decorationPreset() const
void clearNativeWindowSurface()
void windowStatusChange(QOhosWindowProxy::WindowStatus windowStatus)
void setParentOrReparent(QOhosView &parentView)
void requestActivate()
bool consumePendingSelfMinimizeEcho()
void setCursor(const QCursor &cursor)
void handleWindowFlagsChange(Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
void addForeignWindowChild(QOhosForeignWindow *foreignWindow)
void handleWindowStateChange(Qt::WindowStates previousWindowState, Qt::WindowStates currentWindowState)
void restoreMainWindow()
void setFocusable(bool focusable)
QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo nodeAreaInfo() const
QOhosSurface * surfaceOrNull() const
void windowVisibilityChange(bool visibility)
void setPositionOnScreenImmediate(const QPoint &position, QOhosDisplayInfo::JsDisplayId jsDisplayId)
QList< QRect > displayCutoutRects() const
void setTransparentBackground(bool transparent)
void setModality(Qt::WindowModality modality)
WId viewWindowId() const
bool isFullscreenImmersiveModeEnabled()
void setFramelessWindow(bool frameless)
QPixmap makeSnapshot() const
void setWindowShadowDisabled()
void setWindowTransparentForInput(bool transparentForInput)
void tryDetachFromEmbeddedParent()
ViewType viewType() const
QMargins avoidAreaMargins(QOhosWindowProxy::AvoidAreaType type) const
QWindow * ownerWindow() const
void handleSurfaceContentsUpdated()
void hide()
WindowStateSyncReason
Definition qohosview.h:91
void forceGeometryUpdate()
void externalContentInteractionDetected()
void setWindowMinMaxCloseButtonState(const WindowMinMaxCloseButtonsState &state)
void setWindowMask(const QOhosWindowProxy::WindowMask &windowMask)
void setSizeLimits(const QSize &minSize, const QSize &maxSize)
std::optional< QSize > surfaceResolution() const
QHarmonyJsObjectRef abilityObjectRef() const
void windowTouchOutside()
void handlePaletteChange()
void lower()
void windowDisplayIdChanged(QOhosDisplayInfo::JsDisplayId)
void minimize()
void setNativeNodeVisibility(bool visible)
QHarmonyJsObjectRef jsWindowObjectRef() const
void setWindowStaysOnTop(bool staysOnTop)
void setFullScreen()
void maximize()
ViewGeometry viewGeometry() const
void setSize(const QSize &size)
void recover()
bool startMoving()
void setPosition(const QPoint &position)
QOhosView(QWindow *ownerWindow, QSharedPointer< QNativeNode > nativeNode, QOhosPropertiesProvider propertiesProvider)
bool isSubWindowCoveringFullScreen() const
void showImmediate()
QRect nodeParentRelativeGeometryPixels() const
void setTitle(const QString &title)
const QOhosView * viewParentOrNull() const
QRect nodeScreenGeometryPixels() const
void raise()
void setWindowRectAutoSave(bool enabed)
QtOhosQpa::enums::ohos::window::MaximizePresentation MaximizePresentation
static std::shared_ptr< QOhosWindowProxy > createFloatWindow(const FloatWindowCreateInfo &createInfo)
QtOhosQpa::enums::ohos::window::WindowEventType WindowEventType
std::optional< QOhosDisplayInfo::JsDisplayId > tryGetMainWindowJsDisplayId() const
QtOhosQpa::enums::ohos::bundle::bundleManager::SupportWindowMode SupportWindowMode
QOhosWindowProxyExistingMainWindowCreateInfo ExistingMainWindowCreateInfo
bool tryMaximize(MaximizePresentation maximizePresentation)
static std::shared_ptr< QOhosWindowProxy > createForExistingMainWindow(const ExistingMainWindowCreateInfo &createInfo)
QtOhosQpa::enums::ohos::window::ModalityType ModalityType
bool isWindowRectAutoSave() const
QOhosWindowProxySubWindowCreateInfo SubWindowCreateInfo
QtOhosQpa::enums::ohos::window::AvoidAreaType AvoidAreaType
QOhosWindowProxyMainWindowCreateInfo MainWindowCreateInfo
QOhosWindowProxyFloatWindowCreateInfo FloatWindowCreateInfo
static std::shared_ptr< QOhosWindowProxy > createMainWindow(const MainWindowCreateInfo &createInfo)
QOhosWindowProxy::AvoidAreaType AvoidAreaType
Definition qohosview.cpp:92
AvoidAreaCache(std::function< AvoidArea(AvoidAreaType)> avoidAreasProvider)
AvoidArea getStoredOrRetrieveFromWindowProxy(AvoidAreaType avoidAreaType)
void put(AvoidAreaType avoidAreaType, const AvoidArea &avoidArea)
static QWindowProxyRegistry & instance()
Combined button and popup list for selecting options.
QSize evaluateGeometrySizeBasedOnFrameGeometry(const QPoint &geometryOrigin, const QRect &frameGeometry)
std::function< void(SignalParams...)> makeViewConditionalSignalEmitter(QPointer< QOhosView > viewPtr, std::function< bool(QOhosView &)> predicate, void(QOhosView::*signalFuncPtr)(SignalParams ...))
Definition qohosview.cpp:79
std::optional< QColor > tryGetBackgroundColorFromWindow(QWindow *window)
QCursor makeTransparentBitmapCursor(QSize cursorSize)
bool hasMaximizeButtonHintForSubWindow(const QWindow *qWindow)
QWindow * syntheticParentForQWindowOrNull(QWindow *qWindow)
std::optional< QOhosWindowProxy::ModalityType > mapQtWindowModalityToOhosOrDefault(Qt::WindowModality windowModality)
Definition qohosview.cpp:57
QBitmap getCursorMask(const QCursor &cursor)
void tryUpdateMaximumMarginsFromAvoidArea(QMargins &marginsToUpdate, const QOhosWindowProxy::AvoidArea &avoidArea)
QWindow * getFirstTopLevelWindowWithSystemFocusOrNull()
QWindow * getFirstTopLevelWindowOrNull()
QBitmap getCursorBitmap(const QCursor &cursor)
ViewGeometryPersistencePolicy determineViewGeometryPersistencePolicy()
std::optional< QOhosDisplayInfo::JsDisplayId > tryGetSubWindowJsDisplayId(QWindow *logicalParent, QOhosWindowProxy &windowProxy)
ViewTypeInfo determineViewTypeAndLogicalParent(const QOhosPlatformWindow *platformWindow)
WindowGeometryPersistenceState syncWindowGeometryPersistenceState(QOhosWindowProxy *windowProxy)
QImage createImageFromBitmapAndMask(const QBitmap &bitmap, const QBitmap &mask)
bool acquireAndCleanPendingAutoStartedInstanceWindowFlag()
bool isHandheldDeviceType()
QOhosRuntimeDeviceTypeAndMode queryQOhosRuntimeDeviceAndMode()
bool operator==(const WindowMinMaxCloseButtonsState &other) const
bool operator!=(const WindowMinMaxCloseButtonsState &other) const
QOhosView::ViewType viewType
Definition qohosview.cpp:47