Hier soll es heute um eine kurze Vorstellung meines awesome-Systems gehen, das wir hier am Papier nachbasteln werden. Soviel zum T(e)ilen.
... und das Herrschen?
Der AwesomeWM ist ein tastaturgetriebener dynamischer Tiler, der dir die volle Kontrolle über so gut wie sämtliche Aspekte deiner Oberfläche gibt. Konfiguriert wird der Fenstermanager in Lua. Ups!
Das Gute daran - du musst Lua nicht beherrschen um über dein System herrschen zu können. Ein bisschen Grübeln reicht schon...
Warum gerade Awesome?!
Die Gründe, sich seine eigene Oberfläche zu basteln sind vielfältig, unzählige Male diskutiert worden und für jeden von uns (mit Überschneidungen) sicher andere. Ganz konkret waren es bei mir die zunehmende Unzufriedenheit mit meinem vorher genutzten Desktop Environment (MATE), das Reflektieren und Überdenken meiner Arbeitsweise am Rechner und sicher auch einfach die Lust, es zu auszuprobieren.
Nachdem ich mich selbst beim Arbeiten am Rechner bewusst beobachtet habe, ist mir klar geworden, dass ich mir um Fenstergrößen eigentlich keinerlei Gedanken machen will. Ich will ganz einfach, dass meine aktuelles Fenster immer möglichst groß ist und wenn ich mehrere brauche, dann sollen sie sich den Raum (meistens) einfach teilen. Bitte kein Herumschieben und an Fenstern zerren!
Und nachdem es mir irgendwann auch zu blöd wurde, mit meinem Laptop immer auch noch eine Mouse mitzuschleppen, sah ich mich nach tastaturgetriebenen Programmen um. Das mal zusammengenommen brachte mich schon zu dynamischen Tilern.
Awesome wurde es dann, weil ich über ein Video gestolpert war, das mir gefallen hat, es hat mich einfach angesprochen. Der Fenstermanager bringt eine gut funktionierende Taskbar mit, die sich auch ganz gut editieren lässt und - das war für mich der Knaller - eine Art Hilfesystem. Doch dazu ein andermal mehr... Die Dokumentation ist - ich drücke mich vorsichtig aus - ausführlich und auch sonst findet man im Netz jede Menge Hacks. Insgesamt hat man jegliche Freiheiten, die man sich nur wünschen kann, steigt aber nicht ganz bei Null ein. Im Endeffekt war es dann Bauchsache.
Doch genug der langen Worte, legen wir los.
Installation
An Vorarbeit brauchen wir zuerst natürlich mal ein Debian Grundystem inklusive der System-Utils (tasksel). Und richtig, ich installiere nicht im Expertenmodus, ich stelle mir einfach ein Bier auf die Entertaste. Nachdem das erledigt ist, installieren wir für mein Awesome-Grundsystem folgende Abhängigkeiten:
Code: Alles auswählen
Grundlegendes:
apt install xorg lxpolkit iwd awesome lxterminal
Benötigtes:
apulse alsa-utils avahi-daemon dosfstools fd-find firefox-esr firefox-esr-l10n-de fzf galculator gsimplecal
htop libglib2.0-bin micro mpv ntfs-3g rofi scrot suckless-tools systemd-resolved trash-cli xautolock
Benötigtes ohne Schnickschnack (no-install-recommends):
gir1.2-notify-0.7 lf udiskie unzip volumeicon-alsa
Vielen wird hier aber zB. ein grafischer Dateimanager (das ist bei mir ja "nur" lf) fehlen oder ein grafisches Frontend für iwd - das Netzwerken erledige ich (ein Dank geht raus an Margot) mit einem selbstgebauten Deb von iwgtk.
Und fast hätte ich's vergessen, wir brauchen auch noch die Hack Nerd Font und die awesomewm-font.ttf in ~/.local/share/fonts.
Nachdem das erledigt ist, geht es endlich an die
Konfiguration von Awesome
Zuallererst braucht es
Code: Alles auswählen
mkdir -p ~/.config/awesome/awsmwidgets
Und nun zur eigentlichen Konfiguration von Awesome, den beiden Dateien rc.lua und theme.lua.
Vorneweg, vor allem in der rc.lua habe ich mit der Zeit kräftig herumgekürzt und -geschachtelt, vor allem habe ich das grafische Menü sowie die meisten Mouse-Definitionen rausgeschmissen. Eine vollständige Dokumentation oder ein Vergleich der vanilla rc.lua mit meiner persönlichen würde hier sowohl den Rahmen als auch mein Wissen sprengen. Sehr vieles war Githubpiraterie, sehr viel anderes einfach Versuch und Irrtum.
Sollten konkrete Fragen oder Alternativen aufkommen, kann das ja vielleicht in einer Diskussion besprochen werden. Einige -- ## Kommentare in der rc.lua werde ich machen. Los geht's:
Code: Alles auswählen
-- █▀▄ ▄▀▀ █ █ █ ▄▀▄ ~/.config/awesome/rc.lua
-- █▀▄ ▀▄▄ ▄ █▄▄ ▀▄█ █▀█ https://awesomewm.org/doc/api/
-- https://awesomewm.org/doc/api/documentation/05-awesomerc.md.html
-- libraries & widgets
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
local wibox = require("wibox")
local beautiful = require("beautiful")
local naughty = require("naughty")
local hotkeys_popup = require("awful.hotkeys_popup")
require("awful.hotkeys_popup.keys")
-- errors
if awesome.startup_errors then
naughty.notify({ preset = naughty.config.presets.critical,
title = "Oops, there were errors 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 = "Oops, an error happened!",
text = tostring(err) })
in_error = false
end)
end
-- definitions
beautiful.init("/home/sebastian/.config/awesome/theme.lua")
terminal = "lxterminal"
editor = os.getenv("EDITOR") or "micro"
editor_cmd = terminal .. " -e " .. editor
modkey = "Mod4"
-- layouts
-- ## Ich brauche praktisch nur zwei Layouts, Vollbild u. Master-Stack.
-- ## Floating schiebe ich entweder aktiv per Tastenkombination an oder per Rule:
awful.layout.layouts = {
awful.layout.suit.max,
awful.layout.suit.tile,
}
-- bar, barnavigation & wallpaper
mytextclock = wibox.widget.textclock(" %d/%m/%Y %H:%M ", 60)
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end))
local tasklist_buttons = gears.table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
c:emit_signal(
"request::activate",
"tasklist",
{raise = true}
)
end
end))
local function set_wallpaper(s)
if beautiful.wallpaper then
local wallpaper = beautiful.wallpaper
if type(wallpaper) == "function" then
wallpaper = wallpaper(s)
end
gears.wallpaper.maximized(wallpaper, s, true)
end
end
screen.connect_signal("property::geometry", set_wallpaper)
-- ## Deshalb die Awesome-Font, ich brauche allerdings nur 4 Arbeitsplätze/Tags:
awful.screen.connect_for_each_screen(function(s)
set_wallpaper(s)
awful.tag({ "A", "W", "S", "M" }, s, awful.layout.layouts[1])
s.mylayoutbox = awful.widget.layoutbox(s)
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
buttons = taglist_buttons
}
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = tasklist_buttons
}
s.mywibox = awful.wibar({ position = "top", screen = s })
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- left widgets
layout = wibox.layout.fixed.horizontal,
s.mytaglist,
},
-- middle widget
s.mytasklist,
{ -- right widgets
layout = wibox.layout.fixed.horizontal,
wibox.widget.systray(),
-- ## Hier jetzt das Batterywidget, das wir zuvor angelegt haben:
require("awsmwidgets.batterywidget") {},
mytextclock,
s.mylayoutbox,
},
}
end)
-- keys
globalkeys = gears.table.join(
-- awesome
awful.key({ modkey }, "l", function () awful.spawn.with_shell("slock") end,
{description = "lock screen", group = "awesome"}),
awful.key({ modkey, }, "h", hotkeys_popup.show_help,
{description="help keybindings", group="awesome"}),
awful.key({ modkey, }, "Escape", function () awful.util.spawn("rofi -show power:/home/sebastian/.config/rofi/rofipowermanager -theme /home/sebastian/.config/rofi/rofiruntheme.rasi") end,
{description="power", group="awesome"}),
awful.key({ modkey, "Control" }, "r", awesome.restart,
{description = "reload gui", group = "awesome"}),
awful.key({ modkey, "Control" }, "q", awesome.quit,
{description = "quit gui", group = "awesome"}),
-- ## Dmenu als Runprompt (Backup, falls Rofi mal nicht wollen sollte):
awful.key({ modkey }, "F2", function () awful.util.spawn("dmenu_run -fn 'Monospace-14' -p drun:") end,
{description = "drun", group = "awesome"}),
-- clients
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.byidx( 1)
end,
{description = "nächster client", group = "clients"}
),
awful.key({ modkey, }, "^",
function ()
awful.client.focus.byidx(-1)
end,
{description = "vorheriger client", group = "clients"}
),
-- launchers
-- ## Wichtigste Programme:
awful.key({ modkey }, "Return", function () awful.spawn(terminal) end,
{description = "terminal", group = "launchers"}),
awful.key({ modkey }, "Print", function () awful.spawn.with_shell("scrot -s -q 85 '/home/sebastian/dwn/scrot_%Y%m%d_%H%M%S.png'") end,
{description = "scrot select", group = "launchers"}),
awful.key({ modkey, "Control" }, "Print", function () awful.spawn.with_shell("scrot -d 5 -q 85 '/home/sebastian/dwn/scrot_%Y%m%d_%H%M%S.png'") end,
{description = "scrot 5sec", group = "launchers"}),
awful.key({}, "Print", function () awful.spawn.with_shell("scrot -q 85 '/home/sebastian/dwn/scrot_%Y%m%d_%H%M%S.png'") end,
{description = "scrot", group = "launchers"}),
awful.key({ modkey, "Control" }, "e", function () awful.spawn.with_shell("udiskie-umount --detach -a") end,
{description = "eject all media", group = "launchers"}),
-- ## Mein Notizzettel:
awful.key({ modkey }, "p", function () awful.spawn(terminal.." -e 'micro /home/sebastian/dox/zeuch/pin.txt'") end,
{description = "pinzettel", group = "launchers"}),
awful.key({ modkey }, "k", function () awful.util.spawn("gsimplecal") end,
{description = "kalender", group = "launchers"}),
awful.key({ modkey }, "m", function () awful.spawn(terminal.." -e 'micro'") end,
{description = "micro", group = "launchers"}),
awful.key({ modkey }, "r", function () awful.util.spawn("galculator") end,
{description = "rechner", group = "launchers"}),
awful.key({ modkey }, "i", function () awful.util.spawn("iwgtk") end,
{description = "iwgtk", group = "launchers"}),
-- ## Mein Linux-Schummelzettel:
awful.key({ modkey }, "c", function () awful.spawn(terminal.." -e 'less dox/syszeug/cstx'") end,
{description = "cheatsheet", group = "launchers"}),
-- layout
awful.key({ modkey, }, "+", function () awful.tag.incmwfact( 0.05) end,
{description = "verbreitere master", group = "layout"}),
awful.key({ modkey, }, "-", function () awful.tag.incmwfact(-0.05) end,
{description = "verschmälere master", group = "layout"}),
awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
{description = "layoutwechsel", group = "layout"}),
-- navigation
-- ## Schnellzugriff auf meine wichtigsten Ordner:
awful.key({ modkey, "Mod1" }, "b", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/bh/2023'") end,
{description = "buchhaltung", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "d", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dwn/'") end,
{description = "dwn", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "s", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/syszeug/'") end,
{description = "syszeug", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "z", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/zeuch/'") end,
{description = "zeuch", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "x", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/'") end,
{description = "dox", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "v", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/vlgn/'") end,
{description = "vorlagen", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "p", function () awful.spawn(terminal.." -e 'lf /home/sebastian/pix/'") end,
{description = "pix", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "j", function () awful.spawn(terminal.." -e 'lf /home/sebastian/dox/jobs/'") end,
{description = "jobs", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "m", function () awful.spawn(terminal.." -e 'lf /media/sebastian/'") end,
{description = "media", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "c", function () awful.spawn(terminal.." -e 'lf /home/sebastian/.config/'") end,
{description = "configs", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "t", function () awful.spawn(terminal.." -e 'lf /home/sebastian/.local/share/Trash/files/'") end,
{description = "trash", group = "navigation"}),
awful.key({ modkey, "Mod1" }, "h", function () awful.spawn(terminal.." -e 'lf /home/sebastian/'") end,
{description = "home", group = "navigation"}),
-- rofi
-- ## Rofi erledigt bei mir so gut wie alles: Powermenü, Lesezeichen für den Browser, Websuche, Man-Suche,
-- ## Programmlauncher + Fensterwechsler, Dateisuche und Schnellzugriff auf wichtigste Konfigurationsdateien:
awful.key({ modkey }, "b", function () awful.util.spawn("/home/sebastian/.config/rofi/rofibookmarks") end,
{description = "bookmarks", group = "rofi"}),
awful.key({ modkey }, "w", function () awful.util.spawn("/home/sebastian/.config/rofi/rofiwebsearch") end,
{description = "websuche", group = "rofi"}),
awful.key({ modkey }, "ß", function () awful.util.spawn("/home/sebastian/.config/rofi/rofimans") end,
{description = "manpages", group = "rofi"}),
awful.key({ "Control" }, "space", function () awful.util.spawn("rofi -combi-modi window,drun -show combi") end,
{description = "progs", group = "rofi"}),
awful.key({ modkey }, "s", function () awful.util.spawn("/home/sebastian/.config/rofi/rofifinder") end,
{description = "suche", group = "rofi"}),
awful.key({ modkey }, "e", function () awful.util.spawn("/home/sebastian/.config/rofi/rofiedits") end,
{description = "edit configs", group = "rofi"}),
-- tag
awful.key({ modkey, }, "Left", awful.tag.viewprev,
{description = "zeige vorherigen tag", group = "tag"}),
awful.key({ modkey, }, "Right", awful.tag.viewnext,
{description = "zeige nächsten tag", group = "tag"})
)
-- more clients
clientkeys = gears.table.join(
awful.key({ modkey, }, "f",
function (c)
c.fullscreen = not c.fullscreen
c:raise()
end,
{description = "fenster fullscreen", group = "clients"}),
awful.key({ modkey }, "q", function (c) c:kill() end,
{description = "quit client", group = "clients"}),
awful.key({ modkey, "Control" }, "Right", awful.client.floating.toggle ,
{description = "fenster (un)floating", group = "clients"}),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
{description = "aktiven auf master", group = "clients"}),
awful.key({ modkey, }, "Up",
function (c)
c.maximized = not c.maximized
c:raise()
end ,
{description = "(un)maximize", group = "clients"})
)
-- tagkeys
for i = 1, 4 do
globalkeys = gears.table.join(globalkeys,
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then
tag:view_only()
end
end,
{description = "zeige tag", group = "tag"}),
awful.key({ modkey, "Control" }, "#" .. 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 = "pin client an tag", group = "tag"})
)
end
clientbuttons = gears.table.join(
awful.button({ }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
end),
awful.button({ modkey }, 1, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.move(c)
end),
awful.button({ modkey }, 3, function (c)
c:emit_signal("request::activate", "mouse_click", {raise = true})
awful.mouse.client.resize(c)
end)
)
root.keys(globalkeys)
-- rules
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
}
},
-- floating clients
{ rule_any = {
instance = {
"DTA",
"pinentry",
"iwgtk",
},
class = {
"Galculator",
"Gpick",
"MessageWin"},
name = { },
role = {
"AlarmWindow",
"ConfigManager",
"pop-up",
}
},
properties = { floating = true,
ontop = true }},
}
-- signals
client.connect_signal("manage", function (c)
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
awful.placement.no_offscreen(c)
end
end)
-- sloppy focus
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)
-- eof
Code: Alles auswählen
-- ▀█▀ █▄█ ██▀ █▄ ▄█ ██▀ █ █ █ ▄▀▄ ~/.config/awesome/rc.lua
-- █ █ █ █▄▄ █ ▀ █ █▄▄ ▄ █▄▄ ▀▄█ █▀█
local themes_path = require("gears.filesystem").get_themes_dir()
local dpi = require("beautiful.xresources").apply_dpi
-- theme & wallpaper
local theme = {}
theme.wallpaper = "/home/sebastian/dox/syszeug/wp/wpawdebgnu.jpg"
-- font & taskbar
theme.font = "Hack Nerd Font Mono Regular 12"
theme.fg_normal = "#DCDCCC"
theme.fg_focus = "#A5C33F"
theme.fg_urgent = "#CC9393"
theme.bg_normal = "#2F343F"
theme.bg_focus = "#1C1C1C"
theme.bg_urgent = "#3F3F3F"
theme.bg_systray = theme.bg_normal
-- taglist
theme.taglist_fg_focus = "#A5C33F"
theme.taglist_fg_occupied = "#3992af"
theme.taglist_fg_urgent = "#F06060"
theme.taglist_fg_empty = "#828282"
theme.taglist_spacing = 2
theme.taglist_font = "awesomewm-font 13"
theme.taglist_squares_sel = themes_path .. "zenburn/taglist/squarefz.png"
theme.taglist_squares_unsel = themes_path .. "zenburn/taglist/squarez.png"
-- borders
theme.useless_gap = dpi(3)
theme.border_width = dpi(1)
theme.border_normal = "#3F3F3F"
theme.border_focus = "#6F6F6F"
theme.border_marked = "#CC9393"
-- mouse
theme.mouse_finder_color = "#CC9393"
-- layouticons
theme.layout_tile = themes_path .. "zenburn/layouts/tile.png"
theme.layout_tileleft = themes_path .. "zenburn/layouts/tileleft.png"
theme.layout_tilebottom = themes_path .. "zenburn/layouts/tilebottom.png"
theme.layout_tiletop = themes_path .. "zenburn/layouts/tiletop.png"
theme.layout_fairv = themes_path .. "zenburn/layouts/fairv.png"
theme.layout_fairh = themes_path .. "zenburn/layouts/fairh.png"
theme.layout_spiral = themes_path .. "zenburn/layouts/spiral.png"
theme.layout_dwindle = themes_path .. "zenburn/layouts/dwindle.png"
theme.layout_max = themes_path .. "zenburn/layouts/max.png"
theme.layout_fullscreen = themes_path .. "zenburn/layouts/fullscreen.png"
theme.layout_magnifier = themes_path .. "zenburn/layouts/magnifier.png"
theme.layout_floating = themes_path .. "zenburn/layouts/floating.png"
theme.layout_cornernw = themes_path .. "zenburn/layouts/cornernw.png"
theme.layout_cornerne = themes_path .. "zenburn/layouts/cornerne.png"
theme.layout_cornersw = themes_path .. "zenburn/layouts/cornersw.png"
theme.layout_cornerse = themes_path .. "zenburn/layouts/cornerse.png"
return theme
Code: Alles auswählen
#!/bin/sh
# ▀▄▀ █ █▄ █ █ ▀█▀ █▀▄ ▄▀▀ ~/.xinitrc
# ▄ █ █ █ █ ▀█ █ █ █▀▄ ▀▄▄
xset -dpms s off &
/usr/bin/lxpolkit &
xautolock -time 5 -locker slock &
volumeicon &
udiskie &
exec awesome
Nachdem ein Postinstall-Skript dann noch meine restlichen Konfigurationsdateien für mich an die richtigen Stellen setzt und Nichtgebrauchtes wegpurged - ist der Rest:
Tilen und herrschen.