diff --git a/awesomerc.lua.in b/awesomerc.lua.in index ce647de8..89dc8f9e 100755 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -107,6 +107,10 @@ mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menubar.utils.terminal = terminal -- Set the terminal for applications that require it -- }}} +-- Keyboard map indicator and switcher +mykeyboardlayout = awful.widget.keyboardlayout() +-- }}} + -- {{{ Wibox -- Create a textclock widget mytextclock = awful.widget.textclock() @@ -189,6 +193,8 @@ for s = 1, screen.count() do -- Widgets that are aligned to the right local right_layout = wibox.layout.fixed.horizontal() + right_layout:add(mykeyboardlayout) + if s == 1 then right_layout:add(wibox.widget.systray()) end right_layout:add(mytextclock) right_layout:add(mylayoutbox[s]) diff --git a/lib/awful/widget/init.lua.in b/lib/awful/widget/init.lua.in index 0d61b94c..17b3a682 100644 --- a/lib/awful/widget/init.lua.in +++ b/lib/awful/widget/init.lua.in @@ -18,6 +18,7 @@ return graph = require("awful.widget.graph"); layoutbox = require("awful.widget.layoutbox"); textclock = require("awful.widget.textclock"); + keyboardlayout = require("awful.widget.keyboardlayout"); } -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/awful/widget/keyboardlayout.lua.in b/lib/awful/widget/keyboardlayout.lua.in new file mode 100644 index 00000000..ff4f1ab1 --- /dev/null +++ b/lib/awful/widget/keyboardlayout.lua.in @@ -0,0 +1,104 @@ +--------------------------------------------------------------------------- +-- @author Aleksey Fedotov <lexa@cfotr.com> +-- @copyright 2015 Aleksey Fedotov +-- @release @AWESOME_VERSION@ +--------------------------------------------------------------------------- + +local capi = {awesome = awesome, + awful = awful} +local setmetatable = setmetatable +local os = os +local textbox = require("wibox.widget.textbox") +local button = require("awful.button") +local util = require("awful.util") +local widget_base = require("wibox.widget.base") + +--- Keyboard Layout widget. +-- awful.widget.keyboardlayout +local keyboardlayout = { mt = {} } + +-- Callback for updaing current layout +local function update_status (keyboardlayout) + keyboardlayout.current = awesome.xkb_get_layout_group(); + local text = "" + if (#keyboardlayout.layout > 0) then + text = (" " .. keyboardlayout.layout[keyboardlayout.current] .. " ") + end + keyboardlayout.widget:set_text(text) +end + +-- Callback for updating list of layouts +local function update_layout(keyboardlayout) + keyboardlayout.layout = {}; + local group_names = awesome.xkb_get_group_names(); + +-- typical layout string looks like "pc+us+ru:2+de:3+ba:4+inet" +-- and we want to get only three mathes: "us", "ru:2", "de:3" "ba:4" +-- also please note, that numbers of groups reported by xkb_get_group_names +-- is greater by one of the real group number + + + local first_group = string.match(group_names, "+(%a+)"); + if (not first_group) then + error ("Failed to get list of keyboard groups"); + return; + end + keyboardlayout.layout[0] = first_group; + + for name, number_str in string.gmatch(group_names, "+(%a+):(%d)") do + group = tonumber(number_str); + keyboardlayout.layout[group - 1] = name; + end + update_status(keyboardlayout) +end + +--- Create a keyboard layout widget. It shows current keyboard layout name in a textbox. +-- @return A keyboard layout widget. +function keyboardlayout.new() + local widget = textbox() + local keyboardlayout = widget_base.make_widget(widget) + + keyboardlayout.widget = widget + + update_layout(keyboardlayout); + + keyboardlayout.next_layout = function() + new_layout = (keyboardlayout.current + 1) % (#keyboardlayout.layout + 1) + keyboardlayout.set_layout(new_layout) + end + + keyboardlayout.set_layout = function(group_number) + if (0 > group_number) or (group_number > #keyboardlayout.layout) then + error("Invalid group number: " .. group_number .. + "expected number from 0 to " .. #keyboardlayout.layout) + return; + end + awesome.xkb_set_layout_group(group_number); + end + + -- callback for processing layout changes + capi.awesome.connect_signal("xkb::map_changed", + function () update_layout(keyboardlayout) end) + capi.awesome.connect_signal("xkb::group_changed", + function () update_status(keyboardlayout) end); + + -- Mouse bindings + keyboardlayout:buttons( + util.table.join(button({ }, 1, keyboardlayout.next_layout)) + ) + + return keyboardlayout +end + +local _instance = nil; + +function keyboardlayout.mt:__call(...) + if _instance == nil then + _instance = keyboardlayout.new(...) + end + return _instance +end + +return setmetatable(keyboardlayout, keyboardlayout.mt) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80