Merge pull request #2389 from Kingtous/master

opt: fix win7 crash on latest device_info_plus
This commit is contained in:
RustDesk 2022-11-30 14:44:45 +08:00 committed by GitHub
commit 44dd159a49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 73 deletions

View File

@ -1,12 +1,15 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:ffi' hide Size;
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:back_button_interceptor/back_button_interceptor.dart'; import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
import 'package:win32/win32.dart' as win32;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -42,6 +45,7 @@ var isWeb = false;
var isWebDesktop = false; var isWebDesktop = false;
var version = ""; var version = "";
int androidVersion = 0; int androidVersion = 0;
/// only avaliable for Windows target /// only avaliable for Windows target
int windowsBuildNumber = 0; int windowsBuildNumber = 0;
DesktopType? desktopType; DesktopType? desktopType;
@ -1412,11 +1416,12 @@ Timer periodic_immediate(Duration duration, Future<void> Function() callback) {
await callback(); await callback();
}); });
} }
/// return a human readable windows version /// return a human readable windows version
WindowsTarget getWindowsTarget(int buildNumber) { WindowsTarget getWindowsTarget(int buildNumber) {
if (!Platform.isWindows) { if (!Platform.isWindows) {
return WindowsTarget.naw; return WindowsTarget.naw;
} }
if (buildNumber >= 22000) { if (buildNumber >= 22000) {
return WindowsTarget.w11; return WindowsTarget.w11;
} else if (buildNumber >= 10240) { } else if (buildNumber >= 10240) {
@ -1434,3 +1439,47 @@ WindowsTarget getWindowsTarget(int buildNumber) {
return WindowsTarget.xp; return WindowsTarget.xp;
} }
} }
/// Get windows target build number.
///
/// [Note]
/// Please use this function wrapped with `Platform.isWindows`.
int getWindowsTargetBuildNumber() {
final rtlGetVersion = DynamicLibrary.open('ntdll.dll').lookupFunction<
Void Function(Pointer<win32.OSVERSIONINFOEX>),
void Function(Pointer<win32.OSVERSIONINFOEX>)>('RtlGetVersion');
final osVersionInfo = getOSVERSIONINFOEXPointer();
rtlGetVersion(osVersionInfo);
int buildNumber = osVersionInfo.ref.dwBuildNumber;
calloc.free(osVersionInfo);
return buildNumber;
}
/// Get Windows OS version pointer
///
/// [Note]
/// Please use this function wrapped with `Platform.isWindows`.
Pointer<win32.OSVERSIONINFOEX> getOSVERSIONINFOEXPointer() {
final pointer = calloc<win32.OSVERSIONINFOEX>();
pointer.ref
..dwOSVersionInfoSize = sizeOf<win32.OSVERSIONINFOEX>()
..dwBuildNumber = 0
..dwMajorVersion = 0
..dwMinorVersion = 0
..dwPlatformId = 0
..szCSDVersion = ''
..wServicePackMajor = 0
..wServicePackMinor = 0
..wSuiteMask = 0
..wProductType = 0
..wReserved = 0;
return pointer;
}
/// Indicating we need to use compatible ui mode.
///
/// [Conditions]
/// - Windows 7, window will overflow when we use frameless ui.
bool get kUseCompatibleUiMode =>
Platform.isWindows &&
const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion);

View File

@ -266,7 +266,8 @@ class DesktopTab extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column(children: [ return Column(children: [
Obx(() => Offstage( Obx(() => Offstage(
offstage: !stateGlobal.showTabBar.isTrue, offstage: !stateGlobal.showTabBar.isTrue ||
(kUseCompatibleUiMode && isHideSingleItem()),
child: SizedBox( child: SizedBox(
height: _kTabBarHeight, height: _kTabBarHeight,
child: Column( child: Column(
@ -335,6 +336,15 @@ class DesktopTab extends StatelessWidget {
.toList(growable: false)))); .toList(growable: false))));
} }
/// Check whether to show ListView
///
/// Conditions:
/// - hide single item when only has one item (home) on [DesktopTabPage].
bool isHideSingleItem() {
return state.value.tabs.length == 1 &&
controller.tabType == DesktopTabType.main;
}
Widget _buildBar() { Widget _buildBar() {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -362,23 +372,26 @@ class DesktopTab extends StatelessWidget {
child: const SizedBox( child: const SizedBox(
width: 78, width: 78,
)), )),
Row(children: [ Offstage(
Offstage( offstage: kUseCompatibleUiMode,
offstage: !showLogo, child: Row(children: [
child: SvgPicture.asset( Offstage(
'assets/logo.svg', offstage: !showLogo,
width: 16, child: SvgPicture.asset(
height: 16, 'assets/logo.svg',
)), width: 16,
Offstage( height: 16,
offstage: !showTitle, )),
child: const Text( Offstage(
"RustDesk", offstage: !showTitle,
style: TextStyle(fontSize: 13), child: const Text(
).marginOnly(left: 2)) "RustDesk",
]).marginOnly( style: TextStyle(fontSize: 13),
left: 5, ).marginOnly(left: 2))
right: 10, ]).marginOnly(
left: 5,
right: 10,
),
), ),
Expanded( Expanded(
child: Listener( child: Listener(
@ -407,6 +420,7 @@ class DesktopTab extends StatelessWidget {
unSelectedTabBackgroundColor))), unSelectedTabBackgroundColor))),
], ],
))), ))),
// hide simulated action buttons when we in compatible ui mode, because of reusing system title bar.
WindowActionPanel( WindowActionPanel(
isMainWindow: isMainWindow, isMainWindow: isMainWindow,
tabType: tabType, tabType: tabType,
@ -530,50 +544,59 @@ class WindowActionPanelState extends State<WindowActionPanel>
children: [ children: [
Offstage(offstage: widget.tail == null, child: widget.tail), Offstage(offstage: widget.tail == null, child: widget.tail),
Offstage( Offstage(
offstage: !widget.showMinimize, offstage: kUseCompatibleUiMode,
child: ActionIcon( child: Row(
message: 'Minimize', children: [
icon: IconFont.min, Offstage(
onTap: () { offstage: !widget.showMinimize,
if (widget.isMainWindow) { child: ActionIcon(
windowManager.minimize(); message: 'Minimize',
} else { icon: IconFont.min,
WindowController.fromWindowId(windowId!).minimize(); onTap: () {
} if (widget.isMainWindow) {
}, windowManager.minimize();
isClose: false, } else {
)), WindowController.fromWindowId(windowId!).minimize();
Offstage( }
offstage: !widget.showMaximize, },
child: Obx(() => ActionIcon( isClose: false,
message: widget.isMaximized.value ? "Restore" : "Maximize", )),
icon: widget.isMaximized.value Offstage(
? IconFont.restore offstage: !widget.showMaximize,
: IconFont.max, child: Obx(() => ActionIcon(
onTap: _toggleMaximize, message:
isClose: false, widget.isMaximized.value ? "Restore" : "Maximize",
))), icon: widget.isMaximized.value
Offstage( ? IconFont.restore
offstage: !widget.showClose, : IconFont.max,
child: ActionIcon( onTap: _toggleMaximize,
message: 'Close', isClose: false,
icon: IconFont.close, ))),
onTap: () async { Offstage(
final res = await widget.onClose?.call() ?? true; offstage: !widget.showClose,
if (res) { child: ActionIcon(
// hide for all window message: 'Close',
// note: the main window can be restored by tray icon icon: IconFont.close,
Future.delayed(Duration.zero, () async { onTap: () async {
if (widget.isMainWindow) { final res = await widget.onClose?.call() ?? true;
await windowManager.close(); if (res) {
} else { // hide for all window
await WindowController.fromWindowId(windowId!).close(); // note: the main window can be restored by tray icon
} Future.delayed(Duration.zero, () async {
}); if (widget.isMainWindow) {
} await windowManager.close();
}, } else {
isClose: true, await WindowController.fromWindowId(windowId!)
)), .close();
}
});
}
},
isClose: true,
))
],
),
),
], ],
); );
} }

View File

@ -177,8 +177,7 @@ void runMultiWindow(
MyTheme.currentThemeMode(), MyTheme.currentThemeMode(),
); );
// we do not hide titlebar on win7 because of the frame overflow. // we do not hide titlebar on win7 because of the frame overflow.
if (Platform.isWindows && if (kUseCompatibleUiMode) {
const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion)) {
WindowController.fromWindowId(windowId!).showTitleBar(true); WindowController.fromWindowId(windowId!).showTitleBar(true);
} }
switch (appType) { switch (appType) {
@ -283,8 +282,7 @@ void runInstallPage() async {
WindowOptions getHiddenTitleBarWindowOptions({Size? size}) { WindowOptions getHiddenTitleBarWindowOptions({Size? size}) {
var defaultTitleBarStyle = TitleBarStyle.hidden; var defaultTitleBarStyle = TitleBarStyle.hidden;
// we do not hide titlebar on win7 because of the frame overflow. // we do not hide titlebar on win7 because of the frame overflow.
if (Platform.isWindows && if (kUseCompatibleUiMode) {
const [WindowsTarget.w7].contains(windowsBuildNumber.windowsVersion)) {
defaultTitleBarStyle = TitleBarStyle.normal; defaultTitleBarStyle = TitleBarStyle.normal;
} }
return WindowOptions( return WindowOptions(

View File

@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:win32/win32.dart' as win32;
import '../common.dart'; import '../common.dart';
import '../generated_bridge.dart'; import '../generated_bridge.dart';
@ -131,7 +132,7 @@ class PlatformFFI {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
name = '${androidInfo.brand}-${androidInfo.model}'; name = '${androidInfo.brand}-${androidInfo.model}';
id = androidInfo.id.hashCode.toString(); id = androidInfo.id.hashCode.toString();
androidVersion = androidInfo.version.sdkInt; androidVersion = androidInfo.version.sdkInt ?? 0;
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo; IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
name = iosInfo.utsname.machine ?? ''; name = iosInfo.utsname.machine ?? '';
@ -142,12 +143,14 @@ class PlatformFFI {
id = linuxInfo.machineId ?? linuxInfo.id; id = linuxInfo.machineId ?? linuxInfo.id;
} else if (Platform.isWindows) { } else if (Platform.isWindows) {
try { try {
// request windows build number to fix overflow on win7
windowsBuildNumber = getWindowsTargetBuildNumber();
WindowsDeviceInfo winInfo = await deviceInfo.windowsInfo; WindowsDeviceInfo winInfo = await deviceInfo.windowsInfo;
name = winInfo.computerName; name = winInfo.computerName;
id = winInfo.computerName; id = winInfo.computerName;
windowsBuildNumber = winInfo.buildNumber; } catch (e, stacktrace) {
} catch (e) { debugPrint("get windows device info failed: $e");
debugPrint("$e"); debugPrintStack(stackTrace: stacktrace);
name = "unknown"; name = "unknown";
id = "unknown"; id = "unknown";
} }

View File

@ -36,7 +36,7 @@ dependencies:
provider: ^6.0.3 provider: ^6.0.3
tuple: ^2.0.0 tuple: ^2.0.0
wakelock: ^0.6.2 wakelock: ^0.6.2
device_info_plus: ^8.0.0 device_info_plus: ^4.1.2
#firebase_analytics: ^9.1.5 #firebase_analytics: ^9.1.5
package_info_plus: ^1.4.2 package_info_plus: ^1.4.2
url_launcher: ^6.0.9 url_launcher: ^6.0.9
@ -102,6 +102,8 @@ dependencies:
path: ^1.8.1 path: ^1.8.1
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
bot_toast: ^4.0.3 bot_toast: ^4.0.3
win32: any
dev_dependencies: dev_dependencies:
icons_launcher: ^2.0.4 icons_launcher: ^2.0.4