Skip to content

Commit

Permalink
Save the settings in more cases to avoid losing setting changes (espe…
Browse files Browse the repository at this point in the history
…cially on Android) (#14266)
  • Loading branch information
grorp committed May 6, 2024
1 parent 00f6bd0 commit 50edb30
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
11 changes: 11 additions & 0 deletions android/app/src/main/java/net/minetest/minetest/GameActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ protected void onResume() {
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
public void onBackPressed() {
// Ignore the back press so Minetest can handle it
Expand Down
16 changes: 16 additions & 0 deletions builtin/mainmenu/settings/dlg_settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,16 @@ local function get_formspec(dialogdata)
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 dialogdata = this.data
dialogdata.leftscroll = core.explode_scrollbar_event(fields.leftscroll).value or dialogdata.leftscroll
Expand All @@ -622,12 +632,15 @@ local function buttonhandler(this, fields)
if fields.show_technical_names ~= nil then
local value = core.is_yes(fields.show_technical_names)
core.settings:set_bool("show_technical_names", value)
write_settings_early()

return true
end

if fields.show_advanced ~= nil then
local value = core.is_yes(fields.show_advanced)
core.settings:set_bool("show_advanced", value)
write_settings_early()

local suggested_page_id = update_filtered_pages(dialogdata.query)

Expand Down Expand Up @@ -672,12 +685,15 @@ local function buttonhandler(this, fields)

for i, comp in ipairs(dialogdata.components) do
if comp.on_submit and comp:on_submit(fields, this) then
write_settings_early()

-- Clear components so they regenerate
dialogdata.components = nil
return true
end
if comp.setting and fields["reset_" .. i] then
core.settings:remove(comp.setting.name)
write_settings_early()

-- Clear components so they regenerate
dialogdata.components = nil
Expand Down
25 changes: 21 additions & 4 deletions src/client/clientlauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
}

// Break out of menu-game loop to shut down cleanly
if (!m_rendering_engine->run() || *kill) {
if (!g_settings_path.empty())
g_settings->updateConfigFile(g_settings_path.c_str());
if (!m_rendering_engine->run() || *kill)
break;
}

m_rendering_engine->get_video_driver()->setTextureCreationFlag(
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
Expand Down Expand Up @@ -292,6 +289,16 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
receiver->m_touchscreengui = NULL;
#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 (skip_main_menu) {
if (!error_message.empty()) {
Expand Down Expand Up @@ -555,6 +562,16 @@ void ClientLauncher::main_menu(MainMenuData *menudata)

/* leave scene manager in a clean state */
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()
Expand Down
7 changes: 7 additions & 0 deletions src/porting_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "config.h"
#include "filesys.h"
#include "log.h"
#include "settings.h"

#include <sstream>
#include <exception>
Expand All @@ -39,6 +40,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,

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)
{
int retval = 0;
Expand Down

0 comments on commit 50edb30

Please sign in to comment.