Add alt+d deafen keyboard shortcut.

This commit is contained in:
Storm Dragon
2026-09-05 21:53:57 -04:00
parent f21e7c9960
commit cf9746c8de
10 changed files with 124 additions and 7 deletions
+2 -1
View File
@@ -240,6 +240,7 @@ func (b *Barnard) keyboardHelpItems() []uiterm.TreeItem {
adminItem{label: hotkeyLabel(hotkeys.AdminMenu) + ": open actions and settings"},
adminItem{label: hotkeyLabel(hotkeys.Talk) + ": toggle transmission"},
adminItem{label: hotkeyLabel(hotkeys.SelfMuteToggle) + ": toggle self-mute"},
adminItem{label: hotkeyLabel(hotkeys.SelfDeafenToggle) + ": toggle self-deafen"},
adminItem{label: hotkeyLabel(hotkeys.NoiseSuppressionToggle) + ": toggle noise suppression"},
adminItem{label: hotkeyLabel(hotkeys.AGCToggle) + ": toggle automatic gain control"},
adminItem{label: hotkeyLabel(hotkeys.RecordToggle) + ": toggle recording"},
@@ -276,7 +277,7 @@ func hotkeyLabel(key *uiterm.Key) string {
uiterm.KeyF5: "F5", uiterm.KeyF6: "F6", uiterm.KeyF7: "F7", uiterm.KeyF8: "F8",
uiterm.KeyF9: "F9", uiterm.KeyF10: "F10", uiterm.KeyF11: "F11", uiterm.KeyF12: "F12",
uiterm.KeyCtrlL: "Control+L", uiterm.KeyCtrlQ: "Control+Q", uiterm.KeyCtrlR: "Control+R", uiterm.KeyCtrlT: "Control+T",
uiterm.KeyAltM: "Alt+M", uiterm.KeyTab: "Tab", uiterm.KeyHome: "Home", uiterm.KeyEnd: "End",
uiterm.KeyAltD: "Alt+D", uiterm.KeyAltM: "Alt+M", uiterm.KeyTab: "Tab", uiterm.KeyHome: "Home", uiterm.KeyEnd: "End",
uiterm.KeyPgup: "Page Up", uiterm.KeyPgdn: "Page Down", uiterm.KeyArrowUp: "Up Arrow", uiterm.KeyArrowDown: "Down Arrow",
uiterm.KeyArrowLeft: "Left Arrow", uiterm.KeyArrowRight: "Right Arrow",
uiterm.KeyBackspace: "Backspace", uiterm.KeyBackspace2: "Backspace", uiterm.KeyM: "M",
-3
View File
@@ -600,8 +600,6 @@ func (app *App) run() error {
err = app.manage_certificate()
case "Logs":
err = app.manage_logs()
case "About barnard-ui":
err = app.ui.message("barnard-ui is the native Go interface for managing Barnard servers, certificates, and logs. It does not require Python or GNU Dialog.")
}
if err != nil {
return err
@@ -616,7 +614,6 @@ func main_menu_options() []string {
"Remove server",
"Manage Certificate",
"Logs",
"About barnard-ui",
"Exit",
}
}
+3 -3
View File
@@ -196,13 +196,13 @@ func TestConnectionArgsNeverExposePassword(t *testing.T) {
}
}
func TestProgramIdentityAndAboutMenuUseBarnardUI(t *testing.T) {
func TestProgramIdentityAndMainMenuUseBarnardUI(t *testing.T) {
if programName != "barnard-ui" {
t.Fatalf("programName = %q", programName)
}
options := main_menu_options()
if !slices.Contains(options, "About barnard-ui") {
t.Fatalf("main menu lacks About barnard-ui: %v", options)
if slices.Contains(options, "About barnard-ui") {
t.Fatalf("main menu still contains About barnard-ui: %v", options)
}
for _, option := range options {
if strings.Contains(option, "go-ui") {
+1
View File
@@ -24,4 +24,5 @@ type Hotkeys struct {
NoiseSuppressionToggle *uiterm.Key
AGCToggle *uiterm.Key
SelfMuteToggle *uiterm.Key
SelfDeafenToggle *uiterm.Key
}
+5
View File
@@ -182,6 +182,7 @@ func (c *Config) ensureHotkeys() {
NoiseSuppressionToggle: key(uiterm.KeyF9),
AGCToggle: key(uiterm.KeyF12),
SelfMuteToggle: key(uiterm.KeyAltM),
SelfDeafenToggle: key(uiterm.KeyAltD),
}
hotkeys := c.config.Hotkeys
if hotkeys.Talk == nil {
@@ -243,6 +244,9 @@ func (c *Config) ensureHotkeys() {
if hotkeys.SelfMuteToggle == nil {
hotkeys.SelfMuteToggle = defaults.SelfMuteToggle
}
if hotkeys.SelfDeafenToggle == nil {
hotkeys.SelfDeafenToggle = defaults.SelfDeafenToggle
}
}
func hotkeyAlreadyUsed(hotkeys *Hotkeys, wanted uiterm.Key) bool {
@@ -252,6 +256,7 @@ func hotkeyAlreadyUsed(hotkeys *Hotkeys, wanted uiterm.Key) bool {
hotkeys.SwitchViews, hotkeys.ClearOutput, hotkeys.ScrollUp, hotkeys.ScrollDown,
hotkeys.ScrollToTop, hotkeys.ScrollToBottom, hotkeys.AdminMenu,
hotkeys.NoiseSuppressionToggle, hotkeys.AGCToggle, hotkeys.SelfMuteToggle,
hotkeys.SelfDeafenToggle,
}
for _, binding := range bindings {
if binding != nil && *binding == wanted {
+4
View File
@@ -49,6 +49,9 @@ func TestConfigBackfillsRecordingDefaults(t *testing.T) {
if got := *cfg.GetHotkeys().RecordToggle; got != uiterm.KeyCtrlR {
t.Fatalf("expected record toggle ctrl_r, got %s", got)
}
if got := cfg.GetHotkeys().SelfDeafenToggle; got == nil || *got != uiterm.KeyAltD {
t.Fatalf("expected self deafen toggle alt_d, got %v", got)
}
if cfg.GetHotkeys().AdminMenu == nil {
t.Fatal("expected admin menu hotkey to be backfilled")
}
@@ -96,6 +99,7 @@ func TestNewHotkeyDefaults(t *testing.T) {
{name: "volume reset", got: hotkeys.VolumeReset, want: uiterm.KeyBackspace},
{name: "tree mute", got: hotkeys.MuteToggle, want: uiterm.KeyM},
{name: "self mute", got: hotkeys.SelfMuteToggle, want: uiterm.KeyAltM},
{name: "self deafen", got: hotkeys.SelfDeafenToggle, want: uiterm.KeyAltD},
{name: "actions menu", got: hotkeys.AdminMenu, want: uiterm.KeyF10},
{name: "keyboard help", got: hotkeys.HelpMenu, want: uiterm.KeyF1},
{name: "exit", got: hotkeys.Exit, want: uiterm.KeyCtrlQ},
+8
View File
@@ -72,6 +72,14 @@ unmute() {
[[ $notify ]] && notify "You unmuted yourself."
}
mutedeafen() {
[[ $notify ]] && notify "You muted and deafened yourself."
}
muteundeafen() {
[[ $notify ]] && notify "You undeafened yourself. Your microphone remains muted."
}
msg() {
[[ $sound ]] && play -n synth .3 sin 1290:1490 sin 1494:1294 remix - norm -8
[[ $notify ]] && notify "$1 from $2: $3"
+11
View File
@@ -264,6 +264,17 @@ func (u *User) SetSelfDeafened(muted bool) {
u.client.Conn.WriteProto(&packet)
}
// SetSelfMutedAndDeafened changes both self-mute and self-deafen in one
// protocol update so observers never see an intermediate audio state.
func (u *User) SetSelfMutedAndDeafened(muted, deafened bool) {
packet := MumbleProto.UserState{
Session: &u.Session,
SelfMute: &muted,
SelfDeaf: &deafened,
}
u.client.Conn.WriteProto(&packet)
}
// RequestStats requests that the user's stats be sent to the client.
func (u *User) RequestStats() {
packet := MumbleProto.UserStats{
+50
View File
@@ -0,0 +1,50 @@
package gumble
import (
"net"
"testing"
"git.stormux.org/storm/barnard/gumble/gumble/MumbleProto"
"google.golang.org/protobuf/proto"
)
func TestSetSelfMutedAndDeafenedWritesOneCombinedState(t *testing.T) {
for _, deafened := range []bool{true, false} {
name := "undeafen"
if deafened {
name = "deafen"
}
t.Run(name, func(t *testing.T) {
local, remote := net.Pipe()
defer local.Close()
defer remote.Close()
client := &Client{Conn: NewConn(local)}
user := &User{Session: 7, client: client}
written := make(chan struct{})
go func() {
user.SetSelfMutedAndDeafened(true, deafened)
close(written)
}()
packetType, data, err := NewConn(remote).ReadPacket()
if err != nil {
t.Fatal(err)
}
if packetType != 9 {
t.Fatalf("packet type = %d, want UserState (9)", packetType)
}
var state MumbleProto.UserState
if err := proto.Unmarshal(data, &state); err != nil {
t.Fatal(err)
}
if state.SelfMute == nil || !*state.SelfMute {
t.Fatalf("self mute = %v, want true", state.SelfMute)
}
if state.SelfDeaf == nil || *state.SelfDeaf != deafened {
t.Fatalf("self deafen = %v, want %v", state.SelfDeaf, deafened)
}
<-written
})
}
}
+40
View File
@@ -214,6 +214,10 @@ func (b *Barnard) OnSelfMuteToggle(ui *uiterm.Ui, key uiterm.Key) {
b.toggleSelfMute()
}
func (b *Barnard) OnSelfDeafenToggle(ui *uiterm.Ui, key uiterm.Key) {
b.toggleSelfDeafen()
}
func (b *Barnard) selfMuted() bool {
if b.Client == nil || b.Client.Self == nil {
return false
@@ -250,6 +254,41 @@ func (b *Barnard) toggleSelfMute() {
b.setSelfMute(!b.selfMuted())
}
func (b *Barnard) selfDeafened() bool {
if b.Client == nil || b.Client.Self == nil {
return false
}
deafened := false
b.Client.Do(func() { deafened = b.Client.Self.SelfDeafened })
return deafened
}
func (b *Barnard) setSelfDeafen(deafened bool) {
if !b.isConnected() || b.Client == nil || b.Client.Self == nil {
b.Notify("error", "me", "cannot change self deafen while disconnected")
b.UpdateGeneralStatus("cannot change self deafen while disconnected", true)
return
}
if b.selfDeafened() == deafened {
return
}
if b.isTransmitting() {
b.StopTransmission()
}
b.Client.Self.SetSelfMutedAndDeafened(true, deafened)
if deafened {
b.Notify("mutedeafen", "me", "")
b.AddOutputLine("You muted and deafened yourself")
return
}
b.Notify("muteundeafen", "me", "")
b.AddOutputLine("You undeafened yourself; microphone remains muted")
}
func (b *Barnard) toggleSelfDeafen() {
b.setSelfDeafen(!b.selfDeafened())
}
func (b *Barnard) CommandLog(ui *uiterm.Ui, cmd string) {
b.AddOutputLine("command " + cmd)
}
@@ -710,6 +749,7 @@ func (b *Barnard) OnUiInitialize(ui *uiterm.Ui) {
b.Ui.AddKeyListener(b.OnHelpMenuPress, b.Hotkeys.HelpMenu)
b.Ui.AddKeyListener(b.OnVoiceToggle, b.Hotkeys.Talk)
b.Ui.AddKeyListener(b.OnSelfMuteToggle, b.Hotkeys.SelfMuteToggle)
b.Ui.AddKeyListener(b.OnSelfDeafenToggle, b.Hotkeys.SelfDeafenToggle)
b.Ui.AddKeyListener(b.OnTimestampToggle, b.Hotkeys.ToggleTimestamps)
b.Ui.AddKeyListener(b.OnNoiseSuppressionToggle, b.Hotkeys.NoiseSuppressionToggle)
b.Ui.AddKeyListener(b.OnAGCToggle, b.Hotkeys.AGCToggle)