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
qohosfloatingwindow.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 <qohosfloatingwindow.h>
5
6#include <QtCore/private/qohoslogger_p.h>
7#include "QtGui/private/qguiapplication_p.h"
8#include <QtGui/private/qwindow_p.h>
9#include <qohosdeviceinfo_p.h>
10#include <qohosinputcontext.h>
11#include <qohosinputmethodeventhandler.h>
12#include <qohosjsmain.h>
13#include <qohosplatformbackingstore.h>
14#include <qohosplatformwindow.h>
15#include <qohosruntimedevicetypeandmode.h>
16#include <qohossettings.h>
17#include <render/qohossurface.h>
18#include <render/qohoswindowproxy.h>
19#include <render/qwindowproxyregistry.h>
20
22
23namespace {
24
26 QWindow *window, QOhosWindowProxy::RectChangeOptions rectChangeOptions)
27{
29 && rectChangeOptions.rect.isValid()
30 && window->geometry() != rectChangeOptions.rect
31 && rectChangeOptions.reason == QOhosWindowProxy::RectChangeReason::UNDEFINED;
32}
33
34bool shouldClearQtFocusOnSystemFocusLoss(QWindow *windowLosingSystemFocus)
35{
36 return QGuiApplicationPrivate::focus_window == windowLosingSystemFocus
37 || (QGuiApplicationPrivate::focus_window != nullptr
38 && QOhosPlatformWindow::platformWindowFlagsForQWindow(
39 QGuiApplicationPrivate::focus_window).testFlag(Qt::WindowDoesNotAcceptFocus));
40}
41
43{
44 return !QWindowProxyRegistry::instance().queryWindowsWithSystemWindowAndFocus().empty();
45}
46
47}
48
50: QOhosPlatformWindow(window)
51{
52}
53
55
56void QOhosFloatingWindow::setGeometry(const QRect &rect)
57{
58 auto *view = ownedViewOrNull();
59 bool geometryControlledBySystem =
61 && view != nullptr
62 && view->viewType() == QOhosView::ViewType::MainWindow;
63
64 if (geometryControlledBySystem) {
65 const auto actualGeometry = QPlatformWindow::geometry();
66 QPlatformWindow::setGeometry(rect);
67 setWindowGeometryFromOhos(actualGeometry);
68 return;
69 }
70
71 auto *currentScreen = QOhosPlatformWindow::screen();
72 QOhosPlatformWindow::setGeometry(rect);
73 const auto frameGeometry = lastRequestedWindowFrameGeometry();
74
75 auto *targetScreen = QOhosPlatformWindow::screenForGeometry(frameGeometry);
76 if (targetScreen != nullptr && targetScreen != currentScreen)
77 QWindowSystemInterface::handleWindowScreenChanged(window(), targetScreen->screen());
78
79 if (view != nullptr) {
80 if (!qt_window_private(window())->positionAutomatic)
81 view->setPosition(frameGeometry.topLeft());
82 view->setSize(frameGeometry.size());
83
84 if (view->viewType() == QOhosView::ViewType::EmbeddedWindow)
85 setWindowGeometryFromOhos(rect);
86 else if (rect.size() != lastReportedWindowSize())
87 m_optSizeBeforeResizeRequest = lastReportedWindowSize();
88 else
89 m_optSizeBeforeResizeRequest.reset();
90 }
91}
92
94{
95 if (!visible)
96 m_view->hide();
97 else
98 m_view->showImmediate();
99 startAsyncWaitForNodeResizeIfNeeded();
100}
101
103{
104 auto windowObjectName = window()->objectName();
105
106 qOhosPrintfDebug(
107 "%s: winId called for window named: \"%s\"",
108 Q_FUNC_INFO,
109 windowObjectName.toStdString().c_str());
110
111 return reinterpret_cast<WId>(m_view->viewWindowId());
112}
113
115{
116 auto *view = ownedViewOrNull();
117 if (view != nullptr) {
118 view->raise();
119 window()->requestUpdate();
120 }
121}
122
124{
125 auto *view = ownedViewOrNull();
126 if (view != nullptr) {
127 view->lower();
128 window()->requestUpdate();
129 }
130}
131
133{
134 auto *view = ownedViewOrNull();
135 return view != nullptr ? view->surfaceOrNull() : nullptr;
136}
137
139{
140 return m_view.get();
141}
142
144{
146 m_view = QOhosView::createForWindow(this, propertiesProvider());
147
148 auto *qWindow = window();
149
150 // HACK
151 // There is no functionality to fetch the initial window status from ohos
152 // We can only listen for the changes - we need to assume sane default for tablets
153 // so assign the default most-likely status of the tablet here.
154 if (m_view->viewType() == QOhosView::ViewType::MainWindow
155 && !QOhosSettings::instance().isWindowPcModeEnabled()
156 && !m_lastWindowStatusType.has_value()) {
157 m_lastWindowStatusType = QOhosWindowProxy::WindowStatusType::FULL_SCREEN;
158 }
159
160 QObject::connect(
161 m_view.get(), &QOhosView::externalContentInteractionDetected,
162 qWindow, &QOhosPlatformWindow::closeAllActivePopups);
163
164 QObject::connect(
165 m_view.get(), &QOhosView::nodeAreaChanged, m_view.get(),
166 [this](QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo event) {
167 handleNodeResizeEvent(event);
168 });
169
170 QObject::connect(
171 m_view.get(), &QOhosView::windowEvent,
172 qWindow,
173 [this](QOhosWindowProxy::WindowEvent evt) { handleWindowEvent(evt); });
174
175 QObject::connect(
176 m_view.get(), &QOhosView::windowStatusChange,
177 qWindow,
178 [this](QOhosWindowProxy::WindowStatus evt) { handleWindowStatusChange(evt); });
179
180 QObject::connect(
181 m_view.get(), &QOhosView::windowVisibilityChange,
182 qWindow,
183 [this](bool visible) { handleWindowVisibilityChange(visible); });
184
185 bool monitorAvoidAreaChange =
186 !(isHandheldDeviceType() && m_view->viewType() == QOhosView::ViewType::SubWindow);
187
188 if (monitorAvoidAreaChange) {
189 QObject::connect(
190 m_view.get(), &QOhosView::avoidAreaChanged,
191 qWindow,
192 [this](QOhosWindowProxy::AvoidAreaType avoidAreaType,
193 const QOhosWindowProxy::AvoidArea &systemAvoidArea) {
194 handleAvoidAreaChanged(avoidAreaType, systemAvoidArea);
195 });
196 }
197
198 QObject::connect(
199 m_view.get(), &QOhosView::windowRectChangedInGlobalDisplay,
200 qWindow,
201 [this](const QOhosWindowProxy::RectChangeOptions &rectChangeOptions) {
202 handleWindowRectChanged(rectChangeOptions);
203 });
204
205 QObject::connect(qWindow, &QWindow::modalityChanged, m_view.get(), &QOhosView::setModality);
206
207 QObject::connect(
208 m_view.get(), &QOhosView::surfaceStatusChanged,
209 qWindow,
210 [this](const std::optional<QSize> &optSurfaceSize) { handleSurfaceStatusChanged(optSurfaceSize); });
211
212 QObject::connect(qWindow, &QWindow::windowTitleChanged, m_view.get(), &QOhosView::setTitle);
213
214 QObject::connect(
215 m_view.get(), &QOhosView::windowDisplayIdChanged,
216 qWindow,
217 [this](QOhosDisplayInfo::JsDisplayId displayId) { handleWindowDisplayIdChanged(displayId); });
218}
219
220void QOhosFloatingWindow::restoreWindowCurrentCursorIfNeeded()
221{
222 auto *view = ownedViewOrNull();
223 if (view != nullptr && m_cursor.has_value())
224 view->setCursor(m_cursor.value());
225}
226
228 Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
229{
230 auto *view = ownedViewOrNull();
231 if (view == nullptr)
232 return;
233
234 view->handleWindowFlagsChange(previousWindowFlags, currentWindowFlags);
235}
236
238 Qt::WindowStates oldWindowState, Qt::WindowStates currentWindowState)
239{
240 auto *view = ownedViewOrNull();
241 if (view == nullptr)
242 return;
243
244 view->handleWindowStateChange(oldWindowState, currentWindowState);
245}
246
247void QOhosFloatingWindow::internalHijackSystemFocusAsPopup()
248{
249 QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::PopupFocusReason);
250}
251
252void QOhosFloatingWindow::focusHijackingPopupHidden()
253{
254 auto systemFocusedWindows = QWindowProxyRegistry::instance().queryWindowsWithSystemWindowAndFocus();
255 QWindowSystemInterface::handleFocusWindowChanged(
256 !systemFocusedWindows.empty() ? systemFocusedWindows.front() : nullptr,
257 Qt::ActiveWindowFocusReason);
258}
259
260void QOhosFloatingWindow::setMask(const QRegion &region)
261{
262 m_windowMask = region;
263
264 auto *view = ownedViewOrNull();
265 if (view == nullptr)
266 return;
267
268 view->setWindowMask(QOhosWindowProxy::WindowMask{region});
269}
270
272{
273 auto *view = ownedViewOrNull();
274 if (view != nullptr)
275 return view->startMoving();
276 return false;
277}
278
280{
281 if (windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus) && window()->type() == Qt::Popup) {
282 internalHijackSystemFocusAsPopup();
283 return;
284 }
285
287}
288
289void QOhosFloatingWindow::handleWindowEvent(QOhosWindowProxy::WindowEvent evt)
290{
291 auto *qWindow = window();
292 bool windowAcceptsFocusAndInput = checkWindowAcceptsFocus() && checkWindowAcceptsInput();
293 auto previousWindowEventType = std::exchange(m_lastWindowEventType, evt.type);
294
295 if (evt.type != QOhosWindowProxy::WindowEventType::WINDOW_SHOWN)
296 m_activationEventDeferredUntilWindowUnblocked.reset();
297 if (evt.type == QOhosWindowProxy::WindowEventType::WINDOW_INACTIVE
298 || evt.type == QOhosWindowProxy::WindowEventType::WINDOW_HIDDEN) {
299 m_activationEventDeferredUntilExposed.reset();
300 }
301
302 switch (evt.type) {
303 case QOhosWindowProxy::WindowEventType::WINDOW_ACTIVE:
304 {
305 if (m_view->viewType() != QOhosView::ViewType::EmbeddedWindow && !isExposed()) {
306 m_activationEventDeferredUntilExposed = evt;
307 return;
308 }
309
310 QWindow *modalWindow = nullptr;
311 if (QGuiApplicationPrivate::instance()->isWindowBlocked(qWindow, &modalWindow)
312 && qWindow != modalWindow) {
313 if (qWindow->isTopLevel())
314 m_activationEventDeferredUntilWindowUnblocked = evt;
315 modalWindow->requestActivate();
316 return;
317 }
318
319 // FIXME - restore cursor set by the User every time window is activated.
320 // Perform it because Ohos overrides it with default "standard arrow" cursor (when
321 // window is deactivated) and does not bring selected cursor back (when window is
322 // activated again). This bahaviour is Ohos platform issue.
323 restoreWindowCurrentCursorIfNeeded();
324 if (windowAcceptsFocusAndInput) {
325 QWindowSystemInterface::handleFocusWindowChanged(qWindow, Qt::ActiveWindowFocusReason);
327 }
328 break;
329 }
330 case QOhosWindowProxy::WindowEventType::WINDOW_INACTIVE:
331 if (!windowAcceptsFocusAndInput)
332 break;
333 if (shouldClearQtFocusOnSystemFocusLoss(qWindow) && !anyQtWindowHoldsSystemFocus())
334 QWindowSystemInterface::handleFocusWindowChanged(nullptr, Qt::ActiveWindowFocusReason);
336 break;
337 case QOhosWindowProxy::WindowEventType::WINDOW_HIDDEN:
338 if (!checkWindowAcceptsFocus() && QGuiApplicationPrivate::focus_window == qWindow)
339 focusHijackingPopupHidden();
340 updateMinimizedFromPlatformVisibility(false);
341 setShownFromOhos(false);
342 break;
343 case QOhosWindowProxy::WindowEventType::WINDOW_SHOWN:
344 // HACK
345 // This is a fix for the windows hidden using `QWidget::hide()`.
346 // When a window is hidden and then bring back from the system Dock
347 // Qt side keeps wrong (hidden) state. This causes different issues due to
348 // improper state. To fix it - change visibility state based on the system
349 // window state.
350 if (previousWindowEventType == QOhosWindowProxy::WindowEventType::WINDOW_HIDDEN && !qWindow->isVisible())
351 qWindow->setVisible(true);
352 updateMinimizedFromPlatformVisibility(true);
353 setShownFromOhos(true);
354 startAsyncWaitForNodeResizeIfNeeded();
355 break;
356 case QOhosWindowProxy::WindowEventType::WINDOW_DESTROYED:
358 return;
359 }
360}
361
362void QOhosFloatingWindow::updateMinimizedFromPlatformVisibility(bool platformShown)
363{
364 if (m_view->viewType() != QOhosView::ViewType::SubWindow)
365 return;
366
367 const bool platformHidden = !platformShown;
368 if (platformHidden && !window()->isVisible())
369 return;
370
371 auto states = windowStates();
372 if (states.testFlag(Qt::WindowMinimized) == platformHidden)
373 return;
374
375 states.setFlag(Qt::WindowMinimized, platformHidden);
376 setWindowStateFromOhos(states);
377}
378
379void QOhosFloatingWindow::handleWindowStatusChange(QOhosWindowProxy::WindowStatus evt)
380{
381 auto *qWindow = window();
382 qCDebug(
383 QtForOhos,
384 "Window status changed, window: %p(%s) status: %d",
385 qWindow,
386 qPrintable(qWindow->objectName()),
387 evt.type);
388
389 // Drop duplicate FULL_SCREEN notifications; MainWindow views in non-PC mode
390 // are exempt because initialize() pre-seeds their status to FULL_SCREEN.
391 if (m_lastWindowStatusType == evt.type
392 && m_lastWindowStatusType == QOhosWindowProxy::WindowStatusType::FULL_SCREEN
393 && !(m_view->viewType() == QOhosView::ViewType::MainWindow
394 && !QOhosSettings::instance().isWindowPcModeEnabled())) {
395 qCDebug(QtForOhos, "Window status is the same as the previous one");
396 return;
397 }
398
399 Qt::WindowStates windowStatesToSet = windowStates();
400 m_lastWindowStatusType = evt.type;
401
402 switch (evt.type) {
403 // NOTE - Qt::WindowFullScreen and Qt::WindowMaximized represent the exact same
404 // OHOS Window state.
405 case QOhosWindowProxy::WindowStatusType::FULL_SCREEN:
406 case QOhosWindowProxy::WindowStatusType::MAXIMIZE:
407 windowStatesToSet = m_view->isFullscreenImmersiveModeEnabled()
408 ? Qt::WindowState::WindowFullScreen
409 : Qt::WindowState::WindowMaximized;
410 break;
411 case QOhosWindowProxy::WindowStatusType::MINIMIZE:
412 if (m_view->consumePendingSelfMinimizeEcho()) {
413 // The window is hidden in Qt's view, so ignore this echo entirely.
414 // Deliberately skip setWindowStateFromOhos() and the node-resize
415 // reconciliation below: reporting WindowMinimized would cause a
416 // spurious restore -> QShowEvent, and the reconciliation would apply
417 // the minimized node's geometry to a window Qt still considers to be
418 // at its normal (pre-hide) geometry. showImmediate() reconciles it
419 // when the window is shown again.
420 return;
421 }
422 windowStatesToSet.setFlag(Qt::WindowState::WindowMinimized);
423 break;
424 case QOhosWindowProxy::WindowStatusType::UNDEFINED:
425 case QOhosWindowProxy::WindowStatusType::FLOATING:
426 case QOhosWindowProxy::WindowStatusType::SPLIT_SCREEN:
427 windowStatesToSet = Qt::WindowState::WindowNoState;
428 break;
429 }
430
431 setWindowStateFromOhos(windowStatesToSet);
432
433 // HACK
434 // There is no functionality in OHOS to fetch the window status that would allow checking
435 // the value while processing the WINDOW_SHOWN window event type. Therefore, the window
436 // geometry view needs to be recalculated with any change.
437 startAsyncWaitForNodeResizeIfNeeded();
438}
439
440void QOhosFloatingWindow::handleWindowVisibilityChange(bool visible)
441{
442 auto *qWindow = window();
443 qCDebug(
444 QtForOhos,
445 "Window %p(%s) visibility changed: %s",
446 qWindow,
447 qPrintable(qWindow->objectName()),
448 visible ? "true" : "false");
449 if (visible && m_windowMask.has_value())
450 m_view->setWindowMask(QOhosWindowProxy::WindowMask{m_windowMask.value()});
451
452 setShownFromOhos(visible);
453}
454
455void QOhosFloatingWindow::setShownFromOhos(bool shown)
456{
457 m_shownFromOhos = shown;
458 setExposedFromOhos(shown && m_view->surfaceOrNull() != nullptr);
459 activateIfDeferredUntilExposed();
460}
461
462void QOhosFloatingWindow::activateIfDeferredUntilExposed()
463{
464 if (!isExposed())
465 return;
466
467 if (auto deferredActivationEvent = std::exchange(m_activationEventDeferredUntilExposed, std::nullopt))
468 handleWindowEvent(*deferredActivationEvent);
469}
470
471void QOhosFloatingWindow::handleAvoidAreaChanged(
472 QOhosWindowProxy::AvoidAreaType avoidAreaType,
473 const QOhosWindowProxy::AvoidArea &systemAvoidArea)
474{
475 const auto &cached = m_avoidAreaCache[avoidAreaType];
476
477 bool actuallyChanged =
478 cached.visible != systemAvoidArea.visible
479 || cached.leftRect != systemAvoidArea.leftRect
480 || cached.rightRect != systemAvoidArea.rightRect
481 || cached.bottomRect != systemAvoidArea.bottomRect
482 || cached.topRect != systemAvoidArea.topRect;
483
484 if (actuallyChanged) {
485 m_avoidAreaCache[avoidAreaType] = systemAvoidArea;
486 qCDebug(QtForOhos) << "Avoid area changed:"
487 << static_cast<int>(avoidAreaType)
488 << "visible:" << systemAvoidArea.visible
489 << "top:" << systemAvoidArea.topRect
490 << "left:" << systemAvoidArea.leftRect
491 << "right:" << systemAvoidArea.rightRect
492 << "bottom:" << systemAvoidArea.bottomRect;
493 startAsyncWaitForNodeResizeIfNeeded();
494 }
495}
496
497void QOhosFloatingWindow::handleSurfaceStatusChanged(const std::optional<QSize> &optSurfaceSize)
498{
499 m_optLastSurfaceSize = optSurfaceSize;
500 bool hasSurface = m_view->surfaceOrNull() != nullptr;
501 if (m_view->viewType() == QOhosView::ViewType::EmbeddedWindow) {
502 setExposedFromOhos(hasSurface);
503 } else if (m_shownFromOhos && hasSurface != isExposed()) {
504 setExposedFromOhos(hasSurface);
505 activateIfDeferredUntilExposed();
506 }
507
508 if (hasSurface)
509 startAsyncWaitForNodeResizeIfNeeded();
510}
511
512void QOhosFloatingWindow::handleWindowDisplayIdChanged(QOhosDisplayInfo::JsDisplayId displayId)
513{
514 setDisplayIdFromOhos(displayId);
515 startAsyncWaitForNodeResizeIfNeeded();
516}
517
518void QOhosFloatingWindow::handleWindowRectChanged(
519 const QOhosWindowProxy::RectChangeOptions &rectChangeOptions)
520{
521 bool needsCloseAllActivePopups = rectChangeOptions.reason == QOhosWindowProxy::RectChangeReason::DRAG_START;
522
523 qCDebug(QtForOhos)
524 << "windowRectChanged window:" << window()
525 << "rect:" << rectChangeOptions.rect
526 << "reason:" << static_cast<int>(rectChangeOptions.reason);
527
528 if (rectChangeOptions.rect.size() != lastRequestedWindowFrameGeometry().size())
529 m_optSizeBeforeResizeRequest.reset();
530
531 startAsyncWaitForNodeResizeIfNeeded();
532
533 if (isWindowRotatedByTabletScreenRotation(window(), rectChangeOptions))
534 needsCloseAllActivePopups = true;
535
536 if (needsCloseAllActivePopups)
538}
539
541{
542 if (event->type() == QEvent::WindowUnblocked) {
543 auto deferredActivationEvent =
544 std::exchange(m_activationEventDeferredUntilWindowUnblocked, std::nullopt);
545 const QWindow *windowHoldingFocus = QGuiApplicationPrivate::focus_window;
546 bool noVisibleWindowHoldsFocus =
547 windowHoldingFocus == nullptr || !windowHoldingFocus->isVisible();
548 if (deferredActivationEvent && noVisibleWindowHoldsFocus)
549 handleWindowEvent(*deferredActivationEvent);
550 }
551
552 if (event->type() == QEvent::Timer) {
553 auto *timerEvent = static_cast<QTimerEvent *>(event);
554 if (m_view && timerEvent->timerId() == m_geometryChangeTimer.timerId()) {
555 auto syntheticEvent = m_view->nodeAreaInfo();
556 handleNodeResizeEvent(syntheticEvent);
557 }
558 }
559
560 return QOhosPlatformWindow::windowEvent(event);
561}
562
563void QOhosFloatingWindow::startAsyncWaitForNodeResizeIfNeeded()
564{
565 constexpr auto geometryChangeEventTimeoutMs = std::chrono::milliseconds(16);
566
567 if (!m_geometryChangeTimer.isActive()) {
568 m_geometryChangeTimer.start(
569 geometryChangeEventTimeoutMs.count(),
570 Qt::PreciseTimer,
571 window());
572 }
573}
574
575void QOhosFloatingWindow::handleNodeResizeEvent(const QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo &areaChangeEvent)
576{
577 m_geometryChangeTimer.stop();
578
579 if (Q_UNLIKELY(!m_view))
580 return;
581
582 if (m_view->viewType() != QOhosView::ViewType::EmbeddedWindow) {
583 const QSize size = areaChangeEvent.screenGeometryPixels.size();
584 if (size.isEmpty())
585 return;
586
587 if (size != m_optSizeBeforeResizeRequest) {
588 m_optSizeBeforeResizeRequest.reset();
589 setWindowGeometryFromOhos(QRect(areaChangeEvent.globalRelativeOffsetPixels, size));
590 }
591 }
592
593 updateSafeAreaMargins();
594}
595
596// Map display-space cutout rects to window-relative margins, each attributed to
597// the nearest window edge.
598static QMargins cutoutMarginsForWindow(const QList<QRect> &cutoutRects, const QRect &windowRect)
599{
600 QMargins margins;
601 for (const QRect &cutout : cutoutRects) {
602 if (cutout.isEmpty() || !cutout.intersects(windowRect))
603 continue;
604 const int distTop = cutout.top() - windowRect.top();
605 const int distBottom = windowRect.bottom() - cutout.bottom();
606 const int distLeft = cutout.left() - windowRect.left();
607 const int distRight = windowRect.right() - cutout.right();
608 int nearest = qMin(qMin(distTop, distBottom), qMin(distLeft, distRight));
609 if (nearest == distTop)
610 margins.setTop(qMax(margins.top(), cutout.bottom() + 1 - windowRect.top()));
611 else if (nearest == distBottom)
612 margins.setBottom(qMax(margins.bottom(), windowRect.bottom() + 1 - cutout.top()));
613 else if (nearest == distLeft)
614 margins.setLeft(qMax(margins.left(), cutout.right() + 1 - windowRect.left()));
615 else
616 margins.setRight(qMax(margins.right(), windowRect.right() + 1 - cutout.left()));
617 }
618 return margins;
619}
620
621void QOhosFloatingWindow::updateSafeAreaMargins()
622{
623 // The system bar and navigation indicator avoid areas are window-relative
624 // and visibility-aware: they report zero when hidden (e.g. in fullscreen).
625 static constexpr QOhosWindowProxy::AvoidAreaType kSafeAreaContributors[] = {
626 QOhosWindowProxy::AvoidAreaType::TYPE_SYSTEM,
628 };
629
630 // Avoid-area sizes are relative to the full window; subtract the inset the
631 // compositor already applies (frame vs. true on-screen content) so a normal
632 // window reports no safe area, matching Android's max(0, inset - offset).
633 // nodeScreenGeometryPixels() is the real content rect; drawableRect lies.
634 const QRect frame = m_view->viewGeometry().frameGeometry;
635 const QRect content = m_view->nodeScreenGeometryPixels();
636 if (!frame.contains(content))
637 return;
638 const int alreadyTop = content.top() - frame.top();
639 const int alreadyLeft = content.left() - frame.left();
640 const int alreadyRight = frame.right() - content.right();
641 const int alreadyBottom = frame.bottom() - content.bottom();
642
643 QMargins combined;
644 for (auto type : kSafeAreaContributors) {
645 const QMargins m = m_view->avoidAreaMargins(type);
646 combined.setTop(qMax(combined.top(), qMax(0, m.top() - alreadyTop)));
647 combined.setLeft(qMax(combined.left(), qMax(0, m.left() - alreadyLeft)));
648 combined.setRight(qMax(combined.right(), qMax(0, m.right() - alreadyRight)));
649 combined.setBottom(qMax(combined.bottom(), qMax(0, m.bottom() - alreadyBottom)));
650 }
651
652 // The display cutout is not in the avoid areas; fold it in from
653 // getCutoutInfo() (fetched fresh as it rotates with the display) and report
654 // it even in fullscreen, mapped against the content area.
655 const QMargins cutout = cutoutMarginsForWindow(m_view->displayCutoutRects(), content);
656 combined.setTop(qMax(combined.top(), cutout.top()));
657 combined.setLeft(qMax(combined.left(), cutout.left()));
658 combined.setRight(qMax(combined.right(), cutout.right()));
659 combined.setBottom(qMax(combined.bottom(), cutout.bottom()));
660
661 setSafeAreaMarginsFromOhos(combined);
662}
663
664QT_END_NAMESPACE
QOhosFloatingWindow(QWindow *window)
~QOhosFloatingWindow() override
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
bool startSystemMove() override
Reimplement this method to start a system move operation if the system supports it and return true to...
QOhosView * ownedViewOrNull() const override
void onWindowStateChanged(Qt::WindowStates oldWindowState, Qt::WindowStates currentWindowState) override
WId winId() const override
Reimplement in subclasses to return a handle to the native window.
void initialize() override
Called as part of QWindow::create(), after constructing the window.
void onWindowFlagsChanged(Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags) override
bool windowEvent(QEvent *event) override
Reimplement this method to be able to do any platform specific event handling.
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QOhosSurface * ownedSurfaceOrNull() const override
void setMask(const QRegion &region) override
Reimplement to be able to let Qt set the mask of a window.
void lower() override
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
void raise() override
Reimplement to be able to let Qt raise windows to the top of the desktop.
void setDisplayIdFromOhos(std::optional< QOhosDisplayInfo::JsDisplayId > displayId)
void setExposedFromOhos(bool exposed)
void initialize() override
Called as part of QWindow::create(), after constructing the window.
void notifyInputSystemsWindowActiveStatusChanged(bool active)
bool isExposed() const final
Returns if this window is exposed in the windowing system.
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
bool isWindowPcModeEnabled() const
static QOhosSettings & instance()
QOhosSurface * surfaceOrNull() const
void setWindowMask(const QOhosWindowProxy::WindowMask &windowMask)
void lower()
bool startMoving()
void raise()
QtOhosQpa::enums::ohos::window::WindowEventType WindowEventType
QtOhosQpa::enums::ohos::window::RectChangeReason RectChangeReason
QtOhosQpa::enums::ohos::window::AvoidAreaType AvoidAreaType
QtOhosQpa::enums::ohos::window::WindowStatusType WindowStatusType
static QWindowProxyRegistry & instance()
Combined button and popup list for selecting options.
bool shouldClearQtFocusOnSystemFocusLoss(QWindow *windowLosingSystemFocus)
bool isWindowRotatedByTabletScreenRotation(QWindow *window, QOhosWindowProxy::RectChangeOptions rectChangeOptions)
static QMargins cutoutMarginsForWindow(const QList< QRect > &cutoutRects, const QRect &windowRect)