Merge branch 'master' of github.com-rustdesk:rustdesk/rustdesk
This commit is contained in:
commit
3f1a4d581b
@ -1398,6 +1398,17 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
|
|||||||
isMaximized = await wc.isMaximized();
|
isMaximized = await wc.isMaximized();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
const kMinOffset = -10000;
|
||||||
|
const kMaxOffset = 10000;
|
||||||
|
if (position.dx < kMinOffset ||
|
||||||
|
position.dy < kMinOffset ||
|
||||||
|
position.dx > kMaxOffset ||
|
||||||
|
position.dy > kMaxOffset) {
|
||||||
|
debugPrint("Invalid position: $position, ignore saving position");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final pos = LastWindowPosition(
|
final pos = LastWindowPosition(
|
||||||
sz.width, sz.height, position.dx, position.dy, isMaximized);
|
sz.width, sz.height, position.dx, position.dy, isMaximized);
|
||||||
|
@ -4,7 +4,6 @@ import 'dart:ui' as ui;
|
|||||||
|
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/common/shared_state.dart';
|
import 'package:flutter_hbb/common/shared_state.dart';
|
||||||
import 'package:flutter_hbb/consts.dart';
|
import 'package:flutter_hbb/consts.dart';
|
||||||
@ -172,7 +171,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
connectionType.secure.value == ConnectionType.strSecure;
|
connectionType.secure.value == ConnectionType.strSecure;
|
||||||
bool direct =
|
bool direct =
|
||||||
connectionType.direct.value == ConnectionType.strDirect;
|
connectionType.direct.value == ConnectionType.strDirect;
|
||||||
var msgConn;
|
String msgConn;
|
||||||
if (secure && direct) {
|
if (secure && direct) {
|
||||||
msgConn = translate("Direct and encrypted connection");
|
msgConn = translate("Direct and encrypted connection");
|
||||||
} else if (secure && !direct) {
|
} else if (secure && !direct) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui' as ui;
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
@ -360,6 +359,9 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
|||||||
|
|
||||||
triggerAutoHide() => _debouncerHide.value = _debouncerHide.value + 1;
|
triggerAutoHide() => _debouncerHide.value = _debouncerHide.value + 1;
|
||||||
|
|
||||||
|
void _minimize() async =>
|
||||||
|
await WindowController.fromWindowId(windowId).minimize();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -429,6 +431,8 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
|||||||
dragging: _dragging,
|
dragging: _dragging,
|
||||||
fractionX: _fractionX,
|
fractionX: _fractionX,
|
||||||
show: show,
|
show: show,
|
||||||
|
setFullscreen: _setFullscreen,
|
||||||
|
setMinimize: _minimize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -440,8 +444,6 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
|||||||
final List<Widget> toolbarItems = [];
|
final List<Widget> toolbarItems = [];
|
||||||
if (!isWebDesktop) {
|
if (!isWebDesktop) {
|
||||||
toolbarItems.add(_PinMenu(state: widget.state));
|
toolbarItems.add(_PinMenu(state: widget.state));
|
||||||
toolbarItems.add(
|
|
||||||
_FullscreenMenu(state: widget.state, setFullscreen: _setFullscreen));
|
|
||||||
toolbarItems.add(_MobileActionMenu(ffi: widget.ffi));
|
toolbarItems.add(_MobileActionMenu(ffi: widget.ffi));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,27 +551,6 @@ class _PinMenu extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FullscreenMenu extends StatelessWidget {
|
|
||||||
final ToolbarState state;
|
|
||||||
final Function(bool) setFullscreen;
|
|
||||||
bool get isFullscreen => stateGlobal.fullscreen;
|
|
||||||
const _FullscreenMenu(
|
|
||||||
{Key? key, required this.state, required this.setFullscreen})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return _IconMenuButton(
|
|
||||||
assetName:
|
|
||||||
isFullscreen ? "assets/fullscreen_exit.svg" : "assets/fullscreen.svg",
|
|
||||||
tooltip: isFullscreen ? 'Exit Fullscreen' : 'Fullscreen',
|
|
||||||
onPressed: () => setFullscreen(!isFullscreen),
|
|
||||||
color: _ToolbarTheme.blueColor,
|
|
||||||
hoverColor: _ToolbarTheme.hoverBlueColor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MobileActionMenu extends StatelessWidget {
|
class _MobileActionMenu extends StatelessWidget {
|
||||||
final FFI ffi;
|
final FFI ffi;
|
||||||
const _MobileActionMenu({Key? key, required this.ffi}) : super(key: key);
|
const _MobileActionMenu({Key? key, required this.ffi}) : super(key: key);
|
||||||
@ -614,7 +595,7 @@ class _MonitorMenu extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/screen.svg",
|
"assets/screen.svg",
|
||||||
color: Colors.white,
|
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||||
),
|
),
|
||||||
Obx(() {
|
Obx(() {
|
||||||
RxInt display = CurrentDisplayState.find(id);
|
RxInt display = CurrentDisplayState.find(id);
|
||||||
@ -650,7 +631,7 @@ class _MonitorMenu extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/screen.svg",
|
"assets/screen.svg",
|
||||||
color: Colors.white,
|
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
(i + 1).toString(),
|
(i + 1).toString(),
|
||||||
@ -721,7 +702,7 @@ class ScreenAdjustor {
|
|||||||
bool get isFullscreen => stateGlobal.fullscreen;
|
bool get isFullscreen => stateGlobal.fullscreen;
|
||||||
int get windowId => stateGlobal.windowId;
|
int get windowId => stateGlobal.windowId;
|
||||||
|
|
||||||
adjustWindow() {
|
adjustWindow(BuildContext context) {
|
||||||
return futureBuilder(
|
return futureBuilder(
|
||||||
future: isWindowCanBeAdjusted(),
|
future: isWindowCanBeAdjusted(),
|
||||||
hasData: (data) {
|
hasData: (data) {
|
||||||
@ -731,7 +712,7 @@ class ScreenAdjustor {
|
|||||||
children: [
|
children: [
|
||||||
MenuButton(
|
MenuButton(
|
||||||
child: Text(translate('Adjust Window')),
|
child: Text(translate('Adjust Window')),
|
||||||
onPressed: doAdjustWindow,
|
onPressed: () => doAdjustWindow(context),
|
||||||
ffi: ffi),
|
ffi: ffi),
|
||||||
Divider(),
|
Divider(),
|
||||||
],
|
],
|
||||||
@ -739,20 +720,19 @@ class ScreenAdjustor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
doAdjustWindow() async {
|
doAdjustWindow(BuildContext context) async {
|
||||||
await updateScreen();
|
await updateScreen();
|
||||||
if (_screen != null) {
|
if (_screen != null) {
|
||||||
cbExitFullscreen();
|
cbExitFullscreen();
|
||||||
double scale = _screen!.scaleFactor;
|
double scale = _screen!.scaleFactor;
|
||||||
final wndRect = await WindowController.fromWindowId(windowId).getFrame();
|
final wndRect = await WindowController.fromWindowId(windowId).getFrame();
|
||||||
final mediaSize = MediaQueryData.fromWindow(ui.window).size;
|
final mediaSize = MediaQueryData.fromView(View.of(context)).size;
|
||||||
// On windows, wndRect is equal to GetWindowRect and mediaSize is equal to GetClientRect.
|
// On windows, wndRect is equal to GetWindowRect and mediaSize is equal to GetClientRect.
|
||||||
// https://stackoverflow.com/a/7561083
|
// https://stackoverflow.com/a/7561083
|
||||||
double magicWidth =
|
double magicWidth =
|
||||||
wndRect.right - wndRect.left - mediaSize.width * scale;
|
wndRect.right - wndRect.left - mediaSize.width * scale;
|
||||||
double magicHeight =
|
double magicHeight =
|
||||||
wndRect.bottom - wndRect.top - mediaSize.height * scale;
|
wndRect.bottom - wndRect.top - mediaSize.height * scale;
|
||||||
|
|
||||||
final canvasModel = ffi.canvasModel;
|
final canvasModel = ffi.canvasModel;
|
||||||
final width = (canvasModel.getDisplayWidth() * canvasModel.scale +
|
final width = (canvasModel.getDisplayWidth() * canvasModel.scale +
|
||||||
CanvasModel.leftToEdge +
|
CanvasModel.leftToEdge +
|
||||||
@ -895,7 +875,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
|||||||
color: _ToolbarTheme.blueColor,
|
color: _ToolbarTheme.blueColor,
|
||||||
hoverColor: _ToolbarTheme.hoverBlueColor,
|
hoverColor: _ToolbarTheme.hoverBlueColor,
|
||||||
menuChildren: [
|
menuChildren: [
|
||||||
_screenAdjustor.adjustWindow(),
|
_screenAdjustor.adjustWindow(context),
|
||||||
viewStyle(),
|
viewStyle(),
|
||||||
scrollStyle(),
|
scrollStyle(),
|
||||||
imageQuality(),
|
imageQuality(),
|
||||||
@ -1082,9 +1062,9 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
return _SubmenuButton(
|
return _SubmenuButton(
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
menuChildren: <Widget>[
|
menuChildren: <Widget>[
|
||||||
_OriginalResolutionMenuButton(showOriginalBtn),
|
_OriginalResolutionMenuButton(context, showOriginalBtn),
|
||||||
_FitLocalResolutionMenuButton(showFitLocalBtn),
|
_FitLocalResolutionMenuButton(context, showFitLocalBtn),
|
||||||
_customResolutionMenuButton(isVirtualDisplay),
|
_customResolutionMenuButton(context, isVirtualDisplay),
|
||||||
_menuDivider(showOriginalBtn, showFitLocalBtn, isVirtualDisplay),
|
_menuDivider(showOriginalBtn, showFitLocalBtn, isVirtualDisplay),
|
||||||
] +
|
] +
|
||||||
_supportedResolutionMenuButtons(),
|
_supportedResolutionMenuButtons(),
|
||||||
@ -1125,7 +1105,7 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChanged(String? value) async {
|
_onChanged(BuildContext context, String? value) async {
|
||||||
stateGlobal.setLastResolutionGroupValue(
|
stateGlobal.setLastResolutionGroupValue(
|
||||||
widget.id, pi.currentDisplay, value);
|
widget.id, pi.currentDisplay, value);
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
@ -1145,12 +1125,12 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
|
|
||||||
if (w != null && h != null) {
|
if (w != null && h != null) {
|
||||||
if (w != display.width || h != display.height) {
|
if (w != display.width || h != display.height) {
|
||||||
await _changeResolution(w, h);
|
await _changeResolution(context, w, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_changeResolution(int w, int h) async {
|
_changeResolution(BuildContext context, int w, int h) async {
|
||||||
await bind.sessionChangeResolution(
|
await bind.sessionChangeResolution(
|
||||||
sessionId: ffi.sessionId,
|
sessionId: ffi.sessionId,
|
||||||
display: pi.currentDisplay,
|
display: pi.currentDisplay,
|
||||||
@ -1161,18 +1141,19 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
final display = ffiModel.display;
|
final display = ffiModel.display;
|
||||||
if (w == display.width && h == display.height) {
|
if (w == display.width && h == display.height) {
|
||||||
if (await widget.screenAdjustor.isWindowCanBeAdjusted()) {
|
if (await widget.screenAdjustor.isWindowCanBeAdjusted()) {
|
||||||
widget.screenAdjustor.doAdjustWindow();
|
widget.screenAdjustor.doAdjustWindow(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _OriginalResolutionMenuButton(bool showOriginalBtn) {
|
Widget _OriginalResolutionMenuButton(
|
||||||
|
BuildContext context, bool showOriginalBtn) {
|
||||||
return Offstage(
|
return Offstage(
|
||||||
offstage: !showOriginalBtn,
|
offstage: !showOriginalBtn,
|
||||||
child: MenuButton(
|
child: MenuButton(
|
||||||
onPressed: () =>
|
onPressed: () => _changeResolution(
|
||||||
_changeResolution(display.originalWidth, display.originalHeight),
|
context, display.originalWidth, display.originalHeight),
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
child: Text(
|
child: Text(
|
||||||
'${translate('resolution_original_tip')} ${display.originalWidth}x${display.originalHeight}'),
|
'${translate('resolution_original_tip')} ${display.originalWidth}x${display.originalHeight}'),
|
||||||
@ -1180,14 +1161,15 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _FitLocalResolutionMenuButton(bool showFitLocalBtn) {
|
Widget _FitLocalResolutionMenuButton(
|
||||||
|
BuildContext context, bool showFitLocalBtn) {
|
||||||
return Offstage(
|
return Offstage(
|
||||||
offstage: !showFitLocalBtn,
|
offstage: !showFitLocalBtn,
|
||||||
child: MenuButton(
|
child: MenuButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final resolution = _getBestFitResolution();
|
final resolution = _getBestFitResolution();
|
||||||
if (resolution != null) {
|
if (resolution != null) {
|
||||||
_changeResolution(resolution.width, resolution.height);
|
_changeResolution(context, resolution.width, resolution.height);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
@ -1197,13 +1179,13 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _customResolutionMenuButton(isVirtualDisplay) {
|
Widget _customResolutionMenuButton(BuildContext context, isVirtualDisplay) {
|
||||||
return Offstage(
|
return Offstage(
|
||||||
offstage: !isVirtualDisplay,
|
offstage: !isVirtualDisplay,
|
||||||
child: RdoMenuButton(
|
child: RdoMenuButton(
|
||||||
value: _kCustomResolutionValue,
|
value: _kCustomResolutionValue,
|
||||||
groupValue: _groupValue,
|
groupValue: _groupValue,
|
||||||
onChanged: _onChanged,
|
onChanged: (String? value) => _onChanged(context, value),
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -1244,7 +1226,7 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
|||||||
.map((e) => RdoMenuButton(
|
.map((e) => RdoMenuButton(
|
||||||
value: '${e.width}x${e.height}',
|
value: '${e.width}x${e.height}',
|
||||||
groupValue: _groupValue,
|
groupValue: _groupValue,
|
||||||
onChanged: _onChanged,
|
onChanged: (String? value) => _onChanged(context, value),
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
child: Text('${e.width}x${e.height}')))
|
child: Text('${e.width}x${e.height}')))
|
||||||
.toList();
|
.toList();
|
||||||
@ -1597,11 +1579,11 @@ class _IconMenuButtonState extends State<_IconMenuButton> {
|
|||||||
final icon = widget.icon ??
|
final icon = widget.icon ??
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
widget.assetName!,
|
widget.assetName!,
|
||||||
color: Colors.white,
|
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||||
width: _ToolbarTheme.buttonSize,
|
width: _ToolbarTheme.buttonSize,
|
||||||
height: _ToolbarTheme.buttonSize,
|
height: _ToolbarTheme.buttonSize,
|
||||||
);
|
);
|
||||||
final button = SizedBox(
|
var button = SizedBox(
|
||||||
width: _ToolbarTheme.buttonSize,
|
width: _ToolbarTheme.buttonSize,
|
||||||
height: _ToolbarTheme.buttonSize,
|
height: _ToolbarTheme.buttonSize,
|
||||||
child: MenuItemButton(
|
child: MenuItemButton(
|
||||||
@ -1625,6 +1607,12 @@ class _IconMenuButtonState extends State<_IconMenuButton> {
|
|||||||
).marginSymmetric(
|
).marginSymmetric(
|
||||||
horizontal: widget.hMargin ?? _ToolbarTheme.buttonHMargin,
|
horizontal: widget.hMargin ?? _ToolbarTheme.buttonHMargin,
|
||||||
vertical: widget.vMargin ?? _ToolbarTheme.buttonVMargin);
|
vertical: widget.vMargin ?? _ToolbarTheme.buttonVMargin);
|
||||||
|
if (widget.tooltip != null) {
|
||||||
|
button = Tooltip(
|
||||||
|
message: widget.tooltip!,
|
||||||
|
child: button,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (widget.topLevel) {
|
if (widget.topLevel) {
|
||||||
return MenuBar(children: [button]);
|
return MenuBar(children: [button]);
|
||||||
} else {
|
} else {
|
||||||
@ -1668,7 +1656,7 @@ class _IconSubmenuButtonState extends State<_IconSubmenuButton> {
|
|||||||
final icon = widget.icon ??
|
final icon = widget.icon ??
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
widget.svg!,
|
widget.svg!,
|
||||||
color: Colors.white,
|
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||||
width: _ToolbarTheme.buttonSize,
|
width: _ToolbarTheme.buttonSize,
|
||||||
height: _ToolbarTheme.buttonSize,
|
height: _ToolbarTheme.buttonSize,
|
||||||
);
|
);
|
||||||
@ -1817,12 +1805,18 @@ class _DraggableShowHide extends StatefulWidget {
|
|||||||
final RxDouble fractionX;
|
final RxDouble fractionX;
|
||||||
final RxBool dragging;
|
final RxBool dragging;
|
||||||
final RxBool show;
|
final RxBool show;
|
||||||
|
|
||||||
|
final Function(bool) setFullscreen;
|
||||||
|
final Function() setMinimize;
|
||||||
|
|
||||||
const _DraggableShowHide({
|
const _DraggableShowHide({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.sessionId,
|
required this.sessionId,
|
||||||
required this.fractionX,
|
required this.fractionX,
|
||||||
required this.dragging,
|
required this.dragging,
|
||||||
required this.show,
|
required this.show,
|
||||||
|
required this.setFullscreen,
|
||||||
|
required this.setMinimize,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1876,7 +1870,7 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
widget.dragging.value = true;
|
widget.dragging.value = true;
|
||||||
}),
|
}),
|
||||||
onDragEnd: (details) {
|
onDragEnd: (details) {
|
||||||
final mediaSize = MediaQueryData.fromWindow(ui.window).size;
|
final mediaSize = MediaQueryData.fromView(View.of(context)).size;
|
||||||
widget.fractionX.value +=
|
widget.fractionX.value +=
|
||||||
(details.offset.dx - position.dx) / (mediaSize.width - size.width);
|
(details.offset.dx - position.dx) / (mediaSize.width - size.width);
|
||||||
if (widget.fractionX.value < left) {
|
if (widget.fractionX.value < left) {
|
||||||
@ -1901,17 +1895,49 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
minimumSize: MaterialStateProperty.all(const Size(0, 0)),
|
minimumSize: MaterialStateProperty.all(const Size(0, 0)),
|
||||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||||
);
|
);
|
||||||
|
final isFullscreen = stateGlobal.fullscreen;
|
||||||
|
const double iconSize = 20;
|
||||||
final child = Row(
|
final child = Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
_buildDraggable(context),
|
_buildDraggable(context),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
widget.setFullscreen(!isFullscreen);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Tooltip(
|
||||||
|
message: translate(isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'),
|
||||||
|
child: Icon(
|
||||||
|
isFullscreen ? Icons.fullscreen_exit : Icons.fullscreen,
|
||||||
|
size: iconSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: !isFullscreen,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () => widget.setMinimize(),
|
||||||
|
child: Tooltip(
|
||||||
|
message: translate('Minimize'),
|
||||||
|
child: Icon(
|
||||||
|
Icons.remove,
|
||||||
|
size: iconSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => setState(() {
|
onPressed: () => setState(() {
|
||||||
widget.show.value = !widget.show.value;
|
widget.show.value = !widget.show.value;
|
||||||
}),
|
}),
|
||||||
child: Obx((() => Icon(
|
child: Obx((() => Tooltip(
|
||||||
widget.show.isTrue ? Icons.expand_less : Icons.expand_more,
|
message: translate(
|
||||||
size: 20,
|
widget.show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||||
|
child: Icon(
|
||||||
|
widget.show.isTrue ? Icons.expand_less : Icons.expand_more,
|
||||||
|
size: iconSize,
|
||||||
|
),
|
||||||
))),
|
))),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1993,7 +2019,8 @@ class _MultiMonitorMenu extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/screen.svg",
|
"assets/screen.svg",
|
||||||
color: Colors.white,
|
colorFilter:
|
||||||
|
ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => Text(
|
() => Text(
|
||||||
|
@ -65,7 +65,7 @@ class StateGlobal {
|
|||||||
? kMaximizeEdgeSize
|
? kMaximizeEdgeSize
|
||||||
: kWindowEdgeSize;
|
: kWindowEdgeSize;
|
||||||
print(
|
print(
|
||||||
"fullscreen: ${fullscreen}, resizeEdgeSize: ${_resizeEdgeSize.value}");
|
"fullscreen: $fullscreen, resizeEdgeSize: ${_resizeEdgeSize.value}");
|
||||||
_windowBorderWidth.value = fullscreen ? 0 : kWindowBorderWidth;
|
_windowBorderWidth.value = fullscreen ? 0 : kWindowBorderWidth;
|
||||||
WindowController.fromWindowId(windowId)
|
WindowController.fromWindowId(windowId)
|
||||||
.setFullscreen(_fullscreen)
|
.setFullscreen(_fullscreen)
|
||||||
|
@ -181,32 +181,37 @@ pub fn server_clip_file(
|
|||||||
ClipboardFile::MonitorReady => {
|
ClipboardFile::MonitorReady => {
|
||||||
log::debug!("server_monitor_ready called");
|
log::debug!("server_monitor_ready called");
|
||||||
ret = server_monitor_ready(context, conn_id);
|
ret = server_monitor_ready(context, conn_id);
|
||||||
log::debug!("server_monitor_ready called, return {}", ret);
|
log::debug!("server_monitor_ready called, conn_id {}, return {}", conn_id, ret);
|
||||||
}
|
}
|
||||||
ClipboardFile::FormatList { format_list } => {
|
ClipboardFile::FormatList { format_list } => {
|
||||||
log::debug!("server_format_list called");
|
log::debug!("server_format_list called, conn_id {}, format_list: {:?}", conn_id, &format_list);
|
||||||
ret = server_format_list(context, conn_id, format_list);
|
ret = server_format_list(context, conn_id, format_list);
|
||||||
log::debug!("server_format_list called, return {}", ret);
|
log::debug!("server_format_list called, conn_id {}, return {}", conn_id, ret);
|
||||||
}
|
}
|
||||||
ClipboardFile::FormatListResponse { msg_flags } => {
|
ClipboardFile::FormatListResponse { msg_flags } => {
|
||||||
log::debug!("format_list_response called");
|
log::debug!("server_format_list_response called");
|
||||||
ret = server_format_list_response(context, conn_id, msg_flags);
|
ret = server_format_list_response(context, conn_id, msg_flags);
|
||||||
log::debug!("server_format_list_response called, return {}", ret);
|
log::debug!("server_format_list_response called, conn_id {}, msg_flags {}, return {}", conn_id, msg_flags, ret);
|
||||||
}
|
}
|
||||||
ClipboardFile::FormatDataRequest {
|
ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id,
|
requested_format_id,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("format_data_request called");
|
log::debug!("server_format_data_request called");
|
||||||
ret = server_format_data_request(context, conn_id, requested_format_id);
|
ret = server_format_data_request(context, conn_id, requested_format_id);
|
||||||
log::debug!("server_format_data_request called, return {}", ret);
|
log::debug!("server_format_data_request called, conn_id {}, requested_format_id {}, return {}", conn_id, requested_format_id, ret);
|
||||||
}
|
}
|
||||||
ClipboardFile::FormatDataResponse {
|
ClipboardFile::FormatDataResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
format_data,
|
format_data,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("format_data_response called");
|
log::debug!("server_format_data_response called");
|
||||||
ret = server_format_data_response(context, conn_id, msg_flags, format_data);
|
ret = server_format_data_response(context, conn_id, msg_flags, format_data);
|
||||||
log::debug!("server_format_data_response called, return {}", ret);
|
log::debug!(
|
||||||
|
"server_format_data_response called, conn_id {}, msg_flags: {}, return {}",
|
||||||
|
conn_id,
|
||||||
|
msg_flags,
|
||||||
|
ret
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ClipboardFile::FileContentsRequest {
|
ClipboardFile::FileContentsRequest {
|
||||||
stream_id,
|
stream_id,
|
||||||
@ -218,7 +223,7 @@ pub fn server_clip_file(
|
|||||||
have_clip_data_id,
|
have_clip_data_id,
|
||||||
clip_data_id,
|
clip_data_id,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("file_contents_request called");
|
log::debug!("server_file_contents_request called");
|
||||||
ret = server_file_contents_request(
|
ret = server_file_contents_request(
|
||||||
context,
|
context,
|
||||||
conn_id,
|
conn_id,
|
||||||
@ -231,14 +236,24 @@ pub fn server_clip_file(
|
|||||||
have_clip_data_id,
|
have_clip_data_id,
|
||||||
clip_data_id,
|
clip_data_id,
|
||||||
);
|
);
|
||||||
log::debug!("server_file_contents_request called, return {}", ret);
|
log::debug!("server_file_contents_request called, conn_id {}, stream_id: {}, list_index {}, dw_flags {}, n_position_low {}, n_position_high {}, cb_requested {}, have_clip_data_id {}, clip_data_id {}, return {}", conn_id,
|
||||||
|
stream_id,
|
||||||
|
list_index,
|
||||||
|
dw_flags,
|
||||||
|
n_position_low,
|
||||||
|
n_position_high,
|
||||||
|
cb_requested,
|
||||||
|
have_clip_data_id,
|
||||||
|
clip_data_id,
|
||||||
|
ret
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ClipboardFile::FileContentsResponse {
|
ClipboardFile::FileContentsResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("file_contents_response called");
|
log::debug!("server_file_contents_response called");
|
||||||
ret = server_file_contents_response(
|
ret = server_file_contents_response(
|
||||||
context,
|
context,
|
||||||
conn_id,
|
conn_id,
|
||||||
@ -246,7 +261,12 @@ pub fn server_clip_file(
|
|||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
);
|
);
|
||||||
log::debug!("server_file_contents_response called, return {}", ret);
|
log::debug!("server_file_contents_response called, conn_id {}, msg_flags {}, stream_id {}, return {}",
|
||||||
|
conn_id,
|
||||||
|
msg_flags,
|
||||||
|
stream_id,
|
||||||
|
ret
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
@ -515,8 +535,6 @@ extern "C" fn client_format_list(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
clip_format_list: *const CLIPRDR_FORMAT_LIST,
|
clip_format_list: *const CLIPRDR_FORMAT_LIST,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("client_format_list called");
|
|
||||||
|
|
||||||
let conn_id;
|
let conn_id;
|
||||||
let mut format_list: Vec<(i32, String)> = Vec::new();
|
let mut format_list: Vec<(i32, String)> = Vec::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -541,6 +559,7 @@ extern "C" fn client_format_list(
|
|||||||
}
|
}
|
||||||
conn_id = (*clip_format_list).connID as i32;
|
conn_id = (*clip_format_list).connID as i32;
|
||||||
}
|
}
|
||||||
|
log::debug!("client_format_list called, client id: {}, format_list: {:?}", conn_id, &format_list);
|
||||||
let data = ClipboardFile::FormatList { format_list };
|
let data = ClipboardFile::FormatList { format_list };
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
if conn_id == 0 {
|
if conn_id == 0 {
|
||||||
@ -560,14 +579,13 @@ extern "C" fn client_format_list_response(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
format_list_response: *const CLIPRDR_FORMAT_LIST_RESPONSE,
|
format_list_response: *const CLIPRDR_FORMAT_LIST_RESPONSE,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("client_format_list_response called");
|
|
||||||
|
|
||||||
let conn_id;
|
let conn_id;
|
||||||
let msg_flags;
|
let msg_flags;
|
||||||
unsafe {
|
unsafe {
|
||||||
conn_id = (*format_list_response).connID as i32;
|
conn_id = (*format_list_response).connID as i32;
|
||||||
msg_flags = (*format_list_response).msgFlags as i32;
|
msg_flags = (*format_list_response).msgFlags as i32;
|
||||||
}
|
}
|
||||||
|
log::debug!("client_format_list_response called, client id: {}, msg_flags: {}", conn_id, msg_flags);
|
||||||
let data = ClipboardFile::FormatListResponse { msg_flags };
|
let data = ClipboardFile::FormatListResponse { msg_flags };
|
||||||
send_data(conn_id, data);
|
send_data(conn_id, data);
|
||||||
|
|
||||||
@ -578,8 +596,6 @@ extern "C" fn client_format_data_request(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
format_data_request: *const CLIPRDR_FORMAT_DATA_REQUEST,
|
format_data_request: *const CLIPRDR_FORMAT_DATA_REQUEST,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("client_format_data_request called");
|
|
||||||
|
|
||||||
let conn_id;
|
let conn_id;
|
||||||
let requested_format_id;
|
let requested_format_id;
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -589,6 +605,7 @@ extern "C" fn client_format_data_request(
|
|||||||
let data = ClipboardFile::FormatDataRequest {
|
let data = ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id,
|
requested_format_id,
|
||||||
};
|
};
|
||||||
|
log::debug!("client_format_data_request called, conn_id: {}, requested_format_id: {}", conn_id, requested_format_id);
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
send_data(conn_id, data);
|
send_data(conn_id, data);
|
||||||
|
|
||||||
@ -599,8 +616,6 @@ extern "C" fn client_format_data_response(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
format_data_response: *const CLIPRDR_FORMAT_DATA_RESPONSE,
|
format_data_response: *const CLIPRDR_FORMAT_DATA_RESPONSE,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("cconn_idlient_format_data_response called");
|
|
||||||
|
|
||||||
let conn_id;
|
let conn_id;
|
||||||
let msg_flags;
|
let msg_flags;
|
||||||
let format_data;
|
let format_data;
|
||||||
@ -617,6 +632,7 @@ extern "C" fn client_format_data_response(
|
|||||||
.to_vec();
|
.to_vec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log::debug!("client_format_data_response called, client id: {}, msg_flags: {}", conn_id, msg_flags);
|
||||||
let data = ClipboardFile::FormatDataResponse {
|
let data = ClipboardFile::FormatDataResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
format_data,
|
format_data,
|
||||||
@ -630,8 +646,6 @@ extern "C" fn client_file_contents_request(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
file_contents_request: *const CLIPRDR_FILE_CONTENTS_REQUEST,
|
file_contents_request: *const CLIPRDR_FILE_CONTENTS_REQUEST,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("client_file_contents_request called");
|
|
||||||
|
|
||||||
// TODO: support huge file?
|
// TODO: support huge file?
|
||||||
// if (!cliprdr->hasHugeFileSupport)
|
// if (!cliprdr->hasHugeFileSupport)
|
||||||
// {
|
// {
|
||||||
@ -662,7 +676,6 @@ extern "C" fn client_file_contents_request(
|
|||||||
have_clip_data_id = (*file_contents_request).haveClipDataId == TRUE;
|
have_clip_data_id = (*file_contents_request).haveClipDataId == TRUE;
|
||||||
clip_data_id = (*file_contents_request).clipDataId as i32;
|
clip_data_id = (*file_contents_request).clipDataId as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = ClipboardFile::FileContentsRequest {
|
let data = ClipboardFile::FileContentsRequest {
|
||||||
stream_id,
|
stream_id,
|
||||||
list_index,
|
list_index,
|
||||||
@ -673,6 +686,7 @@ extern "C" fn client_file_contents_request(
|
|||||||
have_clip_data_id,
|
have_clip_data_id,
|
||||||
clip_data_id,
|
clip_data_id,
|
||||||
};
|
};
|
||||||
|
log::debug!("client_file_contents_request called, data: {:?}", &data);
|
||||||
send_data(conn_id, data);
|
send_data(conn_id, data);
|
||||||
|
|
||||||
0
|
0
|
||||||
@ -682,8 +696,6 @@ extern "C" fn client_file_contents_response(
|
|||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
file_contents_response: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
|
file_contents_response: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
|
||||||
) -> UINT {
|
) -> UINT {
|
||||||
log::debug!("client_file_contents_response called");
|
|
||||||
|
|
||||||
let conn_id;
|
let conn_id;
|
||||||
let msg_flags;
|
let msg_flags;
|
||||||
let stream_id;
|
let stream_id;
|
||||||
@ -707,6 +719,7 @@ extern "C" fn client_file_contents_response(
|
|||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
};
|
};
|
||||||
|
log::debug!("client_file_contents_response called, conn_id: {}, msg_flags: {}, stream_id: {}", conn_id, msg_flags, stream_id);
|
||||||
send_data(conn_id, data);
|
send_data(conn_id, data);
|
||||||
|
|
||||||
0
|
0
|
||||||
|
@ -1367,6 +1367,11 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
|
|||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
if (!IsClipboardFormatAvailable(CF_HDROP))
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
|
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
|
||||||
|
|
||||||
/* Ignore if other app is holding clipboard */
|
/* Ignore if other app is holding clipboard */
|
||||||
@ -1392,21 +1397,11 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
|
// IsClipboardFormatAvailable(CF_HDROP) is checked above
|
||||||
if (IsClipboardFormatAvailable(CF_HDROP))
|
UINT fsid = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
|
||||||
{
|
UINT fcid = RegisterClipboardFormat(CFSTR_FILECONTENTS);
|
||||||
UINT fsid = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
|
formats[index++].formatId = fsid;
|
||||||
UINT fcid = RegisterClipboardFormat(CFSTR_FILECONTENTS);
|
formats[index++].formatId = fcid;
|
||||||
|
|
||||||
formats[index++].formatId = fsid;
|
|
||||||
formats[index++].formatId = fcid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (formatId = EnumClipboardFormats(formatId) && index < numFormats)
|
|
||||||
formats[index++].formatId = formatId;
|
|
||||||
}
|
|
||||||
|
|
||||||
numFormats = index;
|
numFormats = index;
|
||||||
|
|
||||||
if (!CloseClipboard())
|
if (!CloseClipboard())
|
||||||
|
@ -518,11 +518,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Exit", "Verlaten"),
|
("Exit", "Verlaten"),
|
||||||
("Open", "Open"),
|
("Open", "Open"),
|
||||||
("logout_tip", "Weet je zeker dat je je wilt afmelden?"),
|
("logout_tip", "Weet je zeker dat je je wilt afmelden?"),
|
||||||
("Service", ""),
|
("Service", "Service"),
|
||||||
("Start", ""),
|
("Start", "Start"),
|
||||||
("Stop", ""),
|
("Stop", "Stop"),
|
||||||
("exceed_max_devices", ""),
|
("exceed_max_devices", "Het maximum aantal gecontroleerde apparaten is bereikt."),
|
||||||
("Sync with recent sessions", ""),
|
("Sync with recent sessions", "Recente sessies synchroniseren"),
|
||||||
("Sort tags", ""),
|
("Sort tags", "Labels sorteren"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user