diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000000000000000000000000000000000000..56397aff4d85febeda65a11f60aa2634fc352738 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/lib/utils/config.dart b/example/lib/utils/config.dart index 632f01b98b3f152a8d25a6ce08d15b3831d2a196..d45c39d7936eb0a53256905f7003beb29c57e39a 100644 --- a/example/lib/utils/config.dart +++ b/example/lib/utils/config.dart @@ -2,7 +2,7 @@ import 'dart:collection'; import 'package:flutter/material.dart'; -final class _ListenerEntry extends LinkedListEntry<_ListenerEntry> { +class _ListenerEntry extends LinkedListEntry<_ListenerEntry> { _ListenerEntry(this.listener); final VoidCallback listener; } diff --git a/example/ohos/.gitignore b/example/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6ca13b3170eec5dd5ac5ad7f1c4dd0118845f473 --- /dev/null +++ b/example/ohos/.gitignore @@ -0,0 +1,19 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +*.har +**/BuildProfile.ets +**/oh-package-lock.json5 + +**/src/main/resources/rawfile/flutter_assets/ +**/libs/arm64-v8a/libapp.so +**/libs/arm64-v8a/libflutter.so +**/libs/arm64-v8a/libvmservice_snapshot.so diff --git a/example/ohos/AppScope/app.json5 b/example/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..54b452371434d157a929b2998ae0b4007bf6294c --- /dev/null +++ b/example/ohos/AppScope/app.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "app": { + "bundleName": "com.example.window_manager_plus_example", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} \ No newline at end of file diff --git a/example/ohos/AppScope/resources/base/element/string.json b/example/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c7c7511f937ff71fc713637e40f9611a47861a72 --- /dev/null +++ b/example/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "window_manager_plus_example" + } + ] +} diff --git a/example/ohos/AppScope/resources/base/media/app_icon.png b/example/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/example/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/example/ohos/build-profile.json5 b/example/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..04ec2113ba2579cb805793634ee4a11a1464a1bf --- /dev/null +++ b/example/ohos/build-profile.json5 @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/.gitignore b/example/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/example/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/example/ohos/entry/build-profile.json5 b/example/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/example/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/hvigorfile.ts b/example/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/example/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/example/ohos/entry/oh-package.json5 b/example/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b0ac9797a95abbb76a81e6f70eeaae49397b6dda --- /dev/null +++ b/example/ohos/entry/oh-package.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "window_manager_plus": "file:../har/window_manager_plus.har", + "integration_test": "file:../har/integration_test.har", + "screen_retriever": "file:../har/screen_retriever.har" + } +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..f18870b8f69743cf8a6658ea4d7614904ed0a7f7 --- /dev/null +++ b/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos'; +import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; +import window from '@ohos.window'; +import { AbilityConstant, Want } from '@kit.AbilityKit'; +import WindowManagerPlusPlugin, { WindowStageManager } from 'window_manager_plus'; + +const WINDOW_NAME_KEY = 'WINDOW_NAME'; +const INIT_ROUTE_KEY = 'INIT_ROUTE'; + +/** + * flutter多窗口entry模板代码 + */ +export default class EntryAbility extends FlutterAbility { + windowName: string = '0'; + //默认窗口id=0 + initRoute: string = '/'; + + configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + GeneratedPluginRegistrant.registerWith(flutterEngine) + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + super.onWindowStageCreate(windowStage); + if (this.windowName) { + WindowStageManager.addStage(this.windowName, windowStage); + } + } + + async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + super.onCreate(want, launchParam); + const record: Record | undefined = want.parameters; + if (record && record[WINDOW_NAME_KEY]) { + if (record[WINDOW_NAME_KEY]) { + this.windowName = record[WINDOW_NAME_KEY].toString(); + } + if (record[INIT_ROUTE_KEY]) { + this.initRoute = record[INIT_ROUTE_KEY].toString(); + } + } + } + + getInitialRoute(): string { + return this.initRoute; + } + + onWindowStageWillDestroy(windowStage: window.WindowStage): void { + try { + super.onWindowStageWillDestroy(windowStage); + } catch (e) { + console.error('error on onWindowStageWillDestroy' + e); + } + if (this.windowName) { + WindowManagerPlusPlugin.releaseWindowManager(parseInt(this.windowName)); + } + if (this.windowName) { + WindowStageManager.removeStage(this.windowName); + } + } + + getDartEntrypointArgs(): string[] { + let arr: string[] = super.getDartEntrypointArgs(); + if (!arr) { + arr = []; + } + if (this.windowName) { + arr.push(this.windowName); + } + return arr; + } + + isDefaultFullScreen(): boolean { + return false; + } +} diff --git a/example/ohos/entry/src/main/ets/pages/Index.ets b/example/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9 --- /dev/null +++ b/example/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +let storage = LocalStorage.getShared() +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry(storage) +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + @LocalStorageLink('viewId') viewId: string = ""; + + build() { + Column() { + FlutterPage({ viewId: this.viewId }) + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/module.json5 b/example/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4408d22b92029ca34cf2c0ed7396db985cfe617b --- /dev/null +++ b/example/ohos/entry/src/main/module.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "launchType": "multiton", + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/resources/base/element/color.json b/example/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/example/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/resources/base/element/string.json b/example/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3131bad26604ac44d35a7cc7e4cb59b06e2cbdec --- /dev/null +++ b/example/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "window_manager_plus_example" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/resources/base/media/icon.png b/example/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/example/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/example/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/example/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/example/ohos/entry/src/main/resources/en_US/element/string.json b/example/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3131bad26604ac44d35a7cc7e4cb59b06e2cbdec --- /dev/null +++ b/example/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "window_manager_plus_example" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/example/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..77704b65572b3f50e4ef7cd7189867b76b63862e --- /dev/null +++ b/example/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "window_manager_plus_example" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/example/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/module.json5 b/example/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/example/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/example/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/example/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/example/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/example/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/example/ohos/hvigor/hvigor-config.json5 b/example/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..541ba35711b75986f9295410ee38fdb8f2572878 --- /dev/null +++ b/example/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "modelVersion": "5.0.0", + "dependencies": { + } +} \ No newline at end of file diff --git a/example/ohos/hvigorfile.ts b/example/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1 --- /dev/null +++ b/example/ohos/hvigorfile.ts @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/example/ohos/oh-package.json5 b/example/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f2d99857dfc4840f17e10db44906047032ac716c --- /dev/null +++ b/example/ohos/oh-package.json5 @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "modelVersion": "5.0.0", + "name": "window_manager_plus_example", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + }, + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "overrides": { + "@ohos/flutter_ohos": "file:./har/flutter.har", + "window_manager_plus": "file:./har/window_manager_plus.har", + "integration_test": "file:./har/integration_test.har", + "@ohos/flutter_module": "file:./entry", + "screen_retriever": "file:./har/screen_retriever.har" + } +} \ No newline at end of file diff --git a/example/pubspec.lock b/example/pubspec.lock index 5c163646e19dcad22b5fbd5d2d286555484ebeef..369b5aef2fff058aeb836b6537be46d09c315e47 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,20 +1,28 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.3.2" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.11.0" + version: "2.10.0" boolean_selector: dependency: transitive description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" bot_toast: @@ -22,57 +30,65 @@ packages: description: name: bot_toast sha256: "6b93030a99a98335b8827ecd83021e92e885ffc61d261d3825ffdecdd17f3bdf" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.3" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.0" + version: "1.2.1" clock: dependency: transitive description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.17.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.18.0" + version: "3.0.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.8" + version: "1.0.6" fake_async: dependency: transitive description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.1" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" - url: "https://pub.dev" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.flutter-io.cn" source: hosted - version: "7.0.0" + version: "6.1.4" flutter: dependency: "direct main" description: flutter @@ -98,172 +114,93 @@ packages: description: flutter source: sdk version: "0.0.0" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" - source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: + js: dependency: transitive description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.5" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - lints: - dependency: transitive - description: - name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" - url: "https://pub.dev" - source: hosted - version: "4.0.0" + version: "0.6.5" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.16+1" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.11.1" + version: "0.2.0" menu_base: dependency: transitive description: name: menu_base sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.1" meta: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - mostly_reasonable_lints: - dependency: "direct dev" - description: - name: mostly_reasonable_lints - sha256: e19fec63536866ba307b3dfbc258b4bce9b3745129f038006b56b4067c6293d8 - url: "https://pub.dev" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.2" + version: "1.8.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.0" + version: "1.8.2" platform: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" - url: "https://pub.dev" - source: hosted - version: "3.1.5" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.8" + version: "3.1.0" preference_list: dependency: "direct main" description: name: preference_list - sha256: "1429f8fe03605d5eaf6dc333208d7bbf028bae707c3c1c32386939e4d7f58154" - url: "https://pub.dev" + sha256: d3419b2ec57a6ad2156bd682a46cf3194bf162b36bb013790c7b29e6438f107a + url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.2" + version: "0.0.1" process: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" - url: "https://pub.dev" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.flutter-io.cn" source: hosted - version: "5.0.2" + version: "4.2.4" screen_retriever: dependency: transitive description: - name: screen_retriever - sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_linux: - dependency: transitive - description: - name: screen_retriever_linux - sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_macos: - dependency: transitive - description: - name: screen_retriever_macos - sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_platform_interface: - dependency: transitive - description: - name: screen_retriever_platform_interface - sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_windows: - dependency: transitive - description: - name: screen_retriever_windows - sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13" - url: "https://pub.dev" - source: hosted - version: "0.2.0" + path: "." + ref: "dev_v0.1.9" + resolved-ref: e90de0e1d743ffcd305789ecb5ac1bfa4cf6f7c9 + url: "https://gitee.com/openharmony-sig/fluttertpc_screen_retriever.git" + source: git + version: "0.1.9" shortid: dependency: transitive description: name: shortid sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.2" sky_engine: @@ -275,32 +212,32 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" sync_http: @@ -308,7 +245,7 @@ packages: description: name: sync_http sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.1" term_glyph: @@ -316,56 +253,64 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.2" + version: "0.4.16" tray_manager: dependency: "direct main" description: name: tray_manager - sha256: bdc3ac6c36f3d12d871459e4a9822705ce5a1165a17fa837103bc842719bf3f7 - url: "https://pub.dev" + sha256: "4ab709d70a4374af172f8c39e018db33a4271265549c6fc9d269a65e5f4b0225" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.4" + version: "1.3.1" vector_math: dependency: transitive description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" + sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7 + url: "https://pub.flutter-io.cn" source: hosted - version: "14.2.5" + version: "9.4.0" webdriver: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" - url: "https://pub.dev" + sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841 + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.3" + version: "3.0.1" window_manager_plus: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.0.0" + version: "1.0.5" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=2.19.6 <3.0.0" + flutter: ">=3.3.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bc7784d3ed76a40b32a65447d230d2539ca5e131..59d49ba17dc997b43dd0db36b068de780f11d618 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,15 +3,15 @@ description: Demonstrates how to use the window_manager_plus plugin. publish_to: "none" environment: - sdk: ">=3.0.0 <4.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: bot_toast: ^4.1.3 cupertino_icons: ^1.0.2 flutter: sdk: flutter - preference_list: ^0.0.2 - tray_manager: ^0.2.4 + preference_list: ^0.0.1 + tray_manager: ^0.2.1 window_manager_plus: path: ../ @@ -20,7 +20,6 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mostly_reasonable_lints: ^0.1.2 flutter: uses-material-design: true diff --git a/lib/src/window_listener.dart b/lib/src/window_listener.dart index 2e6f0a60acc059a4e41245813b208229d2b0bed9..837016e8cddba9d9637b6901fc0ca0019c719e05 100644 --- a/lib/src/window_listener.dart +++ b/lib/src/window_listener.dart @@ -4,7 +4,7 @@ import 'package:window_manager_plus/src/window_manager.dart'; /// If this is used as a Global Listener using the [WindowManagerPlus.addGlobalListener] static method, /// the `windowId` parameter will be the ID of the window that emitted the event, /// otherwise, it will be always `null`. -abstract mixin class WindowListener { +mixin WindowListener { /// Emitted when the window is going to be closed. void onWindowClose([int? windowId]) {} diff --git a/ohos/.gitignore b/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c0f9ca4c47ca2d6aea523c5e0cf3331566bbf88a --- /dev/null +++ b/ohos/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/oh_modules +/.preview +/.idea +/build +/.cxx +/.test +/BuildProfile.ets +/oh-package-lock.json5 diff --git a/ohos/build-profile.json5 b/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b1fd98dbe794839b511425d5d0e052658e756b32 --- /dev/null +++ b/ohos/build-profile.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/hvigorfile.ts b/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47e6e1f81d365872f101585f5dbf816bcad65864 --- /dev/null +++ b/ohos/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/index.ets b/ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1136f96ea2c1690bb716ff2f20f1aed82c6fbe9b --- /dev/null +++ b/ohos/index.ets @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import WindowManagerPlusPlugin from './src/main/ets/components/plugin/WindowManagerPlusPlugin'; +export default WindowManagerPlusPlugin; +export { default as WindowStageManager } from './src/main/ets/components/plugin/WindowStageManager'; diff --git a/ohos/local.properties b/ohos/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..4ca8eb882f1a1634ae0304f3f5fa1b0df68dd14b --- /dev/null +++ b/ohos/local.properties @@ -0,0 +1 @@ +hwsdk.dir=C:\\Program Files\\Huawei\\DevEco Studio\\sdk \ No newline at end of file diff --git a/ohos/oh-package.json5 b/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2eeb1574ab45438f4c6f2b895b2907de597e623d --- /dev/null +++ b/ohos/oh-package.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "name": "window_manager_plus", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + } +} diff --git a/ohos/src/main/ets/components/plugin/MultiWindowAbility.ets b/ohos/src/main/ets/components/plugin/MultiWindowAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e6f29c2544ca256dfef4de4100a12f2b43a80b7 --- /dev/null +++ b/ohos/src/main/ets/components/plugin/MultiWindowAbility.ets @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { AbilityConstant, UIAbility, Want } from "@kit.AbilityKit"; +import window from "@ohos.window"; +import WindowStageManager from "./WindowStageManager"; + +export const WINDOW_NAME_KEY = 'WINDOW_NAME'; +export const INIT_ROUTE_KEY = 'INIT_ROUTE'; + +export default class MultiWindowAbility extends UIAbility { + windowName?: string; + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + super.onCreate(want, launchParam); + const record: Record | undefined = want.parameters; + if (record && record[WINDOW_NAME_KEY]) { + this.windowName = record[WINDOW_NAME_KEY].toString(); + } + } + + + onWindowStageCreate(windowStage: window.WindowStage): void { + super.onWindowStageCreate(windowStage); + if (this.windowName) { + WindowStageManager.addStage(this.windowName, windowStage); + } + } + + onWindowStageWillDestroy(windowStage: window.WindowStage): void { + super.onWindowStageWillDestroy(windowStage); + if (this.windowName) { + WindowStageManager.removeStage(this.windowName); + } + } +} \ No newline at end of file diff --git a/ohos/src/main/ets/components/plugin/WindowManagerPlus.ets b/ohos/src/main/ets/components/plugin/WindowManagerPlus.ets new file mode 100644 index 0000000000000000000000000000000000000000..a8685ada107a64b5d1504519d82ad1083030bd88 --- /dev/null +++ b/ohos/src/main/ets/components/plugin/WindowManagerPlus.ets @@ -0,0 +1,571 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { HashMap } from '@kit.ArkTS'; +import { MethodCall, MethodCallHandler, MethodChannel, MethodResult } from '@ohos/flutter_ohos'; +import { window } from '@kit.ArkUI'; +import WindowManagerPlusPlugin from './WindowManagerPlusPlugin'; +import app from '@system.app'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { bundleManager, common } from '@kit.AbilityKit'; +import { getMethodArg } from './WindowManagerUtil'; +import display from '@ohos.display'; +import WindowStateManager from './WindowStageManager'; + + +export default class WindowManagerPlus implements MethodCallHandler { + windowId?: number; + channel: MethodChannel | null = null; + windowClass: window.Window | null = null; + eventType: window.WindowEventType = window.WindowEventType.WINDOW_SHOWN; + statusType: window.WindowStatusType = window.WindowStatusType.UNDEFINED; + isPreventClose: boolean = false; + isLayoutFullScreen: boolean = false; + private moveTimeoutId: number = 0; + //多窗口处理handler集合 + static windowManagerPlusMap: HashMap = new HashMap(); + static autoRiseId: number = 0; + + /** + * 创建新窗口 + * @param args + */ + public static createWindow(args: string[]): number { + const windowId: number = WindowManagerPlus.getNewWindowId(); + return windowId; + } + + public static getNewWindowId(): number { + WindowManagerPlus.autoRiseId += 1; + return WindowManagerPlus.autoRiseId; + } + + onWindowInit() { + if (this.windowId != undefined && this.windowId >= 0) { + WindowManagerPlus.autoRiseId = this.windowId; + } + this.windowClass?.on('windowEvent', (type: window.WindowEventType) => { + this.eventType = type; + console.info('windowEvent. Event:' + type); + switch (type) { + case window.WindowEventType.WINDOW_ACTIVE: + this.onWindowFocus(); + break; + case window.WindowEventType.WINDOW_INACTIVE: + this.onWindowBlur(); + break; + // case window.WindowEventType.WINDOW_DESTROYED: + // 这个时机赶不上napi detach,所以在willDestroy中触发 + // if (this.windowId != undefined && this.windowId >= 0) { + // WindowManagerPlusPlugin.releaseWindowManager(this.windowId); + // } + // break; + default: + break; + } + }) + this.windowClass?.on('windowStatusChange', (type: window.WindowStatusType) => { + //检查是否退出窗口状态 + this.checkWindowStatus(type); + if (this.statusType !== type) { + this.statusType = type; + console.log('windowStatusChange: ' + this.statusType); + switch (type) { + case window.WindowStatusType.FULL_SCREEN: + if (this.windowClass?.getWindowProperties().isFullScreen && + this.windowClass?.getWindowProperties().isLayoutFullScreen) { + this.isLayoutFullScreen = true; + this.onWindowEnterFullScreen(); + } else { + this.isLayoutFullScreen = false; + this.onWindowMaximize(); + } + break; + case window.WindowStatusType.MAXIMIZE: + this.onWindowMaximize(); + break; + case window.WindowStatusType.MINIMIZE: + this.onWindowMinimize(); + break; + default: + break; + } + } + }) + this.windowClass?.on('windowRectChange', (data: window.RectChangeOptions) => { + if (data.reason === window.RectChangeReason.MOVE) { + //窗口拖拽移动 + this.onWindowMove(); + this.setMovedTimeout(); + } else if (data.reason === window.RectChangeReason.DRAG_START || data.reason === window.RectChangeReason.DRAG) { + //窗口拖拽缩放 + this.onWindowResize(); + } else if (data.reason === window.RectChangeReason.DRAG_END) { + //窗口结束拖拽缩放 + this.onWindowResized(); + } + }); + } + + private setMovedTimeout() { + clearTimeout(this.moveTimeoutId); + this.moveTimeoutId = setTimeout(() => { + this.onWindowMoved(); + }, 200); + } + + public release() { + this.onWindowClose(); + this.channel?.setMethodCallHandler(null); + try { + this.windowClass?.off('windowEvent'); + this.windowClass?.off('windowStatusChange'); + this.windowClass?.off('windowRectChange'); + } catch (exception) { + console.error(`Failed to unregister callback. Cause code: ${exception.code}, message: ${exception.message}`); + } + } + + /** + * 获取一个可用的window + * @returns + */ + public static getAvailableWindow(): window.Window | null { + const windowStage: window.WindowStage | undefined = WindowStateManager.getAvailableStage(); + try { + if (windowStage) { + return windowStage.getMainWindowSync(); + } + } catch (exception) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(exception)); + } + return null; + } + + /** + * 返回已创建窗口的id + * @returns + */ + public static getWindowsIds(): Array { + return Array.from(WindowManagerPlus.windowManagerPlusMap.keys()); + } + + + public setAsFrameless(): void { + + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + const argsObj: ESObject = call.args; + let windowId: number = -1; + if (argsObj instanceof Map) { + if (argsObj['windowId']) { + windowId = argsObj['windowId'] as number; + } + } + switch (call.method) { + case "invokeMethodToWindow": + const arg0: ESObject = getMethodArg(call, "targetWindowId"); + const targetWindowId: number = arg0 != null ? arg0 : -1; + if (WindowManagerPlus.windowManagerPlusMap.hasKey(targetWindowId)) { + WindowManagerPlus.windowManagerPlusMap.get(targetWindowId).channel?.invokeMethod('onEvent', + call.argument('args'), { + success: (response: ESObject) => { + result.success(response); + }, + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) => { + result.error(errorCode, errorMessage, errorDetails); + }, + notImplemented: () => { + result.error("1", "target channel not implemented onEvent method", null); + } + }); + } else { + result.error("0", "Cannot invokeMethodToWindow! targetWindowId not found", null); + } + break; + case "waitUntilReadyToShow": + //doNothing + result.success(true); + break; + case "setAsFrameless": + //隐藏标题栏和边框 + this.windowClass?.setWindowSystemBarEnable([]); + // this.windowClass?.setSpecificSystemBarEnabled('navigationIndicator',false); + break; + case "destroy": + this.destroy(); + result.success(true); + break; + case "close": + console.log('close: ' + this.isPreventClose); + if (!this.isPreventClose) { + this.destroy(); + result.success(true); + } + result.success(false); + break; + case "isPreventClose": + result.success(this.isPreventClose); + break; + case "setPreventClose": + this.isPreventClose = getMethodArg(call, 'isPreventClose'); + console.log('setPreventClose: ' + this.isPreventClose); + result.success(true); + break; + case "focus": + // window.shiftAppWindowFocus(0,0); + break; + case "blur": + // window.shiftAppWindowFocus(0,0); + break; + case "isFocused": + result.success(this.eventType === window.WindowEventType.WINDOW_ACTIVE); + break; + case "show": + this.windowClass?.showWindow(); + result.success(true); + break; + case "hide": + this.windowClass?.minimize(); + result.success(true); + break; + case "isVisible": + result.success(this.windowClass?.isWindowShowing()); + break; + case "isMaximized": + result.success(this.statusType == window.WindowStatusType.MAXIMIZE || + this.windowClass?.getWindowProperties().isFullScreen); + break; + case "maximize": + this.windowClass?.maximize(window.MaximizePresentation.FOLLOW_APP_IMMERSIVE_SETTING); + result.success(true); + break; + case "unmaximize": + this.windowClass?.recover(); + result.success(true); + break; + case "isMinimized": + result.success(this.statusType == window.WindowStatusType.MINIMIZE); + break; + case "isMaximizable": + result.success(true); + break; + case "setMaximizable": + result.success(true); + break; + case "minimize": + this.windowClass?.minimize(); + result.success(true); + break; + case "restore": + console.log('not implemented'); + break; + case "isDockable": + console.log('not implemented'); + break; + case "isDocked": + console.log('not implemented'); + break; + case "dock": + console.log('not implemented'); + break; + case "undock": + console.log('not implemented'); + break; + case "isFullScreen": + result.success(this.windowClass?.getWindowProperties().isFullScreen && + this.windowClass?.getWindowProperties().isLayoutFullScreen); + break; + case "setFullScreen": + const isFullScreen: boolean = getMethodArg(call, 'isFullScreen'); + this.windowClass?.setWindowLayoutFullScreen(isFullScreen); + result.success(true); + break; + case "setAspectRatio": + const aspectRatio: number = getMethodArg(call, 'aspectRatio'); + if (aspectRatio > 0) { + this.windowClass?.setAspectRatio(aspectRatio); + } else { + this.windowClass?.resetAspectRatio(); + } + result.success(true); + break; + case "setBackgroundColor": + const backgroundColorA: number = getMethodArg(call, 'backgroundColorA'); + const backgroundColorR: number = getMethodArg(call, 'backgroundColorR'); + const backgroundColorG: number = getMethodArg(call, 'backgroundColorG'); + const backgroundColorB: number = getMethodArg(call, 'backgroundColorB'); + console.log(`setBackgroundColor: ${backgroundColorA}, ${backgroundColorR}, ${backgroundColorG}, ${backgroundColorB}`); + const argb = this.toArgbString(backgroundColorA, backgroundColorR, backgroundColorG, backgroundColorB); + this.windowClass?.setWindowBackgroundColor(argb); + break; + case "getBounds": + let windowRect = this.windowClass?.getWindowProperties().windowRect; + console.log('getBounds windowRect: ' + windowRect); + let rectMap: Map = new Map(); + rectMap.set('x', windowRect?.left); + rectMap.set('y', windowRect?.top); + rectMap.set('width', windowRect?.width); + rectMap.set('height', windowRect?.height); + result.success(rectMap); + break; + case "setBounds": + const x: number = getMethodArg(call, 'x'); + const y: number = getMethodArg(call, 'y'); + const width: number = getMethodArg(call, 'width'); + const height: number = getMethodArg(call, 'height'); + console.log(`setBounds x: ${x}, y: ${y}, width: ${width}, height: ${height},`); + let displayClass = display.getDefaultDisplaySync(); + this.windowClass?.moveWindowTo(x, y).then(() => { + this.windowClass?.resize(width, height); + }) + break; + case "setMinimumSize": + let minWindowLimits = this.windowClass?.getWindowLimits(); + console.log('setMinimumSize minWindowLimits: ' + JSON.stringify(minWindowLimits)); + const minWidth: number = getMethodArg(call, 'width'); + const minHeight: number = getMethodArg(call, 'height'); + console.log(`setMinimumSize: ${minWidth}, ${minHeight}`); + let minLimits: window.WindowLimits = { + minWidth: minWidth, + minHeight: minHeight, + maxWidth: minWindowLimits?.maxWidth, + maxHeight: minWindowLimits?.maxHeight + } + this.windowClass?.setWindowLimits(minLimits) + break; + case "setMaximumSize": + let maxWindowLimits = this.windowClass?.getWindowLimits(); + console.log('setMaximumSize maxWindowLimits: ' + JSON.stringify(maxWindowLimits)); + const maxWidth: number = getMethodArg(call, 'width'); + const maxHeight: number = getMethodArg(call, 'height'); + console.log(`setMaximumSize: ${maxWidth}, ${maxHeight}`); + let maxLimits: window.WindowLimits = { + minWidth: maxWindowLimits?.minWidth, + minHeight: maxWindowLimits?.minHeight, + maxWidth: maxWidth, + maxHeight: maxHeight + } + this.windowClass?.setWindowLimits(maxLimits) + break; + case "isResizable": + console.log('not implemented'); + break; + case "setResizable": + console.log('not implemented'); + break; + case "isMovable": + console.log('not implemented'); + break; + case "setMovable": + console.log('not implemented'); + break; + case "isMinimizable": + console.log('not implemented'); + break; + case "setMinimizable": + console.log('not implemented'); + break; + case "isClosable": + console.log('not implemented'); + break; + case "setClosable": + console.log('not implemented'); + break; + case "isAlwaysOnTop": + console.log('not implemented'); + break; + case "setAlwaysOnTop": + console.log('not implemented'); + break; + case "getTitle": + console.log('not implemented'); + break; + case "setTitle": + console.log('not implemented'); + break; + case "setTitleBarStyle": + console.log('setTitleBarStyle'); + //const windowButtonVisibility: boolean = getMethodArg(call, 'windowButtonVisibility'); + //this.windowClass?.setWindowDecorVisible(windowButtonVisibility); + break; + case "getTitleBarHeight": + console.log('getTitleBarHeight'); + result.success(this.windowClass?.getWindowDecorHeight()); + break; + case "isSkipTaskbar": + console.log('not implemented'); + break; + case "setSkipTaskbar": + console.log('not implemented'); + break; + case "setBadgeLabel": + console.log('not implemented'); + break; + case "setProgressBar": + console.log('not implemented'); + break; + case "isVisibleOnAllWorkspaces": + console.log('not implemented'); + break; + case "setVisibleOnAllWorkspaces": + console.log('not implemented'); + break; + case "hasShadow": + console.log('not implemented'); + break; + case "setHasShadow": + console.log('not implemented'); + break; + case "getOpacity": + console.log('not implemented'); + break; + case "setOpacity": + console.log('not implemented'); + break; + case "setBrightness": + const brightness: string = getMethodArg(call, 'brightness'); + console.log('setBrightness brightness: ' + brightness); + if (brightness == 'light') { + this.windowClass?.setWindowBrightness(1); + } else if (brightness == 'dark') { + this.windowClass?.setWindowBrightness(0); + } + break; + case "setIgnoreMouseEvents": + console.log('not implemented'); + break; + case "startDragging": + console.log('not implemented'); + break; + + default: + result.notImplemented(); + } + // if (call.method == "createWindow") { + // result.success("OpenHarmony ^ ^ ") + // } else if (call.method == "getAllWindowManagerIds") { + // result.success("OpenHarmony ^ ^ ") + // } else { + // result.notImplemented() + // } + } + + private toArgbString(a: number, r: number, g: number, b: number): string { + if (a < 0 || a > 255 || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { + throw new Error('All values must be between 0 and 255'); + } + const toHex = (num: number): string => num.toString(16).padStart(2, '0'); + return `#${toHex(a)}${toHex(r)}${toHex(g)}${toHex(b)}`; + } + + private destroy() { + let context = this.windowClass?.getUIContext().getHostContext() as common.UIAbilityContext; + context?.terminateSelf(() => { + // 这个时机赶不上napi detach,所以在willDestroy中触发 + // if (this.windowId != undefined && this.windowId >= 0) { + // WindowManagerPlusPlugin.releaseWindowManager(this.windowId); + // } + }) + } + + private onWindowBlur() { + console.log('onWindowBlur'); + this.emitEvent("blur"); + } + + private onWindowClose() { + console.log('onWindowClose'); + this.emitEvent("close"); + } + + private onWindowEnterFullScreen() { + console.log('onWindowEnterFullScreen'); + this.emitEvent("enter-full-screen"); + } + + private onWindowFocus() { + console.log('onWindowFocus'); + this.emitEvent("focus"); + } + + private onWindowLeaveFullScreen() { + console.log('onWindowLeaveFullScreen'); + this.emitEvent("leave-full-screen"); + } + + private onWindowMaximize() { + console.log('onWindowMaximize'); + this.emitEvent("maximize"); + } + + private onWindowMinimize() { + console.log('onWindowMinimize'); + this.emitEvent("minimize"); + } + + private onWindowMove() { + console.log('onWindowMove'); + this.emitEvent("move"); + } + + private onWindowMoved() { + console.log('onWindowMoved'); + this.emitEvent("moved"); + } + + private onWindowResize() { + console.log('onWindowResize'); + this.emitEvent("resize"); + } + + private onWindowResized() { + console.log('onWindowResized'); + this.emitEvent("resized"); + } + + private onWindowRestore() { + console.log('onWindowRestore'); + this.emitEvent("restore"); + } + + private onWindowUnmaximize() { + console.log('onWindowUnmaximize'); + this.emitEvent("unmaximize"); + } + + private emitEvent(eventName: string) { + console.log('emitEvent, eventName:' + eventName); + let args: Map = new Map(); + args.set('eventName', eventName); + this.channel?.invokeMethod('onEvent', args); + } + + private checkWindowStatus(type: window.WindowStatusType) { + if (this.statusType != type) { + if (this.statusType === window.WindowStatusType.FULL_SCREEN) { + if (this.isLayoutFullScreen) { + this.onWindowLeaveFullScreen(); + } else { + this.onWindowUnmaximize(); + } + } else if (this.statusType === window.WindowStatusType.MAXIMIZE) { + this.onWindowUnmaximize(); + } else if (this.statusType === window.WindowStatusType.MINIMIZE) { + this.onWindowRestore(); + } + } + } +} diff --git a/ohos/src/main/ets/components/plugin/WindowManagerPlusPlugin.ets b/ohos/src/main/ets/components/plugin/WindowManagerPlusPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..59fa158a5e00da3eea6567e11522e9487121e6c8 --- /dev/null +++ b/ohos/src/main/ets/components/plugin/WindowManagerPlusPlugin.ets @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + FlutterPlugin, + FlutterPluginBinding, + MethodCall, + MethodCallHandler, + MethodChannel, + MethodResult, +} from '@ohos/flutter_ohos'; +import WindowManagerPlus from './WindowManagerPlus'; +import { window } from '@kit.ArkUI'; +import { bundleManager, common, Want } from '@kit.AbilityKit'; +import { WINDOW_NAME_KEY, INIT_ROUTE_KEY } from './MultiWindowAbility'; +import WindowStageManager from './WindowStageManager'; +import { getMethodArg } from './WindowManagerUtil'; + +/** WindowManagerPlusPlugin **/ +export default class WindowManagerPlusPlugin implements FlutterPlugin, MethodCallHandler { + private channelStatic: MethodChannel | null = null; + private channel: MethodChannel | null = null; + private static binding: FlutterPluginBinding; + + constructor() { + } + + getUniqueClassName(): string { + return "WindowManagerPlusPlugin" + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + WindowManagerPlusPlugin.binding = binding; + this.channelStatic = new MethodChannel(binding.getBinaryMessenger(), "window_manager_plus_static"); + this.channelStatic.setMethodCallHandler(this); + + this.channel = new MethodChannel(binding.getBinaryMessenger(), "window_manager_plus"); + this.channel.setMethodCallHandler(this); + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + if (this.channelStatic != null) { + this.channelStatic.setMethodCallHandler(null) + } + } + + /** + * 每个FlutterEngine初始化时会调用该方法 + * @param windowId + */ + public static ensureInitialized(windowId: number, window?: window.Window) { + console.log(`ensureInitialized :${windowId}`); + if (WindowManagerPlus.windowManagerPlusMap.hasKey(windowId)) { + console.log(`this window has init,winId=${windowId}`); + return; + } + if (!window) { + const stage: window.WindowStage | undefined = WindowStageManager.getState(windowId.toString()); + if (stage) { + window = stage.getMainWindowSync(); + } + } + const windowManager: WindowManagerPlus = WindowManagerPlusPlugin.createNewManager(windowId, window); + WindowManagerPlus.windowManagerPlusMap.set(windowId, windowManager); + } + + /** + * 回收窗口 + * @param windowId + */ + public static releaseWindowManager(windowId: number) { + console.log('releaseWindowManager:'+windowId); + if (WindowManagerPlus.windowManagerPlusMap.hasKey(windowId)) { + WindowStageManager.removeStage(windowId.toString()); + const windowManager: WindowManagerPlus = WindowManagerPlus.windowManagerPlusMap.get(windowId); + WindowManagerPlus.windowManagerPlusMap.remove(windowId); + windowManager.release(); + } + } + + public static createNewManager(windowId: number, window?: window.Window): WindowManagerPlus { + const windowManager: WindowManagerPlus = new WindowManagerPlus(); + windowManager.windowId = windowId; + windowManager.channel = + new MethodChannel(WindowManagerPlusPlugin.binding.getBinaryMessenger(), `window_manager_plus_${windowId}`); + windowManager.channel.setMethodCallHandler(windowManager); + if (windowId == 0) { + windowManager.windowClass = WindowManagerPlus.getAvailableWindow(); + } else if (window) { + windowManager.windowClass = window; + } + windowManager.onWindowInit(); + return windowManager; + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + switch (call.method) { + case "createWindow": + const newWindowId: number = WindowManagerPlus.createWindow([]); + let windowClass = WindowManagerPlus.getAvailableWindow(); + let context = windowClass?.getUIContext().getHostContext() as common.UIAbilityContext; + const want: Want = bundleManager.getLaunchWant(); + let record: Record | undefined = want.parameters; + if (!record) { + record = {}; + } + record[WINDOW_NAME_KEY] = newWindowId.toString(); + let defaultRoute:string = '/'; + //从入参的args字符数组中,找到"initRoute /xxx/aaa"字符串,作为新开窗口的初始路由 + const arg0: ESObject = getMethodArg(call, "args"); + if(arg0){ + const arr:Array = arg0 as Array; + for(let i=0;i = new Map(); + + static addStage(key: string, stage: window.WindowStage) { + WindowStateManager.stageMap.set(key, stage); + } + + static removeStage(key: string) { + WindowStateManager.stageMap.delete(key); + } + + static getAvailableStage(): window.WindowStage | undefined { + if (WindowStateManager.stageMap.size > 0) { + const keysArray = Array.from(WindowStateManager.stageMap.keys()); + const key: string = keysArray[0]; + return WindowStateManager.stageMap.get(key); + } + return undefined; + } + + static getState(key: string): window.WindowStage | undefined { + if (WindowStateManager.stageMap.has(key)) { + return WindowStateManager.stageMap.get(key); + } + return undefined; + } +} \ No newline at end of file diff --git a/ohos/src/main/module.json5 b/ohos/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3a7442e0848814375df04f6a0f343638d4d351a0 --- /dev/null +++ b/ohos/src/main/module.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "module": { + "name": "window_manager_plus", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/pubspec.lock b/pubspec.lock index e0c97aed1907e2eca831dafd663a1ed28f42028a..55e2bfee0b51d8df286857c7eb4ba1e5d5cd8d72 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,45 +5,40 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 - url: "https://pub.dev" + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.flutter-io.cn" source: hosted - version: "72.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.2" + version: "61.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 - url: "https://pub.dev" + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.flutter-io.cn" source: hosted - version: "6.7.0" + version: "5.13.0" args: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" - url: "https://pub.dev" + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.0" + version: "2.4.2" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.11.0" + version: "2.10.0" boolean_selector: dependency: transitive description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" build_config: @@ -51,23 +46,23 @@ packages: description: name: build_config sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.0" + version: "1.2.1" checked_yaml: dependency: transitive description: name: checked_yaml sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" clock: @@ -75,57 +70,57 @@ packages: description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.18.0" + version: "1.17.0" convert: dependency: transitive description: name: convert sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.1" crypto: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 - url: "https://pub.dev" + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.5" + version: "3.0.3" dependency_validator: dependency: "direct dev" description: name: dependency_validator - sha256: "81b5dc4cc34a1c05d2fa24aa8d658cb8f048ca23e63d5aaec420200190f1c4b0" - url: "https://pub.dev" + sha256: d27143159d8c2e83bf33e794e3e642c14fd888e2da8f512e6ad38bc854bbf3ec + url: "https://pub.flutter-io.cn" source: hosted - version: "4.1.1" + version: "4.1.2" fake_async: dependency: transitive description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.1" file: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.flutter-io.cn" source: hosted - version: "7.0.1" + version: "6.1.4" flutter: dependency: "direct main" description: flutter @@ -141,7 +136,7 @@ packages: description: name: glob sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" io: @@ -149,177 +144,98 @@ packages: description: name: io sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" - json_annotation: + js: dependency: transitive description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.9.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" - source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - lints: + version: "0.6.5" + json_annotation: dependency: transitive description: - name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" - url: "https://pub.dev" + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.0" + version: "4.8.1" logging: dependency: transitive description: name: logging sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" - macros: - dependency: transitive - description: - name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" - url: "https://pub.dev" - source: hosted - version: "0.1.2-main.4" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.16+1" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.11.1" + version: "0.2.0" meta: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - mostly_reasonable_lints: - dependency: "direct dev" - description: - name: mostly_reasonable_lints - sha256: e19fec63536866ba307b3dfbc258b4bce9b3745129f038006b56b4067c6293d8 - url: "https://pub.dev" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.2" + version: "1.8.0" package_config: dependency: transitive description: name: package_config sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0" path: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" + version: "1.8.2" pub_semver: dependency: transitive description: name: pub_semver sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 - url: "https://pub.dev" + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.0" + version: "1.2.3" screen_retriever: dependency: "direct main" description: - name: screen_retriever - sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_linux: - dependency: transitive - description: - name: screen_retriever_linux - sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_macos: - dependency: transitive - description: - name: screen_retriever_macos - sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_platform_interface: - dependency: transitive - description: - name: screen_retriever_platform_interface - sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - screen_retriever_windows: - dependency: transitive - description: - name: screen_retriever_windows - sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13" - url: "https://pub.dev" - source: hosted - version: "0.2.0" + path: "." + ref: "dev_v0.1.9" + resolved-ref: e90de0e1d743ffcd305789ecb5ac1bfa4cf6f7c9 + url: "https://gitee.com/openharmony-sig/fluttertpc_screen_retriever.git" + source: git + version: "0.1.9" sky_engine: dependency: transitive description: flutter @@ -329,32 +245,32 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" term_glyph: @@ -362,23 +278,23 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.2" + version: "0.4.16" typed_data: dependency: transitive description: name: typed_data sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.2" vector_math: @@ -386,33 +302,25 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" - source: hosted - version: "14.2.5" watcher: dependency: transitive description: name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" - url: "https://pub.dev" + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.0" + version: "1.0.2" yaml: dependency: transitive description: name: yaml sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.2" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=2.19.6 <3.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 46f11b97d5bc892a14fcd5420acb1b565bcc3526..7bdfca366fdca5a78262fd24c24b51e7b7aa94b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,7 @@ platforms: #linux: macos: windows: + ohos: topics: - window - window-resize @@ -18,20 +19,22 @@ topics: - desktop environment: - sdk: ">=3.0.0 <4.0.0" + sdk: ">=2.19.6 <4.0.0" flutter: ">=3.3.0" dependencies: flutter: sdk: flutter path: ^1.8.0 - screen_retriever: ^0.2.0 + screen_retriever: + git: + url: https://gitee.com/openharmony-sig/fluttertpc_screen_retriever.git + ref: dev_v0.1.9 dev_dependencies: dependency_validator: ^4.1.1 flutter_test: sdk: flutter - mostly_reasonable_lints: ^0.1.2 flutter: plugin: @@ -42,3 +45,5 @@ flutter: pluginClass: WindowManagerPlusPlugin windows: pluginClass: WindowManagerPlusPlugin + ohos: + pluginClass: WindowManagerPlusPlugin