61 Commits
-
4.gitignore
-
4.ldoc.lua
-
31.luarc.json
-
36README.md
-
73Rakefile
-
111desktop.conf
-
9extra/README.md
-
13extra/install_luapam.sh
-
57extra/picom.conf
-
BINextra/screenshots/unity.png
-
113libs/asckey.lua
-
296libs/awmtk2.lua
-
53libs/builder.lua
-
43libs/context_menu.lua
-
37libs/digger.lua
-
18libs/imagemagick_blur.lua
-
3libs/pager.lua
-
215libs/parser_test.lua
-
161libs/parsers.lua
-
56libs/syscontrol.lua
-
16libs/utils.lua
-
137libs/xdg_data.lua
-
87modules/autostart.lua
-
5modules/base.lua
-
106modules/binds.lua
-
12modules/collect_garbage.lua
-
50modules/compositor.lua
-
207modules/desktop.lua
-
18modules/global.lua
-
163modules/macros.lua
-
75modules/powermanX.lua
-
34modules/rules_stub.lua
-
8modules/static_tags.lua
-
19modules/tiling.lua
-
105modules/xdg_data.lua
-
8rc.lua
-
12themes/reno98/COPYRIGHT
-
5themes/reno98/config/client_menu.json
-
7themes/reno98/config/global.json
-
16themes/reno98/config/root_menu.json
-
8themes/reno98/config/wibar_bottom.json
-
19themes/reno98/config/wibar_top.json
-
2themes/reno98/icons/README
-
BINthemes/reno98/icons/notifications-area-flagged-symbolic.png
-
BINthemes/reno98/icons/notifications-area-symbolic.png
-
BINthemes/reno98/icons/volume-high-symbolic.png
-
BINthemes/reno98/icons/volume-low-symbolic.png
-
BINthemes/reno98/icons/volume-medium-symbolic.png
-
BINthemes/reno98/icons/volume-muted-symbolic.png
-
BINthemes/reno98/icons/volume98.png
-
191themes/reno98/theme.lua
-
121themes/serenity/COPYING.txt
-
12themes/serenity/COPYRIGHT
-
8themes/serenity/config/client_menu.json
-
9themes/serenity/config/global.json
-
5themes/serenity/config/lockpanel.json
-
31themes/serenity/config/root_menu.json
-
44themes/serenity/config/titlebar_top.json
-
18themes/serenity/config/wibar_bottom.json
-
26themes/serenity/config/wibar_top.json
-
3themes/serenity/icons/README
-
BINthemes/serenity/icons/ac-adapter-symbolic.png
-
BINthemes/serenity/icons/action-lock-screen-symbolic.png
-
BINthemes/serenity/icons/action-poweroff-symbolic.png
-
BINthemes/serenity/icons/action-suspend-symbolic.png
-
BINthemes/serenity/icons/backlight-symbolic.png
-
BINthemes/serenity/icons/battery-caution-charging-symbolic.png
-
BINthemes/serenity/icons/battery-caution-symbolic.png
-
BINthemes/serenity/icons/battery-empty-charging-symbolic.png
-
BINthemes/serenity/icons/battery-empty-symbolic.png
-
BINthemes/serenity/icons/battery-full-charged-symbolic.png
-
BINthemes/serenity/icons/battery-full-charging-symbolic.png
-
BINthemes/serenity/icons/battery-full-symbolic.png
-
BINthemes/serenity/icons/battery-good-charging-symbolic.png
-
BINthemes/serenity/icons/battery-good-symbolic.png
-
BINthemes/serenity/icons/battery-low-charging-symbolic.png
-
BINthemes/serenity/icons/battery-low-symbolic.png
-
BINthemes/serenity/icons/battery-missing-symbolic.png
-
BINthemes/serenity/icons/battery.png
-
BINthemes/serenity/icons/mpc-next-symbolic.png
-
BINthemes/serenity/icons/mpc-pause-symbolic.png
-
BINthemes/serenity/icons/mpc-play-symbolic.png
-
BINthemes/serenity/icons/mpc-previous-symbolic.png
-
BINthemes/serenity/icons/notifications-area-flagged-symbolic.png
-
BINthemes/serenity/icons/notifications-area-symbolic.png
-
BINthemes/serenity/icons/reno98.png
-
BINthemes/serenity/icons/unknown-app.png
-
BINthemes/serenity/icons/volume-high-symbolic.png
-
BINthemes/serenity/icons/volume-low-symbolic.png
-
BINthemes/serenity/icons/volume-medium-symbolic.png
-
BINthemes/serenity/icons/volume-muted-symbolic.png
-
BINthemes/serenity/icons/volume98.png
-
BINthemes/serenity/icons/wallpapers.png
-
BINthemes/serenity/layouts/cornerne.png
-
BINthemes/serenity/layouts/cornernew.png
-
BINthemes/serenity/layouts/cornernw.png
-
BINthemes/serenity/layouts/cornernww.png
-
BINthemes/serenity/layouts/cornerse.png
-
BINthemes/serenity/layouts/cornersew.png
-
BINthemes/serenity/layouts/cornersw.png
@ -1,4 +1,8 @@ |
|||
/desktop.conf |
|||
/wallpaper.txt |
|||
/links |
|||
/libs/pam |
|||
/libs/pam.so |
|||
/doc |
|||
/macros |
|||
/macros/* |
@ -0,0 +1,4 @@ |
|||
file = {"libs","modules","widgets"} |
|||
format = "markdown" |
|||
title = "Reno Desktop documentation" |
|||
description = "Reno Desktop is an AwesomeWM config that harnesses the power of AwesomeWM to bring the essential functionality of a desktop environment." |
@ -0,0 +1,31 @@ |
|||
{ |
|||
"diagnostics": { |
|||
"enable": true, |
|||
"globals": [ |
|||
"awesome", |
|||
"button", |
|||
"dbus", |
|||
"client", |
|||
"mouse", |
|||
"screen", |
|||
"root" |
|||
] |
|||
}, |
|||
"runtime": { |
|||
"version": "Lua 5.3", |
|||
"path": [ |
|||
"/usr/share/awesome/lib/?/?.lua" |
|||
], |
|||
"pathStrict": true |
|||
}, |
|||
"workspace": { |
|||
"library": [ |
|||
"runtime/lua", |
|||
"/usr/share/awesome/lib" |
|||
], |
|||
"checkThirdParty": false, |
|||
"maxPreload": 2000, |
|||
"preloadFileSize": 1000 |
|||
}, |
|||
"telemetry.enable": true |
|||
} |
@ -0,0 +1,73 @@ |
|||
task default: [:install] |
|||
ConfigPath = (ENV["XDG_DATA_HOME"] or ENV["HOME"]+'/.config') |
|||
|
|||
desc "Install (copy) config files" |
|||
task "install-files" do |
|||
base = ["libs","modules","themes","widgets","rc.lua","desktop.conf"] |
|||
sh "mkdir -p #{ConfigPath}/awesome" |
|||
base.each { |f| |
|||
cp_r "./#{f}", "#{ConfigPath}/awesome" |
|||
} |
|||
end |
|||
|
|||
desc "Install LuaPAM" |
|||
task "install-luapam" do |
|||
unless File.exist? "#{ConfigPath}/awesome/libs/pam.so" |
|||
sh "sh ./extra/install_luapam.sh" |
|||
cp "./pam.so","#{ConfigPath}/awesome/libs/" |
|||
cp_r "./pam","#{ConfigPath}/awesome/libs/" |
|||
rm "./pam.so" |
|||
rm_rf "./pam" |
|||
rm_rf "./lua-pam" |
|||
else |
|||
puts "LuaPAM already installed - skipping" |
|||
end |
|||
end |
|||
|
|||
desc "Force install config" |
|||
task "install-force" => ["install-files","install-luapam"] |
|||
|
|||
desc "Install config" |
|||
task :install do |
|||
installed = true |
|||
base = ["libs","modules","themes","widgets","rc.lua","desktop.conf"] |
|||
(base+["libs/pam.so"]).each { |f| |
|||
installed &= File.exist? "#{ConfigPath}/awesome/#{f}" |
|||
} |
|||
if installed |
|||
puts "Baseline files already installed - skipping" |
|||
else |
|||
Rake::Task["install-force"].invoke |
|||
end |
|||
end |
|||
|
|||
desc "Build documentation" |
|||
task :doc do |
|||
sh "ldoc ./.ldoc.lua" |
|||
end |
|||
|
|||
desc "Install extras" |
|||
task "install-extra" do |
|||
cp "./extra/udev/backlight.rules", "/etc/udev/rules.d" |
|||
mkdir "#{ConfigPath}/autostart" |
|||
begin |
|||
sh "sudo cp /usr/share/applications/picom.desktop #{ConfigPath}/autostart/" |
|||
rescue |
|||
puts "picom not installed - ignoring" |
|||
else |
|||
cp "./extra/picom.conf", "#{ConfigPath}" |
|||
end |
|||
puts "Done! Reload awesome to complete installation" |
|||
end |
|||
|
|||
desc "Uninstall from .config" |
|||
task :clean do |
|||
base = ["libs","modules","themes","widgets","rc.lua"] |
|||
base.each { |x| |
|||
rm_rf "#{ConfigPath}/awesome/"+x |
|||
} |
|||
end |
|||
|
|||
desc "Wipe configuration and reinstall from scratch" |
|||
task reinstall: [:clean,:install] |
|||
|
@ -0,0 +1,111 @@ |
|||
# Global variables |
|||
[global] |
|||
# Your preferred terminal emulator |
|||
terminal = "xterm" |
|||
# Your preferred browser (opens the first one available by default) |
|||
browser = "xdg-open about:blank" |
|||
# Your modkey (Mod4 = Super key (Win key)) |
|||
modkey = "Mod4" |
|||
# Your theme (one of the themes available in ./themes/) |
|||
theme = "unity" |
|||
# Your shell (currently doesn't do much, preferrably should remain the same) |
|||
shell = "bash" |
|||
|
|||
# Keybindings |
|||
# Format: <modifier>(+<modifier>+...)+<key> = "<command or :internal.function>" |
|||
# "modkey" as modifier will be substituted for modkey variable in [global] |
|||
[keys] |
|||
"modkey+Left" = ":root.tag_next" |
|||
"modkey+Right" = ":root.tag_prev" |
|||
"modkey+j" = ":root.client_next" |
|||
"modkey+k" = ":root.client_previous" |
|||
"modkey+Control+j" = ":root.screen_next" |
|||
"modkey+Control+k" = ":root.screen_previous" |
|||
"modkey+Tab" = ":root.client_swap" |
|||
"modkey+Return" = ":root.spawn_terminal" |
|||
"modkey+Shift+Return" = ":root.spawn_browser" |
|||
"modkey+Shift+y" = ":root.toggle_titlebars" |
|||
|
|||
# Client keys only work if a focused client exists |
|||
"modkey+Control+o" = ":client.move_to_screen" |
|||
"modkey+Shift+c" = ":client.kill" |
|||
"modkey+t" = ":client.cycle_screen" |
|||
"modkey+o" = ":client.ontop" |
|||
"modkey+b" = ":client.below" |
|||
"modkey+f" = ":client.fullscreen" |
|||
"modkey+n" = ":client.minimize" |
|||
"modkey+m" = ":client.maximize" |
|||
"modkey+p" = ":client.pin" |
|||
"modkey+y" = ":client.toggle_titlebars" |
|||
|
|||
# Widget keys |
|||
"modkey+r" = ":dismal.run" |
|||
"modkey+s" = ":help.show" |
|||
"modkey+q" = ":client.menu" |
|||
"modkey+x" = ":supermenu.open" |
|||
|
|||
"Control+XF86AudioRaiseVolume" = ":client.volume_up" |
|||
"Control+XF86AudioLowerVolume" = ":client.volume_down" |
|||
"Control+XF86AudioMute" = ":client.volume_mute" |
|||
"XF86AudioRaiseVolume" = ":root.volume_up" |
|||
"XF86AudioLowerVolume" = ":root.volume_down" |
|||
"XF86AudioMute" = ":root.volume_mute" |
|||
"XF86MonBrightnessUp" = ":battery.brightness_up" |
|||
"XF86MonBrightnessDown" = ":battery.brightness_down" |
|||
"XF86AudioPlay" = ":mpc.play" |
|||
"XF86AudioPrev" = ":mpc.prev" |
|||
"XF86AudioNext" = ":mpc.next" |
|||
|
|||
# Custom keys |
|||
"Print" = "flameshot gui" |
|||
"Shift+Print" = "flameshot launcher" |
|||
|
|||
# Macro recording/playback keys |
|||
KP_Divide = ":macro.play_1" |
|||
KP_Multiply = ":macro.play_2" |
|||
KP_Add = ":macro.record_1" |
|||
KP_Subtract = ":macro.record_2" |
|||
KP_Delete = ":macro.loop" |
|||
|
|||
# Tiling |
|||
"modkey+Shift+j" = ":layout.swap_next_client" |
|||
"modkey+Shift+k" = ":layout.swap_prev_client" |
|||
"modkey+Control+Return" = ":client.swap_to_master" |
|||
"modkey+l" = ":layout.increase_master" |
|||
"modkey+h" = ":layout.decrease_master" |
|||
"modkey+Shift+l" = ":layout.increase_master_count" |
|||
"modkey+Shift+h" = ":layout.decrease_master_count" |
|||
"modkey+Control+l" = ":layout.increase_column_count" |
|||
"modkey+Control+h" = ":layout.decrease_column_count" |
|||
"modkey+[" = ":layout.next_layout" |
|||
"modkey+]" = ":layout.prev_layout" |
|||
|
|||
# Power manager module |
|||
[powerman] |
|||
# Bad battery condition warning threshold (in %) |
|||
battery_quality_min = 33 |
|||
# Low battery warning threshold (in %) |
|||
battery_capacity_min = 15 |
|||
# Process to execute on low battery |
|||
on_low_battery = "" |
|||
# Process to execute on fully charged battery |
|||
on_charged_battery = "" |
|||
# Process to execute on critical battery condition |
|||
on_critical_condition = "" |
|||
|
|||
# Simple compositor inhibiting |
|||
[compositor] |
|||
# Command to use to spawn compositor |
|||
exec = "picom" |
|||
|
|||
# Macro system |
|||
[macros] |
|||
step = 10 |
|||
|
|||
# Autostart system |
|||
[autostart] |
|||
# Enable minimization of apps with "Hidden" in their .desktop file |
|||
minimize_enable = true |
|||
# How long to target apps that should be minimized |
|||
minimize_timeout = 120 |
|||
|
@ -0,0 +1,57 @@ |
|||
backend = "glx"; |
|||
vsync = true; |
|||
# Shadow |
|||
blur-method = "dual_kawase"; |
|||
blur-strength = 5; |
|||
blur-size = 7; |
|||
shadow = true; # Enabled client-side shadows on windows. |
|||
shadow-radius = 12; # The blur radius for shadows. (default 12) |
|||
shadow-offset-x = -7; # The left offset for shadows. (default -15) |
|||
shadow-offset-y = -7; # The top offset for shadows. (default -15) |
|||
shadow-opacity = 0.25; |
|||
shadow-exclude = [ |
|||
"! name~=''", |
|||
"n:e:Notification", |
|||
"n:e:Plank", |
|||
"n:e:Docky", |
|||
"g:e:Synapse", |
|||
"g:e:Kupfer", |
|||
"g:e:Conky", |
|||
"n:w:*Firefox*", |
|||
"n:w:*Chrome*", |
|||
"n:w:*Chromium*", |
|||
"class_g ?= 'Notify-osd'", |
|||
"class_g ?= 'Cairo-dock'", |
|||
"class_g ?= 'Xfce4-notifyd'", |
|||
"class_g ?= 'Xfce4-power-manager'", |
|||
#"class_g ?= 'awesome'", |
|||
#"class_g ?= 'Awesome'" |
|||
]; |
|||
|
|||
# The shadow exclude options are helpful if you have shadows enabled. Due to the way compton draws its shadows, certain applications will have visual glitches |
|||
# (most applications are fine, only apps that do weird things with xshapes or argb are affected). |
|||
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher. |
|||
|
|||
# Fading |
|||
fading = true; |
|||
# Fade windows during opacity changes. |
|||
fade-delta = 4; # The time between steps in a fade in milliseconds. (default 10). |
|||
fade-in-step = 0.03; # Opacity change between steps while fading in. (default 0.028). |
|||
fade-out-step = 0.03; # Opacity change between steps while fading out. (default 0.03). |
|||
#no-fading-openclose = true; # Fade windows in/out when opening/closing |
|||
|
|||
detect-client-opacity = true; # This prevents opacity being ignored for some apps. For example without this enabled my xfce4-notifyd is 100% opacity no matter what. |
|||
|
|||
# Window type settings |
|||
wintypes: { |
|||
tooltip = { fade = true; shadow = false; }; |
|||
# dock = { shadow = false; fade = false; }; |
|||
# dnd = { shadow = false; fade = false; }; |
|||
}; |
|||
|
|||
# Disable fade for awesomewm components (causes lag with custom menus) |
|||
#fade-exclude = [ |
|||
# "class_g ?= 'awesome'", |
|||
# "class_g ?= 'Awesome'" |
|||
#]; |
|||
|
After Width: 1920 | Height: 1080 | Size: 272 KiB |
@ -0,0 +1,113 @@ |
|||
-- 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/>. |
|||
|
|||
-- library for constructing bindable keys |
|||
local asckey = { |
|||
keymap = {} |
|||
} |
|||
local awful = require("awful") |
|||
local gears = require("gears") |
|||
asckey.set_keymap = function(keymap) |
|||
for k,v in pairs(keymap) do |
|||
asckey.keymap[v] = k |
|||
end |
|||
end |
|||
|
|||
asckey.get_keycomb = function(name) |
|||
local modifiers = {} |
|||
name = name:gsub("[^%s%+]+%+",function(v) |
|||
if v == "modkey+" then v = global.modkey.."+" end |
|||
table.insert(modifiers,v:sub(1,-2)) |
|||
return "" |
|||
end) |
|||
return modifiers,name |
|||
end |
|||
|
|||
asckey.k = function(name,callback,description,release) |
|||
if not asckey.keymap[name] then |
|||
return {} |
|||
end |
|||
local modifiers,key = asckey.get_keycomb(asckey.keymap[name]) |
|||
if key:match("^Mouse(%d+)$") then |
|||
-- After several experiments, the best solution to making the extra mouse buttons bindable |
|||
-- was this. The drawback is that all bindings for these are global, and they do not return |
|||
-- the button object itself. Crappy hack, but it will suffice for now. |
|||
local callback_wrap = function(...) |
|||
callback(...) |
|||
-- For some ungodly reason binding to mouse drops all keybindings |
|||
gears.timer.delayed_call(function() |
|||
mousegrabber.run(function() return false end,"bogosity") |
|||
mousegrabber.stop() |
|||
end) |
|||
end |
|||
local new_button = awful.button(modifiers, tonumber(key:match("^Mouse(%d+)$")), |
|||
callback_wrap,release) |
|||
awful.rules.rules[1].properties.buttons = gears.table.join( |
|||
awful.rules.rules[1].properties.buttons, |
|||
new_button |
|||
) |
|||
root.buttons(gears.table.join( |
|||
root.buttons(), |
|||
new_button |
|||
)) |
|||
return {} |
|||
else |
|||
local callback_wrap = (description.release_pre and function(...) |
|||
root.fake_input("key_release",key) |
|||
callback(...) |
|||
end) or callback |
|||
if release then |
|||
return awful.key(modifiers,key, |
|||
callback_wrap, |
|||
description) |
|||
else |
|||
return awful.key(modifiers,key, |
|||
callback_wrap, |
|||
release, description) |
|||
end |
|||
end |
|||
end |
|||
|
|||
asckey.custom_binds = function() |
|||
local custom_keys = {} |
|||
for comm,_ in pairs(asckey.keymap) do |
|||
if not comm:match("^:.*") then |
|||
table.insert(custom_keys,asckey.k(comm,function() |
|||
awful.spawn(comm) |
|||
end,{description = comm, group = "custom"})) |
|||
end |
|||
end |
|||
return custom_keys |
|||
end |
|||
|
|||
asckey.context = function(keys) |
|||
local context = {keys = keys, key_lookup = {},active = false} |
|||
for _,v in pairs(keys) do |
|||
context.key_lookup[v] = true |
|||
end |
|||
function context:activate() |
|||
context.active = true |
|||
root.keys(gears.table.join( |
|||
root.keys(), |
|||
self.keys |
|||
)) |
|||
end |
|||
function context:deactivate() |
|||
context.active = false |
|||
local root_keys = root.keys() |
|||
for i = #root_keys,1,-1 do |
|||
if self.key_lookup[root_keys[i]] then |
|||
table.remove(root_keys,i) |
|||
end |
|||
end |
|||
root.keys(root_keys) |
|||
end |
|||
return context |
|||
end |
|||
|
|||
return asckey |
@ -0,0 +1,37 @@ |
|||
-- 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/>. |
|||
|
|||
-- Since it would seem that get_widget_by_id is still an open issue (https://github.com/awesomeWM/awesome/issues/2945, https://github.com/awesomeWM/awesome/issues/2181), this abomination is the nuclear solution to finding **ALL** widgets that don't get indexed because they are separated by an already instantiated widget. If you use this, please, use it carefully. Don't call it more than you really need, cache the results if you have to. |
|||
-- Hypothetically, if there occurs such a thing as widget cycle, this will get stuck. Also it's very expensive. |
|||
return function(widget, id) |
|||
local results = {} |
|||
local checked = {} |
|||
local function walker(widget, id) |
|||
if widget.children then |
|||
for _,v in pairs(widget:get_children()) do |
|||
if (v.id == id) and (not checked[v]) then |
|||
table.insert(results, v) |
|||
checked[v] = true |
|||
end |
|||
if (v._private.by_id and v._private.by_id[id]) then |
|||
for _,v2 in pairs(v._private.by_id[id]) do |
|||
if not checked[v2] then |
|||
table.insert(results,v2) |
|||
checked[v2] = true |
|||
end |
|||
end |
|||
end |
|||
walker(v, id) |
|||
end |
|||
end |
|||
end |
|||
walker(widget, id) |
|||
return results |
|||
end |
|||
|
|||
|
@ -0,0 +1,18 @@ |
|||
-- 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/>. |
|||
-- If possible, try to blur the image and return its path via callback. Relies on ImageMagick |
|||
local awful = require("awful") |
|||
return function(image_path,callback) |
|||
local blurred_wallpaper_path = "/tmp/.blur_"..image_path:match("[^/]$") |
|||
if select(3,os.execute("convert -version")) == 0 then |
|||
awful.spawn.easy_async("convert "..image_path.." -blur 0x10 "..blurred_wallpaper_path,function() |
|||
callback(blurred_wallpaper_path) |
|||
end) |
|||
end |
|||
return image_path |
|||
end |
@ -0,0 +1,215 @@ |
|||
-- 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/>. |
|||
|
|||
local parsers = require("parsers") |
|||
function rprint(t,ident) |
|||
ident = ident or 0 |
|||
for k,v in pairs(t) do |
|||
print((" "):rep(ident)..k,v) |
|||
if type(v) == "table" then |
|||
rprint(v,ident+4) |
|||
end |
|||
end |
|||
end |
|||
-- Conf parser |
|||
local data = [[ |
|||
# Global variables |
|||
[global] |
|||
terminal = "$HOME/.local/bin/st" |
|||
browser = "prime-run librewolf" |
|||
modkey = "Mod4" |
|||
theme = "reno98" |
|||
shell = "zsh" |
|||
|
|||
# Keybindings |
|||
# Format: <modifier>(+<modifier>+...)+<key> = "<command or :internal.function>" |
|||
# "modkey" as modifier will be substituted for modkey variable in [global] |
|||
[keys] |
|||
"modkey+Up" = ":root.client_next" |
|||
"modkey+Down" = ":root.client_previous" |
|||
"modkey+Control+Up" = ":root.screen_next" |
|||
"modkey+Control+Down" = ":root.screen_previous" |
|||
"modkey+Tab" = ":root.client_swap" |
|||
"modkey+Return" = ":root.spawn_terminal" |
|||
"modkey+Shift+Return" = ":root.spawn_browser" |
|||
|
|||
# Client keys only work if a focused client exists |
|||
"modkey+Shift+c" = ":client.kill" |
|||
"modkey+t" = ":client.cycle_screen" |
|||
"modkey+o" = ":client.ontop" |
|||
"modkey+b" = ":client.below" |
|||
"modkey+f" = ":client.fullscreen" |
|||
"modkey+n" = ":client.minimize" |
|||
"modkey+m" = ":client.maximize" |
|||
]] |
|||
for k,v in pairs(parsers.conf(data)) do |
|||
print("Block: ["..k.."]") |
|||
for kk,vv in pairs(v) do |
|||
print(kk,vv) |
|||
end |
|||
end |
|||
|
|||
-- yaml-like (pactl) parser |
|||
data = [[ |
|||
Sink Input #75 |
|||
Driver: PipeWire |
|||
Owner Module: n/a |
|||
Client: 58 |
|||
Sink: 46 |
|||
Sample Specification: float32le 2ch 44100Hz |
|||
Channel Map: front-left,front-right |
|||
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\"" |
|||
Corked: no |
|||
Mute: no |
|||
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB |
|||
balance 0.00 |
|||
Buffer Latency: 0 usec |
|||
Sink Latency: 0 usec |
|||
Resample method: PipeWire |
|||
Properties: |
|||
client.api = "pipewire-pulse" |
|||
pulse.server.type = "unix" |
|||
application.name = "LibreWolf" |
|||
application.process.id = "1756" |
|||
application.process.user = "yessiest" |
|||
application.process.host = "architect" |
|||
application.process.binary = "librewolf" |
|||
application.language = "C.UTF-8" |
|||
window.x11.display = ":0" |
|||
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c" |
|||
application.process.session_id = "1" |
|||
media.name = "AudioStream" |
|||
node.rate = "1/44100" |
|||
node.latency = "3307/44100" |
|||
stream.is-live = "true" |
|||
node.name = "LibreWolf" |
|||
node.autoconnect = "true" |
|||
node.want-driver = "true" |
|||
media.class = "Stream/Output/Audio" |
|||
adapt.follower.spa-node = "" |
|||
object.register = "false" |
|||
factory.id = "6" |
|||
clock.quantum-limit = "8192" |
|||
factory.mode = "split" |
|||
audio.adapt.follower = "" |
|||
library.name = "audioconvert/libspa-audioconvert" |
|||
client.id = "56" |
|||
object.id = "57" |
|||
object.serial = "75" |
|||
pulse.attr.maxlength = "4194304" |
|||
pulse.attr.tlength = "44104" |
|||
pulse.attr.prebuf = "35296" |
|||
pulse.attr.minreq = "8816" |
|||
module-stream-restore.id = "sink-input-by-application-name:LibreWolf" |
|||
]] |
|||
rprint(parsers.yaml_pseudo(data)) |
|||
-- Fast incomplete yaml parser |
|||
data = [[ |
|||
Sink Input #73 |
|||
Driver: PipeWire |
|||
Owner Module: n/a |
|||
Client: 58 |
|||
Sink: 46 |
|||
Sample Specification: float32le 2ch 44100Hz |
|||
Channel Map: front-left,front-right |
|||
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\"" |
|||
Corked: no |
|||
Mute: no |
|||
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB |
|||
balance 0.00 |
|||
Buffer Latency: 0 usec |
|||
Sink Latency: 0 usec |
|||
Resample method: PipeWire |
|||
Properties: |
|||
client.api = "pipewire-pulse" |
|||
pulse.server.type = "unix" |
|||
application.name = "LibreWolf" |
|||
application.process.id = "1756" |
|||
application.process.user = "yessiest" |
|||
application.process.host = "architect" |
|||
application.process.binary = "librewolf" |
|||
application.language = "C.UTF-8" |
|||
window.x11.display = ":0" |
|||
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c" |
|||
application.process.session_id = "1" |
|||
media.name = "AudioStream" |
|||
node.rate = "1/44100" |
|||
node.latency = "3307/44100" |
|||
stream.is-live = "true" |
|||
node.name = "LibreWolf" |
|||
node.autoconnect = "true" |
|||
node.want-driver = "true" |
|||
media.class = "Stream/Output/Audio" |
|||
adapt.follower.spa-node = "" |
|||
object.register = "false" |
|||
factory.id = "6" |
|||
clock.quantum-limit = "8192" |
|||
factory.mode = "split" |
|||
audio.adapt.follower = "" |
|||
library.name = "audioconvert/libspa-audioconvert" |
|||
client.id = "56" |
|||
object.id = "57" |
|||
object.serial = "75" |
|||
pulse.attr.maxlength = "4194304" |
|||
pulse.attr.tlength = "44104" |
|||
pulse.attr.prebuf = "35296" |
|||
pulse.attr.minreq = "8816" |
|||
module-stream-restore.id = "sink-input-by-application-name:LibreWolf" |
|||
|
|||
Sink Input #75 |
|||
Driver: PipeWire |
|||
Owner Module: n/a |
|||
Client: 58 |
|||
Sink: 46 |
|||
Sample Specification: float32le 2ch 44100Hz |
|||
Channel Map: front-left,front-right |
|||
Format: pcm, format.sample_format = "\"float32le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\"" |
|||
Corked: no |
|||
Mute: no |
|||
Volume: front-left: 38326 / 58% / -13.98 dB, front-right: 38326 / 58% / -13.98 dB |
|||
balance 0.00 |
|||
Buffer Latency: 0 usec |
|||
Sink Latency: 0 usec |
|||
Resample method: PipeWire |
|||
Properties: |
|||
client.api = "pipewire-pulse" |
|||
pulse.server.type = "unix" |
|||
application.name = "LibreWolf" |
|||
application.process.id = "1756" |
|||
application.process.user = "yessiest" |
|||
application.process.host = "architect" |
|||
application.process.binary = "librewolf" |
|||
application.language = "C.UTF-8" |
|||
window.x11.display = ":0" |
|||
application.process.machine_id = "a8099c2d12fe88c3df940ed562adbe8c" |
|||
application.process.session_id = "1" |
|||
media.name = "AudioStream" |
|||
node.rate = "1/44100" |
|||
node.latency = "3307/44100" |
|||
stream.is-live = "true" |
|||
node.name = "LibreWolf" |
|||
node.autoconnect = "true" |
|||
node.want-driver = "true" |
|||
media.class = "Stream/Output/Audio" |
|||
adapt.follower.spa-node = "" |
|||
object.register = "false" |
|||
factory.id = "6" |
|||
clock.quantum-limit = "8192" |
|||
factory.mode = "split" |
|||
audio.adapt.follower = "" |
|||
library.name = "audioconvert/libspa-audioconvert" |
|||
client.id = "56" |
|||
object.id = "57" |
|||
object.serial = "75" |
|||
pulse.attr.maxlength = "4194304" |
|||
pulse.attr.tlength = "44104" |
|||
pulse.attr.prebuf = "35296" |
|||
pulse.attr.minreq = "8816" |
|||
module-stream-restore.id = "sink-input-by-application-name:LibreWolf" |
|||
]] |
|||
rprint(parsers.fast_split_yaml(data)) |
@ -0,0 +1,161 @@ |
|||
-- 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/>. |
|||
|
|||
-- Various utilitiy parsers |
|||
local parsers = {} |
|||
|
|||
local function split_strings(text) |
|||
-- probably the cleanest function to split by strings i've written to date |
|||
local split = {} |
|||
while text:find("\"") do |
|||
local strstart = text:find("\"") |
|||
while text:sub(strstart-1,strstart-1) == "\\" do |
|||
strstart = text:find("\"",strstart+1) |
|||
end |
|||
local strend = text:find("\"",strstart+1) |
|||
while text:sub(strend-1,strend-1) == "\\" do |
|||
strend = text:find("\"",strend+1) |
|||
end |
|||
if not strend then |
|||
return nil, "String not closed at "..strstart |
|||
end |
|||
local before_string = text:sub(1,strstart-1) |
|||
local string = text:sub(strstart,strend):gsub("\\\"","\"") |
|||
text = text:sub(strend+1,-1) |
|||
table.insert(split,before_string) |
|||
table.insert(split,string) |
|||
end |
|||
table.insert(split,text) |
|||
return split |
|||
end |
|||
|
|||
parsers.fast_split_yaml = function(cfgtext) |
|||
-- Fast yaml splitter - incomplete parsing, only first layer is parsed |
|||
-- Used within timers to find objects while decreasing CPU usage |
|||
local items = {} |
|||
local replacements = 1 |
|||
cfgtext = cfgtext:gsub("^%s*","") |
|||
while replacements > 0 do |
|||
cfgtext,replacements = cfgtext:gsub("^(.-\n)(%S+)",function(struct,n) |
|||
table.insert(items,struct) |
|||
return ""..n |
|||
end) |
|||
end |
|||
table.insert(items,cfgtext) |
|||
return items |
|||
end |
|||
parsers.yaml_pseudo = function(cfgtext) |
|||
-- Somewhat yaml-like structure used by pactl |
|||
local struct = {} |
|||
local lines = {} |
|||
cfgtext:gsub("(%s*)([^\n]*)",function(spacing,line) |
|||
table.insert(lines, |
|||
{ |
|||
spacing:len(), |
|||
-- key |
|||
line:match("^([^:=]-)%s*[:=]") or line, |
|||
-- value |
|||
line:match(":%s*(.-)%s*$") or |
|||
line:match("=%s*(.-)%s*$") |
|||
} |
|||
) |
|||
end) |
|||
local history = {struct} |
|||
local spacing_width = 0 |
|||
for k,v in pairs(lines) do |
|||
if v[1] > spacing_width then |
|||
history[#history][lines[k-1][2]] = { |
|||
[lines[k-1][2]] = lines[k-1][3] |
|||
} |
|||
history[#history+1] = history[#history][lines[k-1][2]] |
|||
elseif v[1] < spacing_width then |
|||
history[#history] = nil |
|||
end |
|||
if v[3] and v[3]:match("^%s*\".*\"%s*$") then |
|||
history[#history][v[2]] = v[3]:match("^%s*\"(.*)\"%s*$") |
|||
else |
|||
history[#history][v[2]] = v[3] |
|||
end |
|||
spacing_width = v[1] |
|||
end |
|||
return struct |
|||
end |
|||
|
|||
local function quotestrip(txt) |
|||
if (txt:sub(1,1):match("['\"]")) |
|||
and (txt:sub(-1,-1) == txt:sub(1,1)) then |
|||
return txt:sub(2,-2) |
|||
else |
|||
return txt |
|||
end |
|||
end |
|||
|
|||
|
|||
parsers.conf = function(cfgtext) |
|||
-- Conf style parser (not exactly TOML) |
|||
cfgtext = cfgtext:gsub("#[^\n]*","") |
|||
local split_by_strings,err = split_strings(cfgtext) |
|||
if not split_by_strings then error(err) end |
|||
local full_split = {{}} |
|||
local current_line = full_split[1] |
|||
-- tokenizer |
|||
for _,v in pairs(split_by_strings) do |
|||
v = v:match("^[ \t]*(.*)[ \t]*$") |
|||
if (not (v == "")) then |
|||
if not v:match("^\".*\"$") then |
|||
v:gsub("[^ \t]+",function(text) |
|||
while text:match("\n") do |
|||
local before,after = text:match("([^\n]*)\n(.*)") |
|||
if before ~= "" then |
|||
table.insert(current_line,before) |
|||
end |
|||
if #current_line > 0 then |
|||
table.insert(full_split,{}) |
|||
current_line = full_split[#full_split] |
|||
end |
|||
text = after |
|||
end |
|||
if text ~= "" then |
|||
table.insert(current_line,text) |
|||
end |
|||
end) |
|||
else |
|||
table.insert(current_line,v) |
|||
end |
|||
end |
|||
end |
|||
table.remove(full_split,#full_split) |
|||
local struct = {global = {}} |
|||
local block = "global" |
|||
-- parser |
|||
for _,line in pairs(full_split) do |
|||
if line[1] and line[1]:match("^%[[^%]]+%]$") then -- block |
|||
block = line[1]:match("^%[([^%]]+)%]$") |
|||
struct[block] = {} |
|||
elseif #line == 3 then -- assignment |
|||
if (line[3]:sub(1,1):match("['\"]")) -- string |
|||
and (line[3]:sub(-1,-1) == line[3]:sub(1,1)) then |
|||
struct[block][quotestrip(line[1])] = quotestrip(line[3]) |
|||
elseif line[3]:match("^%d+$") then -- number |
|||
struct[block][quotestrip(line[1])] = tonumber(line[3]) |
|||
elseif (line[3] == "true") or (line[3] == "false") then -- boolean |
|||
struct[block][quotestrip(line[1])] = (line[3] == "true") |
|||
else |
|||
error("Invalid assignment expression: "..line[3]) |
|||
end |
|||
else -- invalid |
|||
local textline = "" |
|||
for _,v in pairs(line) do |
|||
textline = textline..v.." " |
|||
end |
|||
error("Invalid config expression: "..textline:sub(1,-2)) |
|||
end |
|||
end |
|||
return struct |
|||
end |
|||
return parsers |
@ -0,0 +1,16 @@ |
|||
-- 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/>. |
|||
|
|||
-- Various utilities that are not included into awesomewm |
|||
local utils = {} |
|||
utils.substitute_env = function(str) |
|||
return str:gsub("$[%w_]+",function(var) |
|||
return os.getenv(var:sub(2,-1)) or "" |
|||
end) |
|||
end |
|||
return utils |
@ -0,0 +1,137 @@ |
|||
-- 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/>. |
|||
-- Asynchronous XDG data aggregator (library) |
|||
local menu_utils = require("menubar.utils") |
|||
local awful = require("awful") |
|||
local gears = require("gears") |
|||
local json = require("dkjson") |
|||
local lib = {} |
|||
|
|||
function lib.init_xdg_struct() |
|||
-- Global xdg data struct |
|||
local xdg = { |
|||
directory_integrity = {}, |
|||
directory_listings = {}, |
|||
apps = {}, |
|||
categories = { |
|||
Other = { |
|||
icon = "applications-other", |
|||
apps = {} |
|||
}, |
|||
Wine = { |
|||
icon = "wine", |
|||
apps = {} |
|||
} |
|||
} |
|||
} |
|||
return xdg |
|||
end |
|||
|
|||
function lib.load_xdg_cache() |
|||
-- Load cached applications |
|||
local cache_file = io.open(gears.filesystem.get_xdg_cache_home()..".reno_xdg_cache.json","r") |
|||
local cache |
|||
if cache_file then |
|||
cache = json.decode(cache_file:read("*a")) |
|||
cache_file:close() |
|||
end |
|||
return cache |
|||
end |
|||
|
|||
function lib.add_categories(xdg, categories) |
|||
-- Add missing category entries as defined by awesome |
|||
for _,v in pairs(categories) do |
|||
xdg.categories[v.app_type] = { |
|||
name = v.name, |
|||
icon = v.icon_name, |
|||
apps = {} |
|||
} |
|||
end |
|||
end |
|||
|
|||
function lib.async_process_dirs(xdg, dirs, cache, on_dir_done) |
|||
-- Asynchronous scanning process |
|||
for _,v in pairs(dirs) do |
|||
xdg.directory_listings[v] = {} |
|||
awful.spawn.with_line_callback("find "..tostring(v).." -maxdepth 1 -name *.desktop",{ |
|||
stdout = function(line) |
|||
-- Assume the cache is valid for a listed file |
|||
if cache and cache.directory_listings[v][line] then |
|||
xdg.directory_listings[v][line] = true |
|||
xdg.apps[line] = cache.apps[line] |
|||
xdg.categories[cache.apps[line].category].apps[line] = cache.apps[line] |
|||
return |
|||
end |
|||
local data = menu_utils.parse_desktop_file(line) |
|||
if data.NoDisplay then |
|||
return |
|||
end |
|||
local appdata = { |
|||
name = data.Name, |
|||
category = "Other", |
|||
exec = data.Exec, |
|||
icon = (data.Icon and menu_utils.lookup_icon(data.Icon)), |
|||
description = data.Comment |
|||
} |
|||
-- Match first available cateogry for sorting |
|||
for _,vv in pairs(data.Categories or {"Other"}) do |
|||
if xdg.categories[vv] then |
|||
appdata.category = vv |
|||
break |
|||
end |
|||
-- Oh how do I love those Wine applications and their categories |
|||
if vv:match("^Wine") then |
|||
appdata.category = "Wine" |
|||
break |
|||
end |
|||
end |
|||
-- Open terminal apps in the terminal (duh) |
|||
if data.Terminal then |
|||
appdata.exec = global.terminal.." -e "..appdata.exec |
|||
end |
|||
-- Just for you, Wine - special case because you're being a shit |
|||
if (appdata.exec and appdata.exec:find("%W?wine ")) then |
|||
appdata.category = "Wine" |
|||
end |
|||
xdg.apps[line] = appdata |
|||
xdg.categories[appdata.category].apps[line] = appdata |
|||
-- Add the file to the listing of cached ones |
|||
xdg.directory_listings[v][line] = true |
|||
end, |
|||
output_done = function(...) on_dir_done(v,...) end |
|||
}) |
|||
end |
|||
end |
|||
|
|||
function lib.generate_meta_patch(xdg) |
|||
local patch = {apps = {}} |
|||
for k,v in pairs(xdg.apps) do |
|||
patch.apps[k] = {} |
|||
for kk,vv in pairs(v) do |
|||
patch.apps[k][kk] = vv |
|||
end |
|||
patch.apps[k].name = nil |
|||
patch.apps[k].category = nil |
|||
patch.apps[k].exec = nil |
|||
patch.apps[k].icon = nil |
|||
patch.apps[k].description = nil |
|||
end |
|||
return patch |
|||
end |
|||
|
|||
function lib.apply_meta_patch(xdg,patch) |
|||
for k,v in pairs(patch.apps) do |
|||
if xdg.apps[k] then |
|||
for kk,vv in pairs(v) do |
|||
xdg.apps[k][kk] = vv |
|||
end |
|||
end |
|||
end |
|||
end |
|||
|
|||
return lib |
@ -0,0 +1,50 @@ |
|||
-- 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/>. |
|||
-- Compositor manager with inhibitor |
|||
local awful = require("awful") |
|||
-- Configuration variables |
|||
local cfg = config.compositor or {} |
|||
local compositor_enabled = false |
|||
local inhibitors = {} |
|||
local compositor_pid = nil |
|||
local function count(t) |
|||
local c = 0 |
|||
for _,_ in pairs(t) do |
|||
c = c + 1 |
|||
end |
|||
return c |
|||
end |
|||
if cfg.exec then |
|||
compositor_pid = awful.spawn(cfg.exec) |
|||
compositor_enabled = true |
|||
client.connect_signal("manage",function(c) |
|||
if c.inhibit_compositor then |
|||
inhibitors[c] = true |
|||
if compositor_enabled then |
|||
awful.spawn("kill "..tostring(compositor_pid)) |
|||
compositor_enabled = false |
|||
end |
|||
end |
|||
end) |
|||
client.connect_signal("unmanage",function(c) |
|||
if c.inhibit_compositor then |
|||
inhibitors[c] = nil |
|||
if count(inhibitors) == 0 then |
|||
if compositor_enabled == false then |
|||
compositor_pid = awful.spawn(cfg.exec) |
|||
compositor_enabled = true |
|||
end |
|||
end |
|||
end |
|||
end) |
|||
awesome.connect_signal("exit",function() |
|||
if compositor_enabled and compositor_pid then |
|||
awful.spawn("kill "..tostring(compositor_pid)) |
|||
end |
|||
end) |
|||
end |
@ -0,0 +1,163 @@ |
|||
-- 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/>. |
|||
local awful = require("awful") |
|||
local gears = require("gears") |
|||
local ask = require("asckey") |
|||
local fs = gears.filesystem |
|||
|
|||
_G.MacroTimer = {} |
|||
_G.MacroActive = {} |
|||
|
|||
local mconf = config.macros |
|||
|
|||
local macro_loop = false |
|||
local macro_delay = mconf.step or 10 |
|||
local macro_base_dir = mconf.base_dir or (root_path.."/macros/") |
|||
|
|||
if not fs.dir_readable(root_path.."/macros/") then |
|||
fs.make_directories(root_path.."/macros/") |
|||
end |
|||
|
|||
awesome.connect_signal("macro::record",function(filename) |
|||
if not filename then return end |
|||
local timeline = "loop="..tostring(macro_loop).."\n".. |
|||
"delay="..tostring(macro_delay).."\n" |
|||
require("naughty").notify({title = |
|||
"Recording macro ".. |
|||
tostring(filename).. |
|||
" (Escape to stop)" |
|||
}) |
|||
awful.keygrabber { |
|||
autostart = true, |
|||
stop_key = "Escape", |
|||
keypressed_callback = function(self, mod, key, event) |
|||
if key == " " then |
|||
key = "space" |
|||
end |
|||
timeline = timeline.."+"..key.."\n" |
|||
end, |
|||
keyreleased_callback = function(self, mod, key, event) |
|||
if key == " " then |
|||
key = "space" |
|||
end |
|||
timeline = timeline.."-"..key.."\n" |
|||
end, |
|||
stop_callback = function() |
|||
local macrofile = io.open(filename,"w") |
|||
if macrofile then |
|||
macrofile:write(timeline) |
|||
macrofile:close() |
|||
require("naughty").notify({title="Macro saved as "..tostring(filename)}) |
|||
else |
|||
require("naughty").notify({title="Failed to save macro"}) |
|||
end |
|||
-- For some reason after keygrabber is done input doesn't work |
|||
gears.timer.delayed_call(function() |
|||
awful.keygrabber:stop() |
|||
end) |
|||
end |
|||
} |
|||
end) |
|||
|
|||
awesome.connect_signal("macro::play",function(filename) |
|||
if (not filename) or (not fs.file_readable(filename)) then |
|||
return |
|||
end |
|||
local macrofile = io.open(filename,"r") |
|||
local macrodata = macrofile:read("*a") |
|||
macrofile:close() |
|||
local macro = {} |
|||
local step = 0 |
|||
macrodata:gsub("([^\n]+)",function(line) |
|||
table.insert(macro,line) |
|||
end) |
|||
local delay = tonumber(macro[2]:match("delay=(%d+)")) |
|||
_G.MacroActive[filename] = (macro[1]:match("loop=(.+)") == "true") |
|||
table.remove(macro,2) |
|||
table.remove(macro,1) |
|||
local macro_length = #macro |
|||
_G.MacroTimer[filename] = gears.timer.start_new((1/1000)*delay,function() |
|||
step = step + 1 |
|||
local instruction = macro[step] |
|||
local event = (instruction:match("^%+") and "key_press") or "key_release" |
|||
root.fake_input(event,instruction:match("^[%+%-](.*)")) |
|||
if (step == macro_length) and (_G.MacroActive[filename]) then |
|||
step = 0 |
|||
return true |
|||
elseif (step < macro_length) then |
|||
return true |
|||
else |
|||
_G.MacroTimer[filename] = nil |
|||
_G.MacroActive[filename] = nil |
|||
return false |
|||
end |
|||
end) |
|||
end) |
|||
|
|||
|
|||
root.keys(gears.table.join( |
|||
root.keys(), |
|||
ask.k(":macro.record_1", function() |
|||
awesome.emit_signal("macro::record",macro_base_dir.."macro1") |
|||
end,{group="macros",description="Record macro 1"}), |
|||
ask.k(":macro.record_2", function() |
|||
awesome.emit_signal("macro::record",macro_base_dir.."macro2") |
|||
end,{group="macros",description="Record macro 2"}), |
|||
ask.k(":macro.record_3", function() |
|||
awesome.emit_signal("macro::record",macro_base_dir.."macro3") |
|||
end,{group="macros",description="Record macro 3"}), |
|||
ask.k(":macro.record_4", function() |
|||
awesome.emit_signal("macro::record",macro_base_dir.."macro4") |
|||
end,{group="macros",description="Record macro 4"}), |
|||
ask.k(":macro.record_5", function() |
|||
awesome.emit_signal("macro::record",macro_base_dir.."macro5") |
|||
end,{group="macros",description="Record macro 5"}), |
|||
ask.k(":macro.play_1", function() |
|||
if not _G.MacroActive[macro_base_dir.."macro1"] then |
|||
awesome.emit_signal("macro::play",macro_base_dir.."macro1") |
|||
else |
|||
_G.MacroActive[macro_base_dir.."macro1"] = false |
|||
end |
|||
end,{group="macros",description="Play macro 1",release_pre=true}), |
|||
ask.k(":macro.play_2", function() |
|||
if not _G.MacroActive[macro_base_dir.."macro2"] then |
|||
awesome.emit_signal("macro::play",macro_base_dir.."macro2") |
|||
else |
|||
_G.MacroActive[macro_base_dir.."macro2"] = false |
|||
end |
|||
end,{group="macros",description="Play macro 2",release_pre=true}), |
|||
ask.k(":macro.play_3", function() |
|||
if not _G.MacroActive[macro_base_dir.."macro3"] then |
|||
awesome.emit_signal("macro::play",macro_base_dir.."macro3") |
|||
else |
|||
_G.MacroActive[macro_base_dir.."macro3"] = false |
|||
end |
|||
end,{group="macros",description="Play macro 3",release_pre=true}), |
|||
ask.k(":macro.play_4", function() |
|||
if not _G.MacroActive[macro_base_dir.."macro4"] then |
|||
awesome.emit_signal("macro::play",macro_base_dir.."macro4") |
|||
else |
|||
_G.MacroActive[macro_base_dir.."macro4"] = false |
|||
end |
|||
end,{group="macros",description="Play macro 4",release_pre=true}), |
|||
ask.k(":macro.play_5", function() |
|||
if not _G.MacroActive[macro_base_dir.."macro5"] then |
|||
awesome.emit_signal("macro::play",macro_base_dir.."macro5") |
|||
else |
|||
_G.MacroActive[macro_base_dir.."macro5"] = false |
|||
end |
|||
end,{group="macros",description="Play macro 5",release_pre=true}), |
|||
ask.k(":macro.loop",function() |
|||
macro_loop = not macro_loop |
|||
if macro_loop then |
|||
require("naughty").notify({title="Macro looping turned on"}) |
|||
else |
|||
require("naughty").notify({title="Macro looping turned off"}) |
|||
end |
|||
end,{group="macros",description="turn looping on/off"}) |
|||
)) |
@ -0,0 +1,75 @@ |
|||
-- 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/>. |
|||
-- Powerman X - second generation of the power management module |
|||
local awful = require("awful") |
|||
local sysctl = require("syscontrol") |
|||
local naughty = require("naughty") |
|||
local gears = require("gears") |
|||
local batteries = sysctl.power_supply.enumerate() |
|||
local state_tracking = {} |
|||
-- Configuration variables |
|||
local cfg = config.powerman or {} |
|||
local quality_min = cfg.battery_quality_min or 33 |
|||
local capacity_min = cfg.battery_capacity_min or 15 |
|||
local on_low_battery = cfg.on_low_battery or "" |
|||
local on_charged_battery = cfg.on_charged_battery |
|||
local on_critical_condition = cfg.on_critical_condition |
|||
-- Main loop |
|||
gears.timer({ |
|||
timeout = 2, |
|||
autostart = true, |
|||
callback = function() |
|||
for _,v in pairs(batteries) do |
|||
local data,_ = sysctl.power_supply.read_attribs(v) |
|||
state_tracking[v] = state_tracking[v] or {} |
|||
if data.type == "Battery" then |
|||
if (tonumber(data.quality) < quality_min) and |
|||
(not state_tracking[v].quality_notification) then |
|||
naughty.notify({ |
|||
title = "Critical battery condition", |
|||
text = "Battery "..data.name.." has reached critically low condition, seek a suitable replacement" |
|||
}) |
|||
state_tracking[v].quality_notification = true |
|||
if on_critical_condition then |
|||
awful.spawn(on_critical_condition) |
|||
end |
|||
end |
|||
if (tonumber(data.capacity) <= capacity_min) and |
|||
(not data.charging) and |
|||
(not state_tracking[v].capacity_notification) then |
|||
naughty.notify({ |
|||
title = "Battery capacity low", |
|||
text = "Battery "..data.name.." capacity is at "..tostring(data.capacity).."%" |
|||
}) |
|||
state_tracking[v].capacity_notification = true |
|||
if on_low_battery then |
|||
awful.spawn(on_low_battery) |
|||
end |
|||
end |
|||
if (tonumber(data.capacity) > capacity_min) then |
|||
state_tracking[v].capacity_notification = false |
|||
end |
|||
if (data.capacity == "100") and |
|||
(data.charging) and |
|||
(not state_tracking[v].charged_notification) then |
|||
naughty.notify({ |
|||
title = "Battery is completely charged", |
|||
text = "Disconnect the charger from the power grid to avoid passive electricity usage." |
|||
}) |
|||
if on_charged_battery then |
|||
awful.spawn(on_charged_battery) |
|||
end |
|||
end |
|||
if (not data.charging) then |
|||
state_tracking[v].charged_notification = false |
|||
end |
|||
end |
|||
end |
|||
end |
|||
}) |
|||
|
@ -0,0 +1,34 @@ |
|||
local awful = require("awful") |
|||
local gears = require("gears") |
|||
awful.rules.rules = gears.table.join(awful.rules.rules, { |
|||
{ rule_any = { class = { |
|||
"steam_app_548430", |
|||
"steam_app_%d*", |
|||
"love", |
|||
"^Minecraft.*" |
|||
}}, |
|||
properties = {inhibit_compositor = true}, |
|||
}, |
|||
{ rule = { name = "notificationtoasts.*" }, |
|||
properties = { |
|||
focusable = false |
|||
} |
|||
}, |
|||
{ rule = { fullscreen = true }, |
|||
properties = { |
|||
titlebars_enabled = false, |
|||
floating = true, |
|||
border_width = 0, |
|||
border_color = 0, |
|||
size_hints_honor = false, |
|||
placement=awful.placement.no_offscreen |
|||
}, |
|||
callback = function(c) |
|||
gears.timer.delayed_call(function() |
|||
if c.valid then |
|||
c:geometry(c.screen.geometry) |
|||
end |
|||
end) |
|||
end |
|||
} |
|||
}) |
@ -0,0 +1,19 @@ |
|||
-- 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/>. |
|||
local awful = require("awful") |
|||
|
|||
awful.layout.layouts = { |
|||
awful.layout.suit.floating, |
|||
awful.layout.suit.tile, |
|||
awful.layout.suit.tile.left, |
|||
awful.layout.suit.tile.bottom, |
|||
awful.layout.suit.tile.top, |
|||
awful.layout.suit.fair, |
|||
} |
|||
|
|||
|
@ -0,0 +1,12 @@ |
|||
Notice: all assets in the layouts directory and taglist directory, as well as submenu.png, belong to the AwesomeWM team and respective authors of these assets. |
|||
|
|||
The following assets in the titlebar directory are made specifically for reno98 and are licensed under CC0: |
|||
close_focus.png |
|||
close_normal.png |
|||
maximized_focus_inactive.png |
|||
maximized_normal_inactive.png |
|||
maximized_normal_active.png |
|||
minimize_focus.png |
|||
minimize_normal.png |
|||
|
|||
Other assets in the directory are kept from the default theme of AwesomeWM and belong to the respecitve authors. |
@ -1,7 +1,8 @@ |
|||
{ |
|||
"list": [ |
|||
{"widget": "widgets.clientcontrols"}, |
|||
{"widget": "widgets.clientbuttons"} |
|||
{"widget": "widgets.clientmenu.volume","vertical":false}, |
|||
{"widget": "widgets.clientmenu.controls"}, |
|||
{"widget": "widgets.clientmenu.buttons"} |
|||
], |
|||
"vertical":true |
|||
} |
@ -1,8 +1,9 @@ |
|||
{ |
|||
"widgets.dismal":{ |
|||
"x":0, |
|||
"y":26 |
|||
"pos":"top_left", |
|||
"ignore_wibars":false |
|||
}, |
|||
"widgets.rootmenu":{}, |
|||
"widgets.lockscreen":{} |
|||
"widgets.lockscreen":{}, |
|||
"widgets.base.keypopup":{} |
|||
} |
@ -1,29 +1,30 @@ |
|||
{ |
|||
"align": { |
|||
"left": [ |
|||
{ "widget": "widgets.soundclown" } |
|||
{ "widget": "widgets.desktop.soundclown" } |
|||
], |
|||
"center": [ |
|||
|
|||
], |
|||
"right": [ |
|||
{ "widget": "widgets.notifications", |
|||
{ "widget":"widgets.desktop.volume" }, |
|||
{ "widget": "widgets.desktop.notifications", |
|||
"screen": true |
|||
}, |
|||
{ "widget": "widgets.wallpapers", |
|||
{ "widget": "widgets.desktop.wallpapers", |
|||
"screen": true, |
|||
"options": { |
|||
"path": "$HOME/Pictures/Wallpapers" |
|||
} |
|||
}, |
|||
{ "widget": "widgets.base.subpanel", |
|||
"layout": { |
|||
"list": [ |
|||
{ "widget": "widgets.battery" }, |
|||
{ |
|||
"widget": "widgets.base.subpanel", |
|||
"layout": {"list":[ |
|||
{ "widget": "widgets.base.layout" }, |
|||
{ "widget": "widgets.desktop.battery" }, |
|||
{ "widget": "widgets.base.systray" }, |
|||
{ "widget": "widgets.base.clock" } |
|||
] |
|||
} |
|||
]} |
|||
} |
|||
] |
|||
} |
|||
|
@ -1,3 +1,3 @@ |
|||
Licensed under conditions of CC0 (https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt) |
|||
|
|||
To the extent possible under law, Yessiest (yessiest@memeware.net) has waived all copyright and related or neighboring rights to Reno98 icons |
|||
To the extent possible under law, Yessiest (yessiest@memeware.net) has waived all copyright and related or neighboring rights to Reno icons |
After Width: 48 | Height: 48 | Size: 455 B |
Before Width: 48 | Height: 48 | Size: 455 B After Width: 48 | Height: 48 | Size: 8.3 KiB |
After Width: 48 | Height: 48 | Size: 729 B |
After Width: 48 | Height: 48 | Size: 682 B |
After Width: 48 | Height: 48 | Size: 708 B |
After Width: 48 | Height: 48 | Size: 751 B |
After Width: 48 | Height: 48 | Size: 642 B |
@ -0,0 +1,121 @@ |
|||
Creative Commons Legal Code |
|||
|
|||
CC0 1.0 Universal |
|||
|
|||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE |
|||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN |
|||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS |
|||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES |
|||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS |
|||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM |
|||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED |
|||
HEREUNDER. |
|||
|
|||
Statement of Purpose |
|||
|
|||
The laws of most jurisdictions throughout the world automatically confer |
|||
exclusive Copyright and Related Rights (defined below) upon the creator |
|||
and subsequent owner(s) (each and all, an "owner") of an original work of |
|||
authorship and/or a database (each, a "Work"). |
|||
|
|||
Certain owners wish to permanently relinquish those rights to a Work for |
|||
the purpose of contributing to a commons of creative, cultural and |
|||
scientific works ("Commons") that the public can reliably and without fear |
|||
of later claims of infringement build upon, modify, incorporate in other |
|||
works, reuse and redistribute as freely as possible in any form whatsoever |
|||
and for any purposes, including without limitation commercial purposes. |
|||
These owners may contribute to the Commons to promote the ideal of a free |
|||
culture and the further production of creative, cultural and scientific |
|||
works, or to gain reputation or greater distribution for their Work in |
|||
part through the use and efforts of others. |
|||
|
|||
For these and/or other purposes and motivations, and without any |
|||
expectation of additional consideration or compensation, the person |
|||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she |
|||
is an owner of Copyright and Related Rights in the Work, voluntarily |
|||
elects to apply CC0 to the Work and publicly distribute the Work under its |
|||
terms, with knowledge of his or her Copyright and Related Rights in the |
|||
Work and the meaning and intended legal effect of CC0 on those rights. |
|||
|
|||
1. Copyright and Related Rights. A Work made available under CC0 may be |
|||
protected by copyright and related or neighboring rights ("Copyright and |
|||
Related Rights"). Copyright and Related Rights include, but are not |
|||
limited to, the following: |
|||
|
|||
i. the right to reproduce, adapt, distribute, perform, display, |
|||
communicate, and translate a Work; |
|||
ii. moral rights retained by the original author(s) and/or performer(s); |
|||
iii. publicity and privacy rights pertaining to a person's image or |
|||
likeness depicted in a Work; |
|||
iv. rights protecting against unfair competition in regards to a Work, |
|||
subject to the limitations in paragraph 4(a), below; |
|||
v. rights protecting the extraction, dissemination, use and reuse of data |
|||
in a Work; |
|||
vi. database rights (such as those arising under Directive 96/9/EC of the |
|||
European Parliament and of the Council of 11 March 1996 on the legal |
|||
protection of databases, and under any national implementation |
|||
thereof, including any amended or successor version of such |
|||
directive); and |
|||
vii. other similar, equivalent or corresponding rights throughout the |
|||
world based on applicable law or treaty, and any national |
|||
implementations thereof. |
|||
|
|||
2. Waiver. To the greatest extent permitted by, but not in contravention |
|||
of, applicable law, Affirmer hereby overtly, fully, permanently, |
|||
irrevocably and unconditionally waives, abandons, and surrenders all of |
|||
Affirmer's Copyright and Related Rights and associated claims and causes |
|||
of action, whether now known or unknown (including existing as well as |
|||
future claims and causes of action), in the Work (i) in all territories |
|||
worldwide, (ii) for the maximum duration provided by applicable law or |
|||
treaty (including future time extensions), (iii) in any current or future |
|||
medium and for any number of copies, and (iv) for any purpose whatsoever, |
|||
including without limitation commercial, advertising or promotional |
|||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each |
|||
member of the public at large and to the detriment of Affirmer's heirs and |
|||
successors, fully intending that such Waiver shall not be subject to |
|||
revocation, rescission, cancellation, termination, or any other legal or |
|||
equitable action to disrupt the quiet enjoyment of the Work by the public |
|||
as contemplated by Affirmer's express Statement of Purpose. |
|||
|
|||
3. Public License Fallback. Should any part of the Waiver for any reason |
|||
be judged legally invalid or ineffective under applicable law, then the |
|||
Waiver shall be preserved to the maximum extent permitted taking into |
|||
account Affirmer's express Statement of Purpose. In addition, to the |
|||
extent the Waiver is so judged Affirmer hereby grants to each affected |
|||
person a royalty-free, non transferable, non sublicensable, non exclusive, |
|||
irrevocable and unconditional license to exercise Affirmer's Copyright and |
|||
Related Rights in the Work (i) in all territories worldwide, (ii) for the |
|||
maximum duration provided by applicable law or treaty (including future |
|||
time extensions), (iii) in any current or future medium and for any number |
|||
of copies, and (iv) for any purpose whatsoever, including without |
|||
limitation commercial, advertising or promotional purposes (the |
|||
"License"). The License shall be deemed effective as of the date CC0 was |
|||
applied by Affirmer to the Work. Should any part of the License for any |
|||
reason be judged legally invalid or ineffective under applicable law, such |
|||
partial invalidity or ineffectiveness shall not invalidate the remainder |
|||
of the License, and in such case Affirmer hereby affirms that he or she |
|||
will not (i) exercise any of his or her remaining Copyright and Related |
|||
Rights in the Work or (ii) assert any associated claims and causes of |
|||
action with respect to the Work, in either case contrary to Affirmer's |
|||
express Statement of Purpose. |
|||
|
|||
4. Limitations and Disclaimers. |
|||
|
|||
a. No trademark or patent rights held by Affirmer are waived, abandoned, |
|||
surrendered, licensed or otherwise affected by this document. |
|||
b. Affirmer offers the Work as-is and makes no representations or |
|||
warranties of any kind concerning the Work, express, implied, |
|||
statutory or otherwise, including without limitation warranties of |
|||
title, merchantability, fitness for a particular purpose, non |
|||
infringement, or the absence of latent or other defects, accuracy, or |
|||
the present or absence of errors, whether or not discoverable, all to |
|||
the greatest extent permissible under applicable law. |
|||
c. Affirmer disclaims responsibility for clearing rights of other persons |
|||
that may apply to the Work or any use thereof, including without |
|||
limitation any person's Copyright and Related Rights in the Work. |
|||
Further, Affirmer disclaims responsibility for obtaining any necessary |
|||
consents, permissions or other rights required for any use of the |
|||
Work. |
|||
d. Affirmer understands and acknowledges that Creative Commons is not a |
|||
party to this document and has no duty or obligation with respect to |
|||
this CC0 or use of the Work. |
@ -0,0 +1,12 @@ |
|||
Notice: all assets in the layouts directory and taglist directory, as well as submenu.png, belong to the AwesomeWM team and respective authors of these assets. |
|||
|
|||
The following assets in the titlebar directory are made specifically for reno98 and are licensed under CC0: |
|||
close_focus.png |
|||
close_normal.png |
|||
maximized_focus_inactive.png |
|||
maximized_normal_inactive.png |
|||
maximized_normal_active.png |
|||
minimize_focus.png |
|||
minimize_normal.png |
|||
|
|||
Other assets in the directory are kept from the default theme of AwesomeWM and belong to the respecitve authors. |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"list": [ |
|||
{"widget": "widgets.clientmenu.volume","vertical":false}, |
|||
{"widget": "widgets.clientmenu.controls"}, |
|||
{"widget": "widgets.clientmenu.buttons"} |
|||
], |
|||
"vertical":true |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"widgets.dismal":{ |
|||
"pos":"top_left", |
|||
"ignore_wibars":false |
|||
}, |
|||
"widgets.rootmenu":{}, |
|||
"widgets.lockscreen":{}, |
|||
"widgets.base.keypopup":{} |
|||
} |
@ -0,0 +1,5 @@ |
|||
{ |
|||
"widgets.lock.clock":{ |
|||
"format": "%a %b %d\n %H: %M" |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
{ |
|||
"list": [ |
|||
{"widget": "widgets.base.popuptitle", |
|||
"options":{ |
|||
"icon":"icons/reno98.png", |
|||
"title":"Serenity" |
|||
}, |
|||
"vertical":true |
|||
}, |
|||
{ |
|||
"list": [ |
|||
{"widget": "widgets.base.tagswitcher", |
|||
"screen":true |
|||
}, |
|||
{"multimenu":[ |
|||
{"widget": "widgets.rootmenu.controls"}, |
|||
{"widget": "widgets.xdgmenu", |
|||
"options": { |
|||
"exclude_category": [ |
|||
"Other" |
|||
] |
|||
} |
|||
} |
|||
]}, |
|||
{"widget": "widgets.rootmenu.buttons"} |
|||
], |
|||
"vertical": true |
|||
} |
|||
], |
|||
"vertical": false |
|||
} |
@ -0,0 +1,44 @@ |
|||
{ |
|||
"align": { |
|||
"left": [ |
|||
{ |
|||
"widget":"widgets.clientmenu", |
|||
"client":true |
|||
} |
|||
], |
|||
"center": [ |
|||
{ |
|||
"list":[ |
|||
{ |
|||
"draggable": true |
|||
}, |
|||
{ |
|||
"builtin": "titlewidget", |
|||
"client" : true, |
|||
"options": { |
|||
"align": "left" |
|||
} |
|||
}, |
|||
{ |
|||
"widget":"widgets.base.separator", |
|||
"vertical":true |
|||
} |
|||
] |
|||
} |
|||
], |
|||
"right": [ |
|||
{ |
|||
"builtin": "minimizebutton", |
|||
"client": true |
|||
}, |
|||
{ |
|||
"builtin": "maximizedbutton", |
|||
"client": true |
|||
}, |
|||
{ |
|||
"builtin": "closebutton", |
|||
"client": true |
|||
} |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
{ |
|||
"align": { |
|||
"left": [ |
|||
{ |
|||
"widget": "widgets.desktop.tasklist", |
|||
"screen": true |
|||
} |
|||
], |
|||
"center": [ |
|||
|
|||
], |
|||
"right": [ |
|||
{ |
|||
"widget": "widgets.desktop.launcher" |
|||
} |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
{ |
|||
"align": { |
|||
"left": [ |
|||
{ "widget": "widgets.desktop.soundclown" } |
|||
], |
|||
"center": [ |
|||
|
|||
], |
|||
"right": [ |
|||
{ "widget":"widgets.desktop.volume" }, |
|||
{ "widget": "widgets.desktop.notifications", |
|||
"screen": true |
|||
}, |
|||
{ "widget": "widgets.desktop.wallpapers", |
|||
"screen": true, |
|||
"options": { |
|||
"path": "$HOME/Pictures/Wallpapers" |
|||
} |
|||
}, |
|||
{ "widget": "widgets.base.layout" }, |
|||
{ "widget": "widgets.desktop.battery" }, |
|||
{ "widget": "widgets.base.systray" }, |
|||
{ "widget": "widgets.base.clock" } |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
Licensed under conditions of CC0 (https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt) |
|||
|
|||
To the extent possible under law, Yessiest (yessiest@memeware.net) has waived all copyright and related or neighboring rights to Reno icons |
After Width: 48 | Height: 48 | Size: 550 B |
After Width: 32 | Height: 32 | Size: 510 B |
After Width: 31 | Height: 32 | Size: 787 B |
After Width: 32 | Height: 32 | Size: 721 B |
After Width: 48 | Height: 48 | Size: 1.2 KiB |
After Width: 48 | Height: 48 | Size: 515 B |
After Width: 48 | Height: 48 | Size: 392 B |
After Width: 48 | Height: 48 | Size: 480 B |
After Width: 48 | Height: 48 | Size: 366 B |
After Width: 48 | Height: 48 | Size: 374 B |
After Width: 48 | Height: 48 | Size: 510 B |
After Width: 48 | Height: 48 | Size: 374 B |
After Width: 48 | Height: 48 | Size: 541 B |
After Width: 48 | Height: 48 | Size: 396 B |
After Width: 48 | Height: 48 | Size: 538 B |
After Width: 48 | Height: 48 | Size: 403 B |
After Width: 48 | Height: 48 | Size: 446 B |
After Width: 48 | Height: 48 | Size: 374 B |
After Width: 512 | Height: 512 | Size: 6.1 KiB |
After Width: 512 | Height: 512 | Size: 2.3 KiB |
After Width: 512 | Height: 512 | Size: 7.6 KiB |
After Width: 512 | Height: 512 | Size: 6.3 KiB |
After Width: 48 | Height: 48 | Size: 455 B |
After Width: 48 | Height: 48 | Size: 8.3 KiB |
After Width: 48 | Height: 48 | Size: 718 B |
After Width: 64 | Height: 64 | Size: 768 B |
After Width: 48 | Height: 48 | Size: 729 B |
After Width: 48 | Height: 48 | Size: 682 B |
After Width: 48 | Height: 48 | Size: 708 B |
After Width: 48 | Height: 48 | Size: 751 B |
After Width: 48 | Height: 48 | Size: 642 B |
After Width: 40 | Height: 35 | Size: 682 B |
After Width: 64 | Height: 64 | Size: 272 B |
After Width: 64 | Height: 64 | Size: 272 B |
After Width: 64 | Height: 64 | Size: 263 B |
After Width: 64 | Height: 64 | Size: 264 B |
After Width: 64 | Height: 64 | Size: 264 B |
After Width: 64 | Height: 64 | Size: 264 B |
After Width: 64 | Height: 64 | Size: 263 B |