From 8a4f8e202db9a3a6a28abe87285dad66ae54ce03 Mon Sep 17 00:00:00 2001
From: Kingtous <kingtous@qq.com>
Date: Tue, 29 Nov 2022 23:03:16 +0800
Subject: [PATCH] opt: ui & cursor

- opt: win7 frameless
- opt: disable cursor output & macos free cache
- opt: main window, set location before show/hide
---
 flutter/lib/common.dart                       | 26 ++++++++++++++++++-
 flutter/lib/consts.dart                       | 19 ++++++++++++++
 .../lib/desktop/pages/desktop_home_page.dart  | 10 -------
 flutter/lib/main.dart                         | 18 +++++++++++--
 flutter/lib/models/native_model.dart          |  1 +
 flutter/lib/utils/multi_window_manager.dart   |  5 ++--
 flutter/pubspec.yaml                          |  4 +--
 7 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index 60936cfdf..4e6c8ab14 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -6,7 +6,7 @@ import 'dart:typed_data';
 
 import 'package:back_button_interceptor/back_button_interceptor.dart';
 import 'package:desktop_multi_window/desktop_multi_window.dart';
-import 'package:flutter/foundation.dart';
+import 'package:device_info_plus/device_info_plus.dart';
 import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -42,6 +42,8 @@ var isWeb = false;
 var isWebDesktop = false;
 var version = "";
 int androidVersion = 0;
+/// only avaliable for Windows target
+int windowsBuildNumber = 0;
 DesktopType? desktopType;
 
 /// * debug or test only, DO NOT enable in release build
@@ -1410,3 +1412,25 @@ Timer periodic_immediate(Duration duration, Future<void> Function() callback) {
     await callback();
   });
 }
+/// return a human readable windows version
+WindowsTarget getWindowsTarget(int buildNumber) {
+  if (!Platform.isWindows) {
+    return WindowsTarget.naw;
+  } 
+  if (buildNumber >= 22000) {
+    return WindowsTarget.w11;
+  } else if (buildNumber >= 10240) {
+    return WindowsTarget.w10;
+  } else if (buildNumber >= 9600) {
+    return WindowsTarget.w8_1;
+  } else if (buildNumber >= 9200) {
+    return WindowsTarget.w8;
+  } else if (buildNumber >= 7601) {
+    return WindowsTarget.w7;
+  } else if (buildNumber >= 6002) {
+    return WindowsTarget.vista;
+  } else {
+    // minimum support
+    return WindowsTarget.xp;
+  }
+}
diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart
index ae0d334e2..b0099ca7c 100644
--- a/flutter/lib/consts.dart
+++ b/flutter/lib/consts.dart
@@ -1,6 +1,8 @@
 import 'package:flutter/material.dart';
 import 'dart:io';
 
+import 'package:flutter_hbb/common.dart';
+
 const double kDesktopRemoteTabBarHeight = 28.0;
 
 /// [kAppTypeMain] used by 'Desktop Main Page' , 'Mobile (Client and Server)' , 'Desktop CM Page', "Install Page"
@@ -324,3 +326,20 @@ const Map<int, String> physicalKeyMap = <int, String>{
   0x000c019e: 'LOCK_SCREEN',
   0x000c0208: 'VK_PRINT',
 };
+
+/// The windows targets in the publish time order.
+enum WindowsTarget {
+  naw, // not a windows target
+  xp,
+  vista,
+  w7,
+  w8,
+  w8_1,
+  w10,
+  w11
+}
+
+/// A convenient method to transform a build number to the corresponding windows version.
+extension WindowsTargetExt on int {
+  WindowsTarget get windowsVersion => getWindowsTarget(this);
+}
diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart
index 712563a56..53f4d4d90 100644
--- a/flutter/lib/desktop/pages/desktop_home_page.dart
+++ b/flutter/lib/desktop/pages/desktop_home_page.dart
@@ -496,16 +496,6 @@ class _DesktopHomePageState extends State<DesktopHomePage>
     // initTray();
     trayManager.addListener(this);
     rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged);
-    // main window may be hidden because of the initial uni link or arguments.
-    // note that we must wrap this active window registration in future because
-    // we must ensure the execution is after `windowManager.hide/show()`.
-    Future.delayed(Duration.zero, () {
-      windowManager.isVisible().then((visibility) {
-        if (visibility) {
-          rustDeskWinManager.registerActiveWindow(kWindowMainId);
-        }
-      });
-    });
 
     rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
       debugPrint(
diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart
index 8af2a477f..08095e54c 100644
--- a/flutter/lib/main.dart
+++ b/flutter/lib/main.dart
@@ -118,17 +118,20 @@ void runMainApp(bool startService) async {
     gFFI.serverModel.startService();
   }
   runApp(App());
+  // restore the location of the main window before window hide or show
+  await restoreWindowPosition(WindowType.Main);
   // check the startup argument, if we successfully handle the argument, we keep the main window hidden.
   if (checkArguments()) {
     windowManager.hide();
   } else {
     windowManager.show();
     windowManager.focus();
+    // move registration of active main window here to prevent async visible check.
+    rustDeskWinManager.registerActiveWindow(kWindowMainId);
   }
   // set window option
   WindowOptions windowOptions = getHiddenTitleBarWindowOptions();
   windowManager.waitUntilReadyToShow(windowOptions, () async {
-    restoreWindowPosition(WindowType.Main);
     windowManager.setOpacity(1);
   });
 }
@@ -173,6 +176,11 @@ void runMultiWindow(
     widget,
     MyTheme.currentThemeMode(),
   );
+  // we do not hide titlebar on win7 because of the frame overflow.
+  if (Platform.isWindows &&
+      const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion)) {
+    WindowController.fromWindowId(windowId!).showTitleBar(true);
+  }
   switch (appType) {
     case kAppTypeDesktopRemote:
       await restoreWindowPosition(WindowType.RemoteDesktop,
@@ -273,12 +281,18 @@ void runInstallPage() async {
 }
 
 WindowOptions getHiddenTitleBarWindowOptions({Size? size}) {
+  var defaultTitleBarStyle = TitleBarStyle.hidden;
+  // we do not hide titlebar on win7 because of the frame overflow.
+  if (Platform.isWindows &&
+      const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion)) {
+    defaultTitleBarStyle = TitleBarStyle.normal;
+  }
   return WindowOptions(
     size: size,
     center: false,
     backgroundColor: Colors.transparent,
     skipTaskbar: false,
-    titleBarStyle: TitleBarStyle.hidden,
+    titleBarStyle: defaultTitleBarStyle,
   );
 }
 
diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart
index d29e0fd2c..0fa023e53 100644
--- a/flutter/lib/models/native_model.dart
+++ b/flutter/lib/models/native_model.dart
@@ -145,6 +145,7 @@ class PlatformFFI {
           WindowsDeviceInfo winInfo = await deviceInfo.windowsInfo;
           name = winInfo.computerName;
           id = winInfo.computerName;
+          windowsBuildNumber = winInfo.buildNumber;
         } catch (e) {
           debugPrint("$e");
           name = "unknown";
diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart
index 34367fece..91cb9a08a 100644
--- a/flutter/lib/utils/multi_window_manager.dart
+++ b/flutter/lib/utils/multi_window_manager.dart
@@ -202,9 +202,8 @@ class RustDeskMultiWindowManager {
       // ignore
     } else {
       _activeWindows.add(windowId);
-      _notifyActiveWindow();
     }
-    
+    _notifyActiveWindow();
   }
 
   /// Remove active window which has [`windowId`]
@@ -218,8 +217,8 @@ class RustDeskMultiWindowManager {
       // ignore
     } else {
       _activeWindows.remove(windowId);
-      _notifyActiveWindow();
     }
+    _notifyActiveWindow();
   }
 
   void registerActiveWindowListener(VoidCallback callback) {
diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml
index cb3ce5fc9..f84cbedcd 100644
--- a/flutter/pubspec.yaml
+++ b/flutter/pubspec.yaml
@@ -36,7 +36,7 @@ dependencies:
     provider: ^6.0.3
     tuple: ^2.0.0
     wakelock: ^0.6.2
-    device_info_plus: ^4.1.2
+    device_info_plus: ^8.0.0
     #firebase_analytics: ^9.1.5
     package_info_plus: ^1.4.2
     url_launcher: ^6.0.9
@@ -72,7 +72,7 @@ dependencies:
     flutter_custom_cursor:
         git:
             url: https://github.com/Kingtous/rustdesk_flutter_custom_cursor
-            ref: bfb19c84a8244771488bc05cc5f9c9b5e0324cfd
+            ref: 74b1b314142b6775c1243067a3503ac568ebc74b
     window_size:
         git:
             url: https://github.com/google/flutter-desktop-embedding.git