From 48a00723e4d309018309f4fb40870c8f0403f812 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Fri, 15 May 2026 17:21:41 -0500 Subject: ui: always lock during executable run; kill wineserver on Unlock The "Lock GUI when running executable" toggle is removed from the Workarounds settings tab. Locking is required for the post-run refresh to know when files changed under the prefix, and the off-state was a well-documented foot-gun. The setter/getter on InterfaceSettings, the QSettings key (Settings/lock_gui), the checkbox widget, the tabstop entry, and the two no-lock branches in ProcessRunner::postRun all go. When the user clicks Unlock in the lock dialog, also SIGTERM the tracked game pid and hard-kill the prefix's wineserver. The Cancelled branch (Cancel in PreventExit mode) already did this; the ForceUnlocked branch silently returned and left wineserver running, so Proton's session manager held the prefix open for tens of seconds and the next launch inherited a dirty state. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/src/processrunner.cpp | 30 ++++-------------------------- src/src/settings.cpp | 10 ---------- src/src/settings.h | 5 ----- src/src/settingsdialog.ui | 17 ----------------- src/src/settingsdialogworkarounds.cpp | 2 -- 5 files changed, 4 insertions(+), 60 deletions(-) diff --git a/src/src/processrunner.cpp b/src/src/processrunner.cpp index 91176fd..63ecf83 100644 --- a/src/src/processrunner.cpp +++ b/src/src/processrunner.cpp @@ -1265,16 +1265,10 @@ ProcessRunner::Results ProcessRunner::postRun() m_lockReason = UILocker::LockUI; } - const bool lockEnabled = m_core.settings().interface().lockGUI(); const QStringList expectedExecutables = buildExpectedExecutables(m_sp.binary, m_sp.arguments); - if (mustWait) { - if (!lockEnabled) { - log::debug("locking is disabled, but the output of the application is required; " - "overriding this setting and locking the ui"); - } - } else { + if (!mustWait) { if (m_lockReason == UILocker::NoReason) { // Main window launches typically use TriggerRefresh without // waiting/locking. In that mode we still need post-run refresh/sync once @@ -1327,28 +1321,12 @@ ProcessRunner::Results ProcessRunner::postRun() } return Running; } - - if (!lockEnabled) { - log::debug("process runner: not waiting for process because " - "locking is disabled"); - - return ForceUnlocked; - } } auto r = Error; - - if (mustWait && m_lockReason == UILocker::PreventExit && !lockEnabled) { - // This happens when running shortcuts and locking is disabled. MO must - // stay alive until all processes are dead or child processes may not get - // hooked properly, but the user has disabled locking the ui — so allow - // them to do that. MO runs in the background with no visual feedback. - r = waitForProcess(m_handle.get(), &m_exitCode, nullptr, expectedExecutables); - } else { - withLock([&](auto& ls) { - r = waitForProcess(m_handle.get(), &m_exitCode, &ls, expectedExecutables); - }); - } + withLock([&](auto& ls) { + r = waitForProcess(m_handle.get(), &m_exitCode, &ls, expectedExecutables); + }); if (shouldRefresh(r)) { QEventLoop loop; diff --git a/src/src/settings.cpp b/src/src/settings.cpp index 2b408c0..c665756 100644 --- a/src/src/settings.cpp +++ b/src/src/settings.cpp @@ -2171,16 +2171,6 @@ void SteamSettings::setLogin(QString username, QString password) InterfaceSettings::InterfaceSettings(QSettings& settings) : m_Settings(settings) {} -bool InterfaceSettings::lockGUI() const -{ - return get(m_Settings, "Settings", "lock_gui", true); -} - -void InterfaceSettings::setLockGUI(bool b) -{ - set(m_Settings, "Settings", "lock_gui", b); -} - std::optional InterfaceSettings::styleName() const { return getOptional(m_Settings, "Settings", "style"); diff --git a/src/src/settings.h b/src/src/settings.h index 97b671d..6726b2f 100644 --- a/src/src/settings.h +++ b/src/src/settings.h @@ -584,11 +584,6 @@ class InterfaceSettings public: InterfaceSettings(QSettings& settings); - // whether the GUI should be locked when running executables - // - bool lockGUI() const; - void setLockGUI(bool b); - // filename of the theme // std::optional styleName() const; diff --git a/src/src/settingsdialog.ui b/src/src/settingsdialog.ui index 73ca890..04dcd3e 100644 --- a/src/src/settingsdialog.ui +++ b/src/src/settingsdialog.ui @@ -1993,22 +1993,6 @@ Uncheck this if you want to use Mod Organizer with total conversions (like Nehri - - - - Disable this to prevent the GUI from being locked when running an executable. This may result in abnormal behavior. - - - Disable this to prevent the GUI from being locked when running an executable. This may result in abnormal behavior. - - - Lock GUI when running executable - - - true - - - @@ -2513,7 +2497,6 @@ programs you are intentionally running. managedGameDirEdit browseGameDirBtn pluginSettingsList - lockGUIBox diff --git a/src/src/settingsdialogworkarounds.cpp b/src/src/settingsdialogworkarounds.cpp index 820e697..2b252b3 100644 --- a/src/src/settingsdialogworkarounds.cpp +++ b/src/src/settingsdialogworkarounds.cpp @@ -11,7 +11,6 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d) { // options ui->forceEnableBox->setChecked(settings().game().forceEnableCoreFiles()); - ui->lockGUIBox->setChecked(settings().interface().lockGUI()); ui->enableArchiveParsingBox->setChecked(settings().archiveParsing()); // steam @@ -59,7 +58,6 @@ void WorkaroundsSettingsTab::update() { // options settings().game().setForceEnableCoreFiles(ui->forceEnableBox->isChecked()); - settings().interface().setLockGUI(ui->lockGUIBox->isChecked()); settings().setArchiveParsing(ui->enableArchiveParsingBox->isChecked()); // steam -- cgit v1.3.1