diff options
Diffstat (limited to '')
-rw-r--r-- | pkgs/astal/src/widget/launcher.lua | 100 |
1 files changed, 72 insertions, 28 deletions
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 |