4#include <qohosfloatingwindow.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include "QtGui/private/qguiapplication_p.h"
8#include <qohosdeviceinfo_p.h>
9#include <qohosinputcontext.h>
10#include <qohosinputmethodeventhandler.h>
11#include <qohosjsmain.h>
12#include <qohosplatformbackingstore.h>
13#include <qohosplatformintegration.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 && window->geometry() != rectChangeOptions.rect
46 bool geometryControlledBySystem =
47 !QOhosSettings::isWindowPcModeEnabled()
49 && view->viewType() == QOhosView::ViewType::MainWindow;
51 if (geometryControlledBySystem) {
52 setWindowGeometryFromOhos(windowGeometry());
56 auto oldWindowFrameGeometry = windowFrameGeometry();
58 QOhosPlatformWindow::setGeometry(rect);
60 if (view !=
nullptr) {
61 auto frameGeometry = windowFrameGeometry();
62 if (oldWindowFrameGeometry.topLeft() != frameGeometry.topLeft())
63 view->setPosition(frameGeometry.topLeft());
64 if (oldWindowFrameGeometry.size() != frameGeometry.size())
65 view->setSize(frameGeometry.size());
73 if (!QOhosPlatformWindow::isWindowBeingClosedOrDestroyed(window()))
76 m_view->showImmediate();
82 auto windowObjectName = window()->objectName();
85 "%s: winId called for window named: \"%s\"",
87 windowObjectName.toStdString().c_str());
89 return reinterpret_cast<WId>(m_view->viewWindowId());
95 if (view !=
nullptr) {
97 window()->requestUpdate();
104 if (view !=
nullptr) {
106 window()->requestUpdate();
124 m_view = QOhosView::createForWindow(
this, propertiesProvider());
126 auto *qWindow = window();
132 if (m_view->viewType() == QOhosView::ViewType::MainWindow
133 && !QOhosSettings::isWindowPcModeEnabled()
134 && !m_lastWindowStatusType.hasValue()) {
135 m_lastWindowStatusType = QOhosWindowProxy::WindowStatusType::FULL_SCREEN;
139 m_view.get(), &QOhosView::externalContentInteractionDetected,
140 qWindow, &QOhosPlatformWindow::closeAllActivePopups);
143 m_view.get(), &QOhosView::windowEvent,
145 [
this](QOhosWindowProxy::WindowEvent evt) { handleWindowEvent(evt); });
148 m_view.get(), &QOhosView::windowStatusChange,
150 [
this](QOhosWindowProxy::WindowStatus evt) { handleWindowStatusChange(evt); });
153 m_view.get(), &QOhosView::windowVisibilityChange,
155 [
this](
bool visible) { handleWindowVisibilityChange(visible); });
157 bool monitorAvoidAreaChange =
158 !(isHandheldDeviceType() && m_view->viewType() == QOhosView::ViewType::SubWindow);
160 if (monitorAvoidAreaChange) {
162 m_view.get(), &QOhosView::avoidAreaChanged,
164 [
this](QOhosWindowProxy::AvoidAreaType avoidAreaType,
165 const QOhosWindowProxy::AvoidArea &systemAvoidArea) {
166 handleAvoidAreaChanged(avoidAreaType, systemAvoidArea);
171 m_view.get(), &QOhosView::windowRectChanged,
173 [
this](
const QOhosWindowProxy::RectChangeOptions &rectChangeOptions) {
174 handleWindowRectChanged(rectChangeOptions);
177 QObject::connect(qWindow, &QWindow::modalityChanged, m_view.get(), &QOhosView::setModality);
180 m_view.get(), &QOhosView::surfaceStatusChanged,
182 [
this](
const QOhosOptional<QSize> &optSurfaceSize) { handleSurfaceStatusChanged(optSurfaceSize); });
184 QObject::connect(qWindow, &QWindow::windowTitleChanged, m_view.get(), &QOhosView::setTitle);
187 m_view.get(), &QOhosView::windowDisplayIdChanged,
189 [
this](QOhosDisplayInfo::JsDisplayId displayId) { handleWindowDisplayIdChanged(displayId); });
195 qCDebug(QtForOhos) <<
"View Geometry: " << viewGeometry.frameGeometry << viewGeometry.geometry;
197 if (view.viewType() != QOhosView::ViewType::EmbeddedWindow)
200 if (viewGeometry.geometry.size().isEmpty()) {
201 qCCritical(QtForOhos,
"%s: Failed as the received geometry is invalid", Q_FUNC_INFO);
205 bool shouldSkipMarginCalculation =
206 view.viewType() == QOhosView::ViewType::MainWindow
207 && queryQOhosRuntimeDeviceAndMode() == QOhosRuntimeDeviceTypeAndMode::HandheldDeviceFullScreen;
210 shouldSkipMarginCalculation
214 margins.setTop(qAbs(viewGeometry.frameGeometry.top() - viewGeometry.geometry.top()));
215 margins.setLeft(qAbs(viewGeometry.frameGeometry.left() - viewGeometry.geometry.left()));
216 margins.setRight(viewGeometry.frameGeometry.right() - viewGeometry.geometry.right());
217 margins.setBottom(viewGeometry.frameGeometry.bottom() - viewGeometry.geometry.bottom());
221 const auto oldOhosWindowFrameMargins = frameMargins();
222 bool shouldResizeWindowDueToInconsistentMargins =
223 shouldSkipMarginCalculation
224 && oldOhosWindowFrameMargins != margins;
226 setWindowMarginsFromOhos(margins);
228 if (shouldResizeWindowDueToInconsistentMargins) {
229 const auto newGeometry = viewGeometry.frameGeometry - oldOhosWindowFrameMargins;
230 setGeometry(newGeometry);
234 if (shouldSkipMarginCalculation) {
236 ? viewGeometry.frameGeometry
237 : viewGeometry.frameGeometry
240 setWindowGeometryFromOhos(targetGeometry);
249 bool maximized = windowStates().testFlag(Qt::WindowState::WindowMaximized);
251 auto targetGeometry = viewGeometry.geometry.marginsRemoved(
253 setWindowGeometryFromOhos(targetGeometry);
257 if (windowFrameGeometry() != viewGeometry.frameGeometry)
258 setWindowGeometryFromOhos(viewGeometry.geometry);
263 if (!m_lastRectChangeOptions.hasValue())
266 auto drawableRect = m_lastRectChangeOptions.value().rect.marginsRemoved(frameMargins());
267 setWindowGeometryFromOhos(
269 drawableRect.topLeft(),
270 m_optLastSurfaceSize.valueOr(drawableRect.size())));
276 if (view !=
nullptr && m_cursor.hasValue())
277 view->setCursor(m_cursor.value());
281 Qt::WindowFlags previousWindowFlags, Qt::WindowFlags currentWindowFlags)
287 view->handleWindowFlagsChange(previousWindowFlags, currentWindowFlags);
291 Qt::WindowStates oldWindowState, Qt::WindowStates currentWindowState)
297 view->handleWindowStateChange(oldWindowState, currentWindowState);
302 QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::PopupFocusReason);
308 QWindowSystemInterface::handleFocusWindowChanged(
309 !systemFocusedWindows.empty() ? systemFocusedWindows.front() :
nullptr,
310 Qt::ActiveWindowFocusReason);
315 m_windowMask = region;
334 if (windowFlags().testFlag(Qt::WindowDoesNotAcceptFocus) && window()->type() == Qt::Popup) {
335 internalHijackSystemFocusAsPopup();
344 auto *qWindow = window();
346 Qt::WindowStates windowStatesToSet = windowStates();
347 bool windowActive =
true;
348 auto previousWindowEventType =
std::exchange(m_lastWindowEventType, makeQOhosOptional(evt
.type));
353 QWindow *modalWindow =
nullptr;
354 if (QGuiApplicationPrivate::instance()->isWindowBlocked(qWindow, &modalWindow)
355 && qWindow != modalWindow) {
356 modalWindow->requestActivate();
364 restoreWindowCurrentCursorIfNeeded();
365 if (windowAcceptsFocusAndInput) {
366 QWindowSystemInterface::handleFocusWindowChanged(qWindow);
372 windowActive =
false;
373 if (!windowAcceptsFocusAndInput)
375 if (QGuiApplicationPrivate::focus_window == qWindow
376 || (QGuiApplicationPrivate::focus_window !=
nullptr
377 && QOhosPlatformWindow::platformWindowFlagsForQWindow(
378 QGuiApplicationPrivate::focus_window).testFlag(Qt::WindowDoesNotAcceptFocus))) {
379 QWindowSystemInterface::handleFocusWindowChanged(
nullptr, Qt::ActiveWindowFocusReason);
384 if (!checkWindowAcceptsFocus() && QGuiApplicationPrivate::focus_window == qWindow)
385 focusHijackingPopupHidden();
387 windowActive =
false;
397 qWindow->setVisible(
true);
399 updateWindowGeometryFromView(*m_view);
402 windowActive =
false;
407 windowStatesToSet.setFlag(Qt::WindowState::WindowActive, windowActive && windowAcceptsFocusAndInput);
408 setWindowStateFromOhos(windowStatesToSet);
413 auto *qWindow = window();
416 "Window status changed, window: %p(%s) status: %d",
418 qPrintable(qWindow->objectName()),
420 Qt::WindowStates windowStatesToSet = windowStates();
421 Qt::WindowState flagToSet;
422 m_lastWindowStatusType = evt.type;
425 case QOhosWindowProxy::WindowStatusType::FULL_SCREEN:
426 flagToSet = Qt::WindowState::WindowFullScreen;
428 case QOhosWindowProxy::WindowStatusType::MAXIMIZE:
429 flagToSet = Qt::WindowState::WindowMaximized;
431 case QOhosWindowProxy::WindowStatusType::MINIMIZE:
432 flagToSet = Qt::WindowState::WindowMinimized;
437 case QOhosWindowProxy::WindowStatusType::SPLIT_SCREEN:
438 flagToSet = Qt::WindowState::WindowNoState;
444 if (flagToSet == Qt::WindowState::WindowFullScreen
445 || flagToSet == Qt::WindowState::WindowMaximized) {
446 windowStatesToSet = m_view->isFullscreenImmersiveModeEnabled()
447 ? Qt::WindowState::WindowFullScreen
448 : Qt::WindowState::WindowMaximized;
450 static constexpr Qt::WindowState mutuallyExclusiveFlags[] = {
451 Qt::WindowState::WindowFullScreen,
452 Qt::WindowState::WindowMaximized,
453 Qt::WindowState::WindowMinimized,
454 Qt::WindowState::WindowNoState,
457 for (
const auto exclusiveState : mutuallyExclusiveFlags)
458 windowStatesToSet.setFlag(exclusiveState, flagToSet == exclusiveState);
461 setWindowStateFromOhos(windowStatesToSet);
467 updateWindowGeometryFromView(*m_view);
472 auto *qWindow = window();
475 "Window %p(%s) visibility changed: %s",
477 qPrintable(qWindow->objectName()),
478 visible ?
"true" :
"false");
479 if (visible && m_windowMask.hasValue())
480 m_view->setWindowMask(QOhosWindowProxy::WindowMask{m_windowMask.value()});
490 const QOhosWindowProxy::AvoidArea &systemAvoidArea)
492 const auto &cached = m_avoidAreaCache[avoidAreaType];
494 bool actuallyChanged =
495 cached.visible != systemAvoidArea.visible
496 || cached.leftRect != systemAvoidArea.leftRect
497 || cached.rightRect != systemAvoidArea.rightRect
498 || cached.bottomRect != systemAvoidArea.bottomRect
499 || cached.topRect != systemAvoidArea.topRect;
501 if (actuallyChanged) {
502 m_avoidAreaCache[avoidAreaType] = systemAvoidArea;
503 qCDebug(QtForOhos) <<
"Avoid area changed:"
504 <<
static_cast<
int>(avoidAreaType)
505 <<
"visible:" << systemAvoidArea.visible
506 <<
"top:" << systemAvoidArea.topRect
507 <<
"left:" << systemAvoidArea.leftRect
508 <<
"right:" << systemAvoidArea.rightRect
509 <<
"bottom:" << systemAvoidArea.bottomRect;
510 updateWindowGeometryFromView(*m_view);
514void QOhosFloatingWindow::handleSurfaceStatusChanged(
const QOhosOptional<QSize> &optSurfaceSize)
516 m_optLastSurfaceSize = optSurfaceSize;
517 bool hasSurface = m_view->surfaceOrNull() !=
nullptr;
518 if (m_view->viewType() == QOhosView::ViewType::EmbeddedWindow) {
525 updateWindowGeometryFromSurface();
534 const QOhosWindowProxy::RectChangeOptions &rectChangeOptions)
536 bool shouldUpdateWindowGeometryFromView =
true;
537 bool needsCloseAllActivePopups =
false;
538 m_lastRectChangeOptions = rectChangeOptions;
541 <<
"windowRectChanged window:" << window()
542 <<
"rect:" << rectChangeOptions.rect
543 <<
"reason:" <<
static_cast<
int>(rectChangeOptions.reason);
545 switch (rectChangeOptions.reason) {
550 shouldUpdateWindowGeometryFromView =
false;
551 needsCloseAllActivePopups =
true;
557 shouldUpdateWindowGeometryFromView =
false;
561 if (shouldUpdateWindowGeometryFromView)
562 updateWindowGeometryFromView(*m_view);
564 updateWindowGeometryFromSurface();
566 if (isWindowRotatedByTabletScreenRotation(window(), rectChangeOptions))
567 needsCloseAllActivePopups =
true;
569 if (needsCloseAllActivePopups)
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
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.
QOhosSurface * surfaceOrNull() const
void setWindowMask(const QOhosWindowProxy::WindowMask &windowMask)
ViewGeometry viewGeometry() const
bool isSubWindowCoveringFullScreen() const
@ TYPE_NAVIGATION_INDICATOR
static QWindowProxyRegistry & instance()
bool isWindowPcModeEnabled()
Combined button and popup list for selecting options.
bool isWindowRotatedByTabletScreenRotation(QWindow *window, QOhosWindowProxy::RectChangeOptions rectChangeOptions)
QOhosRuntimeDeviceTypeAndMode
@ HandheldDeviceWindowPcMode
QOhosRuntimeDeviceTypeAndMode queryQOhosRuntimeDeviceAndMode()