Fix: passkey sound now layers in on password fields

RemSound's password boxes are deliberately NOT PasswordChar-masked (a screen-reader user can't see
a mask), so the key-click hook's "is this a password field?" check (UseSystemPasswordChar /
PasswordChar) was always false and the distinct passkey.wav never played. Password fields now mark
themselves with Tag = KeyClickService.PasswordFieldTag, and the hook checks that (keeping the
masking-flag check as a fallback). Tagged both password fields - ProfilePasswordDialog (which all
password entry routes through, including the send/receive streaming gate) and
ProfilePasswordManagerDialog. So a key click + passkey now layer together on every password keystroke.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-06-13 07:23:54 +01:00
co-authored by Claude Opus 4.8
parent 56417eb7c3
commit 0b7ad49021
3 changed files with 13 additions and 2 deletions
+10 -1
View File
@@ -20,6 +20,12 @@ internal static class KeyClickService
{
private const int WM_CHAR = 0x0102;
/// <summary>Tag value a password entry field sets on itself (<c>control.Tag = PasswordFieldTag</c>)
/// so the key-click hook layers in the distinct passkey sound. RemSound's password boxes are
/// deliberately NOT PasswordChar-masked (a screen-reader user can't see the mask anyway), so
/// there's no built-in flag to detect - they mark themselves with this tag instead.</summary>
public const string PasswordFieldTag = "remsound-password-field";
private static KeyClickPlayer? player;
private static MessageFilter? filter;
@@ -58,7 +64,10 @@ internal static class KeyClickService
if (!Enabled || player is null) return;
// The WM_CHAR target window is the focused control. Click only when it's an edit field.
if (System.Windows.Forms.Control.FromHandle(hwnd) is not System.Windows.Forms.TextBoxBase edit) return;
var isPassword = edit is System.Windows.Forms.TextBox tb && (tb.UseSystemPasswordChar || tb.PasswordChar != '\0');
// A password field is marked by its Tag (RemSound's boxes aren't PasswordChar-masked), with
// a fallback to the standard masking flags for any conventionally-masked box.
var isPassword = (edit.Tag as string) == PasswordFieldTag
|| (edit is System.Windows.Forms.TextBox tb && (tb.UseSystemPasswordChar || tb.PasswordChar != '\0'));
player.PlayClick(isPassword);
}
@@ -38,6 +38,8 @@ internal static class ProfilePasswordDialog
Dock = DockStyle.Top,
Width = 400,
AccessibleName = $"Password for profile {profileTitle}",
// Mark as a password field so the key-click hook layers in the passkey sound.
Tag = KeyClickService.PasswordFieldTag,
};
var hint = new Label
{
@@ -60,7 +60,7 @@ internal static class ProfilePasswordManagerDialog
catch { current = ""; }
var label = new Label { Text = title, AutoSize = true, Anchor = AnchorStyles.Left, Padding = new Padding(0, 6, 10, 6) };
var box = new TextBox { Text = current, Anchor = AnchorStyles.Left | AnchorStyles.Right, AccessibleName = $"Password for profile {title}" };
var box = new TextBox { Text = current, Anchor = AnchorStyles.Left | AnchorStyles.Right, AccessibleName = $"Password for profile {title}", Tag = KeyClickService.PasswordFieldTag };
grid.Controls.Add(label);
grid.Controls.Add(box);
rows.Add((title, current, box));