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 return !context.disableWindowFocusableBeforeLoadContentHack
241 ? loadWindowContents(windowObject, context.localStorage, context.contentPagePath)
242 : windowObject.evalToPromiseOrRejectOnThrow(
"setWindowFocusable(*)", {
false})
243 .withContext(LoadWindowContentsArgs {
244 .window = Napi::Persistent(windowObject),
245 .localStorage = Napi::Persistent(context.localStorage),
246 .contentPagePath = context.contentPagePath,
248 .onThenWithContext([](LoadWindowContentsArgs &windowLocalStoragePair) {
249 return loadWindowContents(
250 windowLocalStoragePair.window.Value(),
251 windowLocalStoragePair.localStorage.Value(),
252 windowLocalStoragePair.contentPagePath);
261 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
263 auto optBaseQAbility = jsState.defaultQAbility();
264 if (!optBaseQAbility)
265 qOhosReportFatalErrorAndAbort(
"%s: can't create window without the default Ability instance", Q_FUNC_INFO);
267 auto abilityStartupOptions =
271 {
"windowLeft", createInfo.frameGeometry.x()},
272 {
"windowTop", createInfo.frameGeometry.y()},
273 {
"windowWidth", createInfo.frameGeometry.width()},
274 {
"windowHeight", createInfo.frameGeometry.height()},
278 auto fullscreenWindowMode = jsState.eval<QNapi::Number>(
279 "@ohos.app.ability.AbilityConstant.WindowMode.WINDOW_MODE_FULLSCREEN");
280 abilityStartupOptions.set(
"windowMode", fullscreenWindowMode);
283 jsState.startNewQAbilityInstance(
284 optBaseQAbility.value(), createInfo.qWindowRef,
285 abilityStartupOptions,
286 [qWindowRef = createInfo.qWindowRef,
287 windowId = createInfo.windowId,
289 auto createInfo = QOhosWindowProxyExistingMainWindowCreateInfo {
290 .qWindowRef = qWindowRef,
291 .qAbilityInstanceId = qAbilityPeer->instanceId(),
292 .windowId = windowId,
295 makeWindowProxyDataForExistingMainWindowInJsThread(
296 jsState, createInfo,
std::move(resultConsumer));
303 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
306 getQAbilityPeerByInstanceIdOrFail(jsState, createInfo.qAbilityInstanceId));
307 if (!optQUiAbilityPeer) {
308 qOhosReportFatalErrorAndAbort(
309 "%s Attempting to make window proxy for main window for ability without windowStage. This is most likely a programming error. Aborting...",
312 optQUiAbilityPeer->setQWindow(jsState.env(), createInfo.qWindowRef);
314 auto window = optQUiAbilityPeer->windowStage().eval<QNapi::Object>(
"getMainWindowSync()");
316 auto nodeXComponent = takeNodeXComponentFromRegistryOrFail(nativeNodeXComponentId);
320 QOhosWindowProxyData {
321 .qAbilityPeer = optQUiAbilityPeer,
322 .jsWindow = Napi::Persistent(window),
323 .windowProxyType = WindowProxyType::MainWindow,
324 .nodeXComponent = std::make_shared<QXComponentNode>(nodeXComponent),
325 .jsKeepAliveData =
nullptr,
326 .owningQWindowRef = createInfo.qWindowRef,
348 QNapi::Object windowStageOrWindowObject,
350 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
352 auto xComponentId = QXComponentId::createForNativeNodeSubWindow(createInfo.windowId);
355 bool disableWindowFocusableBeforeLoadContentHack;
358 QtOhos::QObjectThreadSafeRef owningQWindowRef;
361 auto qAbilityPeer = getQAbilityPeerByInstanceIdOrFail(jsState, createInfo.qAbilityInstanceId);
368 auto subWindowCreationPromise = [&]() -> QNapi::Promise {
369 if (!isWindowSessionManagerAvailable(jsState))
370 return createSubWindowViaWindowStage(qAbilityPeer, windowName);
372 return createSubWindowWithOptions(
373 windowStageOrWindowObject,
376 .windowTitle = createInfo.windowTitle,
377 .decorEnabled = createInfo.decorEnabled,
378 .isModal = createInfo.modal,
379 .windowRect = createInfo.windowRect,
381 .onCatch([qAbilityPeer, windowName](
const QtOhos::CallbackInfo &) -> QNapi::Promise {
384 "createSubWindowWithOptions() is unavailable in this context; "
385 "falling back to createSubWindow()");
386 return createSubWindowViaWindowStage(qAbilityPeer, windowName);
390 subWindowCreationPromise
391 .withContext(Context {
393 .xComponentId = xComponentId,
394 .qAbilityPeer = qAbilityPeer,
395 .owningQWindowRef = createInfo.window,
397 .onThenWithContext([resultConsumer = std::move(resultConsumer)](
const QtOhos::
CallbackInfo &cbInfo, Context &context)
mutable {
398 auto windowObject = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
400 auto localStorage = makeLocalStorageForWindow(
402 LocalStorageForWindowCreateInfo {
403 .xComponentId = context.xComponentId,
404 .windowObject = windowObject,
405 .resultConsumer = std::move(resultConsumer),
406 .qAbilityPeer = context.qAbilityPeer,
407 .windowProxyType = WindowProxyType::SubWindow,
408 .owningQWindowRef = context.owningQWindowRef,
411 return onWindowCreatedLoadWindowContents(
412 cbInfo.jsState(), windowObject,
413 OnWindowCreatedLoadWindowContentsContext {
414 .disableWindowFocusableBeforeLoadContentHack = context.disableWindowFocusableBeforeLoadContentHack,
415 .contentPagePath =
"pages/SubWindowNativeNode",
416 .localStorage = localStorage,
420 QtOhos::logJsCallbackError(cbInfo,
"sub window creation failed");
421 qOhosReportFatalErrorAndAbort(
422 "Failed to create subwindow for windowId='%s'",
423 windowId.toStdString().c_str());
429 QOhosConsumer<QtOhos::JsState &, QOhosWindowProxyData> resultConsumer)
431 auto xComponentId = QXComponentId::createForNativeNodeFloatWindow(createInfo.internalWindowId);
434 if (qAbilityPeer->qAbility().IsEmpty())
435 qOhosReportFatalErrorAndAbort(
"%s: can't create window without the default Ability instance", Q_FUNC_INFO);
437 auto configurationObject = QNapi::makeObject(
441 {
"name", makeOhosUniqueSystemWindowName(createInfo.internalWindowId)},
442 {
"windowType", jsState.eval<QNapi::Number>(
"@ohos.window.WindowType.TYPE_FLOAT")},
443 {
"ctx", qAbilityPeer->qAbility().get<QNapi::Object>(
"context")},
450 QtOhos::QObjectThreadSafeRef owningQWindowRef;
454 .evalToPromiseOrRejectOnThrow(
"@ohos.window.createWindow(*)", {configurationObject})
455 .withContext(Context {
456 .xComponentId = xComponentId,
457 .qAbilityPeer = qAbilityPeer,
458 .owningQWindowRef = createInfo.qWindowRef,
460 .onThenWithContext([resultConsumer = std::move(resultConsumer)](
const QtOhos::
CallbackInfo &cbInfo, Context &context)
mutable {
461 auto windowObject = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
463 auto localStorage = makeLocalStorageForWindow(
465 LocalStorageForWindowCreateInfo {
466 .xComponentId = context.xComponentId,
467 .windowObject = windowObject,
468 .resultConsumer = std::move(resultConsumer),
469 .qAbilityPeer = context.qAbilityPeer,
470 .windowProxyType = WindowProxyType::FloatWindow,
471 .owningQWindowRef = context.owningQWindowRef,
474 return onWindowCreatedLoadWindowContents(
475 cbInfo.jsState(), windowObject,
476 OnWindowCreatedLoadWindowContentsContext {
477 .disableWindowFocusableBeforeLoadContentHack =
false,
478 .contentPagePath =
"pages/FloatWindowNativeNode",
479 .localStorage = localStorage,
482 .onCatch([internalWindowId = createInfo.internalWindowId](
const QtOhos::
CallbackInfo &cbInfo) {
483 QtOhos::logJsCallbackError(cbInfo,
"Failed to create TYPE_FLOAT window");
484 qOhosReportFatalErrorAndAbort(
485 "Failed to create TYPE_FLOAT window for windowId='%s'",
486 internalWindowId.toStdString().c_str());
QOhosConsumer< QtOhos::JsState &, QOhosWindowProxyData > resultConsumer
std::shared_ptr< QtOhos::QAbilityPeer > qAbilityPeer