-
Notifications
You must be signed in to change notification settings - Fork 13
/
kbdcfg.lua
146 lines (117 loc) · 4.21 KB
/
kbdcfg.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
--[[
Licensed under MIT
* (c) 2017, Egor Churaev [email protected]
--]]
local awful = require("awful")
local wibox = require("wibox")
local kbdcfg = {}
-- Function to change current layout to the next available layout
function kbdcfg.switch_next()
kbdcfg.current = kbdcfg.current % #(kbdcfg.layouts) + 1
kbdcfg.switch(kbdcfg.layouts[kbdcfg.current])
end
-- Function to find layout in list and set current index
local function find_current_layout(name)
for index, layout in ipairs(kbdcfg.additional_layouts) do
if layout.name == name then
return index, layout
end
end
return nil, nil
end
-- Function to change current layout based on the name
function kbdcfg.switch_by_name(name)
local index, layout = find_current_layout(name)
kbdcfg.switch(layout)
end
-- Function to change layout
function kbdcfg.switch(layout)
local index = find_current_layout(layout.name)
kbdcfg.current = index
if client.focus then
local layout = kbdcfg.additional_layouts[kbdcfg.current]
client.focus.kbd_layout = layout.name
end
if kbdcfg.type == "tui" then
kbdcfg.widget:set_text(kbdcfg.tui_wrap_left .. layout.label .. kbdcfg.tui_wrap_right)
else
kbdcfg.widget.image = layout.label
end
os.execute(kbdcfg.cmd .. " \"" .. layout.subcmd .. "\"")
end
-- Function to add primary layouts
function kbdcfg.add_primary_layout(name, label, subcmd)
local layout = { name = name,
label = label,
subcmd = subcmd };
table.insert(kbdcfg.layouts, layout)
table.insert(kbdcfg.additional_layouts, layout)
end
-- Function to add additional layouts
function kbdcfg.add_additional_layout(name, label, subcmd)
local layout = { name = name,
label = label,
subcmd = subcmd };
table.insert(kbdcfg.additional_layouts, layout)
end
-- Bind function. Applies all settings to the widget
function kbdcfg.bind()
-- Menu for choose additional keyboard layouts
local menu_items = {}
for i = 1, #kbdcfg.additional_layouts do
local layout = kbdcfg.additional_layouts[i]
table.insert(menu_items, {
layout.name,
function () kbdcfg.switch(layout) end,
-- show a fancy image in gui mode
kbdcfg.type == "gui" and layout.label or nil
})
end
kbdcfg.menu = awful.menu({ items = menu_items })
if kbdcfg.type == "tui" then
kbdcfg.widget = wibox.widget.textbox()
else
kbdcfg.widget = wibox.widget.imagebox()
end
if kbdcfg.default_layout_index > #kbdcfg.layouts then
kbdcfg.default_layout_index = 1;
kbdcfg.current = kbdcfg.default_layout_index;
end
if kbdcfg.remember_layout then
client.connect_signal("focus", kbd_client_update)
end
local current_layout = kbdcfg.layouts[kbdcfg.current]
if current_layout then
kbdcfg.switch(current_layout)
end
end
-- Callback function for set remembering layout for windows
function kbd_client_update(c)
if not c then
return
end
if not c.kbd_layout then
c.kbd_layout = kbdcfg.layouts[kbdcfg.default_layout_index].name
end
kbdcfg.switch_by_name(c.kbd_layout)
end
-- Factory function. Creates the widget.
local function factory(args)
local args = args or {}
kbdcfg.cmd = args.cmd or "setxkbmap"
kbdcfg.layouts = args.layouts or {}
kbdcfg.additional_layouts = args.additional_layouts or {}
kbdcfg.default_layout_index = args.default_layout_index or 1
kbdcfg.current = args.current or kbdcfg.default_layout_index
kbdcfg.menu = nil
kbdcfg.type = args.type or "tui"
kbdcfg.tui_wrap_left = args.tui_wrap_left or " "
kbdcfg.tui_wrap_right = args.tui_wrap_right or " "
kbdcfg.remember_layout = args.remember_layout or false
for i = 1, #kbdcfg.layouts do
table.insert(kbdcfg.additional_layouts, kbdcfg.layouts[i])
end
return kbdcfg
end
setmetatable(kbdcfg, { __call = function(_, ...) return factory(...) end })
return kbdcfg