diff --git a/builtin/common/menu.lua b/builtin/common/menu.lua index 165286470..4eb3dfe44 100644 --- a/builtin/common/menu.lua +++ b/builtin/common/menu.lua @@ -9,3 +9,7 @@ mt_color_green = "#72FF63" mt_color_dark_green = "#25C191" mt_color_orange = "#FF8800" mt_color_red = "#FF3300" + +function core.are_keycodes_equal(k1, k2) + return core.normalize_keycode(k1) == core.normalize_keycode(k2) +end diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index a1f352afa..29aa3e5c2 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -634,6 +634,10 @@ if core.gettext then -- for client and mainmenu function fgettext(text, ...) return core.formspec_escape(fgettext_ne(text, ...)) end + + function hgettext(text, ...) + return core.hypertext_escape(fgettext_ne(text, ...)) + end end local ESCAPE_CHAR = string.char(0x1b) diff --git a/builtin/common/settings/dlg_settings.lua b/builtin/common/settings/dlg_settings.lua index e19ed7351..77fc8be3f 100644 --- a/builtin/common/settings/dlg_settings.lua +++ b/builtin/common/settings/dlg_settings.lua @@ -778,11 +778,11 @@ end if INIT == "mainmenu" then - function create_settings_dlg() + function create_settings_dlg(page_id) load() local dlg = dialog_create("dlg_settings", get_formspec, buttonhandler, eventhandler) - dlg.data.page_id = update_filtered_pages("") + dlg.data.page_id = page_id or update_filtered_pages("") return dlg end diff --git a/builtin/mainmenu/dlg_rebind_keys.lua b/builtin/mainmenu/dlg_rebind_keys.lua new file mode 100644 index 000000000..d1b442004 --- /dev/null +++ b/builtin/mainmenu/dlg_rebind_keys.lua @@ -0,0 +1,108 @@ +-- Luanti +-- SPDX-License-Identifier: LGPL-2.1-or-later +-- Modified based on dlg_reinstall_mtg.lua +-- Note that this is only needed for migrating from <5.11 to 5.12. + +local doc_url = "https://docs.luanti.org/for-players/controls/" +local SETTING_NAME = "no_keycode_migration_warning" + +local function get_formspec(dialogdata) + local markup = table.concat({ + "" .. hgettext("Keybindings changed") .. "", + hgettext("The input handling system was reworked in Luanti 5.12.0."), + hgettext("As a result, your keybindings may have been changed."), + hgettext("Check out the key settings or refer to the documentation:"), + (""):format(doc_url), + }, "\n") + + return table.concat({ + "formspec_version[6]", + "size[12,7]", + "hypertext[0.5,0.5;11,4.7;text;", core.formspec_escape(markup), "]", + "container[0.5,5.7]", + "button[0,0;4,0.8;dismiss;", fgettext("Close"), "]", + "button[4.5,0;6.5,0.8;reconfigure;", fgettext("Open settings"), "]", + "container_end[]", + }) +end + +local function close_dialog(this) + cache_settings:set_bool(SETTING_NAME, true) + this:delete() +end + +local function buttonhandler(this, fields) + if fields.reconfigure then + close_dialog(this) + + local maintab = ui.find_by_name("maintab") + + local dlg = create_settings_dlg("controls_keyboard_and_mouse") + dlg:set_parent(maintab) + maintab:hide() + dlg:show() + + return true + end + + if fields.dismiss then + close_dialog(this) + return true + end + + if fields.text == "action:doc_url" then + core.open_url(doc_url) + end +end + +local function eventhandler(event) + if event == "DialogShow" then + mm_game_theme.set_engine() + return true + elseif event == "MenuQuit" then + -- Don't allow closing the dialog with ESC, but still allow exiting + -- Luanti + core.close() + return true + end + return false +end + +local function create_rebind_keys_dlg() + local dlg = dialog_create("dlg_rebind_keys", get_formspec, + buttonhandler, eventhandler) + return dlg +end + +function migrate_keybindings() + -- Show migration dialog if the user upgraded from an earlier version + -- and this has not yet been shown before, *or* if keys settings had to be changed + if core.is_first_run then + cache_settings:set_bool(SETTING_NAME, true) + end + local has_migration = not cache_settings:get_bool(SETTING_NAME) + + -- normalize all existing key settings, this converts them from KEY_KEY_C to SYSTEM_SCANCODE_6 + local settings = core.settings:to_table() + for name, value in pairs(settings) do + if name:match("^keymap_") then + local normalized = core.normalize_keycode(value) + if value ~= normalized then + has_migration = true + core.settings:set(name, normalized) + end + end + end + + if not has_migration then + return + end + + local maintab = ui.find_by_name("maintab") + + local dlg = create_rebind_keys_dlg() + dlg:set_parent(maintab) + maintab:hide() + dlg:show() + ui.update() +end diff --git a/builtin/mainmenu/dlg_reinstall_mtg.lua b/builtin/mainmenu/dlg_reinstall_mtg.lua index 4defa6646..c167b2656 100644 --- a/builtin/mainmenu/dlg_reinstall_mtg.lua +++ b/builtin/mainmenu/dlg_reinstall_mtg.lua @@ -54,10 +54,10 @@ end local function get_formspec(dialogdata) local markup = table.concat({ - "", fgettext("Minetest Game is no longer installed by default"), "\n", - fgettext("For a long time, Luanti shipped with a default game called \"Minetest Game\". " .. + "", hgettext("Minetest Game is no longer installed by default"), "\n", + hgettext("For a long time, Luanti shipped with a default game called \"Minetest Game\". " .. "Since version 5.8.0, Luanti ships without a default game."), "\n", - fgettext("If you want to continue playing in your Minetest Game worlds, you need to reinstall Minetest Game."), + hgettext("If you want to continue playing in your Minetest Game worlds, you need to reinstall Minetest Game."), }) return table.concat({ diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 1394d13f1..14185a484 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -35,6 +35,7 @@ dofile(menupath .. DIR_DELIM .. "dlg_register.lua") dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua") dofile(menupath .. DIR_DELIM .. "dlg_reinstall_mtg.lua") +dofile(menupath .. DIR_DELIM .. "dlg_rebind_keys.lua") dofile(menupath .. DIR_DELIM .. "dlg_clients_list.lua") dofile(menupath .. DIR_DELIM .. "dlg_server_list_mods.lua") @@ -112,6 +113,7 @@ local function init_globals() ui.update() check_reinstall_mtg() + migrate_keybindings() check_new_version() end diff --git a/src/main.cpp b/src/main.cpp index b2affdb70..95a2f7be4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -777,10 +777,13 @@ static bool read_config_file(const Settings &cmd_args) } // If no path found, use the first one (menu creates the file) - if (g_settings_path.empty()) + if (g_settings_path.empty()) { g_settings_path = filenames[0]; + g_first_run = true; + } } - infostream << "Global configuration file: " << g_settings_path << std::endl; + infostream << "Global configuration file: " << g_settings_path + << (g_first_run ? " (first run)" : "") << std::endl; return true; } diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 3d096e018..4b878ee1c 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -1089,6 +1089,9 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(open_dir); API_FCT(share_file); API_FCT(do_async_callback); + + lua_pushboolean(L, g_first_run); + lua_setfield(L, top, "is_first_run"); } /******************************************************************************/ diff --git a/src/script/lua_api/l_menu_common.cpp b/src/script/lua_api/l_menu_common.cpp index 8b3ffda4e..428b902c9 100644 --- a/src/script/lua_api/l_menu_common.cpp +++ b/src/script/lua_api/l_menu_common.cpp @@ -35,11 +35,10 @@ int ModApiMenuCommon::l_irrlicht_device_supports_touch(lua_State *L) } -int ModApiMenuCommon::l_are_keycodes_equal(lua_State *L) +int ModApiMenuCommon::l_normalize_keycode(lua_State *L) { - auto k1 = luaL_checkstring(L, 1); - auto k2 = luaL_checkstring(L, 2); - lua_pushboolean(L, KeyPress(k1) == KeyPress(k2)); + auto keystr = luaL_checkstring(L, 1); + lua_pushstring(L, KeyPress(keystr).sym().c_str()); return 1; } @@ -49,7 +48,7 @@ void ModApiMenuCommon::Initialize(lua_State *L, int top) API_FCT(gettext); API_FCT(get_active_driver); API_FCT(irrlicht_device_supports_touch); - API_FCT(are_keycodes_equal); + API_FCT(normalize_keycode); } diff --git a/src/script/lua_api/l_menu_common.h b/src/script/lua_api/l_menu_common.h index 8cbd58f11..2c1756fa5 100644 --- a/src/script/lua_api/l_menu_common.h +++ b/src/script/lua_api/l_menu_common.h @@ -13,7 +13,7 @@ private: static int l_gettext(lua_State *L); static int l_get_active_driver(lua_State *L); static int l_irrlicht_device_supports_touch(lua_State *L); - static int l_are_keycodes_equal(lua_State *L); + static int l_normalize_keycode(lua_State *L); public: static void Initialize(lua_State *L, int top); diff --git a/src/settings.cpp b/src/settings.cpp index 6a7607cc3..2dccf45de 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -22,6 +22,7 @@ Settings *g_settings = nullptr; static SettingsHierarchy g_hierarchy; std::string g_settings_path; +bool g_first_run = false; std::unordered_map Settings::s_flags; diff --git a/src/settings.h b/src/settings.h index 9bc0e80d9..95083058a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -18,6 +18,8 @@ struct NoiseParams; // Global objects extern Settings *g_settings; // Same as Settings::getLayer(SL_GLOBAL); extern std::string g_settings_path; +/// Is set to true if the engine runs for the first time +extern bool g_first_run; // Type for a settings changed callback function typedef void (*SettingsChangedCallback)(const std::string &name, void *data); diff --git a/util/updatepo.sh b/util/updatepo.sh index 2b9f4a276..edb03c5d2 100755 --- a/util/updatepo.sh +++ b/util/updatepo.sh @@ -58,6 +58,7 @@ xgettext --package-name=luanti \ --keyword=fwgettext \ --keyword=fgettext \ --keyword=fgettext_ne \ + --keyword=hgettext \ --keyword=strgettext \ --keyword=wstrgettext \ --keyword=core.gettext \