diff options
Diffstat (limited to 'awesome/lib/awful/hotkeys_popup/widget.lua')
-rw-r--r-- | awesome/lib/awful/hotkeys_popup/widget.lua | 482 |
1 files changed, 0 insertions, 482 deletions
diff --git a/awesome/lib/awful/hotkeys_popup/widget.lua b/awesome/lib/awful/hotkeys_popup/widget.lua deleted file mode 100644 index 62a2231..0000000 --- a/awesome/lib/awful/hotkeys_popup/widget.lua +++ /dev/null @@ -1,482 +0,0 @@ ---------------------------------------------------------------------------- ---- Popup widget which shows current hotkeys and their descriptions. --- --- @author Yauheni Kirylau <yawghen@gmail.com> --- @copyright 2014-2015 Yauheni Kirylau --- @module awful.hotkeys_popup.widget ---------------------------------------------------------------------------- - -local capi = { - screen = screen, - client = client, - keygrabber = keygrabber, -} -local awful = require("awful") -local wibox = require("wibox") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local compute_textbox_width = require("menubar").utils.compute_textbox_width - - --- Stripped copy of this module https://github.com/copycat-killer/lain/blob/master/util/markup.lua: -local markup = {} --- Set the font. -function markup.font(font, text) - return '<span font="' .. tostring(font) .. '">' .. tostring(text) ..'</span>' -end --- Set the foreground. -function markup.fg(color, text) - return '<span foreground="' .. tostring(color) .. '">' .. tostring(text) .. '</span>' -end --- Set the background. -function markup.bg(color, text) - return '<span background="' .. tostring(color) .. '">' .. tostring(text) .. '</span>' -end - -local widget_module = { - group_rules = {}, -} - ---- Don't show hotkeys without descriptions. -widget_module.hide_without_description = true - ---- Merge hotkey records into one if they have the same modifiers and --- description. -widget_module.merge_duplicates = true - - -function widget_module.new() -local widget = { - hide_without_description = widget_module.hide_without_description, - merge_duplicates = widget_module.merge_duplicates, - group_rules = awful.util.table.clone(widget_module.group_rules), - title_font = "Monospace Bold 9", - description_font = "Monospace 8", - width = dpi(1200), - height = dpi(800), - border_width = beautiful.border_width or dpi(2), - modifiers_color = beautiful.bg_minimize or "#555555", - group_margin = dpi(6), - additional_hotkeys = {}, - labels = { - Mod4="Super", - Mod1="Alt", - Escape="Esc", - Insert="Ins", - Delete="Del", - Backspace="BackSpc", - Return="Enter", - Next="PgDn", - Prior="PgUp", - ['#108']="Alt Gr", - Left='←', - Up='↑', - Right='→', - Down='↓', - ['#67']="F1", - ['#68']="F2", - ['#69']="F3", - ['#70']="F4", - ['#71']="F5", - ['#72']="F6", - ['#73']="F7", - ['#74']="F8", - ['#75']="F9", - ['#76']="F10", - ['#95']="F11", - ['#96']="F12", - ['#10']="1", - ['#11']="2", - ['#12']="3", - ['#13']="4", - ['#14']="5", - ['#15']="6", - ['#16']="7", - ['#17']="8", - ['#18']="9", - ['#19']="0", - ['#20']="-", - ['#21']="=", - Control="Ctrl" - }, -} - -local cached_wiboxes = {} -local cached_awful_keys = nil -local colors_counter = {} -local colors = beautiful.xresources.get_current_theme() -local group_list = {} - - -local function get_next_color(id) - id = id or "default" - if colors_counter[id] then - colors_counter[id] = math.fmod(colors_counter[id] + 1, 15) + 1 - else - colors_counter[id] = 1 - end - return colors["color"..tostring(colors_counter[id], 15)] -end - - -local function join_plus_sort(modifiers) - if #modifiers<1 then return "none" end - table.sort(modifiers) - return table.concat(modifiers, '+') -end - - -local function add_hotkey(key, data, target) - if widget.hide_without_description and not data.description then return end - - local readable_mods = {} - for _, mod in ipairs(data.mod) do - table.insert(readable_mods, widget.labels[mod] or mod) - end - local joined_mods = join_plus_sort(readable_mods) - - local group = data.group or "none" - group_list[group] = true - if not target[group] then target[group] = {} end - local new_key = { - key = (widget.labels[key] or key), - mod = joined_mods, - description = data.description - } - local index = data.description or "none" -- or use its hash? - if not target[group][index] then - target[group][index] = new_key - else - if widget.merge_duplicates and joined_mods == target[group][index].mod then - target[group][index].key = target[group][index].key .. "/" .. new_key.key - else - while target[group][index] do - index = index .. " " - end - target[group][index] = new_key - end - end -end - - -local function sort_hotkeys(target) - -- @TODO: add sort by 12345qwertyasdf etc - for group, _ in pairs(group_list) do - if target[group] then - local sorted_table = {} - for _, key in pairs(target[group]) do - table.insert(sorted_table, key) - end - table.sort( - sorted_table, - function(a,b) return (a.mod or '')..a.key<(b.mod or '')..b.key end - ) - target[group] = sorted_table - end - end -end - - -local function import_awful_keys() - if cached_awful_keys then - return - end - cached_awful_keys = {} - for _, data in pairs(awful.key.hotkeys) do - add_hotkey(data.key, data, cached_awful_keys) - end - sort_hotkeys(cached_awful_keys) -end - - -local function group_label(group, color) - local textbox = wibox.widget.textbox( - markup.font(widget.title_font, - markup.bg( - color or (widget.group_rules[group] and - widget.group_rules[group].color or get_next_color("group_title") - ), - markup.fg(beautiful.bg_normal or "#000000", " "..group.." ") - ) - ) - ) - local margin = wibox.container.margin() - margin:set_widget(textbox) - margin:set_top(widget.group_margin) - return margin -end - -local function get_screen(s) - return s and capi.screen[s] -end - -local function create_wibox(s, available_groups) - s = get_screen(s) - - local wa = s.workarea - local height = (widget.height < wa.height) and widget.height or - (wa.height - widget.border_width * 2) - local width = (widget.width < wa.width) and widget.width or - (wa.width - widget.border_width * 2) - - -- arrange hotkey groups into columns - local line_height = beautiful.get_font_height(widget.title_font) - local group_label_height = line_height + widget.group_margin - -- -1 for possible pagination: - local max_height_px = height - group_label_height - local column_layouts = {} - for _, group in ipairs(available_groups) do - local keys = cached_awful_keys[group] or widget.additional_hotkeys[group] - local joined_descriptions = "" - for i, key in ipairs(keys) do - joined_descriptions = joined_descriptions .. key.description .. (i~=#keys and "\n" or "") - end - -- +1 for group label: - local items_height = awful.util.linecount(joined_descriptions) * line_height + group_label_height - local current_column - local available_height_px = max_height_px - local add_new_column = true - for i, column in ipairs(column_layouts) do - if ((column.height_px + items_height) < max_height_px) or - (i == #column_layouts and column.height_px < max_height_px / 2) - then - current_column = column - add_new_column = false - available_height_px = max_height_px - current_column.height_px - break - end - end - local overlap_leftovers - if items_height > available_height_px then - local new_keys = {} - overlap_leftovers = {} - -- +1 for group title and +1 for possible hyphen (v): - local available_height_items = (available_height_px - group_label_height*2) / line_height - for i=1,#keys do - table.insert(((i<available_height_items) and new_keys or overlap_leftovers), keys[i]) - end - keys = new_keys - table.insert(keys, {key=markup.fg(widget.modifiers_color, "▽"), description=""}) - end - if not current_column then - current_column = {layout=wibox.layout.fixed.vertical()} - end - current_column.layout:add(group_label(group)) - - local function insert_keys(_keys, _add_new_column) - local max_label_width = 0 - local max_label_content = "" - local joined_labels = "" - for i, key in ipairs(_keys) do - local length = string.len(key.key or '') + string.len(key.description or '') - local modifiers = key.mod - if not modifiers or modifiers == "none" then - modifiers = "" - else - length = length + string.len(modifiers) + 1 -- +1 for "+" character - modifiers = markup.fg(widget.modifiers_color, modifiers.."+") - end - local rendered_hotkey = markup.font(widget.title_font, - modifiers .. (key.key or "") .. " " - ) .. markup.font(widget.description_font, - key.description or "" - ) - if length > max_label_width then - max_label_width = length - max_label_content = rendered_hotkey - end - joined_labels = joined_labels .. rendered_hotkey .. (i~=#_keys and "\n" or "") - end - current_column.layout:add(wibox.widget.textbox(joined_labels)) - local max_width = compute_textbox_width(wibox.widget.textbox(max_label_content), s) + - widget.group_margin - if not current_column.max_width or max_width > current_column.max_width then - current_column.max_width = max_width - end - -- +1 for group label: - current_column.height_px = (current_column.height_px or 0) + - awful.util.linecount(joined_labels)*line_height + group_label_height - if _add_new_column then - table.insert(column_layouts, current_column) - end - end - - insert_keys(keys, add_new_column) - if overlap_leftovers then - current_column = {layout=wibox.layout.fixed.vertical()} - insert_keys(overlap_leftovers, true) - end - end - - -- arrange columns into pages - local available_width_px = width - local pages = {} - local columns = wibox.layout.fixed.horizontal() - for _, item in ipairs(column_layouts) do - if item.max_width > available_width_px then - columns.widgets[#columns.widgets]['widget']:add( - group_label("PgDn - Next Page", beautiful.fg_normal) - ) - table.insert(pages, columns) - columns = wibox.layout.fixed.horizontal() - available_width_px = width - item.max_width - local old_widgets = item.layout.widgets - item.layout.widgets = {group_label("PgUp - Prev Page", beautiful.fg_normal)} - awful.util.table.merge(item.layout.widgets, old_widgets) - else - available_width_px = available_width_px - item.max_width - end - local column_margin = wibox.container.margin() - column_margin:set_widget(item.layout) - column_margin:set_left(widget.group_margin) - columns:add(column_margin) - end - table.insert(pages, columns) - - local mywibox = wibox({ - ontop = true, - opacity = beautiful.notification_opacity or 1, - border_width = widget.border_width, - border_color = beautiful.fg_normal, - }) - mywibox:geometry({ - x = wa.x + math.floor((wa.width - width - widget.border_width*2) / 2), - y = wa.y + math.floor((wa.height - height - widget.border_width*2) / 2), - width = width, - height = height, - }) - mywibox:set_widget(pages[1]) - mywibox:buttons(awful.util.table.join( - awful.button({ }, 1, function () mywibox.visible=false end), - awful.button({ }, 3, function () mywibox.visible=false end) - )) - - local widget_obj = {} - widget_obj.current_page = 1 - widget_obj.wibox = mywibox - function widget_obj:page_next() - if self.current_page == #pages then return end - self.current_page = self.current_page + 1 - self.wibox:set_widget(pages[self.current_page]) - end - function widget_obj:page_prev() - if self.current_page == 1 then return end - self.current_page = self.current_page - 1 - self.wibox:set_widget(pages[self.current_page]) - end - function widget_obj:show() - self.wibox.visible = true - end - function widget_obj:hide() - self.wibox.visible = false - end - - return widget_obj -end - - ---- Show popup with hotkeys help. --- @tparam[opt] client c Client. --- @tparam[opt] screen s Screen. -function widget.show_help(c, s) - import_awful_keys() - c = c or capi.client.focus - s = s or (c and c.screen or awful.screen.focused()) - - local available_groups = {} - for group, _ in pairs(group_list) do - local need_match - for group_name, data in pairs(widget.group_rules) do - if group_name==group and ( - data.rule or data.rule_any or data.except or data.except_any - ) then - if not c or not awful.rules.matches(c, { - rule=data.rule, - rule_any=data.rule_any, - except=data.except, - except_any=data.except_any - }) then - need_match = true - break - end - end - end - if not need_match then table.insert(available_groups, group) end - end - - local joined_groups = join_plus_sort(available_groups) - if not cached_wiboxes[s] then - cached_wiboxes[s] = {} - end - if not cached_wiboxes[s][joined_groups] then - cached_wiboxes[s][joined_groups] = create_wibox(s, available_groups) - end - local help_wibox = cached_wiboxes[s][joined_groups] - help_wibox:show() - - return capi.keygrabber.run(function(_, key, event) - if event == "release" then return end - if key then - if key == "Next" then - help_wibox:page_next() - elseif key == "Prior" then - help_wibox:page_prev() - else - capi.keygrabber.stop() - help_wibox:hide() - end - end - end) -end - - ---- Add hotkey descriptions for third-party applications. --- @tparam table hotkeys Table with bindings, --- see `awful.hotkeys_popup.key.vim` as an example. -function widget.add_hotkeys(hotkeys) - for group, bindings in pairs(hotkeys) do - for _, binding in ipairs(bindings) do - local modifiers = binding.modifiers - local keys = binding.keys - for key, description in pairs(keys) do - add_hotkey(key, { - mod=modifiers, - description=description, - group=group}, - widget.additional_hotkeys - ) - end - end - end - sort_hotkeys(widget.additional_hotkeys) -end - - -return widget -end - -local function get_default_widget() - if not widget_module.default_widget then - widget_module.default_widget = widget_module.new() - end - return widget_module.default_widget -end - ---- Show popup with hotkeys help (default widget instance will be used). --- @tparam[opt] client c Client. --- @tparam[opt] screen s Screen. -function widget_module.show_help(...) - return get_default_widget().show_help(...) -end - ---- Add hotkey descriptions for third-party applications --- (default widget instance will be used). --- @tparam table hotkeys Table with bindings, --- see `awful.hotkeys_popup.key.vim` as an example. -function widget_module.add_hotkeys(...) - return get_default_widget().add_hotkeys(...) -end - -return widget_module - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 |