From 3c489d9c6d852c7eee6b1395552fd5a3bdeb41d1 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 29 Oct 2020 07:57:33 -0500 Subject: [PATCH] Pretty confident this will work, just gotta reboot to make sure --- src/cascadia/TerminalApp/AppLogic.cpp | 75 +++++++++++++++++++ src/cascadia/TerminalApp/AppLogic.h | 2 + .../Resources/en-US/Resources.resw | 60 ++++++++------- 3 files changed, 110 insertions(+), 27 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 72d7dae9cf2..3dc6ef8b2dd 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -400,6 +400,30 @@ namespace winrt::TerminalApp::implementation ShowDialog(dialog); } + void AppLogic::_ShowKeyboardServiceDisabledDialog() + { + auto title = RS_(L"KeyboardServiceWarningTitle"); + auto text = RS_(L"KeyboardServiceWarningText"); + auto buttonText = RS_(L"Ok"); + + Controls::TextBlock warningsTextBlock; + // Make sure you can copy-paste + warningsTextBlock.IsTextSelectionEnabled(true); + // Make sure the lines of text wrap + warningsTextBlock.TextWrapping(TextWrapping::Wrap); + + warningsTextBlock.Inlines().Append(_BuildErrorRun(text, Application::Current().as<::winrt::TerminalApp::App>().Resources())); + warningsTextBlock.Inlines().Append(Documents::LineBreak{}); + + Controls::ContentDialog dialog; + dialog.Title(winrt::box_value(title)); + dialog.Content(winrt::box_value(warningsTextBlock)); + dialog.CloseButtonText(buttonText); + dialog.DefaultButton(Controls::ContentDialogButton::Close); + + ShowDialog(dialog); + } + // Method Description: // - Displays a dialog for warnings found while loading or validating the // settings. Displays messages for whatever warnings were found while @@ -470,6 +494,11 @@ namespace winrt::TerminalApp::implementation void AppLogic::_OnLoaded(const IInspectable& /*sender*/, const RoutedEventArgs& /*eventArgs*/) { + const auto keyboardServiceIsDisabled = !_IsKeyboardServiceEnabled(); + if (keyboardServiceIsDisabled) + { + _ShowKeyboardServiceDisabledDialog(); + } if (FAILED(_settingsLoadedResult)) { const winrt::hstring titleKey = USES_RESOURCE(L"InitialJsonParseErrorTitle"); @@ -482,6 +511,52 @@ namespace winrt::TerminalApp::implementation } } + bool AppLogic::_IsKeyboardServiceEnabled() + { + if (IsUwp()) + { + return true; + } + + // If at any point we fail to open the service manager, the service, + // etc, then just quick return true to disable the dialog. We'd rather + // not be noisy with this dialog if we failed for some reason. + + // Open the service manager. This will return 0 if it failed. + wil::unique_schandle hManager{ OpenSCManager(nullptr, nullptr, SERVICE_QUERY_STATUS) }; + + if (LOG_LAST_ERROR_IF(!hManager.is_valid())) + { + return true; + } + + // Get a handle to the keyboard service + wil::unique_schandle hService{ OpenService(hManager.get(), L"TabletInputService", SERVICE_QUERY_STATUS) }; + if (LOG_LAST_ERROR_IF(!hService.is_valid())) + { + return true; + } + + // Get the current state of the service + SERVICE_STATUS status{ 0 }; + if (!LOG_IF_WIN32_BOOL_FALSE(QueryServiceStatus(hService.get(), &status))) + { + return true; + } + + const auto state = status.dwCurrentState; + if (state != SERVICE_RUNNING && state != SERVICE_START_PENDING) + { + // The service is off - return false + return false; + } + else + { + // The service is on - this is good. + return true; + } + } + // Method Description: // - Get the size in pixels of the client area we'll need to launch this // terminal app. This method will use the default profile's settings to do diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index a6dfd3251cd..b5222d7247a 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -85,6 +85,8 @@ namespace winrt::TerminalApp::implementation void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult); void _ShowLoadWarningsDialog(); + bool _IsKeyboardServiceEnabled(); + void _ShowKeyboardServiceDisabledDialog(); fire_and_forget _LoadErrorsDialogRoutine(); fire_and_forget _ShowLoadWarningsDialogRoutine(); diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index c7b08834f56..7887375f036 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -1,17 +1,17 @@  - @@ -149,6 +149,12 @@ Encountered errors while loading user settings + + Warning: + + + The "Touch Keyboard and Handwriting Panel Service" isn't running on your machine. This can prevent the Terminal from receiving keyboard input. + OK