Skip to content

Comments

Improved Focus handling on seeks#2341

Merged
veloce merged 5 commits intolichess-org:mainfrom
HaonRekcef:wakelockonwwaitingforopp
Nov 26, 2025
Merged

Improved Focus handling on seeks#2341
veloce merged 5 commits intolichess-org:mainfrom
HaonRekcef:wakelockonwwaitingforopp

Conversation

@HaonRekcef
Copy link
Collaborator

Fixes issue reported on lichess: https://lichess.org/forum/team-lichess-beta-testers/mobile-app-alpha?page=16#156
The issue was that while seeking a game the screen could lock or the user could switch to another app without cancelling the seek, which led to game aborts.
Implemented fix:

  • Cancel seek when focus is lost and navigate back (the option would be to try to recreate the challenge or seek instead)
  • Added a Wakelock to prevent the screen from timing out during a seek that take a long time.

@veloce
Copy link
Contributor

veloce commented Nov 6, 2025

Thanks for this. But I don't think we should do that.

When the app goes into background the socket connection remains active for 5 minutes, which means in theory the user is seeking a game for that long. Canceling the seek is certainly better than having aborted games, but it is counterintuitive as how an app should work.
So the real solution would be to send a notification when a game starts, as suggested in the forum. If I'm not mistaken I think it shouldn't be hard as we have already all the code to do that.
For the challenges I think we need as well #2244 (I need to finish that one).
About the Wakelock, I don't think it is needed if we properly send notifications.

@ijm8710
Copy link

ijm8710 commented Nov 7, 2025

Hey guys,

I very much agree with veloces approach on this one, but I’m a bit confused.

Most times i start to look for a game and multitask out of app quickly (say to answer a text) I am almost always greeted with the following error message
IMG_0018
So essentially this sounds great, but I’m confused why it’s assumed we maintain background connection for 5 minutes when I lose it within seconds.

perhaps this relates to when I send challenge requests (not correspondence but real time games) to myself and I lose the request within seconds as well. I really never see the connection maintained in the background. Am I doing something wrong? Or is it different on iOS?

@HaonRekcef
Copy link
Collaborator Author

HaonRekcef commented Nov 7, 2025

When the app goes into background the socket connection remains active for 5 minutes, which means in theory the user is seeking a game for that long.

I am not sure at all that this is the case. I think both OS pause background processes really quickly. For example: https://developer.apple.com/forums/thread/685525/ . So I dont think we can assume the user continues listening to the websocket once the app is backgrounded.

I think a solution would be to get a push notification from lila when a game starts, which we will then only display if the user is currently not in the app, but I guess serverside changes would be needed too for this.

Or we could restart the seek automatically when the user returns the app to the foreground.

@veloce
Copy link
Contributor

veloce commented Nov 7, 2025

Maintaining the websocket connection is not the same as executing code in background. It is true that platforms are somewhat conservative in allowing that. Especially on iOS.
You can test by yourself that the connection is really maintained: it is easy if you have 2 lichess accounts that follow each other. Just watch online friends from an account and put the app in background with the other, you'll see that your friend stays online for 5 minutes after.

It was important to allow the connection to remain active for playing games, otherwise lichess thinks you are disconnected and you may lose games quickly (for longer time controls it is useful).

It is not because the connection is maintained that you can do what you want while challenging real time or seeking a game. The game was never designed to allow this, so this is why you just can't do it. It is not a bug, that is just never been possible.

Now, ideally I think we should allow users to go in the background while searching for a game, as I said above. And if we want to do that, we'll probably have issues with the background execution restrictions, so it is not that simple.
There are ways to do it normally. Platforms authorise background code execution for some specific task, and ideally they should not run for a long time. In our case 5m doesn't seem too long.

This plugin is probably what we want: https://pub.dev/packages/workmanager

@veloce
Copy link
Contributor

veloce commented Nov 7, 2025

I think a solution would be to get a push notification from lila when a game starts, which we will then only display if the user is currently not in the app, but I guess serverside changes would be needed too for this.

I don't think push notifications are the good choice for that. Not reliable enough. Also Thibault probably don't want to do that change server side.

@veloce
Copy link
Contributor

veloce commented Nov 7, 2025

Or we could restart the seek automatically when the user returns the app to the foreground.

We can't do that as people will think the app is looking for a game while in background where actually it is not the case. Very confusing.

@HaonRekcef
Copy link
Collaborator Author

Maintaining the websocket connection is not the same as executing code in background. It is true that platforms are somewhat conservative in allowing that. Especially on iOS. You can test by yourself that the connection is really maintained: it is easy if you have 2 lichess accounts that follow each other. Just watch online friends from an account and put the app in background with the other, you'll see that your friend stays online for 5 minutes after.

I can not replicate. If I watch lichess tv on my Android 15 Phone and check with a browser on my laptop if I am online or not, it switches to offline within 20s of the app being backgrounded. Same for my iPad, there it is even within a few seconds.

@veloce
Copy link
Contributor

veloce commented Nov 7, 2025

I can not replicate. If I watch lichess tv on my Android 15 Phone and check with a browser on my laptop if I am online or not, it switches to offline within 20s of the app being backgrounded. Same for my iPad, there it is even within a few seconds.

that is not the way to do it; try with friends as I suggested. TV socket is closed automatically when the app is backgrounded.
or try locally with your emulator: start a game, put in background, watch in web from the other side you'll see that you are still connected;

@ijm8710
Copy link

ijm8710 commented Nov 7, 2025

Veloce I had two related tickets with repro videos on these comments

Should friend status be preserved for several minutes if they’re not in active game?

#2150

should realtime challenge connection be sent if one has been in the app in past few minutes?

#2149

not sure if I’m misunderstanding how you are saying the websocket connection should work

@HaonRekcef
Copy link
Collaborator Author

that is not the way to do it; try with friends as I suggested. TV socket is closed automatically when the app is backgrounded. or try locally with your emulator: start a game, put in background, watch in web from the other side you'll see that you are still connected;

I still can not replicate, see the attached video:

Socket_closing.mp4

Where the white account was me playing on my phone account and immediately after playing Qxf1 I switched to another app.

@veloce
Copy link
Contributor

veloce commented Nov 8, 2025

Ok, that is interesting. Possibly a regression, thanks for reporting. That thing is tested at the socket level but it definitely should be tested at the game level.

Note that I have tested it with the friend online status and it works (on iOS).

@HaonRekcef
Copy link
Collaborator Author

Ok, that is interesting. Possibly a regression, thanks for reporting. That thing is tested at the socket level but it definitely should be tested at the game level.

Note that I have tested it with the friend online status and it works (on iOS).

Is there any version you want me to test? I tried with my iPad too and while I do not replicate the socket staying alive for 5min it is significantly longer(more than 1 min normally) than on my Android device.

@veloce
Copy link
Contributor

veloce commented Nov 11, 2025

I have no clue about a version sorry. I'm also surprised that there is a difference between android and iOS here, especially since it stays longer on iOS as I would expect the opposite.
I'll also do tests myself because these things are tricky. Using dev tools and watch logs at the FINE level would definitely help to see what is happening in the socket.
You should be able to replicate the socket closing after 5m when in background and see the corresponding log message (so not talking about in game socket here).

@veloce
Copy link
Contributor

veloce commented Nov 11, 2025

@HaonRekcef I confirm as well that on android the websocket shuts down only after a few seconds when the app is put into background. I have no idea why tbh; I am pretty sure that at the time when I first implemented this I had tested that and it was working on android, unless I overlooked android... To investigate...

I don't know what is shutting the connection. I doubt that is at the OS level, because in the previous lichess app socket was definitely staying alive in background on android.

@ijm8710
Copy link

ijm8710 commented Nov 11, 2025

especially since it stays longer on iOS as I would expect the opposite.

Veloce, are you sure it's not an issue on iOS as well

I had created 2 separate issue tickets with videos for each scenario

Would you have expected web socket to apply for either of these where connection was lost in one minute or less

#2341 (comment)

@HaonRekcef HaonRekcef marked this pull request as draft November 13, 2025 12:57
@HaonRekcef HaonRekcef force-pushed the wakelockonwwaitingforopp branch from ed04dac to 8199cc2 Compare November 13, 2025 12:58
@HaonRekcef
Copy link
Collaborator Author

Updated the PR, needs a thorough review as it is quite critical

  • I switched to a AppLifecycleListener instead of the visibility detector, as this seems more in line with what we’re trying to achieve. I think onPause is what we need (onHide is the other option) and it worked as expected on my Android 15 Phone and on the Android 16 Emulator, but this should be tested on iOS and on Android Versions <15 too.
  • Displays that the seek/challenge was cancelled on the screen to give feedback to the user
  • Keeps screen active while seeking with a wakelock

@HaonRekcef HaonRekcef marked this pull request as ready for review November 13, 2025 20:20
switch (widget.source) {
case LobbySource():
ref.read(gameScreenLoaderProvider(widget.source).notifier).cancelSeek();
await ref.read(createGameServiceProvider).cancelSeek();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to call the service from the GameScreenLoader.cancelSeek.

BottomBarButton(
onTap: () => Navigator.of(context).pop(),
label: context.l10n.cancel,
label: showBackButton ? 'Back' : context.l10n.cancel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The label shows Back but the icon is still a cross, this is confusing. Better remove this change and see the other comment.

return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: const SocketPingRatingIcon(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of showing the back button in the bottom bar, remove this widget to show it in the top bar as it should be.

_ => const SizedBox.shrink(),
},
),
body: const LoadGameError('The game search was cancelled.', showBackButton: true),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the showBackButton parameter.

@HaonRekcef
Copy link
Collaborator Author

Addressed the review comments.
I dont think we should have a cancel button when the text says game search has been cancelled so I removed the button.

@veloce veloce merged commit 8e080e0 into lichess-org:main Nov 26, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants