Merge pull request #1896 from fufesou/fix_remote_page_layout

flutter_desktop: remote rxbool of fullscreen
This commit is contained in:
RustDesk 2022-11-01 21:01:20 +08:00 committed by GitHub
commit 2629e515fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 142 additions and 138 deletions

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';

View File

@ -5,7 +5,6 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
import 'package:flutter_hbb/models/platform_model.dart';

View File

@ -6,6 +6,7 @@ import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get.dart';
import 'package:window_manager/window_manager.dart';
@ -62,8 +63,6 @@ class _DesktopTabPageState extends State<DesktopTabPage> {
@override
Widget build(BuildContext context) {
RxBool fullscreen = false.obs;
Get.put(fullscreen, tag: 'fullscreen');
final tabWidget = Container(
child: Overlay(initialEntries: [
OverlayEntry(builder: (context) {
@ -84,9 +83,11 @@ class _DesktopTabPageState extends State<DesktopTabPage> {
);
return Platform.isMacOS
? tabWidget
: Obx(() => DragToResizeArea(
resizeEdgeSize:
fullscreen.value ? kFullScreenEdgeSize : kWindowEdgeSize,
child: tabWidget));
: Obx(
() => DragToResizeArea(
resizeEdgeSize: stateGlobal.resizeEdgeSize.value,
child: tabWidget,
),
);
}
}

View File

@ -5,6 +5,7 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/file_manager_page.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
@ -47,7 +48,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
print(
"[FileTransfer] call ${call.method} with args ${call.arguments} from window ${fromWindowId} to ${windowId()}");
"[FileTransfer] call ${call.method} with args ${call.arguments} from window $fromWindowId to ${windowId()}");
// for simplify, just replace connectionId
if (call.method == "new_file_transfer") {
final args = jsonDecode(call.arguments);
@ -87,9 +88,9 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
return Platform.isMacOS
? tabWidget
: SubWindowDragToResizeArea(
resizeEdgeSize: kWindowEdgeSize,
windowId: windowId(),
child: tabWidget,
resizeEdgeSize: stateGlobal.resizeEdgeSize.value,
windowId: stateGlobal.windowId,
);
}

View File

@ -5,6 +5,7 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/port_forward_page.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
@ -50,7 +51,7 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> {
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
debugPrint(
"call ${call.method} with args ${call.arguments} from window ${fromWindowId}");
"call ${call.method} with args ${call.arguments} from window $fromWindowId");
// for simplify, just replace connectionId
if (call.method == "new_port_forward") {
final args = jsonDecode(call.arguments);
@ -98,9 +99,9 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> {
return Platform.isMacOS
? tabWidget
: SubWindowDragToResizeArea(
resizeEdgeSize: kWindowEdgeSize,
windowId: windowId(),
child: tabWidget,
resizeEdgeSize: stateGlobal.resizeEdgeSize.value,
windowId: stateGlobal.windowId,
);
}

View File

@ -28,15 +28,9 @@ class RemotePage extends StatefulWidget {
const RemotePage({
Key? key,
required this.id,
required this.windowId,
required this.tabBarHeight,
required this.windowBorderWidth,
}) : super(key: key);
final String id;
final int windowId;
final double tabBarHeight;
final double windowBorderWidth;
@override
State<RemotePage> createState() => _RemotePageState();
@ -58,11 +52,6 @@ class _RemotePageState extends State<RemotePage>
late FFI _ffi;
void _updateTabBarHeight() {
_ffi.canvasModel.tabBarHeight = widget.tabBarHeight;
_ffi.canvasModel.windowBorderWidth = widget.windowBorderWidth;
}
void _initStates(String id) {
PrivacyModeState.init(id);
BlockInputState.init(id);
@ -91,7 +80,6 @@ class _RemotePageState extends State<RemotePage>
_ffi = FFI();
_updateTabBarHeight();
Get.put(_ffi, tag: widget.id);
_ffi.start(widget.id);
WidgetsBinding.instance.addPostFrameCallback((_) {
@ -164,7 +152,6 @@ class _RemotePageState extends State<RemotePage>
@override
Widget build(BuildContext context) {
super.build(context);
_updateTabBarHeight();
return WillPopScope(
onWillPop: () async {
clientClose(_ffi.dialogManager);
@ -241,7 +228,6 @@ class _RemotePageState extends State<RemotePage>
paints.add(QualityMonitor(_ffi.qualityMonitorModel));
paints.add(RemoteMenubar(
id: widget.id,
windowId: widget.windowId,
ffi: _ffi,
onEnterOrLeaveImageSetter: (func) => _onEnterOrLeaveImage4Menubar = func,
onEnterOrLeaveImageCleaner: () => _onEnterOrLeaveImage4Menubar = null,

View File

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
@ -34,24 +35,20 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
_ConnectionTabPageState(Map<String, dynamic> params) {
RemoteCountState.init();
final RxBool fullscreen = Get.find(tag: 'fullscreen');
final peerId = params['id'];
if (peerId != null) {
ConnectionTypeState.init(peerId);
tabController.add(TabInfo(
key: peerId,
label: peerId,
selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon,
onTabCloseButton: () => tabController.closeBy(peerId),
page: Obx(() => RemotePage(
key: ValueKey(peerId),
id: peerId,
windowId: windowId(),
tabBarHeight:
fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight,
windowBorderWidth: fullscreen.isTrue ? 0 : kWindowBorderWidth,
))));
key: peerId,
label: peerId,
selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon,
onTabCloseButton: () => tabController.closeBy(peerId),
page: RemotePage(
key: ValueKey(peerId),
id: peerId,
),
));
_update_remote_count();
}
}
@ -66,7 +63,6 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
print(
"call ${call.method} with args ${call.arguments} from window $fromWindowId");
final RxBool fullscreen = Get.find(tag: 'fullscreen');
// for simplify, just replace connectionId
if (call.method == "new_remote_desktop") {
final args = jsonDecode(call.arguments);
@ -75,22 +71,13 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
window_on_top(windowId());
ConnectionTypeState.init(id);
tabController.add(TabInfo(
key: id,
label: id,
selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon,
onTabCloseButton: () => tabController.closeBy(id),
page: ObxValue<RxBool>(
(fullscreen) => RemotePage(
id: id,
windowId: windowId(),
tabBarHeight:
fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight,
windowBorderWidth: fullscreen.isTrue ? 0 : kWindowBorderWidth,
),
fullscreen,
key: ValueKey(id),
)));
key: id,
label: id,
selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon,
onTabCloseButton: () => tabController.closeBy(id),
page: RemotePage(key: ValueKey(id), id: id),
));
} else if (call.method == "onDestroy") {
tabController.clear();
} else if (call.method == kWindowActionRebuild) {
@ -105,7 +92,6 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
@override
Widget build(BuildContext context) {
final RxBool fullscreen = Get.find(tag: 'fullscreen');
final tabWidget = Container(
decoration: BoxDecoration(
border: Border.all(
@ -113,61 +99,56 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
width: kWindowBorderWidth)),
child: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: Obx(() => DesktopTab(
controller: tabController,
showTabBar: fullscreen.isFalse,
onWindowCloseButton: handleWindowCloseButton,
tail: const AddButton().paddingOnly(left: 10),
pageViewBuilder: (pageView) {
WindowController.fromWindowId(windowId())
.setFullscreen(fullscreen.isTrue);
return pageView;
},
tabBuilder: (key, icon, label, themeConf) => Obx(() {
final connectionType = ConnectionTypeState.find(key);
if (!connectionType.isValid()) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon,
label,
],
);
} else {
final msgDirect = translate(
connectionType.direct.value == ConnectionType.strDirect
? 'Direct Connection'
: 'Relay Connection');
final msgSecure = translate(
connectionType.secure.value == ConnectionType.strSecure
? 'Secure Connection'
: 'Insecure Connection');
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon,
Tooltip(
message: '$msgDirect\n$msgSecure',
child: SvgPicture.asset(
'assets/${connectionType.secure.value}${connectionType.direct.value}.svg',
width: themeConf.iconSize,
height: themeConf.iconSize,
).paddingOnly(right: 5),
),
label,
],
);
}
}),
))),
body: DesktopTab(
controller: tabController,
onWindowCloseButton: handleWindowCloseButton,
tail: const AddButton().paddingOnly(left: 10),
pageViewBuilder: (pageView) => pageView,
tabBuilder: (key, icon, label, themeConf) => Obx(() {
final connectionType = ConnectionTypeState.find(key);
if (!connectionType.isValid()) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon,
label,
],
);
} else {
final msgDirect = translate(
connectionType.direct.value == ConnectionType.strDirect
? 'Direct Connection'
: 'Relay Connection');
final msgSecure = translate(
connectionType.secure.value == ConnectionType.strSecure
? 'Secure Connection'
: 'Insecure Connection');
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon,
Tooltip(
message: '$msgDirect\n$msgSecure',
child: SvgPicture.asset(
'assets/${connectionType.secure.value}${connectionType.direct.value}.svg',
width: themeConf.iconSize,
height: themeConf.iconSize,
).paddingOnly(right: 5),
),
label,
],
);
}
}),
)),
);
return Platform.isMacOS
? tabWidget
: Obx(() => SubWindowDragToResizeArea(
resizeEdgeSize:
fullscreen.value ? kFullScreenEdgeSize : kWindowEdgeSize,
windowId: windowId(),
child: tabWidget));
: SubWindowDragToResizeArea(
child: tabWidget,
resizeEdgeSize: stateGlobal.resizeEdgeSize.value,
windowId: stateGlobal.windowId,
);
}
void onRemoveId(String id) {

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/pages/remote_tab_page.dart';
import 'package:flutter_hbb/desktop/widgets/refresh_wrapper.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
/// multi-tab desktop remote screen
@ -13,8 +12,6 @@ class DesktopRemoteScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
RxBool fullscreen = false.obs;
Get.put(fullscreen, tag: 'fullscreen');
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: gFFI.ffiModel),

View File

@ -6,6 +6,7 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart' as rxdart;
@ -29,7 +30,6 @@ class _MenubarTheme {
class RemoteMenubar extends StatefulWidget {
final String id;
final int windowId;
final FFI ffi;
final Function(Function(bool)) onEnterOrLeaveImageSetter;
final Function() onEnterOrLeaveImageCleaner;
@ -37,7 +37,6 @@ class RemoteMenubar extends StatefulWidget {
const RemoteMenubar({
Key? key,
required this.id,
required this.windowId,
required this.ffi,
required this.onEnterOrLeaveImageSetter,
required this.onEnterOrLeaveImageCleaner,
@ -55,9 +54,12 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
bool _isCursorOverImage = false;
window_size.Screen? _screen;
bool get isFullscreen => Get.find<RxBool>(tag: 'fullscreen').isTrue;
int get windowId => stateGlobal.windowId;
bool get isFullscreen => stateGlobal.fullscreen;
void _setFullscreen(bool v) {
Get.find<RxBool>(tag: 'fullscreen').value = v;
stateGlobal.setFullscreen(v);
setState(() {});
}
@override
@ -213,7 +215,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
onPressed: () {
_setFullscreen(!isFullscreen);
},
icon: Obx(() => isFullscreen
icon: isFullscreen
? const Icon(
Icons.fullscreen_exit,
color: _MenubarTheme.commonColor,
@ -221,7 +223,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
: const Icon(
Icons.fullscreen,
color: _MenubarTheme.commonColor,
)),
),
);
}
@ -920,8 +922,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
_setFullscreen(false);
double scale = _screen!.scaleFactor;
final wndRect =
await WindowController.fromWindowId(widget.windowId)
.getFrame();
await WindowController.fromWindowId(windowId).getFrame();
final mediaSize = MediaQueryData.fromWindow(ui.window).size;
// On windows, wndRect is equal to GetWindowRect and mediaSize is equal to GetClientRect.
// https://stackoverflow.com/a/7561083
@ -944,8 +945,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
double top = wndRect.top + (wndRect.height - height) / 2;
Rect frameRect = _screen!.frame;
final RxBool fullscreen = Get.find(tag: 'fullscreen');
if (fullscreen.isFalse) {
if (!isFullscreen) {
frameRect = _screen!.visibleFrame;
}
if (left < frameRect.left) {
@ -960,7 +960,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
if ((top + height) > frameRect.bottom) {
top = frameRect.bottom - height;
}
await WindowController.fromWindowId(widget.windowId)
await WindowController.fromWindowId(windowId)
.setFrame(Rect.fromLTWH(left, top, width, height));
}
}();

View File

@ -9,6 +9,7 @@ import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/main.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
import 'package:scroll_pos/scroll_pos.dart';
@ -179,7 +180,6 @@ typedef LabelGetter = Rx<String> Function(String key);
int _lastClickTime = DateTime.now().millisecondsSinceEpoch;
class DesktopTab extends StatelessWidget {
final bool showTabBar;
final bool showLogo;
final bool showTitle;
final bool showMinimize;
@ -206,7 +206,6 @@ class DesktopTab extends StatelessWidget {
DesktopTab({
Key? key,
required this.controller,
this.showTabBar = true,
this.showLogo = true,
this.showTitle = true,
this.showMinimize = true,
@ -229,8 +228,8 @@ class DesktopTab extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(children: [
Offstage(
offstage: !showTabBar,
Obx(() => Offstage(
offstage: !stateGlobal.showTabBar.isTrue,
child: SizedBox(
height: _kTabBarHeight,
child: Column(
@ -245,7 +244,7 @@ class DesktopTab extends StatelessWidget {
),
],
),
)),
))),
Expanded(
child: pageViewBuilder != null
? pageViewBuilder!(_buildPageView())

View File

@ -1,8 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
import 'package:flutter_hbb/desktop/pages/server_page.dart';
import 'package:flutter_hbb/desktop/pages/install_page.dart';
@ -15,7 +15,6 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uni_links_desktop/uni_links_desktop.dart';
import 'package:window_manager/window_manager.dart';
// import 'package:window_manager/window_manager.dart';
@ -41,11 +40,14 @@ Future<void> main(List<String> args) async {
// main window
if (args.isNotEmpty && args.first == 'multi_window') {
windowId = int.parse(args[1]);
stateGlobal.setWindowId(windowId!);
WindowController.fromWindowId(windowId!).showTitleBar(false);
final argument = args[2].isEmpty
? <String, dynamic>{}
: jsonDecode(args[2]) as Map<String, dynamic>;
int type = argument['type'] ?? -1;
// to-do: No need to parse window id ?
// Because stateGlobal.windowId is a global value.
argument['windowId'] = windowId;
WindowType wType = type.windowType;
switch (wType) {

View File

@ -10,6 +10,7 @@ import '../../models/model.dart';
import '../../models/platform_model.dart';
import '../common.dart';
import '../consts.dart';
import './state_model.dart';
import 'dart:ui' as ui;
/// Mouse button enum.
@ -321,9 +322,7 @@ class InputModel {
double x = evt['x'];
double y = max(0.0, evt['y']);
if (isDesktop) {
final RxBool fullscreen = Get.find(tag: 'fullscreen');
final tabBarHeight = fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight;
y = y - tabBarHeight;
y = y - stateGlobal.tabBarHeight;
}
final canvasModel = parent.target!.canvasModel;
final ffiModel = parent.target!.ffiModel;

View File

@ -14,6 +14,7 @@ import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/file_model.dart';
import 'package:flutter_hbb/models/server_model.dart';
import 'package:flutter_hbb/models/user_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tuple/tuple.dart';
@ -483,9 +484,9 @@ class CanvasModel with ChangeNotifier {
// image scale
double _scale = 1.0;
// the tabbar over the image
double tabBarHeight = 0.0;
// double tabBarHeight = 0.0;
// the window border's width
double windowBorderWidth = 0.0;
// double windowBorderWidth = 0.0;
// remote id
String id = '';
// scroll offset x percent
@ -571,6 +572,9 @@ class CanvasModel with ChangeNotifier {
return parent.target?.ffiModel.display.height ?? defaultHeight;
}
double get windowBorderWidth => stateGlobal.windowBorderWidth;
double get tabBarHeight => stateGlobal.tabBarHeight;
Size get size {
final size = MediaQueryData.fromWindow(ui.window).size;
return Size(size.width - windowBorderWidth * 2,

View File

@ -0,0 +1,35 @@
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:get/get.dart';
import '../consts.dart';
class StateGlobal {
int _windowId = -1;
bool _fullscreen = false;
final RxBool _showTabBar = true.obs;
final RxDouble _resizeEdgeSize = 8.0.obs;
int get windowId => _windowId;
bool get fullscreen => _fullscreen;
double get tabBarHeight => fullscreen ? 0 : kDesktopRemoteTabBarHeight;
double get windowBorderWidth => fullscreen ? 0 : kWindowBorderWidth;
RxBool get showTabBar => _showTabBar;
RxDouble get resizeEdgeSize => _resizeEdgeSize;
setWindowId(int id) => _windowId = id;
setFullscreen(bool v) {
if (_fullscreen != v) {
_fullscreen = v;
_showTabBar.value = !_fullscreen;
_resizeEdgeSize.value =
fullscreen ? kFullScreenEdgeSize : kWindowEdgeSize;
WindowController.fromWindowId(windowId).setFullscreen(_fullscreen);
}
}
StateGlobal._();
static final StateGlobal instance = StateGlobal._();
}
final stateGlobal = StateGlobal.instance;