We never re-use these but often forget to destroy them. So, this commit schedules an idle-function to destroy them as long as you don't reshow them before them, or destroy them yourself.
The main thing is to defer this until after run() has returned- destroy() resets the result from that function, if it happens first.
Not destroy()-ed though, that makes run() return NONE. The dialog should be destroyed with its parent at the worst, but we need to hide() it to keep it from locking out the parent dialog.
Explicitly destroying a modal dialog makes run() return Gtk.ResponseType.NONE.
So, I've moved the self.destroy() call down to ModelessDialog. That should fix it.
I noticed this as soon as I pushed. Isn't that always the way?
The YES/NO stuff is localized, but it's not markup. The label has the markup; I'll fix the naming and use the localized text for the clipboard, since there's actually no reason not to.
This duplicates the feature name, which is ugly, but the business of using tabs to line up doesn't work anyway; I hope to replace this with a better layout that won't use tabs soon, and then I can fix the duplication.
Move some methods of the runner version dialog into functions, and make others (which seem more tied to the dialog) static-methods.
This, I hope, will prepare for some of this stuff to be separated from the UI code properly.
The static-methods seem more tied to the UI, so I took them half-way - to static-methods instead of functions. At least they can't mess with GTK from the wrong thread this way.
This keeps the actual exceptions available to everything without hitting circular imports; very few things should need access to the backstops as such.
Resolves#5194
We search a bit for the parent of the error dialog, but the error-handler method has to be on the same object as the signal-handler, so let's not search for it.
This was being called via AsyncCall, but as the completion function, which is scheduled via GLib.idle_add().
But it's just one method. I'll just slap a try-except on it to send the error to the UI delegate.
These will return False on error, to disconnect them. We don't want to report the error over and over, and just calling the same code again is likely to trigger it again.
And remove @watch_errors() from addgameswindow.py.
Swizzling, because we don't admit to 'monkey patching' around here.
The error handling can still call into on_watched_error(), for now. But at least the @watch_errors() decorators are out of lutriswindow.py
Truncating the minutes part of a playtime was unstable; format(parse(x) didn't result in 'x'; rounding fixes that. But the unit tests were impacted, so let's update them.
Resolves#5191