Fix Sway’s Flaky Keyboard Layout Switching for Good It’s not just you. The default methods are unreliable. Here’s the one-line fix that changed my workflow.
👋 Hey everyone,
If you’re like me, you chose a minimalist tiling window manager like Sway for a reason: control. You’re probably running it on a lean system like Arch Linux, you live in the terminal (I’m a foot and neovim user myself), and you curate your dotfiles with obsessive care.
This kind of setup is about building a digital environment that’s a perfect extension of your brain. It’s fast, it’s efficient, and it’s yours.
But this week, a tiny grain of sand got into the gears of my perfect machine. A problem so simple, it was infuriating: I couldn’t reliably switch my keyboard layout.
My Goal This Week 🎯
My workflow is multilingual. I write code, documentation, and commit messages in English (us layout). I also write emails, blog posts, and messages to family in Turkish (tr layout). In a modern desktop environment, this should be a solved problem. You set two layouts, you pick a keybinding, and you switch between them.
My goal was simple: to press a key combination and have my keyboard instantly and reliably switch between “tr” and “us” layouts, every single time, without fail.
I’m deep in my cybersecurity master’s program, and my focus is on becoming a SOC analyst. The last thing I have time for is fighting my window manager over a keyboard layout. My environment should help me, not hinder me.
The Process & The Code 👨💻
Like any good Sway user, the first place I went was my ~/.config/sway/config file.
The standard advice you’ll find on forums and wikis for setting up multiple layouts looks something like this.
First, you define the layouts you want to use in an input block. This part is correct and necessary. You’re telling Sway, “These are the layouts I care about.”
### Input configuration
#
# You can get the names of your inputs by running: swaymsg -t get_inputs
#
input type:keyboard {
# Define the layouts you want to cycle through, separated by a comma.
# For my setup: Turkish and US layouts.
xkb_layout "tr,us"
}
This step is crucial. Without it, xkb_switch_layout has nothing to switch to.
Second, you bind a key to trigger the switch. This is where the internet led me astray. The most common recommendation I found was this:
# The common (but flaky) method
# Note: My $mod key is set to Mod1 (Alt)
bindsym $mod+Ctrl+space exec "swaymsg input * xkb_switch_layout next"
Let’s break this down:
bindsym $mod+Ctrl+space: Bind the key combinationAlt+Ctrl+Space.exec: Execute a shell command.swaymsg: This is the command-line utility that sends commands to the running Sway compositor.input *: This is the target. It means “send the following command to all input devices.”xkb_switch_layout next: This is the command. “Switch to the next keyboard layout in the list.”
On the surface, this looks logical. But it was the source of all my frustration.
Hitting The Wall 🧱
This command was completely unreliable.
I’d hit Alt+Ctrl+Space. Nothing.
I’d hit it again. It switches.
I’d hit it a third time. Nothing.
Sometimes it would work five times in a row, and then fail for the next minute. It felt random, and in a deterministic system like Arch, “random” is just a word for “a problem I don’t understand yet.”
My troubleshooting brain kicked in. What could be the variable?
I ran swaymsg -t get_inputs to see what Sway was actually seeing. The list was long. It wasn’t just my ThinkPad’s keyboard. It was my external keyboard, my mouse (which technically counts as an input device), and several virtual devices I didn’t even know I had.
The “Aha!” moment was realizing what input * truly meant.
I wasn’t telling my keyboard to switch. I was yelling into a crowded room, “Hey, everyone, switch your layout!”
My mouse doesn’t have a keyboard layout. My virtual devices don’t. The command was being sent to all of them, and the system was getting confused, leading to a race condition or just outright failure.
This general, all-encompassing command was the problem. The solution had to be specific.
The Breakthrough Moment ✨
The fix, when it finally clicked, was beautifully simple.
If input * is the problem, the solution is to stop using it. I don’t need to talk to all devices. I need to talk only to the keyboard.
Sway’s input command is much more powerful than a simple wildcard. You can specify exactly what you want to target. And the command for that is type:keyboard.
This led to the new, improved, and 100% reliable command:
swaymsg input type:keyboard xkb_switch_layout next
This command says, “Find all input devices of type keyboard and only to them, issue the command to switch layouts.”
The second part of the breakthrough was rethinking the keybinding itself.
$mod+Ctrl+space(Alt+Ctrl+Space) is a bit of a finger-twister.- More importantly, my
$mod(Alt) key is sacred. I use it constantly for application-level shortcuts in Neovim andfoot.
A system-wide action (like changing layouts) shouldn’t conflict with application-level actions. The “Super” key (or Mod4, the “Windows” key) is perfect for this. It’s almost exclusively reserved for the window manager.
So, I combined these two ideas into my new, perfect keybinding:
# Switch keyboard layout (tr/us) using Super+Space
# This is the 100% reliable fix.
bindsym Mod4+space exec "swaymsg input type:keyboard xkb_switch_layout next"
I added this line to my ~/.config/sway/config, hit $mod+Shift+c to reload…
And it just worked.
I’ve been using it for days. I’ve hit it hundreds of times. It has not failed once. It’s instant, reliable, and decoupled from my application hotkeys. The grain of sand is gone.
📚 Recommended Resource
If you’re spending this much time configuring your dotfiles and living in the terminal, you are a professional user. And professionals need professional tools.
We obsess over software, but often neglect the hardware we touch for 8+ hours a day. After spending hours diagnosing this issue, I was reminded of the importance of ergonomics.
I’ve been researching new keyboards, and the one I keep coming back to is the Logitech K860 Ergonomic Keyboard.
It’s a split, curved keyboard designed to reduce strain on your wrists and shoulders. For those of us who live by the keyboard, investing in something that protects our long-term health is just as important as a well-configured window manager. If you’re going to be a master of your craft, you need to protect your hands. The K860 (or its sibling, the MX Keys) is a fantastic place to start.
Key Takeaways 📚
- 💡 Specificity Beats Generality. In configuration,
*is almost always the wrong answer. Targetingtype:keyboardinstead ofinput *was the key. This applies to code, shell scripts, and life. Be specific. - ⚙️ Separate Your Concerns (WM vs. Apps). Use
Mod4(Super) for your Window Manager (Sway) hotkeys. LeaveMod1(Alt) for your applications (Neovim, foot, etc.). This mental model simplifies your entire workflow. - 📚
swaymsgis Your Best Debugging Tool. When in doubt, don’t guess. Useswaymsg -t get_inputsorswaymsg -t get_outputsto ask Sway exactly what it’s thinking. The answer is always in themanpages or the diagnostic tools.
Thanks for Following ☕
This fix was a small victory, but it felt huge. It restored the “flow” to my workflow. I hope this deep dive helps another Sway user who’s pulling their hair out over the same “simple” problem.
☕ If you found this guide helpful, you can Buy Me a Coffee! Medium Etsy LinkedIn Read More
What’s the one “simple” config-tweak that saved your workflow? Let me know in the comments.
