From 73104189843cbfccff5f71bf49b8ed03294baf53 Mon Sep 17 00:00:00 2001
From: Alexei Kotov <alexdobrohotov@yandex.ru>
Date: Tue, 2 Jan 2024 21:53:00 +0300
Subject: [PATCH] Downgrade Settings GUI mode to a modal (bug #6758)

---
 CHANGELOG.md                           | 1 +
 apps/openmw/mwbase/windowmanager.hpp   | 2 ++
 apps/openmw/mwgui/mainmenu.cpp         | 5 ++++-
 apps/openmw/mwgui/mode.hpp             | 1 -
 apps/openmw/mwgui/settingswindow.cpp   | 6 ++++--
 apps/openmw/mwgui/settingswindow.hpp   | 2 +-
 apps/openmw/mwgui/windowmanagerimp.cpp | 5 ++++-
 apps/openmw/mwgui/windowmanagerimp.hpp | 1 +
 apps/openmw/mwinput/mousemanager.cpp   | 4 +++-
 apps/openmw/mwlua/uibindings.cpp       | 1 -
 10 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index eff35bfa53..1c5c021a0d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -39,6 +39,7 @@
     Bug #6661: Saved games that have no preview screenshot cause issues or crashes
     Bug #6716: mwscript comparison operator handling is too restrictive
     Bug #6754: Beast to Non-beast transformation mod is not working on OpenMW
+    Bug #6758: Main menu background video can be stopped by opening the options menu
     Bug #6807: Ultimate Galleon is not working properly
     Bug #6893: Lua: Inconsistent behavior with actors affected by Disable and SetDelete commands
     Bug #6894: Added item combines with equipped stack instead of creating a new unequipped stack
diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp
index 0c60fe9778..4711994b55 100644
--- a/apps/openmw/mwbase/windowmanager.hpp
+++ b/apps/openmw/mwbase/windowmanager.hpp
@@ -77,6 +77,7 @@ namespace MWGui
     class JailScreen;
     class MessageBox;
     class PostProcessorHud;
+    class SettingsWindow;
 
     enum ShowInDialogueMode
     {
@@ -156,6 +157,7 @@ namespace MWBase
         virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
         virtual MWGui::TradeWindow* getTradeWindow() = 0;
         virtual MWGui::PostProcessorHud* getPostProcessorHud() = 0;
+        virtual MWGui::SettingsWindow* getSettingsWindow() = 0;
 
         /// Make the player use an item, while updating GUI state accordingly
         virtual void useItem(const MWWorld::Ptr& item, bool force = false) = 0;
diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp
index 37e835f1a4..d0c55f432e 100644
--- a/apps/openmw/mwgui/mainmenu.cpp
+++ b/apps/openmw/mwgui/mainmenu.cpp
@@ -18,6 +18,7 @@
 #include "backgroundimage.hpp"
 #include "confirmationdialog.hpp"
 #include "savegamedialog.hpp"
+#include "settingswindow.hpp"
 #include "videowidget.hpp"
 
 namespace MWGui
@@ -97,7 +98,9 @@ namespace MWGui
             winMgr->removeGuiMode(GM_MainMenu);
         }
         else if (name == "options")
-            winMgr->pushGuiMode(GM_Settings);
+        {
+            winMgr->getSettingsWindow()->setVisible(true);
+        }
         else if (name == "credits")
             winMgr->playVideo("mw_credits.bik", true);
         else if (name == "exitgame")
diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp
index 63f81e8b47..44f9743743 100644
--- a/apps/openmw/mwgui/mode.hpp
+++ b/apps/openmw/mwgui/mode.hpp
@@ -6,7 +6,6 @@ namespace MWGui
     enum GuiMode
     {
         GM_None,
-        GM_Settings, // Settings window
         GM_Inventory, // Inventory mode
         GM_Container,
         GM_Companion,
diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp
index 1060b3a20f..fbd54586df 100644
--- a/apps/openmw/mwgui/settingswindow.cpp
+++ b/apps/openmw/mwgui/settingswindow.cpp
@@ -240,7 +240,7 @@ namespace MWGui
     }
 
     SettingsWindow::SettingsWindow()
-        : WindowBase("openmw_settings_window.layout")
+        : WindowModal("openmw_settings_window.layout")
         , mKeyboardMode(true)
         , mCurrentPage(-1)
     {
@@ -450,7 +450,7 @@ namespace MWGui
 
     void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
     {
-        MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Settings);
+        setVisible(false);
     }
 
     void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index)
@@ -1041,6 +1041,8 @@ namespace MWGui
 
     void SettingsWindow::onOpen()
     {
+        WindowModal::onOpen();
+
         highlightCurrentResolution();
         updateControlsBox();
         updateLightSettings();
diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp
index 1f96f7de54..47951ef121 100644
--- a/apps/openmw/mwgui/settingswindow.hpp
+++ b/apps/openmw/mwgui/settingswindow.hpp
@@ -7,7 +7,7 @@
 
 namespace MWGui
 {
-    class SettingsWindow : public WindowBase
+    class SettingsWindow : public WindowModal
     {
     public:
         SettingsWindow();
diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp
index 3bd779a186..63d974ff35 100644
--- a/apps/openmw/mwgui/windowmanagerimp.cpp
+++ b/apps/openmw/mwgui/windowmanagerimp.cpp
@@ -408,7 +408,6 @@ namespace MWGui
         mSettingsWindow = settingsWindow.get();
         mWindows.push_back(std::move(settingsWindow));
         trackWindow(mSettingsWindow, makeSettingsWindowSettingValues());
-        mGuiModeStates[GM_Settings] = GuiModeState(mSettingsWindow);
 
         auto confirmationDialog = std::make_unique<ConfirmationDialog>();
         mConfirmationDialog = confirmationDialog.get();
@@ -1475,6 +1474,10 @@ namespace MWGui
     {
         return mPostProcessorHud;
     }
+    MWGui::SettingsWindow* WindowManager::getSettingsWindow()
+    {
+        return mSettingsWindow;
+    }
 
     void WindowManager::useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions)
     {
diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp
index 7ee0554a26..b378a76ff8 100644
--- a/apps/openmw/mwgui/windowmanagerimp.hpp
+++ b/apps/openmw/mwgui/windowmanagerimp.hpp
@@ -182,6 +182,7 @@ namespace MWGui
         MWGui::ConfirmationDialog* getConfirmationDialog() override;
         MWGui::TradeWindow* getTradeWindow() override;
         MWGui::PostProcessorHud* getPostProcessorHud() override;
+        MWGui::SettingsWindow* getSettingsWindow() override;
 
         /// Make the player use an item, while updating GUI state accordingly
         void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions = false) override;
diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp
index 363a78fadd..c91dfaedac 100644
--- a/apps/openmw/mwinput/mousemanager.cpp
+++ b/apps/openmw/mwinput/mousemanager.cpp
@@ -13,6 +13,8 @@
 #include "../mwbase/windowmanager.hpp"
 #include "../mwbase/world.hpp"
 
+#include "../mwgui/settingswindow.hpp"
+
 #include "../mwworld/player.hpp"
 
 #include "actions.hpp"
@@ -156,7 +158,7 @@ namespace MWInput
 
         // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible
         // Also do not trigger bindings when input controls are disabled, e.g. during save loading
-        if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings
+        if (!MWBase::Environment::get().getWindowManager()->getSettingsWindow()->isVisible()
             && !input->controlsDisabled())
             mBindingsManager->mousePressed(arg, id);
     }
diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp
index 98a653949d..843917275c 100644
--- a/apps/openmw/mwlua/uibindings.cpp
+++ b/apps/openmw/mwlua/uibindings.cpp
@@ -47,7 +47,6 @@ namespace MWLua
         }
 
         const std::unordered_map<MWGui::GuiMode, std::string_view> modeToName{
-            { MWGui::GM_Settings, "SettingsMenu" },
             { MWGui::GM_Inventory, "Interface" },
             { MWGui::GM_Container, "Container" },
             { MWGui::GM_Companion, "Companion" },