Skip to content

Commit

Permalink
fix: mutlwindow, fullscreen (rustdesk#8123)
Browse files Browse the repository at this point in the history
Signed-off-by: fufesou <[email protected]>
  • Loading branch information
fufesou authored May 23, 2024
1 parent 49b0630 commit b8d9c4c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 35 deletions.
84 changes: 51 additions & 33 deletions flutter/lib/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1569,14 +1569,12 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
late bool isMaximized;
bool isFullscreen = stateGlobal.fullscreen.isTrue ||
(isMacOS && stateGlobal.closeOnFullscreen == true);
setFrameIfMaximized() {
if (isMaximized) {
final pos = bind.getLocalFlutterOption(k: windowFramePrefix + type.name);
var lpos = LastWindowPosition.loadFromString(pos);
position = Offset(
lpos?.offsetWidth ?? position.dx, lpos?.offsetHeight ?? position.dy);
sz = Size(lpos?.width ?? sz.width, lpos?.height ?? sz.height);
}
setPreFrame() {
final pos = bind.getLocalFlutterOption(k: windowFramePrefix + type.name);
var lpos = LastWindowPosition.loadFromString(pos);
position = Offset(
lpos?.offsetWidth ?? position.dx, lpos?.offsetHeight ?? position.dy);
sz = Size(lpos?.width ?? sz.width, lpos?.height ?? sz.height);
}

switch (type) {
Expand All @@ -1588,23 +1586,30 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
// `setResizable(!bind.isIncomingOnly());` in main.dart
isMaximized =
bind.isIncomingOnly() ? false : await windowManager.isMaximized();
position = await windowManager.getPosition();
sz = await windowManager.getSize();
setFrameIfMaximized();
if (isFullscreen || isMaximized) {
setPreFrame();
} else {
position = await windowManager.getPosition();
sz = await windowManager.getSize();
}
break;
default:
final wc = WindowController.fromWindowId(windowId!);
isMaximized = await wc.isMaximized();
final Rect frame;
try {
frame = await wc.getFrame();
} catch (e) {
debugPrint("Failed to get frame of window $windowId, it may be hidden");
return;
if (isFullscreen || isMaximized) {
setPreFrame();
} else {
final Rect frame;
try {
frame = await wc.getFrame();
} catch (e) {
debugPrint(
"Failed to get frame of window $windowId, it may be hidden");
return;
}
position = frame.topLeft;
sz = frame.size;
}
position = frame.topLeft;
sz = frame.size;
setFrameIfMaximized();
break;
}
if (isWindows) {
Expand Down Expand Up @@ -1638,7 +1643,7 @@ Future _saveSessionWindowPosition(WindowType windowType, int windowId,
final remoteList = await DesktopMultiWindow.invokeMethod(
windowId, kWindowEventGetRemoteList, null);
getPeerPos(String peerId) {
if (isMaximized) {
if (isMaximized || isFullscreen) {
final peerPos = bind.mainGetPeerFlutterOptionSync(
id: peerId, k: windowFramePrefix + windowType.name);
var lpos = LastWindowPosition.loadFromString(peerPos);
Expand Down Expand Up @@ -1783,15 +1788,10 @@ Future<bool> restoreWindowPosition(WindowType type,
// No need to check mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs)
// Though "open in tabs" is true and the new window restore peer position, it's ok.
if (type == WindowType.RemoteDesktop && windowId != null && peerId != null) {
// If the restore position is called by main window, and the peer id is not null
// then we may need to get the position by reading the peer config.
// Because the session may not be read at this time.
if (desktopType == DesktopType.main) {
pos = bind.mainGetPeerFlutterOptionSync(
id: peerId, k: windowFramePrefix + type.name);
} else {
pos = await bind.sessionGetFlutterOptionByPeerId(
id: peerId, k: windowFramePrefix + type.name);
final peerPos = bind.mainGetPeerFlutterOptionSync(
id: peerId, k: windowFramePrefix + type.name);
if (peerPos.isNotEmpty) {
pos = peerPos;
}
isRemotePeerPos = pos != null;
}
Expand Down Expand Up @@ -1829,7 +1829,7 @@ Future<bool> restoreWindowPosition(WindowType type,
size.height,
);
debugPrint(
"restore lpos: ${size.width}/${size.height}, offset:${offsetDevicePixelRatio?.offset.dx}/${offsetDevicePixelRatio?.offset.dy}, devicePixelRatio:${offsetDevicePixelRatio?.devicePixelRatio}");
"restore lpos: ${size.width}/${size.height}, offset:${offsetDevicePixelRatio?.offset.dx}/${offsetDevicePixelRatio?.offset.dy}, devicePixelRatio:${offsetDevicePixelRatio?.devicePixelRatio}, isMaximized: ${lpos.isMaximized}, isFullscreen: ${lpos.isFullscreen}");

switch (type) {
case WindowType.Main:
Expand Down Expand Up @@ -1889,10 +1889,19 @@ Future<bool> restoreWindowPosition(WindowType type,
}
}
if (lpos.isFullscreen == true) {
await restoreFrame();
if (!isMacOS) {
stateGlobal.setFullscreen(false);
await restoreFrame();
}
// An duration is needed to avoid the window being restored after fullscreen.
Future.delayed(Duration(milliseconds: 300), () async {
stateGlobal.setFullscreen(true);
if (kWindowId == windowId) {
stateGlobal.setFullscreen(true);
} else {
// If is not current window, we need to send a fullscreen message to `windowId`
DesktopMultiWindow.invokeMethod(
windowId, kWindowEventSetFullscreen, 'true');
}
});
} else if (lpos.isMaximized == true) {
await restoreFrame();
Expand Down Expand Up @@ -2895,6 +2904,15 @@ openMonitorInNewTabOrWindow(int i, String peerId, PeerInfo pi,
kMainWindowId, kWindowEventOpenMonitorSession, jsonEncode(args));
}

setNewConnectWindowFrame(int windowId, String peerId, Rect? screenRect) async {
if (screenRect == null) {
restoreWindowPosition(WindowType.RemoteDesktop,
windowId: windowId, peerId: peerId);
} else {
tryMoveToScreenAndSetFullscreen(screenRect);
}
}

tryMoveToScreenAndSetFullscreen(Rect? screenRect) async {
if (screenRect == null) {
return;
Expand Down
1 change: 1 addition & 0 deletions flutter/lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const String kWindowEventActiveDisplaySession = "active_display_session";
const String kWindowEventGetRemoteList = "get_remote_list";
const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventRemoteWindowCoords = "remote_window_coords";
const String kWindowEventSetFullscreen = "set_fullscreen";

const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventGetCachedSessionData = "get_cached_session_data";
Expand Down
14 changes: 12 additions & 2 deletions flutter/lib/desktop/pages/remote_tab_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,15 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {

void onRemoveId(String id) async {
if (tabController.state.value.tabs.isEmpty) {
stateGlobal.setFullscreen(false, procWnd: false);
if (stateGlobal.fullscreen.isTrue) {
if (isLinux) {
// If the window is left fullscreen and then reuse, the frame state will be incorrect when exit fullscreen the next time.
// State `fullscreen -> hide -> show -> exit fullscreen`, then the window will be maximized and overlapped.
// No idea how the strange state comes, just a **workaround**.
await WindowController.fromWindowId(windowId()).setFullscreen(false);
}
stateGlobal.setFullscreen(false, procWnd: false);
}
// Keep calling until the window status is hidden.
//
// Workaround for Windows:
Expand Down Expand Up @@ -417,7 +425,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
final displays = args['displays'];
final screenRect = parseParamScreenRect(args);
windowOnTop(windowId());
tryMoveToScreenAndSetFullscreen(screenRect);
setNewConnectWindowFrame(windowId(), id!, screenRect);
if (tabController.length == 0) {
// Show the hidden window.
if (isMacOS && stateGlobal.closeOnFullscreen == true) {
Expand Down Expand Up @@ -522,6 +530,8 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
returnValue = jsonEncode(coords.toJson());
}
}
} else if (call.method == kWindowEventSetFullscreen) {
stateGlobal.setFullscreen(call.arguments == 'true');
}
_update_remote_count();
return returnValue;
Expand Down

0 comments on commit b8d9c4c

Please sign in to comment.