Merge pull request #3037 from Kingtous/master
fix: synchronize macOS window theme on flutter theme changed.
This commit is contained in:
commit
06204d446e
@ -9,6 +9,7 @@ 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:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_hbb/utils/platform_channel.dart';
|
||||||
import 'package:win32/win32.dart' as win32;
|
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';
|
||||||
@ -224,16 +225,18 @@ class MyTheme {
|
|||||||
return themeModeFromString(bind.mainGetLocalOption(key: kCommConfKeyTheme));
|
return themeModeFromString(bind.mainGetLocalOption(key: kCommConfKeyTheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void changeDarkMode(ThemeMode mode) {
|
static void changeDarkMode(ThemeMode mode) async {
|
||||||
Get.changeThemeMode(mode);
|
Get.changeThemeMode(mode);
|
||||||
if (desktopType == DesktopType.main) {
|
if (desktopType == DesktopType.main) {
|
||||||
if (mode == ThemeMode.system) {
|
if (mode == ThemeMode.system) {
|
||||||
bind.mainSetLocalOption(key: kCommConfKeyTheme, value: '');
|
await bind.mainSetLocalOption(key: kCommConfKeyTheme, value: '');
|
||||||
} else {
|
} else {
|
||||||
bind.mainSetLocalOption(
|
await bind.mainSetLocalOption(
|
||||||
key: kCommConfKeyTheme, value: mode.toShortString());
|
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}) {
|
String getWindowNameWithId(String id, {WindowType? overrideType}) {
|
||||||
return "${DesktopTab.labelGetterAlias(id).value} - ${getWindowName(overrideType: 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/main.dart';
|
import 'package:flutter_hbb/main.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class RefreshWrapper extends StatefulWidget {
|
class RefreshWrapper extends StatefulWidget {
|
||||||
final Widget Function(BuildContext context) builder;
|
final Widget Function(BuildContext context) builder;
|
||||||
|
|
||||||
const RefreshWrapper({super.key, required this.builder});
|
const RefreshWrapper({super.key, required this.builder});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -30,6 +32,8 @@ class RefreshWrapperState extends State<RefreshWrapper> {
|
|||||||
if (Get.context != null) {
|
if (Get.context != null) {
|
||||||
(context as Element).visitChildren(_rebuildElement);
|
(context as Element).visitChildren(_rebuildElement);
|
||||||
}
|
}
|
||||||
|
// Synchronize the window theme of the system.
|
||||||
|
updateSystemWindowTheme();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ Future<void> initEnv(String appType) async {
|
|||||||
await initGlobalFFI();
|
await initGlobalFFI();
|
||||||
// await Firebase.initializeApp();
|
// await Firebase.initializeApp();
|
||||||
_registerEventHandler();
|
_registerEventHandler();
|
||||||
|
// Update the system theme.
|
||||||
|
updateSystemWindowTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runMainApp(bool startService) async {
|
void runMainApp(bool startService) async {
|
||||||
@ -327,6 +329,8 @@ class _AppState extends State<App> {
|
|||||||
to = ThemeMode.light;
|
to = ThemeMode.light;
|
||||||
}
|
}
|
||||||
Get.changeThemeMode(to);
|
Get.changeThemeMode(to);
|
||||||
|
// Synchronize the window theme of the system.
|
||||||
|
updateSystemWindowTheme();
|
||||||
if (desktopType == DesktopType.main) {
|
if (desktopType == DesktopType.main) {
|
||||||
bind.mainChangeTheme(dark: to.toShortString());
|
bind.mainChangeTheme(dark: to.toShortString());
|
||||||
}
|
}
|
||||||
|
34
flutter/lib/utils/platform_channel.dart
Normal file
34
flutter/lib/utils/platform_channel.dart
Normal 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});
|
||||||
|
}
|
||||||
|
}
|
@ -27,12 +27,16 @@ class MainFlutterWindow: NSWindow {
|
|||||||
let windowFrame = self.frame
|
let windowFrame = self.frame
|
||||||
self.contentViewController = flutterViewController
|
self.contentViewController = flutterViewController
|
||||||
self.setFrame(windowFrame, display: true)
|
self.setFrame(windowFrame, display: true)
|
||||||
|
// register self method handler
|
||||||
|
let registrar = flutterViewController.registrar(forPlugin: "RustDeskPlugin")
|
||||||
|
setMethodHandler(registrar: registrar)
|
||||||
|
|
||||||
RegisterGeneratedPlugins(registry: flutterViewController)
|
RegisterGeneratedPlugins(registry: flutterViewController)
|
||||||
|
|
||||||
FlutterMultiWindowPlugin.setOnWindowCreatedCallback { controller in
|
FlutterMultiWindowPlugin.setOnWindowCreatedCallback { controller in
|
||||||
// Register the plugin which you want access from other isolate.
|
// Register the plugin which you want access from other isolate.
|
||||||
// DesktopLifecyclePlugin.register(with: controller.registrar(forPlugin: "DesktopLifecyclePlugin"))
|
// DesktopLifecyclePlugin.register(with: controller.registrar(forPlugin: "DesktopLifecyclePlugin"))
|
||||||
|
self.setMethodHandler(registrar: controller.registrar(forPlugin: "RustDeskPlugin"))
|
||||||
DesktopDropPlugin.register(with: controller.registrar(forPlugin: "DesktopDropPlugin"))
|
DesktopDropPlugin.register(with: controller.registrar(forPlugin: "DesktopDropPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: controller.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: controller.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
FlutterCustomCursorPlugin.register(with: controller.registrar(forPlugin: "FlutterCustomCursorPlugin"))
|
FlutterCustomCursorPlugin.register(with: controller.registrar(forPlugin: "FlutterCustomCursorPlugin"))
|
||||||
@ -53,4 +57,31 @@ class MainFlutterWindow: NSWindow {
|
|||||||
super.order(place, relativeTo: otherWin)
|
super.order(place, relativeTo: otherWin)
|
||||||
hiddenWindowAtLaunch()
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ dependencies:
|
|||||||
url: https://github.com/Kingtous/rustdesk_desktop_multi_window
|
url: https://github.com/Kingtous/rustdesk_desktop_multi_window
|
||||||
ref: bc8604a88e52b2b6e64d2661ae49a71450a47af8
|
ref: bc8604a88e52b2b6e64d2661ae49a71450a47af8
|
||||||
freezed_annotation: ^2.0.3
|
freezed_annotation: ^2.0.3
|
||||||
flutter_custom_cursor: ^0.0.2
|
flutter_custom_cursor: ^0.0.4
|
||||||
window_size:
|
window_size:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/google/flutter-desktop-embedding.git
|
url: https://github.com/google/flutter-desktop-embedding.git
|
||||||
|
Loading…
x
Reference in New Issue
Block a user