├── .github └── README.md ├── binds ├── client │ ├── init.lua │ ├── keys.lua │ └── mouse.lua ├── global │ ├── init.lua │ ├── keys.lua │ └── mouse.lua ├── init.lua └── mod.lua ├── config ├── apps.lua ├── rules.lua └── user.lua ├── module └── README.md ├── rc.lua ├── signal ├── client.lua ├── init.lua ├── naughty.lua ├── screen.lua └── tag.lua ├── theme ├── init.lua └── theme.lua └── ui ├── menu └── init.lua ├── notification └── init.lua ├── titlebar ├── init.lua └── normal.lua └── wibar ├── init.lua └── module ├── init.lua ├── launcher.lua ├── layoutbox.lua ├── taglist.lua └── tasklist.lua /.github/README.md: -------------------------------------------------------------------------------- 1 | # Modularized example rc.lua 2 | 3 | This project is essentially a template for my (and your) convenience when 4 | starting a new AwesomeWM configuration. It's loyal to the 5 | [official example](https://github.com/awesomeWM/awesome/blob/master/awesomerc.lua) 6 | , but way more digestible and generally cleaned up. It also contains some 7 | personal notes on useful things I've learned while using AwesomeWM. 8 | 9 | 10 | # Why? 11 | 12 | There exist a few similar projects that aim to make starting out with AWM a 13 | bit easier, but in my opinion, they fail in some regards. They either: 14 | - Abuse global variables and functions. 15 | - Have obtuse and counterintuitive organization. 16 | 17 | I aimed to make something that I found more comfortable to work with, and I'm doing 18 | you the further courtesy of sharing it. Think this is pointless? You're probably 19 | right. 20 | 21 | 22 | # Structure 23 | 24 | This project is divided into different directories that aim to provide cohesive configuration. 25 | - `binds` is fairly straight forward, it contains all key and mouse bindings that the WM uses. 26 | They're additionally split up into client (window) bindings and global (WM) bindings. 27 | - `config` contains general user-preference customization like default applications, layouts, 28 | tag number and names, and WM rules. 29 | - `module` is a dummy directory for you to put community developed modules into. Some common 30 | examples are [rubato](https://github.com/andOrlando/rubato) and 31 | [bling](https://github.com/blingcorp/bling). 32 | - `signal` contains the AwesomeWM signals that trigger events like tag creation and widget 33 | drawing. This one is easier to understand after you've used AWM for a while. 34 | - `theme` is mostly a dummy directory that currently only includes the `beautiful` initialization 35 | but is intended for you to expand with your own themes. An example of this idea can be found 36 | in one of my personal configurations, [gwileful](https://github.com/Gwynsav/gwileful/tree/widgets/theme). 37 | - `ui` contains all widgets and UI elements, providing a table with all of them for easy access. 38 | - And finally, `rc.lua` just calls whatever needs to be called and handles errors. 39 | 40 | 41 | # How do I get started? 42 | 43 | Simply clone the repository into your AwesomeWM configuration directory and start 44 | working! 45 | ```sh 46 | # Assuming that ~/.config exists and is a directory. 47 | git clone https://github.com/gwynsav/modular-awm-default.git ~/.config/awesome 48 | ``` 49 | 50 | 51 | # Any other recommendations? 52 | 53 | Yes! You may be interested in compiling AwesomeWM against LuaJIT as it basically 54 | just performs better. Instructions on how to do this can be found in the [official 55 | AWM documentation](https://awesomewm.org/apidoc/documentation/10-building-and-testing.md.html). 56 | 57 | While we're on the topic of documentation, here's a link to the [official documentation 58 | for the master branch of Awesome](https://awesomewm.org/apidoc). Why the master branch? 59 | Because, as of the end of 2023, the stable release is about 4 years behind in development. 60 | I would recommend against using it as this project **doesn't work with it**. 61 | -------------------------------------------------------------------------------- /binds/client/init.lua: -------------------------------------------------------------------------------- 1 | -- Returns all client mouse and keybinds. 2 | return { 3 | keys = require(... .. '.keys'), 4 | mouse = require(... .. '.mouse') 5 | } 6 | -------------------------------------------------------------------------------- /binds/client/keys.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | local mod = require('binds.mod') 4 | local modkey = mod.modkey 5 | 6 | --- Client keybindings. 7 | client.connect_signal('request::default_keybindings', function() 8 | awful.keyboard.append_client_keybindings({ 9 | -- Client state management. 10 | awful.key({ modkey, }, 'f', 11 | function(c) 12 | c.fullscreen = not c.fullscreen 13 | c:raise() 14 | end, { description = 'toggle fullscreen', group = 'client' }), 15 | awful.key({ modkey, mod.shift }, 'c', function(c) c:kill() end, 16 | { description = 'close', group = 'client' }), 17 | awful.key({ modkey, mod.ctrl }, 'space', awful.client.floating.toggle, 18 | { description = 'toggle floating', group = 'client' }), 19 | awful.key({ modkey, }, 'n', 20 | function(c) 21 | -- The client currently has the input focus, so it cannot be 22 | -- minimized, since minimized clients can't have the focus. 23 | c.minimized = true 24 | end, { description = 'minimize', group = 'client' }), 25 | awful.key({ modkey, }, 'm', 26 | function(c) 27 | c.maximized = not c.maximized 28 | c:raise() 29 | end, { description = '(un)maximize', group = 'client' }), 30 | awful.key({ modkey, mod.ctrl }, 'm', 31 | function(c) 32 | c.maximized_vertical = not c.maximized_vertical 33 | c:raise() 34 | end, { description = '(un)maximize vertically', group = 'client' }), 35 | awful.key({ modkey, mod.shift }, 'm', 36 | function(c) 37 | c.maximized_horizontal = not c.maximized_horizontal 38 | c:raise() 39 | end, { description = '(un)maximize horizontally', group = 'client' }), 40 | 41 | -- Client position in tiling management. 42 | awful.key({ modkey, mod.ctrl }, 'Return', function(c) c:swap(awful.client.getmaster()) end, 43 | { description = 'move to master', group = 'client' }), 44 | awful.key({ modkey, }, 'o', function(c) c:move_to_screen() end, 45 | { description = 'move to screen', group = 'client' }), 46 | awful.key({ modkey, }, 't', function(c) c.ontop = not c.ontop end, 47 | { description = 'toggle keep on top', group = 'client' }) 48 | }) 49 | end) 50 | -------------------------------------------------------------------------------- /binds/client/mouse.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | local mod = require('binds.mod') 4 | local modkey = mod.modkey 5 | 6 | --- Client mouse bindings. 7 | client.connect_signal('request::default_mousebindings', function() 8 | awful.mouse.append_client_mousebindings({ 9 | awful.button(nil, 1, function(c) 10 | c:activate({ context = 'mouse_click' }) 11 | end), 12 | awful.button({ modkey }, 1, function(c) 13 | c:activate({ context = 'mouse_click', action = 'mouse_move' }) 14 | end), 15 | awful.button({ modkey }, 3, function(c) 16 | c:activate({ context = 'mouse_click', action = 'mouse_resize' }) 17 | end) 18 | }) 19 | end) 20 | -------------------------------------------------------------------------------- /binds/global/init.lua: -------------------------------------------------------------------------------- 1 | -- Returns all global WM mouse and keybinds. 2 | return { 3 | keys = require(... .. '.keys'), 4 | mouse = require(... .. '.mouse') 5 | } 6 | -------------------------------------------------------------------------------- /binds/global/keys.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | local mod = require('binds.mod') 4 | local modkey = mod.modkey 5 | 6 | local apps = require('config.apps') 7 | 8 | --- Global key bindings 9 | awful.keyboard.append_global_keybindings({ 10 | -- General Awesome keys. 11 | awful.key({ modkey, }, 's', require('awful.hotkeys_popup').show_help, 12 | { description = 'show help', group = 'awesome' }), 13 | awful.key({ modkey, }, 'w', function() require('ui.menu').main:show() end, 14 | { description = 'show main menu', group = 'awesome' }), 15 | awful.key({ modkey, mod.ctrl }, 'r', awesome.restart, 16 | { description = 'reload awesome', group = 'awesome' }), 17 | awful.key({ modkey, mod.shift }, 'q', awesome.quit, 18 | { description = 'quit awesome', group = 'awesome' }), 19 | awful.key({ modkey }, 'x', function() awful.prompt.run({ 20 | prompt = 'Run Lua code: ', 21 | textbox = awful.screen.focused().mypromptbox.widget, 22 | exe_callback = awful.util.eval, 23 | history_path = awful.util.get_cache_dir() .. '/history_eval' }) 24 | end, { description = 'lua execute prompt', group = 'awesome' }), 25 | awful.key({ modkey, }, 'Return', function() awful.spawn(apps.terminal) end, 26 | { description = 'open a terminal', group = 'launcher' }), 27 | awful.key({ modkey }, 'r', function() awful.screen.focused().mypromptbox:run() end, 28 | { description = 'run prompt', group = 'launcher' }), 29 | awful.key({ modkey }, 'p', function() require('menubar').show() end, 30 | { description = 'show the menubar', group = 'launcher' }), 31 | 32 | -- Tags related keybindings. 33 | awful.key({ modkey, }, 'Left', awful.tag.viewprev, 34 | { description = 'view previous', group = 'tag' }), 35 | awful.key({ modkey, }, 'Right', awful.tag.viewnext, 36 | { description = 'view next', group = 'tag' }), 37 | awful.key({ modkey, }, 'Escape', awful.tag.history.restore, 38 | { description = 'go back', group = 'tag' }), 39 | 40 | -- Focus related keybindings. 41 | awful.key({ modkey, }, 'j', function() awful.client.focus.byidx( 1) end, 42 | { description = 'focus next by index', group = 'client' }), 43 | awful.key({ modkey, }, 'k', function() awful.client.focus.byidx(-1) end, 44 | { description = 'focus previous by index', group = 'client'}), 45 | awful.key({ modkey, }, 'Tab', function() 46 | awful.client.focus.history.previous() 47 | if client.focus then 48 | client.focus:raise() 49 | end 50 | end, { description = 'go back', group = 'client' }), 51 | awful.key({ modkey, mod.ctrl }, 'j', function() awful.screen.focus_relative( 1) end, 52 | { description = 'focus the next screen', group = 'screen' }), 53 | awful.key({ modkey, mod.ctrl }, 'k', function() awful.screen.focus_relative(-1) end, 54 | { description = 'focus the previous screen', group = 'screen' }), 55 | awful.key({ modkey, mod.ctrl }, 'n', function() 56 | local c = awful.client.restore() 57 | -- Focus restored client 58 | if c then 59 | c:activate { raise = true, context = 'key.unminimize' } 60 | end 61 | end, { description = 'restore minimized', group = 'client' }), 62 | 63 | -- Layout related keybindings. 64 | awful.key({ modkey, mod.shift }, 'j', function() awful.client.swap.byidx( 1) end, 65 | { description = 'swap with next client by index', group = 'client' }), 66 | awful.key({ modkey, mod.shift }, 'k', function() awful.client.swap.byidx(-1) end, 67 | { description = 'swap with previous client by index', group = 'client' }), 68 | awful.key({ modkey, }, 'u', awful.client.urgent.jumpto, 69 | { description = 'jump to urgent client', group = 'client' }), 70 | awful.key({ modkey, }, 'l', function() awful.tag.incmwfact( 0.05) end, 71 | { description = 'increase master width factor', group = 'layout' }), 72 | awful.key({ modkey, }, 'h', function() awful.tag.incmwfact(-0.05) end, 73 | { description = 'decrease master width factor', group = 'layout' }), 74 | awful.key({ modkey, mod.shift }, 'h', function() awful.tag.incnmaster( 1, nil, true) end, 75 | { description = 'increase the number of master clients', group = 'layout' }), 76 | awful.key({ modkey, mod.shift }, 'l', function() awful.tag.incnmaster(-1, nil, true) end, 77 | { description = 'decrease the number of master clients', group = 'layout' }), 78 | awful.key({ modkey, mod.ctrl }, 'h', function() awful.tag.incncol( 1, nil, true) end, 79 | { description = 'increase the number of columns', group = 'layout' }), 80 | awful.key({ modkey, mod.ctrl }, 'l', function() awful.tag.incncol(-1, nil, true) end, 81 | { description = 'decrease the number of columns', group = 'layout' }), 82 | awful.key({ modkey, }, 'space', function() awful.layout.inc( 1) end, 83 | { description = 'select next', group = 'layout' }), 84 | awful.key({ modkey, mod.shift }, 'space', function() awful.layout.inc(-1) end, 85 | { description = 'select previous', group = 'layout' }), 86 | awful.key({ 87 | modifiers = { modkey }, 88 | keygroup = 'numrow', 89 | description = 'only view tag', 90 | group = 'tag', 91 | on_press = function(index) 92 | local tag = awful.screen.focused().tags[index] 93 | if tag then tag:view_only() end 94 | end 95 | }), 96 | awful.key({ 97 | modifiers = { modkey, mod.ctrl }, 98 | keygroup = 'numrow', 99 | description = 'toggle tag', 100 | group = 'tag', 101 | on_press = function(index) 102 | local tag = awful.screen.focused().tags[index] 103 | if tag then awful.tag.viewtoggle(tag) end 104 | end 105 | }), 106 | awful.key({ 107 | modifiers = { modkey, mod.shift }, 108 | keygroup = 'numrow', 109 | description = 'move focused client to tag', 110 | group = 'tag', 111 | on_press = function(index) 112 | if client.focus then 113 | local tag = client.focus.screen.tags[index] 114 | if tag then client.focus:move_to_tag(tag) end 115 | end 116 | end 117 | }), 118 | awful.key({ 119 | modifiers = { modkey, mod.ctrl, mod.shift }, 120 | keygroup = 'numrow', 121 | description = 'toggle focused client on tag', 122 | group = 'tag', 123 | on_press = function(index) 124 | if client.focus then 125 | local tag = client.focus.screen.tags[index] 126 | if tag then client.focus:toggle_tag(tag) end 127 | end 128 | end 129 | }), 130 | awful.key({ 131 | modifiers = { modkey }, 132 | keygroup = 'numpad', 133 | description = 'select layout directly', 134 | group = 'layout', 135 | on_press = function(index) 136 | local t = awful.screen.focused().selected_tag 137 | if t then 138 | t.layout = t.layouts[index] or t.layout 139 | end 140 | end 141 | }) 142 | }) 143 | -------------------------------------------------------------------------------- /binds/global/mouse.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | --- Global mouse bindings 4 | awful.mouse.append_global_mousebindings({ 5 | awful.button(nil, 3, function() require('ui.menu').main:toggle() end), 6 | awful.button(nil, 4, awful.tag.viewprev), 7 | awful.button(nil, 5, awful.tag.viewnext) 8 | }) 9 | -------------------------------------------------------------------------------- /binds/init.lua: -------------------------------------------------------------------------------- 1 | -- Returns all mouse and keybinds for both clients and the WM. 2 | return { 3 | global = require(... .. '.global'), 4 | client = require(... .. '.client') 5 | } 6 | -------------------------------------------------------------------------------- /binds/mod.lua: -------------------------------------------------------------------------------- 1 | return { 2 | alt = 'Mod1', 3 | super = 'Mod4', 4 | shift = 'Shift', 5 | ctrl = 'Control', 6 | 7 | -- Set Super as default modkey if none is present. 8 | modkey = require('config.user').mod or 'Mod4' 9 | } 10 | -------------------------------------------------------------------------------- /config/apps.lua: -------------------------------------------------------------------------------- 1 | -- This is used later as the default terminal and editor to run. 2 | local apps = {} 3 | apps.terminal = 'xterm' 4 | apps.editor = os.getenv('EDITOR') or 'vi' 5 | apps.editor_cmd = apps.terminal .. ' -e ' .. apps.editor 6 | 7 | -- Set the terminal for the menubar. 8 | require('menubar').utils.terminal = apps.terminal 9 | 10 | return apps 11 | -------------------------------------------------------------------------------- /config/rules.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local ruled = require('ruled') 3 | 4 | --- Rules. 5 | -- Rules to apply to new clients. 6 | ruled.client.connect_signal('request::rules', function() 7 | -- All clients will match this rule. 8 | ruled.client.append_rule({ 9 | id = 'global', 10 | rule = { }, 11 | properties = { 12 | focus = awful.client.focus.filter, 13 | raise = true, 14 | screen = awful.screen.preferred, 15 | placement = awful.placement.no_overlap + awful.placement.no_offscreen 16 | } 17 | }) 18 | 19 | -- Floating clients. 20 | ruled.client.append_rule({ 21 | id = 'floating', 22 | rule_any = { 23 | instance = { 'copyq', 'pinentry' }, 24 | class = { 25 | 'Arandr', 'Blueman-manager', 'Gpick', 'Kruler', 'Sxiv', 26 | 'Tor Browser', 'Wpa_gui', 'veromix', 'xtightvncviewer' 27 | }, 28 | -- Note that the name property shown in xprop might be set slightly after creation of the client 29 | -- and the name shown there might not match defined rules here. 30 | name = { 31 | 'Event Tester' -- xev. 32 | }, 33 | role = { 34 | 'AlarmWindow', -- Thunderbird's calendar. 35 | 'ConfigManager', -- Thunderbird's about:config. 36 | 'pop-up' -- e.g. Google Chrome's (detached) Developer Tools. 37 | } 38 | }, 39 | properties = { floating = true } 40 | }) 41 | 42 | -- Add titlebars to normal clients and dialogs. 43 | ruled.client.append_rule({ 44 | id = 'titlebars', 45 | rule_any = { type = { 'normal', 'dialog' } }, 46 | properties = { titlebars_enabled = true } 47 | }) 48 | 49 | -- Set Firefox to always map on the tag named '2' on screen 1. 50 | -- ruled.client.append_rule({ 51 | -- rule = { class = 'Firefox' }, 52 | -- properties = { screen = 1, tag = '2' } 53 | -- }) 54 | end) 55 | -------------------------------------------------------------------------------- /config/user.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | -- Specify user preferences for Awesome's behavior. 4 | return { 5 | -- Default modkey. 6 | -- Usually, Mod4 is the key with a logo between Control and Alt. If you do not like 7 | -- this or do not have such a key, I suggest you to remap Mod4 to another key using 8 | -- xmodmap or other tools. However, you can use another modifier like Mod1, but it 9 | -- may interact with others. 10 | mod = 'Mod4', 11 | -- Each screen has its own tag table. You can just define one and append it to all 12 | -- screens (default behavior). 13 | tags = { '1', '2', '3', '4', '5', '6', '7', '8', '9' }, 14 | -- Table of layouts to cover with awful.layout.inc, ORDER MATTERS, the first layout 15 | -- in the table is your DEFAULT LAYOUT. 16 | layouts = { 17 | awful.layout.suit.floating, 18 | awful.layout.suit.tile, 19 | awful.layout.suit.tile.left, 20 | awful.layout.suit.tile.bottom, 21 | awful.layout.suit.tile.top, 22 | awful.layout.suit.fair, 23 | awful.layout.suit.fair.horizontal, 24 | awful.layout.suit.spiral, 25 | awful.layout.suit.spiral.dwindle, 26 | awful.layout.suit.max, 27 | awful.layout.suit.max.fullscreen, 28 | awful.layout.suit.magnifier, 29 | awful.layout.suit.corner.nw 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /module/README.md: -------------------------------------------------------------------------------- 1 | # AwesomeWM Community Modules 2 | 3 | This directory serves as a container for community modules, for easy access in code. 4 | To add submodules like the popular [bling](https://github.com/blingcorp/bling) or 5 | [rubato](https://github.com/andorlando/rubato), either clone their repos into this 6 | directory or add them as submodules of this repository. 7 | 8 | An example file structure would be: 9 | ``` 10 | ~/.config/awesome/ 11 | ... 12 | - module 13 | - bling 14 | ... 15 | init.lua 16 | - rubato 17 | ... 18 | init.lua 19 | - some_mod 20 | ... 21 | init.lua 22 | ... 23 | ... 24 | ``` 25 | 26 | Which would allow you to use these modules anywhere inside the config directory by 27 | simply referencing them as: 28 | ``` 29 | local bling = require('module.bling') 30 | local some_mod = require('module.some_mod') 31 | ``` 32 | 33 | ## Common Community Modules 34 | 35 | - [blingcorp/bling](https://github.com/blingcorp/bling), a collaborative community library 36 | providing several goods like new layouts, widgets, signals and functionality like 37 | scratchpads and tabbing. 38 | - [andOrlando/rubato](https://github.com/andorlando/rubato), an animation library that's 39 | easy to use. Do mind the fact that AWM runs on a **single CPU thread** and animations can 40 | stress it pretty hard, so don't abuse them. 41 | - [Aire-One/awesome-battery_widget](https://github.com/aire-one/awesome-battery_widget), 42 | a simple and quick library providing battery information for laptops. 43 | 44 | And many more. 45 | -------------------------------------------------------------------------------- /rc.lua: -------------------------------------------------------------------------------- 1 | -- awesome_mode: api-level=4:screen=on 2 | -- If LuaRocks is installed, make sure that packages installed through it are 3 | -- found (e.g. lgi). If LuaRocks is not installed, do nothing. 4 | pcall(require, 'luarocks.loader') 5 | 6 | --- Error handling. 7 | -- Notification library. 8 | local naughty = require('naughty') 9 | -- Check if awesome encountered an error during startup and fell back to 10 | -- another config (This code will only ever execute for the fallback config). 11 | naughty.connect_signal('request::display_error', function(message, startup) 12 | naughty.notification({ 13 | urgency = 'critical', 14 | title = 'Oops, an error happened' .. (startup and ' during startup!' or '!'), 15 | message = message 16 | }) 17 | end) 18 | 19 | -- Allow Awesome to automatically focus a client upon changing tags or loading. 20 | require('awful.autofocus') 21 | -- Enable hotkeys help widget for VIM and other apps when client with a matching 22 | -- name is opened: 23 | require('awful.hotkeys_popup.keys') 24 | 25 | -- Load the theme. In other words, defines the variables within the `beautiful` 26 | -- table. 27 | require('theme') 28 | 29 | -- Treat all signals. Bear in mind this implies creating all tags, attaching 30 | -- their layouts, setting client behavior and loading UI. 31 | require('signal') 32 | 33 | -- Set all keybinds. 34 | require('binds') 35 | 36 | -- Load all client rules. 37 | require('config.rules') 38 | -------------------------------------------------------------------------------- /signal/client.lua: -------------------------------------------------------------------------------- 1 | -- Add a titlebar if titlebars_enabled is set to true for the client in `config/rules.lua`. 2 | client.connect_signal('request::titlebars', function(c) 3 | -- While this isn't actually in the example configuration, it's the most sane thing to do. 4 | -- If a client expressly says not to draw titlebars on it, just don't. 5 | if c.requests_no_titlebars then return end 6 | 7 | require('ui.titlebar').normal(c) 8 | end) 9 | 10 | -- Enable sloppy focus, so that focus follows mouse. 11 | client.connect_signal('mouse::enter', function(c) 12 | c:activate({ context = 'mouse_enter', raise = false }) 13 | end) 14 | -------------------------------------------------------------------------------- /signal/init.lua: -------------------------------------------------------------------------------- 1 | -- Allows all signals to be connected and/or emitted. 2 | return { 3 | client = require(... .. '.client'), 4 | -- NOTE: The `tag` file must be loaded before the `screen` one so that 5 | -- the correct layouts defined in `config.user` are appended to the tags 6 | -- upon creation. 7 | tag = require(... .. '.tag'), 8 | screen = require(... .. '.screen') 9 | } 10 | -------------------------------------------------------------------------------- /signal/naughty.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local naughty = require('naughty') 3 | local ruled = require('ruled') 4 | 5 | --- Notifications 6 | ruled.notification.connect_signal('request::rules', function() 7 | -- All notifications will match this rule. 8 | ruled.notification.append_rule({ 9 | rule = nil, 10 | properties = { 11 | screen = awful.screen.preferred, 12 | implicit_timeout = 5 13 | } 14 | }) 15 | end) 16 | 17 | -- Defines the default notification layout. 18 | naughty.connect_signal('request::display', function(n) 19 | require('ui.notification')(n) 20 | end) 21 | -------------------------------------------------------------------------------- /signal/screen.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local beautiful = require('beautiful') 3 | local wibox = require('wibox') 4 | 5 | --- Attach tags and widgets to all screens. 6 | screen.connect_signal('request::desktop_decoration', function(s) 7 | -- Create all tags and attach the layouts to each of them. 8 | awful.tag(require('config.user').tags, s, awful.layout.layouts[1]) 9 | -- Attach a wibar to each screen. 10 | s.bar = require('ui.wibar')(s) 11 | end) 12 | 13 | --- Wallpaper. 14 | -- NOTE: `awful.wallpaper` is ideal for creating a wallpaper IF YOU 15 | -- BENEFIT FROM IT BEING A WIDGET and not just the root window 16 | -- background. IF YOU JUST WISH TO SET THE ROOT WINDOW BACKGROUND, you 17 | -- may want to use the deprecated `gears.wallpaper` instead. This is 18 | -- the most common case of just wanting to set an image as wallpaper. 19 | screen.connect_signal('request::wallpaper', function(s) 20 | awful.wallpaper({ 21 | screen = s, 22 | widget = { 23 | widget = wibox.container.tile, 24 | valign = 'center', 25 | halign = 'center', 26 | tiled = false, 27 | { 28 | widget = wibox.widget.imagebox, 29 | image = beautiful.wallpaper, 30 | upscale = true, 31 | downscale = true 32 | } 33 | } 34 | }) 35 | end) 36 | -- An example of what's mentioned above. For more information, see: 37 | -- https://awesomewm.org/apidoc/utility_libraries/gears.wallpaper.html 38 | -- gears.wallpaper.maximized(beautiful.wallpaper) 39 | -------------------------------------------------------------------------------- /signal/tag.lua: -------------------------------------------------------------------------------- 1 | --- Tag layouts. 2 | -- Appends all layouts defined in `config/user.lua` to all tags. 3 | tag.connect_signal('request::default_layouts', function() 4 | require('awful').layout.append_default_layouts(require('config.user').layouts) 5 | end) 6 | -------------------------------------------------------------------------------- /theme/init.lua: -------------------------------------------------------------------------------- 1 | -- Theme handling library 2 | local beautiful = require('beautiful') 3 | -- Standard awesome library 4 | local gears = require('gears') 5 | 6 | -- Themes define colors, icons, font and wallpapers. 7 | beautiful.init(gears.filesystem.get_configuration_dir() .. 'theme/theme.lua') 8 | -------------------------------------------------------------------------------- /theme/theme.lua: -------------------------------------------------------------------------------- 1 | --------------------------- 2 | -- Default awesome theme -- 3 | --------------------------- 4 | 5 | local theme_assets = require("beautiful.theme_assets") 6 | local xresources = require("beautiful.xresources") 7 | local rnotification = require("ruled.notification") 8 | local dpi = xresources.apply_dpi 9 | 10 | local gfs = require("gears.filesystem") 11 | local themes_path = gfs.get_themes_dir() 12 | 13 | local theme = {} 14 | 15 | theme.font = "sans 8" 16 | 17 | theme.bg_normal = "#222222" 18 | theme.bg_focus = "#535d6c" 19 | theme.bg_urgent = "#ff0000" 20 | theme.bg_minimize = "#444444" 21 | theme.bg_systray = theme.bg_normal 22 | 23 | theme.fg_normal = "#aaaaaa" 24 | theme.fg_focus = "#ffffff" 25 | theme.fg_urgent = "#ffffff" 26 | theme.fg_minimize = "#ffffff" 27 | 28 | theme.useless_gap = dpi(0) 29 | theme.border_width = dpi(1) 30 | theme.border_color_normal = "#000000" 31 | theme.border_color_active = "#535d6c" 32 | theme.border_color_marked = "#91231c" 33 | 34 | -- There are other variable sets 35 | -- overriding the default one when 36 | -- defined, the sets are: 37 | -- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile] 38 | -- tasklist_[bg|fg]_[focus|urgent] 39 | -- titlebar_[bg|fg]_[normal|focus] 40 | -- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color] 41 | -- prompt_[fg|bg|fg_cursor|bg_cursor|font] 42 | -- hotkeys_[bg|fg|border_width|border_color|shape|opacity|modifiers_fg|label_bg|label_fg|group_margin|font|description_font] 43 | -- Example: 44 | --theme.taglist_bg_focus = "#ff0000" 45 | 46 | -- Generate taglist squares: 47 | local taglist_square_size = dpi(4) 48 | theme.taglist_squares_sel = theme_assets.taglist_squares_sel( 49 | taglist_square_size, theme.fg_normal 50 | ) 51 | theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel( 52 | taglist_square_size, theme.fg_normal 53 | ) 54 | 55 | -- Variables set for theming notifications: 56 | -- notification_font 57 | -- notification_[bg|fg] 58 | -- notification_[width|height|margin] 59 | -- notification_[border_color|border_width|shape|opacity] 60 | 61 | -- Variables set for theming the menu: 62 | -- menu_[bg|fg]_[normal|focus] 63 | -- menu_[border_color|border_width] 64 | theme.menu_submenu_icon = themes_path.."default/submenu.png" 65 | theme.menu_height = dpi(15) 66 | theme.menu_width = dpi(100) 67 | 68 | -- You can add as many variables as 69 | -- you wish and access them by using 70 | -- beautiful.variable in your rc.lua 71 | --theme.bg_widget = "#cc0000" 72 | 73 | -- Define the image to load 74 | theme.titlebar_close_button_normal = themes_path.."default/titlebar/close_normal.png" 75 | theme.titlebar_close_button_focus = themes_path.."default/titlebar/close_focus.png" 76 | 77 | theme.titlebar_minimize_button_normal = themes_path.."default/titlebar/minimize_normal.png" 78 | theme.titlebar_minimize_button_focus = themes_path.."default/titlebar/minimize_focus.png" 79 | 80 | theme.titlebar_ontop_button_normal_inactive = themes_path.."default/titlebar/ontop_normal_inactive.png" 81 | theme.titlebar_ontop_button_focus_inactive = themes_path.."default/titlebar/ontop_focus_inactive.png" 82 | theme.titlebar_ontop_button_normal_active = themes_path.."default/titlebar/ontop_normal_active.png" 83 | theme.titlebar_ontop_button_focus_active = themes_path.."default/titlebar/ontop_focus_active.png" 84 | 85 | theme.titlebar_sticky_button_normal_inactive = themes_path.."default/titlebar/sticky_normal_inactive.png" 86 | theme.titlebar_sticky_button_focus_inactive = themes_path.."default/titlebar/sticky_focus_inactive.png" 87 | theme.titlebar_sticky_button_normal_active = themes_path.."default/titlebar/sticky_normal_active.png" 88 | theme.titlebar_sticky_button_focus_active = themes_path.."default/titlebar/sticky_focus_active.png" 89 | 90 | theme.titlebar_floating_button_normal_inactive = themes_path.."default/titlebar/floating_normal_inactive.png" 91 | theme.titlebar_floating_button_focus_inactive = themes_path.."default/titlebar/floating_focus_inactive.png" 92 | theme.titlebar_floating_button_normal_active = themes_path.."default/titlebar/floating_normal_active.png" 93 | theme.titlebar_floating_button_focus_active = themes_path.."default/titlebar/floating_focus_active.png" 94 | 95 | theme.titlebar_maximized_button_normal_inactive = themes_path.."default/titlebar/maximized_normal_inactive.png" 96 | theme.titlebar_maximized_button_focus_inactive = themes_path.."default/titlebar/maximized_focus_inactive.png" 97 | theme.titlebar_maximized_button_normal_active = themes_path.."default/titlebar/maximized_normal_active.png" 98 | theme.titlebar_maximized_button_focus_active = themes_path.."default/titlebar/maximized_focus_active.png" 99 | 100 | theme.wallpaper = themes_path.."default/background.png" 101 | 102 | -- You can use your own layout icons like this: 103 | theme.layout_fairh = themes_path.."default/layouts/fairhw.png" 104 | theme.layout_fairv = themes_path.."default/layouts/fairvw.png" 105 | theme.layout_floating = themes_path.."default/layouts/floatingw.png" 106 | theme.layout_magnifier = themes_path.."default/layouts/magnifierw.png" 107 | theme.layout_max = themes_path.."default/layouts/maxw.png" 108 | theme.layout_fullscreen = themes_path.."default/layouts/fullscreenw.png" 109 | theme.layout_tilebottom = themes_path.."default/layouts/tilebottomw.png" 110 | theme.layout_tileleft = themes_path.."default/layouts/tileleftw.png" 111 | theme.layout_tile = themes_path.."default/layouts/tilew.png" 112 | theme.layout_tiletop = themes_path.."default/layouts/tiletopw.png" 113 | theme.layout_spiral = themes_path.."default/layouts/spiralw.png" 114 | theme.layout_dwindle = themes_path.."default/layouts/dwindlew.png" 115 | theme.layout_cornernw = themes_path.."default/layouts/cornernww.png" 116 | theme.layout_cornerne = themes_path.."default/layouts/cornernew.png" 117 | theme.layout_cornersw = themes_path.."default/layouts/cornersww.png" 118 | theme.layout_cornerse = themes_path.."default/layouts/cornersew.png" 119 | 120 | -- Generate Awesome icon: 121 | theme.awesome_icon = theme_assets.awesome_icon( 122 | theme.menu_height, theme.bg_focus, theme.fg_focus 123 | ) 124 | 125 | -- Define the icon theme for application icons. If not set then the icons 126 | -- from /usr/share/icons and /usr/share/icons/hicolor will be used. 127 | theme.icon_theme = nil 128 | 129 | -- Set different colors for urgent notifications. 130 | rnotification.connect_signal('request::rules', function() 131 | rnotification.append_rule { 132 | rule = { urgency = 'critical' }, 133 | properties = { bg = '#ff0000', fg = '#ffffff' } 134 | } 135 | end) 136 | 137 | return theme 138 | -------------------------------------------------------------------------------- /ui/menu/init.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local beautiful = require('beautiful') 3 | 4 | --- Menu 5 | local menu = {} 6 | local apps = require('config.apps') 7 | local hkey_popup = require('awful.hotkeys_popup') 8 | 9 | -- Create a main menu. 10 | menu.awesome = { 11 | { 'hotkeys', function() hkey_popup.show_help(nil, awful.screen.focused()) end }, 12 | { 'manual', apps.terminal .. ' -e man awesome' }, 13 | -- Not part of the original config but extremely useful, especially as the example 14 | -- config is meant to serve as an example to build your own environment upon. 15 | { 16 | 'docs', 17 | (os.getenv('BROWSER') or 'firefox') .. ' https://awesomewm.org/apidoc' 18 | }, 19 | { 'edit config', apps.editor_cmd .. ' ' .. awesome.conffile }, 20 | { 'restart', awesome.restart }, 21 | { 'quit', function() awesome.quit() end } 22 | } 23 | 24 | menu.main = awful.menu({ 25 | items = { 26 | { 'awesome', menu.awesome, beautiful.awesome_icon }, 27 | { 'open terminal', apps.terminal } 28 | } 29 | }) 30 | 31 | return menu 32 | -------------------------------------------------------------------------------- /ui/notification/init.lua: -------------------------------------------------------------------------------- 1 | local naughty = require('naughty') 2 | 3 | return function(n) 4 | return naughty.layout.box({ notification = n }) 5 | end 6 | -------------------------------------------------------------------------------- /ui/titlebar/init.lua: -------------------------------------------------------------------------------- 1 | -- Returns titlebars for normal clients, this structure allows one to 2 | -- easily define special titlebars for particular clients. 3 | return { 4 | normal = require(... .. '.normal') 5 | } 6 | -------------------------------------------------------------------------------- /ui/titlebar/normal.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local wibox = require('wibox') 3 | 4 | --- The titlebar to be used on normal clients. 5 | return function(c) 6 | -- Buttons for the titlebar. 7 | local buttons = { 8 | awful.button(nil, 1, function() 9 | c:activate({ context = 'titlebar', action = 'mouse_move' }) 10 | end), 11 | awful.button(nil, 3, function() 12 | c:activate({ context = 'titlebar', action = 'mouse_resize' }) 13 | end) 14 | } 15 | 16 | -- Draws the client titlebar at the default position (top) and size. 17 | awful.titlebar(c).widget = wibox.widget({ 18 | layout = wibox.layout.align.horizontal, 19 | -- Left 20 | { 21 | layout = wibox.layout.fixed.horizontal, 22 | awful.titlebar.widget.iconwidget(c), 23 | buttons = buttons 24 | }, 25 | -- Middle 26 | { 27 | layout = wibox.layout.flex.horizontal, 28 | { -- Title 29 | widget = awful.titlebar.widget.titlewidget(c), 30 | halign = 'center' 31 | }, 32 | buttons = buttons 33 | }, 34 | -- Right 35 | { 36 | layout = wibox.layout.fixed.horizontal, 37 | awful.titlebar.widget.floatingbutton(c), 38 | awful.titlebar.widget.maximizedbutton(c), 39 | awful.titlebar.widget.stickybutton(c), 40 | awful.titlebar.widget.ontopbutton(c), 41 | awful.titlebar.widget.closebutton(c) 42 | } 43 | }) 44 | end 45 | -------------------------------------------------------------------------------- /ui/wibar/init.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local wibox = require('wibox') 3 | 4 | local module = require(... .. '.module') 5 | 6 | return function(s) 7 | s.mypromptbox = awful.widget.prompt() -- Create a promptbox. 8 | 9 | -- Create the wibox 10 | s.mywibox = awful.wibar({ 11 | position = 'top', 12 | screen = s, 13 | widget = { 14 | layout = wibox.layout.align.horizontal, 15 | -- Left widgets. 16 | { 17 | layout = wibox.layout.fixed.horizontal, 18 | module.launcher(), 19 | module.taglist(s), 20 | s.mypromptbox 21 | }, 22 | -- Middle widgets. 23 | module.tasklist(s), 24 | -- Right widgets. 25 | { 26 | layout = wibox.layout.fixed.horizontal, 27 | awful.widget.keyboardlayout(), -- Keyboard map indicator and switcher. 28 | wibox.widget.systray(), 29 | wibox.widget.textclock(), -- Create a textclock widget. 30 | module.layoutbox(s) 31 | } 32 | } 33 | }) 34 | end 35 | -------------------------------------------------------------------------------- /ui/wibar/module/init.lua: -------------------------------------------------------------------------------- 1 | -- Return a table containing all bar modules, with a name attached 2 | -- to each. 3 | local path = ... .. '.' 4 | return setmetatable({}, { 5 | __index = function(_, key) 6 | local module, _ = require(path .. key) 7 | return module 8 | end 9 | }) 10 | -------------------------------------------------------------------------------- /ui/wibar/module/launcher.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | local beautiful = require('beautiful') 3 | 4 | -- Create a launcher widget. Opens the Awesome menu when clicked. 5 | return function() 6 | return awful.widget.launcher({ 7 | image = beautiful.awesome_icon, 8 | menu = require('ui.menu').main 9 | }) 10 | end 11 | -------------------------------------------------------------------------------- /ui/wibar/module/layoutbox.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | return function(s) 4 | -- Create an imagebox widget which will contain an icon indicating which layout we're using. 5 | -- We need one layoutbox per screen. 6 | return awful.widget.layoutbox({ 7 | screen = s, 8 | buttons = { 9 | awful.button(nil, 1, function() awful.layout.inc( 1) end), 10 | awful.button(nil, 3, function() awful.layout.inc(-1) end), 11 | awful.button(nil, 4, function() awful.layout.inc(-1) end), 12 | awful.button(nil, 5, function() awful.layout.inc( 1) end) 13 | } 14 | }) 15 | end 16 | -------------------------------------------------------------------------------- /ui/wibar/module/taglist.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | local mod = require('binds.mod') 4 | local modkey = mod.modkey 5 | 6 | return function(s) 7 | -- Create a taglist widget 8 | return awful.widget.taglist({ 9 | screen = s, 10 | filter = awful.widget.taglist.filter.all, 11 | buttons = { 12 | -- Left-clicking a tag changes to it. 13 | awful.button(nil, 1, function(t) t:view_only() end), 14 | -- Mod + Left-clicking a tag sends the currently focused client to it. 15 | awful.button({ modkey }, 1, function(t) 16 | if client.focus then 17 | client.focus:move_to_tag(t) 18 | end 19 | end), 20 | -- Right-clicking a tag makes its contents visible in the current one. 21 | awful.button(nil, 3, awful.tag.viewtoggle), 22 | -- Mod + Right-clicking a tag makes the currently focused client visible 23 | -- in it. 24 | awful.button({ modkey }, 3, function(t) 25 | if client.focus then 26 | client.focus:toggle_tag(t) 27 | end 28 | end), 29 | -- Mousewheel scrolling cycles through tags. 30 | awful.button(nil, 4, function(t) awful.tag.viewprev(t.screen) end), 31 | awful.button(nil, 5, function(t) awful.tag.viewnext(t.screen) end) 32 | } 33 | }) 34 | end 35 | -------------------------------------------------------------------------------- /ui/wibar/module/tasklist.lua: -------------------------------------------------------------------------------- 1 | local awful = require('awful') 2 | 3 | return function(s) 4 | -- Create a tasklist widget 5 | return awful.widget.tasklist({ 6 | screen = s, 7 | filter = awful.widget.tasklist.filter.currenttags, 8 | buttons = { 9 | -- Left-clicking a client indicator minimizes it if it's unminimized, or unminimizes 10 | -- it if it's minimized. 11 | awful.button(nil, 1, function(c) 12 | c:activate({ context = 'tasklist', action = 'toggle_minimization' }) 13 | end), 14 | -- Right-clicking a client indicator shows the list of all open clients in all visible 15 | -- tags. 16 | awful.button(nil, 3, function() awful.menu.client_list({ theme = { width = 250 } }) end), 17 | -- Mousewheel scrolling cycles through clients. 18 | awful.button(nil, 4, function() awful.client.focus.byidx(-1) end), 19 | awful.button(nil, 5, function() awful.client.focus.byidx( 1) end) 20 | } 21 | }) 22 | end 23 | --------------------------------------------------------------------------------