diff --git a/flutter/lib/common/widgets/peers_view.dart b/flutter/lib/common/widgets/peers_view.dart index befc73338..a73ef0f0b 100644 --- a/flutter/lib/common/widgets/peers_view.dart +++ b/flutter/lib/common/widgets/peers_view.dart @@ -89,6 +89,7 @@ class _PeersViewState extends State<_PeersView> var _lastChangeTime = DateTime.now(); var _lastQueryPeers = {}; var _lastQueryTime = DateTime.now(); + var _lastWindowRestoreTime = DateTime.now(); var _queryCount = 0; var _exit = false; bool _isActive = true; @@ -117,11 +118,37 @@ class _PeersViewState extends State<_PeersView> @override void onWindowFocus() { _queryCount = 0; + _isActive = true; + } + + @override + void onWindowBlur() { + // We need this comparison because window restore (on Windows) also triggers `onWindowBlur()`. + // Maybe it's a bug of the window manager, but the source code seems to be correct. + // + // Although `onWindowRestore()` is called after `onWindowBlur()` in my test, + // we need the following comparison to ensure that `_isActive` is true in the end. + if (isWindows && DateTime.now().difference(_lastWindowRestoreTime) < + const Duration(milliseconds: 300)) { + return; + } + _queryCount = _maxQueryCount; + _isActive = false; + } + + @override + void onWindowRestore() { + // Window restore (on MacOS and Linux) also triggers `onWindowFocus()`. + // But on Windows, it triggers `onWindowBlur()`, mybe it's a bug of the window manager. + if (!isWindows) return; + _queryCount = 0; + _isActive = true; + _lastWindowRestoreTime = DateTime.now(); } @override void onWindowMinimize() { - _queryCount = _maxQueryCount; + // Window minimize also triggers `onWindowBlur()`. } // This function is required for mobile. @@ -234,10 +261,11 @@ class _PeersViewState extends State<_PeersView> physics: DraggableNeverScrollableScrollPhysics(), itemCount: peers.length, itemBuilder: (BuildContext context, int index) { - return buildOnePeer(peers[index], false).marginOnly( - right: space, - top: index == 0 ? 0 : space / 2, - bottom: space / 2); + return buildOnePeer(peers[index], false) + .marginOnly( + right: space, + top: index == 0 ? 0 : space / 2, + bottom: space / 2); }), ) : DesktopScrollWrapper( diff --git a/flutter/lib/models/peer_model.dart b/flutter/lib/models/peer_model.dart index 188dd4e0b..7ab5a2b80 100644 --- a/flutter/lib/models/peer_model.dart +++ b/flutter/lib/models/peer_model.dart @@ -194,10 +194,14 @@ class Peers extends ChangeNotifier { } void _updateOnlineState(Map evt) { + int changedCount = 0; evt['onlines'].split(',').forEach((online) { for (var i = 0; i < peers.length; i++) { if (peers[i].id == online) { - peers[i].online = true; + if (!peers[i].online) { + changedCount += 1; + peers[i].online = true; + } } } }); @@ -205,13 +209,18 @@ class Peers extends ChangeNotifier { evt['offlines'].split(',').forEach((offline) { for (var i = 0; i < peers.length; i++) { if (peers[i].id == offline) { - peers[i].online = false; + if (peers[i].online) { + changedCount += 1; + peers[i].online = false; + } } } }); - event = UpdateEvent.online; - notifyListeners(); + if (changedCount > 0) { + event = UpdateEvent.online; + notifyListeners(); + } } void _updatePeers(Map evt) {