summaryrefslogtreecommitdiff
path: root/pkgs/astal/src/widget/launcher.lua
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/astal/src/widget/launcher.lua')
-rw-r--r--pkgs/astal/src/widget/launcher.lua113
1 files changed, 113 insertions, 0 deletions
diff --git a/pkgs/astal/src/widget/launcher.lua b/pkgs/astal/src/widget/launcher.lua
new file mode 100644
index 0000000..cbac6c3
--- /dev/null
+++ b/pkgs/astal/src/widget/launcher.lua
@@ -0,0 +1,113 @@
+local astal = require("astal")
+local Widget = require("astal.gtk3.widget")
+local App = require("astal.gtk3.app")
+local Gdk = require("astal.gtk3").Gdk
+local Gtk = require("astal.gtk3").Gtk
+local astalify = require("astal.gtk3").astalify
+local Apps = astal.require("AstalApps")
+local Variable = astal.Variable
+local lib = require("lib")
+
+local MAX_ENTRIES = 20
+
+local FlowBox = astalify(Gtk.FlowBox)
+local FlowBoxChild = astalify(Gtk.FlowBoxChild)
+
+local apps = Apps.Apps()
+local text = Variable("")
+local list = text(function(text)
+ return lib.slice(apps:exact_query(text), 0, MAX_ENTRIES)
+end)
+
+function on_show()
+ text:set("")
+end
+
+function close()
+ App:quit()
+end
+
+function on_key_press(self, event)
+ if event.keyval == Gdk.KEY_Escape then
+ close()
+ end
+end
+
+function on_enter()
+ local found = apps:exact_query(text:get())[1]
+ if found then
+ found:launch()
+ close()
+ end
+end
+
+function Application(app)
+ return FlowBoxChild({
+ Widget.Button({
+ class_name = "app",
+ on_clicked = function()
+ app:launch()
+ close()
+ end,
+ Widget.Box({
+ halign = "CENTER",
+ valign = "CENTER",
+ vertical = true,
+ Widget.Icon({
+ icon = app.icon_name,
+ }),
+ Widget.Label({
+ class_name = "name",
+ label = app.name,
+ valign = "CENTER",
+ ellipsize = "END",
+ max_width_chars = 20,
+ }),
+ }),
+ }),
+ })
+end
+
+function Applications(apps)
+ return FlowBox({
+ hexpand = true,
+ homogeneous = true,
+ class_name = "apps",
+ lib.map(apps, Application)
+ })
+end
+
+function Launcher()
+ return Widget.Box({
+ vertical = true,
+ Widget.Entry({
+ class_name = "search",
+ placeholder_text = "Search",
+ halign = "CENTER",
+ text = text(),
+ on_changed = function(self)
+ text:set(self.text)
+ end,
+ on_activate = on_enter,
+ }),
+ Widget.Box({
+ class_name = "apps",
+ list:as(Applications),
+ }),
+ })
+end
+
+return function()
+ local Anchor = astal.require('Astal').WindowAnchor
+
+ return Widget.Window({
+ class_name = "launcher",
+ anchor = Anchor.TOP + Anchor.BOTTOM + Anchor.LEFT + Anchor.RIGHT,
+ exclusivity = "EXCLUSIVE",
+ keymode = "ON_DEMAND",
+ application = App,
+ on_show = on_show,
+ on_key_press_event = on_key_press,
+ Launcher(),
+ })
+end