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