File: init.lua

package info (click to toggle)
awesome-extra 2023010601
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,340 kB
  • sloc: cpp: 112; sh: 84; makefile: 25; python: 11
file content (150 lines) | stat: -rw-r--r-- 3,760 bytes parent folder | download | duplicates (2)
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
147
148
149
150
---------------------------------
-- Author: Andrei Thorp        --
-- Copyright 2010 Andrei Thorp --
---------------------------------
-- Dependencies: setxkbmap (shell command)
-- Ideas:
-- * user specified rewrite table: convert us(dvorak) to "Dvorak"
-- * use formatting system to allow people to format their text widgets
-- * allow the user to override the text widget with some other widget
-- * filter out the current layout from the menu that appears on click
-- * let user configure the quick update delay (1 second) in case their
--   computer is unusually slow or quick or something

local setmetatable = setmetatable
local pairs = pairs
local ipairs = ipairs
local io = {
  popen = io.popen
}
local awful = require("awful")
local wibox = require("wibox")
local lib = {
  hooks = require("obvious.lib.hooks"),
  markup = require("obvious.lib.markup")
}

local defaults = {}
defaults.layouts = {}
defaults.menu = nil
defaults.widget = wibox.widget.textbox()
defaults.widget:set_text("...")

local current_index = 1

-- Clone the defaults to the used settings
local settings = {}
for key, value in pairs(defaults) do
  settings[key] = value
end

-- forward declaration of functions
local update
local set_layouts

-- Updates once after a short delay and then unregisters its timer
local function delayed_update_once(start)
  if start == true then
    lib.hooks.timer.register(1, 1, delayed_update_once, "One-off update for keymap widget")
    lib.hooks.timer.start(delayed_update_once)
  else
    update()
    lib.hooks.timer.unregister(delayed_update_once)
  end
end

local setup_done = false
local function init_once()
  if setup_done then
    return
  end
  lib.hooks.timer.register(5, 60, update, "Update for the keymap widget")
  lib.hooks.timer.start(update)
  delayed_update_once(true)
  setup_done = true
end

local function switch_keymap(layout_string)
  awful.util.spawn("setxkbmap \"" .. layout_string .. "\"")
  delayed_update_once(true)
end

local function init(widget)
  init_once()

  -- Use the default widget if not specified
  if widget then
    settings.widget = widget
  end

  local layouts = settings.layouts
  settings.widget.rotate_layout = function()
    current_index = current_index + 1

    if current_index > #layouts then
      current_index = 1
    end

    switch_keymap(layouts[current_index])
  end

  -- Reconfigure the menu immediately
  set_layouts(settings.layouts)

  -- Set up the on-click menu event
  settings.widget:buttons(awful.util.table.join(
    awful.button({ }, 1, function() settings.menu:toggle() end)
  ))

  return settings.widget
end

-- Returns the current keymap, as discovered from setxkbmap
local function get_current_keymap()
  local fd = io.popen("setxkbmap -print")
  if not fd then return end

  for line in fd:lines() do
    if line:match("xkb_symbols") then
      local keymap = line:match('%+[a-zA-Z0-9()]*%+')

      fd:close()
      if not keymap then
        return "unknown layout"
      else
        return keymap:sub(2, -2)
      end
    end
  end

  fd:close()
  return "unknown layout"
end

--[[local]] function set_layouts(layouts_table)
  settings.layouts = layouts_table or settings.layouts

  local newitems = {}
  for index, value in ipairs(settings.layouts) do
    newitems[index] = { value, function()
      current_index = index
      switch_keymap(value)
    end }
  end

  settings.menu = awful.menu.new({
    id = "keymap_switch",
    items = newitems
  })
end

--[[local]] function update()
  settings.widget:set_markup(get_current_keymap())
end

return setmetatable({
  set_layouts = set_layouts,
  update      = update,
}, { __call = function() return init(settings.widget) end }) -- TODO let the user specify widget here

-- vim:ft=lua:ts=2:sw=2:sts=2:tw=80:et