local beautiful = require("beautiful") local gears = require("gears") local awful = require("awful") local wibox = require("wibox") local naughty = require("naughty") local helpers = {} helpers.rrect = function(radius) radius = radius or dpi(4) return function(cr, width, height) gears.shape.rounded_rect(cr, width, height, radius) end end helpers.addhover = function(element, bg, hbg) element:connect_signal("mouse::enter", function(self) self.bg = hbg end) element:connect_signal("mouse::leave", function(self) self.bg = bg end) end helpers.colortext = function(txt, fg) if fg == "" then fg = beautiful.fg end return "" .. txt .. "" end local filepath = "/tmp/awm_tag_storage" helpers.tag = { store_current = function(tag) if not tag then return end local file = io.open(filepath, "w") if file then file:write(tostring(tag.index)) file:close() end end, read_last = function() local file = io.open(filepath, "r") if not file then return nil end local content = file:read("*all") file:close() return content end, } helpers.buffer = {} helpers.buffer.__index = helpers.buffer function helpers.buffer.new(max) return setmetatable({ data = {}, max = max, size = 0, head = 1, tail = 0, }, helpers.buffer) end function helpers.buffer:push(v) if self.size < self.max then self.tail = (self.tail % self.max) + 1 self.data[self.tail] = v self.size = self.size + 1 else self.tail = (self.tail % self.max) + 1 self.data[self.tail] = v self.head = (self.head % self.max) + 1 end end function helpers.buffer:items() local pos = self.head local remaining = self.size local max = self.max local data = self.data local logical_i = 0 return function() if remaining <= 0 then return nil end logical_i = logical_i + 1 local v = data[pos] pos = (pos % max) + 1 remaining = remaining - 1 return logical_i, v end end helpers.table_contains = function(tbl, value_to_find) for _, value in pairs(tbl) do if value == value_to_find then return true end end return false end local menu = {} helpers.menu = menu local current_menu = nil menu.create = function(theme) local w = awful.popup({ widget = { { homogeneous = false, column_count = 1, spacing = 3, minimum_column_width = 10, minimum_row_height = 10, layout = wibox.layout.grid, id = "grid_id", }, widget = wibox.container.margin, margins = theme.margins or 0, }, ontop = true, visible = false, border_width = theme.border_width or 0, border_color = theme.border_color or beautiful.bg, bg = theme.bg or beautiful.bg, fg = theme.fg or beautiful.fg, shape = helpers.rrect(theme.radius or 0), }) w.add_widget = function(self, widget) self.widget:get_children_by_id("grid_id")[1]:add(widget) end function w:toggle(x, y) -- Close any other open menu first if current_menu and current_menu ~= self and current_menu.visible then current_menu.visible = false end self.screen = mouse.screen self.visible = not self.visible if self.visible then current_menu = self if x and y then -- Better positioning logic local screen_geo = self.screen.geometry -- Adjust Y if menu would go off screen if y + self.height > screen_geo.height then self.y = math.max(screen_geo.y, y - self.height) else self.y = y end -- Adjust X if menu would go off screen if x + self.width > screen_geo.width then self.x = math.max(screen_geo.x, x - self.width) else self.x = x end end else if current_menu == self then current_menu = nil end end end function w:hide() self.visible = false if current_menu == self then current_menu = nil end end return w end return helpers