summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Keller <tjk@tjkeller.xyz>2024-10-18 21:49:17 -0500
committerTim Keller <tjk@tjkeller.xyz>2024-10-18 21:49:17 -0500
commit923eb46350b1102749eb05cd2120c96cc6a715d0 (patch)
tree811da20b4195d4b5c65c8ac0090982a4a23f6a7d
downloadawesome-923eb46350b1102749eb05cd2120c96cc6a715d0.tar.xz
awesome-923eb46350b1102749eb05cd2120c96cc6a715d0.zip
initial commit
-rw-r--r--bar.lua154
-rw-r--r--func/noborders.lua20
-rw-r--r--func/sloppyfocus.lua4
-rw-r--r--func/tagnames.lua51
-rw-r--r--func/warpcursor.lua22
-rw-r--r--hosts/libreX60.lua4
-rw-r--r--keybindings.lua176
-rw-r--r--layouts.lua27
-rw-r--r--lib/errors.lua35
-rw-r--r--lib/manage.lua15
-rw-r--r--lib/screen.lua8
-rw-r--r--mouse.lua47
-rw-r--r--rc.lua31
-rw-r--r--rules.lua56
-rw-r--r--theme.lua39
-rw-r--r--todo24
-rw-r--r--util/seasonalwallpaper.lua26
-rw-r--r--util/widgets.lua19
-rw-r--r--widgets/audio.lua21
-rw-r--r--widgets/battery.lua24
-rw-r--r--widgets/button.lua33
-rw-r--r--widgets/classiclayouts.lua64
-rw-r--r--widgets/cpu.lua38
-rw-r--r--widgets/pavolctld.lua104
-rw-r--r--widgets/ram.lua34
-rw-r--r--widgets/temperature.lua26
26 files changed, 1102 insertions, 0 deletions
diff --git a/bar.lua b/bar.lua
new file mode 100644
index 0000000..c03466e
--- /dev/null
+++ b/bar.lua
@@ -0,0 +1,154 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local beautiful = require("beautiful")
+
+-- load widgets
+--local mylauncher = require("widgets.button")
+local widget_cpu_usage = require("widgets.cpu")
+local widget_ram_usage = require("widgets.ram")
+local widget_temperature = require("widgets.temperature")
+local widget_battery = require("widgets.battery")
+local classiclayoutbox = require("widgets.classiclayouts")
+local volume_control = require("widgets.pavolctld")
+local widget_volume = volume_control.textbox
+
+-- store widgets here
+local spacing = 8
+local separator = { widget = wibox.widget.separator, opacity = 0 }
+
+local widgets = {
+ spacing = spacing, -- constant
+ layoutlist = wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ buttons = layout_buttons,
+ wibox.container.margin(
+ classiclayoutbox(s),
+ spacing, spacing, 0, 0
+ ),
+ },
+ taglist = function(s) return awful.widget.taglist {
+ screen = s,
+ filter = awful.widget.taglist.filter.noempty,
+ buttons = taglist_buttons,
+ } end,
+ tasklist = function(s) return wibox.widget {
+ layout = wibox.layout.align.horizontal,
+ expand = "outside",
+ separator,
+ awful.widget.tasklist {
+ screen = s,
+ filter = awful.widget.tasklist.filter.focused,
+ buttons = tasklist_buttons,
+ widget_template = {
+ id = "text_role",
+ widget = wibox.widget.textbox,
+ align = "center",
+ },
+ },
+ separator,
+ } end,
+ textclock = wibox.widget.textclock("%A, %B %e, %-I:%M %p"),
+ cpu = wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ wibox.widget.textbox "CPU: ",
+ widget_cpu_usage,
+ wibox.widget.textbox "% ",
+ widget_temperature "/sys/class/hwmon/hwmon2/temp1_input",
+ wibox.widget.textbox "°",
+ },
+ ram = {
+ layout = wibox.layout.fixed.horizontal,
+ wibox.widget.textbox "RAM: ",
+ widget_ram_usage,
+ wibox.widget.textbox "%",
+ },
+ vol = {
+ layout = wibox.layout.fixed.horizontal,
+ buttons = volume_buttons,
+ wibox.widget.textbox "VOL: ",
+ widget_volume,
+ wibox.widget.textbox "%",
+ },
+ bat = {
+ layout = wibox.layout.fixed.horizontal,
+ buttons = volume_buttons,
+ wibox.widget.textbox "BAT: ",
+ widget_battery,
+ },
+}
+
+-- left widget group func
+function widgets.left_widgets(s) return wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = spacing,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ widgets.layoutlist,
+ widgets.taglist(s),
+ },
+ widgets.tasklist(s),
+} end
+
+-- miggle widget group func
+function widgets.middle_widgets(s) return wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ widgets.textclock,
+} end
+
+-- right widget group func
+function widgets.right_widgets(s) return wibox.widget {
+ layout = wibox.layout.fixed.horizontal,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ spacing = spacing,
+ widgets.cpu,
+ widgets.ram,
+ widgets.vol,
+ widgets.bat,
+ },
+ {
+ widget = wibox.widget.separator,
+ opacity = 0,
+ forced_width = spacing
+ },
+ --mylauncher,
+} end
+
+-- create a wibox for each screen and add it
+awful.screen.connect_for_each_screen(function (s)
+ awful.tag({"1", "2", "3", "4", "5", "6", "7", "8", "9"}, s, awful.layout.layouts[1])
+ s.mypromptbox = awful.widget.prompt()
+
+ -- create the wibox
+ s.mywibox = awful.wibar({ position = "top", screen = s })
+
+ -- add widgets to the wibox
+ s.mywibox:setup {
+ layout = wibox.layout.align.horizontal,
+ expand = "none",
+ spacing = spacing,
+ widgets.left_widgets(s),
+ widgets.middle_widgets(s),
+ widgets.right_widgets(s),
+ }
+end)
+
+---- signal for changing tasklist filter based on layout
+---- DOESNT WORK TODO
+--local naughty = require("naughty")
+--s:connect_signal("property::layout", function()
+-- naughty.notify({
+-- title = "Hello, AwesomeWM!",
+-- text = "This is a notification.",
+-- timeout = 5, -- Timeout in seconds
+-- position = "top_right" -- Position on the screen
+-- })
+-- if awful.layout.get(s) == awful.layout.suit.max then
+-- s.mytasklist.filter = awful.widget.tasklist.filter.currenttags
+-- else
+-- s.mytasklist.filter = awful.widget.tasklist.filter.focused
+-- end
+--end
+--)
+
+return widgets
diff --git a/func/noborders.lua b/func/noborders.lua
new file mode 100644
index 0000000..fe67024
--- /dev/null
+++ b/func/noborders.lua
@@ -0,0 +1,20 @@
+local beautiful = require("beautiful")
+
+-- TODO this function will call arrange multiple times. once per each change of c.border_width
+local function update_borders(s)
+ local max = s.selected_tag.layout.name == "max"
+ local only_one = #s.tiled_clients == 1 -- use tiled_clients so that other floating windows don't affect the count
+
+ -- but iterate over clients instead of tiled_clients as tiled_clients doesn't include maximized windows
+ for _, c in pairs(s.clients) do
+ if c.prevent_kill then
+ c.border_width = beautiful.border_width * 3
+ elseif (max or only_one or c.maximized) and not c.floating then
+ c.border_width = 0
+ else
+ c.border_width = beautiful.border_width
+ end
+ end
+end
+
+screen.connect_signal("arrange", update_borders) -- NOTE this signal may eventually be deprecated. see issue #2581 and the v5 milestone on github
diff --git a/func/sloppyfocus.lua b/func/sloppyfocus.lua
new file mode 100644
index 0000000..a616286
--- /dev/null
+++ b/func/sloppyfocus.lua
@@ -0,0 +1,4 @@
+-- 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)
diff --git a/func/tagnames.lua b/func/tagnames.lua
new file mode 100644
index 0000000..fcd01a4
--- /dev/null
+++ b/func/tagnames.lua
@@ -0,0 +1,51 @@
+--TODO find out why it doesnt work at start
+--local awful = require("awful")
+
+function nametags(s)
+ local tags = s.tags
+ for _, tag in ipairs(tags) do
+ -- set tag basename
+ if tag.basename == nil then
+ tag.basename = tag.name
+ end
+
+ -- check if tag has any clients. if not, use basename
+ if next(tag:clients()) == nil then
+ tag.name = tag.basename
+ else
+ -- loop over all screen clients (ordered top to bottom)
+ local hastag = nil
+ for _, c in ipairs(s.clients) do
+ -- test if client in on the tag
+ for _, ctag in ipairs(c:tags()) do
+ if ctag == tag then
+ hastag = c
+ break
+ end
+ end
+ -- if it does, this will be the tag name. so break
+ if hastag ~= nil then
+ break
+ end
+ end
+ -- set tag name
+ -- there should always be a tag since we checked above so if there isnt then there is clearly a problem
+ --TODO remove this if statement
+ if hastag then
+ tag.name = tag.basename .. ": " .. hastag.class
+ end
+ end
+ end
+end
+
+function nametagsc(c)
+ nametags(c.screen)
+end
+
+client.connect_signal("manage", nametagsc)
+client.connect_signal("swapped", nametagsc)
+client.connect_signal("tagged", nametagsc)
+client.connect_signal("unmanage", nametagsc)
+client.connect_signal("untagged", nametagsc)
+
+--awful.screen.connect_for_each_screen(nametags)
diff --git a/func/warpcursor.lua b/func/warpcursor.lua
new file mode 100644
index 0000000..f1a46bd
--- /dev/null
+++ b/func/warpcursor.lua
@@ -0,0 +1,22 @@
+function warp_cursor(c)
+-- if c ~= client.focus or not c.warp_cursor then
+ if not c.warp_cursor then
+ return
+ end
+
+ -- dont allow moving mouse unless it is over another client or over nothing
+ local canmovemouse = mouse.current_client or (mouse.current_wibox or mouse.current_widget) == nil
+
+ if canmovemouse and mouse.current_client ~= c then
+ mouse.coords {
+ x = c.x + (c.width / 2),
+ y = c.y + (c.height / 2),
+ }
+ end
+end
+
+client.connect_signal("focus", warp_cursor)
+--client.connect_signal("property::size", warp_cursor)
+--client.connect_signal("property::position", warp_cursor)
+
+return warp_cursor
diff --git a/hosts/libreX60.lua b/hosts/libreX60.lua
new file mode 100644
index 0000000..3ce5619
--- /dev/null
+++ b/hosts/libreX60.lua
@@ -0,0 +1,4 @@
+local wibox = require("wibox")
+local bar_widgets = require("bar")
+
+bar_widgets.textclock.format = "%a, %b %e, %-H:%M"
diff --git a/keybindings.lua b/keybindings.lua
new file mode 100644
index 0000000..9800bbd
--- /dev/null
+++ b/keybindings.lua
@@ -0,0 +1,176 @@
+local awful = require("awful")
+local gears = require("gears")
+local hotkeys_popup = require("awful.hotkeys_popup")
+local menubar = require("menubar")
+-- Enable hotkeys help widget for VIM and other apps
+-- when client with a matching name is opened:
+-- require("awful.hotkeys_popup.keys")
+
+-- Shortcuts for readable keybinds
+local super = "Mod4"
+local alt = "Mod1"
+local shift = "Shift"
+local ctrl = "ctrl"
+
+local key = awful.key
+local a = { alt }
+local as = { alt, shift }
+local w = { super }
+local s = { shift }
+local c = { ctrl }
+local wc = { super, ctrl }
+local ws = { super, shift }
+local wa = { super, alt }
+
+
+-- Functions
+function focus_previous()
+ awful.client.focus.history.previous()
+ if client.focus then
+ client.focus:raise()
+ end
+end
+
+-- Key bindings
+globalkeys = gears.table.join(
+ -- Applications
+ key(a , "Return", function () awful.spawn(terminal) end, { group = "launcher", description = "open a terminal" }),
+ key(a , "f", function () awful.spawn("pcmanfm") end, { group = "launcher", description = "launch pcmanfm" }),
+ key(a , "b", function () awful.spawn("launch firefox") end, { group = "launcher", description = "launch firefox" }),
+ key(a , "c", function () awful.spawn("launch chrome") end, { group = "launcher", description = "launch firefox (alt profile)" }),
+ -- Wallpaper
+ key(w , "w", function () awful.spawn("seasonalwallpaper") end, { group = "launcher", description = "change wallpaper" }),
+ -- Awesome
+ key(w , "F1", hotkeys_popup.show_help , { group = "awesome" , description = "show help" }),
+ key(w , "F10", awesome.restart , { group = "awesome" , description = "reload awesome" }),
+ key(ws, "F10", awesome.quit , { group = "awesome" , description = "quit awesome" }),
+ key(w , "Tab", awful.tag.history.restore , { group = "tag" , description = "go back" }),
+ --
+ key(w , "j", function () awful.client.focus.byidx( 1) end, { group = "client" , description = "focus next by index" }),
+ key(w , "k", function () awful.client.focus.byidx(-1) end, { group = "client" , description = "focus previous by index" }),
+ key(ws, "j", function () awful.client.swap.byidx( 1) end, { group = "client" , description = "swap with next client by index" }),
+ key(ws, "k", function () awful.client.swap.byidx( -1) end, { group = "client" , description = "swap with previous client by index" }),
+ key(w , ",", function () awful.screen.focus_relative(-1) end, { group = "screen" , description = "focus the previous screen" }),
+ key(w , ".", function () awful.screen.focus_relative( 1) end, { group = "screen" , description = "focus the next screen" }),
+ key(w , "u", awful.client.urgent.jumpto , { group = "client" , description = "jump to urgent client" }),
+ key(a , "Tab", focus_previous , { group = "client" , description = "focus previous client" }),
+ key(w , "l", function () awful.tag.incmwfact( 0.05) end, { group = "layout" , description = "increase master width factor" }),
+ key(w , "h", function () awful.tag.incmwfact(-0.05) end, { group = "layout" , description = "decrease master width factor" }),
+ key(ws, "h", function () awful.tag.incnmaster( 1, nil, true) end, { group = "layout" , description = "increase the number of master clients" }),
+ key(ws, "l", function () awful.tag.incnmaster(-1, nil, true) end, { group = "layout" , description = "decrease the number of master clients" }),
+ --key(wc, "h", function () awful.tag.incncol( 1, nil, true) end, { group = "layout" , description = "increase the number of columns" }),
+ --key(wc, "l", function () awful.tag.incncol(-1, nil, true) end, { group = "layout" , description = "decrease the number of columns" }),
+ key(w , "m", function () awful.layout.set(awful.layout.suit.max) end, { group = "layout" , description = "change to max layout" }),
+ key(w , "t", function () awful.layout.set(awful.layout.suit.tile) end, { group = "layout" , description = "change to tile layout" }),
+ key(w , "b", function () awful.layout.set(awful.layout.suit.tile.bottom) end, { group = "layout" , description = "change to tile bottom layout" }),
+ key(w , "r", function () awful.screen.focused().mypromptbox:run() end, { group = "launcher", description = "run prompt" }),
+ key(w , "p", function () menubar.show() end, { group = "launcher", description = "show the menubar" }),
+ -- PC Controls
+ key(w , "Escape", function () awful.spawn("shutdownprompt") end, { group = "system" , description = "show shutdown prompt" }),
+ key(w , "Escape", function () awful.spawn("shutdownprompt") end, { group = "system" , description = "show shutdown prompt" }),
+ key(w , "F9", function () awful.spawn("shutdownprompt Restart") end, { group = "system" , description = "restart system" }),
+ key(w , "F11", function () awful.spawn("shutdownprompt Suspend") end, { group = "system" , description = "suspend system" }),
+ key(w , "F12", function () awful.spawn("shutdownprompt Shutdown") end, { group = "system" , description = "shutdown system" }),
+ key(a , "m", function () awful.spawn("mounter -m") end, { group = "system" , description = "mount drive prompt" }),
+ key(as, "m", function () awful.spawn("mounter -u") end, { group = "system" , description = "unmount drive prompt" }),
+ key(w , "F5", function () awful.spawn("bl set 0") end, { group = "system" , description = "set brightness to 0%" }),
+ key(w , "F6", function () awful.spawn("bl set 25") end, { group = "system" , description = "set brightness to 25%" }),
+ key(w , "F7", function () awful.spawn("bl set 50") end, { group = "system" , description = "set brightness to 50%" }),
+ key(w , "F8", function () awful.spawn("bl set 100") end, { group = "system" , description = "set brightness to 100%" }),
+ -- Screenshots
+ key({}, "Print", function () awful.spawn("screenshot -x") end, { group = "misc" , description = "screenshot, copy to clipboard" }),
+ key(a , "Print", function () awful.spawn("screenshot -xc") end, { group = "misc" , description = "screenshot, crop, copy to clipboard" }),
+ key(w , "Print", function () awful.spawn("screenshot") end, { group = "misc" , description = "screenshot, save to screenshots dir" }),
+ key(wa, "Print", function () awful.spawn("screenshot -c") end, { group = "misc" , description = "screenshot, crop, save to screenshots dir" })
+)
+--Audio Raise Volume Increase volume
+--Audio Lower Volume Decrease volume
+--Audio Mute Toggle mute
+--Backlight Controls:
+--Mon Brightness Up Increase brightness
+--Mon Brightness Down Decrease brightness
+--Alt + Mon Brightness Up Increase brightness by half-step
+--Alt + Mon Brightness Down Decrease brightness by half-step
+
+
+-- Client protection
+local beautiful = require("beautiful")
+local function protectClient(c)
+ c.prevent_kill = true
+ c.screen:emit_signal("arrange")
+end
+local function unProtectClient(c)
+ c.prevent_kill = false
+ c.screen:emit_signal("arrange")
+end
+local function killClient(c)
+ if c.prevent_kill == nil or not c.prevent_kill then
+ c:kill()
+ end
+end
+
+-- Client keys
+clientkeys = gears.table.join(
+ key(w , "q", killClient , { description = "close", group = "client" }),
+ key(w , "x", protectClient , { description = "close", group = "client" }),
+ key(ws, "x", unProtectClient , { description = "close", group = "client" }),
+ key(wc, "space", awful.client.floating.toggle , { description = "toggle floating", group = "client" }),
+ key(w , "Return", function (c) c:swap(awful.client.getmaster()) end, { description = "move to master", group = "client" }),
+ key(ws, ",", function (c) c:move_to_screen(c.screen.index - 1) end, { description = "move to previous screen", group = "client" }),
+ key(ws, ",", function (c) c:move_to_screen(c.screen.index + 1) end, { description = "move to next screen", 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.
+-- Functions
+
+for i = 1, 9 do
+ globalkeys = gears.table.join(globalkeys,
+ -- View tag only.
+ awful.key({ super }, "#" .. 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({ super, "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({ super, "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({ super, "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
+
+-- Set keys
+root.keys(globalkeys)
diff --git a/layouts.lua b/layouts.lua
new file mode 100644
index 0000000..67fd31d
--- /dev/null
+++ b/layouts.lua
@@ -0,0 +1,27 @@
+local awful = require("awful")
+
+-- Table of layouts to cover with awful.layout.inc, order matters.
+awful.layout.layouts = {
+ awful.layout.suit.tile,
+ awful.layout.suit.tile.bottom,
+ awful.layout.suit.max,
+ awful.layout.suit.floating,
+
+
+-- 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,
+}
diff --git a/lib/errors.lua b/lib/errors.lua
new file mode 100644
index 0000000..2079c0e
--- /dev/null
+++ b/lib/errors.lua
@@ -0,0 +1,35 @@
+local awful = require("awful")
+-- require("awful.autofocus")
+-- Widget and layout library
+-- Notification library
+local naughty = require("naughty")
+
+-- {{{ 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
diff --git a/lib/manage.lua b/lib/manage.lua
new file mode 100644
index 0000000..5b1bd40
--- /dev/null
+++ b/lib/manage.lua
@@ -0,0 +1,15 @@
+local awful = require("awful")
+
+-- 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)
diff --git a/lib/screen.lua b/lib/screen.lua
new file mode 100644
index 0000000..3cca05d
--- /dev/null
+++ b/lib/screen.lua
@@ -0,0 +1,8 @@
+local awful = require("awful")
+
+function seasonalwallpaper()
+ awful.spawn("seasonalwallpaper", false) -- if not false then spinner will always spin on desktop
+end
+
+awesome.connect_signal("startup", seasonalwallpaper)
+screen.connect_signal("property::geometry", seasonalwallpaper)
diff --git a/mouse.lua b/mouse.lua
new file mode 100644
index 0000000..13165db
--- /dev/null
+++ b/mouse.lua
@@ -0,0 +1,47 @@
+local awful = require("awful")
+local gears = require("gears")
+local volume_control = require("widgets.pavolctld")
+
+local super = "Mod4"
+local alt = "Mod1"
+local shift = "Shift"
+local ctrl = "Control"
+
+-- window buttons
+clientbuttons = gears.table.join(
+ awful.button({ }, 1, function (c) c:emit_signal("request::activate", "mouse_click", {raise = true}) end),
+ awful.button({ super }, 1, function (c) c:emit_signal("request::activate", "mouse_click", {raise = true}) awful.mouse.client.move(c) end),
+ awful.button({ super }, 3, function (c) c:emit_signal("request::activate", "mouse_click", {raise = true}) awful.mouse.client.resize(c) end)
+)
+
+--root.buttons(gears.table.join(
+-- awful.button({ }, 3, function () mymainmenu:toggle() end),
+-- awful.button({ }, 4, awful.tag.viewnext),
+-- awful.button({ }, 5, awful.tag.viewprev)
+--))
+
+-- wibar widgets
+layout_buttons = gears.table.join(
+ awful.button({ }, 1, function() awful.layout.inc(1, awful.screen.focused().tags[0]) end)
+)
+
+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)
+)
+
+tasklist_buttons = gears.table.join(
+ awful.button({ }, 1, function (c) c:emit_signal("request::activate", "tasklist", {raise = true}) 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)
+)
+
+volume_buttons = gears.table.join(
+ awful.button({ }, 4, function() volume_control.volume_inc(5) end),
+ awful.button({ }, 5, function() volume_control.volume_dec(5) end)
+)
diff --git a/rc.lua b/rc.lua
new file mode 100644
index 0000000..9663506
--- /dev/null
+++ b/rc.lua
@@ -0,0 +1,31 @@
+-- global variable definitions
+terminal = os.getenv("TERMINAL") or "xterm"
+editor = os.getenv("EDITOR") or "vi"
+
+-- get results from uname
+local uname = io.popen("uname -sn")
+local uname_i = uname:read("*a"):gmatch("%g+")
+uname:close()
+
+osname = uname_i()
+hostname = uname_i()
+
+-- import modules
+require("awful.autofocus") -- focus when moving between tags etc.
+require("lib.errors")
+require("lib.manage")
+require("lib.screen")
+require("layouts")
+require("theme") -- load before bar
+require("mouse") -- load before bar & rules
+require("bar")
+require("keybindings")
+require("rules")
+require("func.noborders")
+require("func.sloppyfocus")
+require("func.warpcursor")
+--require("func.tagnames")
+--require("widgets.audio")
+
+-- call override module if exists
+pcall(function() require("hosts." .. hostname) end)
diff --git a/rules.lua b/rules.lua
new file mode 100644
index 0000000..8655541
--- /dev/null
+++ b/rules.lua
@@ -0,0 +1,56 @@
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+-- 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,
+ prevent_kill = false,
+ }
+ },
+ -- Warp cursor
+ {
+ rule_any = { class = {
+ "Chromium-browser",
+ "Firefox",
+ "Firefox-esr",
+ "Gimp",
+ "KeePassXC",
+ "Pcmanfm",
+ }},
+ properties = { warp_cursor = true, }
+ },
+ -- KeePassXC rules
+ {
+ rule = { class = "KeePassXC" },
+ -- except = { name = "Unlock Database - KeePassXC" }, -- Not needed
+ properties = {
+ new_tag = {
+ name = "KeePassXC",
+ layout = awful.layout.suit.max,
+ volatile = true,
+ },
+ -- callback = function(c) c.first_tag.icon = c.icon end
+ }
+ },
+ {
+ rule_any = { name = { "Unlock Database - KeePassXC", "KeePassXC - Browser Access Request" } },
+ properties = {
+ screen = awful.screen.focused(),
+ floating = true,
+ placement = awful.placement.centered,
+ -- tags = awful.screen.focused().selected_tags, -- For some reason, this doesn't work
+ callback = function(c) c:tags(awful.screen.focused().selected_tags) end -- But this does
+ }
+ },
+}
diff --git a/theme.lua b/theme.lua
new file mode 100644
index 0000000..98f0ee8
--- /dev/null
+++ b/theme.lua
@@ -0,0 +1,39 @@
+-- theme handling library
+local beautiful = require("beautiful")
+local gears = require("gears")
+
+-- colors
+local darkgray = "#222222"
+local white = "#ffffff"
+local lightgray = "#aaaaaa"
+
+-- themes define colours, icons, font and wallpapers
+beautiful.init(gears.filesystem.get_themes_dir() .. "gtk/theme.lua")
+
+-- gaps
+beautiful.useless_gap = 0
+beautiful.gap_single_client = false
+
+-- overrides
+beautiful.tasklist_font_focus = beautiful.font -- prevent bold
+beautiful.wibar_height = "18"
+beautiful.wibar_bg = darkgray
+--beautiful.layoutlist_font = "Monospace 8"
+--beautiful.font = "Tamzen 10"
+--beautiful.taglist_font = "Tamzen 10"
+--beautiful.tasklist_font = beautiful.font
+--beautiful.tasklist_align = "center" -- does nothing?
+
+-- hotkeys menu
+beautiful.hotkeys_font = beautiful.font -- TODO make bold
+beautiful.hotkeys_description_font = beautiful.font
+beautiful.hotkeys_border_color = beautiful.border_focus
+beautiful.hotkeys_bg = darkgray
+beautiful.hotkeys_fg = white
+beautiful.hotkeys_label_fg = white
+beautiful.hotkeys_modifiers_fg = lightgray
+beautiful.hotkeys_label_bg = darkgray -- ???
+
+-- set border on clients
+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)
diff --git a/todo b/todo
new file mode 100644
index 0000000..08ab7dd
--- /dev/null
+++ b/todo
@@ -0,0 +1,24 @@
+gaps keybinds
+client mfact/fact keybinds
+hostname configs
+volume dropdown menu
+battery widget
+bar styling / powerline for certain confs
+classiclayout widget minify
+widget icons
+bar title tabs in monocle mode
+better tagnames
+volume/cpu graph/etc in middle right bar when hovering over stats
+new windows should open on the tags activated when spawn was ran
+
+# BUGS
+warp cursor is bugged
+
+
+#general
+other layouts
+floating support
+tabbing support
+cleanup
+
+move pvolctld logic to sep util file with diff callbacks
diff --git a/util/seasonalwallpaper.lua b/util/seasonalwallpaper.lua
new file mode 100644
index 0000000..4ec3bb3
--- /dev/null
+++ b/util/seasonalwallpaper.lua
@@ -0,0 +1,26 @@
+local gears = require("gears")
+local beautiful = require("beautiful")
+
+local wallpapers_directory = gears.get_xdg_data_home() .. "wallpaper"
+local spring = wallpapers_directory .. "/spring"
+local summer = wallpapers_directory .. "/summer"
+local fall = wallpapers_directory .. "/fall"
+local winter = wallpapers_directory .. "/winter"
+
+
+
+--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
+
+function set_wallpaper()
+ gt
+end
diff --git a/util/widgets.lua b/util/widgets.lua
new file mode 100644
index 0000000..301f25b
--- /dev/null
+++ b/util/widgets.lua
@@ -0,0 +1,19 @@
+local wibox = require("wibox")
+local gears = require("gears")
+
+local widgets = {}
+
+function widgets.watchfn(callback, timeout, base_widget)
+ local widget = (base_widget or wibox.widget.textbox)()
+ gears.timer({
+ timeout = timeout or 5,
+ call_now = true,
+ autostart = true,
+ callback = function()
+ callback(widget)
+ end
+ })
+ return widget
+end
+
+return widgets
diff --git a/widgets/audio.lua b/widgets/audio.lua
new file mode 100644
index 0000000..002c556
--- /dev/null
+++ b/widgets/audio.lua
@@ -0,0 +1,21 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local gears = require("gears")
+
+local audio_dropdown = awful.popup {
+ widget = {
+ margins = 10,
+ widget = wibox.container.margin,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ wibox.widget.textbox "AUDIO",
+ },
+ },
+ ontop = true,
+ placement = awful.placement.centered,
+ border_width = 1,
+ border_color = "#ff0000",
+ visible = true,
+}
+
+return audio_dropdown
diff --git a/widgets/battery.lua b/widgets/battery.lua
new file mode 100644
index 0000000..f6e6860
--- /dev/null
+++ b/widgets/battery.lua
@@ -0,0 +1,24 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local naughty = require("naughty")
+
+local widget = wibox.widget.textbox()
+
+-- update widget on lowbat output
+local lowbat_pid = awful.spawn.with_line_callback("lowbat", {
+ stdout = function(stdout)
+ widget:set_text(stdout)
+ end,
+ stderr = function(stderr)
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = "lowbat error",
+ text = stderr
+ })
+ end,
+})
+
+-- kill current lowbat on refresh/exit
+awesome.connect_signal("exit", function() awful.spawn("kill " .. lowbat_pid) end)
+
+return widget
diff --git a/widgets/button.lua b/widgets/button.lua
new file mode 100644
index 0000000..cd1da1e
--- /dev/null
+++ b/widgets/button.lua
@@ -0,0 +1,33 @@
+local awful = require("awful")
+local beautiful = require("beautiful")
+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")
+
+-- Menu
+-- Create a launcher widget and a main menu
+myawesomemenu = {
+ { "hotkeys", function() hotkeys_popup.show_help(nil, awful.screen.focused()) end },
+ { "restart", awesome.restart },
+ { "quit", function() awesome.quit() end },
+}
+
+mymainmenu = awful.menu({
+ items = {
+ { "awesome", myawesomemenu, beautiful.awesome_icon },
+ { "open terminal", terminal }
+ }
+})
+
+mylauncher = awful.widget.launcher({
+ image = beautiful.awesome_icon,
+ menu = mymainmenu
+})
+
+-- Menubar configuration
+menubar.utils.terminal = terminal -- Set the terminal for applications that require it
+
+return mylauncher
diff --git a/widgets/classiclayouts.lua b/widgets/classiclayouts.lua
new file mode 100644
index 0000000..3b4fd64
--- /dev/null
+++ b/widgets/classiclayouts.lua
@@ -0,0 +1,64 @@
+local wibox = require("wibox")
+local layout = require("awful.layout")
+
+local screen_widgets = {} -- need one widget per screen
+
+local layout_icons = {
+ cornernw = "TT=",
+ cornerne = "=TT",
+ cornersw = "LL=",
+ cornerse = "=LL",
+ fairh = "#_#",
+ fairv = "##H",
+ max = "[M]",
+ floating = "><>",
+ magnifier = "=O=",
+ fullscreen = "[*]",
+ spiral = "[]@",
+ dwindle = "[]\\",
+ tile = "[]=",
+ tiletop = "LLL",
+ tilebottom = "TTT",
+ tileleft = "=[]",
+}
+
+function update(screen_index)
+ local s = screen[screen_index or 1]
+ local w = screen_widgets[s]
+ local l = layout.get(s)
+
+ -- create widget if not existing
+ if w == nil then
+ screen_widgets[s] = { widget = wibox.widget.textbox(), layout = l }
+ w = screen_widgets[s]
+ --w._layoutbox_tooltip = tooltip {objects = {w}, delay_show = 1}
+
+ -- skip if no change
+ elseif w.layout == l then
+ return
+ end
+
+ -- set widget
+ local name = layout.getname(l)
+ --w._layoutbox_tooltip:set_text(name)
+ w.widget:set_text(layout_icons[name]) -- TODO handle nil
+ return w.widget
+end
+
+function update_screens()
+ for s, w in pairs(boxes) do
+ if s.valid then
+ update(s)
+ end
+ end
+end
+
+function update_current_tag(t)
+ update(t.screen)
+end
+
+tag.connect_signal("property::selected", update_current_tag)
+tag.connect_signal("property::layout", update_current_tag)
+tag.connect_signal("property::screen", update_screens)
+
+return update
diff --git a/widgets/cpu.lua b/widgets/cpu.lua
new file mode 100644
index 0000000..d92bce8
--- /dev/null
+++ b/widgets/cpu.lua
@@ -0,0 +1,38 @@
+local wibox = require("wibox")
+local widgets = require("util.widgets")
+
+-- this is directly adapted from slstatus's cpu.c module
+local cpu_time = { 0,0,0,0,0,0,0 } -- user, nice, system, idle, iowait, irq, softirq
+
+function linux_cpu_usage(widget)
+ -- read stat
+ local statf = io.open("/proc/stat")
+ local stat_iter = statf:read():gmatch("%d+")
+ statf:close()
+
+ -- calc
+ local sum = 0
+ local a, b = cpu_time, {} -- set cpu_time as a for smaller code
+ table.move(a, 1, 7, 1, b) -- copy first 7 to b
+
+ for i = 1, 7 do
+ a[i] = stat_iter()
+ sum = sum + b[i] - a[i]
+ end
+
+ if sum == 0 then
+ return
+ end
+
+ local usage = ((b[1] + b[2] + b[3] + b[6] + b[7]) -
+ (a[1] + a[2] + a[3] + a[6] + a[7])) * 100 / sum
+
+ widget:set_text(math.floor(usage))
+end
+
+-- return correct widget for os
+if osname == "Linux" then
+ return widgets.watchfn(linux_cpu_usage, 5)
+end
+
+return wibox.widget.textbox("unsupported os")
diff --git a/widgets/pavolctld.lua b/widgets/pavolctld.lua
new file mode 100644
index 0000000..f59b27f
--- /dev/null
+++ b/widgets/pavolctld.lua
@@ -0,0 +1,104 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local naughty = require("naughty")
+
+-- Gio is used to handle the subprocess instead of awful.spawn.
+-- Gio is more flexible and allows writing to stdin.
+-- also, awful.spawn.with_line_callback does not play nicely with pavolctld, as
+-- it seems to feed the stdout back into its stdin and kill performance.
+local lgi = require("lgi")
+local Gio = lgi.Gio
+
+-- return table
+local widget = {
+ textbox = wibox.widget.textbox()
+}
+
+-- start subprocess
+local p = Gio.Subprocess.new({ "pavolctld" }, Gio.SubprocessFlags.STDIN_PIPE + Gio.SubprocessFlags.STDOUT_PIPE)
+
+local stdout = p:get_stdout_pipe()
+local stdin = p:get_stdin_pipe()
+
+-- state vars
+local sinks = {
+ default = nil,
+ command = nil, -- sink being modified by commands
+ sinks = {},
+}
+
+function sinks.get(i)
+ if sinks.sinks[i] == nil then
+ sinks.sinks[i] = {
+ vol = 0,
+ db = 0.0,
+ mute = 0,
+ name = "",
+ desc = "",
+ }
+ end
+ return sinks.sinks[i]
+end
+
+-- parse output
+function parse_csv(csv)
+ return (csv .. ","):gmatch("(.-),")
+end
+
+awful.spawn.read_lines(stdout, function(s)
+ local cmd = s:sub(1, 1) -- first char of output
+ -- volume change
+ if cmd == 'v' then
+ local v = parse_csv(s:sub(2))
+ local i = tonumber(v())
+ local sink = sinks.get(i)
+ sink.vol = tonumber(v())
+ sink.db = tonumber(v())
+ sink.mute = tonumber(v())
+
+ if sink == sinks.default then
+ widget.textbox:set_text(sink.vol)
+ end
+ -- sink description change
+ elseif cmd == 's' then
+ local v = parse_csv(s:sub(2))
+ local i = tonumber(v())
+ local sink = sinks.get(i)
+ sink.name = v()
+ sink.desc = v()
+ -- default sink change
+ elseif cmd == 'f' then
+ local f = tonumber(s:sub(2))
+ sinks.default = sinks.get(f)
+ widget.textbox:set_text(sinks.default.vol)
+ -- set command sink to default sink for now TODO change later
+ pavolctld_cmd("s")
+ -- sink removed
+ elseif cmd == 'x' then
+ local x = tonumber(s:sub(2))
+ table.remove(sinks.sinks, x)
+ else
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = "pavolctld error",
+ text = s
+ })
+ end
+end)
+
+-- pavolctld takes commands in using stdin
+function pavolctld_cmd(cmd)
+ local _, err = stdin:write_all(cmd .. "\n", nil)
+
+ if err then return nil end
+ return true
+end
+
+function widget.volume_inc(vol) return pavolctld_cmd("v+" .. vol) end
+function widget.volume_dec(vol) return pavolctld_cmd("v-" .. vol) end
+function widget.volume_set(vol) return pavolctld_cmd("v" .. vol) end
+function widget.mute_set(muted) return pavolctld_cmd("m" .. muted and 1 or 0) end
+function widget.mute_toggle() return pavolctld_cmd("m") end
+function widget.default_sink_set(i) return pavolctld_cmd("f" .. i) end
+
+return widget
diff --git a/widgets/ram.lua b/widgets/ram.lua
new file mode 100644
index 0000000..44ab314
--- /dev/null
+++ b/widgets/ram.lua
@@ -0,0 +1,34 @@
+local wibox = require("wibox")
+local widgets = require("util.widgets")
+
+
+function linux_ram_usage(widget)
+ -- read meminfo
+ local meminfof = io.open("/proc/meminfo")
+
+ local total = meminfof:read():match("%d+")
+ local free = meminfof:read():match("%d+")
+
+ meminfof:read() -- memavailable not used
+
+ local buffers = meminfof:read():match("%d+")
+ local cached = meminfof:read():match("%d+")
+
+ meminfof:close()
+
+ -- calc
+ if total == nil then
+ return
+ end
+
+ local used = (total - free - buffers - cached) * 100 / total
+
+ widget:set_text(math.floor(used))
+end
+
+-- return correct widget for os
+if osname == "Linux" then
+ return widgets.watchfn(linux_ram_usage, 5)
+end
+
+return wibox.widget.textbox("unsupported os")
diff --git a/widgets/temperature.lua b/widgets/temperature.lua
new file mode 100644
index 0000000..a30e1ed
--- /dev/null
+++ b/widgets/temperature.lua
@@ -0,0 +1,26 @@
+local wibox = require("wibox")
+local widgets = require("util.widgets")
+
+
+local linux = { file = nil }
+function linux.temperature(widget)
+ -- read meminfo
+ local tempf = io.open(linux.file)
+ if tempf then
+ local temp = tempf:read() / 1000
+ tempf:close()
+ widget:set_text(math.floor(temp))
+ else
+ widget:set_text("err")
+ end
+end
+
+-- return correct widget for os
+if osname == "Linux" then
+ return function(file)
+ linux.file = file
+ return widgets.watchfn(linux.temperature, 5)
+ end
+end
+
+return wibox.widget.textbox("unsupported os")