From d9b1d5490cd0ef18578d969153ecab1f9e1f53a5 Mon Sep 17 00:00:00 2001 From: Aleksey Fedotov Date: Mon, 23 Feb 2015 22:30:02 +0300 Subject: [PATCH] xkb: Added widget to display current keyboard layout Widget shows current keyboard layout short name (usually two letters, for example 'us', 'de'). Indicator will be hidden if only one layout configured. Layout can be switched either by clicking on widget or by function keyboardlayout.next_layout() --- awesomerc.lua.in | 6 ++ lib/awful/widget/init.lua.in | 1 + lib/awful/widget/keyboardlayout.lua.in | 104 +++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 lib/awful/widget/keyboardlayout.lua.in 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