O_PATH because we are just pointing at the file, not really opening it. O_NOFOLLOW so we can trash a link not its target. O_CLOEXEC seems unnecessary, but it's what GLib does.
Resolves#5250Resolves#5251
The size can be smaller than required for the localized text; with a default size we get that size and wind up scrolling. Size request will not be honored if we'd have to scroll for that, so the localized text will fit.
This is confusing, but it looks like we pass None to match_game() when the Lutris API says some service game you have corresponds to a another service game from the same service you don't have
I don't understand when this would be true, but it's better not to crash over it.
Resolves#5248
The spinner does not seem to start always when created dynamically. It seems like if blank_overlay has not been shown to the user yet, it fails - even if it is shown before the spinner starts. Once shown to the user, all is good.
This commit works around this by not putting the spinner inside blank_overlay at all, and just pre-creating it.
Rename account.get=("PersonalName") to account.get("PersonaName").
$STEAMROOT/userdata/<AccountID>/config/localconfig.vdf has "PersonaName" inside of file.
We can then show the spinner only if there are 'many' games- I find the GameStore construction is by far the slower part of this, so we can avoid UI flicker this way.
The GameStore is built on a thread regardless, to minimize the chance of the infamous Death Waggle bug. It just looks smoother not to flash the spinner.
You can have a GOG game off the Lutris website that does not download from GOG - you provide the installer file. "Alient Shooter" is one of these.
In this case, we have no appid and can get no extras, and we should not try to get them.
If you click Continue fas enough, you can trigger the prepare_game_files() method to run twice, on two threads concurrently. This results in doubled up files and a duplicate files page in the navigation stack.
This is hard to fix simply or without UI ugliness, so this commit tolerates it.
It adjusts prepare_game_files() to be thread-safer (!) by committing its changes only at the end. The GIL should make this atomic, probably, so the last preparation wins instead of being combined with the other.
The navigation stack will now refuse to add a duplicate page; it still exits the old and re-enters but does not put the second entry in the history, so you'll go back further when you click the Back button.
That should hide the problem with minimal code churn and risk.
I'm not really sure that this code actually runs - there's dead code here for sure, and I can't prove we can ever match an existing game with an api-provided service installer.
Buuut if it does run it can crash us. We can't emi 'game-updated' on a thread, it absolutely hits GTK.
This commit moves the signal to the main thread and adds some error handling to avoid a NoneType error here too.
Super ugly this. Asyncio could do some much better!
Now here's a place where asyncio would clearly have helped.
But, the problem is that the move-game logic runs on a thread and changes the game. It saves the game and *that* fires the 'game-updated' signal. Various bits of the UI handle this to update the UI.
But GTK is not thread-safe at all, and updating the UI from a thread will sometimes crash it.
This commit suppresses the signal, and then manually fires it after the moe completes on the main thread in the AsyncCall callback.
However, we handle the exception here and show a warning dialog about this. The user can choose to just set the location without moving or updating anything - they'll have to fix things up themselves.
Should help with #5223
DLCs you do not own are listed by the GOG api but are _not_ installable, and we will get 404s trying to download the extras for them.
So let's not offer them at all.
This is a bit painful; to do this we extract the downlink information when we pull the extras, and put that in the extras dict.
Then, InstallerWindow keeps the dict rather than just the ID from it; it passes the entire thing back into the service so that the GOG service can obtain the download subdict and it goes from there.
There are minimal changes for itch.io, the only other service with extras. The new code here just strips the IDs out and proceeds as before.
It's better to let users know this feature isn't going to be used. I'd use 'condition' here, but it does not support dynamic updates baed on config settings like the version.
This isn't perfect - a system provided Wine might not be detected at this point. But I think it is likely to be sufficient; the actual check against the Wine exe path remains anyway.
The rather gruff 'not supported' warning remains in any case.
This way the parse/format roundtrip will not be broken by translators getting creative, or forgetting some of the strings.
This does mean we'll lose the translations for playtimes in the next release. I'd hand-fix this, but @strcore has told me not to do this.