mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-17 14:07:28 +08:00
refact: remote toolbar show/hide (#13843)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -120,6 +120,7 @@ const String kOptionApproveMode = "approve-mode";
|
||||
const String kOptionAllowNumericOneTimePassword =
|
||||
"allow-numeric-one-time-password";
|
||||
const String kOptionCollapseToolbar = "collapse_toolbar";
|
||||
const String kOptionHideToolbar = "hide-toolbar";
|
||||
const String kOptionShowRemoteCursor = "show_remote_cursor";
|
||||
const String kOptionFollowRemoteCursor = "follow_remote_cursor";
|
||||
const String kOptionFollowRemoteWindow = "follow_remote_window";
|
||||
|
||||
@@ -509,7 +509,6 @@ class _RemotePageState extends State<RemotePage>
|
||||
() => _ffi.ffiModel.pi.isSet.isFalse
|
||||
? Container(color: Colors.transparent)
|
||||
: Obx(() {
|
||||
widget.toolbarState.initShow(sessionId);
|
||||
_ffi.textureModel.updateCurrentDisplay(peerDisplay.value);
|
||||
return ImagePaint(
|
||||
id: widget.id,
|
||||
|
||||
@@ -251,11 +251,11 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Obx(() => Text(
|
||||
translate(
|
||||
toolbarState.show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||
toolbarState.hide.isTrue ? 'Show Toolbar' : 'Hide Toolbar'),
|
||||
style: style,
|
||||
)),
|
||||
proc: () {
|
||||
toolbarState.switchShow(sessionId);
|
||||
toolbarState.switchHide(sessionId);
|
||||
cancelFunc();
|
||||
},
|
||||
padding: padding,
|
||||
|
||||
@@ -465,7 +465,6 @@ class _ViewCameraPageState extends State<ViewCameraPage>
|
||||
() => _ffi.ffiModel.pi.isSet.isFalse
|
||||
? Container(color: Colors.transparent)
|
||||
: Obx(() {
|
||||
widget.toolbarState.initShow(sessionId);
|
||||
_ffi.textureModel.updateCurrentDisplay(peerDisplay.value);
|
||||
return ImagePaint(
|
||||
id: widget.id,
|
||||
|
||||
@@ -250,11 +250,11 @@ class _ViewCameraTabPageState extends State<ViewCameraTabPage> {
|
||||
MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Obx(() => Text(
|
||||
translate(
|
||||
toolbarState.show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||
toolbarState.hide.isTrue ? 'Show Toolbar' : 'Hide Toolbar'),
|
||||
style: style,
|
||||
)),
|
||||
proc: () {
|
||||
toolbarState.switchShow(sessionId);
|
||||
toolbarState.switchHide(sessionId);
|
||||
cancelFunc();
|
||||
},
|
||||
padding: padding,
|
||||
|
||||
@@ -31,8 +31,12 @@ import 'package:flutter_hbb/common/widgets/custom_scale_base.dart';
|
||||
class ToolbarState {
|
||||
late RxBool _pin;
|
||||
|
||||
bool isShowInited = false;
|
||||
RxBool show = false.obs;
|
||||
RxBool collapse = false.obs;
|
||||
RxBool hide = false.obs;
|
||||
|
||||
// Track initialization state to prevent flickering
|
||||
final RxBool initialized = false.obs;
|
||||
bool _isInitializing = false;
|
||||
|
||||
ToolbarState() {
|
||||
_pin = RxBool(false);
|
||||
@@ -53,19 +57,39 @@ class ToolbarState {
|
||||
|
||||
bool get pin => _pin.value;
|
||||
|
||||
switchShow(SessionID sessionId) async {
|
||||
bind.sessionToggleOption(
|
||||
sessionId: sessionId, value: kOptionCollapseToolbar);
|
||||
show.value = !show.value;
|
||||
/// Initialize all toolbar states from session options.
|
||||
/// This should be called once when the toolbar is first created.
|
||||
Future<void> init(SessionID sessionId) async {
|
||||
if (initialized.value || _isInitializing) return;
|
||||
_isInitializing = true;
|
||||
|
||||
try {
|
||||
// Load both states in parallel for better performance
|
||||
final results = await Future.wait([
|
||||
bind.sessionGetToggleOption(
|
||||
sessionId: sessionId, arg: kOptionCollapseToolbar),
|
||||
bind.sessionGetToggleOption(
|
||||
sessionId: sessionId, arg: kOptionHideToolbar),
|
||||
]);
|
||||
|
||||
collapse.value = results[0] ?? false;
|
||||
hide.value = results[1] ?? false;
|
||||
} finally {
|
||||
_isInitializing = false;
|
||||
initialized.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
initShow(SessionID sessionId) async {
|
||||
if (!isShowInited) {
|
||||
show.value = !(await bind.sessionGetToggleOption(
|
||||
sessionId: sessionId, arg: kOptionCollapseToolbar) ??
|
||||
false);
|
||||
isShowInited = true;
|
||||
}
|
||||
switchCollapse(SessionID sessionId) async {
|
||||
bind.sessionToggleOption(
|
||||
sessionId: sessionId, value: kOptionCollapseToolbar);
|
||||
collapse.value = !collapse.value;
|
||||
}
|
||||
|
||||
// Switch hide state for entire toolbar visibility
|
||||
switchHide(SessionID sessionId) async {
|
||||
bind.sessionToggleOption(sessionId: sessionId, value: kOptionHideToolbar);
|
||||
hide.value = !hide.value;
|
||||
}
|
||||
|
||||
switchPin() async {
|
||||
@@ -237,7 +261,8 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
||||
// setState(() {});
|
||||
}
|
||||
|
||||
RxBool get show => widget.state.show;
|
||||
RxBool get collapse => widget.state.collapse;
|
||||
RxBool get hide => widget.state.hide;
|
||||
bool get pin => widget.state.pin;
|
||||
|
||||
PeerInfo get pi => widget.ffi.ffiModel.pi;
|
||||
@@ -258,6 +283,8 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
||||
arg: 'remote-menubar-drag-x') ??
|
||||
'0.5') ??
|
||||
0.5;
|
||||
// Initialize toolbar states (collapse, hide) from session options
|
||||
widget.state.init(widget.ffi.sessionId);
|
||||
});
|
||||
|
||||
_debouncerHide = Debouncer<int>(
|
||||
@@ -277,8 +304,8 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
||||
}
|
||||
|
||||
_debouncerHideProc(int v) {
|
||||
if (!pin && show.isTrue && _isCursorOverImage && _dragging.isFalse) {
|
||||
show.value = false;
|
||||
if (!pin && collapse.isFalse && _isCursorOverImage && _dragging.isFalse) {
|
||||
collapse.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,17 +318,27 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Obx(() => show.value
|
||||
? _buildToolbar(context)
|
||||
: _buildDraggableShowHide(context)),
|
||||
);
|
||||
return Obx(() {
|
||||
// Wait for initialization to complete to prevent flickering
|
||||
if (!widget.state.initialized.value) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
// If toolbar is hidden, return empty widget
|
||||
if (hide.value) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: collapse.isFalse
|
||||
? _buildToolbar(context)
|
||||
: _buildDraggableCollapse(context),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildDraggableShowHide(BuildContext context) {
|
||||
Widget _buildDraggableCollapse(BuildContext context) {
|
||||
return Obx(() {
|
||||
if (show.isTrue && _dragging.isFalse) {
|
||||
if (collapse.isFalse && _dragging.isFalse) {
|
||||
triggerAutoHide();
|
||||
}
|
||||
final borderRadius = BorderRadius.vertical(
|
||||
@@ -398,7 +435,7 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildDraggableShowHide(context),
|
||||
_buildDraggableCollapse(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -2491,7 +2528,7 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
||||
double left = 0.0;
|
||||
double right = 1.0;
|
||||
|
||||
RxBool get show => widget.toolbarState.show;
|
||||
RxBool get collapse => widget.toolbarState.collapse;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
@@ -2614,20 +2651,20 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
||||
)),
|
||||
buttonWrapper(
|
||||
() => setState(() {
|
||||
widget.toolbarState.switchShow(widget.sessionId);
|
||||
widget.toolbarState.switchCollapse(widget.sessionId);
|
||||
}),
|
||||
Obx((() => Tooltip(
|
||||
message:
|
||||
translate(show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||
message: translate(
|
||||
collapse.isFalse ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||
child: Icon(
|
||||
show.isTrue ? Icons.expand_less : Icons.expand_more,
|
||||
collapse.isFalse ? Icons.expand_less : Icons.expand_more,
|
||||
size: iconSize,
|
||||
),
|
||||
))),
|
||||
),
|
||||
if (isWebDesktop)
|
||||
Obx(() {
|
||||
if (show.isTrue) {
|
||||
if (collapse.isFalse) {
|
||||
return Offstage();
|
||||
} else {
|
||||
return buttonWrapper(
|
||||
|
||||
Reference in New Issue
Block a user