Skip to content

Instantly share code, notes, and snippets.

@sykire
Last active April 23, 2024 01:33
Show Gist options
  • Save sykire/5260878723c6f866b553771220e312ef to your computer and use it in GitHub Desktop.
Save sykire/5260878723c6f866b553771220e312ef to your computer and use it in GitHub Desktop.

Client Hints for AwesomeWM

screenshot

Copy the file bellow hints.lua to your awesome config folder. Then your rc.lua file:

local show_hints = require('hints.lua')

-- Later where you register your keybinds
awful.key({ modkey, "Shift" }, "f", show_hints, { description = "show hints", group = "client" })
  • Type the letters shown in at the top-left corner of your clients.
  • If there only exists one client that starts with a letter you just need to type the first letter.
  • Casing is ignored
  • Press Escape to stop the keygrabber. You can stop it also with any key that doesn't match any hint, but Escape is set as the default stop_key.
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local clients_hints = {}
local clients_widgets = {}
local clients_texts = {}
local hints = {}
local hints_tree = {}
local registered = false
local function randchar()
return string.char(math.random(26) + 96)
end
local function produce_hint()
local hint = ""
while true do
local new_hint = randchar() .. randchar()
if hints[new_hint] == nil then
hint = new_hint
break
end
end
return hint
end
local function register()
if registered then
return
end
client.connect_signal("manage", function(c)
local hint = produce_hint()
hints[hint] = true
clients_hints[c] = hint
local hint_1 = hint:sub(1, 1)
local hint_2 = hint:sub(2, 2)
if hints_tree[hint_1] == nil then
hints_tree[hint_1] = {}
end
hints_tree[hint_1][hint_2] = c
end)
client.connect_signal("unmanage", function(c)
local hint = clients_hints[c]
hints[hint] = nil
clients_hints[c] = nil
clients_texts[c] = nil
clients_widgets[c] = nil
local hint_1 = hint:sub(1, 1)
local hint_2 = hint:sub(2, 2)
hints_tree[hint_1][hint_2] = nil
if next(hints_tree[hint_1]) == nil then
hints_tree[hint_1] = nil
end
end)
registered = true
end
register()
local function visible_clients(c)
if c.first_tag == nil then
return false
end
return c.minimized == false and c.hidden == false and c.maximized == false and c.first_tag.selected == true
end
local function show_hints()
for c in awful.client.iterate(visible_clients) do
local hint = clients_hints[c]
local widget = clients_widgets[c]
local textbox = clients_texts[c]
if widget == nil then
textbox = wibox.widget({
markup = "",
widget = wibox.widget.textbox,
})
widget = awful.popup({
ontop = true,
visible = false,
screen = c.screen,
client = c,
widget = {
{
textbox,
left = 8,
right = 8,
top = 4,
bottom = 4,
widget = wibox.container.margin,
},
bg = "#ffff00",
shape = function(cr, w, h)
gears.shape.rounded_rect(cr, w, h, 4)
end,
widget = wibox.widget.background,
},
})
clients_widgets[c] = widget
clients_texts[c] = textbox
end
widget.x = c.x + 10
widget.y = c.y + 10
widget.visible = true
textbox.markup = "<span foreground='black'>" .. hint:upper() .. "</span>"
end
local keygrabber
local matched = ""
keygrabber = awful.keygrabber({
stop_key = "Escape",
stop_callback = function()
for _, widget in pairs(clients_widgets) do
widget.visible = false
end
end,
keypressed_callback = function(_, _, key)
key = key:lower()
if matched == "" then
if hints_tree[key] ~= nil then
local count = 0
local key_2 = ""
for _key_2, c in pairs(hints_tree[key]) do
local textbox = clients_texts[c]
count = count + 1
key_2 = _key_2
textbox.markup = "<span foreground='black'><span font_weight='heavy' background='blue' foreground='yellow'>"
.. key:upper()
.. "</span>"
.. _key_2:upper()
.. "</span>"
end
if count == 1 then
client.focus = hints_tree[key][key_2]
keygrabber:stop()
end
matched = key
else
keygrabber:stop()
end
else
if hints_tree[matched][key] ~= nil then
client.focus = hints_tree[matched][key]
matched = ""
end
keygrabber:stop()
end
end,
})
keygrabber:start()
end
return show_hints
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment