2022-08-31 12:20:58 +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/>.
-- XDG application menu for the global context menu
2022-08-25 15:27:31 +00:00
local awmtk2 = require ( " awmtk2 " )
local wibox = require ( " wibox " )
local gears = require ( " gears " )
local awful = require ( " awful " )
local beautiful = require ( " beautiful " )
local menugen = require ( " context_menu " )
local menuutils = require ( " menubar " ) . utils
return function ( args )
2022-09-05 21:54:11 +00:00
local style = awmtk2.create_style ( " xdg_menu " ,
awmtk2.generic . menu , args.style )
2022-08-25 15:27:31 +00:00
local templates = awmtk2.create_template_lib ( " xdg_menu " , awmtk2.templates , args.templates )
local t = awmtk2.build_templates ( templates , style )
-- Add a "loading" indicator while XDG is still parsing data
local widget = wibox.widget ( {
t.container ( {
markup = " Loading XDG menu... " ,
widget = wibox.widget . textbox
} ) ,
layout = wibox.layout . fixed.vertical ,
2022-08-31 12:20:58 +00:00
spacing = style.base . spacing ,
2022-08-25 15:27:31 +00:00
id = " xdg_menu_root "
} )
local function exclude ( name )
for k , v in pairs ( args.exclude or { } ) do
if name : match ( v ) then
return true
end
end
return false
end
awesome.connect_signal ( " xdg::all_finished " , function ( )
if not args.parent then return end
local items = { }
for k , v in pairs ( xdg.categories ) do
local noprocess = false
for k2 , v2 in pairs ( args.exclude_category or { } ) do
if k == v2 then
noprocess = true
end
end
if ( not noprocess ) and ( # v.apps > 0 ) then
local category = { k , { } , menuutils.lookup_icon_uncached ( v.icon ) }
for _ , item in pairs ( v.apps ) do
if not exclude ( item.name ) then
table.insert ( category [ 2 ] , {
item.name ,
item.exec : gsub ( " %%%w " , " " ) or " " ,
gears.filesystem . file_readable ( item.icon or " " ) and item.icon
} )
end
end
table.insert ( items , category )
end
end
-- uhhh there's a lot of things about async, some of which i can't explain
local xdg_menu_root = widget : get_children_by_id ( " xdg_menu_root " ) [ 1 ]
xdg_menu_root : reset ( )
local menu = wibox.widget ( menugen ( {
items = items ,
} ) )
local menu_root = menu : get_children_by_id ( " menu_root " ) [ 1 ]
for k , v in pairs ( menu_root.children ) do
v : connect_signal ( " cascade::kill " , function ( )
args.parent . visible = false
end )
args.parent : connect_signal ( " property::visible " , function ( )
if not args.parent . visible then
v : emit_signal ( " cascade::close " )
end
end )
menu : connect_signal ( " widget::redraw_needed " , function ( )
if not menu.visible then
v : emit_signal ( " cascade::close " )
end
end )
end
local appswitch = wibox.widget ( t.button ( t.textbox ( {
markup = " Applications " ,
id = " apptext "
2022-09-07 17:43:25 +00:00
} ) , {
forced_height = style.button . forced_height ,
forced_width = style.button . forced_width
} ) )
2022-08-25 15:27:31 +00:00
appswitch : connect_signal ( " button::press " , function ( self )
menu.visible = ( not menu.visible )
local textbox = appswitch : get_children_by_id ( " apptext " ) [ 1 ]
if menu.visible then
style.button . onpress ( self )
textbox : set_markup ( " <b>Applications</b> " )
else
style.button . onrelease ( self )
textbox : set_markup ( " Applications " )
end
end )
menu.visible = false
xdg_menu_root : add ( appswitch )
xdg_menu_root : add ( menu )
end )
return widget
end