Merge pull request #1896 from fufesou/fix_remote_page_layout
flutter_desktop: remote rxbool of fullscreen
This commit is contained in:
		
						commit
						2629e515fb
					
				@ -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';
 | 
			
		||||
 | 
			
		||||
@ -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';
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
          );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
          );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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),
 | 
			
		||||
 | 
			
		||||
@ -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));
 | 
			
		||||
              }
 | 
			
		||||
            }();
 | 
			
		||||
 | 
			
		||||
@ -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())
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								flutter/lib/models/state_model.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								flutter/lib/models/state_model.dart
									
									
									
									
									
										Normal 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;
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user