diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 84f364189..4e0b39f58 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -1209,6 +1209,7 @@ Basic.Settings.Hotkeys.Pair="Key combinations shared with '%1' act as toggles" Basic.Settings.Hotkeys.Filter="Filter" Basic.Settings.Hotkeys.FilterByHotkey="Filter by Hotkey" Basic.Settings.Hotkeys.DuplicateWarning="This hotkey is shared by one or more other actions, click to show conflicts" +Basic.Settings.Hotkeys.PleaseWait="Loading hotkeys, please wait..." # basic mode hotkeys Basic.Hotkeys.SelectScene="Switch to scene" diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui index ff27f52c2..c20e7d3d1 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui @@ -5692,6 +5692,25 @@ 9 + + + + + 0 + 0 + + + + Basic.Settings.Hotkeys.PleaseWait + + + false + + + Qt::AlignCenter + + + diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index 98720b2c9..0ce8800ab 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -3074,6 +3074,13 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) AddHotkeys(*hotkeysLayout, obs_service_get_name, services); ScanDuplicateHotkeys(hotkeysLayout); + + /* After this function returns the UI can still be unresponsive for a bit. + * So by deferring the call to unsetCursor() to the Qt event loop it will + * take until it has actually finished processing the created widgets + * before the cursor is reset. */ + QTimer::singleShot(1, this, &OBSBasicSettings::unsetCursor); + hotkeysLoaded = true; } void OBSBasicSettings::LoadSettings(bool changedOnly) @@ -3088,8 +3095,6 @@ void OBSBasicSettings::LoadSettings(bool changedOnly) LoadAudioSettings(); if (!changedOnly || videoChanged) LoadVideoSettings(); - if (!changedOnly || hotkeysChanged) - LoadHotkeySettings(); if (!changedOnly || a11yChanged) LoadA11ySettings(); if (!changedOnly || advancedChanged) @@ -3996,6 +4001,20 @@ void OBSBasicSettings::on_listWidget_itemSelectionChanged() if (loading || row == pageIndex) return; + if (!hotkeysLoaded && row == 5) { + setCursor(Qt::BusyCursor); + /* Look, I know this /feels/ wrong, but the specific issue we're dealing with + * here means that the UI locks up immediately even when using "invokeMethod". + * So the only way for the user to see the loading message on the page is to + * give the Qt event loop a tiny bit of time to switch to the hotkey page, + * and only then start loading. This could maybe be done by subclassing QWidget + * for the hotkey page and then using showEvent() but I *really* don't want + * to deal with that right now. I've got better things to do with my life + * than to work around this god damn stupid issue for something we'll remove + * soon enough anyway. So this solution it is. */ + QTimer::singleShot(1, this, [&]() { LoadHotkeySettings(); }); + } + pageIndex = row; } @@ -4629,6 +4648,8 @@ bool OBSBasicSettings::ScanDuplicateHotkeys(QFormLayout *layout) void OBSBasicSettings::ReloadHotkeys(obs_hotkey_id ignoreKey) { + if (!hotkeysLoaded) + return; LoadHotkeySettings(ignoreKey); } diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp index 51f00e941..51f00336f 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp @@ -125,6 +125,7 @@ private: int sampleRateIndex = 0; int channelIndex = 0; bool llBufferingEnabled = false; + bool hotkeysLoaded = false; int lastSimpleRecQualityIdx = 0; int lastServiceIdx = -1;