summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkgs/astal/src/launcher.lua11
-rw-r--r--pkgs/astal/src/shell.lua12
-rw-r--r--pkgs/astal/src/widget/launcher.lua100
3 files changed, 80 insertions, 43 deletions
diff --git a/pkgs/astal/src/launcher.lua b/pkgs/astal/src/launcher.lua
index cc16bb9..88b88cb 100644
--- a/pkgs/astal/src/launcher.lua
+++ b/pkgs/astal/src/launcher.lua
@@ -1,10 +1,13 @@
local App = require("astal.gtk3.app")
+local lib = require("lib")
+
+local Launcher = require("widget.launcher")
App:start({
+ instance_name = "launcher",
+ css = lib.src("main.css"),
main = function()
- error("must start astal-shell first")
- end,
- client = function(req)
- req("launcher")
+ local mon = App.monitors[1]
+ Launcher(mon)
end,
})
diff --git a/pkgs/astal/src/shell.lua b/pkgs/astal/src/shell.lua
index 417f754..c370349 100644
--- a/pkgs/astal/src/shell.lua
+++ b/pkgs/astal/src/shell.lua
@@ -4,11 +4,9 @@ local lib = require("lib")
local Bar = require("widget.bar")
local Corners = require("widget.corners")
local Deck = require("widget.deck")
-local Launcher = require("widget.launcher")
-
-local launcher_visible
App:start({
+ instance_name = "shell",
css = lib.src("main.css"),
main = function()
for _, mon in pairs(App.monitors) do
@@ -16,13 +14,5 @@ App:start({
Corners(mon)
Deck(mon)
end
- launcher_visible = Launcher()
- end,
- request_handler = function(req, res)
- if req == "launcher" then
- launcher_visible:set(true)
- return res("opening launcher")
- end
- res("unknown command")
end,
})
diff --git a/pkgs/astal/src/widget/launcher.lua b/pkgs/astal/src/widget/launcher.lua
index 66fa4b0..3cd161c 100644
--- a/pkgs/astal/src/widget/launcher.lua
+++ b/pkgs/astal/src/widget/launcher.lua
@@ -8,22 +8,22 @@ local Apps = astal.require("AstalApps")
local Variable = astal.Variable
local lib = require("lib")
-local MAX_ENTRIES = 20
-local WIDTH = 7
+local WIDTH
+local MAX_ENTRIES
local FlowBox = astalify(Gtk.FlowBox)
local FlowBoxChild = astalify(Gtk.FlowBoxChild)
-local apps = Apps.Apps()
+local apps = Apps.Apps():exact_query("")
+local list = Variable(apps)
local text = Variable("")
-local visible = Variable(false)
-local selection = Variable(1)
+local selection = Variable(0)
local entry = Variable(nil)
-local list = text(function(text)
- return lib.slice(apps:exact_query(text), 0, MAX_ENTRIES)
-end)
+local function exit()
+ App:quit()
+end
local function on_show()
text:set("")
@@ -31,16 +31,10 @@ local function on_show()
entry:get():grab_focus()
end
-local function hide()
- visible:set(false)
-end
-
local function on_enter()
- local found = apps:exact_query(text:get())[selection:get() + 1]
- if found then
- found:launch()
- hide()
- end
+ local app = list:get()[selection:get() + 1]
+ app:launch()
+ exit()
end
local function update_pos(change_x, change_y)
@@ -48,7 +42,7 @@ local function update_pos(change_x, change_y)
local pos_x = (pos % WIDTH) + change_x
local pos_y = math.floor(pos / WIDTH) + change_y
- local count = lib.count(list:get())
+ local count = math.min(MAX_ENTRIES, lib.count(list:get()))
local height = math.floor((count + WIDTH - 1) / WIDTH)
pos_x = pos_x % WIDTH
@@ -59,7 +53,7 @@ end
local function on_key_press(_, event)
if event.keyval == Gdk.KEY_Escape then
- hide()
+ exit()
elseif event.keyval == Gdk.KEY_Return then
on_enter()
elseif event.keyval == Gdk.KEY_Left then
@@ -74,6 +68,11 @@ local function on_key_press(_, event)
end
function Application(app, idx)
+
+ if idx > MAX_ENTRIES then
+ return
+ end
+
return FlowBoxChild({
Widget.Button({
class_name = selection():as(function(c)
@@ -85,7 +84,7 @@ function Application(app, idx)
end),
on_clicked = function()
app:launch()
- hide()
+ exit()
end,
Widget.Box({
halign = "CENTER",
@@ -106,12 +105,12 @@ function Application(app, idx)
})
end
-function Applications(apps)
+function Applications(appl)
return FlowBox({
hexpand = true,
homogeneous = true,
class_name = "apps",
- lib.map(apps, Application)
+ lib.map(appl, Application)
})
end
@@ -133,25 +132,70 @@ function Launcher()
}),
Widget.Box({
class_name = "apps",
- list:as(Applications),
+ list():as(Applications),
}),
})
end
-return function()
+local function calc_bounds(gdkmonitor)
+ -- constants
+ local font_size = 14
+ local outer_gap = 12
+
+ -- get screen dimensions
+ local screen_width = gdkmonitor.geometry.width
+ local screen_height = gdkmonitor.geometry.height
+
+ -- calculate size of a cell
+ local cell_min_width = 15 * font_size
+ local cell_padding = outer_gap*4
+ local cell_size = cell_min_width + cell_padding
+
+ -- caculate usuable bounds
+ local used_width = 2*5*font_size
+ local used_height = 15*font_size
+ local free_width = screen_width - used_width
+ local free_height = screen_height - used_height
+
+ -- caculate counts
+ local width = math.floor(free_width / cell_size)
+ local height = math.floor(free_height / cell_size)
+
+ WIDTH = width
+ MAX_ENTRIES = width*height
+end
+
+return function(gdkmonitor)
local Anchor = astal.require('Astal').WindowAnchor
- Widget.Window({
+ calc_bounds(gdkmonitor)
+
+ -- enable search callback
+ text:subscribe(function(real_query)
+ local query = real_query:lower():match("^%s*(.-)%s*$")
+ if query == "" then
+ list:set(apps)
+ return
+ end
+ local new_list = {}
+ for _, app in pairs(apps) do
+ local name = app.name:lower()
+ if name:find(query) then
+ table.insert(new_list, app)
+ end
+ end
+ list:set(new_list)
+ end)
+
+ return Widget.Window({
class_name = "launcher",
+ gdkmonitor = gdkmonitor,
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,
- visible = visible(),
Launcher(),
})
-
- return visible
end