Reputation: 43
I change my layouts with a very primitive xkb-switch
utility. I need to imitate the 'Share the same input method among all applications - disabled' behaviour of IBus.
xkb-switch
shell command (it just lists my current layout: us(altgr-intl)
,am
or ru
).xkb-switch --switch <layout_here>
client.connect_signal("unfocus", function(c)
awful.spawn.easy_async_with_shell("xkb-switch", function(stdout)
if c.valid then
c.keyboard_layout = stdout
end
end)
end)
client.connect_signal("focus", function(c)
c = awful.screen.focused({client = true})
if c.keyboard_layout == nil then
c.keyboard_layout = "us(altgr-intl)"
end
awful.spawn.with_shell("xkb-switch -s "..c.keyboard_layout)
end)
Here is the behaviour: the notification popup is showing the intended language, but for some reason the switched language is wrong, is there some race hazard? https://youtu.be/juarLneLBAo
Upvotes: 1
Views: 35
Reputation: 789
Here is the way which I use:
local layout = require("awful.widget.keyboardlayout")
local menubar = require("menubar")
require("awful.client").property.persist("last_layout", "number")
local kbdlayout = {
globally_preferred = "us",
menubar_preferred = "us",
}
local function get_idx_by_name(name)
if not name then
return
end
for i, v in ipairs(layout.get_groups_from_group_names(awesome.xkb_get_group_names())) do
if v.file == name then
return i - 1
end
end
end
local oneshot_lock = false
local function on_layout_change()
if oneshot_lock then
oneshot_lock = false
return
end
local c = client.focus
if c then
c.last_layout = awesome.xkb_get_layout_group()
end
end
local function on_focus_changed(c)
local idx = c.last_layout or get_idx_by_name(c.preferred_layout or kbdlayout.globally_preferred)
if idx and awesome.xkb_get_layout_group() ~= idx then
awesome.xkb_set_layout_group(idx)
end
end
awesome.connect_signal("xkb::map_changed", on_layout_change)
awesome.connect_signal("xkb::group_changed", on_layout_change)
client.connect_signal("focus", on_focus_changed)
local menubar_show = menubar.show
local menubar_hide = menubar.hide
function menubar.show(...)
menubar_show(...)
local idx = get_idx_by_name(kbdlayout.menubar_preferred)
if idx then
oneshot_lock = true
awesome.xkb_set_layout_group(idx)
end
end
function menubar.hide(...)
menubar_hide(...)
local c = client.focus
if c then
on_focus_changed(c)
end
end
return kbdlayout
Upvotes: 0
Reputation: 43
In the end I changed 2 lines of code and now this works:
client.connect_signal("unfocus", function(c)
awful.spawn.easy_async_with_shell("xkb-switch", function(stdout)
if c.valid then -- To avoid 'Invalid Object' error
c.keyboard_layout = stdout
end
end)
end)
client.connect_signal("focus", function(c)
if c.keyboard_layout == nil then
c.keyboard_layout = "us(altgr-intl)"
end
awful.spawn("xkb-switch -s "..c.keyboard_layout, false) -- `false` to prevent cursor being stuck in 'loading' state
end)
Upvotes: 0