flutter_desktop: adjust window
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
03439831a7
commit
2cc92c199c
@ -2,6 +2,7 @@ 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';
|
||||
@ -15,6 +16,7 @@ import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:window_size/window_size.dart' as window_size;
|
||||
|
||||
import 'common/widgets/overlay.dart';
|
||||
import 'mobile/pages/file_manager_page.dart';
|
||||
@ -23,6 +25,8 @@ import 'models/input_model.dart';
|
||||
import 'models/model.dart';
|
||||
import 'models/platform_model.dart';
|
||||
|
||||
import '../consts.dart';
|
||||
|
||||
final globalKey = GlobalKey<NavigatorState>();
|
||||
final navigationBarKey = GlobalKey();
|
||||
|
||||
@ -1022,6 +1026,85 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
|
||||
}
|
||||
}
|
||||
|
||||
_adjustRestoreMainWindowSize(double? width, double? height) async {
|
||||
const double minWidth = 600;
|
||||
const double minHeight = 100;
|
||||
double maxWidth = ((isDesktop || isWebDesktop)
|
||||
? kDesktopMaxDisplayWidth
|
||||
: kMobileMaxDisplayWidth) as double;
|
||||
double maxHeight = ((isDesktop || isWebDesktop)
|
||||
? kDesktopMaxDisplayHeight
|
||||
: kMobileMaxDisplayHeight) as double;
|
||||
|
||||
if (isDesktop || isWebDesktop) {
|
||||
final screen = (await window_size.getWindowInfo()).screen;
|
||||
if (screen != null) {
|
||||
maxWidth = screen.visibleFrame.width;
|
||||
maxHeight = screen.visibleFrame.height;
|
||||
}
|
||||
}
|
||||
|
||||
final defaultWidth = ((isDesktop || isWebDesktop)
|
||||
? 1280
|
||||
: kMobileDefaultDisplayWidth) as double;
|
||||
final defaultHeight = ((isDesktop || isWebDesktop)
|
||||
? 720
|
||||
: kMobileDefaultDisplayHeight) as double;
|
||||
double restoreWidth = width ?? defaultWidth;
|
||||
double restoreHeight = height ?? defaultHeight;
|
||||
|
||||
if (restoreWidth < minWidth) {
|
||||
restoreWidth = minWidth;
|
||||
}
|
||||
if (restoreHeight < minHeight) {
|
||||
restoreHeight = minHeight;
|
||||
}
|
||||
if (restoreWidth > maxWidth) {
|
||||
restoreWidth = maxWidth;
|
||||
}
|
||||
if (restoreHeight > maxHeight) {
|
||||
restoreWidth = maxHeight;
|
||||
}
|
||||
await windowManager.setSize(Size(restoreWidth, restoreHeight));
|
||||
}
|
||||
|
||||
_adjustRestoreMainWindowOffset(double? left, double? top) async {
|
||||
if (left == null || top == null) {
|
||||
await windowManager.center();
|
||||
} else {
|
||||
double windowLeft = left;
|
||||
double windowTop = top;
|
||||
|
||||
double frameLeft = 0;
|
||||
double frameTop = 0;
|
||||
double frameRight = ((isDesktop || isWebDesktop)
|
||||
? kDesktopMaxDisplayWidth
|
||||
: kMobileMaxDisplayWidth) as double;
|
||||
double frameBottom = ((isDesktop || isWebDesktop)
|
||||
? kDesktopMaxDisplayHeight
|
||||
: kMobileMaxDisplayHeight) as double;
|
||||
|
||||
if (isDesktop || isWebDesktop) {
|
||||
final screen = (await window_size.getWindowInfo()).screen;
|
||||
if (screen != null) {
|
||||
frameLeft = screen.visibleFrame.left;
|
||||
frameTop = screen.visibleFrame.top;
|
||||
frameRight = screen.visibleFrame.right;
|
||||
frameBottom = screen.visibleFrame.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
if (windowLeft < frameLeft ||
|
||||
windowLeft > frameRight ||
|
||||
windowTop < frameTop ||
|
||||
windowTop > frameBottom) {
|
||||
await windowManager.center();
|
||||
} else {
|
||||
await windowManager.setPosition(Offset(windowLeft, windowTop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Save window position and size on exit
|
||||
/// Note that windowId must be provided if it's subwindow
|
||||
Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
|
||||
@ -1042,13 +1125,10 @@ Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
|
||||
debugPrint("window position saved, but cannot be parsed");
|
||||
return false;
|
||||
}
|
||||
await windowManager.setSize(Size(lpos.width ?? 1280, lpos.height ?? 720));
|
||||
if (lpos.offsetWidth == null || lpos.offsetHeight == null) {
|
||||
await windowManager.center();
|
||||
} else {
|
||||
await windowManager
|
||||
.setPosition(Offset(lpos.offsetWidth!, lpos.offsetHeight!));
|
||||
}
|
||||
|
||||
await _adjustRestoreMainWindowSize(lpos.width, lpos.height);
|
||||
await _adjustRestoreMainWindowOffset(lpos.offsetWidth, lpos.offsetHeight);
|
||||
|
||||
return true;
|
||||
default:
|
||||
// TODO: implement subwindow
|
||||
|
@ -20,6 +20,12 @@ const int kMobileDefaultDisplayHeight = 1280;
|
||||
const int kDesktopDefaultDisplayWidth = 1080;
|
||||
const int kDesktopDefaultDisplayHeight = 720;
|
||||
|
||||
const int kMobileMaxDisplayWidth = 720;
|
||||
const int kMobileMaxDisplayHeight = 1280;
|
||||
|
||||
const int kDesktopMaxDisplayWidth = 1920;
|
||||
const int kDesktopMaxDisplayHeight = 1080;
|
||||
|
||||
const Size kConnectionManagerWindowSize = Size(300, 400);
|
||||
// Tabbar transition duration, now we remove the duration
|
||||
const Duration kTabTransitionDuration = Duration.zero;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart' hide MenuItem;
|
||||
import 'package:flutter/services.dart';
|
||||
@ -16,6 +17,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:tray_manager/tray_manager.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:window_size/window_size.dart' as window_size;
|
||||
|
||||
import '../widgets/button.dart';
|
||||
|
||||
@ -427,6 +429,27 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
||||
"call ${call.method} with args ${call.arguments} from window $fromWindowId");
|
||||
if (call.method == "main_window_on_top") {
|
||||
window_on_top(null);
|
||||
} else if (call.method == "get_window_info") {
|
||||
final screen = (await window_size.getWindowInfo()).screen;
|
||||
if (screen == null) {
|
||||
return "";
|
||||
} else {
|
||||
return jsonEncode({
|
||||
'frame': {
|
||||
'l': screen.frame.left,
|
||||
't': screen.frame.top,
|
||||
'r': screen.frame.right,
|
||||
'b': screen.frame.bottom,
|
||||
},
|
||||
'visibleFrame': {
|
||||
'l': screen.visibleFrame.left,
|
||||
't': screen.visibleFrame.top,
|
||||
'r': screen.visibleFrame.right,
|
||||
'b': screen.visibleFrame.bottom,
|
||||
},
|
||||
'scaleFactor': screen.scaleFactor,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -9,6 +10,7 @@ import 'package:get/get.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rxdart/rxdart.dart' as rxdart;
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:window_size/window_size.dart' as window_size;
|
||||
|
||||
import '../../common.dart';
|
||||
import '../../mobile/widgets/dialog.dart';
|
||||
@ -51,6 +53,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
final _rxHideReplay = rxdart.ReplaySubject<int>();
|
||||
final _pinMenubar = false.obs;
|
||||
bool _isCursorOverImage = false;
|
||||
window_size.Screen? _screen;
|
||||
|
||||
bool get isFullscreen => Get.find<RxBool>(tag: 'fullscreen').isTrue;
|
||||
void _setFullscreen(bool v) {
|
||||
@ -108,12 +111,34 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
},
|
||||
onPressed: () {
|
||||
_show.value = !_show.value;
|
||||
if (_show.isTrue) {
|
||||
_updateScreen();
|
||||
}
|
||||
},
|
||||
child: Obx(() => Container(
|
||||
color: _hideColor.value,
|
||||
).marginOnly(bottom: 8.0))))));
|
||||
}
|
||||
|
||||
_updateScreen() async {
|
||||
final v = await DesktopMultiWindow.invokeMethod(0, "get_window_info", "");
|
||||
final String valueStr = v;
|
||||
if (valueStr.isEmpty) {
|
||||
_screen = null;
|
||||
} else {
|
||||
final screenMap = jsonDecode(valueStr);
|
||||
_screen = window_size.Screen(
|
||||
Rect.fromLTRB(screenMap['frame']['l'], screenMap['frame']['t'],
|
||||
screenMap['frame']['r'], screenMap['frame']['b']),
|
||||
Rect.fromLTRB(
|
||||
screenMap['visibleFrame']['l'],
|
||||
screenMap['visibleFrame']['t'],
|
||||
screenMap['visibleFrame']['r'],
|
||||
screenMap['visibleFrame']['b']),
|
||||
screenMap['scaleFactor']);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildMenubar(BuildContext context) {
|
||||
final List<Widget> menubarItems = [];
|
||||
if (!isWebDesktop) {
|
||||
@ -594,10 +619,30 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
}
|
||||
|
||||
bool _isWindowCanBeAdjusted(int remoteCount) {
|
||||
if (remoteCount != 1) {
|
||||
return false;
|
||||
}
|
||||
if (_screen == null) {
|
||||
return false;
|
||||
}
|
||||
double scale = _screen!.scaleFactor;
|
||||
double selfWidth = _screen!.frame.width;
|
||||
double selfHeight = _screen!.frame.height;
|
||||
final RxBool fullscreen = Get.find(tag: 'fullscreen');
|
||||
return remoteCount == 1 &&
|
||||
fullscreen.isFalse &&
|
||||
widget.ffi.canvasModel.scale > 1.0;
|
||||
if (fullscreen.isFalse) {
|
||||
selfWidth = _screen!.visibleFrame.width;
|
||||
selfHeight = _screen!.visibleFrame.height;
|
||||
}
|
||||
|
||||
final canvasModel = widget.ffi.canvasModel;
|
||||
final displayWidth = canvasModel.getDisplayWidth();
|
||||
final displayHeight = canvasModel.getDisplayHeight();
|
||||
final requiredWidth = displayWidth +
|
||||
(canvasModel.tabBarHeight + canvasModel.windowBorderWidth * 2);
|
||||
final requiredHeight = displayHeight +
|
||||
(canvasModel.tabBarHeight + canvasModel.windowBorderWidth * 2);
|
||||
return selfWidth > (requiredWidth * scale) &&
|
||||
selfHeight > (requiredHeight * scale);
|
||||
}
|
||||
|
||||
List<MenuEntryBase<String>> _getDisplayMenu(
|
||||
@ -763,25 +808,59 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
0,
|
||||
MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Container(
|
||||
alignment: AlignmentDirectional.center,
|
||||
height: _MenubarTheme.height,
|
||||
child: Text(
|
||||
translate('Adjust Window'),
|
||||
style: style,
|
||||
)),
|
||||
translate('Adjust Window'),
|
||||
style: style,
|
||||
)),
|
||||
proc: () {
|
||||
() async {
|
||||
final wndRect =
|
||||
await WindowController.fromWindowId(widget.windowId)
|
||||
.getFrame();
|
||||
final canvasModel = widget.ffi.canvasModel;
|
||||
final width =
|
||||
canvasModel.size.width + canvasModel.windowBorderWidth * 2;
|
||||
final height = canvasModel.size.height +
|
||||
canvasModel.tabBarHeight +
|
||||
canvasModel.windowBorderWidth * 2;
|
||||
await WindowController.fromWindowId(widget.windowId).setFrame(
|
||||
Rect.fromLTWH(wndRect.left, wndRect.top, width, height));
|
||||
await _updateScreen();
|
||||
if (_screen != null) {
|
||||
double scale = _screen!.scaleFactor;
|
||||
final wndRect =
|
||||
await WindowController.fromWindowId(widget.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
|
||||
double magicWidth =
|
||||
wndRect.right - wndRect.left - mediaSize.width * scale;
|
||||
double magicHeight =
|
||||
wndRect.bottom - wndRect.top - mediaSize.height * scale;
|
||||
|
||||
final canvasModel = widget.ffi.canvasModel;
|
||||
final width = (canvasModel.getDisplayWidth() +
|
||||
canvasModel.windowBorderWidth * 2) *
|
||||
scale +
|
||||
magicWidth;
|
||||
final height = (canvasModel.getDisplayHeight() +
|
||||
canvasModel.tabBarHeight +
|
||||
canvasModel.windowBorderWidth * 2) *
|
||||
scale +
|
||||
magicHeight;
|
||||
double left = wndRect.left + (wndRect.width - width) / 2;
|
||||
double top = wndRect.top + (wndRect.height - height) / 2;
|
||||
|
||||
Rect frameRect = _screen!.frame;
|
||||
final RxBool fullscreen = Get.find(tag: 'fullscreen');
|
||||
if (fullscreen.isFalse) {
|
||||
frameRect = _screen!.visibleFrame;
|
||||
}
|
||||
if (left < frameRect.left) {
|
||||
left = frameRect.left;
|
||||
}
|
||||
if (top < frameRect.top) {
|
||||
top = frameRect.top;
|
||||
}
|
||||
if ((left + width) > frameRect.right) {
|
||||
left = frameRect.right - width;
|
||||
}
|
||||
if ((top + height) > frameRect.bottom) {
|
||||
top = frameRect.bottom - height;
|
||||
}
|
||||
await WindowController.fromWindowId(widget.windowId)
|
||||
.setFrame(Rect.fromLTWH(left, top, width, height));
|
||||
}
|
||||
}();
|
||||
},
|
||||
padding: padding,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,7 +73,12 @@ dependencies:
|
||||
flutter_custom_cursor:
|
||||
git:
|
||||
url: https://github.com/Kingtous/rustdesk_flutter_custom_cursor
|
||||
ref: 4a950fd3a5a228bf5381070a4c803919d5787c07
|
||||
ref: 4a950fd3a5a228bf5381070a4c803919d5787c07
|
||||
window_size:
|
||||
git:
|
||||
url: https://github.com/google/flutter-desktop-embedding.git
|
||||
path: plugins/window_size
|
||||
ref: a738913c8ce2c9f47515382d40827e794a334274
|
||||
get: ^4.6.5
|
||||
visibility_detector: ^0.3.3
|
||||
contextmenu: ^3.0.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user