Repository: microsoft/terminal (language: cpp)

Issue:
Alt and F7 don't work in 1.23.3481.0
### Windows Terminal version

1.23.3481.0

### Windows build number

10.0.19045.5247

### Other Software

FAR Manager 3.0.6401.0 x64

when migrate from canary build terminal-1.23.3461.0 to next canary build terminal-1.23.3481.0
i have trouble with keys: Alt/RAlt and F7

### Steps to reproduce

run utility KeyEvents.exe and press Alt and F7



### Expected Behavior

result when press Alt:

terminal-1.23.3461.0 - good behavior
02:56:37 KEY_EVENT_RECORD: Dn, 1, Vk="VK_MENU" [18/0x0012], Scan=0x0038 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000002 (cAsac - ecns) (Windowed)
02:56:37 KEY_EVENT_RECORD: Up, 1, Vk="VK_MENU" [18/0x0012], Scan=0x0038 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000000 (casac - ecns) (Windowed)

result when press f7:

terminal-1.23.3461.0 - good behavior

03:08:36 KEY_EVENT_RECORD: Dn, 1, Vk="VK_F7" [118/0x0076], Scan=0x0041 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000000 (casac - ecns) (Windowed)
03:08:36 KEY_EVENT_RECORD: Up, 1, Vk="VK_F7" [118/0x0076], Scan=0x0041 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000000 (casac - ecns) (Windowed)

### Actual Behavior

result when press Alt:

terminal-1.23.3481.0 - bad behavior
02:54:44 KEY_EVENT_RECORD: Up, 1, Vk="VK_MENU" [18/0x0012], Scan=0x0038 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000002 (cAsac - ecns) (Windowed)


result when press f7:

terminal-1.23.3481.0 - bad behavior
03:02:27 KEY_EVENT_RECORD: Dn, 1, Vk="VK_F7" [118/0x0076], Scan=0x0041 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000000 (casac - ecns) (Windowed)
03:02:27 KEY_EVENT_RECORD: Dn, 1, Vk="VK_F7" [118/0x0076], Scan=0x0041 uChar=[U=' ' (0x0000): A=' ' (0x00)]
         Ctrl=0x00000000 (casac - ecns) (Windowed)



Discussion / hints:
@lhecker @DHowett 

after close issue is out:
terminal-1.23.10061.0
terminal-1.23.10081.0

but nothing fixed. 
The problem still exists...

Fix patch:
diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp
index 59f26b50b16..91e1a9bdb92 100644
--- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp
+++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp
@@ -387,6 +387,9 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
     MSG msg{};
     while (GetMessageW(&msg, nullptr, 0, 0))
     {
+        // This is `if (WM_KEYDOWN || WM_KEYUP || WM_SYSKEYDOWN || WM_SYSKEYUP)`.
+        // It really doesn't need to be written that obtuse, but it at
+        // least nicely mirrors our `keyDown = msg.message & 1` logic.
         // FYI: For the key-down/up messages the lowest bit indicates if it's up.
         if ((msg.message & ~1) == WM_KEYDOWN || (msg.message & ~1) == WM_SYSKEYDOWN)
         {
@@ -401,7 +404,7 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
                 loggedInteraction = true;
             }
 
-            const bool keyDown = msg.message & 1;
+            const bool keyDown = (msg.message & 1) == 0;
             if (
                 // GH#638: The Xaml input stack doesn't allow an application to suppress the "caret browsing"
                 // dialog experience triggered when you press F7. Official recommendation from the Xaml
@@ -438,15 +441,13 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
     __assume(false);
 }
 
-void WindowEmperor::_dispatchSpecialKey(MSG& msg) const
+void WindowEmperor::_dispatchSpecialKey(const MSG& msg) const
 {
-    const auto hwnd = msg.hwnd;
+    // Each CoreInput window is a child of our IslandWindow.
+    // We can figure out the IslandWindow HWND via GetAncestor().
+    const auto hwnd = GetAncestor(msg.hwnd, GA_ROOT);
     AppHost* window = nullptr;
 
-    // Just in case someone has targed a specific HWND,
-    // we'll try to dispatch it to the corresponding class.
-    // Usually this will not find anything because under WinUI the hidden CoreInput
-    // window is responsible for all input handling (for whatever reason).
     for (const auto& h : _windows)
     {
         const auto w = h->GetWindow();
@@ -457,6 +458,7 @@ void WindowEmperor::_dispatchSpecialKey(MSG& msg) const
         }
     }
 
+    // Fallback.
     if (!window)
     {
         window = _mostRecentWindow();
@@ -468,7 +470,7 @@ void WindowEmperor::_dispatchSpecialKey(MSG& msg) const
 
     const auto vkey = gsl::narrow_cast<uint32_t>(msg.wParam);
     const auto scanCode = gsl::narrow_cast<uint8_t>(msg.lParam >> 16);
-    const bool keyDown = msg.message & 1;
+    const bool keyDown = (msg.message & 1) == 0;
     window->OnDirectKeyEvent(vkey, scanCode, keyDown);
 }
 
diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.h b/src/cascadia/WindowsTerminal/WindowEmperor.h
index 6b9b101507f..ca30159ac2d 100644
--- a/src/cascadia/WindowsTerminal/WindowEmperor.h
+++ b/src/cascadia/WindowsTerminal/WindowEmperor.h
@@ -50,7 +50,7 @@ class WindowEmperor
     AppHost* _mostRecentWindow() const noexcept;
     bool _summonWindow(const SummonWindowSelectionArgs& args) const;
     void _summonAllWindows() const;
-    void _dispatchSpecialKey(MSG& msg) const;
+    void _dispatchSpecialKey(const MSG& msg) const;
     void _dispatchCommandline(winrt::TerminalApp::CommandlineArgs args);
     safe_void_coroutine _dispatchCommandlineCurrentDesktop(winrt::TerminalApp::CommandlineArgs args);
     LRESULT _messageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) noexcept;


Test patch: