From ad1377354194ba315f53f41ffa1e4e0571b469d7 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 24 Oct 2025 18:16:33 +0900 Subject: [PATCH 1/7] Introduce tizen_window_manager plugin --- packages/tizen_window_manager/.gitignore | 75 +++++++ packages/tizen_window_manager/CHANGELOG.md | 3 + packages/tizen_window_manager/LICENSE | 25 +++ packages/tizen_window_manager/README.md | 54 +++++ .../tizen_window_manager/example/.gitignore | 46 ++++ .../tizen_window_manager/example/README.md | 7 + .../example/lib/main.dart | 199 ++++++++++++++++++ .../tizen_window_manager/example/pubspec.yaml | 16 ++ .../example/tizen/.gitignore | 12 ++ .../tizen_window_manager/example/tizen/App.cs | 24 +++ .../example/tizen/Runner.csproj | 19 ++ .../example/tizen/shared/res/ic_launcher.png | Bin 0 -> 1443 bytes .../example/tizen/tizen-manifest.xml | 10 + .../lib/tizen_window_manager.dart | 35 +++ packages/tizen_window_manager/pubspec.yaml | 20 ++ .../tizen_window_manager/tizen/.gitignore | 5 + .../tizen/inc/tizen_window_manager_plugin.h | 27 +++ .../tizen/project_def.prop | 20 ++ .../tizen/src/ecore_wl2_window_proxy.cc | 79 +++++++ .../tizen/src/ecore_wl2_window_proxy.h | 22 ++ packages/tizen_window_manager/tizen/src/log.h | 28 +++ .../tizen/src/tizen_window_manager.cc | 58 +++++ .../tizen/src/tizen_window_manager.h | 29 +++ .../tizen/src/tizen_window_manager_plugin.cc | 88 ++++++++ 24 files changed, 901 insertions(+) create mode 100644 packages/tizen_window_manager/.gitignore create mode 100644 packages/tizen_window_manager/CHANGELOG.md create mode 100644 packages/tizen_window_manager/LICENSE create mode 100644 packages/tizen_window_manager/README.md create mode 100644 packages/tizen_window_manager/example/.gitignore create mode 100644 packages/tizen_window_manager/example/README.md create mode 100644 packages/tizen_window_manager/example/lib/main.dart create mode 100644 packages/tizen_window_manager/example/pubspec.yaml create mode 100644 packages/tizen_window_manager/example/tizen/.gitignore create mode 100644 packages/tizen_window_manager/example/tizen/App.cs create mode 100644 packages/tizen_window_manager/example/tizen/Runner.csproj create mode 100644 packages/tizen_window_manager/example/tizen/shared/res/ic_launcher.png create mode 100644 packages/tizen_window_manager/example/tizen/tizen-manifest.xml create mode 100644 packages/tizen_window_manager/lib/tizen_window_manager.dart create mode 100644 packages/tizen_window_manager/pubspec.yaml create mode 100644 packages/tizen_window_manager/tizen/.gitignore create mode 100644 packages/tizen_window_manager/tizen/inc/tizen_window_manager_plugin.h create mode 100644 packages/tizen_window_manager/tizen/project_def.prop create mode 100644 packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.cc create mode 100644 packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.h create mode 100644 packages/tizen_window_manager/tizen/src/log.h create mode 100644 packages/tizen_window_manager/tizen/src/tizen_window_manager.cc create mode 100644 packages/tizen_window_manager/tizen/src/tizen_window_manager.h create mode 100644 packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc diff --git a/packages/tizen_window_manager/.gitignore b/packages/tizen_window_manager/.gitignore new file mode 100644 index 000000000..a247422ef --- /dev/null +++ b/packages/tizen_window_manager/.gitignore @@ -0,0 +1,75 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 diff --git a/packages/tizen_window_manager/CHANGELOG.md b/packages/tizen_window_manager/CHANGELOG.md new file mode 100644 index 000000000..607323422 --- /dev/null +++ b/packages/tizen_window_manager/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +* Initial release. diff --git a/packages/tizen_window_manager/LICENSE b/packages/tizen_window_manager/LICENSE new file mode 100644 index 000000000..b8fc05698 --- /dev/null +++ b/packages/tizen_window_manager/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/tizen_window_manager/README.md b/packages/tizen_window_manager/README.md new file mode 100644 index 000000000..21bf9afd6 --- /dev/null +++ b/packages/tizen_window_manager/README.md @@ -0,0 +1,54 @@ +# tizen_window_manager + + [![pub package](https://img.shields.io/pub/v/tizen_window_manager.svg)](https://pub.dev/packages/tizen_window_manager) + +Tizen window manager APIs. Used to control windows and get window geometry information. + +## Usage + +To use this package, add `tizen_window_manager` as a dependency in your `pubspec.yaml` file. + +```yaml +dependencies: + tizen_window_manager: ^0.1.0 +``` + +> [!NOTE] +> This plugin only works when the [RendererType](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L110) is [EGL](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L24). Calling this plugin's API when the RendererType is [EvasGL](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L20) will cause the app to crash. + +## API Reference + +The `TizenWindowManagerPlugin` class provides methods to control window behavior on the Tizen platform. + +### Controls windows + +Activates the window and brings it to the foreground. + +```dart +final windowManager = TizenWindowManagerPlugin(); +await windowManager.activate(); +``` + +Lowers the window and sends it to the background. + +```dart +final windowManager = TizenWindowManagerPlugin(); +await windowManager.lower(); +``` + +### Retrieving window geometry + +Gets the geometry(position and size) of the window. + +Returns a `Map` containing: +- `x`: The x coordinate of the window +- `y`: The y coordinate of the window +- `width`: The width of the window +- `height`: The height of the window + +```dart +final windowManager = TizenWindowManagerPlugin(); +Map geometry = await windowManager.getGeometry(); +print('Window position: (${geometry['x']}, ${geometry['y']})'); +print('Window size: ${geometry['width']}x${geometry['height']}'); +``` diff --git a/packages/tizen_window_manager/example/.gitignore b/packages/tizen_window_manager/example/.gitignore new file mode 100644 index 000000000..0fa6b675c --- /dev/null +++ b/packages/tizen_window_manager/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/tizen_window_manager/example/README.md b/packages/tizen_window_manager/example/README.md new file mode 100644 index 000000000..9183c8ee3 --- /dev/null +++ b/packages/tizen_window_manager/example/README.md @@ -0,0 +1,7 @@ +# tizen_window_manager_example + +Demonstrates how to use the tizen_window_manager plugin. + +## Getting Started + +To run this app on your Tizen device, use [flutter-tizen](https://github.com/flutter-tizen/flutter-tizen). diff --git a/packages/tizen_window_manager/example/lib/main.dart b/packages/tizen_window_manager/example/lib/main.dart new file mode 100644 index 000000000..a8a51f313 --- /dev/null +++ b/packages/tizen_window_manager/example/lib/main.dart @@ -0,0 +1,199 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:tizen_window_manager/tizen_window_manager.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({super.key}); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + final TizenWindowManagerPlugin _tizenWindowManagerPlugin = + TizenWindowManagerPlugin(); + + Map? _geometry; + bool _isLoadingGeometry = false; + + Timer? _windowTimer; + + void _activateWindow() { + final AppLifecycleState currentLifecycleState = + WidgetsBinding.instance.lifecycleState!; + if (currentLifecycleState != AppLifecycleState.resumed) { + _windowTimer?.cancel(); + _windowTimer = Timer.periodic(const Duration(milliseconds: 500), ( + Timer timer, + ) { + final AppLifecycleState? currentState = + WidgetsBinding.instance.lifecycleState; + if (currentState == AppLifecycleState.resumed) { + timer.cancel(); + _windowTimer = null; + } else { + debugPrint( + 'AppLifecycleState is still not resumed (current: $currentState), calling activate window again', + ); + _tizenWindowManagerPlugin.activate(); + } + }); + } else { + debugPrint( + 'AppLifecycleState is resumed, no need to start periodic calls'); + } + } + + void _lowerWindow() { + _tizenWindowManagerPlugin.lower(); + debugPrint('Window lowered successfully'); + } + + void _lowerWindowAndActivateWindow() { + _tizenWindowManagerPlugin.lower(); + debugPrint('Window lowered successfully'); + Future.delayed(const Duration(seconds: 3), () { + debugPrint('3 seconds passed, showing window again'); + _activateWindow(); + }); + } + + Future _getGeometry() async { + setState(() { + _isLoadingGeometry = true; + }); + + try { + final Map geometry = + await _tizenWindowManagerPlugin.getGeometry(); + debugPrint('Window geometry: $geometry'); + debugPrint('Position: (${geometry['x']}, ${geometry['y']})'); + debugPrint('Size: ${geometry['width']} x ${geometry['height']}'); + + setState(() { + _geometry = geometry; + _isLoadingGeometry = false; + }); + } catch (e) { + debugPrint('Error getting geometry: $e'); + setState(() { + _isLoadingGeometry = false; + }); + } + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Tizen Window Manager Example'), + backgroundColor: Colors.blue, + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 20), + const Text( + 'Tizen Window Manager API Test', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 20), + const Text( + 'Window Control', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 10), + ElevatedButton( + onPressed: _lowerWindow, + child: const Text('Call lower window.'), + ), + const SizedBox(height: 10), + ElevatedButton( + onPressed: _lowerWindowAndActivateWindow, + child: const Text( + 'Call lower window and call activate window 3 seconds later.'), + ), + const SizedBox(height: 10), + const Text( + 'Window Information', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 10), + if (_geometry != null) ...[ + Container( + padding: const EdgeInsets.all(16.0), + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: BorderRadius.circular(8.0), + border: Border.all(color: Colors.grey[300]!), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Window Geometry:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 8), + Text( + 'Position: (${_geometry!['x']}, ${_geometry!['y']})', + style: const TextStyle(fontSize: 14), + ), + const SizedBox(height: 4), + Text( + 'Size: ${_geometry!['width']} x ${_geometry!['height']}', + style: const TextStyle(fontSize: 14), + ), + ], + ), + ), + ], + const SizedBox(height: 10), + ElevatedButton( + onPressed: _getGeometry, + child: _isLoadingGeometry + ? const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: + AlwaysStoppedAnimation(Colors.white), + ), + ) + : const Text('Get Window Geometry'), + ), + ], + ), + ), + ), + ); + } +} diff --git a/packages/tizen_window_manager/example/pubspec.yaml b/packages/tizen_window_manager/example/pubspec.yaml new file mode 100644 index 000000000..c12e7ce33 --- /dev/null +++ b/packages/tizen_window_manager/example/pubspec.yaml @@ -0,0 +1,16 @@ +name: tizen_window_manager_example +description: Demonstrates how to use the tizen_window_manager plugin. +publish_to: "none" + +environment: + sdk: ">=3.1.0 <4.0.0" + flutter: ">=3.13.0" + +dependencies: + flutter: + sdk: flutter + tizen_window_manager: + path: ../ + +flutter: + uses-material-design: true diff --git a/packages/tizen_window_manager/example/tizen/.gitignore b/packages/tizen_window_manager/example/tizen/.gitignore new file mode 100644 index 000000000..ac0738be2 --- /dev/null +++ b/packages/tizen_window_manager/example/tizen/.gitignore @@ -0,0 +1,12 @@ +flutter/ +.vs/ +*.user +bin/ +obj/ + +# Tizen Core CLI (tz) related files +tizen_dotnet_project.yaml +*.csproj.backup + +# Flutter-tizen dependency information file +.app.deps.json diff --git a/packages/tizen_window_manager/example/tizen/App.cs b/packages/tizen_window_manager/example/tizen/App.cs new file mode 100644 index 000000000..e9ca12765 --- /dev/null +++ b/packages/tizen_window_manager/example/tizen/App.cs @@ -0,0 +1,24 @@ +using Tizen.Flutter.Embedding; + +namespace Runner +{ + public class App : FlutterApplication + { + protected override void OnCreate() + { + WindowOffsetX = 100; + WindowOffsetY = 100; + WindowHeight = 700; + WindowWidth = 1000; + base.OnCreate(); + + GeneratedPluginRegistrant.RegisterPlugins(this); + } + + static void Main(string[] args) + { + var app = new App(); + app.Run(args); + } + } +} diff --git a/packages/tizen_window_manager/example/tizen/Runner.csproj b/packages/tizen_window_manager/example/tizen/Runner.csproj new file mode 100644 index 000000000..da93051cc --- /dev/null +++ b/packages/tizen_window_manager/example/tizen/Runner.csproj @@ -0,0 +1,19 @@ + + + + Exe + tizen80 + + + + + + + + + + %(RecursiveDir) + + + + diff --git a/packages/tizen_window_manager/example/tizen/shared/res/ic_launcher.png b/packages/tizen_window_manager/example/tizen/shared/res/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/packages/tizen_window_manager/example/tizen/tizen-manifest.xml b/packages/tizen_window_manager/example/tizen/tizen-manifest.xml new file mode 100644 index 000000000..585404a6c --- /dev/null +++ b/packages/tizen_window_manager/example/tizen/tizen-manifest.xml @@ -0,0 +1,10 @@ + + + + + + ic_launcher.png + + + + diff --git a/packages/tizen_window_manager/lib/tizen_window_manager.dart b/packages/tizen_window_manager/lib/tizen_window_manager.dart new file mode 100644 index 000000000..f5dc6ba76 --- /dev/null +++ b/packages/tizen_window_manager/lib/tizen_window_manager.dart @@ -0,0 +1,35 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; + +/// A plugin for managing windows on Tizen platform. +/// +/// This plugin provides methods to control window behavior such as +/// activating, raising, lowering, showing, hiding, and getting window geometry. +class TizenWindowManagerPlugin { + final MethodChannel _channel = const MethodChannel('tizen/window_manager'); + + /// Activates the window. + Future activate() => _channel.invokeMethod('activate'); + + /// Lowers the window. + Future lower() => _channel.invokeMethod('lower'); + + /// Gets the geometry (position and size) of the window. + /// + /// Returns a map containing: + /// - 'x': The x coordinate of the window + /// - 'y': The y coordinate of the window + /// - 'width': The width of the window + /// - 'height': The height of the window + Future> getGeometry() async { + final dynamic result = await _channel.invokeMethod('getGeometry'); + if (result is Map) { + return Map.from(result); + } + throw Exception( + 'Unexpected result type from getGeometry: ${result.runtimeType}'); + } +} diff --git a/packages/tizen_window_manager/pubspec.yaml b/packages/tizen_window_manager/pubspec.yaml new file mode 100644 index 000000000..ed12f4ca5 --- /dev/null +++ b/packages/tizen_window_manager/pubspec.yaml @@ -0,0 +1,20 @@ +name: tizen_window_manager +description: Tizen window APIs. +homepage: https://github.com/flutter-tizen/plugins +repository: https://github.com/flutter-tizen/plugins/tree/master/packages/tizen_window_manager +version: 0.2.0 + +environment: + sdk: ">=3.1.0 <4.0.0" + flutter: ">=3.13.0" + +dependencies: + flutter: + sdk: flutter + +flutter: + plugin: + platforms: + tizen: + pluginClass: TizenWindowManagerPlugin + fileName: tizen_window_manager_plugin.h diff --git a/packages/tizen_window_manager/tizen/.gitignore b/packages/tizen_window_manager/tizen/.gitignore new file mode 100644 index 000000000..a2a7d62b1 --- /dev/null +++ b/packages/tizen_window_manager/tizen/.gitignore @@ -0,0 +1,5 @@ +.cproject +.sign +crash-info/ +Debug/ +Release/ diff --git a/packages/tizen_window_manager/tizen/inc/tizen_window_manager_plugin.h b/packages/tizen_window_manager/tizen/inc/tizen_window_manager_plugin.h new file mode 100644 index 000000000..1615c8ae3 --- /dev/null +++ b/packages/tizen_window_manager/tizen/inc/tizen_window_manager_plugin.h @@ -0,0 +1,27 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_PLUGIN_H_ +#define FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_PLUGIN_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void TizenWindowManagerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_PLUGIN_H_ diff --git a/packages/tizen_window_manager/tizen/project_def.prop b/packages/tizen_window_manager/tizen/project_def.prop new file mode 100644 index 000000000..5e44bab53 --- /dev/null +++ b/packages/tizen_window_manager/tizen/project_def.prop @@ -0,0 +1,20 @@ +# See https://docs.tizen.org/application/tizen-studio/native-tools/project-conversion +# for details. + +APPNAME = tizen_window_manager_plugin +type = staticLib +profile = common-5.5 + +# Source files +USER_SRCS += src/*.cc + +# User defines +USER_DEFS = +USER_UNDEFS = +USER_CPP_DEFS = FLUTTER_PLUGIN_IMPL +USER_CPP_UNDEFS = + +# User includes +USER_INC_DIRS = inc src +USER_INC_FILES = +USER_CPP_INC_FILES = diff --git a/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.cc b/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.cc new file mode 100644 index 000000000..f35fe75c1 --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.cc @@ -0,0 +1,79 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ecore_wl2_window_proxy.h" + +#include + +#include "log.h" + +typedef void (*FuncEcoreWl2WindowGeometryGet)(void *window, int *x, int *y, + int *width, int *height); +typedef void (*FuncEcoreWl2WindowActivate)(void *window); +typedef void (*FuncEcoreWl2WindowRaise)(void *window); +typedef void (*FuncEcoreWl2WindowLower)(void *window); + +EcoreWl2WindowProxy::EcoreWl2WindowProxy() { + ecore_wl2_window_handle_ = dlopen("libecore_wl2.so.1", RTLD_LAZY); + if (ecore_wl2_window_handle_ == nullptr) { + LOG_ERROR("Failed to open ecore wl2."); + } +} + +EcoreWl2WindowProxy::~EcoreWl2WindowProxy() { + if (ecore_wl2_window_handle_) { + dlclose(ecore_wl2_window_handle_); + ecore_wl2_window_handle_ = nullptr; + } +} + +void EcoreWl2WindowProxy::ecore_wl2_window_geometry_get(void *window, int *x, + int *y, int *width, + int *height) { + if (!ecore_wl2_window_handle_) { + LOG_ERROR("ecore_wl2_window_handle_ not valid"); + return; + } + + FuncEcoreWl2WindowGeometryGet ecore_wl2_window_geometry_get = + reinterpret_cast( + dlsym(ecore_wl2_window_handle_, "ecore_wl2_window_geometry_get")); + if (!ecore_wl2_window_geometry_get) { + LOG_ERROR("Fail to find ecore_wl2_window_geometry_get."); + return; + } + ecore_wl2_window_geometry_get(window, x, y, width, height); +} + +void EcoreWl2WindowProxy::ecore_wl2_window_activate(void *window) { + if (!ecore_wl2_window_handle_) { + LOG_ERROR("ecore_wl2_window_handle_ not valid"); + return; + } + + FuncEcoreWl2WindowActivate ecore_wl2_window_activate = + reinterpret_cast( + dlsym(ecore_wl2_window_handle_, "ecore_wl2_window_activate")); + if (!ecore_wl2_window_activate) { + LOG_ERROR("Fail to find ecore_wl2_window_activate."); + return; + } + ecore_wl2_window_activate(window); +} + +void EcoreWl2WindowProxy::ecore_wl2_window_lower(void *window) { + if (!ecore_wl2_window_handle_) { + LOG_ERROR("ecore_wl2_window_handle_ not valid"); + return; + } + + FuncEcoreWl2WindowLower ecore_wl2_window_lower = + reinterpret_cast( + dlsym(ecore_wl2_window_handle_, "ecore_wl2_window_lower")); + if (!ecore_wl2_window_lower) { + LOG_ERROR("Fail to find ecore_wl2_window_lower."); + return; + } + ecore_wl2_window_lower(window); +} diff --git a/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.h b/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.h new file mode 100644 index 000000000..0eed95ebf --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/ecore_wl2_window_proxy.h @@ -0,0 +1,22 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ +#define FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ + +class EcoreWl2WindowProxy { + public: + EcoreWl2WindowProxy(); + ~EcoreWl2WindowProxy(); + void ecore_wl2_window_geometry_get(void *window, int *x, int *y, int *width, + int *height); + + void ecore_wl2_window_activate(void *window); + void ecore_wl2_window_lower(void *window); + + private: + void *ecore_wl2_window_handle_ = nullptr; +}; + +#endif // FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ diff --git a/packages/tizen_window_manager/tizen/src/log.h b/packages/tizen_window_manager/tizen/src/log.h new file mode 100644 index 000000000..6e7002473 --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/log.h @@ -0,0 +1,28 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TizenWindowManagerPlugin" + +#ifndef __MODULE__ +#define __MODULE__ strrchr("/" __FILE__, '/') + 1 +#endif + +#define LOG(prio, fmt, arg...) \ + dlog_print(prio, LOG_TAG, "%s: %s(%d) > " fmt, __MODULE__, __func__, \ + __LINE__, ##arg) + +#define LOG_DEBUG(fmt, args...) LOG(DLOG_DEBUG, fmt, ##args) +#define LOG_INFO(fmt, args...) LOG(DLOG_INFO, fmt, ##args) +#define LOG_WARN(fmt, args...) LOG(DLOG_WARN, fmt, ##args) +#define LOG_ERROR(fmt, args...) LOG(DLOG_ERROR, fmt, ##args) + +#endif // __LOG_H__ diff --git a/packages/tizen_window_manager/tizen/src/tizen_window_manager.cc b/packages/tizen_window_manager/tizen/src/tizen_window_manager.cc new file mode 100644 index 000000000..d4ed5b57a --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/tizen_window_manager.cc @@ -0,0 +1,58 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tizen_window_manager.h" + +#include +#include + +#include + +#include "ecore_wl2_window_proxy.h" +#include "log.h" + +TizenWindowManager::TizenWindowManager(void* handle) + : window_handle_(handle), proxy_(std::make_unique()) {} + +TizenWindowManager::~TizenWindowManager() {} + +void TizenWindowManager::Activate() { + if (!window_handle_) { + LOG_ERROR("Window handle is null"); + } + + proxy_->ecore_wl2_window_activate(window_handle_); +} + +void TizenWindowManager::Lower() { + if (!window_handle_) { + LOG_ERROR("Window handle is null"); + } + + proxy_->ecore_wl2_window_lower(window_handle_); +} + +flutter::EncodableMap TizenWindowManager::GetGeometry() { + flutter::EncodableMap geometry; + + if (!window_handle_) { + LOG_ERROR("Window handle is null"); + geometry[flutter::EncodableValue("x")] = flutter::EncodableValue(0); + geometry[flutter::EncodableValue("y")] = flutter::EncodableValue(0); + geometry[flutter::EncodableValue("width")] = flutter::EncodableValue(0); + geometry[flutter::EncodableValue("height")] = flutter::EncodableValue(0); + return geometry; + } + + int x, y, width, height; + proxy_->ecore_wl2_window_geometry_get(window_handle_, &x, &y, &width, + &height); + + geometry[flutter::EncodableValue("x")] = flutter::EncodableValue(x); + geometry[flutter::EncodableValue("y")] = flutter::EncodableValue(y); + geometry[flutter::EncodableValue("width")] = flutter::EncodableValue(width); + geometry[flutter::EncodableValue("height")] = flutter::EncodableValue(height); + + return geometry; +} diff --git a/packages/tizen_window_manager/tizen/src/tizen_window_manager.h b/packages/tizen_window_manager/tizen/src/tizen_window_manager.h new file mode 100644 index 000000000..0f3475eea --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/tizen_window_manager.h @@ -0,0 +1,29 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_H_ +#define FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_H_ + +#include +#include + +#include + +class EcoreWl2WindowProxy; + +class TizenWindowManager { + public: + explicit TizenWindowManager(void* handle); + virtual ~TizenWindowManager(); + + void Activate(); + void Lower(); + flutter::EncodableMap GetGeometry(); + + private: + void* window_handle_; + std::unique_ptr proxy_; +}; + +#endif // FLUTTER_PLUGIN_TIZEN_WINDOW_MANAGER_H_ diff --git a/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc b/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc new file mode 100644 index 000000000..1ad23ad31 --- /dev/null +++ b/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc @@ -0,0 +1,88 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tizen_window_manager_plugin.h" + +#include +#include +#include +#include + +#include + +#include "log.h" +#include "tizen_window_manager.h" + +namespace { + +class TizenWindowManagerPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar_ref, + flutter::PluginRegistrar *plugin_registrar) { + auto channel = + std::make_unique>( + plugin_registrar->messenger(), "tizen/window_manager", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(registrar_ref); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + plugin_registrar->AddPlugin(std::move(plugin)); + } + + TizenWindowManagerPlugin(FlutterDesktopPluginRegistrarRef registrar_ref) + : registrar_ref_(registrar_ref) { + FlutterDesktopViewRef flutter_view = + FlutterDesktopPluginRegistrarGetView(registrar_ref_); + void *handle = FlutterDesktopViewGetNativeHandle(flutter_view); + if (!handle) { + LOG_ERROR("Fail to get native window handle."); + return; + } + window_manager_ = std::make_unique(handle); + } + + virtual ~TizenWindowManagerPlugin() {} + + private: + void HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result) { + const auto &method_name = method_call.method_name(); + + if (!window_manager_) { + result->Error("No window handle."); + return; + } + + if (method_name == "activate") { + window_manager_->Activate(); + result->Success(); + } else if (method_name == "lower") { + window_manager_->Lower(); + result->Success(); + } else if (method_name == "getGeometry") { + result->Success(flutter::EncodableValue(window_manager_->GetGeometry())); + } else { + result->NotImplemented(); + } + } + + FlutterDesktopPluginRegistrarRef registrar_ref_; + std::unique_ptr window_manager_ = nullptr; +}; + +} // namespace + +void TizenWindowManagerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + TizenWindowManagerPlugin::RegisterWithRegistrar( + registrar, flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} From 0f0a2eba0b9a5765786be0801956b733c1a23e30 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 27 Oct 2025 15:54:58 +0900 Subject: [PATCH 2/7] Fix typo --- packages/tizen_window_manager/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tizen_window_manager/pubspec.yaml b/packages/tizen_window_manager/pubspec.yaml index ed12f4ca5..e75043d9d 100644 --- a/packages/tizen_window_manager/pubspec.yaml +++ b/packages/tizen_window_manager/pubspec.yaml @@ -2,7 +2,7 @@ name: tizen_window_manager description: Tizen window APIs. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/tizen_window_manager -version: 0.2.0 +version: 0.1.0 environment: sdk: ">=3.1.0 <4.0.0" From 48832be391dff97cc504a1b8ab18a360af7db71b Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 27 Oct 2025 16:40:18 +0900 Subject: [PATCH 3/7] Add integration_test --- .github/recipe.yaml | 1 + packages/tizen_window_manager/README.md | 11 +++---- .../tizen_window_manager_test.dart | 32 +++++++++++++++++++ .../example/lib/main.dart | 12 +++---- .../tizen_window_manager/example/pubspec.yaml | 10 ++++++ .../example/test_driver/integration_test.dart | 3 ++ .../lib/tizen_window_manager.dart | 12 ++++--- 7 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 packages/tizen_window_manager/example/integration_test/tizen_window_manager_test.dart create mode 100644 packages/tizen_window_manager/example/test_driver/integration_test.dart diff --git a/.github/recipe.yaml b/.github/recipe.yaml index 2cd04c327..236687241 100644 --- a/.github/recipe.yaml +++ b/.github/recipe.yaml @@ -15,6 +15,7 @@ plugins: tizen_bundle: ["tv-9.0"] tizen_package_manager: ["tv-9.0"] tizen_rpc_port: ["tv-9.0"] + tizen_window_manager: ["tv-9.0"] url_launcher: ["tv-9.0"] wakelock_plus: ["tv-9.0"] diff --git a/packages/tizen_window_manager/README.md b/packages/tizen_window_manager/README.md index 21bf9afd6..b796b2141 100644 --- a/packages/tizen_window_manager/README.md +++ b/packages/tizen_window_manager/README.md @@ -18,22 +18,20 @@ dependencies: ## API Reference -The `TizenWindowManagerPlugin` class provides methods to control window behavior on the Tizen platform. +The `WindowManager` class provides methods to control window behavior on the Tizen platform. ### Controls windows Activates the window and brings it to the foreground. ```dart -final windowManager = TizenWindowManagerPlugin(); -await windowManager.activate(); +await WindowManager.activate(); ``` Lowers the window and sends it to the background. ```dart -final windowManager = TizenWindowManagerPlugin(); -await windowManager.lower(); +await WindowManager.lower(); ``` ### Retrieving window geometry @@ -47,8 +45,7 @@ Returns a `Map` containing: - `height`: The height of the window ```dart -final windowManager = TizenWindowManagerPlugin(); -Map geometry = await windowManager.getGeometry(); +Map geometry = await WindowManager.getGeometry(); print('Window position: (${geometry['x']}, ${geometry['y']})'); print('Window size: ${geometry['width']}x${geometry['height']}'); ``` diff --git a/packages/tizen_window_manager/example/integration_test/tizen_window_manager_test.dart b/packages/tizen_window_manager/example/integration_test/tizen_window_manager_test.dart new file mode 100644 index 000000000..0b9fd1ddf --- /dev/null +++ b/packages/tizen_window_manager/example/integration_test/tizen_window_manager_test.dart @@ -0,0 +1,32 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:tizen_window_manager/tizen_window_manager.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Can get window geometry info', (WidgetTester tester) async { + final Map geometry = await WindowManager.getGeometry(); + expect(geometry['x'], 100); + expect(geometry['y'], 100); + expect(geometry['width'], 1000); + expect(geometry['height'], 700); + }); + + testWidgets('Control lower/activate window', (WidgetTester tester) async { + await WindowManager.lower(); + await Future.delayed(const Duration(seconds: 2)); + + expect(WidgetsBinding.instance.lifecycleState, AppLifecycleState.paused); + + await WindowManager.activate(); + await Future.delayed(const Duration(seconds: 2)); + + expect(WidgetsBinding.instance.lifecycleState, AppLifecycleState.resumed); + }); +} diff --git a/packages/tizen_window_manager/example/lib/main.dart b/packages/tizen_window_manager/example/lib/main.dart index a8a51f313..4ffd3f0df 100644 --- a/packages/tizen_window_manager/example/lib/main.dart +++ b/packages/tizen_window_manager/example/lib/main.dart @@ -21,9 +21,6 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - final TizenWindowManagerPlugin _tizenWindowManagerPlugin = - TizenWindowManagerPlugin(); - Map? _geometry; bool _isLoadingGeometry = false; @@ -46,7 +43,7 @@ class _MyAppState extends State { debugPrint( 'AppLifecycleState is still not resumed (current: $currentState), calling activate window again', ); - _tizenWindowManagerPlugin.activate(); + WindowManager.activate(); } }); } else { @@ -56,12 +53,12 @@ class _MyAppState extends State { } void _lowerWindow() { - _tizenWindowManagerPlugin.lower(); + WindowManager.lower(); debugPrint('Window lowered successfully'); } void _lowerWindowAndActivateWindow() { - _tizenWindowManagerPlugin.lower(); + WindowManager.lower(); debugPrint('Window lowered successfully'); Future.delayed(const Duration(seconds: 3), () { debugPrint('3 seconds passed, showing window again'); @@ -75,8 +72,7 @@ class _MyAppState extends State { }); try { - final Map geometry = - await _tizenWindowManagerPlugin.getGeometry(); + final Map geometry = await WindowManager.getGeometry(); debugPrint('Window geometry: $geometry'); debugPrint('Position: (${geometry['x']}, ${geometry['y']})'); debugPrint('Size: ${geometry['width']} x ${geometry['height']}'); diff --git a/packages/tizen_window_manager/example/pubspec.yaml b/packages/tizen_window_manager/example/pubspec.yaml index c12e7ce33..2198f7604 100644 --- a/packages/tizen_window_manager/example/pubspec.yaml +++ b/packages/tizen_window_manager/example/pubspec.yaml @@ -12,5 +12,15 @@ dependencies: tizen_window_manager: path: ../ +dev_dependencies: + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + integration_test_tizen: + path: ../../integration_test/ + flutter: uses-material-design: true diff --git a/packages/tizen_window_manager/example/test_driver/integration_test.dart b/packages/tizen_window_manager/example/test_driver/integration_test.dart new file mode 100644 index 000000000..b38629cca --- /dev/null +++ b/packages/tizen_window_manager/example/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/packages/tizen_window_manager/lib/tizen_window_manager.dart b/packages/tizen_window_manager/lib/tizen_window_manager.dart index f5dc6ba76..c66343506 100644 --- a/packages/tizen_window_manager/lib/tizen_window_manager.dart +++ b/packages/tizen_window_manager/lib/tizen_window_manager.dart @@ -8,14 +8,16 @@ import 'package:flutter/services.dart'; /// /// This plugin provides methods to control window behavior such as /// activating, raising, lowering, showing, hiding, and getting window geometry. -class TizenWindowManagerPlugin { - final MethodChannel _channel = const MethodChannel('tizen/window_manager'); +class WindowManager { + WindowManager._(); + + static const MethodChannel _channel = MethodChannel('tizen/window_manager'); /// Activates the window. - Future activate() => _channel.invokeMethod('activate'); + static Future activate() => _channel.invokeMethod('activate'); /// Lowers the window. - Future lower() => _channel.invokeMethod('lower'); + static Future lower() => _channel.invokeMethod('lower'); /// Gets the geometry (position and size) of the window. /// @@ -24,7 +26,7 @@ class TizenWindowManagerPlugin { /// - 'y': The y coordinate of the window /// - 'width': The width of the window /// - 'height': The height of the window - Future> getGeometry() async { + static Future> getGeometry() async { final dynamic result = await _channel.invokeMethod('getGeometry'); if (result is Map) { return Map.from(result); From 8e3bcfc234f7a174b8be4ccc723d870a43c0af6e Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 27 Oct 2025 17:03:53 +0900 Subject: [PATCH 4/7] Add readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d3af10f02..21b96012d 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ The _"non-endorsed"_ status means that the plugin is not endorsed by the origina | [**tizen_notification**](packages/tizen_notification) | (Tizen-only) | [![pub package](https://img.shields.io/pub/v/tizen_notification.svg)](https://pub.dev/packages/tizen_notification) | N/A | | [**tizen_package_manager**](packages/tizen_package_manager) | (Tizen-only) | [![pub package](https://img.shields.io/pub/v/tizen_package_manager.svg)](https://pub.dev/packages/tizen_package_manager) | N/A | | [**tizen_rpc_port**](packages/tizen_rpc_port) | (Tizen-only) | [![pub package](https://img.shields.io/pub/v/tizen_rpc_port.svg)](https://pub.dev/packages/tizen_rpc_port) | N/A | +| [**tizen_window_manager**](packages/tizen_window_manager) | (Tizen-only) | [![pub package](https://img.shields.io/pub/v/tizen_window_manager.svg)](https://pub.dev/packages/tizen_window_manager) | N/A | | [**url_launcher_tizen**](packages/url_launcher) | [url_launcher](https://pub.dev/packages/url_launcher) (1st-party) | [![pub package](https://img.shields.io/pub/v/url_launcher_tizen.svg)](https://pub.dev/packages/url_launcher_tizen) | No | | [**video_player_avplay**](packages/video_player_avplay) | (Tizen-only) | [![pub package](https://img.shields.io/pub/v/video_player_avplay.svg)](https://pub.dev/packages/video_player_avplay) | N/A | | [**video_player_tizen**](packages/video_player) | [video_player](https://pub.dev/packages/video_player) (1st-party) | [![pub package](https://img.shields.io/pub/v/video_player_tizen.svg)](https://pub.dev/packages/video_player_tizen) | No | @@ -91,6 +92,7 @@ The _"non-endorsed"_ status means that the plugin is not endorsed by the origina | [**tizen_notification**](packages/tizen_notification) | ✔️ | ✔️ | ❌ | API not supported | | [**tizen_package_manager**](packages/tizen_package_manager) | ✔️ | ✔️ | ✔️ | | [**tizen_rpc_port**](packages/tizen_rpc_port) | ✔️ | ✔️ | ✔️ | +| [**tizen_window_manager**](packages/tizen_window_manager) | ✔️ | ✔️ | ✔️ | | [**url_launcher_tizen**](packages/url_launcher) | ✔️ | ❌ | ❌ | No browser app | | [**video_player_avplay**](packages/video_player_avplay) | ✔️ | ❌ | ❌ | See README for details | | [**video_player_tizen**](packages/video_player) | ✔️ | ❌ | ✔️ | TV emulator issue | From 7a3d6dea13ce9ca7c8c99e4409f9612a523b1137 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 29 Oct 2025 10:40:56 +0900 Subject: [PATCH 5/7] Add labeler --- .github/labeler.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index d4b5dba42..4eba0868c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -63,6 +63,8 @@ - packages/tizen_package_manager/**/* "p: tizen_rpc_port": - packages/tizen_rpc_port/**/* +"p: tizen_window_manager": + - packages/tizen_window_manager/**/* "p: url_launcher": - packages/url_launcher/**/* "p: video_player": From 1ddeefe55b57269cc6738ef4d45a656ab0460014 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 29 Oct 2025 16:14:52 +0900 Subject: [PATCH 6/7] Remove unnecessary note --- packages/tizen_window_manager/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/tizen_window_manager/README.md b/packages/tizen_window_manager/README.md index b796b2141..cf6324b13 100644 --- a/packages/tizen_window_manager/README.md +++ b/packages/tizen_window_manager/README.md @@ -13,9 +13,6 @@ dependencies: tizen_window_manager: ^0.1.0 ``` -> [!NOTE] -> This plugin only works when the [RendererType](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L110) is [EGL](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L24). Calling this plugin's API when the RendererType is [EvasGL](https://github.com/flutter-tizen/flutter-tizen/blob/master/embedding/csharp/Tizen.Flutter.Embedding/FlutterApplication.cs#L20) will cause the app to crash. - ## API Reference The `WindowManager` class provides methods to control window behavior on the Tizen platform. From 785e21aa69225799652a563e5e7d16060aa766b1 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 29 Oct 2025 20:02:05 +0900 Subject: [PATCH 7/7] Apply review comments --- packages/tizen_window_manager/LICENSE | 2 +- .../tizen/src/tizen_window_manager_plugin.cc | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/tizen_window_manager/LICENSE b/packages/tizen_window_manager/LICENSE index b8fc05698..9b10b19e9 100644 --- a/packages/tizen_window_manager/LICENSE +++ b/packages/tizen_window_manager/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2025 Samsung Electronics Co., Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc b/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc index 1ad23ad31..4ba8c98e1 100644 --- a/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc +++ b/packages/tizen_window_manager/tizen/src/tizen_window_manager_plugin.cc @@ -36,10 +36,9 @@ class TizenWindowManagerPlugin : public flutter::Plugin { plugin_registrar->AddPlugin(std::move(plugin)); } - TizenWindowManagerPlugin(FlutterDesktopPluginRegistrarRef registrar_ref) - : registrar_ref_(registrar_ref) { + TizenWindowManagerPlugin(FlutterDesktopPluginRegistrarRef registrar_ref) { FlutterDesktopViewRef flutter_view = - FlutterDesktopPluginRegistrarGetView(registrar_ref_); + FlutterDesktopPluginRegistrarGetView(registrar_ref); void *handle = FlutterDesktopViewGetNativeHandle(flutter_view); if (!handle) { LOG_ERROR("Fail to get native window handle."); @@ -74,7 +73,6 @@ class TizenWindowManagerPlugin : public flutter::Plugin { } } - FlutterDesktopPluginRegistrarRef registrar_ref_; std::unique_ptr window_manager_ = nullptr; };