diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua
index b74d3f9..8d3b331 100644
--- a/config/awesome/rc.lua
+++ b/config/awesome/rc.lua
@@ -1,13 +1,11 @@
pcall(require, "luarocks.loader")
-
-local gears = require("gears")
-local awful = require("awful")
-local naughty = require("naughty")
+local gears = require("gears")
+local awful = require("awful")
+local naughty = require("naughty")
local wibox = require("wibox")
-local beautiful = require("beautiful")
+local beautiful = require("beautiful")
local hotkeys_popup = require("awful.hotkeys_popup")
local menubar = require("menubar")
-
require("awful.autofocus")
-- Pick a random image from the folder on start/reload
@@ -15,7 +13,7 @@ awful.spawn.with_shell("feh --bg-fill --randomize /home/jason/Pictures/Wallpaper
-- Global config
-- Alt. Use "Mod4" for the Super/Windows key.
-modkey = "Mod4"
+modkey = "Mod4"
terminal = "alacritty"
theChurch = "emacs"
editor = os.getenv("EDITOR") or "nano"
@@ -27,22 +25,22 @@ awful.layout.layouts = { awful.layout.suit.tile, awful.layout.suit.max }
-- hasn't started yet at this point in the session)
awful.spawn.easy_async_with_shell("pkill xfce4-notifyd", function() end)
gears.timer.start_new(3, function()
- awful.spawn.easy_async_with_shell("pkill xfce4-notifyd", function() end)
- return false -- don't repeat
+ awful.spawn.easy_async_with_shell("pkill xfce4-notifyd", function() end)
+ return false -- don't repeat
end)
-- Error handling
if awesome.startup_errors then
- naughty.notify({ preset = naughty.config.presets.critical, title = "Error during startup", text = awesome.startup_errors })
+ naughty.notify({ preset = naughty.config.presets.critical, title = "Error during startup", text = awesome.startup_errors })
end
do
- local in_error = false
- awesome.connect_signal("debug::error", function(err)
- if in_error then return end
- in_error = true
- naughty.notify({ preset = naughty.config.presets.critical, title = "An error happened", text = tostring(err) })
- in_error = false
- end)
+ local in_error = false
+ awesome.connect_signal("debug::error", function(err)
+ if in_error then return end
+ in_error = true
+ naughty.notify({ preset = naughty.config.presets.critical, title = "An error happened", text = tostring(err) })
+ in_error = false
+ end)
end
-- ================================================
@@ -60,18 +58,14 @@ local colors = {
disabled = "#6a9589", -- cyan (normal) - muted, low-contrast
white = "#ffffff", -- white (normal) - dimmer than foreground
}
-
-
beautiful.wallpaper = nil
beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
-
beautiful.useless_gap = 8
beautiful.gap_single_client = true
beautiful.font = "JetBrainsMono Nerd Font 11"
beautiful.border_width = 4
beautiful.border_normal = colors.background_alt
beautiful.border_focus = colors.accent
-
beautiful.taglist_bg_focus = colors.accent
beautiful.taglist_fg_focus = colors.background
beautiful.taglist_fg_occupied = colors.accent
@@ -80,10 +74,8 @@ beautiful.taglist_fg_empty = colors.white
beautiful.taglist_bg_empty = colors.background
beautiful.taglist_bg_urgent = colors.red
beautiful.taglist_fg_urgent = colors.background
-
beautiful.bg_systray = colors.background
beautiful.systray_icon_spacing = 4
-
-- Notifications, styled to match the wibar/client theme
naughty.config.defaults.position = "top_right"
naughty.config.defaults.timeout = 5
@@ -94,7 +86,6 @@ naughty.config.defaults.icon_size = 48
naughty.config.defaults.border_width = 3
naughty.config.defaults.font = "JetBrainsMono Nerd Font 12"
naughty.config.defaults.shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 13) end
-
naughty.config.presets.normal = {
bg = colors.background, fg = colors.foreground, border_color = colors.accent,
border_width = 3, font = "JetBrainsMono Nerd Font 12", timeout = 5,
@@ -109,27 +100,24 @@ naughty.config.presets.critical = {
-- WIDGETS
-- ================================================
local widgets = {}
-
-- "ICON value" with ICON tinted accent, like polybar's *-prefix-foreground.
function widgets.label(icon, val)
return string.format("%s %s", colors.white, icon, val or "")
end
-
-- A slim separator in the disabled color, like polybar's separator.
function widgets.sep()
local w = wibox.widget.textbox()
w.markup = string.format(" ", colors.disabled)
return w
end
-
-- Wrap a widget in a small margin so bar modules aren't crammed together.
function widgets.padded(w, left, right)
return wibox.container.margin(w, left or 8, right or 8)
end
-
-- Focused window title (polybar xwindow / %title%)
function widgets.make_title()
local t = wibox.widget.textbox()
+ t.align = "center"
local function update()
local c = client.focus
t.markup = c and string.format("%s", colors.white, gears.string.xml_escape(c.name or "")) or ""
@@ -139,20 +127,17 @@ function widgets.make_title()
client.connect_signal("property::name", update)
return t
end
-
-- CPU usage % (two top samples so the reading is accurate)
function widgets.make_cpu()
return awful.widget.watch(
{ "bash", "-c", [[LANG=C top -bn2 -d0.3 | grep -m2 '^%Cpu' | tail -1 | awk '{printf "%.0f", 100 - $8}']] },
- 3, function(w, out) w.markup = widgets.label(" ", out:gsub("%s+$", "") .. "%") end)
+ 3, function(w, out) w.markup = widgets.label("", out:gsub("%s+$", "") .. "%") end)
end
-
-- Volume: click to mute, scroll to adjust, right-click for the mixer.
-- Keeps its own refresh() so button presses update instantly instead of
-- waiting on the polling timer.
function widgets.make_vol()
local w = wibox.widget.textbox()
-
local vol_script = [[
sink=$(LANG=C pactl get-default-sink 2>/dev/null)
m=$(LANG=C pactl get-sink-mute "$sink" 2>/dev/null | grep -oE 'yes|no')
@@ -161,7 +146,6 @@ function widgets.make_vol()
]]
local function shell_quote(s) return "'" .. s:gsub("'", "'\\''") .. "'" end
local vol_cmd = "sh -c " .. shell_quote(vol_script)
-
local function refresh()
awful.spawn.easy_async_with_shell(vol_cmd, function(out)
local muted, pct = out:match("(%a+)%s+(%d+)%%")
@@ -174,36 +158,29 @@ function widgets.make_vol()
w.markup = muted and string.format("MUTE", colors.yellow) or widgets.label("", pct .. "%")
end)
end
-
w:buttons(gears.table.join(
awful.button({ }, 1, function() awful.spawn("/home/jason/.local/bin/audioswitch") end),
awful.button({ }, 3, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-mute "$(pactl get-default-sink)" toggle']], function() refresh() end) end),
awful.button({ }, 4, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" +2%']], function() refresh() end) end),
awful.button({ }, 5, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" -2%']], function() refresh() end) end)
))
-
gears.timer { timeout = 2, call_now = true, autostart = true, callback = refresh }
return w
end
-
-- Brightness: click to toggle between night (default gamma) and day (boosted).
function widgets.make_brightness()
- local OUTPUT = "HDMI-A-0"
- local DAY_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1.1,0,0,0,1.1,0,0,0,1.1\" --gamma 1.08:1.08:1.08"
- local NIGHT_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1,0,0,0,1,0,0,0,1\" --gamma 1.0:1.0:1.0"
-
+ local OUTPUT = "HDMI-A-0"
+ local DAY_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1.1,0,0,0,1.1,0,0,0,1.1\" --gamma 1.08:1.08:1.08"
+ local NIGHT_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1,0,0,0,1,0,0,0,1\" --gamma 1.0:1.0:1.0"
local w = wibox.widget.textbox()
local is_day = true
-
- local function render()
- local icon = is_day and " " or " "
-
- w.markup = string.format(
- "%s",
- colors.white, icon
- )
- end
-
+ local function render()
+ local icon = is_day and "" or ""
+ w.markup = string.format(
+ "%s ",
+ colors.white, icon
+ )
+ end
local function apply(day)
local cmd = day and DAY_CMD or NIGHT_CMD
awful.spawn.easy_async_with_shell(cmd, function()
@@ -211,11 +188,9 @@ function widgets.make_brightness()
render()
end)
end
-
w:buttons(gears.table.join(
awful.button({ }, 1, function() apply(not is_day) end)
))
-
apply(true)
return w
end
@@ -224,54 +199,42 @@ end
-- KEYBINDS
-- ================================================
local keys = {}
-
keys.globalkeys = gears.table.join(
awful.key({ modkey }, "s", hotkeys_popup.show_help, { description = "show help", group = "awesome" }),
-
-- Directional focus (vim keys)
awful.key({ modkey }, "h", function() awful.client.focus.bydirection("left") end, { description = "focus left", group = "client" }),
awful.key({ modkey }, "j", function() awful.client.focus.bydirection("down") end, { description = "focus down", group = "client" }),
awful.key({ modkey }, "k", function() awful.client.focus.bydirection("up") end, { description = "focus up", group = "client" }),
awful.key({ modkey }, "l", function() awful.client.focus.bydirection("right") end, { description = "focus right", group = "client" }),
-
-- Directional move (swap clients in the tiling layout)
awful.key({ modkey, "Control" }, "h", function() awful.client.swap.bydirection("left") end, { description = "move left", group = "client" }),
awful.key({ modkey, "Control" }, "j", function() awful.client.swap.bydirection("down") end, { description = "move down", group = "client" }),
awful.key({ modkey, "Control" }, "k", function() awful.client.swap.bydirection("up") end, { description = "move up", group = "client" }),
awful.key({ modkey, "Control" }, "l", function() awful.client.swap.bydirection("right") end, { description = "move right", group = "client" }),
-
-- Resize the master/other split
awful.key({ modkey, "Shift" }, "h", function() awful.tag.incmwfact(-0.05) end, { description = "shrink master", group = "layout" }),
awful.key({ modkey, "Shift" }, "l", function() awful.tag.incmwfact( 0.05) end, { description = "grow master", group = "layout" }),
-
-- Launching / layout
awful.key({ modkey }, "Return", function() awful.spawn(theChurch) end, { description = "open the church of emacs", group = "launcher" }),
awful.key({ modkey }, "t", function() awful.spawn(terminal) end, { description = "open alacritty", group = "launcher" }),
awful.key({ modkey }, "e", function() awful.spawn("thunar") end, { description = "Filemanager", group = "system" }),
awful.key({ modkey }, "w", function() awful.layout.inc(1) end, { description = "next layout", group = "layout" }),
-
-
- -- screenshooter
+ -- screenshooter
awful.key({ modkey, "Control" }, "p", function() awful.spawn("xfce4-screenshooter") end, { description = "screenshot", group = "system" }),
-
- -- Alt tab current workspace windows
- awful.key({ modkey }, "Tab", function() awful.client.focus.byidx(1) end),
-
+ -- Alt tab current workspace windows
+ awful.key({ modkey }, "Tab", function() awful.client.focus.byidx(1) end, { description = "cycle focus", group = "client" }),
-- Media keys
awful.key({ }, "XF86AudioRaiseVolume", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" +2%']]) end, { description = "volume up", group = "media" }),
awful.key({ }, "XF86AudioLowerVolume", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" -2%']]) end, { description = "volume down", group = "media" }),
awful.key({ }, "XF86AudioMute", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-mute "$(pactl get-default-sink)" toggle']]) end, { description = "toggle mute", group = "media" }),
-
-- rofi menus
- awful.key({ modkey }, "space", function() awful.spawn("/home/jason/.local/bin/runrofi") end, { description = "application launcher", group = "launcher" }),
+ awful.key({ modkey }, "space", function() awful.spawn("/home/jason/.local/bin/runrofi") end, { description = "application launcher", group = "launcher" }),
awful.key({ modkey }, "`", function() awful.spawn("/home/jason/.local/bin/powermenu") end, { description = "power menu", group = "system" }),
awful.key({ modkey }, "a", function() awful.spawn("/home/jason/.local/bin/audioswitch") end, { description = "audio output", group = "system" }),
- awful.key({ modkey }, "b", function () awful.spawn("/home/jason/.local/bin/bookmarks") end, {description = "bookmarks", group = "internet"}),
-
+ awful.key({ modkey }, "b", function () awful.spawn("/home/jason/.local/bin/bookmarks") end, {description = "bookmarks", group = "internet"}),
-- Awesome control
awful.key({ modkey, "Control" }, "r", awesome.restart, { description = "reload awesome", group = "awesome" })
)
-
-- Workspace keys 1..5: Alt+N view, Alt+Shift+N move client to tag
for i = 1, 5 do
keys.globalkeys = gears.table.join(keys.globalkeys,
@@ -280,7 +243,6 @@ for i = 1, 5 do
local tag = screen.tags[i]
if tag then tag:view_only() end
end, { description = "view tag #" .. i, group = "tag" }),
-
awful.key({ modkey, "Control" }, "#" .. i + 9, function()
if client.focus then
local tag = client.focus.screen.tags[i]
@@ -289,21 +251,18 @@ for i = 1, 5 do
end, { description = "move focused client to tag #" .. i, group = "tag" })
)
end
-
keys.clientkeys = gears.table.join(
awful.key({ modkey }, "q", function(c) c:kill() end, { description = "kill window", group = "client" }),
awful.key({ modkey }, "f", function(c) c.fullscreen = not c.fullscreen; c:raise() end, { description = "toggle fullscreen", group = "client" }),
-- awful.key({ modkey }, "m", function(c) c:swap(awful.client.getmaster()) end, { description = "make master", group = "client" }),
- awful.key({ modkey }, "m", function (c) c.maximized = not c.maximized c:raise() end, {description = "(un)maximize", 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" }, "space", awful.client.floating.toggle, { description = "toggle floating", group = "client" })
)
-
keys.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)
)
-
root.keys(keys.globalkeys)
-- ================================================
@@ -314,97 +273,96 @@ local taglist_buttons = gears.table.join(
awful.button({ modkey }, 1, function(t) if client.focus then client.focus:move_to_tag(t) end end),
awful.button({ }, 3, awful.tag.viewtoggle)
)
-
local function bar_setup()
awful.screen.connect_for_each_screen(function(s)
awful.tag({ "1", "2", "3", "4", "5" }, s, awful.layout.layouts[1])
-
s.mypromptbox = awful.widget.prompt()
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)
))
-
s.mytaglist = awful.widget.taglist {
screen = s, filter = awful.widget.taglist.filter.all, buttons = taglist_buttons,
style = { shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 4) end },
- layout = { spacing = 4, layout = wibox.layout.fixed.horizontal },
+ layout = { spacing = 8, layout = wibox.layout.fixed.horizontal },
widget_template = {
{ { id = "text_role", widget = wibox.widget.textbox }, left = 10, right = 10, top = 4, bottom = 4, widget = wibox.container.margin },
id = "background_role", widget = wibox.container.background,
},
}
-
-- Per-screen monitor widgets (created here so multi-monitor stays valid)
local title = widgets.make_title()
local vol = widgets.make_vol()
local cpu = widgets.make_cpu()
- local brightness = widgets.make_brightness()
+ local brightness = widgets.make_brightness()
local clock = wibox.widget.textclock("%Y-%m-%d %H:%M")
-
local right = wibox.layout.fixed.horizontal()
- local function push(w) right:add(widgets.padded(w, 4, 4)) end
- push(wibox.widget.systray()); right:add(widgets.sep())
- push(vol); right:add(widgets.sep())
- push(cpu); right:add(widgets.sep())
- push(clock);
- push(brightness);
- push(s.mylayoutbox)
-
+ right.spacing = 16 -- one uniform gap between all right-hand modules
+ right:add(wibox.widget.systray())
+ right:add(vol)
+ right:add(cpu)
+ right:add(clock)
+ right:add(brightness)
s.mywibox = awful.wibar {
position = "top", screen = s, height = 45, bg = colors.background, fg = colors.white,
shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 0) end,
}
-
s.mywibox:setup {
layout = wibox.container.margin, left = 8, right = 8, top = 10, bottom = 10,
{
layout = wibox.layout.align.horizontal,
- { -- Left: workspaces + focused window title
+ expand = "none", -- center widget is centered on the whole bar
+ -- Left: layout indicator + workspaces
+ {
layout = wibox.layout.fixed.horizontal,
- widgets.padded(s.mytaglist, 8, 4), s.mypromptbox,
- { title, left = 18, widget = wibox.container.margin },
+ widgets.padded(s.mylayoutbox, 8, 8),
+ widgets.padded(s.mytaglist, 4, 4), s.mypromptbox,
},
- nil, -- empty center
+ -- Center: focused window title
+ title,
+ -- Right
widgets.padded(right, 4, 12),
}
}
end)
-
- -- Overlay for rofi launchers
- local dim_overlay = wibox({
- visible = false,
- ontop = true,
- type = "splash",
- bg = "#00000099",
- })
- dim_overlay.name = "awesome_dim_overlay"
-
- awful.screen.connect_for_each_screen(function(s)
- dim_overlay.screen = s -- adjust if you want it per-screen vs spanning all
- end)
-
- -- span the primary screen's geometry (or loop over all screens if you use a multi-monitor dim)
- local function update_dim_geometry()
- local geo = screen.primary.geometry
- dim_overlay:geometry(geo)
- end
- update_dim_geometry()
- screen.connect_signal("property::geometry", update_dim_geometry)
-
- -- expose functions over awesome-client
- _G.show_dim = function() dim_overlay.visible = true end
- _G.hide_dim = function() dim_overlay.visible = false end
-
- -- Prime the window so X/picom register its type before first real use,
- -- avoiding a one-time grow animation on the very first show_dim() call
- dim_overlay.visible = true
- gears.timer.delayed_call(function()
- dim_overlay.visible = false
- end)
+ -- Overlay for rofi launchers.
+ -- Real dim colour; the overlay is created fully transparent so the
+ -- startup prime (below) can run without ever showing on screen.
+ local DIM_BG = "#00000099"
+ local dim_overlay = wibox({
+ visible = false,
+ ontop = true,
+ type = "splash",
+ bg = "#00000000",
+ })
+ dim_overlay.name = "awesome_dim_overlay"
+ awful.screen.connect_for_each_screen(function(s)
+ dim_overlay.screen = s -- adjust if you want it per-screen vs spanning all
+ end)
+ -- span the primary screen's geometry (or loop over all screens if you use a multi-monitor dim)
+ local function update_dim_geometry()
+ local geo = screen.primary.geometry
+ dim_overlay:geometry(geo)
+ end
+ update_dim_geometry()
+ screen.connect_signal("property::geometry", update_dim_geometry)
+ -- expose functions over awesome-client
+ _G.show_dim = function() dim_overlay.visible = true end
+ _G.hide_dim = function() dim_overlay.visible = false end
+ -- Prime the overlay invisibly at startup. While it is fully
+ -- transparent we map it once, so picom plays and finishes its one-time
+ -- "open" animation now -- with alpha 00 there is nothing to see, so no
+ -- flash. We then hide it and swap in the real dim colour. Every later
+ -- show_dim() is a re-map ("show"), which picom doesn't animate, so the
+ -- overlay simply appears: no startup flash, no grow.
+ dim_overlay.visible = true
+ gears.timer.start_new(1.0, function()
+ dim_overlay.visible = false
+ dim_overlay.bg = DIM_BG
+ return false -- one-shot
+ end)
end
-
bar_setup()
-- ================================================
@@ -435,7 +393,6 @@ awful.rules.rules = {
properties = { floating = false, },
callback = function(c)
awful.client.setslave(c)
-
local t = c.first_tag
if t then
t.master_width_factor = 0.67
@@ -453,20 +410,16 @@ client.connect_signal("manage", function(c)
end
-- New windows open into the stack (to the right); first window becomes master.
if not awesome.startup then awful.client.setslave(c) end
- -- 0 or ie 13 = corner radius
+ -- 0 or ie 13 = corner radius
c.shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 0) end
end)
-
client.connect_signal("property::floating", function(c)
if c.floating and c.type ~= "notification" then awful.placement.centered(c, { honor_workarea = true }) end
end)
-
client.connect_signal("manage", function(c)
if c.floating and c.type ~= "notification" then awful.placement.centered(c, { honor_workarea = true }) end
end)
-
-- Focus follows mouse (i3-like). Comment out for click-to-focus only.
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)
diff --git a/config/picom/picom.conf b/config/picom/picom.conf
index e973138..2217432 100644
--- a/config/picom/picom.conf
+++ b/config/picom/picom.conf
@@ -7,7 +7,7 @@ fade-out-step = 0.04;
#################################
# Corners #
#################################
-# corner-radius = 0;
+corner-radius = 5;
#################################
# FAST SNAPPY ANIMATIONS #