mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-03-30 16:41:00 +03:00
fix(desktop): wakelock issue with multiple tabs in same window (#13956)
Each desktop isolate now independently tracks wakelock state. WakelockPlus.disable() is only called when all tabs within the same isolate are closed/minimized. WakelockPlus ensures screen stays awake as long as any isolate has wakelock enabled. Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
@@ -24,6 +24,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:uni_links/uni_links.dart';
|
import 'package:uni_links/uni_links.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
import 'package:window_size/window_size.dart' as window_size;
|
import 'package:window_size/window_size.dart' as window_size;
|
||||||
|
|
||||||
@@ -2676,6 +2677,31 @@ class SimpleWrapper<T> {
|
|||||||
SimpleWrapper(this.value);
|
SimpleWrapper(this.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wakelock manager with reference counting for desktop.
|
||||||
|
/// Ensures wakelock is only disabled when all sessions are closed/minimized.
|
||||||
|
///
|
||||||
|
/// Note: Each isolate has its own WakelockPlus instance with independent assertion.
|
||||||
|
/// As long as one isolate has wakelock enabled, the screen stays awake.
|
||||||
|
/// This manager handles multiple tabs within the same isolate.
|
||||||
|
class WakelockManager {
|
||||||
|
static final Set<UniqueKey> _enabledKeys = {};
|
||||||
|
|
||||||
|
static void enable(UniqueKey key) {
|
||||||
|
if (isLinux) return;
|
||||||
|
_enabledKeys.add(key);
|
||||||
|
WakelockPlus.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disable(UniqueKey key) {
|
||||||
|
if (isLinux) return;
|
||||||
|
if (_enabledKeys.remove(key)) {
|
||||||
|
if (_enabledKeys.isEmpty) {
|
||||||
|
WakelockPlus.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// call this to reload current window.
|
/// call this to reload current window.
|
||||||
///
|
///
|
||||||
/// [Note]
|
/// [Note]
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
|||||||
import 'package:flutter_hbb/models/file_model.dart';
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
|
||||||
import 'package:flutter_hbb/web/dummy.dart'
|
import 'package:flutter_hbb/web/dummy.dart'
|
||||||
if (dart.library.html) 'package:flutter_hbb/web/web_unique.dart';
|
if (dart.library.html) 'package:flutter_hbb/web/web_unique.dart';
|
||||||
|
|
||||||
@@ -86,6 +85,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
|
|
||||||
final _dropMaskVisible = false.obs; // TODO impl drop mask
|
final _dropMaskVisible = false.obs; // TODO impl drop mask
|
||||||
final _overlayKeyState = OverlayKeyState();
|
final _overlayKeyState = OverlayKeyState();
|
||||||
|
final _uniqueKey = UniqueKey();
|
||||||
|
|
||||||
late FFI _ffi;
|
late FFI _ffi;
|
||||||
|
|
||||||
@@ -107,9 +107,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
||||||
});
|
});
|
||||||
Get.put<FFI>(_ffi, tag: 'ft_${widget.id}');
|
Get.put<FFI>(_ffi, tag: 'ft_${widget.id}');
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
_ffi.ffiModel.updateEventListener(_ffi.sessionId, widget.id);
|
_ffi.ffiModel.updateEventListener(_ffi.sessionId, widget.id);
|
||||||
}
|
}
|
||||||
@@ -127,9 +125,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
model.close().whenComplete(() {
|
model.close().whenComplete(() {
|
||||||
_ffi.close();
|
_ffi.close();
|
||||||
_ffi.dialogManager.dismissAll();
|
_ffi.dialogManager.dismissAll();
|
||||||
if (!isLinux) {
|
WakelockManager.disable(_uniqueKey);
|
||||||
WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
Get.delete<FFI>(tag: 'ft_${widget.id}');
|
Get.delete<FFI>(tag: 'ft_${widget.id}');
|
||||||
});
|
});
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
|
||||||
import 'package:flutter_hbb/models/state_model.dart';
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
|
|
||||||
import '../../consts.dart';
|
import '../../consts.dart';
|
||||||
@@ -85,6 +84,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
late RxBool _zoomCursor;
|
late RxBool _zoomCursor;
|
||||||
late RxBool _remoteCursorMoved;
|
late RxBool _remoteCursorMoved;
|
||||||
late RxBool _keyboardEnabled;
|
late RxBool _keyboardEnabled;
|
||||||
|
final _uniqueKey = UniqueKey();
|
||||||
|
|
||||||
var _blockableOverlayState = BlockableOverlayState();
|
var _blockableOverlayState = BlockableOverlayState();
|
||||||
|
|
||||||
@@ -138,9 +138,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_ffi.dialogManager
|
_ffi.dialogManager
|
||||||
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
||||||
});
|
});
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
_ffi.ffiModel.updateEventListener(sessionId, widget.id);
|
_ffi.ffiModel.updateEventListener(sessionId, widget.id);
|
||||||
if (!isWeb) bind.pluginSyncUi(syncTo: kAppTypeDesktopRemote);
|
if (!isWeb) bind.pluginSyncUi(syncTo: kAppTypeDesktopRemote);
|
||||||
@@ -206,26 +204,20 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
_isWindowBlur = false;
|
_isWindowBlur = false;
|
||||||
}
|
}
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the window is unminimized, onWindowMaximize or onWindowRestore can be called when the old state was maximized or not.
|
// When the window is unminimized, onWindowMaximize or onWindowRestore can be called when the old state was maximized or not.
|
||||||
@override
|
@override
|
||||||
void onWindowMaximize() {
|
void onWindowMaximize() {
|
||||||
super.onWindowMaximize();
|
super.onWindowMaximize();
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onWindowMinimize() {
|
void onWindowMinimize() {
|
||||||
super.onWindowMinimize();
|
super.onWindowMinimize();
|
||||||
if (!isLinux) {
|
WakelockManager.disable(_uniqueKey);
|
||||||
WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -268,9 +260,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
}
|
}
|
||||||
if (!isLinux) {
|
WakelockManager.disable(_uniqueKey);
|
||||||
await WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
await Get.delete<FFI>(tag: widget.id);
|
await Get.delete<FFI>(tag: widget.id);
|
||||||
removeSharedStates(widget.id);
|
removeSharedStates(widget.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_hbb/common/widgets/remote_input.dart';
|
import 'package:flutter_hbb/common/widgets/remote_input.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
|
||||||
import 'package:flutter_hbb/models/state_model.dart';
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
|
|
||||||
import '../../consts.dart';
|
import '../../consts.dart';
|
||||||
@@ -77,6 +76,7 @@ class _ViewCameraPageState extends State<ViewCameraPage>
|
|||||||
String keyboardMode = "legacy";
|
String keyboardMode = "legacy";
|
||||||
bool _isWindowBlur = false;
|
bool _isWindowBlur = false;
|
||||||
final _cursorOverImage = false.obs;
|
final _cursorOverImage = false.obs;
|
||||||
|
final _uniqueKey = UniqueKey();
|
||||||
|
|
||||||
var _blockableOverlayState = BlockableOverlayState();
|
var _blockableOverlayState = BlockableOverlayState();
|
||||||
|
|
||||||
@@ -124,9 +124,7 @@ class _ViewCameraPageState extends State<ViewCameraPage>
|
|||||||
_ffi.dialogManager
|
_ffi.dialogManager
|
||||||
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
.showLoading(translate('Connecting...'), onCancel: closeConnection);
|
||||||
});
|
});
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
_ffi.ffiModel.updateEventListener(sessionId, widget.id);
|
_ffi.ffiModel.updateEventListener(sessionId, widget.id);
|
||||||
if (!isWeb) bind.pluginSyncUi(syncTo: kAppTypeDesktopRemote);
|
if (!isWeb) bind.pluginSyncUi(syncTo: kAppTypeDesktopRemote);
|
||||||
@@ -185,26 +183,20 @@ class _ViewCameraPageState extends State<ViewCameraPage>
|
|||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
_isWindowBlur = false;
|
_isWindowBlur = false;
|
||||||
}
|
}
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the window is unminimized, onWindowMaximize or onWindowRestore can be called when the old state was maximized or not.
|
// When the window is unminimized, onWindowMaximize or onWindowRestore can be called when the old state was maximized or not.
|
||||||
@override
|
@override
|
||||||
void onWindowMaximize() {
|
void onWindowMaximize() {
|
||||||
super.onWindowMaximize();
|
super.onWindowMaximize();
|
||||||
if (!isLinux) {
|
WakelockManager.enable(_uniqueKey);
|
||||||
WakelockPlus.enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onWindowMinimize() {
|
void onWindowMinimize() {
|
||||||
super.onWindowMinimize();
|
super.onWindowMinimize();
|
||||||
if (!isLinux) {
|
WakelockManager.disable(_uniqueKey);
|
||||||
WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -247,9 +239,7 @@ class _ViewCameraPageState extends State<ViewCameraPage>
|
|||||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
}
|
}
|
||||||
if (!isLinux) {
|
WakelockManager.disable(_uniqueKey);
|
||||||
await WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
await Get.delete<FFI>(tag: widget.id);
|
await Get.delete<FFI>(tag: widget.id);
|
||||||
removeSharedStates(widget.id);
|
removeSharedStates(widget.id);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user