cleanup
This commit is contained in:
parent
e2f420d934
commit
537619514f
21
README.md
21
README.md
|
@ -1,12 +1,12 @@
|
||||||
We are surprised at the time of this writing that the system tray remains such an obvious bottleneck in the nevertheless ubiquitous fight against mouse-dependency among neckbeards the world over. We present accordingly, systray_hints.
|
We are surprised at the time of this writing that the system tray remains such an obvious bottleneck in the nevertheless ubiquitous fight against mouse-dependency among neckbeards the world over. We present accordingly: systray_hints.
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
When `systray_hints.run()` is executed, a popup widget displays numbers next to each icon in the system tray while keygrabber listens for input. The number entered on the keyboard sends a right click to the corresponding icon and the original position of the mouse pointer is restored. For most programs this opens a context menu the user may then navigate using arrow keys and pressing Return.
|
When `systray_hints.run()` is executed, a popup widget displays a number next to each icon in the system tray while keygrabber listens for input. The number entered on the keyboard sends a right click to the corresponding icon and the original position of the mouse pointer is restored. For most programs this opens a context menu the user may then navigate using arrows and the Return key. To cancel, submit any invalid entry; in practice this includes the Escape key as well as whatever keybinding was configured to launch the function.
|
||||||
|
|
||||||
The default option of a right click may be overriden on the fly by pressing the Left or Right arrow key before making a selection for a left or right click, respectively. Alternatively, pressing either the Up or Down key will bypass all clicking and the pointer is simply moved to the location of the selected icon to display its on-hover tooltip, if any.
|
The configured mouse button (right-click by default) can be overridden before entering a selection by pressing the Left or Right arrow key for a left or right click, respectively. Alternatively, pressing the Up arrow key will substitute hovering for clicking to display a given icon's tooltip, if any.
|
||||||
|
|
||||||
If ten or more icons are displayed, the function will interpret the "1" key as the first digit of the selection and wait for the second digit, or wait for the Return key. Up to 19 icons are supported.
|
If ten or more icons are displayed, the keygrabber will interpret the "1" key as the first digit of the selection and wait for the second digit, or for the Return key to select the first icon. Up to 19 icons are supported.
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
|
|
||||||
|
@ -17,6 +17,13 @@ Add `systray_hints = require("systray_hints")` to rc.lua. Note this may work bet
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
|
Configure by overriding systray_hints table values after the require statement. For example, set the font, left-click by default, and redefine the keybindings for left-click [1], hover [2], and right-click [3].
|
||||||
|
|
||||||
|
systray_hints = require("systray_hints")
|
||||||
|
systray_hints.font = "Iosevka Bold 16"
|
||||||
|
systray_hints.default_button = 1
|
||||||
|
systray_hints.mouse_buttons = { "h", "j", "l" }
|
||||||
|
|
||||||
If the system tray is normally hidden in your environment and toggled as needed with a keybinding, you can replace that keybinding with something like this:
|
If the system tray is normally hidden in your environment and toggled as needed with a keybinding, you can replace that keybinding with something like this:
|
||||||
|
|
||||||
awful.key({ modkey }, "s", function ()
|
awful.key({ modkey }, "s", function ()
|
||||||
|
@ -34,7 +41,7 @@ If the system tray is normally hidden in your environment and toggled as needed
|
||||||
|
|
||||||
end, {description="toggle systray with hints", group="awesome"}),
|
end, {description="toggle systray with hints", group="awesome"}),
|
||||||
|
|
||||||
The `systray_hints.run()` function will automatically unhide the system tray as needed and will return it to its original visiblity state whenever a selection is not made.
|
The `systray_hints.run()` function will automatically unhide the system tray as needed and will return it to its original visiblity state whenever a selection is not made, such as when the key combination is pressed again.
|
||||||
|
|
||||||
If your system tray is always displayed, simply create a keybinding like the following:
|
If your system tray is always displayed, simply create a keybinding like the following:
|
||||||
|
|
||||||
|
@ -53,6 +60,4 @@ If your system tray is always displayed, simply create a keybinding like the fol
|
||||||
|
|
||||||
The ability to obtain the geometry of the system tray is not referenced in the awesome API for a reason; in theory it may occasionally return incorrect data, requiring an additional execution of the keybinding.
|
The ability to obtain the geometry of the system tray is not referenced in the awesome API for a reason; in theory it may occasionally return incorrect data, requiring an additional execution of the keybinding.
|
||||||
|
|
||||||
This project was previously assembled as a quick hack in the form of a shell script requiring iocane, rofi, and xdotool. It has been rewritten as a native lua module for the latest stable release with no external dependencies. Final testing and clean-up in progress.
|
This project was previously assembled as a quick hack in the form of a shell script requiring iocane, rofi, and xdotool. It has been rewritten as a native lua module for the latest stable release with no external dependencies. While deprecated functions were avoided, we have not yet tested it in the development version.
|
||||||
|
|
||||||
While deprecated functions were avoided, we have not yet tested it in the development version.
|
|
||||||
|
|
208
init.lua
208
init.lua
|
@ -1,45 +1,42 @@
|
||||||
-- S Y S T R A Y H I N T S
|
-- S Y S T R A Y H I N T S
|
||||||
-- rts/oarion7 - ryanthomas.org
|
-- rts/oarion7 - ryanthomas.org
|
||||||
-- Module to control the awesomewm systray from the keyboard using
|
-- Control the awesomewm systray from the keyboard using vimium-like
|
||||||
-- vimium-like number hints. Developed and tested on awesome v4.3.
|
-- number hints. Developed and tested on awesome v4.3.
|
||||||
|
|
||||||
-- TO DO: move widget to table (remove globals)
|
|
||||||
-- cleanup
|
|
||||||
|
|
||||||
local awful = require("awful")
|
local awful = require("awful")
|
||||||
local gears = require("gears")
|
local gears = require("gears")
|
||||||
local b = require("beautiful")
|
local b = require("beautiful")
|
||||||
local wibox = require("wibox")
|
local wibox = require("wibox")
|
||||||
|
|
||||||
local s
|
local s
|
||||||
|
|
||||||
local font = b.systray_hints_font or b.taglist_font or b.font
|
awful.screen.connect_for_each_screen(function(screen)
|
||||||
local bgcolor = b.systray_hints_bg or b.taglist_bg_occupied or "#55465a"
|
if screen.systray then s = screen end
|
||||||
local highlight = b.systray_hints_bg_highlight or "#aa53aa"
|
end)
|
||||||
local highlight_alt = b.systray_hints_bg_highlight_alt or "#426f5a"
|
|
||||||
local fgcolor = b.systray_hints_fg or b.taglist_fg_occupied or "#fdf6e3"
|
|
||||||
local bordercolor = "#fdf6e333"
|
|
||||||
|
|
||||||
awful.screen.connect_for_each_screen(function(screen) if screen.systray then s = screen end end)
|
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
|
|
||||||
local systray_hints = {
|
local systray_hints = {
|
||||||
arrows = { "Left", "Down", "Up", "Right" },
|
|
||||||
--arrows = { "h", "j", "k", "l" },
|
font = b.systray_hints_font or b.taglist_font or b.font,
|
||||||
default_button = 3,
|
bgcolor = b.systray_hints_bg or b.taglist_bg_occupied or "#55465a",
|
||||||
--default_button = 1,
|
highlight = b.systray_hints_bg_highlight or "#aa53aa",
|
||||||
hints = hints,
|
|
||||||
systray = s.systray,
|
highlight_alt = b.systray_hints_bg_highlight_alt or "#426f5a",
|
||||||
wibox = s.mywibox, --where the system tray is located
|
color = b.systray_hints_fg or b.taglist_fg_occupied or "#fdf6e3",
|
||||||
run = run,
|
bordercolor = "#fdf6e333",
|
||||||
|
spacing = 1,
|
||||||
|
mouse_buttons = { "Left", "Up", "Right" },
|
||||||
|
default_button = 3,
|
||||||
|
popup = popup,
|
||||||
|
systray = s.systray,
|
||||||
|
wibox = s.mywibox, --wibox in which to locate the system tray
|
||||||
|
run = run,
|
||||||
}
|
}
|
||||||
|
|
||||||
local total
|
local total
|
||||||
local was_hidden
|
local was_hidden
|
||||||
local icon_count
|
|
||||||
local icon_width
|
local icon_width
|
||||||
local half_icon
|
local icons_x
|
||||||
local first_icon_x
|
|
||||||
local icons_y
|
local icons_y
|
||||||
|
|
||||||
local function delay(time, cmd)
|
local function delay(time, cmd)
|
||||||
|
@ -47,48 +44,47 @@ local function delay(time, cmd)
|
||||||
callback = function () cmd () end, } )
|
callback = function () cmd () end, } )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function execute(choice, mouse_button)
|
local function execute(choice, mouse_button)
|
||||||
|
|
||||||
local target
|
local saved
|
||||||
local factor
|
local factor
|
||||||
local saved_coords
|
local target
|
||||||
|
|
||||||
saved_coords = mouse.coords({x = x, y = y})
|
saved = mouse.coords({x = x, y = y})
|
||||||
if choice == 1 then factor = 0 else factor = choice - 1 end
|
if choice == 1 then factor = 0 else factor = choice - 1 end
|
||||||
target = first_icon_x + ( icon_width * factor )
|
target = icons_x + ( icon_width * factor )
|
||||||
mouse.coords { x = target , y = icons_y }
|
mouse.coords { x = target , y = icons_y }
|
||||||
|
|
||||||
if mouse_button ~= 2 then
|
if mouse_button ~= 2 then
|
||||||
root.fake_input("button_press" , tostring(mouse_button))
|
root.fake_input("button_press" , tostring(mouse_button))
|
||||||
root.fake_input("button_release", tostring(mouse_button))
|
root.fake_input("button_release", tostring(mouse_button))
|
||||||
delay(0.05, function () mouse.coords({x = saved_coords.x, y = saved_coords.y}, true) end)
|
delay(0.05, function () mouse.coords({x = saved.x, y = saved.y}, true) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if systray_hints.hints then systray_hints.hints.visible = false end
|
if systray_hints.popup then systray_hints.popup.visible = false end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function highlight_options(total)
|
local function highlight_multidigits(total)
|
||||||
local color
|
local color
|
||||||
for i = 9, total do
|
for i = 9, total do
|
||||||
color = highlight_alt
|
color = systray_hints.highlight_alt
|
||||||
if i == 9 then
|
if i == 9 then
|
||||||
i = 1
|
i = 1
|
||||||
color = highlight
|
color = systray_hints.highlight
|
||||||
end
|
end
|
||||||
systray_hints.hints.widget:get_children()[1]:get_children()[i].widget:set_bg(color)
|
systray_hints.popup.widget:get_children()[1]:get_children()[i].widget:set_bg(color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_key_input(total)
|
local function get_key_input(total)
|
||||||
|
|
||||||
local grabber
|
local grabber
|
||||||
local mouse_button
|
local mouse_button
|
||||||
local mouse_button = systray_hints.default_button
|
|
||||||
local function conc(n) return tonumber( 1 .. n ) end
|
local function conc(n) return tonumber( 1 .. n ) end
|
||||||
|
|
||||||
|
mouse_button = systray_hints.default_button
|
||||||
|
|
||||||
grabber = awful.keygrabber {
|
grabber = awful.keygrabber {
|
||||||
|
|
||||||
mask_modkeys = true,
|
mask_modkeys = true,
|
||||||
|
@ -97,9 +93,10 @@ local function get_key_input(total)
|
||||||
|
|
||||||
if key == '1' and total > 9 then
|
if key == '1' and total > 9 then
|
||||||
|
|
||||||
if systray_hints.hints then
|
if systray_hints.popup then
|
||||||
highlight_options(total)
|
highlight_multidigits(total)
|
||||||
end
|
end
|
||||||
|
|
||||||
grabber.keypressed_callback = function(self, mod, key, cmd)
|
grabber.keypressed_callback = function(self, mod, key, cmd)
|
||||||
if key == "Return" then
|
if key == "Return" then
|
||||||
execute(1, mouse_button)
|
execute(1, mouse_button)
|
||||||
|
@ -109,20 +106,20 @@ local function get_key_input(total)
|
||||||
grabber:stop()
|
grabber:stop()
|
||||||
else
|
else
|
||||||
grabber:stop()
|
grabber:stop()
|
||||||
if was_hidden then s.systray.visible = false end
|
if was_hidden then systray_hints.systray.visible = false end
|
||||||
if systray_hints.hints then systray_hints.hints.visible = false end
|
if systray_hints.popup then systray_hints.popup.visible = false end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif key == systray_hints.arrows[1] then mouse_button = 1
|
elseif key == systray_hints.mouse_buttons[1] then mouse_button = 1
|
||||||
elseif key == systray_hints.arrows[4] then mouse_button = 3
|
elseif key == systray_hints.mouse_buttons[2] then mouse_button = 2
|
||||||
elseif key == systray_hints.arrows[2] or key == systray_hints.arrows[3] then mouse_button = 2
|
elseif key == systray_hints.mouse_buttons[3] then mouse_button = 3
|
||||||
elseif not key:match("%D") and tonumber(key) <= total then
|
elseif not key:match("%D") and tonumber(key) <= total then
|
||||||
execute(tonumber(key), mouse_button)
|
execute(tonumber(key), mouse_button)
|
||||||
grabber:stop()
|
grabber:stop()
|
||||||
else
|
else
|
||||||
grabber:stop()
|
grabber:stop()
|
||||||
if was_hidden then s.systray.visible = false end
|
if was_hidden then systray_hints.systray.visible = false end
|
||||||
if systray_hints.hints then systray_hints.hints.visible = false end
|
if systray_hints.popup then systray_hints.popup.visible = false end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
@ -131,79 +128,67 @@ local function get_key_input(total)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function show_hints(x, y, w, total, s)
|
||||||
|
|
||||||
|
local hints = {}
|
||||||
|
local hint_width
|
||||||
|
|
||||||
local function show_hints(sys_hints_geo_x, sys_hints_geo_y, w, sys_hints_icon_count, s)
|
hint_width = w - ( systray_hints.spacing * 2 )
|
||||||
|
|
||||||
local sys_hints_icon_width = w - 2 --subtract for margins
|
--Decide whether hints should display above or below systray icons.
|
||||||
|
if y >= 100 then y = y - hint_width else y = y + hint_width end
|
||||||
|
|
||||||
if sys_hints_geo_y >= 100 then
|
--Hide if already displayed
|
||||||
sys_hints_geo_y = sys_hints_geo_y - sys_hints_icon_width
|
if systray_hints.popup then systray_hints.popup.visible = false end
|
||||||
else sys_hints_geo_y = sys_hints_geo_y + sys_hints_icon_width
|
|
||||||
--Decide if hints should display above or below systray icons.
|
|
||||||
end
|
|
||||||
|
|
||||||
--hide if already displayed
|
|
||||||
if systray_hints.hints then systray_hints.hints.visible = false end
|
|
||||||
|
|
||||||
local num_rows = sys_hints_icon_count
|
|
||||||
local sys_hints_list = {}
|
|
||||||
local systray_widget_list = {}
|
|
||||||
|
|
||||||
local widget_shape = function(cr, width, height)
|
local widget_shape = function(cr, width, height)
|
||||||
gears.shape.rounded_rect(cr, width, height, 5)
|
gears.shape.rounded_rect(cr, width, height, 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
local var = {}
|
for i = 1, total do
|
||||||
for i = 1, num_rows do table.insert(sys_hints_list, tostring(i)) end
|
|
||||||
for k, v in pairs(sys_hints_list) do
|
|
||||||
|
|
||||||
var["text_" .. v] = wibox.widget.textbox(tostring(v))
|
local text
|
||||||
local text_alias = var["text_" .. v]
|
local placement = {}
|
||||||
text_alias.font = font -- "Sans 14"
|
local background = {}
|
||||||
text_alias.markup = '<span color="' .. fgcolor ..
|
local margins = {}
|
||||||
'">' .. v .. '</span>'
|
|
||||||
|
|
||||||
local item_place = {}
|
text = wibox.widget.textbox(tostring(i))
|
||||||
table.insert(item_place, text_alias)
|
text.font = systray_hints.font
|
||||||
|
text.markup = '<span color="' .. systray_hints.color .. '">' ..
|
||||||
|
i .. '</span>'
|
||||||
|
|
||||||
item_place.widget = wibox.container.place
|
table.insert(placement, text)
|
||||||
|
|
||||||
|
placement.widget = wibox.container.place
|
||||||
|
table.insert(background, placement)
|
||||||
|
|
||||||
local item_background = {}
|
background.widget = wibox.container.background
|
||||||
table.insert(item_background, item_place)
|
background.bg = systray_hints.bgcolor
|
||||||
|
background.forced_width = hint_width
|
||||||
|
background.shape = widget_shape
|
||||||
|
background.shape_border_width = 2
|
||||||
|
background.shape_border_color = systray_hints.bordercolor
|
||||||
|
|
||||||
item_background.widget = wibox.container.background
|
table.insert(margins, background)
|
||||||
item_background.bg = bgcolor -- "#ff00ff"
|
|
||||||
item_background.forced_width = sys_hints_icon_width
|
|
||||||
item_background.shape = widget_shape
|
|
||||||
item_background.shape_border_width = 2
|
|
||||||
item_background.shape_border_color = bordercolor
|
|
||||||
tostring(v)
|
|
||||||
|
|
||||||
local item_margin = {}
|
margins.widget = wibox.container.margin
|
||||||
table.insert(item_margin, item_background)
|
margins.right = systray_hints.spacing
|
||||||
|
margins.left = systray_hints.spacing
|
||||||
item_margin.widget = wibox.container.margin
|
table.insert(hints, margins)
|
||||||
item_margin.right = 1
|
|
||||||
item_margin.left = 1
|
|
||||||
|
|
||||||
local complete_widget = item_margin
|
|
||||||
table.insert(systray_widget_list, complete_widget)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
systray_widget_list.layout = wibox.layout.fixed.horizontal
|
hints.layout = wibox.layout.fixed.horizontal
|
||||||
systray_hints.hints = awful.popup {
|
systray_hints.popup = awful.popup {
|
||||||
widget = {
|
widget = {
|
||||||
screen = s,
|
screen = s,
|
||||||
systray_widget_list,
|
hints,
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
layout = wibox.layout.fixed.horizontal,
|
|
||||||
},
|
},
|
||||||
x = sys_hints_geo_x,
|
x = x,
|
||||||
y = sys_hints_geo_y,
|
y = y,
|
||||||
visible = true,
|
visible = true,
|
||||||
ontop = true,
|
ontop = true,
|
||||||
bg = "#00000000",
|
bg = "#00000000",
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -214,14 +199,13 @@ local function find_widget_in_wibox(wb, wdg)
|
||||||
local g = gears.matrix.transform_rectangle
|
local g = gears.matrix.transform_rectangle
|
||||||
local x, y, w, h = g(hi:get_matrix_to_device(), 0, 0, hi:get_size())
|
local x, y, w, h = g(hi:get_matrix_to_device(), 0, 0, hi:get_size())
|
||||||
|
|
||||||
icon_count = math.floor( ( w - ( w % h) ) / h + 1 )
|
total = math.floor( ( w - ( w % h) ) / h + 1 )
|
||||||
icon_width = math.floor(w / icon_count )
|
icon_width = math.floor(w / total )
|
||||||
half_icon = math.floor( icon_width / 2)
|
icons_x = math.floor( x + icon_width / 2)
|
||||||
first_icon_x = math.floor( x + half_icon)
|
icons_y = math.floor(y + icon_width / 2)
|
||||||
icons_y = math.floor(y + half_icon)
|
|
||||||
|
|
||||||
show_hints( math.floor(x), math.floor(y), icon_width, icon_count, s )
|
show_hints( math.floor(x), math.floor(y), icon_width, total, s )
|
||||||
get_key_input(icon_count)
|
get_key_input(total)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -231,9 +215,7 @@ local function find_widget_in_wibox(wb, wdg)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for _, child in ipairs(hi:get_children()) do
|
for _, child in ipairs(hi:get_children()) do
|
||||||
-- return traverse(child)
|
|
||||||
traverse(child)
|
traverse(child)
|
||||||
-- allow for additional round of recursion across container widgets.
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return traverse(wb._drawable._widget_hierarchy)
|
return traverse(wb._drawable._widget_hierarchy)
|
||||||
|
@ -241,9 +223,9 @@ end
|
||||||
|
|
||||||
systray_hints.run = function ()
|
systray_hints.run = function ()
|
||||||
|
|
||||||
if not s.systray.visible then
|
if not systray_hints.systray.visible then
|
||||||
was_hidden = true
|
was_hidden = true
|
||||||
s.systray.visible = true
|
systray_hints.systray.visible = true
|
||||||
delay(0.05, function () find_widget_in_wibox(systray_hints.wibox, systray_hints.systray) end)
|
delay(0.05, function () find_widget_in_wibox(systray_hints.wibox, systray_hints.systray) end)
|
||||||
else
|
else
|
||||||
find_widget_in_wibox(systray_hints.wibox, systray_hints.systray)
|
find_widget_in_wibox(systray_hints.wibox, systray_hints.systray)
|
||||||
|
|
Loading…
Reference in New Issue