UP  |  HOME

Squeekboard

I used the Debian package of squeekboard, but it doesn't include any keyboard layouts. So the first order of business is to create your own or download some existing ones and place them in ~/.local/share/squeekboard/keyboards.

To enable squeekboard dbus service I created this file:

Listing 1: /usr/share/dbus-1/services/sm.puri.OSK0.service
[D-BUS Service]
Name=sm.puri.OSK0
Exec=/usr/bin/squeekboard

It uses the layouts set in gnome settings, but since I'm not using gnome I opted to just set my desired layouts manually. Setting layout for the on-screen keyboard has no effect on hardware keyboards. The setting is maintained after you set it, but I did not test if Gnome modifies it without asking.

Set available layouts
gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ru'), ('xkb', 'us+dvorak')]"

Now you should be able to run squeekboard. Try it in a terminal first to see any output. It should be hidden by default so enable it as below:

Enabled on-screen keyboard
gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true

Now it will automatically toggle visibility when it detects text input.

You can also manually trigger it while leaving it enabled as below:

Manually trigger keyboard
busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true

With these basics I built up these scripts and a little custom waybar module. For now they are just triggered by waybar, but I might want to use them with touchscreen gestures or sway binds later.

Listing 2: ~/.config/waybar/osk/toggle_enable.sh
#!/bin/sh

# check if squeekboard running
if ! pgrep -x squeekboard > /dev/null; then
    nohup squeekboard > /dev/null &
fi

key="org.gnome.desktop.a11y.applications screen-keyboard-enabled"

if [ "$(gsettings get $key)" = "true" ]; then
    gsettings set $key false
else
    gsettings set $key true
fi
Listing 3: ~/.config/waybar/osk/toggle_visible.sh
#!/bin/sh

# check if squeekboard running
if ! pgrep -x squeekboard > /dev/null; then
    nohup squeekboard > /dev/null &
fi

dbus_string="--user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0" 
visible=$(busctl get-property $dbus_string Visible| cut -d ' ' -f 2)

if [ "$visible" = "true" ]; then
    busctl call $dbus_string SetVisible b false
else
    busctl call $dbus_string SetVisible b true
fi
Listing 4: ~/.config/waybar/osk/status.sh
#!/bin/sh

# check if squeekboard running
if ! pgrep -x squeekboard > /dev/null; then
    nohup squeekboard > /dev/null &
fi

sleep 0.1 # wait for things to propagate

text=""
tooltip="Squeekboard"

dbus_string="--user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0" 
visible=$(busctl get-property $dbus_string Visible| cut -d ' ' -f 2)
# percentage is a proxy for 'enabled'. 0 = disabled, 100 = enabled
if [ "$visible" = "true" ]; then
    percentage=100
else
    percentage=0
fi

key="org.gnome.desktop.a11y.applications screen-keyboard-enabled"
if [ "$(gsettings get $key)" = "true" ]; then
    class="activated"
else
    class=""
fi

echo "{\"text\": \"$text\", \"tooltip\": \"$tooltip\", \"class\": \"$class\", \"percentage\": $percentage}"
Listing 5: ~/.config/waybar/config (excerpt)
"custom/osk": {
  "format": "{icon}",
  "format-icons": ["⌧", "⌨"],
  "exec": "$HOME/.config/waybar/osk/status.sh",
  "return-type": "json",
  "interval": 1,
  "exec-on-event": true,
  "exec-if": "! lsusb -d 045e:096f",
  "on-click": "$HOME/.config/waybar/osk/toggle_visible.sh",
  "on-click-right": "$HOME/.config/waybar/osk/toggle_enable.sh"
}