fix: mutlwindow, fullscreen (#8123)

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou 2024-05-23 09:51:19 +08:00 committed by GitHub
parent 49b0630752
commit b8d9c4c378
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 35 deletions

View File

@ -1569,14 +1569,12 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
late bool isMaximized; late bool isMaximized;
bool isFullscreen = stateGlobal.fullscreen.isTrue || bool isFullscreen = stateGlobal.fullscreen.isTrue ||
(isMacOS && stateGlobal.closeOnFullscreen == true); (isMacOS && stateGlobal.closeOnFullscreen == true);
setFrameIfMaximized() { setPreFrame() {
if (isMaximized) { final pos = bind.getLocalFlutterOption(k: windowFramePrefix + type.name);
final pos = bind.getLocalFlutterOption(k: windowFramePrefix + type.name); var lpos = LastWindowPosition.loadFromString(pos);
var lpos = LastWindowPosition.loadFromString(pos); position = Offset(
position = Offset( lpos?.offsetWidth ?? position.dx, lpos?.offsetHeight ?? position.dy);
lpos?.offsetWidth ?? position.dx, lpos?.offsetHeight ?? position.dy); sz = Size(lpos?.width ?? sz.width, lpos?.height ?? sz.height);
sz = Size(lpos?.width ?? sz.width, lpos?.height ?? sz.height);
}
} }
switch (type) { switch (type) {
@ -1588,23 +1586,30 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
// `setResizable(!bind.isIncomingOnly());` in main.dart // `setResizable(!bind.isIncomingOnly());` in main.dart
isMaximized = isMaximized =
bind.isIncomingOnly() ? false : await windowManager.isMaximized(); bind.isIncomingOnly() ? false : await windowManager.isMaximized();
position = await windowManager.getPosition(); if (isFullscreen || isMaximized) {
sz = await windowManager.getSize(); setPreFrame();
setFrameIfMaximized(); } else {
position = await windowManager.getPosition();
sz = await windowManager.getSize();
}
break; break;
default: default:
final wc = WindowController.fromWindowId(windowId!); final wc = WindowController.fromWindowId(windowId!);
isMaximized = await wc.isMaximized(); isMaximized = await wc.isMaximized();
final Rect frame; if (isFullscreen || isMaximized) {
try { setPreFrame();
frame = await wc.getFrame(); } else {
} catch (e) { final Rect frame;
debugPrint("Failed to get frame of window $windowId, it may be hidden"); try {
return; 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; break;
} }
if (isWindows) { if (isWindows) {
@ -1638,7 +1643,7 @@ Future _saveSessionWindowPosition(WindowType windowType, int windowId,
final remoteList = await DesktopMultiWindow.invokeMethod( final remoteList = await DesktopMultiWindow.invokeMethod(
windowId, kWindowEventGetRemoteList, null); windowId, kWindowEventGetRemoteList, null);
getPeerPos(String peerId) { getPeerPos(String peerId) {
if (isMaximized) { if (isMaximized || isFullscreen) {
final peerPos = bind.mainGetPeerFlutterOptionSync( final peerPos = bind.mainGetPeerFlutterOptionSync(
id: peerId, k: windowFramePrefix + windowType.name); id: peerId, k: windowFramePrefix + windowType.name);
var lpos = LastWindowPosition.loadFromString(peerPos); var lpos = LastWindowPosition.loadFromString(peerPos);
@ -1783,15 +1788,10 @@ Future<bool> restoreWindowPosition(WindowType type,
// No need to check mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs) // No need to check mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs)
// Though "open in tabs" is true and the new window restore peer position, it's ok. // 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 (type == WindowType.RemoteDesktop && windowId != null && peerId != null) {
// If the restore position is called by main window, and the peer id is not null final peerPos = bind.mainGetPeerFlutterOptionSync(
// then we may need to get the position by reading the peer config. id: peerId, k: windowFramePrefix + type.name);
// Because the session may not be read at this time. if (peerPos.isNotEmpty) {
if (desktopType == DesktopType.main) { pos = peerPos;
pos = bind.mainGetPeerFlutterOptionSync(
id: peerId, k: windowFramePrefix + type.name);
} else {
pos = await bind.sessionGetFlutterOptionByPeerId(
id: peerId, k: windowFramePrefix + type.name);
} }
isRemotePeerPos = pos != null; isRemotePeerPos = pos != null;
} }
@ -1829,7 +1829,7 @@ Future<bool> restoreWindowPosition(WindowType type,
size.height, size.height,
); );
debugPrint( 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) { switch (type) {
case WindowType.Main: case WindowType.Main:
@ -1889,10 +1889,19 @@ Future<bool> restoreWindowPosition(WindowType type,
} }
} }
if (lpos.isFullscreen == true) { 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. // An duration is needed to avoid the window being restored after fullscreen.
Future.delayed(Duration(milliseconds: 300), () async { 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) { } else if (lpos.isMaximized == true) {
await restoreFrame(); await restoreFrame();
@ -2895,6 +2904,15 @@ openMonitorInNewTabOrWindow(int i, String peerId, PeerInfo pi,
kMainWindowId, kWindowEventOpenMonitorSession, jsonEncode(args)); 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 { tryMoveToScreenAndSetFullscreen(Rect? screenRect) async {
if (screenRect == null) { if (screenRect == null) {
return; return;

View File

@ -63,6 +63,7 @@ const String kWindowEventActiveDisplaySession = "active_display_session";
const String kWindowEventGetRemoteList = "get_remote_list"; const String kWindowEventGetRemoteList = "get_remote_list";
const String kWindowEventGetSessionIdList = "get_session_id_list"; const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventRemoteWindowCoords = "remote_window_coords"; const String kWindowEventRemoteWindowCoords = "remote_window_coords";
const String kWindowEventSetFullscreen = "set_fullscreen";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window"; const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventGetCachedSessionData = "get_cached_session_data"; const String kWindowEventGetCachedSessionData = "get_cached_session_data";

View File

@ -350,7 +350,15 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
void onRemoveId(String id) async { void onRemoveId(String id) async {
if (tabController.state.value.tabs.isEmpty) { 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. // Keep calling until the window status is hidden.
// //
// Workaround for Windows: // Workaround for Windows:
@ -417,7 +425,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
final displays = args['displays']; final displays = args['displays'];
final screenRect = parseParamScreenRect(args); final screenRect = parseParamScreenRect(args);
windowOnTop(windowId()); windowOnTop(windowId());
tryMoveToScreenAndSetFullscreen(screenRect); setNewConnectWindowFrame(windowId(), id!, screenRect);
if (tabController.length == 0) { if (tabController.length == 0) {
// Show the hidden window. // Show the hidden window.
if (isMacOS && stateGlobal.closeOnFullscreen == true) { if (isMacOS && stateGlobal.closeOnFullscreen == true) {
@ -522,6 +530,8 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
returnValue = jsonEncode(coords.toJson()); returnValue = jsonEncode(coords.toJson());
} }
} }
} else if (call.method == kWindowEventSetFullscreen) {
stateGlobal.setFullscreen(call.arguments == 'true');
} }
_update_remote_count(); _update_remote_count();
return returnValue; return returnValue;