removed duplicate widgets
This commit is contained in:
parent
c052387d77
commit
785fe57f1f
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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…
Reference in New Issue