From dcbf7c74f18a344ae255b62dbec31c2965a0433f Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 5 Aug 2021 23:33:44 +0200 Subject: [PATCH] Reload settings when the input method changes (#10876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `VkKeyScanW` as well as `MapVirtualKeyW` are used throughout the project, but are input method sensitive functions. Since #10666 `win+sc(41)` is used as the quake mode keybinding, which is then mapped to a virtual key in order to call `RegisterHotKey`. This mapping is highly dependent on the input method and the quake mode key binding will fail to work once the input method was changed. ## PR Checklist * [x] Closes #10729 * [x] I work here * [ ] Tests added/passed ## Validation Steps Performed * win+` opens quake window before & after changing keyboard layout ✔️ * keyboard layout changes while WT is minimized trigger reloaded ✔️ --- src/cascadia/TerminalApp/AppLogic.cpp | 4 ++ src/cascadia/TerminalApp/AppLogic.h | 16 ++++--- .../TerminalApp/LanguageProfileNotifier.cpp | 42 +++++++++++++++++++ .../TerminalApp/LanguageProfileNotifier.h | 21 ++++++++++ .../TerminalApp/TerminalAppLib.vcxproj | 12 +++--- .../TerminalAppLib.vcxproj.filters | 25 ++++------- src/cascadia/TerminalApp/pch.h | 1 + 7 files changed, 93 insertions(+), 28 deletions(-) create mode 100644 src/cascadia/TerminalApp/LanguageProfileNotifier.cpp create mode 100644 src/cascadia/TerminalApp/LanguageProfileNotifier.h diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index e9350ef95..a9ac10d8f 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -209,6 +209,10 @@ namespace winrt::TerminalApp::implementation self->_ReloadSettings(); } }); + + _languageProfileNotifier = winrt::make_self([this]() { + _reloadSettings->Run(); + }); } // Method Description: diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 3d7782039..6d2e36d9e 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -5,8 +5,9 @@ #include "AppLogic.g.h" #include "FindTargetWindowResult.g.h" -#include "TerminalPage.h" #include "Jumplist.h" +#include "LanguageProfileNotifier.h" +#include "TerminalPage.h" #include #include @@ -110,12 +111,8 @@ namespace winrt::TerminalApp::implementation // ALSO: If you add any UIElements as roots here, make sure they're // updated in _ApplyTheme. The root currently is _root. winrt::com_ptr _root{ nullptr }; - Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr }; - wil::unique_folder_change_reader_nothrow _reader; - std::shared_ptr> _reloadSettings; - til::throttled_func_trailing<> _reloadState; winrt::hstring _settingsLoadExceptionText; HRESULT _settingsLoadedResult = S_OK; bool _loadedInitialSettings = false; @@ -124,6 +121,15 @@ namespace winrt::TerminalApp::implementation ::TerminalApp::AppCommandlineArgs _appArgs; ::TerminalApp::AppCommandlineArgs _settingsAppArgs; + + std::shared_ptr> _reloadSettings; + til::throttled_func_trailing<> _reloadState; + + // These fields invoke _reloadSettings and must be destroyed before _reloadSettings. + // (C++ destroys members in reverse-declaration-order.) + winrt::com_ptr _languageProfileNotifier; + wil::unique_folder_change_reader_nothrow _reader; + static TerminalApp::FindTargetWindowResult _doFindTargetWindow(winrt::array_view args, const Microsoft::Terminal::Settings::Model::WindowingMode& windowingBehavior); diff --git a/src/cascadia/TerminalApp/LanguageProfileNotifier.cpp b/src/cascadia/TerminalApp/LanguageProfileNotifier.cpp new file mode 100644 index 000000000..9655947a4 --- /dev/null +++ b/src/cascadia/TerminalApp/LanguageProfileNotifier.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "LanguageProfileNotifier.h" + +using namespace winrt::TerminalApp::implementation; + +LanguageProfileNotifier::LanguageProfileNotifier(std::function&& callback) : + _callback{ std::move(callback) }, + _currentKeyboardLayout{ GetKeyboardLayout(0) } +{ + const auto manager = wil::CoCreateInstance(CLSID_TF_ThreadMgr); + _source = manager.query(); + if (FAILED(_source->AdviseSink(IID_ITfInputProcessorProfileActivationSink, static_cast(this), &_cookie))) + { + _cookie = TF_INVALID_COOKIE; + THROW_LAST_ERROR(); + } +} + +LanguageProfileNotifier::~LanguageProfileNotifier() +{ + if (_cookie != TF_INVALID_COOKIE) + { + _source->UnadviseSink(_cookie); + } +} + +STDMETHODIMP LanguageProfileNotifier::OnActivated(DWORD /*dwProfileType*/, LANGID /*langid*/, REFCLSID /*clsid*/, REFGUID /*catid*/, REFGUID /*guidProfile*/, HKL hkl, DWORD /*dwFlags*/) +{ + if (hkl && hkl != _currentKeyboardLayout) + { + _currentKeyboardLayout = hkl; + try + { + _callback(); + } + CATCH_RETURN(); + } + return S_OK; +} diff --git a/src/cascadia/TerminalApp/LanguageProfileNotifier.h b/src/cascadia/TerminalApp/LanguageProfileNotifier.h new file mode 100644 index 000000000..865330455 --- /dev/null +++ b/src/cascadia/TerminalApp/LanguageProfileNotifier.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +namespace winrt::TerminalApp::implementation +{ + class LanguageProfileNotifier : public winrt::implements + { + public: + explicit LanguageProfileNotifier(std::function&& callback); + ~LanguageProfileNotifier(); + STDMETHODIMP OnActivated(DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags); + + private: + std::function _callback; + wil::com_ptr _source; + DWORD _cookie = TF_INVALID_COOKIE; + HKL _currentKeyboardLayout; + }; +} diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 67317f4e4..25cd7cfa3 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -53,7 +53,7 @@ Designer - + Designer @@ -74,6 +74,7 @@ + MinMaxCloseControl.xaml @@ -112,7 +113,7 @@ HighlightedTextControl.xaml - + ColorPickupFlyout.xaml @@ -139,7 +140,7 @@ AppLogic.idl - + @@ -149,6 +150,7 @@ + MinMaxCloseControl.xaml @@ -195,7 +197,7 @@ HighlightedTextControl.xaml - + ColorPickupFlyout.xaml @@ -280,7 +282,7 @@ HighlightedTextControl.xaml Code - + ColorPickupFlyout.xaml Code diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters index 1511e14d9..f041b68d7 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters @@ -13,9 +13,6 @@ pane - - tab - pane @@ -23,7 +20,6 @@ - tab @@ -49,10 +45,10 @@ highlightedText + + - - app @@ -60,9 +56,6 @@ pane - - tab - @@ -92,14 +85,13 @@ highlightedText + + app - - settings - settings @@ -107,9 +99,6 @@ settings - - tab - tab @@ -125,6 +114,9 @@ tab + + + @@ -160,9 +152,6 @@ commandPalette - - commandPalette - commandPalette diff --git a/src/cascadia/TerminalApp/pch.h b/src/cascadia/TerminalApp/pch.h index 299d7de63..1f84f821e 100644 --- a/src/cascadia/TerminalApp/pch.h +++ b/src/cascadia/TerminalApp/pch.h @@ -66,6 +66,7 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalAppProvider); #include #include +#include #include #include