diff --git a/default.svg b/default.svg
new file mode 100644
index 0000000..347cc93
--- /dev/null
+++ b/default.svg
@@ -0,0 +1,325 @@
+
+
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..cbcd8db
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,186 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local gears = require("gears")
+local beautiful = require("beautiful")
+local menubar = require("menubar")
+local naughty = require "naughty"
+local cairo = require("lgi").cairo
+local Rsvg = require("lgi").Rsvg
+local longpress = require("awesome-longpress")
+local launcherpopup = {
+ buttonsize = 128,
+ spacing = 5,
+ iconPath = gears.filesystem.get_configuration_dir() .. "/awesome-launcherpopup/",
+ updateOnSpawn = true,
+ font = "sans",
+ fontSize = 15,
+ applications = {},
+ allInstances = {}
+}
+
+function launcherpopup.update()
+ naughty.notify({text="started update"})
+ menubar.menu_gen.generate(function(rv)
+ launcherpopup.applications = rv
+ for k,v in pairs(launcherpopup.allInstances) do
+ if k and v then
+ w,e = pcall(v.populateMenu)
+ if not w then naughty.notify{text=e} end
+ end
+ end
+ end)
+end
+
+local function tryLoadIcon(icon)
+ local img = icon
+ if dentry.icon:match("%.([^%.]+)$") == "svg" then
+ naughty.notify{text="is svg"}
+ img = cairo.ImageSurface(cairo.Format.ARGB32,launcherpopup.buttonsize,launcherpopup.buttonsize)
+ local cr = cairo.Context(img)
+ Rsvg.Handle.new_from_file(dentry.icon):render_cairo(cr)
+ end
+ return img
+end
+
+local function getFont(scale)
+ return string.format("%s %d",launcherpopup.font,launcherpopup.fontSize * (scale or 1))
+end
+
+function launcherpopup.new(s)
+ local menuStart = 1
+ local launcherWidget = wibox.widget{
+ layout = wibox.layout.fixed.vertical,
+ spacing = launcherpopup.spacing
+ }
+ local launcher = awful.popup{
+ layout = wibox.layout.fixed.vertical,
+ widget = launcherWidget,
+ border_color = beautiful.border_focus,
+ border_width = 2,
+ ontop = true,
+ placement = awful.placement.centered,
+ visible = false,
+ screen = s,
+ }
+ local launcherButtons = wibox.widget{
+ layout = wibox.layout.grid.vertical,
+ spacing = launcherpopup.spacing
+ }
+ local launcherNav = wibox.widget{
+ layout = wibox.layout.ratio.horizontal,
+ forced_width = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2)) * (launcherpopup.buttonsize + launcherpopup.spacing)
+ }
+ local launcherList = wibox.widget{
+ layout = wibox.layout.grid,
+ spacing = launcherpopup.spacing
+ }
+ launcherWidget:add(launcherList)
+ launcherWidget:add(launcherNav)
+ local launcherNextPage = wibox.widget{
+ widget = wibox.widget.imagebox,
+ image = launcherpopup.iconPath .. "/next.svg",
+ forced_width=launcherpopup.buttonsize * 0.75,
+ forced_height=launcherpopup.buttonsize * 0.75
+ }
+ local launcherPreviousPage = wibox.widget{
+ widget = wibox.widget.imagebox,
+ image = launcherpopup.iconPath .. "/previous.svg",
+ forced_width=launcherpopup.buttonsize * 0.75,
+ forced_height=launcherpopup.buttonsize * 0.75
+ }
+ launcherNav:add(
+ wibox.container.place(launcherPreviousPage,"left","top"),
+ wibox.container.place(launcherNextPage,"right","top"))
+ local function fillMenu()
+ launcherList:reset()
+ local maxRows = math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2
+ local maxColumns = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2))
+ local maxEntries = maxRows * maxColumns
+ local x,y = 1,1
+ for y = 1, maxRows do
+ for x = 1, maxColumns do
+ local dentry = launcherpopup.applications[(menuStart - 1) + (y-1)*maxColumns + x]
+ if not dentry then dentry = {icon="",name=""} end
+ local mwidget = wibox.widget{
+ layout = wibox.layout.fixed.vertical
+ }
+ local mwicon = wibox.widget{
+ image = dentry.icon or launcherpopup.iconPath .. "/default.svg",
+ widget = wibox.widget.imagebox,
+ forced_width = launcherpopup.buttonsize,
+ forced_height = launcherpopup.buttonsize
+ }
+ mwidget:add(mwicon)
+ local mwtext = wibox.container.constraint(wibox.widget{
+ widget = wibox.widget.textbox,
+ valign = center,
+ align = center,
+ font = getFont(),
+ text = dentry.name
+ },"exact",launcherpopup.buttonsize,launcherpopup.buttonsize * 0.5)
+ mwidget:add(mwtext)
+ longpress.add(mwidget,function()
+ if dentry.cmdline then
+ awful.spawn(dentry.cmdline)
+ launcher:hide()
+ end
+ end)
+ launcherList:add_widget_at(wibox.container.constraint(mwidget,"max",launcherpopup.buttonsize,launcherpopup.buttonsize*1.5),y,x)
+ end
+ end
+ end
+ local function goToEntry(n)
+ local maxRows = math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2
+ local maxColumns = math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2))
+ local maxEntries = maxRows * maxColumns
+ menuStart = n
+ if menuStart < 1 then menuStart = (math.floor(#launcherpopup.applications / maxEntries) * maxEntries) + 1 end
+ if menuStart > #launcherpopup.applications then menuStart = 1 end
+ fillMenu()
+ end
+ longpress.add(launcherNextPage,function()
+ goToEntry(menuStart + ((math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2) * math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2))))
+ end,
+ function()
+ goToEntry(#launcherpopup.applications)
+ end)
+ longpress.add(launcherPreviousPage,function()
+ goToEntry(menuStart - ((math.floor(s.geometry.height / (launcherpopup.buttonsize * 1.5 + launcherpopup.spacing * 2)) - 2) * math.floor((s.geometry.width) / (launcherpopup.buttonsize + launcherpopup.spacing * 2))))
+ end,
+ function()
+ goToEntry(1)
+ end)
+ function launcher.populateMenu()
+ fillMenu()
+ end
+ function launcher.addButton(icon, fn)
+ local newButton = awful.widget.button{
+ image = launcherpopup.iconPath .. "/" .. icon
+ }
+ newButton:set_forced_width(launcherpopup.buttonsize)
+ newButton:set_forced_height(launcherpopup.buttonsize)
+ newButton:buttons(gears.table.join(
+ newButton:buttons(),
+ awful.button({}, 1, nil, function()
+ fn()
+ launcher:hide()
+ end)
+ ))
+ launcherButtons:add(newButton)
+ end
+
+ function launcher.show(self)
+ self.visible = true
+ end
+ function launcher.hide(self)
+ self.visible = false
+ end
+ function launcher.toggle(self)
+ self.visible = not self.visible
+ end
+ launcherpopup.allInstances[#launcherpopup.allInstances+1] = launcher
+ launcherpopup.update()
+ return launcher
+end
+
+return launcherpopup
diff --git a/next.svg b/next.svg
new file mode 100644
index 0000000..cfe6f2f
--- /dev/null
+++ b/next.svg
@@ -0,0 +1,151 @@
+
+
diff --git a/previous.svg b/previous.svg
new file mode 100644
index 0000000..e55cb62
--- /dev/null
+++ b/previous.svg
@@ -0,0 +1,151 @@
+
+