-- This file is part of Reno desktop. -- -- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -- -- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see . local awful = require("awful") local gears = require("gears") local awmtk2 = require("awmtk2") local wibox = require("wibox") local beautiful = require("beautiful") local pager_gen = require("pager") local asckey_context = require("asckey").context local icon = beautiful["applications-tab-symbolic"] local xdg_search = function(name,rlimit,sorting_method) local ranked_results = {} if sorting_method == "usage" then local filter = {} local keys = {} for k,v in pairs(xdg.apps) do if not v.count then v.count = 0 end if v.name:lower():find(name,nil,true) then if not filter[v.count] then table.insert(keys, v.count) filter[v.count] = {} end table.insert(filter[v.count],{k,v}) end end table.sort(keys,function(a,b) return a > b end) local count = 0 local exit = false for k = 1,rlimit do local i = keys[k] if not filter[i] then break end for _,v in pairs(filter[i]) do table.insert(ranked_results, v) count = count + 1 if count >= rlimit then exit = true break end end if exit == true then break end end elseif sorting_method == "recent" then local most_recent = 0 for k,v in pairs(xdg.apps) do if v.name:lower():find(name,nil,true) and v.atime and v.atime >= most_recent then most_recent = v.atime table.insert(ranked_results,1,{k,v}) end if #ranked_results > rlimit then table.remove(ranked_results,rlimit+1) end end end return ranked_results end return function(args) local style = awmtk2.create_style("applications_tab", awmtk2.generic.menu, args.style, args.vertical) local templates = awmtk2.create_template_lib("applications_tab", awmtk2.templates,args.templates) local t = awmtk2.build_templates(templates,style,args.vertical) args.rows = args.rows or 8 args.columns = args.columns or 6 local widget = wibox.widget({ { { t.center(t.container( t.container({ widget = wibox.widget.textbox, markup = "Search", id = "searchtext" },{ id = "searchbox", bg = style.container.bg_highlight, forced_width = 240 }) )), t.center( t.container({ t.button( t.textbox({ markup = "Most used" }),{ id = "usage" } ), t.button( t.textbox({ markup = "Recent" }),{ id = "recent" } ), layout = wibox.layout.flex.horizontal, spacing = style.base.spacing, forced_width = 240 },{ bg = "#00000000" }) ), layout = wibox.layout.fixed.vertical, spacing = style.base.spacing, }, { { layout = wibox.layout.grid, forced_num_cols = args.columns, forced_num_rows = args.rows, homogenous = true, expand = true, vertical_expand = true, orientation = "veritcal", spacing = style.base.spacing, id = "appgrid" }, margins = 20, widget = wibox.container.margin }, { widget = wibox.container.background }, layout = wibox.layout.align.vertical, spacing = style.base.spacing, expand = "inside", id = "root_ratio" }, widget = wibox.container.margin, margins = 20 }) local sorting_method = "usage" local recent_sort = widget:get_children_by_id("recent")[1] local usage_sort = widget:get_children_by_id("usage")[1] local searchbox = widget:get_children_by_id("searchbox")[1] local searchtext = widget:get_children_by_id("searchtext")[1] usage_sort:connect_signal("button::press",function() recent_sort:set_bg(style.bg_normal) if style.button.onrelease then style.button.onrelease(recent_sort) end usage_sort:set_bg(style.bg_focus) if style.button.onpress then style.button.onpress(usage_sort) end sorting_method = "usage" end) recent_sort:connect_signal("button::press",function() usage_sort:set_bg(style.bg_normal) if style.button.onrelease then style.button.onrelease(usage_sort) end recent_sort:set_bg(style.bg_focus) if style.button.onpress then style.button.onpress(recent_sort) end sorting_method = "recent" end) local appgrid = widget:get_children_by_id("appgrid")[1] local pager = pager_gen(appgrid,{},args.rows*args.columns) local pager_context = asckey_context(gears.table.join( awful.key({},"Next",function() pager:next() end), awful.key({},"Prior",function() pager:prev() end), awful.key({},"Return",function() searchbox:emit_signal("button::press") end), awful.key({}," ",function() searchbox:emit_signal("button::press") end) )) supermenu:connect_signal("property::visible",function() if (not pager_context.active) and (supermenu.visible) then pager_context:activate() end if (pager_context.active) and (not supermenu.visible) then pager_context:deactivate() end end) local root = widget:get_children_by_id("root_ratio")[1] root:connect_signal("button::press",function(_,_,_,button) if button == 4 then pager:prev() elseif button == 5 then pager:next() end end) local icon_cache = gears.cache(function(icon,title,exec) local appicon = wibox.widget({ t.icon({ image = icon or beautiful.icon_default, }), { markup = title, widget = wibox.widget.textbox, align = "center" }, spacing = style.base.spacing, layout = wibox.layout.fixed.vertical }) appicon:connect_signal("button::press",function(_,_,_,button) if button == 1 then supermenu.visible = false awful.spawn(exec:gsub("%%%w","")) end end) return appicon end) local prompt_open = false supermenu:connect_signal("property::visible",function() if prompt_open then awful.keygrabber.stop() prompt_open = false end end) searchbox:connect_signal("button::press",function() if prompt_open then return end prompt_open = true awful.prompt.run { textbox = searchtext, exe_callback = function(command) local results = xdg_search(command, math.huge, sorting_method) pager.list = {} pager.index = 0 for _,v in pairs(results) do table.insert(pager.list,icon_cache:get( v[2].icon or beautiful.icon_default, v[2].name, v[2].exec )) end pager:update() end, done_callback = function() prompt_open = false searchtext:set_markup("Search") end } end) awesome.connect_signal("xdg::all_finished",function() for _,v in pairs(xdg.apps) do table.insert(pager.list,icon_cache:get(v.icon or beautiful.icon_default,v.name,v.exec)) end pager:update() end) return widget,icon end