chore!: separated galaxy deps and own collections; modified ansible script generation to use two paths for collections

REQUIRES REGENERATING ansible.cfg!
This commit is contained in:
NaeiKinDus 2025-02-23 00:00:00 +00:00
parent 4af69c31ce
commit 888590ed9f
Signed by: WoodSmellParticle
GPG key ID: 8E52ADFF7CA8AE56
188 changed files with 30 additions and 30 deletions

View file

@ -0,0 +1,4 @@
---
workstation_user_account: "{{ custom_base_user_account }}"
workstation_github_token: "{{ custom_github_token | default('') }}"
workstation_setup_xorg_enabled: false

View file

@ -0,0 +1,22 @@
---
galaxy_info:
author: Florian L.
namespace: nullified
description: Install workstation environment
# issue_tracker_url: http://example.com/issue/tracker
license: MIT
min_ansible_version: 2.15
# https://galaxy.ansible.com/api/v1/platforms/
platforms:
- name: Debian
versions:
- bookworm
galaxy_tags:
- github
- assets
- utils
- system
dependencies: []

View file

@ -0,0 +1,242 @@
---
- name: '[home] get user account information'
ansible.builtin.getent:
database: passwd
key: "{{ workstation_user_account }}"
split: ":"
changed_when: false
when: ansible_facts['getent_passwd'] is undefined or workstation_user_account not in ansible_facts['getent_passwd']
- name: '[setup] ensure expected home directories exist'
become: true
ansible.builtin.file:
path: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/{{ item }}"
state: directory
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
mode: '0750'
loop:
- .local/bin
- .local/share/applications
- name: '[apt] install dependencies and tools'
become: true
ansible.builtin.apt:
update_cache: true
force_apt_get: true
cache_valid_time: 3600
pkg:
- apt-file
- curl
- dbus-x11 # terminator
- diffpdf
- feh
- ffmpeg
- flatpak
- gettext # terminator
- gir1.2-keybinder-3.0 # terminator
- gir1.2-vte-2.91 # terminator
- gnupg2
- gvfs-backends
- intltool # terminator
- mesa-utils
- mpc
- mpd
- mpv
- ncmpcpp
- numlockx
- openssh-server
- pass
- poppler-utils
- pwgen
- python3-configobj # terminator
- python3-gi # terminator
- python3-gi-cairo # terminator
- python3-pip
- python3-psutil # terminator
- python3-setuptools # terminator
- ruby
- ruby-dev
- scrot
- smbclient
- socat
- sshfs
- suckless-tools
- sudo
- unclutter-xfixes
- vlc
- whois
- wireshark
- xdotool
- xsel
- xserver-xephyr
state: present
- name: '[setup] add user to sudo group'
become: true
ansible.builtin.user:
name: "{{ workstation_user_account }}"
groups:
- sudo
append: true
- name: '[setup] setup Flatpak'
become: true
become_user: "{{ workstation_user_account }}"
block:
- name: '[flatpak] add flatpak repos'
ansible.builtin.command:
cmd: flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
changed_when: false
- name: '[flatpak] install flatpak apps'
ansible.builtin.command:
cmd: "flatpak install --user --noninteractive {{ item.repo }} {{ item.app }}"
creates: "/var/lib/flatpak/app/{{ item.app }}"
loop:
- repo: flathub
app: com.discordapp.Discord
- repo: flathub
app: md.obsidian.Obsidian
- name: '[github] install tools'
become: true
nullified.infrastructure.github_artifact:
github_token: '{{ workstation_github_token }}'
asset_name: "{{ item.asset_name | default('') }}"
asset_type: "{{ item.asset_type }}"
cmds: "{{ item.cmds | default([]) }}"
creates: "{{ item.creates | default('') }}"
repository: "{{ item.repository }}"
version: "{{ item.version | default('') }}"
loop:
- asset_name: terminator-{version}.tar.gz
asset_type: release
repository: gnome-terminator/terminator
creates: /usr/local/bin/terminator
cmds:
- tar -zxf {asset_dirname}/{asset_filename}
- cd $(find . -maxdepth 1 -name terminator\* -type d); python3 setup.py build; python3 setup.py install --single-version-externally-managed --record=install-files.txt
- rm -rf {asset_dirname}/{asset_filename}
- asset_name: noseyparker-{version}-x86_64-unknown-linux-gnu.tar.gz
asset_type: release
repository: praetorian-inc/noseyparker
creates: /usr/local/bin/noseyparker
cmds:
- tar -zxf {asset_dirname}/{asset_filename}
- install --group=root --mode=755 --owner=root bin/noseyparker /usr/local/bin
- name: '[ruby] install tools'
become: true
ansible.builtin.command:
cmd: "gem install {{ item.app }}"
creates: "{{ item.creates }}"
loop:
- app: mdless
creates: /usr/local/bin/mdless
- name: '[system] setup various directories'
become: true
ansible.builtin.file:
path: "{{ item.path }}"
mode: "{{ item.mode | default('0750') }}"
owner: "{{ item.owner | default(workstation_user_account) }}"
group: "{{ item.group | default(workstation_user_account) }}"
state: directory
loop:
- { path: '/srv/git/foss' }
- { path: '/srv/git/perso' }
- { path: '/srv/git/work' }
- { path: '/srv/storage' }
- name: '[emacs] fetch emacs configuration files'
become: true
become_user: "{{ workstation_user_account }}"
ansible.builtin.git:
repo: "https://gitlab.0x2a.ninja/naeikindus/emacsd.git"
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.emacs.d"
force: false
- name: '[config] set tools configuration'
become: true
become_user: "{{ workstation_user_account }}"
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode | default('0640') }}"
loop:
- { src: "../templates/.config/terminator", dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.config" }
- { src: "../templates/.config/vlc", dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.config" }
- name: '[authenticator] find if binary is already installed'
ansible.builtin.file:
path: /opt/yubico-authenticator/authenticator
register: authenticator_stat
changed_when: false
failed_when: false
- name: '[yubico] install authenticator'
become: true
when: authenticator_stat.state is match("absent")
block:
- name: '[yubico] prepare target directory'
ansible.builtin.file:
path: "{{ item }}"
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
mode: '0750'
state: directory
loop:
- /tmp/yubico-unarchive
- /opt/yubico-authenticator
- name: '[yubico] extract data'
ansible.builtin.unarchive:
src: https://developers.yubico.com/yubioath-flutter/Releases/yubico-authenticator-latest-linux.tar.gz
remote_src: true
dest: /tmp/yubico-unarchive
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
- name: '[yubico] find extracted directory'
ansible.builtin.command:
cmd: find /tmp/yubico-unarchive -mindepth 1 -maxdepth 1
register: yubico_extract_path
changed_when: false
- name: '[yubico] move extracted data to final dir'
ansible.builtin.copy:
remote_src: true
src: "{{ yubico_extract_path.stdout }}/"
dest: /opt/yubico-authenticator
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
- name: '[yubico] cleanup'
ansible.builtin.file:
path: /tmp/yubico-unarchive
state: absent
- name: '[yubico] create shell wrapper'
ansible.builtin.template:
src: ../templates/bin_wrapper.sh.j2
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.local/bin/authenticator"
mode: '0750'
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
vars:
application: "/opt/yubico-authenticator/authenticator"
- name: '[yubico] create desktop entry'
ansible.builtin.template:
src: ../templates/desktop_app.j2
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.local/share/applications/authenticator.desktop"
mode: '0600'
owner: "{{ workstation_user_account }}"
group: "{{ workstation_user_account }}"
vars:
application:
nodisplay: false
exec_cmd: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.local/bin/authenticator"
name: "Authenticator"
- include_tasks: window_manager.yml

View file

@ -0,0 +1,176 @@
---
- name: '[home] get user account information'
ansible.builtin.getent:
database: passwd
key: "{{ workstation_user_account }}"
split: ":"
changed_when: false
when: ansible_facts['getent_passwd'] is undefined or workstation_user_account not in ansible_facts['getent_passwd']
- name: '[awesomewm] install dependencies'
become: true
ansible.builtin.apt:
update_cache: true
force_apt_get: true
cache_valid_time: 3600
pkg:
- asciidoctor
- build-essential
- cmake
- gir1.2-freedesktop
- gir1.2-gdkpixbuf-2.0
- gir1.2-glib-2.0
- gir1.2-gtk-3.0
- gir1.2-pango-1.0
- imagemagick
- libcairo-gobject2
- libcairo2-dev
- libdbus-1-dev
- libgdk-pixbuf-2.0-dev
- libgirepository1.0-dev
- libglib2.0-dev
- liblua5.4-dev
- liblua5.4-dev
- librsvg2-dev
- libstartup-notification0-dev
- libx11-dev
- libx11-xcb-dev
- libxcb-cursor-dev
- libxcb-icccm4-dev
- libxcb-keysyms1-dev
- libxcb-randr0-dev
- libxcb-shape0-dev
- libxcb-util0-dev
- libxcb-xfixes0-dev
- libxcb-xinerama0-dev
- libxcb-xkb-dev
- libxcb-xrm-dev
- libxcb-xtest0-dev
- libxcb1-dev
- libxdg-basedir-dev
- libxkbcommon-x11-dev
- libxkbcommon-dev
- lua5.4
- luajit2
- menu
- picom
- x11-xserver-utils
- xutils-dev
- name: '[lua-lgi] install lua-lgi'
block:
- name: '[lua-lgi] fetch source'
become: true
become_user: "{{ workstation_user_account }}"
ansible.builtin.git:
repo: https://github.com/lgi-devs/lgi.git
dest: /srv/git/foss/lua-lgi
force: false
register: repo_clone
failed_when:
- repo_clone.failed
- not 'Local modifications exist in the destination' in repo_clone.msg
- name: '[lua-lgi] switch from LUA 5.1 to LUA 5.4'
ansible.builtin.replace:
path: /srv/git/foss/lua-lgi/lgi/Makefile
regexp: '5\.1'
replace: '5.4'
- name: '[lua-lgi] building project'
ansible.builtin.command:
chdir: /srv/git/foss/lua-lgi
cmd: make all
creates: /srv/git/foss/lua-lgi/lgi/corelgilua51.so
environment:
LUA_CFLAGS: "-I/usr/include/lua5.4"
- name: '[lua-lgi] compile and install'
become: true
ansible.builtin.command:
chdir: /srv/git/foss/lua-lgi
cmd: make install
creates: /usr/local/lib/lua/5.4/lgi/corelgilua51.so
environment:
LUA_CFLAGS: "-I/usr/include/lua5.4"
- name: '[lua-lgi] set permissions'
become: true
ansible.builtin.file:
path: '{{ item }}'
mode: 'u=rwX,g=rwX,o=rX'
recurse: true
loop:
- /usr/local/lib/lua
- /usr/local/share/lua/
- name: '[lua-lgi] set permissions'
become: true
ansible.builtin.file:
path: '{{ item }}'
mode: 'u=rwX,g=rwX,o=rX'
loop:
- /usr/local/lib/lua
- /usr/local/share/lua
- name: '[awesomewm] install window manager'
block:
- name: '[awesomewm] fetch source'
become: true
become_user: "{{ workstation_user_account }}"
ansible.builtin.git:
repo: https://github.com/awesomeWM/awesome.git
dest: /srv/git/foss/awesomeWM
force: false
register: repo_clone
failed_when:
- repo_clone.failed
- not 'Local modifications exist in the destination' in repo_clone.msg
- name: '[awesomewm] building project'
become: true
become_user: "{{ workstation_user_account }}"
ansible.builtin.command:
chdir: /srv/git/foss/awesomeWM
cmd: 'make'
creates: /srv/git/foss/awesomeWM/build
environment:
CMAKE_ARGS: "-DWITH_DBUS=ON -DLUA_LIBRARY=/usr/lib/x86_64-linux-gnu/liblua5.4.so.0 -DLUA_INCLUDE_DIR=/usr/include/lua5.4"
- name: '[awesomewm] building project'
become: true
ansible.builtin.command:
chdir: /srv/git/foss/awesomeWM
cmd: make install
creates: /usr/local/bin/awesome
- name: '[awesomewm] setup configuration'
become: true
become_user: "{{ workstation_user_account }}"
block:
- name: '[awesomewm] fetch copycats base'
ansible.builtin.git:
repo: https://github.com/lcpz/awesome-copycats.git
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.config/awesome"
depth: 1
recursive: true
force: false
- name: '[awesomewm] copy customization'
ansible.builtin.copy:
src: ../templates/.config/awesome/
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.config/awesome"
mode: '0640'
- name: '[home] copy X related configuration'
become: true
when: workstation_setup_xorg_enabled is truthy
block:
- name: '[x11] xorg.conf'
ansible.builtin.copy:
src: ../templates/system/xorg.conf
dest: /etc/X11/xorg.conf
mode: '0640'
- name: '[x11] user .xsession'
ansible.builtin.copy:
src: ../templates/.xsession
dest: "{{ ansible_facts['getent_passwd'][workstation_user_account][4] }}/.xsession"

View file

@ -0,0 +1,138 @@
-------------------------------------------------
-- Battery Widget for Awesome Window Manager
-- Shows the battery status using the ACPI tool
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget
-- @author Pavel Makhov
-- @copyright 2017 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local naughty = require("naughty")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
-- acpi sample outputs
-- Battery 0: Discharging, 75%, 01:51:38 remaining
-- Battery 0: Charging, 53%, 00:57:43 until charged
local PATH_TO_ICONS = "/usr/share/icons/Arc/status/symbolic/"
local HOME = os.getenv("HOME")
local battery_widget = wibox.widget {
{
id = "icon",
widget = wibox.widget.imagebox,
resize = true
},
layout = wibox.container.margin(_, 0, 0, 3)
}
-- Popup with battery info
-- One way of creating a pop-up notification - naughty.notify
local notification
local function show_battery_status()
awful.spawn.easy_async([[bash -c 'acpi']],
function(stdout, _, _, _)
naughty.destroy(notification)
notification = naughty.notify{
text = stdout,
title = "Battery status",
timeout = 5, hover_timeout = 0.5,
width = 200,
}
end
)
end
-- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one
--battery_popup = awful.tooltip({objects = {battery_widget}})
-- To use colors from beautiful theme put
-- following lines in rc.lua before require("battery"):
-- beautiful.tooltip_fg = beautiful.fg_normal
-- beautiful.tooltip_bg = beautiful.bg_normal
local function show_battery_warning()
naughty.notify{
-- icon = HOME .. "/.config/awesome/nichosi.png",
-- icon_size=100,
text = "Huston, we have a problem",
title = "Battery is dying",
timeout = 5, hover_timeout = 0.5,
position = "bottom_right",
bg = "#F06060",
fg = "#EEE9EF",
width = 300,
}
end
local last_battery_check = os.time()
watch("acpi -i", 10,
function(widget, stdout, stderr, exitreason, exitcode)
local batteryType
local battery_info = {}
local capacities = {}
for s in stdout:gmatch("[^\r\n]+") do
local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*')
if string.match(s, 'rate information') then
-- ignore such line
elseif status ~= nil then
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
else
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
table.insert(capacities, tonumber(cap_str))
end
end
local capacity = 0
for i, cap in ipairs(capacities) do
capacity = capacity + cap
end
local charge = 0
local status
for i, batt in ipairs(battery_info) do
if batt.charge >= charge then
status = batt.status -- use most charged battery status
-- this is arbitrary, and maybe another metric should be used
end
charge = charge + batt.charge * capacities[i]
end
charge = charge / capacity
if (charge >= 0 and charge < 15) then
batteryType = "battery-empty%s-symbolic"
if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
-- if 5 minutes have elapsed since the last warning
last_battery_check = time()
show_battery_warning()
end
elseif (charge >= 15 and charge < 40) then batteryType = "battery-caution%s-symbolic"
elseif (charge >= 40 and charge < 60) then batteryType = "battery-low%s-symbolic"
elseif (charge >= 60 and charge < 80) then batteryType = "battery-good%s-symbolic"
elseif (charge >= 80 and charge <= 100) then batteryType = "battery-full%s-symbolic"
end
if status == 'Charging' then
batteryType = string.format(batteryType, '-charging')
else
batteryType = string.format(batteryType, '')
end
widget.icon:set_image(PATH_TO_ICONS .. batteryType .. ".svg")
-- Update popup text
-- battery_popup.text = string.gsub(stdout, "\n$", "")
end,
battery_widget)
battery_widget:connect_signal("mouse::enter", function() show_battery_status() end)
battery_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
return battery_widget

View file

@ -0,0 +1,759 @@
--[[
Awesome WM configuration template
github.com/lcpz
--]]
-- {{{ Required libraries
local awesome, client, mouse, screen, tag = awesome, client, mouse, screen, tag
local ipairs, string, os, table, tostring, tonumber, type = ipairs, string, os, table, tostring, tonumber, type
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
local wibox = require("wibox")
local beautiful = require("beautiful")
local naughty = require("naughty")
local lain = require("lain")
local menubar = require("menubar")
local freedesktop = require("freedesktop")
local hotkeys_popup = require("awful.hotkeys_popup").widget
require("awful.hotkeys_popup.keys")
local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
local dpi = require("beautiful.xresources").apply_dpi
-- }}}
-- {{{ 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)
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
-- }}}
-- {{{ Autostart windowless processes
-- This function will run once every time Awesome is started
local function run_once(cmd_arr)
for _, cmd in ipairs(cmd_arr) do
awful.spawn.with_shell(string.format("pgrep -u $USER -fx '%s' > /dev/null || (%s)", cmd, cmd))
end
end
run_once({ "unclutter -root", os.getenv("HOME") .. "/bin/autorun.sh" }) -- entries must be separated by commas
-- }}}
-- {{{ Variable definitions
local themes = {
"blackburn", -- 1
"copland", -- 2
"dremora", -- 3
"holo", -- 4
"multicolor", -- 5
"powerarrow", -- 6
"powerarrow-dark", -- 7
"rainbow", -- 8
"steamburn", -- 9
"vertex", -- 10
}
local chosen_theme = themes[6]
local modkey = "Mod4"
local altkey = "Mod1"
local terminal = "terminator"
local vi_focus = false -- vi-like client focus - https://github.com/lcpz/awesome-copycats/issues/275
local cycle_prev = true -- cycle trough all previous client or just the first -- https://github.com/lcpz/awesome-copycats/issues/274
local editor = os.getenv("EDITOR") or "emacs"
local gui_editor = os.getenv("GUI_EDITOR") or "gvim"
local browser = os.getenv("BROWSER") or "firefox"
local scrshooter = os.getenv("SCREENSHOOTER") or "xfce4-screenshooter"
local scrlocker = "slock"
awful.util.terminal = terminal
awful.util.tagnames = { "Web", "Dev", "Admin", "Media" }
awful.layout.layouts = {
awful.layout.suit.tile,
awful.layout.suit.fair,
lain.layout.centerwork
--awful.layout.suit.floating,
--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,
--lain.layout.cascade,
--lain.layout.cascade.tile,
--lain.layout.centerwork,
--lain.layout.centerwork.horizontal,
--lain.layout.termfair,
--lain.layout.termfair.center,
}
awful.util.taglist_buttons = my_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)
)
awful.util.tasklist_buttons = my_table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
--c:emit_signal("request::activate", "tasklist", {raise = true})<Paste>
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
awful.button({ }, 2, function (c) c:kill() end),
awful.button({ }, 3, function ()
local instance = nil
return function ()
if instance and instance.wibox.visible then
instance:hide()
instance = nil
else
instance = awful.menu.clients({theme = {width = dpi(250)}})
end
end
end),
awful.button({ }, 4, function () awful.client.focus.byidx(1) end),
awful.button({ }, 5, function () awful.client.focus.byidx(-1) end)
)
lain.layout.termfair.nmaster = 3
lain.layout.termfair.ncol = 1
lain.layout.termfair.center.nmaster = 3
lain.layout.termfair.center.ncol = 1
lain.layout.cascade.tile.offset_x = dpi(2)
lain.layout.cascade.tile.offset_y = dpi(32)
lain.layout.cascade.tile.extra_padding = dpi(5)
lain.layout.cascade.tile.nmaster = 5
lain.layout.cascade.tile.ncol = 2
beautiful.init(string.format("%s/.config/awesome/themes/%s/theme-personal.lua", os.getenv("HOME"), chosen_theme))
-- }}}
-- {{{ Menu
local myawesomemenu = {
{ "hotkeys", function() return false, hotkeys_popup.show_help end },
{ "manual", terminal .. " -e man awesome" },
{ "edit config", string.format("%s -e %s %s", terminal, editor, awesome.conffile) },
{ "restart", awesome.restart },
{ "quit", function() awesome.quit() end }
}
awful.util.mymainmenu = freedesktop.menu.build({
icon_size = beautiful.menu_height or dpi(16),
before = {
{ "Awesome", myawesomemenu, beautiful.awesome_icon },
-- other triads can be put here
},
after = {
{ "Open terminal", terminal },
-- other triads can be put here
}
})
-- hide menu when mouse leaves it
--awful.util.mymainmenu.wibox:connect_signal("mouse::leave", function() awful.util.mymainmenu:hide() end)
menubar.utils.terminal = terminal -- Set the Menubar terminal for applications that require it
-- }}}
-- {{{ Screen
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
screen.connect_signal("property::geometry", function(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)
-- No borders when rearranging only 1 non-floating or maximized client
screen.connect_signal("arrange", function (s)
local only_one = #s.tiled_clients == 1
for _, c in pairs(s.clients) do
if only_one and not c.floating or c.maximized then
c.border_width = 0
else
c.border_width = beautiful.border_width
end
end
end)
-- Create a wibox for each screen and add it
awful.screen.connect_for_each_screen(function(s) beautiful.at_screen_connect(s) end)
-- }}}
-- {{{ Mouse bindings
root.buttons(my_table.join(
awful.button({ }, 3, function () awful.util.mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = my_table.join(
-- X screen locker
awful.key({ altkey, "Control" }, "l", function () awful.spawn(scrlocker) end,
{description = "lock screen", group = "hotkeys"}),
-- Hotkeys
awful.key({ modkey, }, "s", hotkeys_popup.show_help,
{description = "show help", group="awesome"}),
-- Tag browsing
awful.key({ modkey, }, "Left", awful.tag.viewprev,
{description = "view previous", group = "tag"}),
awful.key({ modkey, }, "Right", awful.tag.viewnext,
{description = "view next", group = "tag"}),
awful.key({ modkey, }, "Escape", awful.tag.history.restore,
{description = "go back", group = "tag"}),
-- Non-empty tag browsing
awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end,
{description = "view previous nonempty", group = "tag"}),
awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end,
{description = "view previous nonempty", group = "tag"}),
-- Default client focus
awful.key({ altkey, }, "j",
function ()
awful.client.focus.byidx( 1)
end,
{description = "focus next by index", group = "client"}
),
awful.key({ altkey, }, "k",
function ()
awful.client.focus.byidx(-1)
end,
{description = "focus previous by index", group = "client"}
),
-- By direction client focus
awful.key({ modkey }, "j",
function()
awful.client.focus.global_bydirection("down")
if client.focus then client.focus:raise() end
end,
{description = "focus down", group = "client"}),
awful.key({ modkey }, "k",
function()
awful.client.focus.global_bydirection("up")
if client.focus then client.focus:raise() end
end,
{description = "focus up", group = "client"}),
awful.key({ modkey }, "h",
function()
awful.client.focus.global_bydirection("left")
if client.focus then client.focus:raise() end
end,
{description = "focus left", group = "client"}),
awful.key({ modkey }, "l",
function()
awful.client.focus.global_bydirection("right")
if client.focus then client.focus:raise() end
end,
{description = "focus right", group = "client"}),
awful.key({ modkey, }, "w", function () awful.util.mymainmenu:show() end,
{description = "show main menu", group = "awesome"}),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
{description = "swap with next client by index", group = "client"}),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
{description = "swap with previous client by index", group = "client"}),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
{description = "focus the next screen", group = "screen"}),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
{description = "focus the previous screen", group = "screen"}),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
{description = "jump to urgent client", group = "client"}),
awful.key({ modkey, }, "Tab",
function ()
if cycle_prev then
awful.client.focus.history.previous()
else
awful.client.focus.byidx(-1)
end
if client.focus then
client.focus:raise()
end
end,
{description = "cycle with previous/go back", group = "client"}),
awful.key({ modkey, "Shift" }, "Tab",
function ()
if cycle_prev then
awful.client.focus.byidx(1)
if client.focus then
client.focus:raise()
end
end
end,
{description = "go forth", group = "client"}),
-- Show/Hide Wibox
awful.key({ modkey }, "b", function ()
for s in screen do
s.mywibox.visible = not s.mywibox.visible
if s.mybottomwibox then
s.mybottomwibox.visible = not s.mybottomwibox.visible
end
end
end,
{description = "toggle wibox", group = "awesome"}),
-- On the fly useless gaps change
awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end,
{description = "increment useless gaps", group = "tag"}),
awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end,
{description = "decrement useless gaps", group = "tag"}),
-- Dynamic tagging
awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag() end,
{description = "add new tag", group = "tag"}),
awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag() end,
{description = "rename tag", group = "tag"}),
awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(-1) end,
{description = "move tag to the left", group = "tag"}),
awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(1) end,
{description = "move tag to the right", group = "tag"}),
awful.key({ modkey, "Shift" }, "d", function () lain.util.delete_tag() end,
{description = "delete tag", group = "tag"}),
-- Standard program
awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
{description = "open a terminal", group = "launcher"}),
awful.key({ modkey, "Control" }, "r", awesome.restart,
{description = "reload awesome", group = "awesome"}),
awful.key({ modkey, "Shift" }, "q", awesome.quit,
{description = "quit awesome", group = "awesome"}),
awful.key({ altkey, "Shift" }, "l", function () awful.tag.incmwfact( 0.05) end,
{description = "increase master width factor", group = "layout"}),
awful.key({ altkey, "Shift" }, "h", function () awful.tag.incmwfact(-0.05) end,
{description = "decrease master width factor", group = "layout"}),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
{description = "increase the number of master clients", group = "layout"}),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
{description = "decrease the number of master clients", group = "layout"}),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
{description = "increase the number of columns", group = "layout"}),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
{description = "decrease the number of columns", group = "layout"}),
awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
{description = "select next", group = "layout"}),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
{description = "select previous", group = "layout"}),
awful.key({ modkey, "Control" }, "n",
function ()
local c = awful.client.restore()
-- Focus restored client
if c then
client.focus = c
c:raise()
end
end,
{description = "restore minimized", group = "client"}),
-- Dropdown application
awful.key({ modkey, }, "z", function () awful.screen.focused().quake:toggle() end,
{description = "dropdown application", group = "launcher"}),
-- Widgets popups
awful.key({ altkey, }, "c", function () if beautiful.cal then beautiful.cal.show(7) end end,
{description = "show calendar", group = "widgets"}),
awful.key({ altkey, }, "h", function () if beautiful.fs then beautiful.fs.show(7) end end,
{description = "show filesystem", group = "widgets"}),
awful.key({ altkey, }, "w", function () if beautiful.weather then beautiful.weather.show(7) end end,
{description = "show weather", group = "widgets"}),
-- Brightness
awful.key({ }, "XF86MonBrightnessUp", function () awful.spawn("xbacklight -inc 10") end,
{description = "+10%", group = "hotkeys"}),
awful.key({ }, "XF86MonBrightnessDown", function () awful.spawn("xbacklight -dec 10") end,
{description = "-10%", group = "hotkeys"}),
-- ALSA volume control
awful.key({ altkey }, "Up",
function ()
awful.spawn(string.format("amixer -q set %s 1%%+", beautiful.volume.channel))
beautiful.volume.update()
end,
{description = "volume up", group = "hotkeys"}),
awful.key({ altkey }, "Down",
function ()
awful.spawn(string.format("amixer -q set %s 1%%-", beautiful.volume.channel))
beautiful.volume.update()
end,
{description = "volume down", group = "hotkeys"}),
awful.key({ altkey }, "m",
function ()
awful.spawn(string.format("amixer -q set %s toggle", beautiful.volume.togglechannel or beautiful.volume.channel))
beautiful.volume.update()
end,
{description = "toggle mute", group = "hotkeys"}),
awful.key({ altkey, "Control" }, "m",
function ()
awful.spawn(string.format("amixer -q set %s 100%%", beautiful.volume.channel))
beautiful.volume.update()
end,
{description = "volume 100%", group = "hotkeys"}),
awful.key({ altkey, "Control" }, "0",
function ()
awful.spawn(string.format("amixer -q set %s 0%%", beautiful.volume.channel))
beautiful.volume.update()
end,
{description = "volume 0%", group = "hotkeys"}),
-- MPD control
awful.key({ altkey, "Control" }, "Up",
function ()
awful.spawn("mpc toggle")
beautiful.mpd.update()
end,
{description = "mpc toggle", group = "widgets"}),
awful.key({ altkey, "Control" }, "Down",
function ()
awful.spawn("mpc stop")
beautiful.mpd.update()
end,
{description = "mpc stop", group = "widgets"}),
awful.key({ altkey, "Control" }, "Left",
function ()
awful.spawn("mpc prev")
beautiful.mpd.update()
end,
{description = "mpc prev", group = "widgets"}),
awful.key({ altkey, "Control" }, "Right",
function ()
awful.spawn("mpc next")
beautiful.mpd.update()
end,
{description = "mpc next", group = "widgets"}),
awful.key({ altkey }, "0",
function ()
local common = { text = "MPD widget ", position = "top_middle", timeout = 2 }
if beautiful.mpd.timer.started then
beautiful.mpd.timer:stop()
common.text = common.text .. lain.util.markup.bold("OFF")
else
beautiful.mpd.timer:start()
common.text = common.text .. lain.util.markup.bold("ON")
end
naughty.notify(common)
end,
{description = "mpc on/off", group = "widgets"}),
-- Copy primary to clipboard (terminals to gtk)
awful.key({ modkey }, "c", function () awful.spawn.with_shell("xsel | xsel -i -b") end,
{description = "copy terminal to gtk", group = "hotkeys"}),
-- Copy clipboard to primary (gtk to terminals)
awful.key({ modkey }, "v", function () awful.spawn.with_shell("xsel -b | xsel") end,
{description = "copy gtk to terminal", group = "hotkeys"}),
-- User programs
awful.key({ modkey }, "q", function () awful.spawn(browser) end,
{description = "run browser", group = "launcher"}),
awful.key({ modkey }, "a", function () awful.spawn(gui_editor) end,
{description = "run gui editor", group = "launcher"}),
awful.key({ }, "Print", function () awful.spawn(scrshooter) end,
{description = "run screenshot program", group = "hotkeys"}),
-- Menubar
awful.key({ modkey }, "p", function() menubar.show() end,
{description = "show the menubar", group = "launcher"}),
-- Prompt
awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
{description = "run prompt", group = "launcher"}),
awful.key({ modkey }, "x",
function ()
awful.prompt.run {
prompt = "Run Lua code: ",
textbox = awful.screen.focused().mypromptbox.widget,
exe_callback = awful.util.eval,
history_path = awful.util.get_cache_dir() .. "/history_eval"
}
end,
{description = "lua execute prompt", group = "awesome"})
--
)
clientkeys = my_table.join(
awful.key({ altkey, "Shift" }, "m", lain.util.magnify_client,
{description = "magnify client", group = "client"}),
awful.key({ modkey, }, "f",
function (c)
c.fullscreen = not c.fullscreen
c:raise()
end,
{description = "toggle fullscreen", group = "client"}),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
{description = "close", group = "client"}),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
{description = "toggle floating", group = "client"}),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
{description = "move to master", group = "client"}),
awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
{description = "move to screen", group = "client"}),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
{description = "toggle keep on top", group = "client"}),
awful.key({ modkey, }, "n",
function (c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end ,
{description = "minimize", group = "client"}),
awful.key({ modkey, }, "m",
function (c)
c.maximized = not c.maximized
c:raise()
end ,
{description = "maximize", group = "client"})
)
-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, 9 do
-- Hack to only show tags 1 and 9 in the shortcut window (mod+s)
local descr_view, descr_toggle, descr_move, descr_toggle_focus
if i == 1 or i == 9 then
descr_view = {description = "view tag #", group = "tag"}
descr_toggle = {description = "toggle tag #", group = "tag"}
descr_move = {description = "move focused client to tag #", group = "tag"}
descr_toggle_focus = {description = "toggle focused client on tag #", group = "tag"}
end
globalkeys = my_table.join(globalkeys,
-- View tag only.
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
tag:view_only()
end
end,
descr_view),
-- Toggle tag display.
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
awful.tag.viewtoggle(tag)
end
end,
descr_toggle),
-- Move client to tag.
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:move_to_tag(tag)
end
end
end,
descr_move),
-- Toggle tag on focused client.
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:toggle_tag(tag)
end
end
end,
descr_toggle_focus)
)
end
clientbuttons = gears.table.join(
awful.button({ }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
end),
awful.button({ modkey }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ modkey }, 3, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.resize(c)
end)
)
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
-- Rules to apply to new clients (through the "manage" signal).
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = awful.client.focus.filter,
raise = true,
keys = clientkeys,
buttons = clientbuttons,
screen = awful.screen.preferred,
placement = awful.placement.no_overlap+awful.placement.no_offscreen,
size_hints_honor = false
}
},
-- Titlebars
{ rule_any = { type = { "dialog", "normal" } },
properties = { titlebars_enabled = true } },
-- Set Firefox to always map on the first tag on screen 1.
{ rule = { class = "Firefox" },
properties = { screen = 1, tag = awful.util.tagnames[1] } },
{ rule = { class = "Gimp", role = "gimp-image-window" },
properties = { maximized = true } },
}
-- }}}
-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c)
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- if not awesome.startup then awful.client.setslave(c) end
if awesome.startup and
not c.size_hints.user_position
and not c.size_hints.program_position then
-- Prevent clients from being unreachable after screen count changes.
awful.placement.no_offscreen(c)
end
end)
-- Add a titlebar if titlebars_enabled is set to true in the rules.
client.connect_signal("request::titlebars", function(c)
-- Custom
if beautiful.titlebar_fun then
beautiful.titlebar_fun(c)
return
end
-- Default
-- buttons for the titlebar
local buttons = my_table.join(
awful.button({ }, 1, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ }, 2, function() c:kill() end),
awful.button({ }, 3, function()
c:emit_signal("request::activate", "titlebar", {raise = true})
awful.mouse.client.resize(c)
end)
)
awful.titlebar(c, {size = dpi(16)}) : setup {
{ -- Left
awful.titlebar.widget.iconwidget(c),
buttons = buttons,
layout = wibox.layout.fixed.horizontal
},
{ -- Middle
{ -- Title
align = "center",
widget = awful.titlebar.widget.titlewidget(c)
},
buttons = buttons,
layout = wibox.layout.flex.horizontal
},
{ -- Right
awful.titlebar.widget.floatingbutton (c),
awful.titlebar.widget.maximizedbutton(c),
awful.titlebar.widget.stickybutton (c),
awful.titlebar.widget.ontopbutton (c),
awful.titlebar.widget.closebutton (c),
layout = wibox.layout.fixed.horizontal()
},
layout = wibox.layout.align.horizontal
}
end)
-- Enable sloppy focus, so that focus follows mouse.
client.connect_signal("mouse::enter", function(c)
c:emit_signal("request::activate", "mouse_enter", {raise = vi_focus})
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)
-- possible workaround for tag preservation when switching back to default screen:
-- https://github.com/lcpz/awesome-copycats/issues/251
-- }}}
-- Test to work around fullscreen game issues
client.connect_signal("property::fullscreen", function(c)
if c.fullscreen then
gears.timer.delayed_call(function()
if c.valid then
c:geometry(c.screen.geometry)
end
end)
end
end)

View file

@ -0,0 +1,386 @@
--[[
Powerarrow Awesome WM theme
github.com/lcpz
--]]
local gears = require("gears")
local lain = require("lain")
local awful = require("awful")
local wibox = require("wibox")
local dpi = require("beautiful.xresources").apply_dpi
local math, string, os = math, string, os
local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
local output_sink_index = 1
local theme = {}
theme.dir = os.getenv("HOME") .. "/.config/awesome/themes/powerarrow"
theme.wallpaper = os.getenv("HOME") .. "/.config/awesome/background.png"
theme.font = "Roboto Slab 9"
theme.fg_normal = "#FEFEFE"
theme.fg_focus = "#32D6FF"
theme.fg_urgent = "#C83F11"
theme.bg_normal = "#222222"
theme.bg_focus = "#1E2320"
theme.bg_urgent = "#3F3F3F"
theme.taglist_fg_focus = "#00CCFF"
theme.tasklist_bg_focus = "#222222"
theme.tasklist_fg_focus = "#00CCFF"
theme.border_width = dpi(2)
theme.border_normal = "#3F3F3F"
theme.border_focus = "#6F6F6F"
theme.border_marked = "#CC9393"
theme.titlebar_bg_focus = "#3F3F3F"
theme.titlebar_bg_normal = "#3F3F3F"
theme.titlebar_bg_focus = theme.bg_focus
theme.titlebar_bg_normal = theme.bg_normal
theme.titlebar_fg_focus = theme.fg_focus
theme.menu_height = dpi(16)
theme.menu_width = dpi(140)
theme.menu_submenu_icon = theme.dir .. "/icons/submenu.png"
theme.awesome_icon = theme.dir .. "/icons/awesome.png"
theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png"
theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png"
theme.layout_tile = theme.dir .. "/icons/tile.png"
theme.layout_tileleft = theme.dir .. "/icons/tileleft.png"
theme.layout_tilebottom = theme.dir .. "/icons/tilebottom.png"
theme.layout_tiletop = theme.dir .. "/icons/tiletop.png"
theme.layout_fairv = theme.dir .. "/icons/fairv.png"
theme.layout_fairh = theme.dir .. "/icons/fairh.png"
theme.layout_spiral = theme.dir .. "/icons/spiral.png"
theme.layout_dwindle = theme.dir .. "/icons/dwindle.png"
theme.layout_max = theme.dir .. "/icons/max.png"
theme.layout_fullscreen = theme.dir .. "/icons/fullscreen.png"
theme.layout_magnifier = theme.dir .. "/icons/magnifier.png"
theme.layout_floating = theme.dir .. "/icons/floating.png"
theme.widget_ac = theme.dir .. "/icons/ac.png"
theme.widget_battery = theme.dir .. "/icons/battery.png"
theme.widget_battery_low = theme.dir .. "/icons/battery_low.png"
theme.widget_battery_empty = theme.dir .. "/icons/battery_empty.png"
theme.widget_brightness = theme.dir .. "/icons/brightness.png"
theme.widget_mem = theme.dir .. "/icons/mem.png"
theme.widget_cpu = theme.dir .. "/icons/cpu.png"
theme.widget_temp = theme.dir .. "/icons/temp.png"
theme.widget_net = theme.dir .. "/icons/net.png"
theme.widget_hdd = theme.dir .. "/icons/hdd.png"
theme.widget_music = theme.dir .. "/icons/note.png"
theme.widget_music_on = theme.dir .. "/icons/note_on.png"
theme.widget_music_pause = theme.dir .. "/icons/pause.png"
theme.widget_music_stop = theme.dir .. "/icons/stop.png"
-- Borrow volume icons from powerarrow-dark
theme.widget_vol = theme.dir .. "/../powerarrow-dark/icons/vol.png"
theme.widget_vol_low = theme.dir .. "/../powerarrow-dark/icons/vol_low.png"
theme.widget_vol_no = theme.dir .. "/../powerarrow-dark/icons/vol_no.png"
theme.widget_vol_mute = theme.dir .. "/../powerarrow-dark/icons/vol_mute.png"
--
theme.widget_mail = theme.dir .. "/icons/mail.png"
theme.widget_mail_on = theme.dir .. "/icons/mail_on.png"
theme.widget_task = theme.dir .. "/icons/task.png"
theme.widget_scissors = theme.dir .. "/icons/scissors.png"
theme.tasklist_plain_task_name = true
theme.tasklist_disable_icon = true
theme.useless_gap = 0
theme.titlebar_close_button_focus = theme.dir .. "/icons/titlebar/close_focus.png"
theme.titlebar_close_button_normal = theme.dir .. "/icons/titlebar/close_normal.png"
theme.titlebar_ontop_button_focus_active = theme.dir .. "/icons/titlebar/ontop_focus_active.png"
theme.titlebar_ontop_button_normal_active = theme.dir .. "/icons/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_inactive = theme.dir .. "/icons/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_inactive = theme.dir .. "/icons/titlebar/ontop_normal_inactive.png"
theme.titlebar_sticky_button_focus_active = theme.dir .. "/icons/titlebar/sticky_focus_active.png"
theme.titlebar_sticky_button_normal_active = theme.dir .. "/icons/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_inactive = theme.dir .. "/icons/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_inactive = theme.dir .. "/icons/titlebar/sticky_normal_inactive.png"
theme.titlebar_floating_button_focus_active = theme.dir .. "/icons/titlebar/floating_focus_active.png"
theme.titlebar_floating_button_normal_active = theme.dir .. "/icons/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_inactive = theme.dir .. "/icons/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_inactive = theme.dir .. "/icons/titlebar/floating_normal_inactive.png"
theme.titlebar_maximized_button_focus_active = theme.dir .. "/icons/titlebar/maximized_focus_active.png"
theme.titlebar_maximized_button_normal_active = theme.dir .. "/icons/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_inactive = theme.dir .. "/icons/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_inactive = theme.dir .. "/icons/titlebar/maximized_normal_inactive.png"
local markup = lain.util.markup
local separators = lain.util.separators
-- Conventional clock
local convclock = wibox.widget.textclock()
-- Calendar
theme.cal = lain.widget.cal({
--cal = "cal --color=always",
--attach_to = { binclock.widget },
attach_to = { convclock },
notification_preset = {
-- font = "Terminus 10",
font = "Roboto Slab 10",
fg = theme.fg_normal,
bg = theme.bg_normal
}
})
-- Taskwarrior
local task = wibox.widget.imagebox(theme.widget_task)
lain.widget.contrib.task.attach(task, {
-- do not colorize output
show_cmd = "task | sed -r 's/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g'"
})
task:buttons(my_table.join(awful.button({}, 1, lain.widget.contrib.task.prompt)))
-- Scissors (xsel copy and paste)
local scissors = wibox.widget.imagebox(theme.widget_scissors)
scissors:buttons(my_table.join(awful.button({}, 1, function() awful.spawn.with_shell("xsel | xsel -i -b") end)))
-- PulseAudio volume
local volicon = wibox.widget.imagebox(theme.widget_vol)
theme.volume = lain.widget.pulse({
settings = function()
if volume_now == nil or volume_now.muted == "yes" then
volicon:set_image(theme.widget_vol_mute)
elseif volume_now.left == "N/A" then
volicon:set_image(theme.widget_vol_no)
elseif tonumber(volume_now.left) == 0 then
volicon:set_image(theme.widget_vol_no)
elseif tonumber(volume_now.left) <= 50 then
volicon:set_image(theme.widget_vol_low)
else
volicon:set_image(theme.widget_vol)
end
widget:set_markup(markup.font(theme.font, " " .. volume_now.left .. "% "))
end
})
theme.volume.widget:buttons(awful.util.table.join(
awful.button({}, 4, function ()
awful.spawn("pactl set-sink-volume " .. output_sink_index .. " +3%")
theme.volume.update()
end),
awful.button({}, 5, function ()
awful.spawn("pactl set-sink-volume " .. output_sink_index .. " -3%")
theme.volume.update()
end)
))
-- MPD
local musicplr = awful.util.terminal .. " --title Music -g 130x34-320+16 -e ncmpcpp"
local mpdicon = wibox.widget.imagebox(theme.widget_music)
mpdicon:buttons(my_table.join(
awful.button({ modkey }, 1, function () awful.spawn.with_shell(musicplr) end),
awful.button({ }, 1, function ()
os.execute("mpc prev")
theme.mpd.update()
end),
awful.button({ }, 2, function ()
os.execute("mpc toggle")
theme.mpd.update()
end),
awful.button({ }, 3, function ()
os.execute("mpc next")
theme.mpd.update()
end)))
theme.mpd = lain.widget.mpd({
settings = function()
if mpd_now.state == "play" then
artist = " " .. mpd_now.artist .. " "
title = mpd_now.title .. " "
mpdicon:set_image(theme.widget_music_on)
widget:set_markup(markup.font(theme.font, markup("#FF8466", artist) .. " " .. title))
elseif mpd_now.state == "pause" then
widget:set_markup(markup.font(theme.font, " mpd paused "))
mpdicon:set_image(theme.widget_music_pause)
else
widget:set_text("")
mpdicon:set_image(theme.widget_music)
end
end
})
-- MEM
local memicon = wibox.widget.imagebox(theme.widget_mem)
local mem = lain.widget.mem({
settings = function()
widget:set_markup(markup.font(theme.font, " " .. mem_now.used .. "MB "))
end
})
-- CPU
local cpuicon = wibox.widget.imagebox(theme.widget_cpu)
local cpu = lain.widget.cpu({
settings = function()
widget:set_markup(markup.font(theme.font, " " .. cpu_now.usage .. "% "))
end
})
-- Coretemp (lain, average)
local temp = lain.widget.temp({
settings = function()
widget:set_markup(markup.font(theme.font, " " .. coretemp_now .. "°C "))
end
})
--
local tempicon = wibox.widget.imagebox(theme.widget_temp)
-- / fs
local fsicon = wibox.widget.imagebox(theme.widget_hdd)
-- commented because it needs Gio/Glib >= 2.54
theme.fs = lain.widget.fs({
-- notification_preset = { fg = theme.fg_normal, bg = theme.bg_normal, font = "Terminus 10" },
notification_preset = { fg = theme.fg_normal, bg = theme.bg_normal, font = "Roboto Slab 10" },
settings = function()
local fsp = string.format(" %3.2f %s ", fs_now["/"].free, fs_now["/"].units)
widget:set_markup(markup.font(theme.font, fsp))
end
})
--
-- Battery
local baticon = wibox.widget.imagebox(theme.widget_battery)
local bat = lain.widget.bat({
settings = function()
if bat_now.status and bat_now.status ~= "N/A" then
if bat_now.ac_status == 1 then
widget:set_markup(markup.font(theme.font, " AC "))
baticon:set_image(theme.widget_ac)
return
elseif not bat_now.perc and tonumber(bat_now.perc) <= 5 then
baticon:set_image(theme.widget_battery_empty)
elseif not bat_now.perc and tonumber(bat_now.perc) <= 15 then
baticon:set_image(theme.widget_battery_low)
else
baticon:set_image(theme.widget_battery)
end
widget:set_markup(markup.font(theme.font, " " .. bat_now.perc .. "% "))
else
widget:set_markup()
baticon:set_image(theme.widget_ac)
end
end
})
-- Net
local neticon = wibox.widget.imagebox(theme.widget_net)
local net = lain.widget.net({
settings = function()
widget:set_markup(markup.fontfg(theme.font, "#FEFEFE", " " .. net_now.received .. " ↓↑ " .. net_now.sent .. " "))
end
})
-- Brigtness
local brighticon = wibox.widget.imagebox(theme.widget_brightness)
-- If you use xbacklight, comment the line with "light -G" and uncomment the line bellow
-- local brightwidget = awful.widget.watch('xbacklight -get', 0.1,
local brightwidget = awful.widget.watch('light -G', 0.1,
function(widget, stdout, stderr, exitreason, exitcode)
local brightness_level = tonumber(string.format("%.0f", stdout))
widget:set_markup(markup.font(theme.font, " " .. brightness_level .. "%"))
end)
-- Separators
local arrow = separators.arrow_left
function theme.powerline_rl(cr, width, height)
local arrow_depth, offset = height/2, 0
-- Avoid going out of the (potential) clip area
if arrow_depth < 0 then
width = width + 2*arrow_depth
offset = -arrow_depth
end
cr:move_to(offset + arrow_depth , 0 )
cr:line_to(offset + width , 0 )
cr:line_to(offset + width - arrow_depth , height/2 )
cr:line_to(offset + width , height )
cr:line_to(offset + arrow_depth , height )
cr:line_to(offset , height/2 )
cr:close_path()
end
local function pl(widget, bgcolor, padding)
return wibox.container.background(wibox.container.margin(widget, dpi(16), dpi(16)), bgcolor, theme.powerline_rl)
end
function theme.at_screen_connect(s)
-- Quake application
s.quake = lain.util.quake({ app = awful.util.terminal })
-- If wallpaper is a function, call it with the screen
local wallpaper = theme.wallpaper
if type(wallpaper) == "function" then
wallpaper = wallpaper(s)
end
gears.wallpaper.maximized(wallpaper, s, true)
-- Tags
awful.tag(awful.util.tagnames, s, awful.layout.layouts)
-- Create a promptbox for each screen
s.mypromptbox = awful.widget.prompt()
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(my_table.join(
awful.button({}, 1, function () awful.layout.inc( 1) end),
awful.button({}, 2, function () awful.layout.set( awful.layout.layouts[1] ) end),
awful.button({}, 3, function () awful.layout.inc(-1) end),
awful.button({}, 4, function () awful.layout.inc( 1) end),
awful.button({}, 5, function () awful.layout.inc(-1) end)))
-- Create a taglist widget
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, awful.util.taglist_buttons)
-- Create a tasklist widget
s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, awful.util.tasklist_buttons)
-- Create the wibox
s.mywibox = awful.wibar({ position = "top", screen = s, height = dpi(16), bg = theme.bg_normal, fg = theme.fg_normal })
-- Add widgets to the wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
--spr,
s.mytaglist,
s.mypromptbox,
spr,
},
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
wibox.container.margin(scissors, dpi(4), dpi(8)),
arrow(theme.bg_normal, theme.bg_normal),
wibox.container.background(wibox.container.margin(wibox.widget { volicon, theme.volume.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(7)), theme.bg_focus),
arrow(theme.bg_normal, "#343434"),
wibox.container.background(wibox.container.margin(wibox.widget { mailicon, theme.mail and theme.mail.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(7)), "#343434"),
arrow("#343434", theme.bg_normal),
wibox.container.background(wibox.container.margin(wibox.widget { mpdicon, theme.mpd.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(6)), theme.bg_focus),
arrow(theme.bg_normal, "#343434"),
wibox.container.background(wibox.container.margin(task, dpi(3), dpi(7)), "#343434"),
arrow("#343434", "#777E76"),
wibox.container.background(wibox.container.margin(wibox.widget { memicon, mem.widget, layout = wibox.layout.align.horizontal }, dpi(2), dpi(3)), "#777E76"),
arrow("#777E76", "#4B696D"),
wibox.container.background(wibox.container.margin(wibox.widget { cpuicon, cpu.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(4)), "#4B696D"),
arrow("#4B696D", "#4B3B51"),
wibox.container.background(wibox.container.margin(wibox.widget { tempicon, temp.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(4)), "#4B3B51"),
arrow("#4B3B51", "#CB755B"),
wibox.container.background(wibox.container.margin(wibox.widget { fsicon, theme.fs and theme.fs.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#CB755B"),
arrow("#CB755B", "#8DAA9A"),
wibox.container.background(wibox.container.margin(wibox.widget { baticon, bat.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#8DAA9A"),
arrow("#8DAA9A", "#C0C0A2"),
wibox.container.background(wibox.container.margin(wibox.widget { nil, neticon, net.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#C0C0A2"),
arrow("#C0C0A2", "#777E76"),
--wibox.container.background(wibox.container.margin(binclock.widget, dpi(4), dpi(8)), "#777E76"),
wibox.container.background(wibox.container.margin(convclock, dpi(4), dpi(8)), "#777E76"),
arrow("#777E76", "alpha"),
--
s.mylayoutbox,
},
}
end
return theme

View file

@ -0,0 +1,21 @@
[global_config]
enabled_plugins = SaveLastSessionLayout, LaunchpadBugURLHandler, LaunchpadCodeURLHandler, APTURLHandler
[keybindings]
[profiles]
[[default]]
background_darkness = 0.8
background_type = transparent
font = JetBrainsMono Nerd Font Mono 10
scrollback_lines = 15000
palette = "#282828:#cc241d:#98971a:#d79921:#458588:#b16286:#689d6a:#a89984:#928374:#fb4934:#b8bb26:#fabd2f:#83a598:#d3869b:#8ec07c:#ebdbb2"
use_system_font = False
copy_on_selection = True
[layouts]
[[default]]
[[[window0]]]
type = Window
parent = ""
[[[child1]]]
type = Terminal
parent = window0
[plugins]

View file

@ -0,0 +1,3 @@
setxkbmap -layout us -variant alt-intl
picom --daemon
exec awesome

View file

@ -0,0 +1,9 @@
#!/usr/bin/env zsh
APP_BIN="{{ application }}"
if [ ! -x "${APP_BIN}" ]; then
printf "%s: target not found" "${APP_BIN}" >&2
fi
exec "${APP_BIN}" "$@"

View file

@ -0,0 +1,8 @@
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
NoDisplay={{ application.nodisplay }}
Exec={{ application.exec_cmd }}
Name={{ application.name }}
Comment={{ application.comment | default(application.name) }}

View file

@ -0,0 +1,105 @@
#############################################
# FILES #
#############################################
Section "Files"
ModulePath "/usr/lib/xorg/modules"
FontPath "/usr/share/fonts/X11/misc"
FontPath "/usr/share/fonts/X11/100dpi/:unscaled"
FontPath "/usr/share/fonts/X11/75dpi/:unscaled"
FontPath "/usr/share/fonts/X11/Type1"
FontPath "/usr/share/fonts/X11/100dpi"
FontPath "/usr/share/fonts/X11/75dpi"
FontPath "built-ins"
EndSection
#############################################
# MODULES #
#############################################
Section "Module"
Load "glx"
EndSection
#############################################
# INPUTDEVICES #
#############################################
Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7"
Option "CorePointer"
EndSection
Section "InputDevice"
Identifier "Keyboard0"
Driver "keyboard"
Option "CoreKeyboard"
Option "XkbRules" "xorg"
EndSection
#############################################
# DEVICES #
#############################################
Section "Device"
Identifier "Card0"
Driver "amdgpu"
Option "Monitor-HDMI-A-0" "VG248"
Option "HDMI-A-0" "VG248"
Option "Monitor-DisplayPort-2" "LG UWQHD"
Option "DisplayPort-2" "LG UWQHD"
Option "Monitor-DisplayPort-0" "LG ULTRAWIDE"
Option "DisplayPort-0" "LG ULTRAWIDE"
EndSection
#############################################
# SERVER LAYOUT #
#############################################
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
Option "Xinerama" "0"
EndSection
#############################################
# SCREENS #
#############################################
Section "Screen"
Identifier "Screen0"
Device "Card0"
EndSection
#############################################
# MONITORS #
#############################################
Section "Monitor"
Identifier "VG248"
ModelName "VG248"
VendorName "ACI"
Option "DPMS" "on"
Option "PreferredMode" "1920x1080"
Option "LeftOf" "DisplayPort-2"
Option "Position" "0 520"
EndSection
Section "Monitor"
Identifier "LG UWQHD"
ModelName "LG UWQHD"
VendorName "GSM"
Option "LeftOf" "DisplayPort-0"
Option "DPMS" "on"
Option "PreferredMode" "3840x1600"
Option "Primary" "true"
Option "Position" "1920 0"
EndSection
Section "Monitor"
Identifier "LG ULTRAWIDE"
ModelName "LG ULTRAWIDE"
VendorName "GSM"
Option "DPMS" "on"
Option "PreferredMode" "3440x1440"
Option "Position" "5760 160"
EndSection

View file

@ -0,0 +1,2 @@
localhost