Merge pull request #3037 from Kingtous/master

fix: synchronize macOS window theme on flutter theme changed.
This commit is contained in:
RustDesk 2023-02-02 14:08:34 +08:00 committed by GitHub
commit 06204d446e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 5 deletions

View File

@ -9,6 +9,7 @@ import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_hbb/utils/platform_channel.dart';
import 'package:win32/win32.dart' as win32;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
@ -224,16 +225,18 @@ class MyTheme {
return themeModeFromString(bind.mainGetLocalOption(key: kCommConfKeyTheme));
}
static void changeDarkMode(ThemeMode mode) {
static void changeDarkMode(ThemeMode mode) async {
Get.changeThemeMode(mode);
if (desktopType == DesktopType.main) {
if (mode == ThemeMode.system) {
bind.mainSetLocalOption(key: kCommConfKeyTheme, value: '');
await bind.mainSetLocalOption(key: kCommConfKeyTheme, value: '');
} else {
bind.mainSetLocalOption(
await bind.mainSetLocalOption(
key: kCommConfKeyTheme, value: mode.toShortString());
}
bind.mainChangeTheme(dark: mode.toShortString());
await bind.mainChangeTheme(dark: mode.toShortString());
// Synchronize the window theme of the system.
updateSystemWindowTheme();
}
}
@ -1686,3 +1689,16 @@ String getWindowName({WindowType? overrideType}) {
String getWindowNameWithId(String id, {WindowType? overrideType}) {
return "${DesktopTab.labelGetterAlias(id).value} - ${getWindowName(overrideType: overrideType)}";
}
Future<void> updateSystemWindowTheme() async {
// Set system window theme for macOS.
final userPreference = MyTheme.getThemeModePreference();
if (userPreference != ThemeMode.system) {
if (Platform.isMacOS) {
await RdPlatformChannel.instance.changeSystemWindowTheme(
userPreference == ThemeMode.light
? SystemWindowTheme.light
: SystemWindowTheme.dark);
}
}
}

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/main.dart';
import 'package:get/get.dart';
class RefreshWrapper extends StatefulWidget {
final Widget Function(BuildContext context) builder;
const RefreshWrapper({super.key, required this.builder});
@override
@ -30,6 +32,8 @@ class RefreshWrapperState extends State<RefreshWrapper> {
if (Get.context != null) {
(context as Element).visitChildren(_rebuildElement);
}
// Synchronize the window theme of the system.
updateSystemWindowTheme();
setState(() {});
}

View File

@ -108,6 +108,8 @@ Future<void> initEnv(String appType) async {
await initGlobalFFI();
// await Firebase.initializeApp();
_registerEventHandler();
// Update the system theme.
updateSystemWindowTheme();
}
void runMainApp(bool startService) async {
@ -327,6 +329,8 @@ class _AppState extends State<App> {
to = ThemeMode.light;
}
Get.changeThemeMode(to);
// Synchronize the window theme of the system.
updateSystemWindowTheme();
if (desktopType == DesktopType.main) {
bind.mainChangeTheme(dark: to.toShortString());
}

View File

@ -0,0 +1,34 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/main.dart';
enum SystemWindowTheme { light, dark }
/// The platform channel for RustDesk.
class RdPlatformChannel {
RdPlatformChannel._();
static final RdPlatformChannel _windowUtil = RdPlatformChannel._();
static RdPlatformChannel get instance => _windowUtil;
final MethodChannel _osxMethodChannel =
MethodChannel("org.rustdesk.rustdesk/macos");
final MethodChannel _winMethodChannel =
MethodChannel("org.rustdesk.rustdesk/windows");
final MethodChannel _linuxMethodChannel =
MethodChannel("org.rustdesk.rustdesk/linux");
/// Change the theme of the system window
Future<void> changeSystemWindowTheme(SystemWindowTheme theme) {
assert(Platform.isMacOS);
if (kDebugMode) {
print(
"[Window ${kWindowId ?? 'Main'}] change system window theme to ${theme.name}");
}
return _osxMethodChannel
.invokeMethod("setWindowTheme", {"themeName": theme.name});
}
}

View File

@ -27,12 +27,16 @@ class MainFlutterWindow: NSWindow {
let windowFrame = self.frame
self.contentViewController = flutterViewController
self.setFrame(windowFrame, display: true)
// register self method handler
let registrar = flutterViewController.registrar(forPlugin: "RustDeskPlugin")
setMethodHandler(registrar: registrar)
RegisterGeneratedPlugins(registry: flutterViewController)
FlutterMultiWindowPlugin.setOnWindowCreatedCallback { controller in
// Register the plugin which you want access from other isolate.
// DesktopLifecyclePlugin.register(with: controller.registrar(forPlugin: "DesktopLifecyclePlugin"))
self.setMethodHandler(registrar: controller.registrar(forPlugin: "RustDeskPlugin"))
DesktopDropPlugin.register(with: controller.registrar(forPlugin: "DesktopDropPlugin"))
DeviceInfoPlusMacosPlugin.register(with: controller.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FlutterCustomCursorPlugin.register(with: controller.registrar(forPlugin: "FlutterCustomCursorPlugin"))
@ -53,4 +57,31 @@ class MainFlutterWindow: NSWindow {
super.order(place, relativeTo: otherWin)
hiddenWindowAtLaunch()
}
/// Override window theme.
public func setWindowInterfaceMode(window: NSWindow, themeName: String) {
window.appearance = NSAppearance(named: themeName == "light" ? .aqua : .darkAqua)
}
public func setMethodHandler(registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "org.rustdesk.rustdesk/macos", binaryMessenger: registrar.messenger)
channel.setMethodCallHandler({
(call, result) -> Void in
switch call.method {
case "setWindowTheme":
let arg = call.arguments as! [String: Any]
let themeName = arg["themeName"] as? String
guard let window = registrar.view?.window else {
result(nil)
return
}
self.setWindowInterfaceMode(window: window,themeName: themeName ?? "light")
result(nil)
break;
default:
result(FlutterMethodNotImplemented)
}
})
}
}

View File

@ -61,7 +61,7 @@ dependencies:
url: https://github.com/Kingtous/rustdesk_desktop_multi_window
ref: bc8604a88e52b2b6e64d2661ae49a71450a47af8
freezed_annotation: ^2.0.3
flutter_custom_cursor: ^0.0.2
flutter_custom_cursor: ^0.0.4
window_size:
git:
url: https://github.com/google/flutter-desktop-embedding.git