104 QNapi::Object windowStageOrWindowObject,
107 auto subWindowOptionsObject =
109 windowStageOrWindowObject.Env(),
111 {
"title", subWindowOptions.windowTitle},
112 {
"decorEnabled", subWindowOptions.decorEnabled},
113 {
"isModal", subWindowOptions.isModal},
115 "windowRect", makeRectObject(windowStageOrWindowObject.Env(), subWindowOptions.windowRect)
119 return windowStageOrWindowObject.evalToPromiseOrRejectOnThrow(
120 "createSubWindowWithOptions(*)",
121 {windowName, subWindowOptionsObject});
166 auto sharedContext = QtOhos::moveToSharedPtr(std::move(subWindowOnAppearCbCtx));
171 auto xComponent = takeNodeXComponentFromRegistryOrFail(sharedContext->xComponentId);
173 sharedContext->resultConsumer(
175 QOhosWindowProxyData {
176 .qAbilityPeer = sharedContext->qAbilityPeer,
177 .jsWindow = std::move(sharedContext->windowObject),
178 .windowProxyType = sharedContext->windowProxyType,
179 .nodeXComponent = std::make_shared<QXComponentNode>(xComponent),
180 .jsKeepAliveData = QtOhos::moveToSharedPtr(std::move(sharedContext->localStorageObj)),
181 .owningQWindowRef = sharedContext->owningQWindowRef,
184 sharedContext.reset();
196 auto *env = jsState.env();
198 auto localStorage = makeLocalStorage(jsState);
199 auto subWindowNativeNodeCreateInfo = QNapi::makeObject(
202 {
"xComponentId", createInfo.xComponentId.toNapiValue(env)},
205 [xComponentId = createInfo.xComponentId.stringId()]() {
207 "WindowNativeNodeCreateInfo.onDisAppear() called from JS for xComponentId='%s'",
208 xComponentId.c_str());
213 makeSubWindowOnAppearCallbackHandler(SubWindowOnAppearContext {
214 .xComponentId = createInfo.xComponentId,
215 .localStorageObj = Napi::Persistent(localStorage),
216 .windowObject = Napi::Persistent(createInfo.windowObject),
217 .resultConsumer = std::move(createInfo.resultConsumer),
218 .qAbilityPeer = std::move(createInfo.qAbilityPeer),
219 .windowProxyType = createInfo.windowProxyType,
220 .owningQWindowRef = createInfo.owningQWindowRef,
225 localStorage.eval(
"setOrCreate(*)", {
"createInfo", subWindowNativeNodeCreateInfo});
233 struct LoadWindowContentsArgs
235 QNapi::Reference<QNapi::Object> window;
236 QNapi::Reference<QNapi::Object> localStorage;
237 std::string contentPagePath;
240 if (!context.disableWindowFocusableBeforeLoadContentHack)
241 return loadWindowContents(windowObject, context.localStorage, context.contentPagePath);
243 auto loadWindowContentsArgs = LoadWindowContentsArgs {
244 .window = Napi::Persistent(windowObject),
245 .localStorage = Napi::Persistent(context.localStorage),
246 .contentPagePath = context.contentPagePath,
249 return windowObject.evalToPromiseOrRejectOnThrow(
"setWindowFocusable(*)", {
false})
250 .onThen([loadWindowContentsArgs = std::move(loadWindowContentsArgs)]() {
251 return loadWindowContents(
252 loadWindowContentsArgs.window.Value(),
253 loadWindowContentsArgs.localStorage.Value(),
254 loadWindowContentsArgs.contentPagePath);
263 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
265 auto optBaseQAbility = jsState.defaultQAbility();
266 if (!optBaseQAbility)
267 qOhosReportFatalErrorAndAbort(
"%s: can't create window without the default Ability instance", Q_FUNC_INFO);
269 auto abilityStartupOptions =
273 {
"windowLeft", createInfo.frameGeometry.x()},
274 {
"windowTop", createInfo.frameGeometry.y()},
275 {
"windowWidth", createInfo.frameGeometry.width()},
276 {
"windowHeight", createInfo.frameGeometry.height()},
280 auto fullscreenWindowMode = jsState.eval<QNapi::Number>(
281 "@ohos.app.ability.AbilityConstant.WindowMode.WINDOW_MODE_FULLSCREEN");
282 abilityStartupOptions.set(
"windowMode", fullscreenWindowMode);
285 jsState.startNewQAbilityInstance(
286 optBaseQAbility.value(), createInfo.qWindowRef,
287 abilityStartupOptions,
288 [qWindowRef = createInfo.qWindowRef,
289 windowId = createInfo.windowId,
291 auto createInfo = QOhosWindowProxyExistingMainWindowCreateInfo {
292 .qWindowRef = qWindowRef,
293 .qAbilityInstanceId = qAbilityPeer->instanceId(),
294 .windowId = windowId,
297 makeWindowProxyDataForExistingMainWindowInJsThread(
298 jsState, createInfo,
std::move(resultConsumer));
305 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
308 getQAbilityPeerByInstanceIdOrFail(jsState, createInfo.qAbilityInstanceId));
309 if (!optQUiAbilityPeer) {
310 qOhosReportFatalErrorAndAbort(
311 "%s Attempting to make window proxy for main window for ability without windowStage. This is most likely a programming error. Aborting...",
314 optQUiAbilityPeer->setQWindow(jsState.env(), createInfo.qWindowRef);
316 auto window = optQUiAbilityPeer->windowStage().eval<QNapi::Object>(
"getMainWindowSync()");
318 auto nodeXComponent = takeNodeXComponentFromRegistryOrFail(nativeNodeXComponentId);
322 QOhosWindowProxyData {
323 .qAbilityPeer = optQUiAbilityPeer,
324 .jsWindow = Napi::Persistent(window),
325 .windowProxyType = WindowProxyType::MainWindow,
326 .nodeXComponent = std::make_shared<QXComponentNode>(nodeXComponent),
327 .jsKeepAliveData =
nullptr,
328 .owningQWindowRef = createInfo.qWindowRef,
350 QNapi::Object windowStageOrWindowObject,
352 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
354 auto xComponentId = QXComponentId::createForNativeNodeSubWindow(createInfo.windowId);
357 bool disableWindowFocusableBeforeLoadContentHack;
360 QtOhos::QObjectThreadSafeRef owningQWindowRef;
363 auto qAbilityPeer = getQAbilityPeerByInstanceIdOrFail(jsState, createInfo.qAbilityInstanceId);
370 auto subWindowCreationPromise = [&]() -> QNapi::Promise {
371 if (!isWindowSessionManagerAvailable(jsState))
372 return createSubWindowViaWindowStage(qAbilityPeer, windowName);
374 return createSubWindowWithOptions(
375 windowStageOrWindowObject,
378 .windowTitle = createInfo.windowTitle,
379 .decorEnabled = createInfo.decorEnabled,
380 .isModal = createInfo.modal,
381 .windowRect = createInfo.windowRect,
383 .onCatch([qAbilityPeer, windowName](
const QtOhos::CallbackInfo &) -> QNapi::Promise {
386 "createSubWindowWithOptions() is unavailable in this context; "
387 "falling back to createSubWindow()");
388 return createSubWindowViaWindowStage(qAbilityPeer, windowName);
392 auto context = Context {
394 .xComponentId = xComponentId,
395 .qAbilityPeer = qAbilityPeer,
396 .owningQWindowRef = createInfo.window,
399 subWindowCreationPromise
400 .onThen([resultConsumer = std::move(resultConsumer), context = std::move(context)](
const QtOhos::
CallbackInfo &cbInfo)
mutable {
401 auto windowObject = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
403 auto localStorage = makeLocalStorageForWindow(
405 LocalStorageForWindowCreateInfo {
406 .xComponentId = context.xComponentId,
407 .windowObject = windowObject,
408 .resultConsumer = std::move(resultConsumer),
409 .qAbilityPeer = context.qAbilityPeer,
410 .windowProxyType = WindowProxyType::SubWindow,
411 .owningQWindowRef = context.owningQWindowRef,
414 return onWindowCreatedLoadWindowContents(
415 cbInfo.jsState(), windowObject,
416 OnWindowCreatedLoadWindowContentsContext {
417 .disableWindowFocusableBeforeLoadContentHack = context.disableWindowFocusableBeforeLoadContentHack,
418 .contentPagePath =
"pages/SubWindowNativeNode",
419 .localStorage = localStorage,
423 QtOhos::logJsCallbackError(cbInfo,
"sub window creation failed");
424 qOhosReportFatalErrorAndAbort(
425 "Failed to create subwindow for windowId='%s'",
426 windowId.toStdString().c_str());
432 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
434 auto xComponentId = QXComponentId::createForNativeNodeFloatWindow(createInfo.internalWindowId);
437 if (qAbilityPeer->qAbility().IsEmpty())
438 qOhosReportFatalErrorAndAbort(
"%s: can't create window without the default Ability instance", Q_FUNC_INFO);
440 auto configurationObject = QNapi::makeObject(
444 {
"name", makeOhosUniqueSystemWindowName(createInfo.internalWindowId)},
445 {
"windowType", jsState.eval<QNapi::Number>(
"@ohos.window.WindowType.TYPE_FLOAT")},
446 {
"ctx", qAbilityPeer->qAbility().get<QNapi::Object>(
"context")},
453 QtOhos::QObjectThreadSafeRef owningQWindowRef;
456 auto context = Context {
457 .xComponentId = xComponentId,
458 .qAbilityPeer = qAbilityPeer,
459 .owningQWindowRef = createInfo.qWindowRef,
463 .evalToPromiseOrRejectOnThrow(
"@ohos.window.createWindow(*)", {configurationObject})
464 .onThen([resultConsumer = std::move(resultConsumer), context = std::move(context)](
const QtOhos::
CallbackInfo &cbInfo)
mutable {
465 auto windowObject = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
467 auto localStorage = makeLocalStorageForWindow(
469 LocalStorageForWindowCreateInfo {
470 .xComponentId = context.xComponentId,
471 .windowObject = windowObject,
472 .resultConsumer = std::move(resultConsumer),
473 .qAbilityPeer = context.qAbilityPeer,
474 .windowProxyType = WindowProxyType::FloatWindow,
475 .owningQWindowRef = context.owningQWindowRef,
478 return onWindowCreatedLoadWindowContents(
479 cbInfo.jsState(), windowObject,
480 OnWindowCreatedLoadWindowContentsContext {
481 .disableWindowFocusableBeforeLoadContentHack =
false,
482 .contentPagePath =
"pages/FloatWindowNativeNode",
483 .localStorage = localStorage,
486 .onCatch([internalWindowId = createInfo.internalWindowId](
const QtOhos::
CallbackInfo &cbInfo) {
487 QtOhos::logJsCallbackError(cbInfo,
"Failed to create TYPE_FLOAT window");
488 qOhosReportFatalErrorAndAbort(
489 "Failed to create TYPE_FLOAT window for windowId='%s'",
490 internalWindowId.toStdString().c_str());
QOhosConsumer< QtOhos::JsState &, QOhosWindowProxyData > resultConsumer
std::shared_ptr< QtOhos::QAbilityPeer > qAbilityPeer