Signed-off-by: Rainer Bendig <hexathos@mailbox.org>
This commit is contained in:
2020-02-25 23:55:12 +01:00
parent 5ba5cf9f2b
commit 9b3266a32e
33 changed files with 1551 additions and 0 deletions

111
awesome/bootstrap.lua Normal file
View File

@@ -0,0 +1,111 @@
-- Alexander Tsepkov, 2015
--
-- Collection of utilities for awesome WM to import/use awesome-zen platform better.
local awful = require("awful")
local naughty = require("naughty")
-- spawn a system tool/utility once, useful for those pesky system tray icons that keep stacking with themselves,
-- also can be used to load anything, including compositor, etc.
function spawn_once_name(name, command)
os.execute("pgrep " .. name .. " || " .. command .. " &")
end
function spawn_once(name)
spawn_once_name(name, name)
end
-- loads a widget
function load_widget(config)
require(config.widget)
-- if user defined a zenstate, assign it to the widget so it can respond accordingly
if config.zenstate then
widget.zenstate = config.zenstate
end
-- notify that the widget was loaded, if asked by rc.lua
if config.notify then
naughty.notify({
title = "Widget Loaded",
text = "Loaded " .. config.widget
})
end
return widget
end
-- load utility if not loaded yet, if loaded avoid loading it twice, print message if asked
function load_script(name, notify)
local success
local result
-- Which file? In rc/ or in lib/?
local path = awful.util.getdir("config") ..
"/" .. name .. ".lua"
-- Execute the RC/module file
success, result = pcall(function() return dofile(path) end)
if not success then
naughty.notify({
title = "Error Loading Script",
text = "When loading `" .. name .. "`, got the following error:\n" .. result,
preset = naughty.config.presets.critical
})
return print("E: error loading script: '" .. name .. "': " .. result)
elseif notify then
naughty.notify({
title = "Script Loaded",
text = "Loaded " .. name
})
end
return result
end
-- rounding error is pretty bad in lua
local EPSILON = 1e-3
-- compare two tables, because out of the box lua sucks
function equals(a, b)
if a == b then return true end
local aType = type(a)
local bType = type(b)
if aType == 'number' and bType == 'number' and math.abs(a - b) < EPSILON then return true end
if aType ~= bType then return false end
if aType ~= 'table' then return false end
local seen = {}
for key, val1 in pairs(a) do
local val2 = b[key]
if val2 == nil or equals(val1, val2) == false then
return false
end
seen[key] = true
end
for key, _ in pairs(b) do
if not seen[key] then return false end
end
return true
end
-- dump loa table to string
function dump(tbl, indent)
local output = ''
if not indent then indent = 0 end
for k, v in pairs(tbl) do
formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
output = output .. formatting .. "\n"
tprint(v, indent+1)
elseif type(v) == 'boolean' then
output = output .. formatting .. tostring(v) .. "\n"
else
output = output .. formatting .. v .. "\n"
end
end
return output
end

596
awesome/rc.lua Normal file
View File

@@ -0,0 +1,596 @@
-- If LuaRocks is installed, make sure that packages installed through it are
-- found (e.g. lgi). If LuaRocks is not installed, do nothing.
pcall(require, "luarocks.loader")
-- Standard awesome library
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
-- Widget and layout library
local wibox = require("wibox")
-- Theme handling library
local beautiful = require("beautiful")
-- Notification library
local naughty = require("naughty")
local menubar = require("menubar")
local hotkeys_popup = require("awful.hotkeys_popup")
-- Enable hotkeys help widget for VIM and other apps
-- when client with a matching name is opened:
require("awful.hotkeys_popup.keys")
-- Load Debian menu entries
local debian = require("debian.menu")
local has_fdo, freedesktop = pcall(require, "freedesktop")
-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, there were errors during startup!",
text = awesome.startup_errors })
end
-- Handle runtime errors after startup
do
local in_error = false
awesome.connect_signal("debug::error", function (err)
-- Make sure we don't go into an endless error loop
if in_error then return end
in_error = true
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, an error happened!",
text = tostring(err) })
in_error = false
end)
end
-- }}}
-- {{{ Variable definitions
-- Themes define colours, icons, font and wallpapers.
beautiful.init("~/.config/awesome/theme.lua")
-- This is used later as the default terminal and editor to run.
terminal = "x-terminal-emulator"
editor = "vim"
editor_cmd = terminal .. " -e " .. editor
-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"
-- Table of layouts to cover with awful.layout.inc, order matters.
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,
awful.layout.suit.fair.horizontal,
awful.layout.suit.spiral,
awful.layout.suit.spiral.dwindle,
awful.layout.suit.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier,
awful.layout.suit.corner.nw,
-- awful.layout.suit.corner.ne,
-- awful.layout.suit.corner.sw,
-- awful.layout.suit.corner.se,
}
-- }}}
-- {{{ Menu
-- Create a launcher widget and a main menu
myawesomemenu = {
{ "hotkeys", function() hotkeys_popup.show_help(nil, awful.screen.focused()) end },
{ "manual", terminal .. " -e man awesome" },
{ "edit config", editor_cmd .. " " .. awesome.conffile },
{ "restart", awesome.restart },
{ "quit", function() awesome.quit() end },
}
local menu_awesome = { "awesome", myawesomemenu, beautiful.awesome_icon }
local menu_terminal = { "open terminal", terminal }
if has_fdo then
mymainmenu = freedesktop.menu.build({
before = { menu_awesome },
after = { menu_terminal }
})
else
mymainmenu = awful.menu({
items = {
menu_awesome,
{ "Debian", debian.menu.Debian_menu.Debian },
menu_terminal,
}
})
end
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
menu = mymainmenu })
-- Menubar configuration
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
-- }}}
-- Keyboard map indicator and switcher
mykeyboardlayout = awful.widget.keyboardlayout()
-- {{{ Wibar
-- Create a textclock widget
mytextclock = wibox.widget.textclock()
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ modkey }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
)
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({ }, 3, function()
awful.menu.client_list({ theme = { width = 250 } })
end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(-1)
end))
local function set_wallpaper(s)
-- Wallpaper
if beautiful.wallpaper then
local wallpaper = beautiful.wallpaper
-- If wallpaper is a function, call it with the screen
if type(wallpaper) == "function" then
wallpaper = wallpaper(s)
end
gears.wallpaper.maximized(wallpaper, s, true)
end
end
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
screen.connect_signal("property::geometry", set_wallpaper)
awful.screen.connect_for_each_screen(function(s)
-- Wallpaper
set_wallpaper(s)
-- Each screen has its own tag table.
awful.tag({ "code", "web", "cli", "Files", "Zeugs" }, s, awful.layout.layouts[1])
-- Create a promptbox for each screen
s.mypromptbox = awful.widget.prompt()
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
-- Create a taglist widget
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
buttons = taglist_buttons
}
-- Create a tasklist widget
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = tasklist_buttons
}
-- Create the wibox
s.mywibox = awful.wibar({ position = "top", screen = s })
-- Add widgets to the wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
mylauncher,
s.mytaglist,
s.mypromptbox,
},
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
mykeyboardlayout,
wibox.widget.systray(),
mytextclock,
s.mylayoutbox,
},
}
end)
-- }}}
-- {{{ Mouse bindings
root.buttons(gears.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = gears.table.join(
awful.key({ modkey, }, "s", hotkeys_popup.show_help,
{description="show help", group="awesome"}),
awful.key({ modkey, }, "Left", awful.tag.viewprev,
{description = "view previous", group = "tag"}),
awful.key({ modkey, }, "Right", awful.tag.viewnext,
{description = "view next", group = "tag"}),
awful.key({ modkey, }, "Escape", awful.tag.history.restore,
{description = "go back", group = "tag"}),
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
end,
{description = "focus next by index", group = "client"}
),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
end,
{description = "focus previous by index", group = "client"}
),
awful.key({ modkey, }, "w", function () mymainmenu:show() end,
{description = "show main menu", group = "awesome"}),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
{description = "swap with next client by index", group = "client"}),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
{description = "swap with previous client by index", group = "client"}),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
{description = "focus the next screen", group = "screen"}),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
{description = "focus the previous screen", group = "screen"}),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
{description = "jump to urgent client", group = "client"}),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end,
{description = "go back", group = "client"}),
-- Standard program
awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
{description = "open a terminal", group = "launcher"}),
awful.key({ modkey, "Control" }, "r", awesome.restart,
{description = "reload awesome", group = "awesome"}),
awful.key({ modkey, "Shift" }, "q", awesome.quit,
{description = "quit awesome", group = "awesome"}),
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
{description = "increase master width factor", group = "layout"}),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
{description = "decrease master width factor", group = "layout"}),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
{description = "increase the number of master clients", group = "layout"}),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
{description = "decrease the number of master clients", group = "layout"}),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
{description = "increase the number of columns", group = "layout"}),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
{description = "decrease the number of columns", group = "layout"}),
awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
{description = "select next", group = "layout"}),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
{description = "select previous", group = "layout"}),
awful.key({ modkey, "Control" }, "n",
function ()
local c = awful.client.restore()
-- Focus restored client
if c then
c:emit_signal(
"request::activate", "key.unminimize", {raise = true}
)
end
end,
{description = "restore minimized", group = "client"}),
-- Prompt
awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
{description = "run prompt", group = "launcher"}),
awful.key({ modkey }, "x",
function ()
awful.prompt.run {
prompt = "Run Lua code: ",
textbox = awful.screen.focused().mypromptbox.widget,
exe_callback = awful.util.eval,
history_path = awful.util.get_cache_dir() .. "/history_eval"
}
end,
{description = "lua execute prompt", group = "awesome"}),
-- Menubar
awful.key({ modkey }, "p", function() menubar.show() end,
{description = "show the menubar", group = "launcher"})
)
clientkeys = gears.table.join(
awful.key({ modkey, }, "f",
function (c)
c.fullscreen = not c.fullscreen
c:raise()
end,
{description = "toggle fullscreen", group = "client"}),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
{description = "close", group = "client"}),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
{description = "toggle floating", group = "client"}),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
{description = "move to master", group = "client"}),
awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
{description = "move to screen", group = "client"}),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
{description = "toggle keep on top", group = "client"}),
awful.key({ modkey, }, "n",
function (c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end ,
{description = "minimize", group = "client"}),
awful.key({ modkey, }, "m",
function (c)
c.maximized = not c.maximized
c:raise()
end ,
{description = "(un)maximize", group = "client"}),
awful.key({ modkey, "Control" }, "m",
function (c)
c.maximized_vertical = not c.maximized_vertical
c:raise()
end ,
{description = "(un)maximize vertically", group = "client"}),
awful.key({ modkey, "Shift" }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c:raise()
end ,
{description = "(un)maximize horizontally", group = "client"})
)
-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it work on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, 9 do
globalkeys = gears.table.join(globalkeys,
-- View tag only.
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
tag:view_only()
end
end,
{description = "view tag #"..i, group = "tag"}),
-- Toggle tag display.
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
awful.tag.viewtoggle(tag)
end
end,
{description = "toggle tag #" .. i, group = "tag"}),
-- Move client to tag.
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:move_to_tag(tag)
end
end
end,
{description = "move focused client to tag #"..i, group = "tag"}),
-- Toggle tag on focused client.
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:toggle_tag(tag)
end
end
end,
{description = "toggle focused client on tag #" .. i, group = "tag"})
)
end
clientbuttons = gears.table.join(
awful.button({ }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
end),
awful.button({ modkey }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ modkey }, 3, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.resize(c)
end)
)
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
-- Rules to apply to new clients (through the "manage" signal).
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = awful.client.focus.filter,
raise = true,
keys = clientkeys,
buttons = clientbuttons,
screen = awful.screen.preferred,
placement = awful.placement.no_overlap+awful.placement.no_offscreen
}
},
{ rule = { class = "Atom" },
properties = { tag = 'code', screen=1 } },
{ rule = { class = "Firefox" },
properties = { tag = 'web', screen=2 } },
{ rule = { instance = "x-terminal-emulator" },
properties = { tag = 'cli', floating=true, screen=2 } },
-- Floating clients.
{ rule_any = {
instance = {
"DTA", -- Firefox addon DownThemAll.
"copyq", -- Includes session name in class.
"pinentry",
},
class = {
"Arandr",
"Blueman-manager",
"Gpick",
"Kruler",
"MessageWin", -- kalarm.
"Sxiv",
"Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
"Wpa_gui",
"veromix",
"xtightvncviewer"},
-- Note that the name property shown in xprop might be set slightly after creation of the client
-- and the name shown there might not match defined rules here.
name = {
"Event Tester", -- xev.
},
role = {
"AlarmWindow", -- Thunderbird's calendar.
"ConfigManager", -- Thunderbird's about:config.
"pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
}
}, properties = { floating = true }},
-- Add titlebars to normal clients and dialogs
{ rule_any = {type = { "normal", "dialog" }
}, properties = { titlebars_enabled = true }
},
-- Set Firefox to always map on the tag named "2" on screen 1.
-- { rule = { class = "Firefox" },
-- properties = { screen = 1, tag = "2" } },
}
-- }}}
-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c)
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- if not awesome.startup then awful.client.setslave(c) end
if awesome.startup
and not c.size_hints.user_position
and not c.size_hints.program_position then
-- Prevent clients from being unreachable after screen count changes.
awful.placement.no_offscreen(c)
end
end)
-- Add a titlebar if titlebars_enabled is set to true in the rules.
client.connect_signal("request::titlebars", function(c)
-- buttons for the titlebar
local buttons = gears.table.join(
awful.button({ }, 1, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ }, 3, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.resize(c)
end)
)
awful.titlebar(c) : setup {
{ -- Left
awful.titlebar.widget.iconwidget(c),
buttons = buttons,
layout = wibox.layout.fixed.horizontal
},
{ -- Middle
{ -- Title
align = "center",
widget = awful.titlebar.widget.titlewidget(c)
},
buttons = buttons,
layout = wibox.layout.flex.horizontal
},
{ -- Right
awful.titlebar.widget.floatingbutton (c),
awful.titlebar.widget.maximizedbutton(c),
awful.titlebar.widget.stickybutton (c),
awful.titlebar.widget.ontopbutton (c),
awful.titlebar.widget.closebutton (c),
layout = wibox.layout.fixed.horizontal()
},
layout = wibox.layout.align.horizontal
}
end)
-- Enable sloppy focus, so that focus follows mouse.
client.connect_signal("mouse::enter", function(c)
c:emit_signal("request::activate", "mouse_enter", {raise = false})
end)
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
dofile(os.getenv("HOME") .. "/.config/awesome/bootstrap.lua")
spawn_once_name("numlockx", "numlockx on")
spawn_once("compton")
spawn_once("volumeicon")
-- }}}

137
awesome/theme.lua Normal file
View File

@@ -0,0 +1,137 @@
---------------------------
-- Default awesome theme --
---------------------------
local theme_assets = require("beautiful.theme_assets")
local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
local gfs = require("gears.filesystem")
local themes_path = gfs.get_themes_dir()
local theme = {}
theme.font = "Ubuntu 8"
theme.bg_normal = "#222222"
theme.bg_focus = "#535d6c"
theme.bg_urgent = "#ff0000"
theme.bg_minimize = "#444444"
theme.bg_systray = theme.bg_normal
theme.fg_normal = "#aaaaaa"
theme.fg_focus = "#ffffff"
theme.fg_urgent = "#ffffff"
theme.fg_minimize = "#ffffff"
theme.useless_gap = dpi(0)
theme.border_width = dpi(1)
theme.border_normal = "#000000"
theme.border_focus = "#222222"
theme.border_marked = "#91231c"
-- There are other variable sets
-- overriding the default one when
-- defined, the sets are:
-- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile]
-- tasklist_[bg|fg]_[focus|urgent]
-- titlebar_[bg|fg]_[normal|focus]
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
-- prompt_[fg|bg|fg_cursor|bg_cursor|font]
-- hotkeys_[bg|fg|border_width|border_color|shape|opacity|modifiers_fg|label_bg|label_fg|group_margin|font|description_font]
-- Example:
--theme.taglist_bg_focus = "#ff0000"
theme.tasklist_bg_normal = "#000000"
theme.tasklist_bg_focus = "#111111"
theme.tasklist_fg = "#fcfcfc"
theme.titlebar_bg = "#000000"
theme.titlebar_fg = "#fcfcfc"
-- Generate taglist squares:
local taglist_square_size = dpi(4)
theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
taglist_square_size, theme.fg_normal
)
theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
taglist_square_size, theme.fg_normal
)
-- Variables set for theming notifications:
-- notification_font
-- notification_[bg|fg]
-- notification_[width|height|margin]
-- notification_[border_color|border_width|shape|opacity]
-- Variables set for theming the menu:
-- menu_[bg|fg]_[normal|focus]
-- menu_[border_color|border_width]
theme.menu_submenu_icon = themes_path.."default/submenu.png"
theme.menu_height = dpi(15)
theme.menu_width = dpi(100)
-- You can add as many variables as
-- you wish and access them by using
-- beautiful.variable in your rc.lua
--theme.bg_widget = "#cc0000"
-- Define the image to load
theme.titlebar_close_button_normal = themes_path.."default/titlebar/close_normal.png"
theme.titlebar_close_button_focus = themes_path.."default/titlebar/close_focus.png"
theme.titlebar_minimize_button_normal = themes_path.."default/titlebar/minimize_normal.png"
theme.titlebar_minimize_button_focus = themes_path.."default/titlebar/minimize_focus.png"
theme.titlebar_ontop_button_normal_inactive = themes_path.."default/titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive = themes_path.."default/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_active = themes_path.."default/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_active = themes_path.."default/titlebar/ontop_focus_active.png"
theme.titlebar_sticky_button_normal_inactive = themes_path.."default/titlebar/sticky_normal_inactive.png"
theme.titlebar_sticky_button_focus_inactive = themes_path.."default/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_active = themes_path.."default/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_active = themes_path.."default/titlebar/sticky_focus_active.png"
theme.titlebar_floating_button_normal_inactive = themes_path.."default/titlebar/floating_normal_inactive.png"
theme.titlebar_floating_button_focus_inactive = themes_path.."default/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_active = themes_path.."default/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active = themes_path.."default/titlebar/floating_focus_active.png"
theme.titlebar_maximized_button_normal_inactive = themes_path.."default/titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive = themes_path.."default/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active = themes_path.."default/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_active = themes_path.."default/titlebar/maximized_focus_active.png"
theme.wallpaper = "~/Bilder/paintpowder_1.jpg"
-- You can use your own layout icons like this:
theme.layout_fairh = themes_path.."default/layouts/fairhw.png"
theme.layout_fairv = themes_path.."default/layouts/fairvw.png"
theme.layout_floating = themes_path.."default/layouts/floatingw.png"
theme.layout_magnifier = themes_path.."default/layouts/magnifierw.png"
theme.layout_max = themes_path.."default/layouts/maxw.png"
theme.layout_fullscreen = themes_path.."default/layouts/fullscreenw.png"
theme.layout_tilebottom = themes_path.."default/layouts/tilebottomw.png"
theme.layout_tileleft = themes_path.."default/layouts/tileleftw.png"
theme.layout_tile = themes_path.."default/layouts/tilew.png"
theme.layout_tiletop = themes_path.."default/layouts/tiletopw.png"
theme.layout_spiral = themes_path.."default/layouts/spiralw.png"
theme.layout_dwindle = themes_path.."default/layouts/dwindlew.png"
theme.layout_cornernw = themes_path.."default/layouts/cornernww.png"
theme.layout_cornerne = themes_path.."default/layouts/cornernew.png"
theme.layout_cornersw = themes_path.."default/layouts/cornersww.png"
theme.layout_cornerse = themes_path.."default/layouts/cornersew.png"
-- Generate Awesome icon:
theme.awesome_icon = theme_assets.awesome_icon(
theme.menu_height, theme.bg_focus, theme.fg_focus
)
-- Define the icon theme for application icons. If not set then the icons
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = nil
return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

48
awesome/utils/README.md Normal file
View File

@@ -0,0 +1,48 @@
Utils
-----
This directory contains a list of convenience utilities for awesome WM.
## remember_positions.lua
By default, awesome WM doesn't remember positions of your floating windows when you cycle through different layouts. This can be a problem both to the users who accidentally switched layouts as well as those wishing to temporarily rearrange windows and come back to original layout once they're done with their work. It's also a problem for those reloading their awesome configuration, since it forgets original window positions as well. This script fixes that. To take advantage of it, install it by adding the following line to your `rc.lua`:
load_script("utils/remember_positions", true)
## ondemand_tile.lua
Move floating window into any corner/tile via convenient shortcuts, i.e:
local positions = require('utils.ondemand_tile')
-- later in code
awful.key({ modkey, "Shift" }, "Down", function (c) position.at('bottom', c) end),
awful.key({ modkey, "Shift" }, "Left", function (c) position.at('left', c) end),
awful.key({ modkey, "Shift" }, "Right", function (c) position.at('right', c) end),
awful.key({ modkey, "Shift" }, "Up", function (c) position.at('top', c) end),
Positions can be specified as a table `{x, y, w, h}` or as a string to identify one of existing presets:
left
right
top
bottom
top_left
top_right
bottom_left
bottom_right
fullscreen
center_pad
left_third
middle_third
right_third
left_two_thirds
right_two_thirds
middle_two_thirds
There is also a compound-resize option in positions module. It stacks previous tiling actions on top of each other in an intuitive manner. For example, when the window is on the `left` half of the screen, sending `down` event will move it to `bottom_left` position. In this way you can iterate through most of the presets in an intuitive manner with just 4 shortcuts:
awful.key({ modkey, "Shift" }, "Down", function (c) position.compound('bottom', c) end),
awful.key({ modkey, "Shift" }, "Left", function (c) position.compound('left', c) end),
awful.key({ modkey, "Shift" }, "Right", function (c) position.compound('right', c) end),
awful.key({ modkey, "Shift" }, "Up", function (c) position.compound('top', c) end),

View File

@@ -0,0 +1,259 @@
-- Alexander Tsepkov, 2015
--
-- Logic to compute window positions in order to tile them on the fly, even when in floating layout
local awful = require("awful")
local position = {}
local capi =
{
client = client,
mouse = mouse,
screen = screen,
wibox = wibox,
awesome = awesome,
}
local coords = {
left = {
x = 0,
y = 0,
h = 1,
w = 1 / 2
},
right = {
x = 1 / 2,
y = 0,
h = 1,
w = 1 / 2
},
top = {
x = 0,
y = 0,
h = 1 / 2,
w = 1,
},
bottom = {
x = 0,
y = 1 / 2,
h = 1 / 2,
w = 1
},
top_left = {
x = 0,
y = 0,
h = 1 / 2,
w = 1 / 2
},
top_right = {
x = 1 / 2,
y = 0,
h = 1 / 2,
w = 1 / 2
},
bottom_left = {
x = 0,
y = 1 / 2,
h = 1 / 2,
w = 1 / 2
},
bottom_right = {
x = 1 / 2,
y = 1 / 2,
h = 1 / 2,
w = 1 / 2
},
fullscreen = {
x = 0,
y = 0,
h = 1,
w = 1
},
center_pad = {
x = 1 / 8,
y = 1 / 8,
h = (1 / 4) * 3,
w = (1 / 4) * 3
},
left_third = {
x = 0,
y = 0,
h = 1,
w = 1 / 3
},
middle_third = {
x = (1 / 3),
y = 0,
h = 1,
w = 1 / 3
},
left_two_thirds = {
x = 0,
y = 0,
h = 1,
w = (1 / 3) * 2
},
right_third = {
x = ((1 / 3) * 2),
y = 0,
h = 1,
w = 1 / 3
},
right_two_thirds = {
x = (1 / 3),
y = 0,
h = 1,
w = (1 / 3) * 2
},
middle_two_thirds = {
x = (1 / 6),
y = 0,
h = 1,
w = (1 / 3) * 2
}
}
-- takes geometry, client window, and parent window (uses entire screen as parent window if omitted)
-- resizes client window based on geometry in relation to parent window. If geometry is a string, uses
-- one of existing geometry presets, if geometry is a table, reads x, y, w, h values from it to determine
-- position and size.
function position.at(geometry, c, p)
if type(geometry) == "string" then
geometry = coords[geometry]
end
local c = c or capi.client.focus
local c_geometry = c:geometry()
local screen = c.screen or awful.screen.getbycoord(c_geometry.x, c_geometry.y)
local s_geometry
if p then
s_geometry = p:geometry()
else
-- s_geometry = capi.screen[screen].geometry
s_geometry = capi.screen[screen].workarea
end
return c:geometry({
x = s_geometry.x + s_geometry.width * geometry.x,
y = s_geometry.y + s_geometry.height * geometry.y,
width = s_geometry.width * geometry.w,
height = s_geometry.height * geometry.h
})
end
-- A smarter version of the above function, computes existing window state to see if it already matches
-- a position above, and stacks direction intuitively
-- Direction should be a string identifying 1 of 4 directions: left, right, top, bottom
function position.compound(direction, c, p)
local c = c or capi.client.focus
local c_geometry = c:geometry()
local screen = c.screen or awful.screen.getbycoord(c_geometry.x, c_geometry.y)
local s_geometry
if p then
s_geometry = p:geometry()
else
s_geometry = capi.screen[screen].workarea
end
empirical_geometry = {
x = (c_geometry.x - s_geometry.x) / s_geometry.width,
y = (c_geometry.y - s_geometry.y) / s_geometry.height,
h = c_geometry.height / s_geometry.height,
w = c_geometry.width / s_geometry.width
}
-- figure out if we're already in one of the preset states
local state = nil
for key, val in pairs(coords) do
if equals(val, empirical_geometry) then
state = key
break
end
end
-- local naughty = require('naughty')
-- naughty.notify({text=dump(empirical_geometry)})
local geometry
if state == nil then
-- just starting, no stack yet
geometry = coords[direction]
elseif direction == 'left' then
-- stacking left
if state == 'left' then
geometry = coords['left_third']
elseif state == 'top' then
geometry = coords['top_left']
elseif state == 'bottom' then
geometry = coords['bottom_left']
elseif state == 'right' then
geometry = coords['middle_third']
elseif state == 'middle_third' or state == 'center_pad' then
geometry = coords['left']
elseif state == 'right_third' then
geometry = coords['right']
elseif state == 'top_right' then
geometry = coords['top']
elseif state == 'bottom_right' then
geometry = coords['bottom']
end
elseif direction == 'right' then
-- stacking right
if state == 'right' then
geometry = coords['right_third']
elseif state == 'top' then
geometry = coords['top_right']
elseif state == 'bottom' then
geometry = coords['bottom_right']
elseif state == 'left' then
geometry = coords['middle_third']
elseif state == 'middle_third' or state == 'center_pad' then
geometry = coords['right']
elseif state == 'left_third' then
geometry = coords['left']
elseif state == 'top_left' then
geometry = coords['top']
elseif state == 'bottom_left' then
geometry = coords['bottom']
end
elseif direction == 'top' then
-- stacking up
if state == 'left' or state == 'left_third' then
geometry = coords['top_left']
elseif state == 'bottom' or state == 'middle_third' then
geometry = coords['center_pad']
elseif state == 'right' or state == 'right_third' then
geometry = coords['top_right']
elseif state == 'center_pad' then
geometry = coords['top']
elseif state == 'bottom_left' then
geometry = coords['left']
elseif state == 'bottom_right' then
geometry = coords['right']
end
elseif direction == 'bottom' then
-- stacking down
if state == 'left' or state == 'left_third' then
geometry = coords['bottom_left']
elseif state == 'top' or state == 'middle_third' then
geometry = coords['center_pad']
elseif state == 'right' or state == 'right_third' then
geometry = coords['bottom_right']
elseif state == 'center_pad' then
geometry = coords['bottom']
elseif state == 'top_left' then
geometry = coords['left']
elseif state == 'top_right' then
geometry = coords['right']
end
end
if geometry == nil then return c:geometry() end
return c:geometry({
x = s_geometry.x + s_geometry.width * geometry.x,
y = s_geometry.y + s_geometry.height * geometry.y,
width = s_geometry.width * geometry.w,
height = s_geometry.height * geometry.h
})
end
return position

View File

@@ -0,0 +1,33 @@
-- Alexander Tsepkov, 2015
--
-- By default awesome forgets window positions when you switch between layouts, this is especially a problem
-- for floating layout, which awesome wasn't designed to handle gracefully out of the box. This tidbit of code
-- fixes that issue by remembering window positions in floating layout and coming back to the same positions when
-- you return to floating layout from a tiling one.
local awful = require("awful")
floatgeoms = {}
tag.connect_signal("property::layout", function(t)
for k, c in ipairs(t:clients()) do
if ((awful.layout.get(mouse.screen) == awful.layout.suit.floating)
or (awful.client.floating.get(c) == true)) then
c:geometry(floatgeoms[c.window])
end
end
client.connect_signal("unmanage", function(c) floatgeoms[c.window] = nil end)
end)
client.connect_signal("property::geometry", function(c)
if ((awful.layout.get(mouse.screen) == awful.layout.suit.floating) or (awful.client.floating.get(c) == true)) then
floatgeoms[c.window] = c:geometry()
end
end)
client.connect_signal("unmanage", function(c) floatgeoms[c.window] = nil end)
client.connect_signal("manage", function(c)
if ((awful.layout.get(mouse.screen) == awful.layout.suit.floating) or (awful.client.floating.get(c) == true)) then
floatgeoms[c.window] = c:geometry()
end
end)

103
awesome/widgets/README.md Normal file
View File

@@ -0,0 +1,103 @@
Widgets
-------
This directory contains a list of widget that you can use in your theme.
## Existing Widgets
### Temperature
A widget that shows current CPU temperature and changes color as the temperature gets higher. It even warns the user when the temperature reaches critical levels.
![Normal](https://github.com/atsepkov/awesome-zen/blob/master/widgets/temperature/1.png)
![High](https://github.com/atsepkov/awesome-zen/blob/master/widgets/temperature/2.png)
![Dangerous](https://github.com/atsepkov/awesome-zen/blob/master/widgets/temperature/3.png)
![Critical](https://github.com/atsepkov/awesome-zen/blob/master/widgets/temperature/4.png)
In case you don't notice the red icon, the widget will grab your attention via a message:
![Critical Notification](https://github.com/atsepkov/awesome-zen/blob/master/widgets/temperature/notification_example.png)
To use this widget, simply add the following to your `rc.lua`:
myTempWidget = load_widget({
widget = "widgets.temperature.widget"
})
And then add the widget to your wibox (here is an example, although your code may look different):
right_layout:add(myTempWidget)
You could also add an optional callback to `load_widget` that determines when to show/hide the temperature widget:
myTempWidget = load_widget({
widget = "widgets.temperature.temp",
zenstate = function(t) if t < 60 then return true end return false end,
})
The above example will hide temperature widget when the temperature falls below 60 degrees and show it when it goes above.
### Volume
Allow user to control volume via the keyboard volume keys and see feedback. This widget is compatible with pulseaudio and automatically gets volume of the relevant output (i.e. if you've switched to HDMI, you'll be controlling the HDMI volume).
![Max Volume](https://github.com/atsepkov/awesome-zen/blob/master/widgets/volume/1.png)
![Lower Volume](https://github.com/atsepkov/awesome-zen/blob/master/widgets/volume/2.png)
![Muted](https://github.com/atsepkov/awesome-zen/blob/master/widgets/volume/3.png)
Install this widget the usual way:
volume = load_widget({
widget = "widgets.volume.widget"
})
Since this widget has no icon, `zenstate` does nothing (I use Maato's volumeicon for icon instead, which works great as an icon but not so well with actual audio controls, which is where this widget excels). To map this widget to your volume keys, add the following in your rc.lua clientkeys section:
awful.key({ }, "XF86AudioRaiseVolume", volume.up),
awful.key({ }, "XF86AudioLowerVolume", volume.down),
awful.key({ }, "XF86AudioMute", volume.toggle),
## Memory Usage
Display memory usage as a percentage and show more detail, including biggest-offending processes when user hovers over. Like temperature widget, color adjusts automatically based on how much memory you use and informs you when the status reaches critical.
![Normal](https://github.com/atsepkov/awesome-zen/blob/master/widgets/memory/1.png)
![High](https://github.com/atsepkov/awesome-zen/blob/master/widgets/memory/2.png)
![Dangerous](https://github.com/atsepkov/awesome-zen/blob/master/widgets/memory/3.png)
As with temperature widget, the widget will notify you when the memory usage gets uncomfortably high but before the point of no return:
![Critical](https://github.com/atsepkov/awesome-zen/blob/master/widgets/memory/notification_example.png)
Hover example:
![Hover](https://github.com/atsepkov/awesome-zen/blob/master/widgets/memory/hover_example.png)
To use this widget, simply add the following to your `rc.lua`:
memoryWidget = load_widget({
widget = "widgets.memory.widget"
})
As with temperature widget, this widget accepts a zenstate parameter telling it when to hide, if ever.
## Adding New Widgets
Interested in adding your own widget to `Zen` library? Great!
Make sure your widget follows these `Zen` guidelines, otherwise your pull request may get rejected:
- Your widget must embrace `Zen` philosophy (it must be as minimalistic as possible, remember that "less is more", don't confuse user with excessive options and prompts, don't take up unnecessary real estate on the screen, try to minimize the number of dependencies your widget brings in)
- Your widget must catch all errors that it could generate (It doesn't matter if `awesome` or `bash` is at fault, if as a result of adding your widget user will start seeing occasional red notifications from awesome, your widget will be rejected)
- Your widget must not be dominated by an existing `Zen` widget or perform identical functionality (there is no reason to have 50 volume widgets, for example, they just add clutter and confusion, but if you think your widget is superior to an existing widget by all means submit it). I don't want this repository to become another widget graveyard.
- Your widget must follow `Zen` architecture, it must conform to the `load_widget` options. That basically means the following:
- You must include a handler for user-defined `zenstate` callback, a function that determines when the widget can hide or change state (you can define inputs for the callback and document them in this README, the function will return a boolean identifying true (show) and false (hide) states)
- Your widget must be named `widget` by the end of your script, since this is what `load_widget` script assumes as the name and returns to the user
- You must include a brief description and screenshot or two of your widget, awesome WM is cluttered with undocumented widgets that users have no way of previewing before installing. Once again, I don't want this repository to become another widget graveyard.
## To Add
- CPU Usage
- Audio Player
- Calendar
- Battery
- Network
- Define/Search Word

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

15
awesome/widgets/memory/mem.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Copyright 2015 Alexander Tsepkov
#
colorize_title='1s/\(.*\)/<span foreground="#669900"><b>\1<\/b><\/span>/'
case "$1" in
simple)
free | grep Mem | awk '{printf("%.1f\n", $3/$2 * 100)}'
;;
summary)
free -h | sed -e "$colorize_title"
echo ''
ps -eo pid:6,time:10,pmem:6,rss:8,comm --sort -rss | head -n 20 | sed -e "$colorize_title"
;;
esac

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,85 @@
-- Alexander Tsepkov, 2015
--
-- Memory Monitor for awesome that changes color as the memory usage goes up
-- dependency: FontAwesome
local awful = require("awful")
local wibox = require("wibox")
local naughty = require("naughty")
local last_id
widget = wibox.widget.textbox()
function testmem()
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/memory/mem.sh simple")
if fd then
-- occasionally awesome craps out for no reason running the operation
-- and fd is nil, do nothing in that case (aside from ignoring the value
-- rather than throwing an error), it will fix itself next run
local memstr = fd:read("*all")
local mem = tonumber(memstr)
fd:close()
local color
local font = "<span font='FontAwesome 8' "
if mem > 94 then
color = font .. "color='#FF0000'>"
last_id = naughty.notify({
title = "High Memory Usage",
text = "Consider closing some processes to prevent miserable experience.",
preset = naughty.config.presets.critical,
replaces_id = last_id,
icon = os.getenv("HOME") .. "/.config/awesome/widgets/memory/" .. "max.png"
}).id
elseif mem > 85 then
color = font .. "color='#FF8000'>"
elseif mem > 75 then
color = font .. "color='#F5F549'>"
else
color = font .. "color='#669900'>"
end
if widget.zenstate ~= nil then
if widget.zenstate(mem) then
return ""
end
end
return color .. "" .. mem .. " </span>"
end
return "N/A " -- something failed
end
-- to display on hover event
local summary = nil
function show_tooltip()
local font = 'monospace 8'
local text_color = '#FFFFFF'
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/memory/mem.sh summary")
local str = fd:read("*all")
local content = string.format('<span font="%s" foreground="%s">%s</span>', font, text_color, str)
summary = naughty.notify({
-- title = "Memory Usage",
text = content,
timeout = 0,
hover_timeout = 0.5,
width = 60*8
})
end
function hide_tooltip()
if summary ~= nil then
naughty.destroy(summary)
end
end
widget:set_markup(testmem())
widget:connect_signal("mouse::enter", show_tooltip)
widget:connect_signal("mouse::leave", hide_tooltip)
-- update every 30 secs
memtimer = timer({ timeout = 30 })
memtimer:connect_signal("timeout", function()
widget:set_markup(testmem())
end)
memtimer:start()

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Copyright 2015 Alexander Tsepkov
sensors | awk '/^Core/ {t=substr($3,2,4);if (t>max) max=t} END {print max}'

View File

@@ -0,0 +1,56 @@
-- Alexander Tsepkov, 2015
--
-- Temperature Monitor for awesome that changes color as the temperature goes up
-- dependency: FontAwesome
local wibox = require("wibox")
local naughty = require("naughty")
local last_id
widget = wibox.widget.textbox()
function testtemps()
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/temperature/sensors.sh")
if fd then
-- occasionally awesome craps out for no reason running the operation
-- and fd is nil, do nothing in that case (aside from ignoring the value
-- rather than throwing an error), it will fix itself next run
local tempstr = fd:read("*all")
local temp = tonumber(tempstr)
fd:close()
local color
local font = "<span font='FontAwesome 8' "
if temp > 90 then
color = font .. "color='#FF0000'>"
last_id = naughty.notify({
title = "Temperature Critical",
text = "CPU temperature is dangerously hot, turn it off to prevent damage.",
preset = naughty.config.presets.critical,
replaces_id = last_id,
icon = os.getenv("HOME") .. "/.config/awesome/widgets/temperature/" .. "hot.png"
}).id
elseif temp > 80 then
color = font .. "color='#FF8000'>"
elseif temp > 70 then
color = font .. "color='#F5F549'>"
else
color = font .. "color='#669900'>"
end
if widget.zenstate ~= nil then
if widget.zenstate(temp) then
return ""
end
end
return color .. "" .. temp .. " </span>"
end
return "N/A " -- something failed
end
widget:set_markup(testtemps())
-- update every 30 secs
temptimer = timer({ timeout = 30 })
temptimer:connect_signal("timeout", function() widget:set_markup(testtemps()) end)
temptimer:start()

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

View File

@@ -0,0 +1,52 @@
#!/bin/bash
# Copyright 2015 Alexander Tsepkov
#SINK_NAME="alsa_output.pci-0000_00_1b.0.analog-stereo"
#SINK_NAME="alsa_output.pci-0000_00_1b.0.hdmi-stereo"
SOUND_DEVICE=`pacmd dump | grep -P "^set-card-profile" | grep stereo | cut -d: -f2 | cut -d+ -f1`
SINK_NAME="alsa_output.pci-0000_00_1b.0.$SOUND_DEVICE"
VOL_STEP="0x01000"
MUTE_STATE=`pacmd dump | grep -P "^set-sink-mute $SINK_NAME\s+" | perl -p -i -e 's/.+\s(yes|no)$/$1/'`
VOL_NOW=`pacmd dump | grep -P "^set-sink-volume $SINK_NAME\s+" | perl -p -i -e 's/.+\s(.x.+)$/$1/'`
VOL_MAX=$((0x10000))
case "$1" in
plus)
if [ $MUTE_STATE = yes ]; then
echo "Muted"
else
VOL_NEW=$((VOL_NOW + VOL_STEP))
if [ $VOL_NEW -gt $VOL_MAX ]
then
VOL_NEW=$VOL_MAX
fi
pactl set-sink-volume $SINK_NAME `printf "0x%X" $VOL_NEW`
echo "$((100*VOL_NEW / VOL_MAX))%"
fi
;;
minus)
if [ $MUTE_STATE = yes ]; then
echo "Muted"
else
VOL_NEW=$((VOL_NOW - VOL_STEP))
if [ $(($VOL_NEW)) -lt $((0x00000)) ]
then
VOL_NEW=$((0x00000))
fi
pactl set-sink-volume $SINK_NAME `printf "0x%X" $VOL_NEW`
echo "$((100*VOL_NEW / VOL_MAX))%"
fi
;;
mute)
if [ $MUTE_STATE = no ]; then
pactl set-sink-mute $SINK_NAME 1
echo "Muted"
elif [ $MUTE_STATE = yes ]; then
pactl set-sink-mute $SINK_NAME 0
echo "$((100*VOL_NOW / VOL_MAX))%"
fi
esac

View File

@@ -0,0 +1,52 @@
-- Alexander Tsepkov, 2015
--
-- Minimalistic Volume Widget that works with multiple output sources
-- dependency: FontAwesome
local wibox = require("wibox")
local naughty = require("naughty")
local last_id
local vol_muted
function mixercommand(command)
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/pa-vol.sh " .. command)
local status = fd:read("*all")
fd:close()
local pic = os.getenv("HOME") .. "/.config/awesome/widgets/volume/"
local value
if status == "Muted\n" then
pic = pic .. "audio-muted.png"
else
-- dividing by 26 is a little cheat to prevent overflow on 100%
value = math.floor(tonumber(string.sub(status:gsub("%s+$", ""), 0, -2)) / 26)
pic = pic .. "audio-" .. value .. ".png"
end
last_id = naughty.notify({
title = "Volume",
text = status,
replaces_id = last_id,
icon = pic,
}).id
end
function volumeup()
mixercommand("plus")
end
function volumedown()
mixercommand("minus")
end
function volumetoggle()
mixercommand("mute")
end
-- zenstate not applicable bescause there is no volume icon for this widget at all
-- this widget doesn't have an icon, I use volumeicon instead but I prefer the messages/control through this
-- widget instead
widget = {
up = volumeup,
down = volumedown,
toggle = volumetoggle,
}