Browse Source

removed duplicate widgets

master
Yessiest 1 year ago
parent
commit
785fe57f1f
  1. 310
      widgets/battery.lua
  2. 88
      widgets/clientbuttons.lua
  3. 72
      widgets/clientcontrols.lua
  4. 148
      widgets/clientvolume.lua
  5. 55
      widgets/launcher.lua
  6. 110
      widgets/notifications.lua
  7. 63
      widgets/rootbuttons.lua
  8. 33
      widgets/rootcontrols.lua
  9. 142
      widgets/soundclown.lua
  10. 91
      widgets/start/xdgmenu.lua
  11. 89
      widgets/startbutton.lua
  12. 136
      widgets/tasklist.lua
  13. 108
      widgets/volume.lua
  14. 146
      widgets/wallpapers.lua

310
widgets/battery.lua

@ -1,310 +0,0 @@
-- 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/>.
-- Generic battery widget with support for multiple power sources, backlights and backlight control
local awful = require("awful")
local beautiful = require("beautiful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local syscontrol = require("syscontrol")
local ask = require("asckey")
local function get_virtual_icon(data)
-- Get an icon from a cumulative total of battery percentages and current charging state
local count = 0
local cumulative = 0
local name = "battery-"
for _,v in pairs(data) do
if type(v) == "number" then
cumulative = cumulative + v
count = count + 1
end
end
local percentage = math.floor((cumulative/(count*100))*100)
if percentage < 15 then
name = name.."caution-"
elseif percentage < 30 then
name = name.."low-"
elseif percentage < 60 then
name = name.."good-"
else
name = name.."full-"
end
if data["charge"] then
name = name.."charging-"
end
return beautiful[name.."symbolic"],percentage
end
return function(args)
local style = awmtk2.create_style("battery",
awmtk2.generic.popup,args.style)
local templates = awmtk2.create_template_lib("battery",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
-- set up popup layout
local layout = wibox.widget({
layout = wibox.layout.fixed.vertical,
spacing = style.base.spacing
})
-- create popup
local popup = awful.popup(t.popup(layout))
local battery_widget
do -- create battery widget
local style = awmtk2.create_style("battery",
awmtk2.generic.status_widget,args.style)
local templates = awmtk2.create_template_lib("battery",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
battery_widget = wibox.widget(t.button({
t.icon({
image = beautiful["battery-missing-symbolic"],
resize = true,
id = "virtual_id"
}),
(args.percentage and {
markup = "0%",
id = "percentage_id",
widget = wibox.widget.textbox
}),
layout = wibox.layout.fixed.horizontal,
spacing = style.base.spacing
}))
-- make it possible to press the button and make it toggle the popup
battery_widget:connect_signal("button::press",style.button.onpress)
battery_widget:connect_signal("button::release",style.button.onrelease)
battery_widget:connect_signal("button::press",function(_,_,_,button)
if button == 1 then
popup.visible = (not popup.visible)
if popup.visible then
popup:move_next_to(mouse.current_widget_geometry)
end
end
end)
end
-- map widgets to their names to make it easier to update separate components
local widget_map = {}
-- also map current charge state of every device to get the icon for the tray
local percentage_map = {}
-- {{{ Power supply devices
local power_devices = syscontrol.power_supply.enumerate()
for _,device in pairs(power_devices) do
local data = syscontrol.power_supply.read_attribs(device)
if data.type == "Battery" then
widget_map[data.name] = wibox.widget(t.container({
t.article({
icon = get_virtual_icon({
data.capacity,
charge = data.charging
}),
icon_id = "battery_icon",
title = "Battery ("..data.model..")",
}),
t.textbox({
markup = ("Capacity: %d%%"):format(data.capacity),
id = "capacity_id"
}),
t.textbox({
markup = ("Quality: %.4f%%"):format(data.quality),
id = "quality_id",
}),
layout = wibox.layout.fixed.vertical
},{
bg = style.container.bg_highlight,
bgimage = style.container.bgimage_highlight
}))
layout:add(widget_map[data.name])
percentage_map[data.name] = data.capacity
elseif data.type == "Mains" then
widget_map[data.name] = wibox.widget(t.container({
t.article({
icon = beautiful["ac-adapter-symbolic"],
title = "Power supply",
}),
t.textbox({
markup = "Powered: "..tostring(data.online),
id = "online_id",
}),
layout = wibox.layout.fixed.vertical
},{
bg = style.container.bg_highlight,
bgimage = style.container.bgimage_highlight
}))
layout:add(widget_map[data.name])
percentage_map["charge"] = data.online
end
end
-- "Virtual" here means a battery that displays the state of a cumulative total of all attached batteries (as if there are any devices that even have more than 1 battery)
local function update_virtual_battery()
local icon = battery_widget:get_children_by_id("virtual_id")[1]
local percentage = battery_widget:get_children_by_id("percentage_id")[1]
local capacity
icon.image,capacity = get_virtual_icon(percentage_map)
if percentage then
percentage:set_markup(tostring(capacity).."%")
end
end
update_virtual_battery()
-- Update loop
local power_update = gears.timer({
timeout = args.power_polling or 2,
autostart = true,
callback = function()
for _,v in pairs(power_devices) do
local data,err = syscontrol.power_supply.read_attribs(v)
if data and data.type == "Mains" then
local w = widget_map[data.name]
local online = w:get_children_by_id("online_id")[1]
online:set_markup("Powered: "..tostring(data.online))
percentage_map["charge"] = data.online
elseif data and data.type == "Battery" then
local w = widget_map[data.name]
local icon = w:get_children_by_id("battery_icon")[1]
local capacity = w:get_children_by_id("capacity_id")[1]
local quality = w:get_children_by_id("quality_id")[1]
icon.image = get_virtual_icon({
data.capacity,
charge = data.charging
})
capacity:set_markup(("Capacity: %d%%"):format(data.capacity))
quality:set_markup(("Quality: %.4f%%"):format(data.quality))
percentage_map[data.name] = data.capacity
else
print(err)
end
update_virtual_battery()
end
end
})
-- }}}
-- {{{ Backlight
local backlight_devices = syscontrol.backlight.enumerate()
local default_backlight_device
for _,v in pairs(backlight_devices) do
local data = syscontrol.backlight.read_attribs(v)
if data then
widget_map[data.name] = wibox.widget(t.container({
{
t.article({
icon = beautiful["backlight-symbolic"],
title = "Backlight",
}),
(data.writable and t.center(
t.checkbox({
checked = false,
id = "checkbox",
forced_height = style.article.icon_size,
forced_width = style.article.icon_size
}),
{
width = style.checkbox.width,
height = style.checkbox.height
})
),
layout = wibox.layout.fixed.horizontal,
spacing = style.base.spacing
},
t.textbox({
markup = "Brightness: "..tostring(data.brightness),
id = "brightness_id"
}),
t.textbox({
markup = "Max brightness: "..tostring(data.max_brightness),
id = "max_brightness"
}),
(data.writable and t.slider({
minimum = data.max_brightness*0.05,
maximum = data.max_brightness,
value = tonumber(data.brightness),
id = "slider"
})),
layout = wibox.layout.fixed.vertical
},{
bg = style.container.bg_highlight,
bgimage = style.container.bgimage_highlight
}))
if data.writable then
local w = widget_map[data.name]
local slider = w:get_children_by_id("slider")[1]
slider:connect_signal("widget::redraw_needed",function(self)
local value = self.value
syscontrol.backlight.set_brightness(data,math.floor(value))
end)
slider.value = tonumber(data.brightness)
local checkbox = w:get_children_by_id("checkbox")[1]
checkbox:connect_signal("button::press",function()
if default_backlight_device then
local check2 = widget_map[default_backlight_device.name]
:get_children_by_id("checkbox")[1]
check2.checked = true
end
default_backlight_device = data
end)
end
layout:add(widget_map[data.name])
end
end
-- Update loop
local backlight_update = gears.timer({
timeout = args.backlight_polling or 2,
autostart = true,
callback = function()
for _,v in pairs(backlight_devices) do
local data,err = syscontrol.backlight.read_attribs(v)
if data then
local w = widget_map[data.name]
local online = w:get_children_by_id("brightness_id")[1]
online:set_markup("Brightness: "..tostring(data.brightness))
else
print(err)
end
end
end
})
-- Keybindings
root.keys(gears.table.join(
root.keys(),
ask.k(":battery.brightness_up",function()
if default_backlight_device then
local data = default_backlight_device
local s = widget_map[data.name]:get_children_by_id("slider")[1]
local value = s.value+(data.max_brightness*0.05)
if value > data.max_brightness then
value = data.max_brightness
end
syscontrol.backlight.set_brightness(data,math.floor(value))
s.value = math.floor(value)
end
end,{description="increase brightness", group = "widgets"}),
ask.k(":battery.brightness_down",function()
if default_backlight_device then
local data = default_backlight_device
local s = widget_map[data.name]:get_children_by_id("slider")[1]
local value = s.value-(data.max_brightness*0.05)
if value < data.max_brightness*0.05 then
value = data.max_brightness*0.05
end
syscontrol.backlight.set_brightness(data,math.floor(value))
s.value = math.floor(value)
end
end,{description="decrease brightness", group = "widgets"})
))
-- }}}
-- We don't need this widget if we don't have anything to show
local function count(t)
local count = 0
for k,v in pairs(t) do
count = count + 1
end
return count
end
if count(widget_map) == 0 then
backlight_update:stop()
power_update:stop()
return
end
return battery_widget
end

88
widgets/clientbuttons.lua

@ -1,88 +0,0 @@
-- 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/>.
-- Additional client controls, hidden for cleaner UI in the submenu.
local awmtk2 = require("awmtk2")
local wibox = require("wibox")
local beautiful = require("beautiful")
return function(args)
local style = awmtk2.create_style("client_buttons",
awmtk2.generic.button_list,args.style)
local templates = awmtk2.create_template_lib("client_buttons",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local floating_on = beautiful.titlebar_floating_button_normal_inactive
local floating_off = beautiful.titlebar_floating_button_normal_active
local ontop_on = beautiful.titlebar_ontop_button_normal_inactive
local ontop_off = beautiful.titlebar_ontop_button_normal_active
local sticky_on = beautiful.titlebar_sticky_button_normal_inactive
local sticky_off = beautiful.titlebar_sticky_button_normal_active
local floating = wibox.widget(t.button(t.icon({
image = (client.focus and client.focus.floating and floating_on) or floating_off,
id = "icon"
}),{
forced_height = style.button.forced_height,
forced_width = style.button.forced_width
}))
floating:connect_signal("button::press",style.button.onpress)
floating:connect_signal("button::release",style.button.onrelease)
floating:connect_signal("button::press",function(widget)
client.focus.floating = (not client.focus.floating)
widget:emit_signal("widget::update",widget)
end)
floating:connect_signal("widget::update",function(widget)
local icon = widget:get_children_by_id("icon")[1]
icon.image = (client.focus.floating and floating_on) or floating_off
end)
local ontop = wibox.widget(t.button(t.icon({
image = (client.focus and client.focus.ontop and ontop_on) or ontop_off,
id = "icon"
}),{
forced_height = style.button.forced_height,
forced_width = style.button.forced_width
}))
ontop:connect_signal("button::press",style.button.onpress)
ontop:connect_signal("button::release",style.button.onrelease)
ontop:connect_signal("button::press",function(widget)
client.focus.ontop = (not client.focus.ontop)
widget:emit_signal("widget::update",widget)
end)
ontop:connect_signal("widget::update",function(widget)
local icon = widget:get_children_by_id("icon")[1]
icon.image = (client.focus.ontop and ontop_on) or ontop_off
end)
local sticky = wibox.widget(t.button(t.icon({
image = (client.focus and client.focus.sticky and sticky_on) or sticky_off,
id = "icon"
}),{
forced_height = style.button.forced_height,
forced_width = style.button.forced_width
}))
sticky:connect_signal("button::press",style.button.onpress)
sticky:connect_signal("button::release",style.button.onrelease)
sticky:connect_signal("button::press",function(widget)
client.focus.sticky = (not client.focus.sticky)
widget:emit_signal("widget::update",widget)
end)
sticky:connect_signal("widget::update",function(widget)
local icon = widget:get_children_by_id("icon")[1]
icon.image = (client.focus.sticky and sticky_on) or sticky_off
end)
client.connect_signal("focus",function(c)
sticky:emit_signal("widget::update")
ontop:emit_signal("widget::update")
floating:emit_signal("widget::update")
end)
local widget = wibox.widget({
floating,
ontop,
sticky,
layout = wibox.layout.fixed.horizontal,
spacing = style.base.spacing
})
return widget
end

72
widgets/clientcontrols.lua

@ -1,72 +0,0 @@
-- 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/>.
-- Basic client control menu
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")
return function(args)
local style = awmtk2.create_style("client_controls",
awmtk2.generic.menu,args.style)
local templates = awmtk2.create_template_lib("client_controls",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local move_to_tag = {}
local add_to_tag = {}
awful.screen.connect_for_each_screen(function(s)
table.insert(move_to_tag,{
"Screen "..s.index,
(function()
local t = {}
for k,v in pairs(s.tags) do
table.insert(t,{v.name,function()
if client.focus then
client.focus:tags({v})
end
end})
end
return t
end)()
})
table.insert(add_to_tag,{
"Screen "..s.index,
(function()
local t = {}
for k,v in pairs(s.tags) do
table.insert(t,{v.name,function()
if client.focus then
local tags = client.focus:tags()
for k,tag in pairs(tags) do
if v == tag then
table.remove(tags,k)
client.focus:tags(tags)
return
end
end
table.insert(tags,v)
client.focus:tags(tags)
end
end})
end
return t
end)()
})
end)
local widget = menugen({
items = {
{ "Kill client", function() client.focus:kill() end },
{ "Raise client", function() client.focus:raise() end},
{ "Lower client", function() client.focus:lower() end},
{ "Move to tag", move_to_tag },
{ "Switch on tag", add_to_tag }
},
})
return widget
end

148
widgets/clientvolume.lua

@ -1,148 +0,0 @@
-- 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/>.
-- Pulseaudio per-client volume setting
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local fastyaml = require("parsers").fast_split_yaml
local beautiful = require("beautiful")
local ask = require("asckey")
local test_pactl = os.execute("pactl --version")
local result = test_pactl
if _VERSION:match("5.1") then
result = (test_pactl == 0)
end
if not result then
return
end
local function get_icon(percent)
if percent >= 66 then
return beautiful["volume-high-symbolic"]
elseif percent >= 33 then
return beautiful["volume-medium-symbolic"]
elseif percent > 0 then
return beautiful["volume-low-symbolic"]
else
return beautiful["volume-muted-symbolic"]
end
end
return function(args)
local style = awmtk2.create_style("client_volume",
awmtk2.generic.oneline_widget, args.style)
local templates = awmtk2.create_template_lib("client_volume",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local widget = wibox.widget(t.container({
t.icon({
id = "client_volume_icon",
resize = true,
}),
t.textbox({
id = "error"
}),
t.slider({
minimum = 0,
maximum = 100,
id = "client_volume",
value = -1
}),
layout = wibox.layout.fixed.horizontal
}))
local errorbox = widget:get_children_by_id("error")[1]
local icon = widget:get_children_by_id("client_volume_icon")[1]
local slider = widget:get_children_by_id("client_volume")[1]
-- Local tracking value to prevent zero volume on start
local touched = false
-- Attach to focus change
client.connect_signal("update_volume",function(c)
awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
local pactl_data = fastyaml(stdout)
local cl
for _,v in pairs(pactl_data) do
if not c then return end
if v:match("application.process.id = \""..tostring(c.pid).."\"") then
cl = v
end
end
if not cl then
slider.visible = false
errorbox.visible = true
errorbox:set_markup("No sound/Not available")
icon:set_image(beautiful["volume-muted-symbolic"])
return
end
local volume = tonumber(cl:match("Volume:[^\n]-(%d*)%%"))
slider.visible = true
errorbox.visible = false
icon:set_image(get_icon(volume))
slider.value = volume
touched = true
end)
end)
client.connect_signal("focus",function(c)
touched = false
c:emit_signal("update_volume")
end)
local update_timer = gears.timer({
timeout = 0.5,
autostart = true,
callback = function()
if client.focus then
client.focus:emit_signal("update_volume")
end
end
})
-- Async lock to prevent callback interference
local volume_lock = false
-- Function to set client volume
local function volume(value)
if volume_lock then return end
volume_lock = true
awful.spawn.easy_async("pactl list sink-inputs",function(stdout)
local pactl_data = fastyaml(stdout)
if not (client.focus and client.focus.pid) then
volume_lock = false
return
end
for _,v in pairs(pactl_data) do
if v:match("application.process.id = \""..tostring(client.focus.pid).."\"") then
local sink_id = v:match("^%s*Sink Input #(%d+)")
if sink_id then
print(sink_id, value)
awful.spawn("pactl set-sink-input-volume "..tostring(sink_id).." "..tostring(value).."%")
end
end
end
volume_lock = false
end)
end
-- Attach change to slider
slider:connect_signal("widget::redraw_needed",function()
if touched then
volume(slider.value)
update_timer:again()
end
end)
root.keys(gears.table.join(
root.keys(),
ask.k(":client.volume_up", function()
volume("+5")
end,{description = "increase client volume", group = "client"}),
ask.k(":client.volume_down", function()
volume("-5")
end,{description = "decrease client volume", group = "client"}),
ask.k(":client.volume_mute", function()
volume(0)
end,{description = "mute client", group = "client"})
))
return widget
end

55
widgets/launcher.lua

@ -1,55 +0,0 @@
-- 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/>.
-- Quick application launcher
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local awmtk2 = require("awmtk2")
local beautiful = require("beautiful")
local menubar_utils = require("menubar").utils
local function synchronous_ls(dir)
local filenames = {}
local handler = io.popen("ls -1 "..dir,"r")
handler:read("*a"):gsub("[^\n]+",function(filename)
table.insert(filenames,filename)
end)
return filenames
end
return function(args)
local style = awmtk2.create_style("launcher",
awmtk2.generic.button_list, args.style)
local templates = awmtk2.create_template_lib("launcher", awmtk2.templates, args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local w = wibox.widget({
layout = ((args.vertical and
wibox.layout.fixed.vertical) or
wibox.layout.fixed.horizontal
),
spacing = style.base.spacing
})
local path = args.path or root_path.."/links"
if gears.filesystem.dir_readable(path) then
local files = synchronous_ls(path)
for _,v in pairs(files) do
local data = menubar_utils.parse_desktop_file(path.."/"..v)
local new_widget = wibox.widget(t.button(t.icon({
image = menubar_utils.lookup_icon_uncached(data.Icon),
})))
local exec = data.Exec:gsub("%%%w","")
new_widget:connect_signal("button::press",style.button.onpress)
new_widget:connect_signal("button::release",style.button.onrelease)
new_widget:connect_signal("button::press",function()
awful.spawn(exec)
end)
w:add(new_widget)
end
end
return w
end

110
widgets/notifications.lua

@ -1,110 +0,0 @@
-- 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/>.
-- Notifications pager
local awful = require("awful")
local pager = require("pager")
local beautiful = require("beautiful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local naughty = require("naughty")
return function(args)
local style = awmtk2.create_style("notifications",
awmtk2.generic.popup,args.style)
local templates = awmtk2.create_template_lib("notifications",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local layout = wibox.widget({
layout = wibox.layout.fixed.vertical,
spacing = style.base.spacing
})
local pager = pager(layout,{},args.max_notifications or 8)
local test_xclip = os.execute("xclip -version")
local result = test_xclip
if _VERSION:match("5.1") then
result = (test_xclip == 0)
end
local count = 0
local popup = awful.popup(t.popup({
t.textbox({
markup = "Click to copy text"
}),
((not result) and t.textbox({
markup = "(xclip is not installed)"
})),
t.container(layout,{
bg = style.container.bg_highlight,
bgimage = style.container.bgimage_highlight
}),
t.textbox({
id = "page_id",
markup = "Page 0/0"
}),
layout = wibox.layout.fixed.vertical
},{
visible = false
}))
naughty.config.notify_callback = function(update_args)
count = count + 1
local w = wibox.widget(t.button(t.article({
icon = update_args.icon,
title = update_args.title or "(No title)",
description = update_args.text
}),{
forced_height = style.button.height,
forced_width = style.button.width
}))
local page_index = popup.widget:get_children_by_id("page_id")[1]
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(count/(args.max_notifications or 8))))
w:connect_signal("button::press",style.button.onpress)
w:connect_signal("button::release",style.button.onrelease)
w:connect_signal("button::press",function(self,x,y,button)
if button == 1 then
clip = io.open("/tmp/clip","w")
clip:write(update_args.text)
clip:close()
awful.spawn.with_shell("cat /tmp/clip | xclip -selection clipboard")
elseif button == 4 then
pager:prev()
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(count/(args.max_notifications or 8))))
elseif button == 5 then
pager:next()
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(count/(args.max_notifications or 8))))
end
end)
table.insert(pager.list,1,w)
pager:update()
return update_args
end
-- create popup button
local clip_widget
do
local style = awmtk2.create_style("notifications",
awmtk2.generic.iconified_widget,args.style)
local templates = awmtk2.create_template_lib("notifications",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
clip_widget = wibox.widget(t.button(t.icon({
image = beautiful["notifications-area-symbolic"],
resize = true,
})))
clip_widget:connect_signal("button::press",style.button.onpress)
clip_widget:connect_signal("button::release",style.button.onrelease)
clip_widget:connect_signal("button::press",function(self,x,y,button)
if button == 1 then
popup.visible = (not popup.visible)
if popup.visible then
popup:move_next_to(mouse.current_widget_geometry)
end
end
end)
end
return clip_widget
end

63
widgets/rootbuttons.lua

@ -1,63 +0,0 @@
-- 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/>.
-- Power/lock/suspend buttons for the global context menu
local awmtk2 = require("awmtk2")
local wibox = require("wibox")
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful")
return function(args)
local style = awmtk2.create_style("root_buttons",
awmtk2.generic.button_list,args.style)
local templates = awmtk2.create_template_lib("root_buttons",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local poweroff = wibox.widget(t.button(t.icon({
image = beautiful["action-poweroff-symbolic"],
}),{
forced_width = style.button.forced_width,
forced_height = style.button.forced_height
}))
poweroff:connect_signal("button::press",style.button.onpress)
poweroff:connect_signal("button::release",style.button.onrelease)
poweroff:connect_signal("button::press",function()
awful.spawn("systemctl poweroff") -- Works only with systemd
awful.spawn("loginctl poweroff") -- Works only with elogind
end)
local lock = wibox.widget(t.button(t.icon({
image = beautiful["action-lock-screen-symbolic"],
}),{
forced_width = style.button.forced_width,
forced_height = style.button.forced_height
}))
lock:connect_signal("button::press",style.button.onpress)
lock:connect_signal("button::release",style.button.onrelease)
lock:connect_signal("button::press",function()
awesome.emit_signal("lock_screen")
end)
local suspend = wibox.widget(t.button(t.icon({
image = beautiful["action-suspend-symbolic"],
}),{
forced_width = style.button.forced_width,
forced_height = style.button.forced_height
}))
suspend:connect_signal("button::press",style.button.onpress)
suspend:connect_signal("button::release",style.button.onrelease)
suspend:connect_signal("button::press",function()
awful.spawn("systemctl suspend")
awful.spawn("loginctl suspend")
end)
local widget = wibox.widget {
poweroff,
lock,
suspend,
layout = wibox.layout.fixed.horizontal,
spacing = style.base.spacing
}
return widget
end

33
widgets/rootcontrols.lua

@ -1,33 +0,0 @@
-- 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/>.
-- Simple global context menu controls
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")
return function(args)
local style = awmtk2.create_style("root_menu",
awmtk2.generic.menu,args.style)
local templates = awmtk2.create_template_lib("root_menu",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local widget = menugen({
items = {
{"Awesome", {
{"open config dir", "xdg-open "..root_path},
{"open docs", "xdg-open https://awesomewm.org/doc/api/"},
{"restart", function() awesome.restart() end},
{"quit", function() awesome.quit() end}
}, beautiful.awesome_icon},
{"open terminal", global.terminal},
},
})
return widget
end

142
widgets/soundclown.lua

@ -1,142 +0,0 @@
-- 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/>.
-- Widget for interacting with mpd
-- MPC IS REQUIRED
local awmtk2 = require("awmtk2")
local wibox = require("wibox")
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful")
local ask = require("asckey")
return function(args)
local style = awmtk2.create_style("soundclown",
awmtk2.generic.oneline_widget,args.style)
local templates = awmtk2.create_template_lib("soundclown",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local test = os.execute("mpc help")
if type(test) == "number" then
test = (test == 0)
end
if not test then
return
end
local widget = wibox.widget({
t.container({
{
t.textbox({
markup = "MPC Loading..",
id = "display"
}),
widget = wibox.container.scroll.horizontal,
step_function = wibox.container.scroll.step_functions
.linear_back_and_forth,
speed = 50,
},
widget = wibox.container.constraint,
height = style.base.height,
width = style.base.width,
strategy = "exact"
}),
((not args.hide_controls) and {
t.button(t.icon({
image = beautiful["mpc-previous-symbolic"],
}),{
id = "prev"
}),
t.button(t.icon({
image = beautiful["mpc-play-symbolic"],
id = "statusicon"
}),{
id = "play"
}),
t.button(t.icon({
image = beautiful["mpc-next-symbolic"],
}),{
id = "next"
}),
spacing = style.base.spacing,
layout = wibox.layout.fixed.horizontal
}),
spacing = style.base.spacing,
layout = wibox.layout.fixed.horizontal
})
local display = widget:get_children_by_id("display")[1]
local bprev = widget:get_children_by_id("prev")[1]
bprev:connect_signal("button::press",style.button.onpress)
bprev:connect_signal("button::release",style.button.onrelease)
local function prev()
awful.spawn("mpc cdprev")
end
bprev:connect_signal("button::press",prev)
local pause_state = true
local icon = widget:get_children_by_id("statusicon")[1]
local bplay = widget:get_children_by_id("play")[1]
bplay:connect_signal("button::press",style.button.onpress)
bplay:connect_signal("button::release",style.button.onrelease)
local function play()
pause_state = (not pause_state)
if pause_state == false then
icon.image = beautiful["mpc-pause-symbolic"]
awful.spawn("mpc pause")
else
icon.image = beautiful["mpc-play-symbolic"]
awful.spawn("mpc play")
end
end
bplay:connect_signal("button::press",play)
local bnext = widget:get_children_by_id("next")[1]
bnext:connect_signal("button::press",style.button.onpress)
bnext:connect_signal("button::release",style.button.onrelease)
local function nextb()
awful.spawn("mpc next")
end
bnext:connect_signal("button::press",nextb)
local update_ready = true
local function update_mpd_status()
awful.spawn.easy_async("mpc",function(out)
local status = ""
if not out:match("playing") then
if not out:match("paused") then
state = true
icon.image = beautiful["mpc-play-symbolic"]
display:set_markup(status)
update_ready = true
return
else
status = status.."[PAUSED] "
end
end
status = status..out:match("#%d*").." "..
out:match("[^\n]*").." "..
out:match("%d*:%d*/%d*:%d*%s*%(%d*%%%)")
display:set_markup(status)
update_ready = true
end)
end
update_mpd_status()
gears.timer {
timeout = args.polling_delay or 1,
autostart = true,
callback = function()
if not update_ready then return end
update_ready = false
update_mpd_status()
end
}
root.keys(gears.table.join(
root.keys(),
ask.k(":mpc.prev",prev,
{description = "switch to previous MPD track",group="widgets"}),
ask.k(":mpc.play",play,
{description = "play/pause MPD",group="widgets"}),
ask.k(":mpc.next",nextb,
{description = "switch to next MPD track",group="widgets"})
))
return widget
end

91
widgets/start/xdgmenu.lua

@ -1,91 +0,0 @@
-- 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
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)
local style = awmtk2.create_style("xdg_menu",
awmtk2.generic.menu,args.style)
local templates = awmtk2.create_template_lib("xdg_menu",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
-- 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,
spacing = style.base.spacing,
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
xdg_menu_root:add(menu)
end)
return widget
end

89
widgets/startbutton.lua

@ -1,89 +0,0 @@
-- 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/>.
-- Start button that summons the root menu or any other menu if needed
local awmtk2 = require("awmtk2")
local wibox = require("wibox")
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful")
local builder = require("builder")
return function(args)
local popup
do
local style = awmtk2.create_style("startbutton",
awmtk2.generic.popup,args.style)
local templates = awmtk2.create_template_lib("startbutton",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local config_file = io.open(root_path.."/themes/"..global.theme.."/config/startbutton.lua","r")
local config
if config_file then
config = config_file:read("*a")
config_file:close()
else
config = [[{"list": [{"widget": "widgets.base.popuptitle","options":{"vertical":true}},{"widget":"widgets.start.xdgmenu"}]}]]
end
popup = awful.popup(t.popup({
markup = "brainhurt 2",
widget = wibox.widget.textbox
}))
popup.widget = wibox.widget(t.popup(builder(
config,
{
style = style.base,
screen = mouse.screen,
passthrough = {
parent = popup
}
}
)).widget)
for _,layout in pairs(popup.widget:get_children_by_id("menu_root")) do
for _,button in pairs(layout.children) do
button:connect_signal("cascade::kill",function()
popup.visible = false
end)
end
end
popup:connect_signal("property::visible",function()
local roots = popup.widget:get_children_by_id("menu_root")
for k,v in pairs(roots) do
for _,w in ipairs(v.children) do
w:emit_signal("cascade::close")
end
end
end)
end
local style = awmtk2.create_style("startbutton",
awmtk2.generic.iconified_widget,args.style)
local templates = awmtk2.create_template_lib("startbutton",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local widget = wibox.widget(t.button(t.article({
icon = style.article.icon,
title = style.article.title or "Start"
})))
widget:connect_signal("button::press",style.button.onpress)
widget:connect_signal("button::release",style.button.onrelease)
widget:connect_signal("button::press",function()
popup.visible = (not popup.visible)
if popup.visible then
local _, corner = awful.placement.closest_corner(
mouse,
{parent = mouse.screen,pretend = true}
)
if corner then
(awful.placement[corner]+
awful.placement.no_offscreen+
awful.placement.no_overlap) (
popup,
{parent = mouse.screen}
)
end
end
end)
return widget
end

136
widgets/tasklist.lua

@ -1,136 +0,0 @@
-- 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/>.
-- awful.widget.tasklist but it can change geometry based on "vertical" property
local awful = require("awful")
local wibox = require("wibox")
local gears = require("gears")
local awmtk2 = require("awmtk2")
local tasklist_buttons = gears.table.join(
awful.button({}, 1, function(c)
if c == client.focus then
c.minimized = true
else
c:emit_signal(
"request::activate",
"tasklist",
{raise = true}
)
end
end),
awful.button({}, 4, function()
awful.client.focus.byidx(1)
end),
awful.button({}, 5, function()
awful.client.focus.byidx(-1)
end)
)
return function(args)
local style = awmtk2.create_style("tasklist",
awmtk2.generic.oneline_widget, args.style)
local templates = awmtk2.create_template_lib("tasklist", awmtk2.templates, args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local button = t.button({
{
{
id = "clienticon",
widget = awful.widget.clienticon
},
(not args.vertical) and t.textbox({
id = "text_role"
}),
layout = wibox.layout.fixed.horizontal,
spacing = style.button.spacing
},
widget = wibox.container.constraint,
strategy="exact",
width = style.button.width,
height = style.button.height,
id = "constraint_task"
},{
create_callback = function(self, c, index, objects)
self:get_children_by_id('clienticon')[1].client = c
-- If for some ungodly reason you enabled the behaviour of the original awesomewm, this script will just stop after setting the client icon.
if self.id == "background_role" then
return
end
local textbox = self:get_children_by_id("text_role")[1] or {}
-- Apparently the original system for changing bgimage is
-- 1) broken
-- 2) uses deprecated functions (nice code practices awesomewm)
-- Solution: write my own. I blame material design for all this.
-- (P.S: Not to bullshit you, check it yourself - replicatable
-- by adding theme.tasklist_bg_image_normal or
-- theme.tasklist_bg_image_focus in current beautiful theme.)
local onfocus = function()
self.bgimage = style.button.bgimage_focus
self.bg = style.button.bg_focus
self.shape = style.button.shape_focus
self.shape_border_width = style.button.shape_border_width_focus
self.shape_border_color = style.button.shape_border_color_focus
textbox.font = style.textbox.font_focus
end
local onunfocus = function()
self.bgimage = style.button.bgimage_normal
self.bg = style.button.bg_normal
self.shape = style.button.shape_normal
self.shape_border_width = style.button.shape_border_width_normal
self.shape_border_color = style.button.shape_border_color_normal
textbox.font = style.textbox.font_normal
end
local onurgent = function()
if not c.urgent then return end
self.bgimage = style.button.bgimage_urgent
self.bg = style.button.bg_urgent
self.shape = style.button.shape_urgent
self.shape_border_width = style.button.shape_border_width_urgent
self.shape_border_color = style.button.shape_border_color_urgent
textbox.font = style.textbox.font_urgent
end
local onminimize = function()
if not c.minimized then return end
self.bgimage = style.button.bgimage_minimize
self.bg = style.button.bg_minimize
self.shape = style.button.shape_minimize
self.shape_border_width = style.button.shape_border_width_minimize
self.shape_border_color = style.button.shape_border_color_minimize
textbox.font = style.textbox.font_minimize
end
c:connect_signal("focus",onfocus)
c:connect_signal("unfocus",onunfocus)
c:connect_signal("property::urgent",onurgent)
c:connect_signal("property::minimized",onminimize)
if client.focus == c then
onfocus()
else
onunfocus()
end
end,
-- Uncomment this only, and **ONLY** if you actually need it.
--id = "background_role"
})
return awful.widget.tasklist {
screen = args.screen,
filter = awful.widget.tasklist.filter.currenttags,
buttons = tasklist_buttons,
layout = {
-- basically we just map every property of this to beautiful.tasklist.base
spacing = style.base.spacing,
spacing_widget = style.base.spacing_widget,
-- Now THIS is shit racing
layout = (
(args.vertical and style.base.layout_vertical) or
style.base.layout_horizontal
) or (
(args.vertical and wibox.layout.fixed.vertical) or
wibox.layout.fixed.horizontal
)
},
widget_template = button
}
end

108
widgets/volume.lua

@ -1,108 +0,0 @@
-- 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/>.
-- Pulseaudio per-client volume setting
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local beautiful = require("beautiful")
local ask = require("asckey")
local test_pactl = os.execute("pactl --version")
local pactl_found = test_pactl
if _VERSION:match("5.1") then
pactl_found = (test_pactl == 0)
end
local test_amixer = os.execute("amixer --version")
local amixer_found = test_amixer
if _VERSION:match("5.1") then
amixer_found = (test_amixer == 0)
end
if (not (amixer_found or pactl_found)) then
return
end
local try_launch = [[which pavucontrol && pavucontrol || which pulsemixer && ]]..global.terminal..[[ -e pulsemixer || which alsamixer && ]]..global.terminal..[[ -e alsamixer ]]
local function get_icon(percent)
if percent >= 66 then
return beautiful["volume-high-symbolic"]
elseif percent >= 33 then
return beautiful["volume-medium-symbolic"]
elseif percent > 0 then
return beautiful["volume-low-symbolic"]
else
return beautiful["volume-muted-symbolic"]
end
end
return function(args)
local style = awmtk2.create_style("volume",
awmtk2.generic.oneline_widget, args.style)
local templates = awmtk2.create_template_lib("volume",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
local widget = wibox.widget({
t.button(t.icon({
image = get_icon(0),
id = "volume_icon",
resize = true,
})),
t.container({
t.slider({
minimum = 0,
maximum = 100,
id = "volume",
value = -1
}),
layout = (args.vertical and wibox.layout.fixed.vertical) or
wibox.layout.fixed.horizontal
},{
visible = false,
id = "slidercontainer"
}),
t.textbox({
markup = "nassal"
}),
layout = (args.veritcal and wibox.layout.fixed.vertical) or
wibox.layout.fixed.horizontal
})
local icon = widget:get_children_by_id("volume_icon")[1]
local slider = widget:get_children_by_id("volume")[1]
local container = widget:get_children_by_id("slidercontainer")[1]
-- Alsa master handle
args.device = args.device or "default"
gears.timer {
autostart = true,
timeout = 0.5,
call_now = true,
callback = function()
awful.spawn.easy_async_with_shell("amixer -D "..args.device.." sget Master",function(stdout)
local volume_percent = stdout:match("%[(%d+)%%%]")
volume_percent = tonumber(volume_percent)
if not volume_percent then
return
end
slider.value = volume_percent
icon.image = get_icon(volume_percent)
end)
end
}
slider:connect_signal("widget::redraw_needed",function()
awful.spawn("amixer -D "..args.device.." sset Master "..slider.value.."%")
icon.image = get_icon(slider.value)
end)
icon:connect_signal("button::press",function(self,lx,ly,button)
if button == 1 then
container.visible = not container.visible
end
if button == 2 then
awful.spawn.with_shell(args.mixer or try_launch)
end
end)
return widget
end

146
widgets/wallpapers.lua

@ -1,146 +0,0 @@
-- 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/>.
-- Wallpaper list widget
local awful = require("awful")
local pager = require("pager")
local beautiful = require("beautiful")
local gears = require("gears")
local wibox = require("wibox")
local awmtk2 = require("awmtk2")
local thumbnailer = require("thumbnail")
local function ls(path)
local ls_data = io.popen("find "..path.." -maxdepth 1 -type f \\( -name \\*.jpg -o -name \\*.png \\) -exec realpath {} \\;")
local output = {}
if ls_data then
ls_data:read("*a"):gsub("[^\n]+",function(capt)
table.insert(output,capt)
end)
ls_data:close()
return output
end
error("Failed to process directory "..path)
end
return function(args)
local style = awmtk2.create_style("wallpapers",
awmtk2.generic.popup,args.style)
local templates = awmtk2.create_template_lib("wallpapers",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
-- set wallpaper
local fhandler = io.open(root_path.."/wallpaper.txt","r")
if fhandler then
local wallpaper_path = fhandler:read("*a")
gears.wallpaper.maximized(wallpaper_path,args.screen)
else
-- try to set wallpaper from theme settings
if beautiful.wallpaper then
gears.wallpaper.maximized(beautiful.wallpaper,args.screen)
end
end
-- update wallpaper preference and set wallpaper
local function set_wallpaper(s)
local handler = io.open(root_path.."/wallpaper.txt","w")
handler:write(s)
handler:close()
gears.wallpaper.maximized(s,args.screen)
end
if not args.path then
args.path = os.getenv("HOME")..".local/share/wallpapers/"
end
args.path = args.path:gsub("$HOME",os.getenv("HOME"))
-- read wallpapers from wallpaper directory
local image_list = ls(args.path)
-- generate thumbnails to save memory
thumbnailer.generate(args.path,args.path.."/.thumbnails",60)
-- create a layout for wallpaper buttons
local layout = wibox.widget({
layout = wibox.layout.grid,
forced_num_cols = args.columns or 4,
homogenous = true,
expand = true,
orientation = "vertical",
spacing = style.base.spacing
})
-- create layout popup
local popup = awful.popup(t.popup({
t.container(layout,{
bg = style.container.bg_highlight,
bgimage = style.container.bgimage_highlight
}),
t.textbox({
markup = "Page 0/0",
id = "page_index"
}),
layout = wibox.layout.fixed.vertical
},{
visible = false
}))
local page_index = popup.widget:get_children_by_id("page_index")[1]
-- set up a pager for having multiple pages of wallpapers
local pager_size = ((args.rows and args.columns) and args.rows*args.columns) or 20
local pager = pager(layout,{},pager_size)
-- add wallpaper buttons
for _,v in pairs(image_list) do
local new_button = wibox.widget(t.button(t.icon({
image = args.path.."/.thumbnails/"..v:match("/[^/]*$"),
resize = true,
height = args.height or 60,
width = args.width or 100
})))
new_button:connect_signal("button::press",style.button.onpress)
new_button:connect_signal("button::release",style.button.onrelease)
new_button:connect_signal("button::press",function(self,x,y,button)
if button == 1 then
set_wallpaper(v)
elseif button == 4 then
pager:prev()
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(#image_list/pager_size)))
elseif button == 5 then
pager:next()
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(#image_list/pager_size)))
end
end)
table.insert(pager.list,new_button)
end
page_index:set_markup("Page "..tostring(pager.index+1).."/"..
tostring(math.ceil(#image_list/pager_size)))
-- update pager
pager:update()
-- make popup togglable
popup:connect_signal("button::press",function(self,x,y,button)
if button == 3 then
popup.visible = false
end
end)
-- create popup button
local clip_widget
do
local style = awmtk2.create_style("wallpapers",
awmtk2.generic.iconified_widget,args.style)
local templates = awmtk2.create_template_lib("wallpapers",awmtk2.templates,args.templates)
local t = awmtk2.build_templates(templates,style,args.vertical)
clip_widget = wibox.widget(t.button(t.icon({
image = beautiful.wallpapers_icon,
resize = true,
})))
clip_widget:connect_signal("button::press",style.button.onpress)
clip_widget:connect_signal("button::release",style.button.onrelease)
clip_widget:connect_signal("button::press",function(self,x,y,button)
if button == 1 then
popup.visible = (not popup.visible)
if popup.visible then
popup:move_next_to(mouse.current_widget_geometry)
end
end
end)
end
return clip_widget
end
Loading…
Cancel
Save