diff options
author | Tim Keller <tjk@tjkeller.xyz> | 2024-10-18 21:49:17 -0500 |
---|---|---|
committer | Tim Keller <tjk@tjkeller.xyz> | 2024-10-18 21:49:17 -0500 |
commit | 923eb46350b1102749eb05cd2120c96cc6a715d0 (patch) | |
tree | 811da20b4195d4b5c65c8ac0090982a4a23f6a7d | |
download | awesome-923eb46350b1102749eb05cd2120c96cc6a715d0.tar.xz awesome-923eb46350b1102749eb05cd2120c96cc6a715d0.zip |
initial commit
-rw-r--r-- | bar.lua | 154 | ||||
-rw-r--r-- | func/noborders.lua | 20 | ||||
-rw-r--r-- | func/sloppyfocus.lua | 4 | ||||
-rw-r--r-- | func/tagnames.lua | 51 | ||||
-rw-r--r-- | func/warpcursor.lua | 22 | ||||
-rw-r--r-- | hosts/libreX60.lua | 4 | ||||
-rw-r--r-- | keybindings.lua | 176 | ||||
-rw-r--r-- | layouts.lua | 27 | ||||
-rw-r--r-- | lib/errors.lua | 35 | ||||
-rw-r--r-- | lib/manage.lua | 15 | ||||
-rw-r--r-- | lib/screen.lua | 8 | ||||
-rw-r--r-- | mouse.lua | 47 | ||||
-rw-r--r-- | rc.lua | 31 | ||||
-rw-r--r-- | rules.lua | 56 | ||||
-rw-r--r-- | theme.lua | 39 | ||||
-rw-r--r-- | todo | 24 | ||||
-rw-r--r-- | util/seasonalwallpaper.lua | 26 | ||||
-rw-r--r-- | util/widgets.lua | 19 | ||||
-rw-r--r-- | widgets/audio.lua | 21 | ||||
-rw-r--r-- | widgets/battery.lua | 24 | ||||
-rw-r--r-- | widgets/button.lua | 33 | ||||
-rw-r--r-- | widgets/classiclayouts.lua | 64 | ||||
-rw-r--r-- | widgets/cpu.lua | 38 | ||||
-rw-r--r-- | widgets/pavolctld.lua | 104 | ||||
-rw-r--r-- | widgets/ram.lua | 34 | ||||
-rw-r--r-- | widgets/temperature.lua | 26 |
26 files changed, 1102 insertions, 0 deletions
@@ -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) +) @@ -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) @@ -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") |