shiny/driver/internal/win32: handle syskey messages

Under certain circumstances Windows sends `_WM_SYSKEYDOWN` and `_WM_SYSKEYUP` messages instead of `_WM_KEYDOWN` and `_WM_KEYUP` messages.

This handles the `SYSKEY` messages in the same way as the other messages, to be able to forward all key events to the application.

The exact circumstances are when the key is F10 or when the ALT key is currently pressed while another key is pressed. This behavior is documented in the Windows documentation [here](https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeydown).

Fixes golang/go#36213.

Change-Id: I12ef1b45110a2e02ce319b12c1e6d93a011e5fab
GitHub-Last-Rev: 60a04482b25617f456c0f05a6e6737a0acd0bc6d
GitHub-Pull-Request: golang/exp#8
Reviewed-on: https://go-review.googlesource.com/c/exp/+/212403
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
diff --git a/shiny/driver/internal/win32/key.go b/shiny/driver/internal/win32/key.go
index c7b9e38..cb8f6e5 100644
--- a/shiny/driver/internal/win32/key.go
+++ b/shiny/driver/internal/win32/key.go
@@ -332,14 +332,14 @@
 		Modifiers: keyModifiers(),
 	}
 	switch uMsg {
-	case _WM_KEYDOWN:
+	case _WM_KEYDOWN, _WM_SYSKEYDOWN:
 		const prevMask = 1 << 30
 		if repeat := lParam&prevMask == prevMask; repeat {
 			e.Direction = key.DirNone
 		} else {
 			e.Direction = key.DirPress
 		}
-	case _WM_KEYUP:
+	case _WM_KEYUP, _WM_SYSKEYUP:
 		e.Direction = key.DirRelease
 	default:
 		panic(fmt.Sprintf("win32: unexpected key message: %d", uMsg))
diff --git a/shiny/driver/internal/win32/win32.go b/shiny/driver/internal/win32/win32.go
index 6925085..4fe6696 100644
--- a/shiny/driver/internal/win32/win32.go
+++ b/shiny/driver/internal/win32/win32.go
@@ -333,7 +333,8 @@
 
 	_WM_KEYDOWN: sendKeyEvent,
 	_WM_KEYUP:   sendKeyEvent,
-	// TODO case _WM_SYSKEYDOWN, _WM_SYSKEYUP:
+	_WM_SYSKEYDOWN: sendKeyEvent,
+	_WM_SYSKEYUP: sendKeyEvent,
 }
 
 func AddWindowMsg(fn func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr)) uint32 {