Yessiest
1 year ago
14 changed files with 0 additions and 1591 deletions
-
310widgets/battery.lua
-
88widgets/clientbuttons.lua
-
72widgets/clientcontrols.lua
-
148widgets/clientvolume.lua
-
55widgets/launcher.lua
-
110widgets/notifications.lua
-
63widgets/rootbuttons.lua
-
33widgets/rootcontrols.lua
-
142widgets/soundclown.lua
-
91widgets/start/xdgmenu.lua
-
89widgets/startbutton.lua
-
136widgets/tasklist.lua
-
108widgets/volume.lua
-
146widgets/wallpapers.lua
@ -1,310 +0,0 @@ |
|||
-- This file is part of Reno desktop. |
|||
-- |
|||
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. |
|||
-- |
|||
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|||
-- |
|||
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>. |
|||
-- Generic battery widget with support for multiple power sources, backlights and backlight control |
|||
local awful = require("awful") |
|||
local beautiful = require("beautiful") |
|||
local gears = require("gears") |
|||
local wibox = require("wibox") |
|||
local awmtk2 = require("awmtk2") |
|||
local syscontrol = require("syscontrol") |
|||
local ask = require("asckey") |
|||
|
|||
local function get_virtual_icon(data) |
|||
-- Get an icon from a cumulative total of battery percentages and current charging state |
|||
local count = 0 |
|||
local cumulative = 0 |
|||
local name = "battery-" |
|||
for _,v in pairs(data) do |
|||
if type(v) == "number" then |
|||
cumulative = cumulative + v |
|||
count = count + 1 |
|||
end |
|||
end |
|||
local percentage = math.floor((cumulative/(count*100))*100) |
|||
if percentage < 15 then |
|||
name = name.."caution-" |
|||
elseif percentage < 30 then |
|||
name = name.."low-" |
|||
elseif percentage < 60 then |
|||
name = name.."good-" |
|||
else |
|||
name = name.."full-" |
|||
end |
|||
if data["charge"] then |
|||
name = name.."charging-" |
|||
end |
|||
return beautiful[name.."symbolic"],percentage |
|||
end |
|||
|
|||
return function(args) |
|||
local style = awmtk2.create_style("battery", |
|||
awmtk2.generic.popup,args.style) |
|||
local templates = awmtk2.create_template_lib("battery",awmtk2.templates,args.templates) |
|||
local t = awmtk2.build_templates(templates,style,args.vertical) |
|||
-- set up popup layout |
|||
local layout = wibox.widget({ |
|||
layout = wibox.layout.fixed.vertical, |
|||
spacing = style.base.spacing |
|||
}) |
|||
-- create popup |
|||
local popup = awful.popup(t.popup(layout)) |
|||
local battery_widget |
|||
do -- create battery widget |
|||
local style = awmtk2.create_style("battery", |
|||
awmtk2.generic.status_widget,args.style) |
|||
local templates = awmtk2.create_template_lib("battery",awmtk2.templates,args.templates) |
|||
local t = awmtk2.build_templates(templates,style,args.vertical) |
|||
battery_widget = wibox.widget(t.button({ |
|||
t.icon({ |
|||
image = beautiful["battery-missing-symbolic"], |
|||
resize = true, |
|||
id = "virtual_id" |
|||
}), |
|||
(args.percentage and { |
|||
markup = "0%", |
|||
id = "percentage_id", |
|||
widget = wibox.widget.textbox |
|||
}), |
|||
layout = wibox.layout.fixed.horizontal, |
|||
spacing = style.base.spacing |
|||
})) |
|||
-- make it possible to press the button and make it toggle the popup |
|||
battery_widget:connect_signal("button::press",style.button.onpress) |
|||
battery_widget:connect_signal("button::release",style.button.onrelease) |
|||
battery_widget:connect_signal("button::press",function(_,_,_,button) |
|||
if button == 1 then |
|||
popup.visible = (not popup.visible) |
|||
if popup.visible then |
|||
popup:move_next_to(mouse.current_widget_geometry) |
|||
end |
|||
end |
|||
end) |
|||
end |
|||
-- map widgets to their names to make it easier to update separate components |
|||
local widget_map = {} |
|||
-- also map current charge state of every device to get the icon for the tray |
|||
local percentage_map = {} |
|||
-- {{{ Power supply devices |
|||
local power_devices = syscontrol.power_supply.enumerate() |
|||
for _,device in pairs(power_devices) do |
|||
local data = syscontrol.power_supply.read_attribs(device) |
|||
if data.type == "Battery" then |
|||
widget_map[data.name] = wibox.widget(t.container({ |
|||
t.article({ |
|||
icon = get_virtual_icon({ |
|||
data.capacity, |
|||
charge = data.charging |
|||
}), |
|||
icon_id = "battery_icon", |
|||
title = "Battery ("..data.model..")", |
|||
}), |
|||
t.textbox({ |
|||
markup = ("Capacity: %d%%"):format(data.capacity), |
|||
id = "capacity_id" |
|||
}), |
|||
t.textbox({ |
|||
markup = ("Quality: %.4f%%"):format(data.quality), |
|||
id = "quality_id", |
|||
}), |
|||
layout = wibox.layout.fixed.vertical |
|||
},{ |
|||
bg = style.container.bg_highlight, |
|||
bgimage = style.container.bgimage_highlight |
|||
})) |
|||
layout:add(widget_map[data.name]) |
|||
percentage_map[data.name] = data.capacity |
|||
elseif data.type == "Mains" then |
|||
widget_map[data.name] = wibox.widget(t.container({ |
|||
t.article({ |
|||
icon = beautiful["ac-adapter-symbolic"], |
|||
title = "Power supply", |
|||
}), |
|||
t.textbox({ |
|||
markup = "Powered: "..tostring(data.online), |
|||
id = "online_id", |
|||
}), |
|||
layout = wibox.layout.fixed.vertical |
|||
},{ |
|||
bg = style.container.bg_highlight, |
|||
bgimage = style.container.bgimage_highlight |
|||
})) |
|||
layout:add(widget_map[data.name]) |
|||
percentage_map["charge"] = data.online |
|||
end |
|||
end |
|||
-- "Virtual" here means a battery that displays the state of a cumulative total of all attached batteries (as if there are any devices that even have more than 1 battery) |
|||
local function update_virtual_battery() |
|||
local icon = battery_widget:get_children_by_id("virtual_id")[1] |
|||
local percentage = battery_widget:get_children_by_id("percentage_id")[1] |
|||
local capacity |
|||
icon.image,capacity = get_virtual_icon(percentage_map) |
|||
if percentage then |
|||
percentage:set_markup(tostring(capacity).."%") |
|||
end |
|||
end |
|||
update_virtual_battery() |
|||
-- Update loop |
|||
local power_update = gears.timer({ |
|||
timeout = args.power_polling or 2, |
|||
autostart = true, |
|||
callback = function() |
|||
for _,v in pairs(power_devices) do |
|||
local data,err = syscontrol.power_supply.read_attribs(v) |
|||
if data and data.type == "Mains" then |
|||
local w = widget_map[data.name] |
|||
local online = w:get_children_by_id("online_id")[1] |
|||
online:set_markup("Powered: "..tostring(data.online)) |
|||
percentage_map["charge"] = data.online |
|||
elseif data and data.type == "Battery" then |
|||
local w = widget_map[data.name] |
|||
local icon = w:get_children_by_id("battery_icon")[1] |
|||
local capacity = w:get_children_by_id("capacity_id")[1] |
|||
local quality = w:get_children_by_id("quality_id")[1] |
|||
icon.image = get_virtual_icon({ |
|||
data.capacity, |
|||
charge = data.charging |
|||
}) |
|||
capacity:set_markup(("Capacity: %d%%"):format(data.capacity)) |
|||
quality:set_markup(("Quality: %.4f%%"):format(data.quality)) |
|||
percentage_map[data.name] = data.capacity |
|||
else |
|||
print(err) |
|||
end |
|||
update_virtual_battery() |
|||
end |
|||
end |
|||
}) |
|||
-- }}} |
|||
-- {{{ Backlight |
|||
local backlight_devices = syscontrol.backlight.enumerate() |
|||
local default_backlight_device |
|||
for _,v in pairs(backlight_devices) do |
|||
local data = syscontrol.backlight.read_attribs(v) |
|||
if data then |
|||
widget_map[data.name] = wibox.widget(t.container({ |
|||
{ |
|||
t.article({ |
|||
icon = beautiful["backlight-symbolic"], |
|||
title = "Backlight", |
|||
}), |
|||
(data.writable and t.center( |
|||
t.checkbox({ |
|||
checked = false, |
|||
id = "checkbox", |
|||
forced_height = style.article.icon_size, |
|||
forced_width = style.article.icon_size |
|||
}), |
|||
{ |
|||
width = style.checkbox.width, |
|||
height = style.checkbox.height |
|||
}) |
|||
), |
|||
layout = wibox.layout.fixed.horizontal, |
|||
spacing = style.base.spacing |
|||
}, |
|||
t.textbox({ |
|||
markup = "Brightness: "..tostring(data.brightness), |
|||
id = "brightness_id" |
|||
}), |
|||
t.textbox({ |
|||
markup = "Max brightness: "..tostring(data.max_brightness), |
|||
id = "max_brightness" |
|||
}), |
|||
(data.writable and t.slider({ |
|||
minimum = data.max_brightness*0.05, |
|||
maximum = data.max_brightness, |
|||
value = tonumber(data.brightness), |
|||
id = "slider" |
|||
})), |
|||
layout = wibox.layout.fixed.vertical |
|||
},{ |
|||
bg = style.container.bg_highlight, |
|||
bgimage = style.container.bgimage_highlight |
|||
})) |
|||
if data.writable then |
|||
local w = widget_map[data.name] |
|||
local slider = w:get_children_by_id("slider")[1] |
|||
slider:connect_signal("widget::redraw_needed",function(self) |
|||
local value = self.value |
|||
syscontrol.backlight.set_brightness(data,math.floor(value)) |
|||
end) |
|||
slider.value = tonumber(data.brightness) |
|||
local checkbox = w:get_children_by_id("checkbox")[1] |
|||
checkbox:connect_signal("button::press",function() |
|||
if default_backlight_device then |
|||
local check2 = widget_map[default_backlight_device.name] |
|||
:get_children_by_id("checkbox")[1] |
|||
check2.checked = true |
|||
end |
|||
default_backlight_device = data |
|||
end) |
|||
end |
|||
layout:add(widget_map[data.name]) |
|||
end |
|||
end |
|||
-- Update loop |
|||
local backlight_update = gears.timer({ |
|||
timeout = args.backlight_polling or 2, |
|||
autostart = true, |
|||
callback = function() |
|||
for _,v in pairs(backlight_devices) do |
|||
local data,err = syscontrol.backlight.read_attribs(v) |
|||
if data then |
|||
local w = widget_map[data.name] |
|||
local online = w:get_children_by_id("brightness_id")[1] |
|||
online:set_markup("Brightness: "..tostring(data.brightness)) |
|||
else |
|||
print(err) |
|||
end |
|||
end |
|||
end |
|||
}) |
|||
-- Keybindings |
|||
root.keys(gears.table.join( |
|||
root.keys(), |
|||
ask.k(":battery.brightness_up",function() |
|||
if default_backlight_device then |
|||
local data = default_backlight_device |
|||
local s = widget_map[data.name]:get_children_by_id("slider")[1] |
|||
local value = s.value+(data.max_brightness*0.05) |
|||
if value > data.max_brightness then |
|||
value = data.max_brightness |
|||
end |
|||
syscontrol.backlight.set_brightness(data,math.floor(value)) |
|||
s.value = math.floor(value) |
|||
end |
|||
end,{description="increase brightness", group = "widgets"}), |
|||
ask.k(":battery.brightness_down",function() |
|||
if default_backlight_device then |
|||
local data = default_backlight_device |
|||
local s = widget_map[data.name]:get_children_by_id("slider")[1] |
|||
local value = s.value-(data.max_brightness*0.05) |
|||
if value < data.max_brightness*0.05 then |
|||
value = data.max_brightness*0.05 |
|||
end |
|||
syscontrol.backlight.set_brightness(data,math.floor(value)) |
|||
s.value = math.floor(value) |
|||
end |
|||
end,{description="decrease brightness", group = "widgets"}) |
|||
)) |
|||
-- }}} |
|||
-- We don't need this widget if we don't have anything to show |
|||
local function count(t) |
|||
local count = 0 |
|||
for k,v in pairs(t) do |
|||
count = count + 1 |
|||
end |
|||
return count |
|||
end |
|||
if count(widget_map) == 0 then |
|||
backlight_update:stop() |
|||
power_update:stop() |
|||
return |
|||
end |
|||
return battery_widget |
|||
end |
@ -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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue