Learning Swedish with Linux, Sway, and an X1 Yoga tablet
This post is about how I configured a tablet-mode for my Lenovo X1 Yoga so that I can use it in my Swedish classes. It includes details on the configuration of Sway, Waybar, and my own custom Textual-based Swedish-English dictionary. Hopefully it will come useful to other Linux users that would like to use their convertible laptop as a tablet.
Introduction
I’ve been using the X1 Yoga for 7 years now. It’s a well-designed powerful device that’s built to very high standards. Like other āYogaā devices, the screen can be folded all the way to the back, and since itās a touch screen, it essentially turns the laptop into one big tablet. Admittedly, I have only used the laptop on ātablet-modeā very seldom, usually when reading lengthy articles. As a Linux user using Sway and spending most of my time in the terminal, Iām relying heavily on the keyboard and the whole touch thing felt like it wasnāt built for my use case.
But then I started taking Swedish classes. Some people used the physical books, but some just downloaded them off libgen and had it on their tablet. Not only are the two books heavier than my laptop, I also find it more comfortable to read from the laptop in front of me, rather than to hold the book for hours. While the laptop is great for reading, it isnāt so great when working with the book: often there are tasks like āunderline the words you donāt understandā, ācross the words that donāt fitā, ādraw a line between X and Yā etc. The X1 Yoga has a pen built into it, but it feels weird to draw on the screen when the laptop is in laptop mode. I therefore decided to try to build a functioning ātablet-modeā and see how this workflow works for me.
Configuration
Sway receives an event when the screen is opened more than 180Ā°. Iāve used it run some commands that reconfigure my UI according to the status:
~/.config/sway/config
bindswitch tablet:on exec 'notify-send "tablet mode on" -t 1000', \
exec 'gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true', \
exec 'bash -c "killall waybar; waybar --config /home/bjesus/.config/waybar/tablet --style /home/bjesus/.config/waybar/tablet.css"', \
exec 'rot8', \
exec 'squeekboard', \
exec 'swaymsg input "1386:21173:Wacom_HID_52B5_Finger" map_to_output "eDP-1"', \
exec 'swaymsg input "1386:21173:Wacom_HID_52B5_Pen" map_to_output "eDP-1"', \
exec 'swaymsg "[workspace=^] border pixel 15"'
bindswitch tablet:off exec 'notify-send "tablet-mode off" -t 1000', \
exec 'gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled false', \
exec 'bash -c "killall waybar; waybar"', \
exec 'killall rot8', \
exec 'killall squeekboard', \
exec 'swaymsg input "1386:21173:Wacom_HID_52B5_Finger" map_to_output "eDP-1"', \
exec 'swaymsg input "1386:21173:Wacom_HID_52B5_Pen" map_to_output "eDP-1"', \
exec 'swaymsg "[workspace=^] border pixel 0"'
Useful tools
Iām using squeekboard as my on-screen keyboard. It was quite easy to set up and configure custom layouts, so I created a Colemak Swedish layout. The command gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true
is used to automatically show the keyboard whenever a text input field is focused.
rot8 is used to automatically rotate the screen when in tablet mode. I donāt need it when using the device as a laptop, so I simply kill the process along with the on-screen keyboard.
Iāve noticed that sometimes the screen and its touch interface can go out of sync, so Iām using the map_to_output
command to relink them. The border pixel 15
setting gives a 15px border to all windows, making it easier to resize windows without using the keyboard/mouse. I found 15px to be perfect when using my pen or finger, but YMMV.
As you can see, one other thing Sway is doing is to restart Waybar, each time with a different configuration.
Waybar
Waybar is what Iām using to show a little horizontal bar with information on the current workspace, next meeting, time, weather, battery status etc. Iāve been using it for a few years and I love how customizable it is. I needed to make a few changes however: First, I wanted to make things a little bigger, so I can easily click them with my finger. Second, I removed some widgets that arenāt used, such as āthe last line from my tmux sessionā or āthe next eventā, and made some widgets clickable - for example, since I donāt have the keyboardās airplane mode button available, I made the Wifi widget toggle the wifi status. Third, Iāve added four buttons - kill the current window, open the keyboard, translate the selection, and a launcher to start apps. This features are all binded to keyboard shortcuts, but I donāt have my keyboard on tablet-mode, so…
~/.config/waybar/tablet
{
// ...
"custom/touchbutton": {
"format": " š ",
"on-click": "wofi -i --show drun -Iam -H 600"
},
"custom/closebutton": {
"format": " ā ",
"on-click": "swaymsg kill"
},
"custom/keyboard": {
"format": " āØļø",
"on-click": "busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true"
},
"custom/translate": {
"format": " š ",
"on-click": "/home/bjesus/.scripts/babylon"
},
"network": {
"format-wifi": " ",
"format-ethernet": "ó° {ifname}: {ipaddr}/{cidr}",
"format-linked": " {ifname} (No IP)",
"format-disconnected": "ā N/A",
"tooltip-format-wifi": "{essid}: {ipaddr}",
"on-click": "/home/bjesus/.scripts/toggle-wifi"
},
"backlight": {
"format": "{icon} {percent}",
"on-scroll-up": "light -U 1",
"on-scroll-down": "light -A 1",
"format-icons": ["", ""],
"on-click": "/home/bjesus/.scripts/set-screen-brightness"
}
// ...
}
Iām sure there are more suitable launchers than wofi for this, but Iāve been using it before and it works just fine on touch too. The closebutton
uses swaymsg
to kill the current window, which is useful for windows without window decorations. The keyboard button opens the keyboard regardless of the current focused element. Lastly, Iāve written a script for toggling the WiFi and for setting the screen brightness ā two things Iām fiddling with often to preserve battery life:
~/.scripts/toggle-wifi
#!/bin/sh
if iwctl device wlan0 show | grep Powered | grep on; then
notify-send "turning wifi off" -t 1000
iwctl device wlan0 set-property Powered off
else
notify-send "turning wifi on" -t 1000
iwctl device wlan0 set-property Powered on
fi
~/.scripts/set-screen-brightness
#!/bin/sh
light -S $(echo -e '01\n05\n10\n20\n30\n40\n50\n60\n70\n80\n90\n100' | wofi --show dmenu --columns 3 -G --cache-file /dev/null)
The first script uses iwd
to toggle the WiFi power status. The second one uses wofi
to display options of screen brightness, and then passes it to light
to actually set the brightness. It’s not a slider and it’s not the most beautiful interface ever, but it’s one line of code and I enjoy the simplicity of reusing tools. You can just touch “60” with your finger to set the brightness to 60%.
The translate
button is the one Iām using the most however. It calls this tiny script:
#!/bin/sh
mkdir /tmp/babylon
export SWAYSHOT_HIDE_MESSAGE=true
export SWAYSHOT_SCREENSHOTS=/tmp/babylon
swayshot region
notify-send "$(tesseract /tmp/babylon/* - -l swe | trans --indent 0 --brief :en --no-bidi)"
rm -rf /tmp/babylon
This allows me to mark an area on the screen, pass it through an OCR, translate it, and then display the result as a message. Like this:
Note I did patch Swayshot to use the SWAYSHOT_HIDE_MESSAGE
environment variable to not display a message about the screenshot being taken. Simply change the show_message
function to this:
show_message() {
if [ -z $SWAYSHOT_HIDE_MESSAGE ]; then
if type notify-send >/dev/null 2>&1; then
notify-send --expire-time=3000 --category=screenshot --icon="$2" "$3" "$1"
fi
fi
}
The swe
dictionary
When studying Swedish we were recommended using Folkets Lexikon for translating Swedish to English. While the website is a bit clunky (especially on mobile), it lets you download the whole dictionary as XML. I previously wrote a simple CLI tool to search the XML file and print the word definition, but now on tablet mode I felt like it needed some UI. I used Textual to create a Terminal User Interface (TUI) that works also with touch.
The nice thing about using Textual is that I can also use swe
now as an app on my Android phone. Termux + Termux:Widget lets me have an icon that starts the command immediately, and exits Termux when it quits. Touch works perfectly too. Textual can even start the interface as a web application, but I havenāt made use of that either.
I’ve also extended swe
to make use of Wiktionary. By parsing the HTML there and converting it to Markdown while preserving the links, I basically turned swe
into a text-only web-browser specific for this website.
Conclusion
When I first started working on this tablet-mode interface I often questioned its usefulness. Would it really be more comfortable than using the device as a laptop? Now when itās done I can say that yes, for me, in a class-room environment where I mostly need to follow some PDF and mark things around it, itās been great to have a tablet interface. Later, when Iām home and I need to do more writing, I use the laptop normally. Having both functionalities in one device ended up being super useful. Lastly, even though Sway and my entire workflow was optimised for working with the keyboard, it ended up being quite simple to reconfigure things so that theyāll work smoothly using touch.
- July 26, 2024