diff --git a/lib/main.dart b/lib/main.dart index 0983a784..1f6aa707 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,6 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -17,7 +16,7 @@ import 'package:island/firebase_options.dart'; import 'package:island/pods/config.dart'; import 'package:island/pods/network.dart'; import 'package:island/pods/theme.dart'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; + import 'package:island/pods/userinfo.dart'; import 'package:island/pods/websocket.dart'; import 'package:island/route.dart'; @@ -30,6 +29,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:window_manager/window_manager.dart'; @pragma('vm:entry-point') Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { @@ -89,31 +89,39 @@ void main() async { final prefs = await SharedPreferences.getInstance(); if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) { - doWhenWindowReady(() { - const defaultSize = Size(360, 640); + await windowManager.ensureInitialized(); - // Get saved window size from preferences - final savedSizeString = prefs.getString(kAppWindowSize); - Size initialSize = defaultSize; + const defaultSize = Size(360, 640); - if (savedSizeString != null) { - try { - final parts = savedSizeString.split(','); - if (parts.length == 2) { - final width = double.parse(parts[0]); - final height = double.parse(parts[1]); - initialSize = Size(width, height); - } - } catch (e) { - log("[SplashScreen] Failed to parse saved window size: $e"); - initialSize = defaultSize; + // Get saved window size from preferences + final savedSizeString = prefs.getString(kAppWindowSize); + Size initialSize = defaultSize; + + if (savedSizeString != null) { + try { + final parts = savedSizeString.split(','); + if (parts.length == 2) { + final width = double.parse(parts[0]); + final height = double.parse(parts[1]); + initialSize = Size(width, height); } + } catch (e) { + log("[SplashScreen] Failed to parse saved window size: $e"); + initialSize = defaultSize; } + } - appWindow.minSize = defaultSize; - appWindow.size = initialSize; - appWindow.alignment = Alignment.center; - appWindow.show(); + WindowOptions windowOptions = WindowOptions( + size: initialSize, + center: true, + backgroundColor: Colors.transparent, + skipTaskbar: false, + titleBarStyle: TitleBarStyle.hidden, + ); + windowManager.waitUntilReadyToShow(windowOptions, () async { + await windowManager.setMinimumSize(defaultSize); + await windowManager.show(); + await windowManager.focus(); log( "[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}", ); diff --git a/lib/screens/tray_manager.dart b/lib/screens/tray_manager.dart index 5f03e40b..0bd076ce 100644 --- a/lib/screens/tray_manager.dart +++ b/lib/screens/tray_manager.dart @@ -1,8 +1,7 @@ import 'dart:io'; - -import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:flutter/foundation.dart'; import 'package:tray_manager/tray_manager.dart'; +import 'package:window_manager/window_manager.dart'; class TrayService { TrayService._(); @@ -48,15 +47,10 @@ class TrayService { void handleAction(MenuItem item) { switch (item.key) { case 'show_window': - () async { - appWindow.show(); - appWindow.restore(); - await Future.delayed(const Duration(milliseconds: 32)); - appWindow.show(); - }(); + windowManager.show(); break; case 'exit_app': - appWindow.close(); + windowManager.destroy(); break; } } diff --git a/lib/widgets/app_scaffold.dart b/lib/widgets/app_scaffold.dart index 05e78ffa..c46660b5 100644 --- a/lib/widgets/app_scaffold.dart +++ b/lib/widgets/app_scaffold.dart @@ -1,6 +1,5 @@ import 'dart:io'; import 'dart:ui'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -15,6 +14,7 @@ import 'package:island/services/responsive.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:path_provider/path_provider.dart'; import 'package:styled_widget/styled_widget.dart'; +import 'package:window_manager/window_manager.dart'; class AppScrollBehavior extends MaterialScrollBehavior { @override @@ -36,11 +36,12 @@ class WindowScaffold extends HookConsumerWidget { if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) { void saveWindowSize() { - final size = appWindow.size; - final settingsNotifier = ref.read( - appSettingsNotifierProvider.notifier, - ); - settingsNotifier.setWindowSize(size); + windowManager.getBounds().then((bounds) { + final settingsNotifier = ref.read( + appSettingsNotifierProvider.notifier, + ); + settingsNotifier.setWindowSize(bounds.size); + }); } // Save window size when app is about to close @@ -61,13 +62,6 @@ class WindowScaffold extends HookConsumerWidget { if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) { final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; - final windowButtonColor = WindowButtonColors( - iconNormal: Theme.of(context).colorScheme.primary, - mouseOver: Theme.of(context).colorScheme.primaryContainer, - mouseDown: Theme.of(context).colorScheme.onPrimaryContainer, - iconMouseOver: Theme.of(context).colorScheme.primary, - iconMouseDown: Theme.of(context).colorScheme.primary, - ); return Material( child: Stack( @@ -75,44 +69,66 @@ class WindowScaffold extends HookConsumerWidget { children: [ Column( children: [ - WindowTitleBarBox( - child: Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 1 / devicePixelRatio, - ), + Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 1 / devicePixelRatio, ), ), - child: MoveWindow( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - Platform.isMacOS - ? MainAxisAlignment.center - : MainAxisAlignment.start, - children: [ - Expanded( - child: Text( - 'Solar Network', - textAlign: - Platform.isMacOS - ? TextAlign.center - : TextAlign.start, - ).padding(horizontal: 12, vertical: 5), + ), + child: DragToMoveArea( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: + Platform.isMacOS + ? MainAxisAlignment.center + : MainAxisAlignment.start, + children: [ + Expanded( + child: Text( + 'Solar Network', + textAlign: + Platform.isMacOS + ? TextAlign.center + : TextAlign.start, + ).padding(horizontal: 12, vertical: 5), + ), + if (!Platform.isMacOS) + IconButton( + icon: Icon(Symbols.minimize), + onPressed: () => windowManager.minimize(), + iconSize: 16, + padding: EdgeInsets.all(8), + constraints: BoxConstraints(), + color: Theme.of(context).iconTheme.color, ), - if (!Platform.isMacOS) - MinimizeWindowButton(colors: windowButtonColor), - if (!Platform.isMacOS) - MaximizeWindowButton(colors: windowButtonColor), - if (!Platform.isMacOS) - CloseWindowButton( - colors: windowButtonColor, - onPressed: () => appWindow.hide(), - ), - ], - ), + if (!Platform.isMacOS) + IconButton( + icon: Icon(Symbols.maximize), + onPressed: () async { + if (await windowManager.isMaximized()) { + windowManager.restore(); + } else { + windowManager.maximize(); + } + }, + iconSize: 16, + padding: EdgeInsets.all(8), + constraints: BoxConstraints(), + color: Theme.of(context).iconTheme.color, + ), + if (!Platform.isMacOS) + IconButton( + icon: Icon(Symbols.close), + onPressed: () => windowManager.close(), + iconSize: 16, + padding: EdgeInsets.all(8), + constraints: BoxConstraints(), + color: Theme.of(context).iconTheme.color, + ), + ], ), ), ), diff --git a/lib/widgets/app_wrapper.dart b/lib/widgets/app_wrapper.dart index 0fb5a802..a2965823 100644 --- a/lib/widgets/app_wrapper.dart +++ b/lib/widgets/app_wrapper.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -12,6 +11,7 @@ import 'package:island/services/update_service.dart'; import 'package:island/widgets/content/network_status_sheet.dart'; import 'package:island/widgets/tour/tour.dart'; import 'package:tray_manager/tray_manager.dart'; +import 'package:window_manager/window_manager.dart'; class AppWrapper extends HookConsumerWidget with TrayListener { final Widget child; @@ -67,11 +67,7 @@ class AppWrapper extends HookConsumerWidget with TrayListener { } void _trayIconPrimaryAction() { - if (appWindow.isVisible) { - appWindow.restore(); - } else { - appWindow.show(); - } + windowManager.show(); } void _trayIconSecondaryAction() { diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e2cb05c4..d0550359 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,7 +6,6 @@ #include "generated_plugin_registrant.h" -#include #include #include #include @@ -20,16 +19,15 @@ #include #include #include +#include #include #include #include #include #include +#include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin"); - bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar); g_autoptr(FlPluginRegistrar) file_saver_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin"); file_saver_plugin_register_with_registrar(file_saver_registrar); @@ -69,6 +67,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) record_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin"); record_linux_plugin_register_with_registrar(record_linux_registrar); + g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin"); + screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar); g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar); @@ -84,4 +85,7 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) volume_controller_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "VolumeControllerPlugin"); volume_controller_plugin_register_with_registrar(volume_controller_registrar); + g_autoptr(FlPluginRegistrar) window_manager_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); + window_manager_plugin_register_with_registrar(window_manager_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 400c4236..fe4cdeb5 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - bitsdojo_window_linux file_saver file_selector_linux flutter_platform_alert @@ -17,11 +16,13 @@ list(APPEND FLUTTER_PLUGIN_LIST media_kit_video pasteboard record_linux + screen_retriever_linux sqlite3_flutter_libs super_native_extensions tray_manager url_launcher_linux volume_controller + window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index bc5ed6a0..96cf76b6 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,7 +5,6 @@ import FlutterMacOS import Foundation -import bitsdojo_window_macos import connectivity_plus import device_info_plus import file_picker @@ -32,6 +31,7 @@ import package_info_plus import pasteboard import path_provider_foundation import record_macos +import screen_retriever_macos import share_plus import shared_preferences_foundation import sign_in_with_apple @@ -42,9 +42,9 @@ import tray_manager import url_launcher_macos import volume_controller import wakelock_plus +import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) @@ -71,6 +71,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin")) + ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin")) @@ -81,4 +82,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) + WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 80933cd0..b9ceafac 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,6 +1,4 @@ PODS: - - bitsdojo_window_macos (0.0.1): - - FlutterMacOS - connectivity_plus (0.0.1): - FlutterMacOS - croppy (0.0.1): @@ -202,6 +200,8 @@ PODS: - record_macos (1.1.0): - FlutterMacOS - SAMKeychain (1.5.3) + - screen_retriever_macos (0.0.1): + - FlutterMacOS - share_plus (0.0.1): - FlutterMacOS - shared_preferences_foundation (0.0.1): @@ -248,9 +248,10 @@ PODS: - wakelock_plus (0.0.1): - FlutterMacOS - WebRTC-SDK (137.7151.04) + - window_manager (0.5.0): + - FlutterMacOS DEPENDENCIES: - - bitsdojo_window_macos (from `Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos`) - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) - croppy (from `Flutter/ephemeral/.symlinks/plugins/croppy/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) @@ -279,6 +280,7 @@ DEPENDENCIES: - pasteboard (from `Flutter/ephemeral/.symlinks/plugins/pasteboard/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - record_macos (from `Flutter/ephemeral/.symlinks/plugins/record_macos/macos`) + - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - sign_in_with_apple (from `Flutter/ephemeral/.symlinks/plugins/sign_in_with_apple/macos`) @@ -289,6 +291,7 @@ DEPENDENCIES: - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - volume_controller (from `Flutter/ephemeral/.symlinks/plugins/volume_controller/macos`) - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) + - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) SPEC REPOS: trunk: @@ -314,8 +317,6 @@ SPEC REPOS: - WebRTC-SDK EXTERNAL SOURCES: - bitsdojo_window_macos: - :path: Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos connectivity_plus: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos croppy: @@ -372,6 +373,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin record_macos: :path: Flutter/ephemeral/.symlinks/plugins/record_macos/macos + screen_retriever_macos: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos shared_preferences_foundation: @@ -392,9 +395,10 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/volume_controller/macos wakelock_plus: :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos + window_manager: + :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: - bitsdojo_window_macos: 7959fb0ca65a3ccda30095c181ecb856fae48ea9 connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e croppy: d9bfc8c02f3cd1851f669a421df298a474b78f43 device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 @@ -441,6 +445,7 @@ SPEC CHECKSUMS: PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 record_macos: 43194b6c06ca6f8fa132e2acea72b202b92a0f5b SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c + screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 sign_in_with_apple: 6673c03c9e3643f6c8d33601943fbfa9ae99f94e @@ -453,6 +458,7 @@ SPEC CHECKSUMS: volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e + window_manager: b729e31d38fb04905235df9ea896128991cad99e PODFILE CHECKSUM: 346bfb2deb41d4a6ebd6f6799f92188bde2d246f diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index b3c17614..0c358c9e 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -4,10 +4,25 @@ import FlutterMacOS @main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true + return false } override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } + + override func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) + -> Bool + { + if !flag { + for window in NSApp.windows { + if !window.isVisible { + window.setIsVisible(true) + } + window.makeKeyAndOrderFront(self) + NSApp.activate(ignoringOtherApps: true) + } + } + return true + } } diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index b8e380c0..a2e2d608 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -1,12 +1,7 @@ import Cocoa import FlutterMacOS -import bitsdojo_window_macos - -class MainFlutterWindow: BitsdojoWindow { - override func bitsdojo_window_configure() -> UInt { - return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP - } +class MainFlutterWindow: NSWindow { override func awakeFromNib() { let flutterViewController = FlutterViewController() let windowFrame = self.frame @@ -17,4 +12,4 @@ class MainFlutterWindow: BitsdojoWindow { super.awakeFromNib() } -} +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index cf1127b3..5a0c557f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -81,46 +81,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - bitsdojo_window: - dependency: "direct main" - description: - name: bitsdojo_window - sha256: "88ef7765dafe52d97d7a3684960fb5d003e3151e662c18645c1641c22b873195" - url: "https://pub.dev" - source: hosted - version: "0.1.6" - bitsdojo_window_linux: - dependency: transitive - description: - name: bitsdojo_window_linux - sha256: "9519c0614f98be733e0b1b7cb15b827007886f6fe36a4fb62cf3d35b9dd578ab" - url: "https://pub.dev" - source: hosted - version: "0.1.4" - bitsdojo_window_macos: - dependency: transitive - description: - name: bitsdojo_window_macos - sha256: f7c5be82e74568c68c5b8449e2c5d8fd12ec195ecd70745a7b9c0f802bb0268f - url: "https://pub.dev" - source: hosted - version: "0.1.4" - bitsdojo_window_platform_interface: - dependency: transitive - description: - name: bitsdojo_window_platform_interface - sha256: "65daa015a0c6dba749bdd35a0f092e7a8ba8b0766aa0480eb3ef808086f6e27c" - url: "https://pub.dev" - source: hosted - version: "0.1.2" - bitsdojo_window_windows: - dependency: transitive - description: - name: bitsdojo_window_windows - sha256: fa982cf61ede53f483e50b257344a1c250af231a3cdc93a7064dd6dc0d720b68 - url: "https://pub.dev" - source: hosted - version: "0.1.6" boolean_selector: dependency: transitive description: @@ -2125,6 +2085,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + 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" screenshot: dependency: "direct main" description: @@ -2796,6 +2796,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + window_manager: + dependency: "direct main" + description: + name: window_manager + sha256: "7eb6d6c4164ec08e1bf978d6e733f3cebe792e2a23fb07cbca25c2872bfdbdcd" + url: "https://pub.dev" + source: hosted + version: "0.5.1" windows_notification: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 64654296..5653cdf3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,6 @@ dependencies: cupertino_icons: ^1.0.8 flutter_hooks: ^0.21.3+1 hooks_riverpod: ^2.6.1 - bitsdojo_window: ^0.1.6 go_router: ^16.2.4 styled_widget: ^0.4.1 shared_preferences: ^2.5.3 @@ -153,6 +152,7 @@ dependencies: ffi: ^2.1.4 dart_ipc: ^1.0.1 pretty_diff_text: ^2.1.0 + window_manager: ^0.5.1 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 65268343..1ca28477 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,7 +6,6 @@ #include "generated_plugin_registrant.h" -#include #include #include #include @@ -26,17 +25,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { - BitsdojoWindowPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DartIpcPluginCApiRegisterWithRegistrar( @@ -75,6 +74,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("PasteboardPlugin")); RecordWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("RecordWindowsPluginCApi")); + ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi")); SharePlusWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); Sqlite3FlutterLibsPluginRegisterWithRegistrar( @@ -87,6 +88,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("UrlLauncherWindows")); VolumeControllerPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("VolumeControllerPluginCApi")); + WindowManagerPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("WindowManagerPlugin")); WindowsNotificationPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowsNotificationPluginCApi")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 332b7ad7..5908cff3 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - bitsdojo_window_windows connectivity_plus dart_ipc file_saver @@ -23,12 +22,14 @@ list(APPEND FLUTTER_PLUGIN_LIST media_kit_video pasteboard record_windows + screen_retriever_windows share_plus sqlite3_flutter_libs super_native_extensions tray_manager url_launcher_windows volume_controller + window_manager windows_notification ) diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index f2872cdd..9884be88 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -9,10 +9,20 @@ auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { + _In_ wchar_t *command_line, _In_ int show_command) +{ + HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"single_instance_example"); + if (hwnd != NULL) + { + ::ShowWindow(hwnd, SW_NORMAL); + ::SetForegroundWindow(hwnd); + return EXIT_FAILURE; + } + // Attach to console when present (e.g., 'flutter run') or create a // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) + { CreateAndAttachConsole(); } @@ -30,13 +40,15 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); - if (!window.Create(L"Solian", origin, size)) { + if (!window.Create(L"Solian", origin, size)) + { return EXIT_FAILURE; } window.SetQuitOnClose(true); ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { + while (::GetMessage(&msg, nullptr, 0, 0)) + { ::TranslateMessage(&msg); ::DispatchMessage(&msg); }