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>
29 && rectChangeOptions.rect.isValid()
30 && window->geometry() != rectChangeOptions.rect
46 bool geometryControlledBySystem =
47 !QOhosSettings::instance().isWindowPcModeEnabled()
49 && view->viewType() == QOhosView::ViewType::MainWindow;
51 if (geometryControlledBySystem) {
52 setWindowGeometryFromOhos(windowGeometry());
56 auto *currentScreen = QOhosPlatformWindow::screen();
57 QOhosPlatformWindow::setGeometry(rect);
59 auto *targetScreen = QOhosPlatformWindow::screenForGeometry(rect.marginsAdded(frameMargins()));
60 if (targetScreen !=
nullptr && targetScreen != currentScreen)
61 QWindowSystemInterface::handleWindowScreenChanged(window(), targetScreen->screen());
63 if (view !=
nullptr) {
64 auto frameGeometry = rect.marginsAdded(frameMargins());
65 if (!qt_window_private(window())->positionAutomatic)
66 view->setPosition(frameGeometry.topLeft());
67 view->setSize(frameGeometry.size());
69 if (view->viewType() == QOhosView::ViewType::EmbeddedWindow)
70 setWindowGeometryFromOhos(rect);
79 m_view->showImmediate();
80 startAsyncWaitForNodeResizeIfNeeded();
85 auto windowObjectName = window()->objectName();
88 "%s: winId called for window named: \"%s\"",
90 windowObjectName.toStdString().c_str());
92 return reinterpret_cast<WId>(m_view->viewWindowId());
98 if (view !=
nullptr) {
100 window()->requestUpdate();
107 if (view !=
nullptr) {
109 window()->requestUpdate();
127 m_view = QOhosView::createForWindow(
this, propertiesProvider());
129 auto *qWindow = window();
135 if (m_view->viewType() == QOhosView::ViewType::MainWindow
136 && !QOhosSettings::instance().isWindowPcModeEnabled()
137 && !m_lastWindowStatusType.has_value()) {
138 m_lastWindowStatusType = QOhosWindowProxy::WindowStatusType::FULL_SCREEN;
142 m_view.get(), &QOhosView::externalContentInteractionDetected,
143 qWindow, &QOhosPlatformWindow::closeAllActivePopups);
146 m_view.get(), &QOhosView::nodeAreaChanged, m_view.get(),
147 [
this](QArkUi::QQtEmbeddedWindowNode::NodeAreaInfo event) {
148 handleNodeResizeEvent(event);
152 m_view.get(), &QOhosView::windowEvent,
154 [
this](QOhosWindowProxy::WindowEvent evt) { handleWindowEvent(evt); });
157 m_view.get(), &QOhosView::windowStatusChange,
159 [
this](QOhosWindowProxy::WindowStatus evt) { handleWindowStatusChange(evt); });
162 m_view.get(), &QOhosView::windowVisibilityChange,
164 [
this](
bool visible) { handleWindowVisibilityChange(visible); });
166 bool monitorAvoidAreaChange =
167 !(isHandheldDeviceType() && m_view->viewType() == QOhosView::ViewType::SubWindow);
169 if (monitorAvoidAreaChange) {
171 m_view.get(), &QOhosView::avoidAreaChanged,
173 [
this](QOhosWindowProxy::AvoidAreaType avoidAreaType,
174 const QOhosWindowProxy::AvoidArea &systemAvoidArea) {
175 handleAvoidAreaChanged(avoidAreaType, systemAvoidArea);
180 m_view.get(), &QOhosView::windowRectChangedInGlobalDisplay,
182 [
this](
const QOhosWindowProxy::RectChangeOptions &rectChangeOptions) {
183 handleWindowRectChanged(rectChangeOptions);
186 QObject::connect(qWindow, &QWindow::modalityChanged, m_view.get(), &QOhosView::setModality);
189 m_view.get(), &QOhosView::surfaceStatusChanged,
191 [
this](
const std::optional<QSize> &optSurfaceSize) { handleSurfaceStatusChanged(optSurfaceSize); });
193 QObject::connect(qWindow, &QWindow::windowTitleChanged, m_view.get(), &QOhosView::setTitle);
196 m_view.get(), &QOhosView::windowDisplayIdChanged,
198 [
this](QOhosDisplayInfo::JsDisplayId displayId) { handleWindowDisplayIdChanged(displayId); });
204 if (view !=
nullptr && m_cursor.has_value())
205 view->setCursor(m_cursor.value());
209 Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
215 view->handleWindowFlagsChange(previousWindowFlags, currentWindowFlags);
219 Qt::WindowStates oldWindowState, Qt::WindowStates currentWindowState)
225 view->handleWindowStateChange(oldWindowState, currentWindowState);
230 QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::PopupFocusReason);
236 QWindowSystemInterface::handleFocusWindowChanged(
237 !systemFocusedWindows.empty() ? systemFocusedWindows.front() :
nullptr,
238 Qt::ActiveWindowFocusReason);
243 m_windowMask = region;
262 if (windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus) && window()->type() == Qt::Popup) {
263 internalHijackSystemFocusAsPopup();
272 auto *qWindow = window();
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 if (!windowAcceptsFocusAndInput)
300 if (QGuiApplicationPrivate::focus_window == qWindow
301 || (QGuiApplicationPrivate::focus_window !=
nullptr
302 && QOhosPlatformWindow::platformWindowFlagsForQWindow(
303 QGuiApplicationPrivate::focus_window).testFlag(Qt::WindowDoesNotAcceptFocus))) {
304 QWindowSystemInterface::handleFocusWindowChanged(
nullptr, Qt::ActiveWindowFocusReason);
309 if (!checkWindowAcceptsFocus() && QGuiApplicationPrivate::focus_window == qWindow)
310 focusHijackingPopupHidden();
321 qWindow->setVisible(
true);
323 startAsyncWaitForNodeResizeIfNeeded();
333 auto *qWindow = window();
336 "Window status changed, window: %p(%s) status: %d",
338 qPrintable(qWindow->objectName()),
343 if (m_lastWindowStatusType == evt.type
344 && m_lastWindowStatusType == QOhosWindowProxy::WindowStatusType::FULL_SCREEN
345 && !(m_view->viewType() == QOhosView::ViewType::MainWindow
346 && !QOhosSettings::instance().isWindowPcModeEnabled())) {
347 qCDebug(QtForOhos,
"Window status is the same as the previous one");
351 Qt::WindowStates windowStatesToSet = windowStates();
352 m_lastWindowStatusType = evt.type;
357 case QOhosWindowProxy::WindowStatusType::FULL_SCREEN:
358 case QOhosWindowProxy::WindowStatusType::MAXIMIZE:
359 windowStatesToSet = m_view->isFullscreenImmersiveModeEnabled()
360 ? Qt::WindowState::WindowFullScreen
361 : Qt::WindowState::WindowMaximized;
364 windowStatesToSet.setFlag(Qt::WindowState::WindowMinimized);
366 case QOhosWindowProxy::WindowStatusType::UNDEFINED:
367 case QOhosWindowProxy::WindowStatusType::FLOATING:
368 case QOhosWindowProxy::WindowStatusType::SPLIT_SCREEN:
369 windowStatesToSet = Qt::WindowState::WindowNoState;
373 setWindowStateFromOhos(windowStatesToSet);
379 startAsyncWaitForNodeResizeIfNeeded();
384 auto *qWindow = window();
387 "Window %p(%s) visibility changed: %s",
389 qPrintable(qWindow->objectName()),
390 visible ?
"true" :
"false");
391 if (visible && m_windowMask.has_value())
392 m_view->setWindowMask(QOhosWindowProxy::WindowMask{m_windowMask.value()});
399 const QOhosWindowProxy::AvoidArea &systemAvoidArea)
401 const auto &cached = m_avoidAreaCache[avoidAreaType];
403 bool actuallyChanged =
404 cached.visible != systemAvoidArea.visible
405 || cached.leftRect != systemAvoidArea.leftRect
406 || cached.rightRect != systemAvoidArea.rightRect
407 || cached.bottomRect != systemAvoidArea.bottomRect
408 || cached.topRect != systemAvoidArea.topRect;
410 if (actuallyChanged) {
411 m_avoidAreaCache[avoidAreaType] = systemAvoidArea;
412 qCDebug(QtForOhos) <<
"Avoid area changed:"
413 <<
static_cast<
int>(avoidAreaType)
414 <<
"visible:" << systemAvoidArea.visible
415 <<
"top:" << systemAvoidArea.topRect
416 <<
"left:" << systemAvoidArea.leftRect
417 <<
"right:" << systemAvoidArea.rightRect
418 <<
"bottom:" << systemAvoidArea.bottomRect;
419 startAsyncWaitForNodeResizeIfNeeded();
423void QOhosFloatingWindow::handleSurfaceStatusChanged(
const std::optional<QSize> &optSurfaceSize)
425 m_optLastSurfaceSize = optSurfaceSize;
426 bool hasSurface = m_view->surfaceOrNull() !=
nullptr;
427 if (m_view->viewType() == QOhosView::ViewType::EmbeddedWindow) {
432 startAsyncWaitForNodeResizeIfNeeded();
438 startAsyncWaitForNodeResizeIfNeeded();
442 const QOhosWindowProxy::RectChangeOptions &rectChangeOptions)
447 <<
"windowRectChanged window:" << window()
448 <<
"rect:" << rectChangeOptions.rect
449 <<
"reason:" <<
static_cast<
int>(rectChangeOptions.reason);
451 startAsyncWaitForNodeResizeIfNeeded();
453 if (isWindowRotatedByTabletScreenRotation(window(), rectChangeOptions))
454 needsCloseAllActivePopups =
true;
456 if (needsCloseAllActivePopups)
462 if (event->type() == QEvent::Timer) {
463 auto *timerEvent =
static_cast<QTimerEvent *>(event);
464 if (m_view && timerEvent->timerId() == m_geometryChangeTimer.timerId()) {
465 auto syntheticEvent = m_view->nodeAreaInfo();
466 handleNodeResizeEvent(syntheticEvent);
470 return QOhosPlatformWindow::windowEvent(event);
475 constexpr auto geometryChangeEventTimeoutMs = std::chrono::milliseconds(16);
477 if (!m_geometryChangeTimer.isActive()) {
478 m_geometryChangeTimer.start(
479 geometryChangeEventTimeoutMs.count(),
487 m_geometryChangeTimer.stop();
489 if (Q_UNLIKELY(!m_view))
492 if (m_view->viewType() != QOhosView::ViewType::EmbeddedWindow)
493 setWindowGeometryFromOhos(
494 QRect(areaChangeEvent.globalRelativeOffsetPixels, 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)