4#include <qohosfloatingwindow.h>
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>
30 && rectChangeOptions.rect.isValid()
31 && window->geometry() != rectChangeOptions.rect
47 bool geometryControlledBySystem =
48 !QOhosSettings::instance().isWindowPcModeEnabled()
50 && view->viewType() == QOhosView::ViewType::MainWindow;
52 if (geometryControlledBySystem) {
53 setWindowGeometryFromOhos(windowGeometry());
57 auto *currentScreen = QOhosPlatformWindow::screen();
58 QOhosPlatformWindow::setGeometry(rect);
60 auto *targetScreen = QOhosPlatformWindow::screenForGeometry(rect.marginsAdded(frameMargins()));
61 if (targetScreen !=
nullptr && targetScreen != currentScreen)
62 QWindowSystemInterface::handleWindowScreenChanged(window(), targetScreen->screen());
64 if (view !=
nullptr) {
65 auto frameGeometry = rect.marginsAdded(frameMargins());
66 if (!qt_window_private(window())->positionAutomatic)
67 view->setPosition(frameGeometry.topLeft());
68 view->setSize(frameGeometry.size());
77 m_view->showImmediate();
78 startAsyncWaitForNodeResizeIfNeeded();
83 auto windowObjectName = window()->objectName();
86 "%s: winId called for window named: \"%s\"",
88 windowObjectName.toStdString().c_str());
90 return reinterpret_cast<WId>(m_view->viewWindowId());
96 if (view !=
nullptr) {
98 window()->requestUpdate();
105 if (view !=
nullptr) {
107 window()->requestUpdate();
125 m_view = QOhosView::createForWindow(
this, propertiesProvider());
127 auto *qWindow = window();
133 if (m_view->viewType() == QOhosView::ViewType::MainWindow
134 && !QOhosSettings::instance().isWindowPcModeEnabled()
135 && !m_lastWindowStatusType.has_value()) {
136 m_lastWindowStatusType = QOhosWindowProxy::WindowStatusType::FULL_SCREEN;
140 m_view.get(), &QOhosView::externalContentInteractionDetected,
141 qWindow, &QOhosPlatformWindow::closeAllActivePopups);
144 m_view.get(), &QOhosView::nodeAreaChanged, m_view.get(),
145 [
this](QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo event) {
146 handleNodeResizeEvent(event);
150 m_view.get(), &QOhosView::windowEvent,
152 [
this](QOhosWindowProxy::WindowEvent evt) { handleWindowEvent(evt); });
155 m_view.get(), &QOhosView::windowStatusChange,
157 [
this](QOhosWindowProxy::WindowStatus evt) { handleWindowStatusChange(evt); });
160 m_view.get(), &QOhosView::windowVisibilityChange,
162 [
this](
bool visible) { handleWindowVisibilityChange(visible); });
164 bool monitorAvoidAreaChange =
165 !(isHandheldDeviceType() && m_view->viewType() == QOhosView::ViewType::SubWindow);
167 if (monitorAvoidAreaChange) {
169 m_view.get(), &QOhosView::avoidAreaChanged,
171 [
this](QOhosWindowProxy::AvoidAreaType avoidAreaType,
172 const QOhosWindowProxy::AvoidArea &systemAvoidArea) {
173 handleAvoidAreaChanged(avoidAreaType, systemAvoidArea);
178 m_view.get(), &QOhosView::windowRectChangedInGlobalDisplay,
180 [
this](
const QOhosWindowProxy::RectChangeOptions &rectChangeOptions) {
181 handleWindowRectChanged(rectChangeOptions);
184 QObject::connect(qWindow, &QWindow::modalityChanged, m_view.get(), &QOhosView::setModality);
187 m_view.get(), &QOhosView::surfaceStatusChanged,
189 [
this](
const std::optional<QSize> &optSurfaceSize) { handleSurfaceStatusChanged(optSurfaceSize); });
191 QObject::connect(qWindow, &QWindow::windowTitleChanged, m_view.get(), &QOhosView::setTitle);
194 m_view.get(), &QOhosView::windowDisplayIdChanged,
196 [
this](QOhosDisplayInfo::JsDisplayId displayId) { handleWindowDisplayIdChanged(displayId); });
202 if (view !=
nullptr && m_cursor.has_value())
203 view->setCursor(m_cursor.value());
207 Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
213 view->handleWindowFlagsChange(previousWindowFlags, currentWindowFlags);
217 Qt::WindowStates oldWindowState, Qt::WindowStates currentWindowState)
223 view->handleWindowStateChange(oldWindowState, currentWindowState);
228 QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::PopupFocusReason);
234 QWindowSystemInterface::handleFocusWindowChanged(
235 !systemFocusedWindows.empty() ? systemFocusedWindows.front() :
nullptr,
236 Qt::ActiveWindowFocusReason);
241 m_windowMask = region;
260 if (windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus) && window()->type() == Qt::Popup) {
261 internalHijackSystemFocusAsPopup();
270 auto *qWindow = window();
272 Qt::WindowStates windowStatesToSet = windowStates();
273 bool windowActive =
true;
274 auto previousWindowEventType =
std::exchange(m_lastWindowEventType, evt
.type);
279 QWindow *modalWindow =
nullptr;
280 if (QGuiApplicationPrivate::instance()->isWindowBlocked(qWindow, &modalWindow)
281 && qWindow != modalWindow) {
282 modalWindow->requestActivate();
290 restoreWindowCurrentCursorIfNeeded();
291 if (windowAcceptsFocusAndInput) {
292 QWindowSystemInterface::handleFocusWindowChanged(qWindow, Qt::ActiveWindowFocusReason);
298 windowActive =
false;
299 if (!windowAcceptsFocusAndInput)
301 if (QGuiApplicationPrivate::focus_window == qWindow
302 || (QGuiApplicationPrivate::focus_window !=
nullptr
303 && QOhosPlatformWindow::platformWindowFlagsForQWindow(
304 QGuiApplicationPrivate::focus_window).testFlag(Qt::WindowDoesNotAcceptFocus))) {
305 QWindowSystemInterface::handleFocusWindowChanged(
nullptr, Qt::ActiveWindowFocusReason);
310 if (!checkWindowAcceptsFocus() && QGuiApplicationPrivate::focus_window == qWindow)
311 focusHijackingPopupHidden();
313 windowActive =
false;
323 qWindow->setVisible(
true);
325 startAsyncWaitForNodeResizeIfNeeded();
328 windowActive =
false;
333 windowStatesToSet.setFlag(Qt::WindowState::WindowActive, windowActive && windowAcceptsFocusAndInput);
334 setWindowStateFromOhos(windowStatesToSet);
339 auto *qWindow = window();
342 "Window status changed, window: %p(%s) status: %d",
344 qPrintable(qWindow->objectName()),
349 if (m_lastWindowStatusType == evt.type
350 && m_lastWindowStatusType == QOhosWindowProxy::WindowStatusType::FULL_SCREEN
351 && !(m_view->viewType() == QOhosView::ViewType::MainWindow
352 && !QOhosSettings::instance().isWindowPcModeEnabled())) {
353 qCDebug(QtForOhos,
"Window status is the same as the previous one");
357 Qt::WindowStates windowStatesToSet = windowStates();
358 Qt::WindowState flagToSet;
359 m_lastWindowStatusType = evt.type;
362 case QOhosWindowProxy::WindowStatusType::FULL_SCREEN:
363 flagToSet = Qt::WindowState::WindowFullScreen;
365 case QOhosWindowProxy::WindowStatusType::MAXIMIZE:
366 flagToSet = Qt::WindowState::WindowMaximized;
368 case QOhosWindowProxy::WindowStatusType::MINIMIZE:
369 flagToSet = Qt::WindowState::WindowMinimized;
374 case QOhosWindowProxy::WindowStatusType::SPLIT_SCREEN:
375 flagToSet = Qt::WindowState::WindowNoState;
381 if (flagToSet == Qt::WindowState::WindowFullScreen
382 || flagToSet == Qt::WindowState::WindowMaximized) {
383 windowStatesToSet = m_view->isFullscreenImmersiveModeEnabled()
384 ? Qt::WindowState::WindowFullScreen
385 : Qt::WindowState::WindowMaximized;
387 static constexpr Qt::WindowState mutuallyExclusiveFlags[] = {
388 Qt::WindowState::WindowFullScreen,
389 Qt::WindowState::WindowMaximized,
390 Qt::WindowState::WindowMinimized,
391 Qt::WindowState::WindowNoState,
394 for (
const auto exclusiveState : mutuallyExclusiveFlags)
395 windowStatesToSet.setFlag(exclusiveState, flagToSet == exclusiveState);
398 setWindowStateFromOhos(windowStatesToSet);
404 startAsyncWaitForNodeResizeIfNeeded();
409 auto *qWindow = window();
412 "Window %p(%s) visibility changed: %s",
414 qPrintable(qWindow->objectName()),
415 visible ?
"true" :
"false");
416 if (visible && m_windowMask.has_value())
417 m_view->setWindowMask(QOhosWindowProxy::WindowMask{m_windowMask.value()});
424 const QOhosWindowProxy::AvoidArea &systemAvoidArea)
426 const auto &cached = m_avoidAreaCache[avoidAreaType];
428 bool actuallyChanged =
429 cached.visible != systemAvoidArea.visible
430 || cached.leftRect != systemAvoidArea.leftRect
431 || cached.rightRect != systemAvoidArea.rightRect
432 || cached.bottomRect != systemAvoidArea.bottomRect
433 || cached.topRect != systemAvoidArea.topRect;
435 if (actuallyChanged) {
436 m_avoidAreaCache[avoidAreaType] = systemAvoidArea;
437 qCDebug(QtForOhos) <<
"Avoid area changed:"
438 <<
static_cast<
int>(avoidAreaType)
439 <<
"visible:" << systemAvoidArea.visible
440 <<
"top:" << systemAvoidArea.topRect
441 <<
"left:" << systemAvoidArea.leftRect
442 <<
"right:" << systemAvoidArea.rightRect
443 <<
"bottom:" << systemAvoidArea.bottomRect;
444 startAsyncWaitForNodeResizeIfNeeded();
448void QOhosFloatingWindow::handleSurfaceStatusChanged(
const std::optional<QSize> &optSurfaceSize)
450 m_optLastSurfaceSize = optSurfaceSize;
451 bool hasSurface = m_view->surfaceOrNull() !=
nullptr;
452 if (m_view->viewType() == QOhosView::ViewType::EmbeddedWindow) {
457 startAsyncWaitForNodeResizeIfNeeded();
463 startAsyncWaitForNodeResizeIfNeeded();
467 const QOhosWindowProxy::RectChangeOptions &rectChangeOptions)
472 <<
"windowRectChanged window:" << window()
473 <<
"rect:" << rectChangeOptions.rect
474 <<
"reason:" <<
static_cast<
int>(rectChangeOptions.reason);
476 startAsyncWaitForNodeResizeIfNeeded();
478 if (isWindowRotatedByTabletScreenRotation(window(), rectChangeOptions))
479 needsCloseAllActivePopups =
true;
481 if (needsCloseAllActivePopups)
487 if (event->type() == QEvent::Timer) {
488 auto *timerEvent =
static_cast<QTimerEvent *>(event);
489 if (m_view && timerEvent->timerId() == m_geometryChangeTimer.timerId()) {
490 auto syntheticEvent = m_view->nodeAreaInfo();
491 handleNodeResizeEvent(syntheticEvent);
495 return QOhosPlatformWindow::windowEvent(event);
500 constexpr auto geometryChangeEventTimeoutMs = std::chrono::milliseconds(16);
502 if (!m_geometryChangeTimer.isActive()) {
503 m_geometryChangeTimer.start(
504 geometryChangeEventTimeoutMs.count(),
512 m_geometryChangeTimer.stop();
514 if (Q_UNLIKELY(!m_view))
517 setWindowGeometryFromOhos(
518 m_view->viewType() != QOhosView::ViewType::EmbeddedWindow
519 ? QRect(areaChangeEvent.globalRelativeOffsetPixels, areaChangeEvent.screenGeometryPixels.size())
520 : QRect(areaChangeEvent.parentRelativeOffsetPixels, areaChangeEvent.screenGeometryPixels.size()));
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 ®ion) 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.
bool isWindowPcModeEnabled() const
static QOhosSettings & instance()
QOhosSurface * surfaceOrNull() const
void setWindowMask(const QOhosWindowProxy::WindowMask &windowMask)
QtOhos::enums::ohos::window::AvoidAreaType AvoidAreaType
QtOhos::enums::ohos::window::RectChangeReason RectChangeReason
QtOhos::enums::ohos::window::WindowEventType WindowEventType
QtOhos::enums::ohos::window::WindowStatusType WindowStatusType
static QWindowProxyRegistry & instance()
Combined button and popup list for selecting options.
bool isWindowRotatedByTabletScreenRotation(QWindow *window, QOhosWindowProxy::RectChangeOptions rectChangeOptions)