2023-05-27 14:57:46 +00:00
-- 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 <https://www.gnu.org/licenses/>.
2023-05-06 08:56:25 +00:00
local awful = require ( " awful " )
local gears = require ( " gears " )
local awmtk2 = require ( " awmtk2 " )
local wibox = require ( " wibox " )
local beautiful = require ( " beautiful " )
2023-05-21 10:33:49 +00:00
local pager_gen = require ( " pager " )
local asckey_context = require ( " asckey " ) . context
2023-05-06 08:56:25 +00:00
2023-05-20 15:54:06 +00:00
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
2023-05-06 08:56:25 +00:00
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 )
2023-05-20 15:54:06 +00:00
args.rows = args.rows or 8
args.columns = args.columns or 6
2023-05-06 08:56:25 +00:00
local widget = wibox.widget ( {
{
2023-05-20 16:31:42 +00:00
{
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 ,
} ,
2023-05-06 08:56:25 +00:00
{
{
layout = wibox.layout . grid ,
2023-05-20 15:54:06 +00:00
forced_num_cols = args.columns ,
2023-05-20 16:33:49 +00:00
forced_num_rows = args.rows ,
2023-05-06 08:56:25 +00:00
homogenous = true ,
expand = true ,
2023-05-20 16:31:42 +00:00
vertical_expand = true ,
2023-05-06 08:56:25 +00:00
orientation = " veritcal " ,
spacing = style.base . spacing ,
id = " appgrid "
} ,
margins = 20 ,
widget = wibox.container . margin
} ,
2023-05-20 16:31:42 +00:00
{
widget = wibox.container . background
} ,
layout = wibox.layout . align.vertical ,
2023-05-06 08:56:25 +00:00
spacing = style.base . spacing ,
2023-05-20 16:31:42 +00:00
expand = " inside " ,
2023-05-06 08:56:25 +00:00
id = " root_ratio "
} ,
widget = wibox.container . margin ,
margins = 20
} )
2023-05-20 15:54:06 +00:00
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 )
2023-05-06 08:56:25 +00:00
local appgrid = widget : get_children_by_id ( " appgrid " ) [ 1 ]
2023-05-21 10:33:49 +00:00
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 )
2023-05-20 15:54:06 +00:00
local icon_cache = gears.cache ( function ( icon , title , exec )
2023-05-06 08:56:25 +00:00
local appicon = wibox.widget ( {
t.icon ( {
2023-05-20 15:54:06 +00:00
image = icon or beautiful.icon_default ,
2023-05-06 08:56:25 +00:00
} ) ,
{
2023-05-20 15:54:06 +00:00
markup = title ,
2023-05-06 08:56:25 +00:00
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
2023-05-20 15:54:06 +00:00
supermenu.visible = false
2023-05-21 10:33:49 +00:00
awful.spawn ( exec : gsub ( " %%%w " , " " ) )
2023-05-06 08:56:25 +00:00
end
end )
return appicon
2023-05-20 15:54:06 +00:00
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 ( )
2023-05-21 10:33:49 +00:00
if prompt_open then return end
2023-05-20 15:54:06 +00:00
prompt_open = true
awful.prompt . run {
textbox = searchtext ,
exe_callback = function ( command )
2023-05-21 11:14:35 +00:00
local results = xdg_search ( command , math.huge , sorting_method )
2023-05-21 10:33:49 +00:00
pager.list = { }
2023-05-21 11:14:35 +00:00
pager.index = 0
2023-05-20 15:54:06 +00:00
for _ , v in pairs ( results ) do
2023-05-21 10:33:49 +00:00
table.insert ( pager.list , icon_cache : get (
2023-05-20 15:54:06 +00:00
v [ 2 ] . icon or beautiful.icon_default ,
v [ 2 ] . name ,
v [ 2 ] . exec
) )
end
2023-05-21 10:33:49 +00:00
pager : update ( )
2023-05-20 15:54:06 +00:00
end ,
done_callback = function ( )
prompt_open = false
searchtext : set_markup ( " Search " )
end
}
end )
2023-05-06 08:56:25 +00:00
awesome.connect_signal ( " xdg::all_finished " , function ( )
2023-05-20 15:54:06 +00:00
for _ , v in pairs ( xdg.apps ) do
2023-05-21 10:33:49 +00:00
table.insert ( pager.list , icon_cache : get ( v.icon or beautiful.icon_default , v.name , v.exec ) )
2023-05-20 15:54:06 +00:00
end
2023-05-21 11:10:00 +00:00
pager : update ( )
2023-05-06 08:56:25 +00:00
end )
2023-05-20 15:54:06 +00:00
return widget , icon
2023-05-06 08:56:25 +00:00
end