resolution, mid commit, to debug
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
a603e046e3
commit
07500013ff
@ -19,8 +19,6 @@ import '../../common/widgets/peer_tab_page.dart';
|
||||
import '../../models/platform_model.dart';
|
||||
import '../widgets/button.dart';
|
||||
|
||||
import 'package:flutter_hbb/common/widgets/dialog.dart';
|
||||
|
||||
/// Connection page for connecting to a remote peer.
|
||||
class ConnectionPage extends StatefulWidget {
|
||||
const ConnectionPage({Key? key}) : super(key: key);
|
||||
|
@ -664,71 +664,24 @@ class _ControlMenu extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _DisplayMenu extends StatefulWidget {
|
||||
class ScreenAdjustor {
|
||||
final String id;
|
||||
final FFI ffi;
|
||||
final MenubarState state;
|
||||
final Function(bool) setFullscreen;
|
||||
final Widget pluginItem;
|
||||
_DisplayMenu(
|
||||
{Key? key,
|
||||
required this.id,
|
||||
required this.ffi,
|
||||
required this.state,
|
||||
required this.setFullscreen})
|
||||
: pluginItem = LocationItem.createLocationItem(
|
||||
id,
|
||||
ffi,
|
||||
kLocationClientRemoteToolbarDisplay,
|
||||
true,
|
||||
),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
State<_DisplayMenu> createState() => _DisplayMenuState();
|
||||
}
|
||||
|
||||
class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
final VoidCallback cbExitFullscreen;
|
||||
window_size.Screen? _screen;
|
||||
|
||||
ScreenAdjustor({
|
||||
required this.id,
|
||||
required this.ffi,
|
||||
required this.cbExitFullscreen,
|
||||
});
|
||||
|
||||
bool get isFullscreen => stateGlobal.fullscreen;
|
||||
|
||||
int get windowId => stateGlobal.windowId;
|
||||
|
||||
Map<String, bool> get perms => widget.ffi.ffiModel.permissions;
|
||||
RxBool _isOrignalResolution = true.obs;
|
||||
RxBool _isFitLocalResolution = false.obs;
|
||||
|
||||
PeerInfo get pi => widget.ffi.ffiModel.pi;
|
||||
FfiModel get ffiModel => widget.ffi.ffiModel;
|
||||
FFI get ffi => widget.ffi;
|
||||
String get id => widget.id;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_updateScreen();
|
||||
return _IconSubmenuButton(
|
||||
tooltip: 'Display Settings',
|
||||
svg: "assets/display.svg",
|
||||
ffi: widget.ffi,
|
||||
color: _MenubarTheme.blueColor,
|
||||
hoverColor: _MenubarTheme.hoverBlueColor,
|
||||
menuChildren: [
|
||||
adjustWindow(),
|
||||
viewStyle(),
|
||||
scrollStyle(),
|
||||
imageQuality(),
|
||||
codec(),
|
||||
resolutions(),
|
||||
Divider(),
|
||||
toggles(),
|
||||
widget.pluginItem,
|
||||
]);
|
||||
}
|
||||
|
||||
adjustWindow() {
|
||||
return futureBuilder(
|
||||
future: _isWindowCanBeAdjusted(),
|
||||
future: isWindowCanBeAdjusted(),
|
||||
hasData: (data) {
|
||||
final visible = data as bool;
|
||||
if (!visible) return Offstage();
|
||||
@ -736,18 +689,18 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
children: [
|
||||
MenuButton(
|
||||
child: Text(translate('Adjust Window')),
|
||||
onPressed: _doAdjustWindow,
|
||||
ffi: widget.ffi),
|
||||
onPressed: doAdjustWindow,
|
||||
ffi: ffi),
|
||||
Divider(),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
_doAdjustWindow() async {
|
||||
await _updateScreen();
|
||||
doAdjustWindow() async {
|
||||
await updateScreen();
|
||||
if (_screen != null) {
|
||||
widget.setFullscreen(false);
|
||||
cbExitFullscreen();
|
||||
double scale = _screen!.scaleFactor;
|
||||
final wndRect = await WindowController.fromWindowId(windowId).getFrame();
|
||||
final mediaSize = MediaQueryData.fromWindow(ui.window).size;
|
||||
@ -758,7 +711,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
double magicHeight =
|
||||
wndRect.bottom - wndRect.top - mediaSize.height * scale;
|
||||
|
||||
final canvasModel = widget.ffi.canvasModel;
|
||||
final canvasModel = ffi.canvasModel;
|
||||
final width = (canvasModel.getDisplayWidth() * canvasModel.scale +
|
||||
CanvasModel.leftToEdge +
|
||||
CanvasModel.rightToEdge) *
|
||||
@ -793,7 +746,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
}
|
||||
}
|
||||
|
||||
_updateScreen() async {
|
||||
updateScreen() async {
|
||||
final v = await rustDeskWinManager.call(
|
||||
WindowType.Main, kWindowGetWindowInfo, '');
|
||||
final String valueStr = v;
|
||||
@ -813,8 +766,8 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _isWindowCanBeAdjusted() async {
|
||||
final viewStyle = await bind.sessionGetViewStyle(id: widget.id) ?? '';
|
||||
Future<bool> isWindowCanBeAdjusted() async {
|
||||
final viewStyle = await bind.sessionGetViewStyle(id: id) ?? '';
|
||||
if (viewStyle != kRemoteViewStyleOriginal) {
|
||||
return false;
|
||||
}
|
||||
@ -833,7 +786,7 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
selfHeight = _screen!.frame.height;
|
||||
}
|
||||
|
||||
final canvasModel = widget.ffi.canvasModel;
|
||||
final canvasModel = ffi.canvasModel;
|
||||
final displayWidth = canvasModel.getDisplayWidth();
|
||||
final displayHeight = canvasModel.getDisplayHeight();
|
||||
final requiredWidth =
|
||||
@ -843,6 +796,77 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
return selfWidth > (requiredWidth * scale) &&
|
||||
selfHeight > (requiredHeight * scale);
|
||||
}
|
||||
}
|
||||
|
||||
class _DisplayMenu extends StatefulWidget {
|
||||
final String id;
|
||||
final FFI ffi;
|
||||
final MenubarState state;
|
||||
final Function(bool) setFullscreen;
|
||||
final Widget pluginItem;
|
||||
_DisplayMenu(
|
||||
{Key? key,
|
||||
required this.id,
|
||||
required this.ffi,
|
||||
required this.state,
|
||||
required this.setFullscreen})
|
||||
: pluginItem = LocationItem.createLocationItem(
|
||||
id,
|
||||
ffi,
|
||||
kLocationClientRemoteToolbarDisplay,
|
||||
true,
|
||||
),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
State<_DisplayMenu> createState() => _DisplayMenuState();
|
||||
}
|
||||
|
||||
class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
late final ScreenAdjustor _screenAdjustor = ScreenAdjustor(
|
||||
id: widget.id,
|
||||
ffi: widget.ffi,
|
||||
cbExitFullscreen: () => widget.setFullscreen(false),
|
||||
);
|
||||
|
||||
bool get isFullscreen => stateGlobal.fullscreen;
|
||||
int get windowId => stateGlobal.windowId;
|
||||
Map<String, bool> get perms => widget.ffi.ffiModel.permissions;
|
||||
PeerInfo get pi => widget.ffi.ffiModel.pi;
|
||||
FfiModel get ffiModel => widget.ffi.ffiModel;
|
||||
FFI get ffi => widget.ffi;
|
||||
String get id => widget.id;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_screenAdjustor.updateScreen();
|
||||
return _IconSubmenuButton(
|
||||
tooltip: 'Display Settings',
|
||||
svg: "assets/display.svg",
|
||||
ffi: widget.ffi,
|
||||
color: _MenubarTheme.blueColor,
|
||||
hoverColor: _MenubarTheme.hoverBlueColor,
|
||||
menuChildren: [
|
||||
_screenAdjustor.adjustWindow(),
|
||||
viewStyle(),
|
||||
scrollStyle(),
|
||||
imageQuality(),
|
||||
codec(),
|
||||
_ResolutionsMenu(
|
||||
id: widget.id,
|
||||
ffi: widget.ffi,
|
||||
screenAdjustor: _screenAdjustor,
|
||||
),
|
||||
Divider(),
|
||||
toggles(),
|
||||
widget.pluginItem,
|
||||
]);
|
||||
}
|
||||
|
||||
viewStyle() {
|
||||
return futureBuilder(
|
||||
@ -941,70 +965,6 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
});
|
||||
}
|
||||
|
||||
resolutions() {
|
||||
final resolutions = pi.resolutions;
|
||||
final visible = ffiModel.keyboard && resolutions.length > 1;
|
||||
if (!visible) return Offstage();
|
||||
final display = ffiModel.display;
|
||||
final groupValue = "${display.width}x${display.height}";
|
||||
onChanged(String? value) async {
|
||||
if (value == null) return;
|
||||
|
||||
final list = value.split('x');
|
||||
if (list.length == 2) {
|
||||
final w = int.tryParse(list[0]);
|
||||
final h = int.tryParse(list[1]);
|
||||
if (w != null && h != null) {
|
||||
await bind.sessionChangeResolution(
|
||||
id: widget.id, width: w, height: h);
|
||||
Future.delayed(Duration(seconds: 3), () async {
|
||||
final display = ffiModel.display;
|
||||
if (w == display.width && h == display.height) {
|
||||
if (await _isWindowCanBeAdjusted()) {
|
||||
_doAdjustWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _SubmenuButton(
|
||||
ffi: widget.ffi,
|
||||
menuChildren: [
|
||||
RdoMenuButton(
|
||||
value: _kResolutionOrigin,
|
||||
groupValue: groupValue,
|
||||
onChanged: onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text('Origin'),
|
||||
),
|
||||
RdoMenuButton(
|
||||
value: _kResolutionFitLocal,
|
||||
groupValue: groupValue,
|
||||
onChanged: onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text('Fit local'),
|
||||
),
|
||||
// RdoMenuButton(
|
||||
// value: _kResolutionCustom,
|
||||
// groupValue: groupValue,
|
||||
// onChanged: onChanged,
|
||||
// ffi: widget.ffi,
|
||||
// child: Text('Custom resolution'),
|
||||
// ),
|
||||
] +
|
||||
resolutions
|
||||
.map((e) => RdoMenuButton(
|
||||
value: '${e.width}x${e.height}',
|
||||
groupValue: groupValue,
|
||||
onChanged: onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text('${e.width}x${e.height}')))
|
||||
.toList(),
|
||||
child: Text(translate("Resolution")));
|
||||
}
|
||||
|
||||
toggles() {
|
||||
return futureBuilder(
|
||||
future: toolbarDisplayToggle(context, id, ffi),
|
||||
@ -1023,6 +983,242 @@ class _DisplayMenuState extends State<_DisplayMenu> {
|
||||
}
|
||||
}
|
||||
|
||||
class _ResolutionsMenu extends StatefulWidget {
|
||||
final String id;
|
||||
final FFI ffi;
|
||||
final ScreenAdjustor screenAdjustor;
|
||||
|
||||
_ResolutionsMenu({
|
||||
Key? key,
|
||||
required this.id,
|
||||
required this.ffi,
|
||||
required this.screenAdjustor,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<_ResolutionsMenu> createState() => _ResolutionsMenuState();
|
||||
}
|
||||
|
||||
class _ResolutionsMenuState extends State<_ResolutionsMenu> {
|
||||
String _groupValue = '';
|
||||
Resolution? _localResolution;
|
||||
late final _customWidth =
|
||||
TextEditingController(text: display.width.toString());
|
||||
late final _customHeight =
|
||||
TextEditingController(text: display.height.toString());
|
||||
|
||||
PeerInfo get pi => widget.ffi.ffiModel.pi;
|
||||
FfiModel get ffiModel => widget.ffi.ffiModel;
|
||||
Display get display => ffiModel.display;
|
||||
List<Resolution> get resolutions => pi.resolutions;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final visible = ffiModel.keyboard && resolutions.length > 1;
|
||||
if (!visible) return Offstage();
|
||||
_groupValue = "${display.width}x${display.height}";
|
||||
|
||||
_getLocalResolution();
|
||||
return _SubmenuButton(
|
||||
ffi: widget.ffi,
|
||||
menuChildren: <Widget>[
|
||||
_OriginalResolutionMenuButton(),
|
||||
_FitLocalResolutionMenuButton(),
|
||||
_customResolutionMenuButton(),
|
||||
] +
|
||||
_supportedResolutionMenuButtons(),
|
||||
child: Text(translate("Resolution")));
|
||||
}
|
||||
|
||||
_getLocalResolution() {
|
||||
_localResolution = null;
|
||||
final String currentDisplay = bind.mainGetCurrentDisplay();
|
||||
if (currentDisplay.isNotEmpty) {
|
||||
try {
|
||||
final display = json.decode(currentDisplay);
|
||||
if (display['w'] != null && display['h'] != null) {
|
||||
_localResolution = Resolution(display['w'], display['h']);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Failed to decode $currentDisplay, $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onChanged(String? value) async {
|
||||
if (value == null) return;
|
||||
|
||||
int? w;
|
||||
int? h;
|
||||
if (value == _kResolutionOrigin) {
|
||||
w = display.originalWidth;
|
||||
h = display.originalHeight;
|
||||
} else if (value == _kResolutionFitLocal) {
|
||||
final resolution = _getBestFitResolution();
|
||||
if (resolution != null) {
|
||||
w = resolution.width;
|
||||
h = resolution.height;
|
||||
}
|
||||
} else if (value == _kResolutionCustom) {
|
||||
debugPrint(
|
||||
'REMOVE ME ======================= ${_customWidth.value} ${_customHeight.value}');
|
||||
w = int.tryParse(_customWidth.value as String);
|
||||
h = int.tryParse(_customHeight.value as String);
|
||||
} else {
|
||||
final list = value.split('x');
|
||||
if (list.length == 2) {
|
||||
w = int.tryParse(list[0]);
|
||||
h = int.tryParse(list[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (w != null && h != null) {
|
||||
await bind.sessionChangeResolution(
|
||||
id: widget.id,
|
||||
width: w,
|
||||
height: h,
|
||||
);
|
||||
Future.delayed(Duration(seconds: 3), () async {
|
||||
final display = ffiModel.display;
|
||||
if (w == display.width && h == display.height) {
|
||||
if (await widget.screenAdjustor.isWindowCanBeAdjusted()) {
|
||||
widget.screenAdjustor.doAdjustWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _OriginalResolutionMenuButton() {
|
||||
return Offstage(
|
||||
offstage: display.isOriginalResolution,
|
||||
child: RdoMenuButton(
|
||||
value: _kResolutionOrigin,
|
||||
groupValue: _groupValue,
|
||||
onChanged: _onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text(
|
||||
'${translate('Original')} ${display.originalWidth}x${display.originalHeight}'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _FitLocalResolutionMenuButton() {
|
||||
return Offstage(
|
||||
offstage: _isRemoteResolutionFitLocal(),
|
||||
child: RdoMenuButton(
|
||||
value: _kResolutionFitLocal,
|
||||
groupValue: _groupValue,
|
||||
onChanged: _onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text(
|
||||
'${translate('Fit Local')} ${display.originalWidth}x${display.originalHeight}'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _supportedResolutionMenuButtons() => resolutions
|
||||
.map((e) => RdoMenuButton(
|
||||
value: '${e.width}x${e.height}',
|
||||
groupValue: _groupValue,
|
||||
onChanged: _onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: Text('${e.width}x${e.height}')))
|
||||
.toList();
|
||||
|
||||
Widget _customResolutionMenuButton() {
|
||||
return Offstage(
|
||||
offstage: _isRemoteResolutionFitLocal(),
|
||||
child: RdoMenuButton(
|
||||
value: _kResolutionCustom,
|
||||
groupValue: _groupValue,
|
||||
onChanged: _onChanged,
|
||||
ffi: widget.ffi,
|
||||
child: _customResolutionWidget(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _customResolutionWidget() {
|
||||
return Column(
|
||||
children: [
|
||||
Text(translate('Custom')),
|
||||
SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
_resolutionInput(_customWidth),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
),
|
||||
Text('x'),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
),
|
||||
_resolutionInput(_customHeight),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
TextField _resolutionInput(TextEditingController controller) {
|
||||
return TextField(
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
LengthLimitingTextInputFormatter(4),
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
|
||||
],
|
||||
controller: controller,
|
||||
);
|
||||
}
|
||||
|
||||
Resolution? _getBestFitResolution() {
|
||||
if (_localResolution == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
squareDistance(Resolution lhs, Resolution rhs) =>
|
||||
(lhs.width - rhs.width) * (lhs.width - rhs.width) +
|
||||
(lhs.height - rhs.height) * (lhs.height - rhs.height);
|
||||
|
||||
Resolution? res;
|
||||
for (final r in resolutions) {
|
||||
if (r.width <= _localResolution!.width &&
|
||||
r.height <= _localResolution!.height) {
|
||||
if (res == null) {
|
||||
res = r;
|
||||
} else {
|
||||
if (squareDistance(r, _localResolution!) <
|
||||
squareDistance(res, _localResolution!)) {
|
||||
res = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool _isRemoteResolutionFitLocal() {
|
||||
if (_localResolution == null) {
|
||||
return true;
|
||||
}
|
||||
final bestFitResolution = _getBestFitResolution();
|
||||
if (bestFitResolution == null) {
|
||||
return true;
|
||||
}
|
||||
return bestFitResolution.width == display.width &&
|
||||
bestFitResolution.height == display.height;
|
||||
}
|
||||
}
|
||||
|
||||
class _KeyboardMenu extends StatelessWidget {
|
||||
final String id;
|
||||
final FFI ffi;
|
||||
|
@ -295,11 +295,15 @@ class FfiModel with ChangeNotifier {
|
||||
handleSwitchDisplay(Map<String, dynamic> evt, String peerId) {
|
||||
_pi.currentDisplay = int.parse(evt['display']);
|
||||
var newDisplay = Display();
|
||||
newDisplay.x = double.parse(evt['x']);
|
||||
newDisplay.y = double.parse(evt['y']);
|
||||
newDisplay.width = int.parse(evt['width']);
|
||||
newDisplay.height = int.parse(evt['height']);
|
||||
newDisplay.cursorEmbedded = int.parse(evt['cursor_embedded']) == 1;
|
||||
newDisplay.x = double.tryParse(evt['x']) ?? newDisplay.x;
|
||||
newDisplay.y = double.tryParse(evt['y']) ?? newDisplay.y;
|
||||
newDisplay.width = int.tryParse(evt['width']) ?? newDisplay.width;
|
||||
newDisplay.height = int.tryParse(evt['height']) ?? newDisplay.height;
|
||||
newDisplay.cursorEmbedded = int.tryParse(evt['cursor_embedded']) == 1;
|
||||
newDisplay.originalWidth =
|
||||
int.tryParse(evt['original_width']) ?? newDisplay.originalWidth;
|
||||
newDisplay.originalHeight =
|
||||
int.tryParse(evt['original_height']) ?? newDisplay.originalHeight;
|
||||
|
||||
_updateCurDisplay(peerId, newDisplay);
|
||||
|
||||
@ -466,14 +470,7 @@ class FfiModel with ChangeNotifier {
|
||||
_pi.displays = [];
|
||||
List<dynamic> displays = json.decode(evt['displays']);
|
||||
for (int i = 0; i < displays.length; ++i) {
|
||||
Map<String, dynamic> d0 = displays[i];
|
||||
var d = Display();
|
||||
d.x = d0['x'].toDouble();
|
||||
d.y = d0['y'].toDouble();
|
||||
d.width = d0['width'];
|
||||
d.height = d0['height'];
|
||||
d.cursorEmbedded = d0['cursor_embedded'] == 1;
|
||||
_pi.displays.add(d);
|
||||
_pi.displays.add(evtToDisplay(displays[i]));
|
||||
}
|
||||
stateGlobal.displaysCount.value = _pi.displays.length;
|
||||
if (_pi.currentDisplay < _pi.displays.length) {
|
||||
@ -533,20 +530,25 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Display evtToDisplay(Map<String, dynamic> evt) {
|
||||
var d = Display();
|
||||
d.x = evt['x']?.toDouble() ?? d.x;
|
||||
d.y = evt['y']?.toDouble() ?? d.y;
|
||||
d.width = evt['width'] ?? d.width;
|
||||
d.height = evt['height'] ?? d.height;
|
||||
d.cursorEmbedded = evt['cursor_embedded'] == 1;
|
||||
d.originalWidth = evt['original_width'] ?? d.originalWidth;
|
||||
d.originalHeight = evt['original_height'] ?? d.originalHeight;
|
||||
return d;
|
||||
}
|
||||
|
||||
/// Handle the peer info synchronization event based on [evt].
|
||||
handleSyncPeerInfo(Map<String, dynamic> evt, String peerId) async {
|
||||
if (evt['displays'] != null) {
|
||||
List<dynamic> displays = json.decode(evt['displays']);
|
||||
List<Display> newDisplays = [];
|
||||
for (int i = 0; i < displays.length; ++i) {
|
||||
Map<String, dynamic> d0 = displays[i];
|
||||
var d = Display();
|
||||
d.x = d0['x'].toDouble();
|
||||
d.y = d0['y'].toDouble();
|
||||
d.width = d0['width'];
|
||||
d.height = d0['height'];
|
||||
d.cursorEmbedded = d0['cursor_embedded'] == 1;
|
||||
newDisplays.add(d);
|
||||
newDisplays.add(evtToDisplay(displays[i]));
|
||||
}
|
||||
_pi.displays = newDisplays;
|
||||
stateGlobal.displaysCount.value = _pi.displays.length;
|
||||
@ -1718,6 +1720,8 @@ class Display {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
bool cursorEmbedded = false;
|
||||
int originalWidth = 0;
|
||||
int originalHeight = 0;
|
||||
|
||||
Display() {
|
||||
width = (isDesktop || isWebDesktop)
|
||||
@ -1740,6 +1744,9 @@ class Display {
|
||||
other.width == width &&
|
||||
other.height == height &&
|
||||
other.cursorEmbedded == cursorEmbedded;
|
||||
|
||||
bool get isOriginalResolution =>
|
||||
width == originalWidth && height == originalHeight;
|
||||
}
|
||||
|
||||
class Resolution {
|
||||
|
@ -1211,6 +1211,14 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
s.cursor_embedded,
|
||||
);
|
||||
}
|
||||
let custom_resolution = if s.width != s.original_resolution.width
|
||||
|| s.height != s.original_resolution.height
|
||||
{
|
||||
Some((s.width, s.height))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.handler.set_custom_resolution(custom_resolution);
|
||||
}
|
||||
Some(misc::Union::CloseReason(c)) => {
|
||||
self.handler.msgbox("error", "Connection Error", &c, "");
|
||||
|
@ -286,6 +286,8 @@ impl FlutterHandler {
|
||||
h.insert("width", d.width);
|
||||
h.insert("height", d.height);
|
||||
h.insert("cursor_embedded", if d.cursor_embedded { 1 } else { 0 });
|
||||
h.insert("original_width", d.original_resolution.width);
|
||||
h.insert("original_height", d.original_resolution.height);
|
||||
msg_vec.push(h);
|
||||
}
|
||||
serde_json::ser::to_string(&msg_vec).unwrap_or("".to_owned())
|
||||
@ -618,6 +620,14 @@ impl InvokeUiSession for FlutterHandler {
|
||||
.to_string(),
|
||||
),
|
||||
("resolutions", &resolutions),
|
||||
(
|
||||
"original_width",
|
||||
&display.original_resolution.width.to_string(),
|
||||
),
|
||||
(
|
||||
"original_height",
|
||||
&display.original_resolution.height.to_string(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -880,6 +880,18 @@ pub fn main_handle_relay_id(id: String) -> String {
|
||||
handle_relay_id(id)
|
||||
}
|
||||
|
||||
pub fn main_get_current_display() -> SyncReturn<String> {
|
||||
let display_info = match crate::video_service::get_current_display() {
|
||||
Ok((_, _, display)) => serde_json::to_string(&HashMap::from([
|
||||
("w", display.width()),
|
||||
("h", display.height()),
|
||||
]))
|
||||
.unwrap_or_default(),
|
||||
Err(..) => "".to_string(),
|
||||
};
|
||||
SyncReturn(display_info)
|
||||
}
|
||||
|
||||
pub fn session_add_port_forward(
|
||||
id: String,
|
||||
local_port: i32,
|
||||
@ -1426,10 +1438,10 @@ pub fn plugin_event(_id: String, _peer: String, _event: Vec<u8>) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plugin_register_event_stream(id: String, event2ui: StreamSink<EventToUI>) {
|
||||
pub fn plugin_register_event_stream(_id: String, _event2ui: StreamSink<EventToUI>) {
|
||||
#[cfg(feature = "plugin_framework")]
|
||||
{
|
||||
crate::plugin::native_handlers::session::session_register_event_stream(id, event2ui);
|
||||
crate::plugin::native_handlers::session::session_register_event_stream(_id, _event2ui);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1577,16 +1589,16 @@ pub fn plugin_list_reload() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plugin_install(id: String, b: bool) {
|
||||
pub fn plugin_install(_id: String, _b: bool) {
|
||||
#[cfg(feature = "plugin_framework")]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
{
|
||||
if b {
|
||||
if _b {
|
||||
if let Err(e) = crate::plugin::install_plugin(&id) {
|
||||
log::error!("Failed to install plugin '{}': {}", id, e);
|
||||
}
|
||||
} else {
|
||||
crate::plugin::uninstall_plugin(&id, true);
|
||||
crate::plugin::uninstall_plugin(&_id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -829,11 +829,12 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_custom_resolution(&mut self, wh: Option<(i32, i32)>) {
|
||||
self.lc.write().unwrap().set_custom_resolution(wh);
|
||||
}
|
||||
|
||||
pub fn change_resolution(&self, width: i32, height: i32) {
|
||||
self.lc
|
||||
.write()
|
||||
.unwrap()
|
||||
.set_custom_resolution(Some((width, height)));
|
||||
let mut misc = Misc::new();
|
||||
misc.set_change_resolution(Resolution {
|
||||
width,
|
||||
|
Loading…
x
Reference in New Issue
Block a user