Skip to content

push-to-talk on linux

Written by

bdeshi

Intro

Regularly doing online meet­ings and let­ting every­one lis­ten in on your fam­i­ly dra­ma because you for­got to mute the call is almost a rite of pas­sage for remote work­ers. Sadly too few devices come with a hard­ware micro­phone mute but­ton. So let’s hack togeth­er a soft­ware push-to-talk for Linux!

By the way, you may find some alter­na­tive or bet­ter push-to-talk solu­tions for lin­ux from a web search, but this is my own pro­ce­dure that I’ve been using hap­pi­ly. Your mileage may vary.

Requirements

You are going to need these:

  • xbind­keys
  • xset
  • setxkbmap
  • pulseau­dio or pipewire
  • an X11 desk­top environment
  • a key­board key to sacrifice

We have to hijack a key­board key for our push-to-talk func­tion­al­i­ty — let’s pick on the CapsLock key. Install the nec­es­sary pro­grams from your dis­tro’s pack­age repos­i­to­ries. Don’t know how? just search for “install tool­name in dis­tro”!

the script

We will use xbind­keys to attach scripts for tog­gling micro­phone mute state to CapsLock’s key press and key release events. You need to run a com­mand that can iden­ti­fy micro­phone input sources, then mute and unmute them. You can tin­ker with the out­puts of var­i­ous argu­ments for pactl to fig­ure out a work­ing com­mand pipeline, or you can use this over-engi­neered mute-con­trol script I’ve writ­ten for myself.

This can do more than just mute micro­phones, but for our pur­pos­es, mute-control.sh in mute --all and mute-control.sh in unmute --all are the two com­mands we need to use.

Save this script some­where in $PATH, such as ~/.local/share/bin/mute-control.sh, and make it executable:

chmod 755 path/to/mute-control.sh

attach­ing to the key

This is sim­ple. Create or update ~/xbindkeysrc.scm1 with this content:

; ~/.xbindkeysrc.scm ========================================================= ;
; xbindkeys scheme configuration file                                          ;
; overrides ~/.xbindkeysrc (if exists)                                         ;
;==============================================================================;

; push-to-talk with Caps_Lock
(begin
    (xbindkey '(Caps_Lock)
        "mute-control.sh in unmute --all"
    )
    (xbindkey '(Release Caps_Lock)
        "mute-control.sh in mute --all"
    )
)

Great! Now add xbindkeys -p -n to your desk­top envi­ron­men­t’s start­up com­mands. You can run xbindkeys -p -n in a ter­mi­nal right now to test your very own PTT. Isn’t this cool?

Not quite.

Steven Universe No GIF by Cartoon Network EMEA - Find & Share on GIPHY

prob­lem #1: caps-lock state toggle

You have a small prob­lem now: press­ing and releas­ing CapsLock does tog­gle micro­phone mut­ing2, but it also tog­gles caps lock sta­tus, so every­thing you type next will turn into all-caps. The work-around for this is a lit­tle involved. First, let’s con­vert CapsLock to the Compose key, with setxkbmap:

setxkbmap -option 'caps:none,compose:caps'

You should make that setxkbmap com­mand per­ma­nent. Your desk­top’s key­board set­tings might already have a UI for set­ting this option, oth­er­wise you can add it as a start­up command.

Or, add a line to ~/.xprofile like this, for example:

setxkbmap -layout us -option 'caps:none,compose:caps'

Alternatively, run localectl like this (again, this is just an exam­ple, do not run blindly):

localectl set-x11-keymap us,bd '' ',probhat' 'caps:none,compose:caps,grp:win_space_toggle'

Then replace Caps_Lock with Multi_Key in xbind­keys config:

; ~/.xbindkeysrc.scm ========================================================= ;
; xbindkeys scheme configuration file                                          ;
; overrides ~/.xbindkeysrc (if exists)                                         ;
;==============================================================================;

; push-to-talk with Multi_key
(begin
    (xbindkey '(Multi_key)
        "mute-control in unmute --all"
    )
    (xbindkey '(Release Multi_key)
        "mute-control in mute --all"
    )
)

Now it should work fine, except…

prob­lem #2: key repeating

if you press and hold the key, mic tog­gle prob­a­bly goes insane, rapid­ly mut­ing and unmut­ing for­ev­er. I guess this is because CapsLock is cat­e­go­rized as a mod­i­fi­er key and does not trig­ger key repeat; so when you press and hold it, only a sin­gle key press event is gen­er­at­ed, and anoth­er sin­gle release event is gen­er­at­ed when you release the key — but Multi_​key/​Compose is not con­sid­ered a mod­i­fi­er key, so it has key repeat by default; mean­ing a stream of key press and key release events are gen­er­at­ed as long as you hold this key.

To work around this, we need sup­port from xset:

$ xset -r Multi_key

Instead of man­u­al­ly run­ning this com­mand every time, you should add this as a start­up com­mand in your desk­top envi­ron­ment. Or in fact, we can start it from xbind­keys con­fig directly:

; ~/.xbindkeysrc.scm ========================================================= ;
; xbindkeys scheme configuration file                                          ;
; overrides ~/.xbindkeysrc (if exists)                                         ;
;==============================================================================;

; push-to-talk with Multi_key
(begin
    (run-command "xset -r Multi_key > /dev/null")
    (xbindkey '(Multi_key)
        "mute-control in unmute --all"
    )
    (xbindkey '(Release Multi_key)
        "mute-control in mute --all"
    )
)

Done!

By the way, your CapsLock has bonus fea­tures now: you can hold the key for push-to-talk, and you can press Shift+CapsLock to use it as the Compose key.


This arti­cle was moti­vat­ed by The Penguins Club BlogTalk event. #blogtalk #pen­guin­sclub


  1. xbind­keys sup­ports plain-text based con­fig­u­ra­tion as ~/.xbindkeysrc, and guile scheme script con­fig as ~/.xbindkeys.scm. The scheme con­fig is far more expres­sive with sup­port for pro­gram­ma­ble con­structs like loops, func­tions etc. Isn’t this impres­sive?
  2. if it does­n’t, then I guess you have two prob­lems 🤷‍♂️. Let’s close­ly review every­thing from the start.

Previous article

start

Next article

deleting twitter like a nerd

Join the discussion

Leave a Reply

Your email address will not be published. Required fields are marked *