From da2705206c64a264ed26ec5eb92155c6fe4212b6 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Sat, 28 Jun 2025 16:03:42 -0500 Subject: [PATCH] Put alt handling code in FormBase. Fixes #3584. --- src/BizHawk.Client.EmuHawk/FormBase.cs | 35 +++++++++++++++++ src/BizHawk.Client.EmuHawk/Input/Input.cs | 12 +++--- src/BizHawk.Client.EmuHawk/MainForm.cs | 48 ++--------------------- 3 files changed, 44 insertions(+), 51 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/FormBase.cs b/src/BizHawk.Client.EmuHawk/FormBase.cs index e1220576230..7b38f3d017a 100644 --- a/src/BizHawk.Client.EmuHawk/FormBase.cs +++ b/src/BizHawk.Client.EmuHawk/FormBase.cs @@ -94,5 +94,40 @@ public void UpdateWindowTitle() => base.Text = Config?.UseStaticWindowTitles == true ? (_windowTitleStatic ??= WindowTitleStatic) : WindowTitle; + + // Alt key hacks. We need this in order for hotkey bindings with alt to work. + /// sends a simulation of a plain alt key keystroke + internal void SendPlainAltKey(int lparam) + { + var m = new Message { WParam = new IntPtr(0xF100), LParam = new IntPtr(lparam), Msg = 0x0112, HWnd = Handle }; + base.WndProc(ref m); + } + + /// HACK to send an alt+mnemonic combination + internal void SendAltKeyChar(char c) => ProcessMnemonic(c); + + protected override void WndProc(ref Message m) + { + if (!BlocksInputWhenFocused) + { + // this is necessary to trap plain alt keypresses so that only our hotkey system gets them + if (m.Msg == 0x0112) // WM_SYSCOMMAND + { + if (m.WParam.ToInt32() == 0xF100) // SC_KEYMENU + { + return; + } + } + } + + base.WndProc(ref m); + } + + protected override bool ProcessDialogChar(char charCode) + { + // this is necessary to trap alt+char combinations so that only our hotkey system gets them + return (ModifierKeys & Keys.Alt) != 0 || base.ProcessDialogChar(charCode); + } + } } diff --git a/src/BizHawk.Client.EmuHawk/Input/Input.cs b/src/BizHawk.Client.EmuHawk/Input/Input.cs index 23c47126f92..a8f2f38f219 100644 --- a/src/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/src/BizHawk.Client.EmuHawk/Input/Input.cs @@ -36,7 +36,7 @@ public void ControlInputFocus(Control c, HostInputType types, bool wants) private readonly Func _getConfigCallback; - internal Input(IntPtr mainFormHandle, Func getConfigCallback, Func mainFormInputAllowedCallback) + internal Input(IntPtr mainFormHandle, Func getConfigCallback, Func mainFormInputAllowedCallback) { _getConfigCallback = getConfigCallback; _currentConfig = _getConfigCallback(); @@ -133,7 +133,7 @@ private void HandleButton(string button, bool newState, HostInputType source) private void HandleAxis(string axis, int newValue) { - if (ShouldSwallow(MainFormInputAllowedCallback(false), HostInputType.Pad)) + if (ShouldSwallow(MainFormInputAllowedCallback(), HostInputType.Pad)) return; if (_trackDeltas) @@ -189,7 +189,7 @@ public KeyValuePair[] GetAxisValues() /// /// Controls whether MainForm generates input events. should be turned off for most modal dialogs /// - public readonly Func MainFormInputAllowedCallback; + public readonly Func MainFormInputAllowedCallback; private void UpdateThreadProc() { @@ -262,13 +262,11 @@ private void UpdateThreadProc() if (_newEvents.Count != 0) { //WHAT!? WE SHOULD NOT BE SO NAIVELY TOUCHING MAINFORM FROM THE INPUTTHREAD. ITS BUSY RUNNING. - AllowInput allowInput = MainFormInputAllowedCallback(false); + AllowInput allowInput = MainFormInputAllowedCallback(); foreach (var ie in _newEvents) { //events are swallowed in some cases: - if ((ie.LogicalButton.Modifiers & LogicalButton.MASK_ALT) is not 0U && ShouldSwallow(MainFormInputAllowedCallback(true), ie.Source)) - continue; if (ie.EventType == InputEventType.Press && ShouldSwallow(allowInput, ie.Source)) continue; @@ -332,7 +330,7 @@ public string GetNextBindEvent(ref InputEvent lastPress) lock (this) { if (_inputEvents.Count == 0) return null; - AllowInput allowInput = MainFormInputAllowedCallback(false); + AllowInput allowInput = MainFormInputAllowedCallback(); //wait for the first release after a press to complete input binding, because we need to distinguish pure modifierkeys from modified keys //if you just pressed ctrl, wanting to bind ctrl, we'd see: pressed:ctrl, unpressed:ctrl diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 4250a9ce0cf..17b9daa43fa 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; -using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -620,14 +619,13 @@ _argParser.SocketAddress is var (socketIP, socketPort) Input.Instance = new Input( Handle, () => Config, - yieldAlt => ActiveForm switch + () => ActiveForm switch { null => Config.AcceptBackgroundInput // none of our forms are focused, check the background input config ? Config.AcceptBackgroundInputControllerOnly ? AllowInput.OnlyController : AllowInput.All : AllowInput.None, - TAStudio when yieldAlt => AllowInput.None, FormBase { BlocksInputWhenFocused: false } => AllowInput.All, ControllerConfig => AllowInput.All, HotkeyConfig => AllowInput.All, @@ -1267,7 +1265,7 @@ private void ProcessInput( // look for hotkey bindings for this key var triggers = searchHotkeyBindings(ie.LogicalButton.ToString()); - if (triggers.Count == 0) + if (triggers.Count == 0 && ActiveForm is FormBase afb) { // Maybe it is a system alt-key which hasn't been overridden if (ie.EventType is InputEventType.Press && (ie.LogicalButton.Modifiers & LogicalButton.MASK_ALT) is not 0U) @@ -1277,12 +1275,12 @@ private void ProcessInput( var c = ie.LogicalButton.Button.ToLowerInvariant()[0]; if ((c >= 'a' && c <= 'z') || c == ' ') { - SendAltKeyChar(c); + afb.SendAltKeyChar(c); } } else if (ie.LogicalButton.Button == "Space") { - SendPlainAltKey(32); + afb.SendPlainAltKey(32); } } @@ -2474,23 +2472,6 @@ private void SaveSlotSelectedMessage() DisplayManager.UpdateSource(video); } - // sends a simulation of a plain alt key keystroke - private void SendPlainAltKey(int lparam) - { - var m = new Message { WParam = new IntPtr(0xF100), LParam = new IntPtr(lparam), Msg = 0x0112, HWnd = Handle }; - base.WndProc(ref m); - } - - /// HACK to send an alt+mnemonic combination - private void SendAltKeyChar(char c) - => _ = typeof(ToolStrip).InvokeMember( - OSTailoredCode.IsUnixHost ? "ProcessMnemonic" : "ProcessMnemonicInternal", - BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, - null, - MainformMenu, - new object/*?*/[] { c }, - CultureInfo.InvariantCulture); - public static readonly FilesystemFilterSet ConfigFileFSFilterSet = new(new FilesystemFilter("Config File", new[] { "ini" })) { AppendAllFilesEntry = false, @@ -2925,27 +2906,6 @@ private void FdsInsertDiskMenuAdd(string name, string button, string msg) private const int WmDeviceChange = 0x0219; - // Alt key hacks - protected override void WndProc(ref Message m) - { - // this is necessary to trap plain alt keypresses so that only our hotkey system gets them - if (m.Msg == 0x0112) // WM_SYSCOMMAND - { - if (m.WParam.ToInt32() == 0xF100) // SC_KEYMENU - { - return; - } - } - - base.WndProc(ref m); - } - - protected override bool ProcessDialogChar(char charCode) - { - // this is necessary to trap alt+char combinations so that only our hotkey system gets them - return (ModifierKeys & Keys.Alt) != 0 || base.ProcessDialogChar(charCode); - } - private void UpdateCoreStatusBarButton() { var attributes = Emulator.Attributes();