Revert "Fix Adjust Window sizing across DPI (#15592)" (#15620)

This reverts commit 61f0944990.
This commit is contained in:
RustDesk
2026-07-18 16:37:30 +08:00
committed by GitHub
parent 61f0944990
commit 082a5a2a4e

View File

@@ -1348,7 +1348,7 @@ class ScreenAdjustor {
adjustWindow(BuildContext context) { adjustWindow(BuildContext context) {
return futureBuilder( return futureBuilder(
future: isWindowCanBeAdjusted(context), future: isWindowCanBeAdjusted(),
hasData: (data) { hasData: (data) {
final visible = data as bool; final visible = data as bool;
if (!visible) return Offstage(); if (!visible) return Offstage();
@@ -1364,29 +1364,20 @@ class ScreenAdjustor {
}); });
} }
Future<Rect?> _getAdjustedWindowFrame(Size mediaSize) async { doAdjustWindow(BuildContext context) async {
final screen = _screen; await updateScreen();
if (screen != null) { if (_screen != null) {
// Windows window frames use physical pixels while Flutter view sizes are cbExitFullscreen();
// logical. macOS and Linux window frames use the same units as Flutter. double scale = _screen!.scaleFactor;
double scale = isWindows ? screen.scaleFactor : 1.0; final wndRect = await WindowController.fromWindowId(windowId).getFrame();
final Rect wndRect; final mediaSize = MediaQueryData.fromView(View.of(context)).size;
try { // On windows, wndRect is equal to GetWindowRect and mediaSize is equal to GetClientRect.
wndRect = await WindowController.fromWindowId(windowId).getFrame();
} catch (e) {
debugPrint(
"Failed to get frame of window $windowId, it may be hidden");
return null;
}
// On Windows, wndRect is GetWindowRect while mediaSize is 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;
// canvasModel.scale is the rendered scale and already applies kIgnoreDpi.
// Use it instead of the remote source resolution.
final width = (canvasModel.getDisplayWidth() * canvasModel.scale + final width = (canvasModel.getDisplayWidth() * canvasModel.scale +
CanvasModel.leftToEdge + CanvasModel.leftToEdge +
CanvasModel.rightToEdge) * CanvasModel.rightToEdge) *
@@ -1400,36 +1391,9 @@ class ScreenAdjustor {
double left = wndRect.left + (wndRect.width - width) / 2; double left = wndRect.left + (wndRect.width - width) / 2;
double top = wndRect.top + (wndRect.height - height) / 2; double top = wndRect.top + (wndRect.height - height) / 2;
// Adjust Window exits fullscreen before setting the window frame. Rect frameRect = _screen!.frame;
Rect frameRect = screen.visibleFrame; if (!isFullscreen) {
if (isLinux && bind.mainCurrentIsWayland()) { frameRect = _screen!.visibleFrame;
// In testing, Wayland at 200% reported an unscaled screen frame while
// GTK window sizes used logical units, so convert the frame first.
double screenScale = screen.scaleFactor;
if (screenScale > 1) {
frameRect = Rect.fromLTRB(
frameRect.left / screenScale,
frameRect.top / screenScale,
frameRect.right / screenScale,
frameRect.bottom / screenScale,
);
}
}
// A window frame cannot be smaller than its client area. Tolerate small
// floating-point differences; larger negative values mean the native
// frame and Flutter view metrics are not synchronized.
if (magicWidth < -0.1 || magicHeight < -0.1) {
return null;
}
// Transient fullscreen metrics once produced a calculated 4.0x60.0
// target frame. Reject implausibly small targets to avoid hiding the window.
if (width < 300 || height < 300) {
return null;
}
// The remote size may change after the menu is built. Require the target
// frame to be strictly smaller than the available screen area.
if (width >= frameRect.width || height >= frameRect.height) {
return null;
} }
if (left < frameRect.left) { if (left < frameRect.left) {
left = frameRect.left; left = frameRect.left;
@@ -1443,45 +1407,8 @@ class ScreenAdjustor {
if ((top + height) > frameRect.bottom) { if ((top + height) > frameRect.bottom) {
top = frameRect.bottom - height; top = frameRect.bottom - height;
} }
return Rect.fromLTWH(left, top, width, height); await WindowController.fromWindowId(windowId)
} .setFrame(Rect.fromLTWH(left, top, width, height));
return null;
}
doAdjustWindow([BuildContext? context]) async {
// A resolution change is adjusted after a delay, when the menu context may
// already be disposed. Each desktop_multi_window window has its own engine,
// so that engine's first view is the current window.
final views = WidgetsBinding.instance.platformDispatcher.views;
if (context == null && views.isEmpty) {
return;
}
final view = context != null
? View.of(context)
: views.first;
await updateScreen();
if (_screen != null) {
final wc = WindowController.fromWindowId(windowId);
final wasFullscreen = isFullscreen;
cbExitFullscreen();
if (wasFullscreen) {
// Wait for the native fullscreen exit to update the window frame.
await Future.delayed(Duration(milliseconds: 700));
await updateScreen();
}
if (isLinux) {
if (await wc.isMaximized()) {
// setFrame may be ignored while the native window is maximized.
await wc.unmaximize();
stateGlobal.setMaximized(false);
}
}
final mediaSize = MediaQueryData.fromView(view).size;
final frame = await _getAdjustedWindowFrame(mediaSize);
if (frame == null) {
return;
}
await wc.setFrame(frame);
stateGlobal.setMaximized(false); stateGlobal.setMaximized(false);
} }
} }
@@ -1511,20 +1438,7 @@ class ScreenAdjustor {
return v.result; return v.result;
} }
Future<bool> isWindowCanBeAdjusted([BuildContext? context]) async { Future<bool> isWindowCanBeAdjusted() async {
if (isWeb) {
return false;
}
// Capture the view before awaiting because the menu context may be disposed.
final views = WidgetsBinding.instance.platformDispatcher.views;
if (context == null && views.isEmpty) {
return false;
}
final view = context != null
? View.of(context)
: views.first;
final mediaSize = MediaQueryData.fromView(view).size;
await updateScreen();
final viewStyle = final viewStyle =
await bind.sessionGetViewStyle(sessionId: ffi.sessionId) ?? ''; await bind.sessionGetViewStyle(sessionId: ffi.sessionId) ?? '';
if (viewStyle != kRemoteViewStyleOriginal) { if (viewStyle != kRemoteViewStyleOriginal) {
@@ -1539,7 +1453,23 @@ class ScreenAdjustor {
if (_screen == null) { if (_screen == null) {
return false; return false;
} }
return await _getAdjustedWindowFrame(mediaSize) != null; final scale = kIgnoreDpi ? 1.0 : _screen!.scaleFactor;
double selfWidth = _screen!.visibleFrame.width;
double selfHeight = _screen!.visibleFrame.height;
if (isFullscreen) {
selfWidth = _screen!.frame.width;
selfHeight = _screen!.frame.height;
}
final canvasModel = ffi.canvasModel;
final displayWidth = canvasModel.getDisplayWidth();
final displayHeight = canvasModel.getDisplayHeight();
final requiredWidth =
CanvasModel.leftToEdge + displayWidth + CanvasModel.rightToEdge;
final requiredHeight =
CanvasModel.topToEdge + displayHeight + CanvasModel.bottomToEdge;
return selfWidth > (requiredWidth * scale) &&
selfHeight > (requiredHeight * scale);
} }
} }
@@ -2247,9 +2177,7 @@ class _ResolutionsMenuState extends State<_ResolutionsMenu> {
} }
if (w == rect.width.toInt() && h == rect.height.toInt()) { if (w == rect.width.toInt() && h == rect.height.toInt()) {
if (await widget.screenAdjustor.isWindowCanBeAdjusted()) { if (await widget.screenAdjustor.isWindowCanBeAdjusted()) {
// This delayed callback can outlive the menu State, so its context widget.screenAdjustor.doAdjustWindow(context);
// is unsafe.
widget.screenAdjustor.doAdjustWindow();
} }
} }
}); });