Save the settings in more cases to avoid losing setting changes (especially on Android) (#14266)

This commit is contained in:
grorp 2024-01-23 21:33:27 +01:00
parent 00f6bd0f08
commit 50edb30a18
4 changed files with 55 additions and 4 deletions

@ -80,6 +80,17 @@ public class GameActivity extends NativeActivity {
makeFullScreen(); makeFullScreen();
} }
private native void saveSettings();
@Override
protected void onStop() {
super.onStop();
// Avoid losing setting changes in case the app is onDestroy()ed later.
// Saving stuff in onStop() is recommended in the Android activity
// lifecycle documentation.
saveSettings();
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
// Ignore the back press so Minetest can handle it // Ignore the back press so Minetest can handle it

@ -608,6 +608,16 @@ local function get_formspec(dialogdata)
end end
-- On Android, closing the app via the "Recents screen" won't result in a clean
-- exit, discarding any setting changes made by the user.
-- To avoid that, we write the settings file in more cases on Android.
function write_settings_early()
if PLATFORM == "Android" then
core.settings:write()
end
end
local function buttonhandler(this, fields) local function buttonhandler(this, fields)
local dialogdata = this.data local dialogdata = this.data
dialogdata.leftscroll = core.explode_scrollbar_event(fields.leftscroll).value or dialogdata.leftscroll dialogdata.leftscroll = core.explode_scrollbar_event(fields.leftscroll).value or dialogdata.leftscroll
@ -622,12 +632,15 @@ local function buttonhandler(this, fields)
if fields.show_technical_names ~= nil then if fields.show_technical_names ~= nil then
local value = core.is_yes(fields.show_technical_names) local value = core.is_yes(fields.show_technical_names)
core.settings:set_bool("show_technical_names", value) core.settings:set_bool("show_technical_names", value)
write_settings_early()
return true return true
end end
if fields.show_advanced ~= nil then if fields.show_advanced ~= nil then
local value = core.is_yes(fields.show_advanced) local value = core.is_yes(fields.show_advanced)
core.settings:set_bool("show_advanced", value) core.settings:set_bool("show_advanced", value)
write_settings_early()
local suggested_page_id = update_filtered_pages(dialogdata.query) local suggested_page_id = update_filtered_pages(dialogdata.query)
@ -672,12 +685,15 @@ local function buttonhandler(this, fields)
for i, comp in ipairs(dialogdata.components) do for i, comp in ipairs(dialogdata.components) do
if comp.on_submit and comp:on_submit(fields, this) then if comp.on_submit and comp:on_submit(fields, this) then
write_settings_early()
-- Clear components so they regenerate -- Clear components so they regenerate
dialogdata.components = nil dialogdata.components = nil
return true return true
end end
if comp.setting and fields["reset_" .. i] then if comp.setting and fields["reset_" .. i] then
core.settings:remove(comp.setting.name) core.settings:remove(comp.setting.name)
write_settings_early()
-- Clear components so they regenerate -- Clear components so they regenerate
dialogdata.components = nil dialogdata.components = nil

@ -247,11 +247,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
} }
// Break out of menu-game loop to shut down cleanly // Break out of menu-game loop to shut down cleanly
if (!m_rendering_engine->run() || *kill) { if (!m_rendering_engine->run() || *kill)
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
break; break;
}
m_rendering_engine->get_video_driver()->setTextureCreationFlag( m_rendering_engine->get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map")); video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
@ -292,6 +289,16 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
receiver->m_touchscreengui = NULL; receiver->m_touchscreengui = NULL;
#endif #endif
/* Save the settings when leaving the game.
* This makes sure that setting changes made in-game are persisted even
* in case of a later unclean exit from the mainmenu.
* This is especially useful on Android because closing the app from the
* "Recents screen" results in an unclean exit.
* Caveat: This means that the settings are saved twice when exiting Minetest.
*/
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
// If no main menu, show error and exit // If no main menu, show error and exit
if (skip_main_menu) { if (skip_main_menu) {
if (!error_message.empty()) { if (!error_message.empty()) {
@ -555,6 +562,16 @@ void ClientLauncher::main_menu(MainMenuData *menudata)
/* leave scene manager in a clean state */ /* leave scene manager in a clean state */
m_rendering_engine->get_scene_manager()->clear(); m_rendering_engine->get_scene_manager()->clear();
/* Save the settings when leaving the mainmenu.
* This makes sure that setting changes made in the mainmenu are persisted
* even in case of a later unclean exit from the game.
* This is especially useful on Android because closing the app from the
* "Recents screen" results in an unclean exit.
* Caveat: This means that the settings are saved twice when exiting Minetest.
*/
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
} }
void ClientLauncher::speed_tests() void ClientLauncher::speed_tests()

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "config.h" #include "config.h"
#include "filesys.h" #include "filesys.h"
#include "log.h" #include "log.h"
#include "settings.h"
#include <sstream> #include <sstream>
#include <exception> #include <exception>
@ -39,6 +40,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
extern int main(int argc, char *argv[]); extern int main(int argc, char *argv[]);
extern "C" JNIEXPORT void JNICALL
Java_net_minetest_minetest_GameActivity_saveSettings(JNIEnv* env, jobject /* this */) {
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
}
void android_main(android_app *app) void android_main(android_app *app)
{ {
int retval = 0; int retval = 0;