supermenu

This commit is contained in:
Yessiest 2023-05-20 19:54:06 +04:00
parent b81cf9cbe1
commit 46df86a906
14 changed files with 297 additions and 34 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
/libs/pam.so /libs/pam.so
/doc /doc
/macros /macros
/macros/*

View File

@ -3,7 +3,7 @@
terminal = "st" terminal = "st"
browser = "librewolf" browser = "librewolf"
modkey = "Mod4" modkey = "Mod4"
theme = "unity_mate" theme = "unity"
shell = "zsh" shell = "zsh"
# Keybindings # Keybindings
@ -37,6 +37,8 @@ modkey+y = ":client.toggle_titlebars"
modkey+r = ":dismal.run" modkey+r = ":dismal.run"
modkey+s = ":help.show" modkey+s = ":help.show"
modkey+q = ":client.menu" modkey+q = ":client.menu"
modkey+x = ":supermenu.open"
Control+XF86AudioRaiseVolume = ":client.volume_up" Control+XF86AudioRaiseVolume = ":client.volume_up"
Control+XF86AudioLowerVolume = ":client.volume_down" Control+XF86AudioLowerVolume = ":client.volume_down"
Control+XF86AudioMute = ":client.volume_mute" Control+XF86AudioMute = ":client.volume_mute"

View File

@ -1,6 +1,9 @@
backend = "xrender"; backend = "glx";
vsync = true; vsync = true;
# Shadow # Shadow
blur-method = "dual_kawase";
blur-strength = 5;
blur-size = 7;
shadow = true; # Enabled client-side shadows on windows. shadow = true; # Enabled client-side shadows on windows.
shadow-radius = 12; # The blur radius for shadows. (default 12) shadow-radius = 12; # The blur radius for shadows. (default 12)
shadow-offset-x = -7; # The left offset for shadows. (default -15) shadow-offset-x = -7; # The left offset for shadows. (default -15)

View File

@ -130,7 +130,7 @@ theme.hotkeys_border_width = 3
theme.hotkeys_border_color = theme.bg_focus theme.hotkeys_border_color = theme.bg_focus
theme.hotkeys_modifiers_fg = theme.fg_normal theme.hotkeys_modifiers_fg = theme.fg_normal
theme.hotkeys_label_fg = theme.fg_normal theme.hotkeys_label_fg = theme.fg_normal
theme_assets.recolor_layout(theme,theme.fg_normal)
theme.bgimage_outset = function(context, cr, width, height,...) theme.bgimage_outset = function(context, cr, width, height,...)
local light = gears.color(theme.bg_highlight_light) local light = gears.color(theme.bg_highlight_light)
local shadow = gears.color(theme.bg_highlight_shadow) local shadow = gears.color(theme.bg_highlight_shadow)
@ -399,6 +399,16 @@ theme.widgets = {
bgimage_normal = theme.bgimage_outset, bgimage_normal = theme.bgimage_outset,
stretch = true stretch = true
}, },
checkbox = {
width = 15,
height = 15,
shape = gears.shape.circle,
border_width = 2,
border_color = theme.bg_normal,
bg = theme.bg_highlight,
check_color = "#000000",
paddings = 2
},
slider = { slider = {
shape = function(cr,width,height) shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0) return gears.shape.rounded_rect(cr,width,height,0)

View File

@ -124,7 +124,7 @@ theme.layout_cornernw = themes_path.."serenity/layouts/cornernww.png"
theme.layout_cornerne = themes_path.."serenity/layouts/cornernew.png" theme.layout_cornerne = themes_path.."serenity/layouts/cornernew.png"
theme.layout_cornersw = themes_path.."serenity/layouts/cornersww.png" theme.layout_cornersw = themes_path.."serenity/layouts/cornersww.png"
theme.layout_cornerse = themes_path.."serenity/layouts/cornersew.png" theme.layout_cornerse = themes_path.."serenity/layouts/cornersew.png"
theme_assets.recolor_layout(theme,theme.fg_normal)
-- Generate Awesome icon: -- Generate Awesome icon:
theme.awesome_icon = theme_assets.awesome_icon( theme.awesome_icon = theme_assets.awesome_icon(
theme.menu_height, theme.bg_focus, theme.fg_focus theme.menu_height, theme.bg_focus, theme.fg_focus
@ -500,6 +500,16 @@ theme.widgets = {
bgimage_normal = theme.bgimage_outset, bgimage_normal = theme.bgimage_outset,
stretch = true stretch = true
}, },
checkbox = {
width = 15,
height = 15,
shape = gears.shape.circle,
border_width = 2,
border_color = theme.bg_normal,
bg = theme.bg_highlight,
check_color = "#000000",
paddings = 2
},
slider = { slider = {
shape = function(cr,width,height) shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0) return gears.shape.rounded_rect(cr,width,height,0)

View File

@ -5,5 +5,6 @@
}, },
"widgets.rootmenu":{}, "widgets.rootmenu":{},
"widgets.lockscreen":{}, "widgets.lockscreen":{},
"widgets.base.keypopup":{} "widgets.base.keypopup":{},
"widgets.supermenu":{}
} }

View File

@ -0,0 +1,3 @@
{
"widgets.supermenu.applications-tab":{}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

View File

@ -242,7 +242,7 @@ theme["volume-high-symbolic"] = themes_path.."unity/icons/volume-high-symbolic.p
theme["volume-medium-symbolic"] = themes_path.."unity/icons/volume-medium-symbolic.png" theme["volume-medium-symbolic"] = themes_path.."unity/icons/volume-medium-symbolic.png"
theme["volume-low-symbolic"] = themes_path.."unity/icons/volume-low-symbolic.png" theme["volume-low-symbolic"] = themes_path.."unity/icons/volume-low-symbolic.png"
theme["volume-muted-symbolic"] = themes_path.."unity/icons/volume-muted-symbolic.png" theme["volume-muted-symbolic"] = themes_path.."unity/icons/volume-muted-symbolic.png"
theme["applications-tab-symbolic"] = themes_path.."unity/icons/applications-tab-symbolic.png"
theme.wallpaper = themes_path.."unity/background.png" theme.wallpaper = themes_path.."unity/background.png"
theme.wallpapers_icon = themes_path.."unity/icons/wallpapers.png" theme.wallpapers_icon = themes_path.."unity/icons/wallpapers.png"
@ -251,6 +251,7 @@ theme.wallpapers_icon = themes_path.."unity/icons/wallpapers.png"
theme.icon_default = themes_path.."unity/icons/unknown-app.png" theme.icon_default = themes_path.."unity/icons/unknown-app.png"
for _,v in pairs({ for _,v in pairs({
"applications-tab-symbolic",
"battery-caution-symbolic", "battery-caution-symbolic",
"battery-empty-symbolic", "battery-empty-symbolic",
"battery-full-symbolic", "battery-full-symbolic",
@ -284,6 +285,7 @@ for _,v in pairs({
theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal) theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal)
end end
end end
theme_assets.recolor_layout(theme,theme.fg_normal)
-- Notification popups settings -- Notification popups settings
theme.notification_width = 240 theme.notification_width = 240
theme.notification_height = 60 theme.notification_height = 60
@ -355,9 +357,9 @@ theme.widgets = {
width = 15, width = 15,
height = 15, height = 15,
shape = gears.shape.circle, shape = gears.shape.circle,
border_width = 3, border_width = 1,
border_color = theme.bg_normal, border_color = theme.bg_normal,
paddings = {2,2,2,2} paddings = 2
}, },
icon = { icon = {
width = 25, width = 25,
@ -624,6 +626,28 @@ theme.widgets = {
font = "Ubuntu Mono 20" font = "Ubuntu Mono 20"
} }
}, },
supermenu = {
popup = {
shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0)
end,
root_shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0)
end,
margins = 0,
transparent = true
},
icon = {
height = 48,
width = 48
}
},
applications_tab = {
icon = {
height = 48,
width = 48
}
},
titlebar = { titlebar = {
titlebar_top = { titlebar_top = {
onfocus = function(titlebar) onfocus = function(titlebar)

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

View File

@ -242,7 +242,7 @@ theme["volume-high-symbolic"] = themes_path.."unity_mate/icons/volume-high-symbo
theme["volume-medium-symbolic"] = themes_path.."unity_mate/icons/volume-medium-symbolic.png" theme["volume-medium-symbolic"] = themes_path.."unity_mate/icons/volume-medium-symbolic.png"
theme["volume-low-symbolic"] = themes_path.."unity_mate/icons/volume-low-symbolic.png" theme["volume-low-symbolic"] = themes_path.."unity_mate/icons/volume-low-symbolic.png"
theme["volume-muted-symbolic"] = themes_path.."unity_mate/icons/volume-muted-symbolic.png" theme["volume-muted-symbolic"] = themes_path.."unity_mate/icons/volume-muted-symbolic.png"
theme["applications-tab-symbolic"] = themes_path.."unity_mate/icons/applications-tab-symbolic.png"
theme.wallpaper = themes_path.."unity_mate/background.png" theme.wallpaper = themes_path.."unity_mate/background.png"
theme.wallpapers_icon = themes_path.."unity_mate/icons/wallpapers.png" theme.wallpapers_icon = themes_path.."unity_mate/icons/wallpapers.png"
@ -251,6 +251,7 @@ theme.wallpapers_icon = themes_path.."unity_mate/icons/wallpapers.png"
theme.icon_default = themes_path.."unity_mate/icons/unknown-app.png" theme.icon_default = themes_path.."unity_mate/icons/unknown-app.png"
for _,v in pairs({ for _,v in pairs({
"applications-tab-symbolic",
"battery-caution-symbolic", "battery-caution-symbolic",
"battery-empty-symbolic", "battery-empty-symbolic",
"battery-full-symbolic", "battery-full-symbolic",
@ -284,6 +285,8 @@ for _,v in pairs({
theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal) theme[v] = gears.color.recolor_image(theme[v],theme.fg_normal)
end end
end end
theme_assets.recolor_layout(theme,theme.fg_normal)
-- Notification popups settings -- Notification popups settings
theme.notification_width = 240 theme.notification_width = 240
theme.notification_height = 60 theme.notification_height = 60
@ -313,7 +316,7 @@ theme.widgets = {
end, end,
root_shape = function(cr,width,height) root_shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,6) return gears.shape.rounded_rect(cr,width,height,6)
end, end
}, },
titlebar = { titlebar = {
hidden_size = 2, hidden_size = 2,
@ -355,9 +358,9 @@ theme.widgets = {
width = 15, width = 15,
height = 15, height = 15,
shape = gears.shape.circle, shape = gears.shape.circle,
border_width = 3, border_width = 1,
border_color = theme.bg_normal, border_color = theme.bg_normal,
paddings = {2,2,2,2} paddings = 2
}, },
icon = { icon = {
width = 25, width = 25,
@ -624,6 +627,31 @@ theme.widgets = {
font = "Ubuntu Mono 20" font = "Ubuntu Mono 20"
} }
}, },
supermenu = {
popup = {
shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0)
end,
root_shape = function(cr,width,height)
return gears.shape.rounded_rect(cr,width,height,0)
end,
margins = 0,
-- WARNING: Change this to true only if you're wiliing to take
-- the visual performance impact from cairo re-rendering the
-- canvas a lot!
transparent = true
},
icon = {
height = 48,
width = 48
}
},
applications_tab = {
icon = {
height = 48,
width = 48
}
},
titlebar = { titlebar = {
titlebar_top = { titlebar_top = {
onfocus = function(titlebar) onfocus = function(titlebar)

View File

@ -244,9 +244,10 @@ return function(args)
if default_backlight_device then if default_backlight_device then
local check2 = widget_map[default_backlight_device.name] local check2 = widget_map[default_backlight_device.name]
:get_children_by_id("checkbox")[1] :get_children_by_id("checkbox")[1]
check2.checked = true check2.checked = false
end end
default_backlight_device = data default_backlight_device = data
checkbox.checked = true
end) end)
end end
layout:add(widget_map[data.name]) layout:add(widget_map[data.name])

View File

@ -12,6 +12,7 @@ local beautiful = require("beautiful")
local wibox = require("wibox") local wibox = require("wibox")
local json = require("dkjson") local json = require("dkjson")
local try_blur = require("imagemagick_blur") local try_blur = require("imagemagick_blur")
local ask = require("asckey")
local bgimagegen = function(path) local bgimagegen = function(path)
return function(cont,cr,width,height) return function(cont,cr,width,height)
@ -67,24 +68,33 @@ local function _preload(args)
layout = wibox.layout.align.horizontal layout = wibox.layout.align.horizontal
}, },
widget = wibox.container.background, widget = wibox.container.background,
forced_width = args.screen.workarea.width-style.container.margins, forced_width = args.screen.workarea.width-style.popup.margins,
forced_height = args.screen.workarea.height-style.container.margins, forced_height = args.screen.workarea.height-style.popup.margins,
id = "supermenu_root" id = "supermenu_root"
},{ },{
x = args.screen.workarea.x, x = args.screen.workarea.x,
y = args.screen.workarea.y, y = args.screen.workarea.y,
visible = true visible = false
})) }))
local supermenu_root = supermenu.widget:get_children_by_id("supermenu_root")[1] local supermenu_root = supermenu.widget:get_children_by_id("supermenu_root")[1]
if style.popup.transparent then
if not awesome.composite_manager_running then
-- Really slow but the effect is ok
supermenu_root.bgimage = bgimagegen(try_blur(wallpaper or beautiful.wallpaper, supermenu_root.bgimage = bgimagegen(try_blur(wallpaper or beautiful.wallpaper,
function(path) function(path)
supermenu_root.bgimage = bgimagegen(path) supermenu_root.bgimage = bgimagegen(path)
end)) end))
else
-- Let the compositor handle transparency
supermenu_root.bg = style.popup.bg_normal.."33"
supermenu.widget.bg = "#00000000"
end
end
args.screen:connect_signal("property::workarea",function() args.screen:connect_signal("property::workarea",function()
supermenu.x = args.screen.workarea.x supermenu.x = args.screen.workarea.x
supermenu.y = args.screen.workarea.y supermenu.y = args.screen.workarea.y
supermenu_root.forced_width = args.screen.workarea.width-style.container.margins*2 supermenu_root.forced_width = args.screen.workarea.width-style.popup.margins*2
supermenu_root.forced_height = args.screen.workarea.height-style.container.margins*2 supermenu_root.forced_height = args.screen.workarea.height-style.popup.margins*2
end) end)
supermenu:connect_signal("button::press",function(self,x,y,button) supermenu:connect_signal("button::press",function(self,x,y,button)
if button == 3 then if button == 3 then
@ -92,16 +102,46 @@ local function _preload(args)
end end
end) end)
local tabsfile = io.open(root_path.."/themes/"..global.theme..'/config/supermenu.json',"r") local tabsfile = io.open(root_path.."/themes/"..global.theme..'/config/supermenu.json',"r")
local contents = supermenu.widget:get_children_by_id("contents")[1]
local buttonlist = supermenu.widget:get_children_by_id("buttonlist")[1]
local tabs = {} local tabs = {}
local tab_icons = {}
local function gen_buttons(tab_id,icon)
local button = wibox.widget({
image = icon,
resize = true,
widget = wibox.widget.imagebox,
forced_width = style.icon.width,
forced_height = style.icon.height
})
button:connect_signal("button::press",function()
contents:set(1,tabs[tab_id])
end)
return button
end
if tabsfile then if tabsfile then
for k,v in pairs(json.decode(tabsfile:read("*a"))) do for k,v in pairs(json.decode(tabsfile:read("*a"))) do
table.insert(tabs,require(k)(v)) local widget,icon = require(k)(v)
print(widget,icon)
table.insert(tab_icons,icon or beautiful.icon_default)
table.insert(tabs,widget)
end end
end end
local contents = supermenu.widget:get_children_by_id("contents")[1]
if tabs[1] then if tabs[1] then
contents:add(tabs[1]) contents:add(tabs[1])
end end
for k,_ in pairs(tabs) do
buttonlist:add(gen_buttons(k,tab_icons[k]))
end
root.keys(gears.table.join(
root.keys(),
ask.k(":supermenu.open",function()
supermenu.visible = not supermenu.visible
end,{
description = "open supermenu",
group = "widgets"
})
))
return supermenu return supermenu
end end
return function(args) return function(args)

View File

@ -4,17 +4,75 @@ local awmtk2 = require("awmtk2")
local wibox = require("wibox") local wibox = require("wibox")
local beautiful = require("beautiful") local beautiful = require("beautiful")
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) return function(args)
local style = awmtk2.create_style("applications_tab", local style = awmtk2.create_style("applications_tab",
awmtk2.generic.menu, args.style, args.vertical) awmtk2.generic.menu, args.style, args.vertical)
local templates = awmtk2.create_template_lib("applications_tab", local templates = awmtk2.create_template_lib("applications_tab",
awmtk2.templates,args.templates) awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical) 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({ local widget = wibox.widget({
{ {
t.center(t.container(t.container({ t.center(t.container(
t.container({
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
markup = "Search area", markup = "Search",
id = "searchtext" id = "searchtext"
},{ },{
id = "searchbox", id = "searchbox",
@ -22,10 +80,33 @@ return function(args)
forced_width = 240 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.grid, layout = wibox.layout.grid,
forced_num_cols = args.columns or 4, forced_num_cols = args.columns,
homogenous = true, homogenous = true,
expand = true, expand = true,
orientation = "veritcal", orientation = "veritcal",
@ -42,14 +123,41 @@ return function(args)
widget = wibox.container.margin, widget = wibox.container.margin,
margins = 20 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 appgrid = widget:get_children_by_id("appgrid")[1]
local gen_icon = function(appdata) local icon_cache = gears.cache(function(icon,title,exec)
local appicon = wibox.widget({ local appicon = wibox.widget({
t.icon({ t.icon({
image = appdata.icon or beautiful.icon_default, image = icon or beautiful.icon_default,
}), }),
{ {
markup = appdata.title, markup = title,
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
align = "center" align = "center"
}, },
@ -58,12 +166,44 @@ return function(args)
}) })
appicon:connect_signal("button::press",function(_,_,_,button) appicon:connect_signal("button::press",function(_,_,_,button)
if button == 1 then if button == 1 then
awful.spawn(appdata.exec) supermenu.visible = false
awful.spawn(exec)
end end
end) end)
return appicon return appicon
end
awesome.connect_signal("xdg::all_finished",function()
end) end)
return widget 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()
prompt_open = true
awful.prompt.run {
textbox = searchtext,
exe_callback = function(command)
local results = xdg_search(command, args.rows*args.columns, sorting_method)
appgrid:reset()
for _,v in pairs(results) do
appgrid:add(icon_cache:get(
v[2].icon or beautiful.icon_default,
v[2].name,
v[2].exec
))
end
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
appgrid:add(icon_cache:get(v.icon or beautiful.icon_default,v.name,v.exec))
end
end)
return widget,icon
end end