From 7cc3903efe7bb76f8aa4521a2e8139988384dbff Mon Sep 17 00:00:00 2001 From: mark Date: Sun, 1 Aug 2021 07:24:26 -0700 Subject: [PATCH] Reset old config --- .gitignore | 2 + README.md | 78 ++++ bin/configs/compton.conf | 79 ++++ bin/init.lua | 81 +++++ bin/rofi/launcher.rasi | 155 ++++++++ bin/scripts/backlight | 37 ++ bin/scripts/battery | 8 + bin/scripts/capture | 74 ++++ binds/desktop/awesome.lua | 19 + binds/desktop/launcher.lua | 76 ++++ binds/desktop/screenshot.lua | 24 ++ binds/init.lua | 19 + binds/system/backlight.lua | 56 +++ binds/system/input.lua | 11 + binds/system/mpd.lua | 51 +++ binds/system/system.lua | 15 + binds/system/volume.lua | 31 ++ binds/unused.lua | 83 +++++ binds/window/client.lua | 78 ++++ binds/window/layout.lua | 81 +++++ binds/window/tags.lua | 41 +++ clients/binds/buttons.lua | 31 ++ clients/binds/keys.lua | 129 +++++++ clients/binds/titlebar.lua | 20 ++ clients/render.lua | 24 ++ clients/rules.lua | 78 ++++ clients/signals.lua | 55 +++ clients/titlebar.lua | 72 ++++ conf-example.lua | 156 ++++++++ desktop/init.lua | 232 ++++++++++++ desktop/popups/language.lua | 110 ++++++ desktop/tagger.lua | 141 ++++++++ desktop/wallpaper.lua | 62 ++++ desktop/widgets/backlight.lua | 101 ++++++ desktop/widgets/battery.lua | 214 +++++++++++ desktop/widgets/keymap.lua | 41 +++ desktop/widgets/launcher.lua | 52 +++ desktop/widgets/layoutbox.lua | 38 ++ desktop/widgets/mdadm.lua | 49 +++ desktop/widgets/mpc.lua | 193 ++++++++++ desktop/widgets/shortcut.lua | 51 +++ desktop/widgets/tagindicator.lua | 68 ++++ desktop/widgets/tasklist.lua | 119 ++++++ desktop/widgets/textclock.lua | 49 +++ desktop/widgets/volume.lua | 142 ++++++++ errors.lua | 30 ++ layoutmanager.lua | 86 +++++ rc.lua | 79 ++++ theme/bar.lua | 36 ++ theme/clients.lua | 16 + theme/color.lua | 46 +++ theme/init.lua | 59 +++ theme/notifications.lua | 66 ++++ theme/resources/icons.lua | 176 +++++++++ theme/resources/icons/arch.svg | 5 + .../icons/battery/caution-charging.svg | 102 ++++++ theme/resources/icons/battery/caution.svg | 90 +++++ .../icons/battery/empty-charging.svg | 102 ++++++ theme/resources/icons/battery/empty.svg | 90 +++++ .../resources/icons/battery/full-charging.svg | 102 ++++++ theme/resources/icons/battery/full.svg | 90 +++++ .../resources/icons/battery/good-charging.svg | 102 ++++++ theme/resources/icons/battery/good.svg | 90 +++++ .../resources/icons/battery/low-charging.svg | 102 ++++++ theme/resources/icons/battery/low.svg | 90 +++++ theme/resources/icons/battery/missing.svg | 136 +++++++ .../brightness/clockwise/brightness-0.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-1.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-2.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-3.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-4.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-5.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-6.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-7.svg | 339 ++++++++++++++++++ .../brightness/clockwise/brightness-8.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-0.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-1.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-2.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-3.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-4.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-5.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-6.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-7.svg | 339 ++++++++++++++++++ .../counterclockwise/brightness-8.svg | 339 ++++++++++++++++++ theme/resources/icons/layout/cornerne.svg | 105 ++++++ theme/resources/icons/layout/cornernw.svg | 109 ++++++ theme/resources/icons/layout/cornerse.svg | 109 ++++++ theme/resources/icons/layout/cornersw.svg | 109 ++++++ theme/resources/icons/layout/dwindle.svg | 97 +++++ theme/resources/icons/layout/fairh.svg | 109 ++++++ theme/resources/icons/layout/fairv.svg | 109 ++++++ theme/resources/icons/layout/floating.svg | 72 ++++ theme/resources/icons/layout/fullscreen.svg | 65 ++++ theme/resources/icons/layout/magnifier.svg | 89 +++++ theme/resources/icons/layout/max.svg | 65 ++++ theme/resources/icons/layout/spiral.svg | 101 ++++++ theme/resources/icons/layout/tile.svg | 117 ++++++ theme/resources/icons/layout/tilebottom.svg | 116 ++++++ theme/resources/icons/layout/tileleft.svg | 117 ++++++ theme/resources/icons/layout/tiletop.svg | 117 ++++++ theme/resources/icons/music/pause-blue.svg | 79 ++++ theme/resources/icons/music/pause-grey.svg | 80 +++++ theme/resources/icons/music/play-blue.svg | 72 ++++ theme/resources/icons/music/play-grey.svg | 72 ++++ theme/resources/icons/music/stop-blue.svg | 73 ++++ theme/resources/icons/music/stop-grey.svg | 73 ++++ .../resources/icons/raid/degraded-recover.svg | 161 +++++++++ theme/resources/icons/raid/degraded.svg | 153 ++++++++ .../resources/icons/raid/healthy-recover.svg | 161 +++++++++ theme/resources/icons/raid/healthy.svg | 147 ++++++++ .../resources/icons/titlebar/hover/close.svg | 37 ++ .../resources/icons/titlebar/hover/float.svg | 36 ++ .../icons/titlebar/hover/maximize.svg | 36 ++ .../icons/titlebar/hover/minimize.svg | 39 ++ .../resources/icons/titlebar/hover/ontop.svg | 36 ++ .../resources/icons/titlebar/hover/stick.svg | 36 ++ .../icons/titlebar/regular/close.svg | 37 ++ .../icons/titlebar/regular/float.svg | 36 ++ .../icons/titlebar/regular/maximize.svg | 36 ++ .../icons/titlebar/regular/minimize.svg | 39 ++ .../icons/titlebar/regular/ontop.svg | 36 ++ .../icons/titlebar/regular/stick.svg | 36 ++ theme/resources/icons/volume/error.svg | 259 +++++++++++++ theme/resources/icons/volume/high.svg | 253 +++++++++++++ theme/resources/icons/volume/low.svg | 253 +++++++++++++ theme/resources/icons/volume/medium.svg | 253 +++++++++++++ theme/resources/icons/volume/mute-red.svg | 257 +++++++++++++ theme/resources/icons/volume/mute.svg | 257 +++++++++++++ theme/resources/icons/volume/off.svg | 253 +++++++++++++ theme/resources/init.lua | 86 +++++ theme/resources/sounds.lua | 4 + theme/resources/sounds/accept.ogg | Bin 0 -> 21662 bytes theme/resources/sounds/hover.ogg | Bin 0 -> 4826 bytes theme/resources/sounds/request.ogg | Bin 0 -> 5752 bytes theme/resources/sounds/send.ogg | Bin 0 -> 5146 bytes theme/resources/sounds/type.ogg | Bin 0 -> 4797 bytes theme/resources/sounds/volumedown-click.mp3 | Bin 0 -> 1916 bytes theme/resources/sounds/volumeup-click.mp3 | Bin 0 -> 1917 bytes wrapper/backlight.lua | 36 ++ wrapper/ibus.lua | 102 ++++++ wrapper/init.lua | 7 + wrapper/mdadm.lua | 38 ++ wrapper/sound.lua | 22 ++ wrapper/volume.lua | 146 ++++++++ 144 files changed, 16466 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 bin/configs/compton.conf create mode 100755 bin/init.lua create mode 100755 bin/rofi/launcher.rasi create mode 100755 bin/scripts/backlight create mode 100755 bin/scripts/battery create mode 100755 bin/scripts/capture create mode 100755 binds/desktop/awesome.lua create mode 100755 binds/desktop/launcher.lua create mode 100755 binds/desktop/screenshot.lua create mode 100755 binds/init.lua create mode 100755 binds/system/backlight.lua create mode 100644 binds/system/input.lua create mode 100755 binds/system/mpd.lua create mode 100644 binds/system/system.lua create mode 100755 binds/system/volume.lua create mode 100755 binds/unused.lua create mode 100755 binds/window/client.lua create mode 100755 binds/window/layout.lua create mode 100755 binds/window/tags.lua create mode 100755 clients/binds/buttons.lua create mode 100755 clients/binds/keys.lua create mode 100755 clients/binds/titlebar.lua create mode 100755 clients/render.lua create mode 100755 clients/rules.lua create mode 100755 clients/signals.lua create mode 100755 clients/titlebar.lua create mode 100755 conf-example.lua create mode 100755 desktop/init.lua create mode 100644 desktop/popups/language.lua create mode 100755 desktop/tagger.lua create mode 100755 desktop/wallpaper.lua create mode 100755 desktop/widgets/backlight.lua create mode 100755 desktop/widgets/battery.lua create mode 100755 desktop/widgets/keymap.lua create mode 100644 desktop/widgets/launcher.lua create mode 100755 desktop/widgets/layoutbox.lua create mode 100644 desktop/widgets/mdadm.lua create mode 100644 desktop/widgets/mpc.lua create mode 100644 desktop/widgets/shortcut.lua create mode 100755 desktop/widgets/tagindicator.lua create mode 100755 desktop/widgets/tasklist.lua create mode 100755 desktop/widgets/textclock.lua create mode 100755 desktop/widgets/volume.lua create mode 100755 errors.lua create mode 100644 layoutmanager.lua create mode 100755 rc.lua create mode 100755 theme/bar.lua create mode 100755 theme/clients.lua create mode 100755 theme/color.lua create mode 100755 theme/init.lua create mode 100755 theme/notifications.lua create mode 100755 theme/resources/icons.lua create mode 100755 theme/resources/icons/arch.svg create mode 100755 theme/resources/icons/battery/caution-charging.svg create mode 100755 theme/resources/icons/battery/caution.svg create mode 100755 theme/resources/icons/battery/empty-charging.svg create mode 100755 theme/resources/icons/battery/empty.svg create mode 100755 theme/resources/icons/battery/full-charging.svg create mode 100755 theme/resources/icons/battery/full.svg create mode 100755 theme/resources/icons/battery/good-charging.svg create mode 100755 theme/resources/icons/battery/good.svg create mode 100755 theme/resources/icons/battery/low-charging.svg create mode 100755 theme/resources/icons/battery/low.svg create mode 100755 theme/resources/icons/battery/missing.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-0.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-1.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-2.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-3.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-4.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-5.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-6.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-7.svg create mode 100755 theme/resources/icons/brightness/clockwise/brightness-8.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-0.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-1.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-2.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-3.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-4.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-5.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-6.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-7.svg create mode 100755 theme/resources/icons/brightness/counterclockwise/brightness-8.svg create mode 100755 theme/resources/icons/layout/cornerne.svg create mode 100755 theme/resources/icons/layout/cornernw.svg create mode 100755 theme/resources/icons/layout/cornerse.svg create mode 100755 theme/resources/icons/layout/cornersw.svg create mode 100755 theme/resources/icons/layout/dwindle.svg create mode 100755 theme/resources/icons/layout/fairh.svg create mode 100755 theme/resources/icons/layout/fairv.svg create mode 100755 theme/resources/icons/layout/floating.svg create mode 100755 theme/resources/icons/layout/fullscreen.svg create mode 100755 theme/resources/icons/layout/magnifier.svg create mode 100755 theme/resources/icons/layout/max.svg create mode 100755 theme/resources/icons/layout/spiral.svg create mode 100755 theme/resources/icons/layout/tile.svg create mode 100755 theme/resources/icons/layout/tilebottom.svg create mode 100755 theme/resources/icons/layout/tileleft.svg create mode 100755 theme/resources/icons/layout/tiletop.svg create mode 100755 theme/resources/icons/music/pause-blue.svg create mode 100755 theme/resources/icons/music/pause-grey.svg create mode 100755 theme/resources/icons/music/play-blue.svg create mode 100755 theme/resources/icons/music/play-grey.svg create mode 100755 theme/resources/icons/music/stop-blue.svg create mode 100755 theme/resources/icons/music/stop-grey.svg create mode 100644 theme/resources/icons/raid/degraded-recover.svg create mode 100644 theme/resources/icons/raid/degraded.svg create mode 100644 theme/resources/icons/raid/healthy-recover.svg create mode 100755 theme/resources/icons/raid/healthy.svg create mode 100755 theme/resources/icons/titlebar/hover/close.svg create mode 100755 theme/resources/icons/titlebar/hover/float.svg create mode 100755 theme/resources/icons/titlebar/hover/maximize.svg create mode 100755 theme/resources/icons/titlebar/hover/minimize.svg create mode 100755 theme/resources/icons/titlebar/hover/ontop.svg create mode 100755 theme/resources/icons/titlebar/hover/stick.svg create mode 100755 theme/resources/icons/titlebar/regular/close.svg create mode 100755 theme/resources/icons/titlebar/regular/float.svg create mode 100755 theme/resources/icons/titlebar/regular/maximize.svg create mode 100755 theme/resources/icons/titlebar/regular/minimize.svg create mode 100755 theme/resources/icons/titlebar/regular/ontop.svg create mode 100755 theme/resources/icons/titlebar/regular/stick.svg create mode 100755 theme/resources/icons/volume/error.svg create mode 100755 theme/resources/icons/volume/high.svg create mode 100755 theme/resources/icons/volume/low.svg create mode 100755 theme/resources/icons/volume/medium.svg create mode 100755 theme/resources/icons/volume/mute-red.svg create mode 100755 theme/resources/icons/volume/mute.svg create mode 100755 theme/resources/icons/volume/off.svg create mode 100755 theme/resources/init.lua create mode 100755 theme/resources/sounds.lua create mode 100755 theme/resources/sounds/accept.ogg create mode 100755 theme/resources/sounds/hover.ogg create mode 100755 theme/resources/sounds/request.ogg create mode 100755 theme/resources/sounds/send.ogg create mode 100755 theme/resources/sounds/type.ogg create mode 100755 theme/resources/sounds/volumedown-click.mp3 create mode 100755 theme/resources/sounds/volumeup-click.mp3 create mode 100755 wrapper/backlight.lua create mode 100644 wrapper/ibus.lua create mode 100755 wrapper/init.lua create mode 100644 wrapper/mdadm.lua create mode 100644 wrapper/sound.lua create mode 100755 wrapper/volume.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a938d75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +conf.lua +*.note diff --git a/README.md b/README.md new file mode 100644 index 0000000..8526ccd --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# Awesomewm configuration +Core configuration for awesomewm. +The PACKAGES file contains information on dependencies and desktop setup + +Rofi config in bin/rofi is set to use the papirus theme. Edit the configs there +to change it. + +Copy conf-example.lua into conf.lua, then configure your system. + +## Project structure + +All directories are ``require``d from the root project dir. + +Most directories contain an init.lua. +That file initializes the module, it is run when the module is required. + + +bin: various non-awesome scripts and configs +binds: keyboard and mouse binds +errors.lua: manages errors in rc.lua + +clients: + Manages applications. + Awesome keybinds for applications are in clients/binds. + +desktop: + Manages tags, wallpapers, and the bar (with its widgets). + +theme: + Theming. Everything there compiles into a ton of awesome.beautiful.* + variables that are used throughout this project. + +wrapper: + Scripts that provide an interface to system functions. + +rc.lua: + The main script, axwesomewm only looks for this file. + Everything else in this project is pulled in by it. + + + +## Dependencies +rofi + Launcher. Config is in bin/rofi + +Fish shell + All scripts in bin/scripts are written for the fish shell. + +upower, xbacklight + Used for battery and backlight management. + +flameshot, scrot, xclip, tesseract + Scrot is used for quick screenshots. Script is bin/scripts/capture. + Tesseract is used for OCR screenshots. Make sure to install language packs! + (e.g. tesseract-data-eng, tesseract-data-rus) + It is also used in bin/scripts/capture. + Flameshot is used for regular screenshots. + +pamixer + Used to control pulseaudio in wrapper/volume + +sox + provides the play command used to play system sounds. + It may need some extra packages for certain file types (mp3). + See the documentation. + +ibus + This configuration does not rely on ibus default keybinds. Instead, it uses + ibus cli commands (see wrapper.ibus) to make language switching work. + + If you do not need multilanguage input, you may remove wrapper.ibus, + desktop.popups.language, and the language binds in binds.system.input. + +redshift + Used to tint the screen. + +MPC + Used in keybinds. diff --git a/bin/configs/compton.conf b/bin/configs/compton.conf new file mode 100755 index 0000000..24b4716 --- /dev/null +++ b/bin/configs/compton.conf @@ -0,0 +1,79 @@ +backend = "glx"; +mark-wmwin-focused = true; +mark-ovredir-focused = true; +detect-rounded-corners = true; +detect-client-opacity = true; +refresh-rate = 0; +vsync = "none"; +dbe = false; +paint-on-overlay = true; + +focus-exclude = [ + "class_g = 'Firefox Developer Edition'", + "class_g = 'Firefox-esr'" +]; + +detect-transient = true; +detect-client-leader = true; +invert-color-include = [ ]; +glx-copy-from-front = false; +glx-swap-method = "undefined"; + +wintypes: +{ + tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; }; +}; + + + +shadow = true; +no-dnd-shadow = true; +no-dock-shadow = false; +clear-shadow = true; +shadow-radius = 10; +shadow-offset-x = -7; +shadow-offset-y = -7; +shadow-opacity = 0.3; +shadow-exclude = [ + #"!(class_g = 'kitty-noblur')" +]; + + + +fading = true; +fade-in-step=0.02; +fade-out-step=0.03; +fade-delta=5; +fade-exclude = [ + "(!class_g = 'awesome') && (!class_g = 'Rofi')" +] + + +opacity = false +active-opacity = 1; +inactive-opacity = 1; +frame-opacity = 1; + +opacity-rule = [ + # Kitty already has a transparent background. + # 99% opacity to make text opaque + "99:class_g = 'kitty'" +]; + + + +## blur +blur-background = true; +blur-background-frame = false; +blur-background-fixed = false; +blur-kern = "3x3box"; +blur-method = "kawase"; +blur-strength = 16; + +blur-background-exclude = [ + "window_type = 'desktop'", + "name = 'awesome'", + "name = 'Zoom Meeting'", + #"(class_g = 'awesome') && !(window_type = 'normal')", + "class_g = 'kitty-noblur'" +]; diff --git a/bin/init.lua b/bin/init.lua new file mode 100755 index 0000000..0c1f7bb --- /dev/null +++ b/bin/init.lua @@ -0,0 +1,81 @@ +dir = configuration_dir .. "bin/" +local script_dir = dir .. "scripts/" + +return { + + system = { + shutdown = function(confirm_prompt) + if (string.lower(confirm_prompt) == "y") or (string.lower(confirm_prompt) == "yes") then + awful.spawn("shutdown now", false) + elseif (string.lower(confirm_prompt) == "r") or (string.lower(confirm_prompt) == "reset") then + awful.spawn("shutdown -r now", false) + end + end + }, + + backlight = { + watch = function(timeout, callback, widget) + awful.widget.watch(script_dir .. "backlight get", timeout, callback, widget) + end, + + get = function(callback) + awful.spawn.easy_async(script_dir .. "backlight get", callback) + end, + + set = function(value) + awful.spawn(script_dir .. "backlight set " .. value, false) + end, + + up = function() + awful.spawn(script_dir .. "backlight up", false) + end, + + down = function() + awful.spawn(script_dir .. "backlight down", false) + end, + + redshift = function(temp) + awful.spawn("redshift -O " .. tostring(temp), false) + end, + + redshift_reset = function() + awful.spawn("redshift -x", false) + end, + }, + + battery = { + watch = function(timeout, callback, widget) + awful.widget.watch(script_dir .. "battery", timeout, callback, widget) + end, + + status = function(callback) + awful.spawn.easy_async(script_dir .. "battery", callback) + end, + }, + + rofi = { + launcher = function() + awful.spawn("rofi -show drun -theme \"" .. dir .. "/rofi/launcher.rasi\"") + end + }, + + capture = function(source, target) + awful.spawn(script_dir .. "capture " .. source .. " " .. target, false) + end, + + flameshot = { + gui = function() + awful.spawn("flameshot gui -p \"" .. conf.screenshot_dir .. "\"", false) + end + }, + + mpc = { + watch = function(command, timeout, callback, widget) + awful.widget.watch("mpc --host " .. conf.mpd_host .. " " .. command, timeout, callback, widget) + end, + + command = function(command, callback) + awful.spawn.easy_async("mpc --host " .. conf.mpd_host .. " " .. command, callback) + end + } +} diff --git a/bin/rofi/launcher.rasi b/bin/rofi/launcher.rasi new file mode 100755 index 0000000..8af9945 --- /dev/null +++ b/bin/rofi/launcher.rasi @@ -0,0 +1,155 @@ +configuration { + font: "Inter Regular 10"; + show-icons: true; + icon-theme: "Papirus"; + drun-display-format: "{name}"; + fullscreen: false; + threads: 0; + matching: "fuzzy"; + scroll-method: 1; + disable-history: false; + fullscreen: false; + window-thumbnail: true; +} + +* { + transparent: #00000000; + background: #000000FF; + foreground: #F2F2F2EE; + background-selected: #F2F2F245; + background-active: #F2F2F230; + background-white: #F2F2F211; + background-black: #00000066; + urgent: #E91E6366; + urgent-selected: #E91E6377; +} + +window { + transparency: "real"; + background-color: @background; + location: southwest; + anchor: southwest; + x-offset: 4px; + y-offset: -50px; + height: 500px; + width: 400px; + orientation: vertical; + border-radius: 5px; +} + +prompt { + enabled: false; +} + +button { + action: "ok"; + str: " "; + font: "FantasqueSansMono Nerd Font 11"; + expand: false; + text-color: @foreground; + background-color: @transparent; + vertical-align: 0.7; + horizontal-align: 0.5; +} + +entry { + font: "Inter Regular 11"; + background-color: @transparent; + text-color: @foreground; + expand: true; + vertical-align: 0.5; + horizontal-align: 0.5; + placeholder: "Search"; + placeholder-color: @foreground; + blink: true; +} + +case-indicator { + background-color: @transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +entry-wrapper { + orientation: horizontal; + vertical-align: 0.5; + spacing: 4px; + background-color: @transparent; + children: [ button, entry, case-indicator ]; +} + +inputbar { + background-color: @background-white; + text-color: @foreground; + expand: false; + border-radius: 24px; + margin: 0px 0px 0px 0px; + padding: 10px 10px 10px 10px; + position: north; + children: [ entry-wrapper ]; +} + +listview { + background-color: @transparent; + columns: 1; + spacing: 5px; + cycle: false; + dynamic: true; + layout: vertical; +} + +mainbox { + background-color: @background-black; + children: [listview, inputbar ]; + spacing: 25px; + padding: 40px 25px 25px 25px; +} + +element { + background-color: @transparent; + text-color: @foreground; + orientation: horizontal; + border-radius: 6px; + padding: 5px 10px 5px 10px; +} + +element-icon { + size: 36px; + border: 0; +} + +element-text { + expand: true; + horizontal-align: 0; + vertical-align: 0.5; + margin: 0 10px 0 10px; +} + +element normal.urgent, +element alternate.urgent { + background-color: @urgent; + text-color: @foreground; + border-radius: 9px; +} + +element normal.active, +element alternate.active { + background-color: @background-active; + text-color: @foreground; +} + +element selected { + background-color: @background-selected; + text-color: @foreground; +} + +element selected.urgent { + background-color: @urgent-selected; + text-color: @foreground; +} + +element selected.active { + background-color: @background-active; + color: @foreground-selected; +} diff --git a/bin/scripts/backlight b/bin/scripts/backlight new file mode 100755 index 0000000..63014c8 --- /dev/null +++ b/bin/scripts/backlight @@ -0,0 +1,37 @@ +#!/usr/bin/fish +# +# Usage: +# backlight get +# backlight set [value] +# backlight max +# +# Returns: +# Set - nothing +# Get, max - Number between 0 and 100 (eg: 0, 25.445283, 100) +# + +function backlight + switch $argv[1] + case "get" + xbacklight -get + case "max" + echo 100 + case "set" + xbacklight -set $argv[2] + case "up" + xbacklight -inc 10 + case "down" + xbacklight -dec 10 + case "*" + echo "Unknown function \"$argv[1]\"" + echo "" + echo "Usage:" + echo " backlight get" + echo " backlight set [value]" + echo " backlight max" + return 0 + end + return 1 +end + +backlight $argv diff --git a/bin/scripts/battery b/bin/scripts/battery new file mode 100755 index 0000000..ddeeb98 --- /dev/null +++ b/bin/scripts/battery @@ -0,0 +1,8 @@ +#!/usr/bin/fish +# returns battery percentage and status +# 45%, discharging +# second parameter returns "fully" when fully charged. Since awesome only checks for "discharging," fixing that isn't necessary. + +echo \ + (upower --show-info /org/freedesktop/UPower/devices/battery_BAT1 | grep percentage | grep -Po "(\d\d?\d?)%"), \ + (upower --show-info /org/freedesktop/UPower/devices/battery_BAT1 | grep state | grep -Po "(?<=state:)\s*(\w*)" | xargs) \ diff --git a/bin/scripts/capture b/bin/scripts/capture new file mode 100755 index 0000000..e283e2e --- /dev/null +++ b/bin/scripts/capture @@ -0,0 +1,74 @@ +#!/usr/bin/fish +# +# Screenshot wrapper +# +# Take a screenshot of a +# region, window, or screen +# and +# save it to $dest +# copy it to the clipboard +# pipe it through tesseract and xclip the result + + +function capture + # Screenshot save location + set dest $HOME/Screenshots/ + + #set tmp_file (mktemp --tmpdir "scrot-tmp-XXX.png") + set tmp_file "/tmp/scrot-tmp.png" + + # Capture the desired portion of the screen + switch $argv[1] + case window + scrot --overwrite --silent --focused $tmp_file + case screen + scrot --overwrite --silent $tmp_file + case region + scrot --overwrite --silent --select --freeze --line style=dash,width=2 $tmp_file + case "*" + echo "Unknown source \"$argv[1]\"" + echo "" + echo "Usage: capture [source] [target]" + echo " Valid sources: window, screen, region" + echo " Valid targets: save, copy, ocr" + return 0 + end + + # Output to the desired location + switch $argv[2] + case save + set fname (md5sum $tmp_file | cut -c 1-32) + mv $tmp_file "$dest$fname.png" + + case copy + # Don't use the mktmp file here, since we can't clean + # it away immediately. Use the fixed /tmp/scrot-clip insead. + # (Only applicable when a mktemp file is being used) + #rm $tmp_file + #set tmp_file /tmp/scrot-clip.png + + xclip -i -selection clipboard -t "image/png" $tmp_file + + case ocr + # Recognize text + set ocr (tesseract --dpi 96 -l eng $tmp_file stdout) + + # Trim whitespace and copy to clipboard + echo $ocr | sed -e "s/^[ \t]*//" | xclip -i -rmlastnl -selection clipboard + rm $tmp_file + + case "*" + echo "Unknown target \"$argv[2]\"" + echo "" + echo "Usage: capture [source] [target]" + echo " Valid sources: window, screen, region" + echo " Valid targets: save, copy, ocr" + return 0 + end + + return 1 +end + +# Awesomewm refuses to execute this without a sleep. +sleep 0.1 +capture $argv diff --git a/binds/desktop/awesome.lua b/binds/desktop/awesome.lua new file mode 100755 index 0000000..22bd73c --- /dev/null +++ b/binds/desktop/awesome.lua @@ -0,0 +1,19 @@ +local hotkeys = require("awful.hotkeys_popup") + +return gears.table.join( + awful.key( {"Mod4"}, "s", + hotkeys.show_help, + { + description = "Show help", + group = "Desktop" + } + ), + + awful.key( {"Mod4", "Control", "Shift"}, "r", + awesome.restart, + { + description = "Restart awesome", + group = "Desktop" + } + ) +) diff --git a/binds/desktop/launcher.lua b/binds/desktop/launcher.lua new file mode 100755 index 0000000..c7cfede --- /dev/null +++ b/binds/desktop/launcher.lua @@ -0,0 +1,76 @@ +return gears.table.join( + awful.key( {"Mod4"}, "r", + function () + awful.screen.focused().mypromptbox:run() + end, + { + description = "Run prompt", + group = "Launcher" + } + ), + + awful.key( {"Mod4"}, "x", + function () + awful.screen.focused().mypromptbox:run() + end, + { + description = "Run prompt", + group = "Launcher" + } + ), + + awful.key( {"Mod4"}, "Tab", + function () + bin.rofi.launcher() + end, + + { + description = "Open Launcher", + group = "Launcher" + } + ), + + awful.key( {"Mod4"}, "Return", + function () + awful.spawn(terminal) + end, + + { + description = "Open a terminal", + group = "Launcher" + } + ), + + awful.key( {"Mod4"}, "]", + function () + awful.spawn(terminal .. " ranger /home/mark") + end, + + { + description = "Launch ranger in kitty", + group = "Launcher" + } + ), + + awful.key( {"Mod4", "Control"}, "Return", + function () + awful.spawn("kitty --class \"kitty-noblur\" --override background_opacity=0.5 --override hide_window_decorations=yes") + end, + + { + description = "Open a floating kitty terminal", + group = "Launcher" + } + ), + + awful.key( {"Mod4"}, "\\", + function () + awful.spawn(conf.browser) + end, + + { + description = "Open a browser tab", + group = "Launcher" + } + ) +) diff --git a/binds/desktop/screenshot.lua b/binds/desktop/screenshot.lua new file mode 100755 index 0000000..d9c38e9 --- /dev/null +++ b/binds/desktop/screenshot.lua @@ -0,0 +1,24 @@ +return gears.table.join( + awful.key( {"Control"}, "Print", + function () + bin.capture("region", "ocr") + end, + + { + description = "OCR a region to the clipboard", + group = "Desktop" + } + ), + + awful.key( {}, "Print", + function () + bin.flameshot.gui() + end, + + { + description = "Take a screenshot", + group = "Desktop" + } + ) +) + diff --git a/binds/init.lua b/binds/init.lua new file mode 100755 index 0000000..8a8c17b --- /dev/null +++ b/binds/init.lua @@ -0,0 +1,19 @@ +return { + keys = gears.table.join( + require("binds.system.backlight"), + require("binds.system.mpd"), + require("binds.system.volume"), + require("binds.system.system"), + require("binds.system.input"), + + require("binds.window.client"), + require("binds.window.layout"), + require("binds.window.tags"), + + require("binds.desktop.awesome"), + require("binds.desktop.launcher"), + require("binds.desktop.screenshot") + ), + + buttons = {} +} diff --git a/binds/system/backlight.lua b/binds/system/backlight.lua new file mode 100755 index 0000000..e5f8685 --- /dev/null +++ b/binds/system/backlight.lua @@ -0,0 +1,56 @@ +return gears.table.join( + awful.key( {}, "XF86MonBrightnessUp", + function () + wrapper.backlight.up() + end, + { + description = "Raise brightness", + group = "System" + } + ), + + awful.key( {}, "XF86MonBrightnessDown", + function () + wrapper.backlight.down() + end, + { + description = "Lower brightness", + group = "System" + } + ), + + awful.key( { "Mod4" }, "o", + function () + bin.backlight.redshift(5600) + end, + { + description = "Default redshift", + group = "System" + } + ), + + awful.key( { "Mod4", "Shift" }, "o", + function () + bin.backlight.redshift_reset() + end, + { + description = "Reset redshift", + group = "System" + } + ), + + awful.key( { "Mod4", "Shift", "Control" }, "o", + function () + bin.backlight.redshift_reset() + awful.prompt.run { + prompt = "Color temperature: ", + textbox = awful.screen.focused().mypromptbox.widget, + exe_callback = bin.backlight.redshift + } + end, + { + description = "Set redshift", + group = "System" + } + ) +) diff --git a/binds/system/input.lua b/binds/system/input.lua new file mode 100644 index 0000000..9b6d463 --- /dev/null +++ b/binds/system/input.lua @@ -0,0 +1,11 @@ +return gears.table.join( + awful.key( {"Mod4"}, "space", + function() + desktop.popup.language.next() + end, + { + description = "Change input language", + group = "System" + } + ) +) diff --git a/binds/system/mpd.lua b/binds/system/mpd.lua new file mode 100755 index 0000000..476af5a --- /dev/null +++ b/binds/system/mpd.lua @@ -0,0 +1,51 @@ +return gears.table.join( + awful.key( {}, "XF86AudioPrev", + function () + bin.mpc.command("prev") + end, + { + description = "Previous track", + group = "MPD" + } + ), + + awful.key( {}, "XF86AudioPlay", + function () + bin.mpc.command("toggle") + end, + { + description = "Play/Pause", + group = "MPD" + } + ), + + awful.key( {}, "XF86AudioNext", + function () + bin.mpc.command("next") + end, + { + description = "Next track", + group = "MPD" + } + ), + + awful.key( {"Mod4"}, "XF86AudioRaiseVolume", + function () + bin.mpc.command("vol +5") + end, + { + description = "Volume up", + group = "MPD" + } + ), + + awful.key( {"Mod4"}, "XF86AudioLowerVolume", + function () + bin.mpc.command("vol -5") + end, + { + description = "Volume down", + group = "MPD" + } + ) +) diff --git a/binds/system/system.lua b/binds/system/system.lua new file mode 100644 index 0000000..8ad95f1 --- /dev/null +++ b/binds/system/system.lua @@ -0,0 +1,15 @@ +return gears.table.join( + awful.key( {"Mod4"}, "p", + function () + awful.prompt.run { + prompt = "Really shutdown? (y/n/r) ", + textbox = awful.screen.focused().mypromptbox.widget, + exe_callback = bin.system.shutdown + } + end, + { + description = "Shutdown", + group = "System" + } + ) +) diff --git a/binds/system/volume.lua b/binds/system/volume.lua new file mode 100755 index 0000000..4d2d6d9 --- /dev/null +++ b/binds/system/volume.lua @@ -0,0 +1,31 @@ +return gears.table.join( + awful.key( {}, "XF86AudioRaiseVolume", + function () + wrapper.volume.up() + end, + { + description = "Volume up", + group = "System" + } + ), + + awful.key( {}, "XF86AudioLowerVolume", + function () + wrapper.volume.down() + end, + { + description = "Volume down", + group = "System" + } + ), + + awful.key( {}, "XF86AudioMute", + function () + wrapper.volume.togglemute() + end, + { + description = "Mute", + group = "System" + } + ) +) diff --git a/binds/unused.lua b/binds/unused.lua new file mode 100755 index 0000000..f47d7d0 --- /dev/null +++ b/binds/unused.lua @@ -0,0 +1,83 @@ +--[[ + + + + +awful.key({"Mod4", "Control"}, "j", + function () + awful.screen.focus_relative( 1) + end, + { + description = "focus the next screen", + group = "screen" + } +), + + + + + +awful.key({"Mod4", "Control"}, "k", + function () + awful.screen.focus_relative(-1) + end, + { + description = "focus the previous screen", + group = "screen" + } +) + + + + + +-- Bind all key numbers to tags. +-- Be careful: we use keycodes to make it work on any keyboard layout. +-- This should map on the top row of your keyboard, usually 1 to 9. +for i = 1, 9 do + globalkeys = gears.table.join(globalkeys, + -- View tag only. + awful.key({ "Mod4" }, "#" .. i + 9, + function () + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + tag:view_only() + end + end, + {description = "view tag #"..i, group = "tag"}), + -- Toggle tag display. + awful.key({ "Mod4", "Control" }, "#" .. i + 9, + function () + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + awful.tag.viewtoggle(tag) + end + end, + {description = "toggle tag #" .. i, group = "tag"}), + -- Move client to tag. + awful.key({ "Mod4", "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:move_to_tag(tag) + end + end + end, + {description = "move focused client to tag #"..i, group = "tag"}), + -- Toggle tag on focused client. + awful.key({ "Mod4", "Control", "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:toggle_tag(tag) + end + end + end, + {description = "toggle focused client on tag #" .. i, group = "tag"}) + ) +end +--]] diff --git a/binds/window/client.lua b/binds/window/client.lua new file mode 100755 index 0000000..90e914d --- /dev/null +++ b/binds/window/client.lua @@ -0,0 +1,78 @@ +return gears.table.join( + awful.key( {"Mod4"}, "Left", + function () + awful.client.focus.byidx( 1) + end, + { + description = "Focus next", + group = "Client" + } + ), + + awful.key( {"Mod4"}, "Right", + function () + awful.client.focus.byidx(-1) + end, + { + description = "Focus previous", + group = "Client" + } + ), + + awful.key( {"Mod4", "Shift"}, "j", + function () + awful.client.swap.byidx(1) + end, + { + description = "Swap with next window", + group = "Client" + } + ), + + awful.key( {"Mod4", "Shift"}, "k", + function () + awful.client.swap.byidx(-1) + end, + { + description = "Swap with previous window", + group = "Client" + } + ), + + awful.key( {"Mod4"}, "u", + awful.client.urgent.jumpto, + { + description = "Jump to urgent window", + group = "Client" + } + ), + + awful.key( {"Mod4"}, "b", + function () + awful.client.focus.history.previous() + if client.focus then + client.focus:raise() + end + end, + { + description = "Go back", + group = "Client" + } + ), + + awful.key( {"Mod4", "Control"}, "n", + function () + local c = awful.client.restore() + -- Focus restored client + if c then + c:emit_signal( + "request::activate", "key.unminimize", {raise = true} + ) + end + end, + { + description = "Restore minimized", + group = "Client" + } + ) +) diff --git a/binds/window/layout.lua b/binds/window/layout.lua new file mode 100755 index 0000000..bd30d34 --- /dev/null +++ b/binds/window/layout.lua @@ -0,0 +1,81 @@ +return gears.table.join( + awful.key( {"Mod4"}, "j", + function () + awful.tag.incmwfact( 0.05) + end, + { + description = "increase master width factor", + group = "Layout" + } + ), + + awful.key({"Mod4"}, "h", + function () + awful.tag.incmwfact(-0.05) + end, + { + description = "decrease master width factor", + group = "Layout" + } + ), + + awful.key( {"Mod4", "Shift"}, "h", + function () + awful.tag.incnmaster(1, nil, true) + end, + { + description = "increase the number of master clients", + group = "Layout" + } + ), + + awful.key( {"Mod4", "Shift"}, "l", + function () + awful.tag.incnmaster(-1, nil, true) + end, + { + description = "decrease the number of master clients", + group = "Layout" + } + ), + + awful.key( {"Mod4", "Control"}, "h", + function () + awful.tag.incncol(1, nil, true) + end, + { + description = "increase the number of columns", + group = "Layout" + } + ), + + awful.key( {"Mod4", "Control"}, "l", + function () + awful.tag.incncol(-1, nil, true) + end, + { + description = "decrease the number of columns", + group = "Layout" + } + ), + + awful.key( {"Mod4"}, "l", + function () + layoutmanager:next() + end, + { + description = "select layouts", + group = "Layout" + } + ), + + awful.key( {"Mod4"}, "k", + function () + layoutmanager:next_alt() + end, + { + description = "cycle alt layouts", + group = "Layout" + } + ) +) diff --git a/binds/window/tags.lua b/binds/window/tags.lua new file mode 100755 index 0000000..dea5080 --- /dev/null +++ b/binds/window/tags.lua @@ -0,0 +1,41 @@ +return gears.table.join( + awful.key( {"Mod1", "Control"}, "Left", + function () + awful.screen.focused().tagger:left() + end, + { + description = "Left", + group = "Tags" + } + ), + + awful.key( {"Mod1", "Control"}, "Right", + function () + awful.screen.focused().tagger:right() + end, + { + description = "Right", + group = "Tags" + } + ), + + awful.key( {"Mod1", "Control"}, "Up", + function () + awful.screen.focused().tagger:up() + end, + { + description = "Up", + group = "Tags" + } + ), + + awful.key( {"Mod1", "Control"}, "Down", + function () + awful.screen.focused().tagger:down() + end, + { + description = "Down", + group = "Tags" + } + ) +) diff --git a/clients/binds/buttons.lua b/clients/binds/buttons.lua new file mode 100755 index 0000000..4d67c92 --- /dev/null +++ b/clients/binds/buttons.lua @@ -0,0 +1,31 @@ +-- Make sure clients and titlebars don't share bids. Both will trigger, +-- and that will cause problems. See titlebar.lua + +return gears.table.join( + awful.button( {}, 1, + function(client) + client:emit_signal("request::activate", "mouse_click", {raise = true}) + end + ), + + awful.button( {"Mod4"}, 1, + function(client) + client:emit_signal("request::activate", "mouse_click", {raise = true}) + awful.mouse.client.move(client) + end + ), + + awful.button( {"Mod4", "Control"}, 1, + function(client) + client:emit_signal("request::activate", "mouse_click", {raise = true}) + awful.mouse.client.resize(client) + end + ), + + awful.button( {"Mod4"}, 3, + function(client) + client:emit_signal("request::activate", "mouse_click", {raise = true}) + awful.mouse.client.resize(client) + end + ) +) diff --git a/clients/binds/keys.lua b/clients/binds/keys.lua new file mode 100755 index 0000000..4104c66 --- /dev/null +++ b/clients/binds/keys.lua @@ -0,0 +1,129 @@ +return gears.table.join( + awful.key( {"Mod4", "Control"}, "Left", + function (c) + c.screen.tagger:move_client(c, "left") + end, + { + description = "move client left", + group = "client" + } + ), + awful.key( {"Mod4", "Control"}, "Right", + function (c) + c.screen.tagger:move_client(c, "right") + end, + { + description = "move client right", + group = "client" + } + ), + awful.key( {"Mod4", "Control"}, "Down", + function (c) + c.screen.tagger:move_client(c, "down") + end, + { + description = "move client down", + group = "client" + } + ), + awful.key( {"Mod4", "Control"}, "Up", + function (c) + c.screen.tagger:move_client(c, "up") + end, + { + description = "move client up", + group = "client" + } + ), + + awful.key( {"Mod4"}, "f", + function (c) + c.fullscreen = not c.fullscreen + c:raise() + end, + { + description = "toggle fullscreen", + group = "client" + } + ), + + awful.key( {"Mod4", "Shift"}, "c", + function (c) + c:kill() + end, + { + description = "close", + group = "client" + } + ), + + awful.key( {"Mod4", "Control"}, "space", + awful.client.floating.toggle, + { + description = "toggle floating", + group = "client" + } + ), + + awful.key( {"Mod4", "Control"}, "Return", + function (c) + c:swap(awful.client.getmaster()) + end, + { + description = "move to master", + group = "client" + } + ), + + awful.key( {"Mod4"}, "t", + function (c) + c.ontop = not c.ontop + end, + { + description = "toggle keep on top", + group = "client" + } + ), + + awful.key( {"Mod4"}, "n", + function (c) + c.minimized = true + end, + { + description = "minimize", + group = "client" + } + ), + + awful.key( {"Mod4"}, "m", + function (c) + c.maximized = not c.maximized + c:raise() + end, + { + description = "(un)maximize", group = "client" + } + ), + + awful.key( {"Mod4", "Control"}, "m", + function (c) + c.maximized_vertical = not c.maximized_vertical + c:raise() + end, + { + description = "(un)maximize vertically", + group = "client" + } + ), + + awful.key( {"Mod4", "Shift"}, "m", + function (c) + c.maximized_horizontal = not c.maximized_horizontal + c:raise() + end, + { + description = "(un)maximize horizontally", + group = "client" + } + ) +) diff --git a/clients/binds/titlebar.lua b/clients/binds/titlebar.lua new file mode 100755 index 0000000..f21c0c5 --- /dev/null +++ b/clients/binds/titlebar.lua @@ -0,0 +1,20 @@ +-- Make sure clients and titlebars don't share bids. Both will trigger, +-- and that will cause problems. See buttons.lua + +return function(client) + return gears.table.join( + awful.button( {}, 1, + function() + client:emit_signal("request::activate", "titlebar", {raise = true}) + awful.mouse.client.move(client) + end + ), + + awful.button( {}, 3, + function() + client:emit_signal("request::activate", "titlebar", {raise = true}) + awful.mouse.client.resize(client) + end + ) + ) +end diff --git a/clients/render.lua b/clients/render.lua new file mode 100755 index 0000000..560780c --- /dev/null +++ b/clients/render.lua @@ -0,0 +1,24 @@ +local render = {} + +render.renderClient = function(client) + if not beautiful.rounded_corners then + return + end + + if (not beautiful.disable_rounded_corners) and ( + client.first_tag.layout == awful.layout.suit.floating or + client.floating + ) then + + client.shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, beautiful.corner_radius, beautiful.corner_radius) + end + else + + client.shape = function(cr, w, h) + gears.shape.rectangle(cr, w, h) + end + end +end + +return render diff --git a/clients/rules.lua b/clients/rules.lua new file mode 100755 index 0000000..7818dc6 --- /dev/null +++ b/clients/rules.lua @@ -0,0 +1,78 @@ +local client_buttons = require("clients.binds.buttons") +local client_keys = require("clients.binds.keys") + +-- Use xprop to get client properties. + +return { + -- 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, + + placement = awful.placement.no_overlap + awful.placement.no_offscreen, + screen = awful.screen.preferred, + buttons = client_buttons, + keys = client_keys, + } + }, + + -- Designate floating clients. + { + rule_any = { + class = { + "feh", + "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size. + "zoom", + "flameshot" + }, + + role = { + "AlarmWindow", -- Thunderbird's calendar. + "ConfigManager", -- Thunderbird's about:config. + "pop-up", "Popup" + } + }, + + properties = { floating = true } + }, + + -- Keep passwordsafe on top + { + rule_any = { class={"pwsafe","Pwsafe"} }, + properties = { + floating = true, + ontop = true + } + }, + + + + -- Custom rules for a floating, transparent terminal + { + rule = { class="kitty-noblur" }, + properties = { + floating = true, + ontop = true, + sticky = true, + + border_color = beautiful.titlebar_fg_normal, + border_width = 0 + } + }, + + -- Set Firefox to always map on the tag named "2" on screen 1. + --[[ + { + rule = { class="Firefox" }, + properties = { + screen = 1, + tag = "2" + } + }, + --]] +} diff --git a/clients/signals.lua b/clients/signals.lua new file mode 100755 index 0000000..c4b9b7e --- /dev/null +++ b/clients/signals.lua @@ -0,0 +1,55 @@ +-- Signal function to execute when a new client appears. +-- Run in rc.lua + +local titlebar = require("clients.titlebar") +local render = require("clients.render") + + +-- Add a titlebar +client.connect_signal("request::titlebars", titlebar.add) + +-- Update titlebars when a screen is arranged +screen.connect_signal("arrange", + function(screen) + for _, client in pairs(screen.clients) do + titlebar.update(client) + render.renderClient(client) + end + end +) + +client.connect_signal("manage", + function (client) + -- Update titlebar status + titlebar.update(client) + render.renderClient(client) + + -- 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 + + -- Prevent clients from being unreachable after screen count changes. + if awesome.startup and not ( + client.size_hints.user_position or client.size_hints.program_position + ) then + awful.placement.no_offscreen(client) + end + end +) + +--[[ Enable sloppy focus, so that focus follows mouse. +client.connect_signal("mouse::enter", + function(c) + c:emit_signal( + "request::activate", + "mouse_enter", + { + raise = true + } + ) + end +) +]]-- + +client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) +client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) diff --git a/clients/titlebar.lua b/clients/titlebar.lua new file mode 100755 index 0000000..7bfe9d3 --- /dev/null +++ b/clients/titlebar.lua @@ -0,0 +1,72 @@ +-- Per-client titlebar setup +-- Required in rc.lua + +local titlebar = {} + +-- bar_buttons is a function. Whenever a title bar is created, its button binds +-- must be specific to the client it's attached to! +local bar_buttons = require("clients.binds.titlebar") + +titlebar.add = function(client) + local bar = awful.titlebar(client, { + position = "left", + size = beautiful.dpi(25) + }) + + bar : setup { + -- Top segment + { + { + --awful.titlebar.widget.iconwidget(client), + awful.titlebar.widget.closebutton(client), + awful.titlebar.widget.minimizebutton(client), + awful.titlebar.widget.maximizedbutton(client), + + spacing = beautiful.titlebar_spacing, + layout = wibox.layout.fixed.vertical + }, + margins = beautiful.titlebar_margins, + widget = wibox.container.margin + }, + + -- Middle segment + { + --[[{} Title + align = "center", + widget = awful.titlebar.widget.titlewidget(client) + },]] + buttons = bar_buttons(client), + layout = wibox.layout.flex.vertical + }, + + -- Bottom segment + { + { + awful.titlebar.widget.floatingbutton(client), + awful.titlebar.widget.stickybutton(client), + awful.titlebar.widget.ontopbutton(client), + + spacing = beautiful.titlebar_spacing, + layout = wibox.layout.fixed.vertical + }, + margins = beautiful.titlebar_margins, + widget = wibox.container.margin + }, + + layout = wibox.layout.align.vertical + } +end + +titlebar.update = function(client) + if ( + (client.first_tag.layout == awful.layout.suit.floating or client.floating) and + --not (client.maximized) and + not (client.requests_no_titlebar) + ) then + awful.titlebar.show(client, "left") + else + awful.titlebar.hide(client, "left") + end +end + +return titlebar diff --git a/conf-example.lua b/conf-example.lua new file mode 100755 index 0000000..aa9cc59 --- /dev/null +++ b/conf-example.lua @@ -0,0 +1,156 @@ +-- Per-machine config file +-- Make a copy of this file named "conf.lua" +-- and set options there. +local conf = {} + + +conf.screenshot_dir = "screenshot_target_dir" + +-- See bar.shortcuts +conf.app_icon_dir = "theme_icon_dir" + + +-- Mount root dir for system mount keybind. +-- Must end with a /. +conf.user_mount_root = "user_mount_path" + + +-- Should tag indicators be updated continuously? +-- Once every two seconds. The timer is in desktop.init +conf.continuous_tag_updates = true + +-- Wallpaper configuration +-- Wallpapers are managed by the desktop module. +-- Static walls will be set in desktop/init.lua; dynamic, time-based +-- walls will be managed by desktop/wallpaper.lua +-- +-- Static: a path to an image file +conf.wallpaper = "path-to-wallpaper.png.png" +-- +-- Dynamic: a table of files and times +-- {file = "path", start_time = {hour, minute}} +--[[ +conf.wallpaper = { + { file = "morning-file.png", start_time = {04, 00} }, + { file = "noon-file.png", start_time = {11, 00} }, + { file = "night-file.png", start_time = {19, 00} }, +} +]]-- + + +-- Enable/disable the battery and backlight control and widgets +conf.battery_enabled = false +conf.backlight_enabled = false + + +-- The position of the bar on each screen +conf.bar_position = "bottom" +-- Bar size in dpi +conf.bar_height = 44 +-- Size of bar widget margins +conf.bar_margin = 3 + +-- A list of shortcuts in the bar. +--[[ defined as follows: +conf.bar_shortcuts = { + { + "command-to-run", + "icon-file" (relative to conf.app_icon_dir) + }, +} +]]-- +conf.bar_shortcuts = {} + + + +-- Enable/Disable the MPC widget +conf.mpc_enabled = true + +-- MPC server. Usually localhost. +-- If your MPC server has a password, use the following format: "passwd@host" +conf.mpd_host = "localhost" +-- Fixed width of the mpc widget +conf.mpc_width = 250 + + +-- Preferred terminal. +conf.terminal = "kitty" + +-- Preferred browser. +conf.browser = "firefox-developer-edition --new-tab" + + +-- The pulse sink volume widgets and keybinds should use. +-- To use the default, keep this value an empty string. +-- Applies the --sink option to pamixer in wrapper.volume +conf.pamixer_sink = "" + + + +-- Table of layouts. +-- This is not handled by the regular awesomewm facility. +-- It's handled by layoutmanager, to add extra features. +-- +-- This table is a table of tables. +-- (see the example) +-- the tables it contains are groups, switched through using the main +-- layout keybind. +-- +-- groups contain one or more layouts. The first layout is selected by default, +-- and is used whenever that group is seleced. +-- Likewise, the first group is the default, and is applied to all tags at the start. +conf.layouts = { + { + awful.layout.suit.tile.left, + awful.layout.suit.tile, + }, + { + awful.layout.suit.fair, + awful.layout.suit.fair.horizontal, + }, + { + awful.layout.suit.floating, + } + + --awful.layout.suit.tile.bottom, + --awful.layout.suit.tile.top, + --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, +} + +-- Order matters! +-- The first entry will be activated at startup. +-- Use ibus engine to get the current engine name. +-- DUPLICATE IBUS_ENGINE VALUES WILL BREAK THE SWITCHER! +-- +-- Some overlay layours require a switch to en:us first. +-- For example, switching from russian (xkb remap) to pinyin (ibus overlay on en:us) +-- will not work. +-- +conf.ibus_language_list = { + { + title = "English", + indicator_code = "en", + ibus_engine = "xkb:us::eng", + }, + { + title = "Russian", + indicator_code = "ru", + ibus_engine = "xkb:ru::rus" + }, + { + title = "Mathwriter", + indicator_code = "∫x", + ibus_engine = "table:mathwriter-ibus", + requires_engine = "xkb:us::eng" + } +} + +return conf diff --git a/desktop/init.lua b/desktop/init.lua new file mode 100755 index 0000000..5220ce2 --- /dev/null +++ b/desktop/init.lua @@ -0,0 +1,232 @@ +local desktop = { + Tagger = require("desktop.tagger"), + + popup = { + language = require("desktop.popups.language") + }, + + widgets = { + tasklist = require("desktop.widgets.tasklist"), + textclock = require("desktop.widgets.textclock"), + layoutbox = require("desktop.widgets.layoutbox"), + keymap = require("desktop.widgets.keymap"), + volume = require("desktop.widgets.volume"), + tagindicator = require("desktop.widgets.tagindicator"), + launcher = require("desktop.widgets.launcher"), + shortcut = require("desktop.widgets.shortcut"), + mdadm = require("desktop.widgets.mdadm"), + + space = function(size) + return wibox.widget { + { + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(size) + }, + layout = wibox.container.background, + } + end, + + + separator = function(size, margin_h, margin_v) + return wibox.widget { + { + widget = wibox.widget.separator, + color = "#FFFFFF55", + forced_width = beautiful.dpi(size), + thickness = beautiful.dpi(size) + }, + layout = wibox.container.margin, + top = beautiful.dpi(margin_v), + bottom = beautiful.dpi(margin_v), + left = beautiful.dpi(margin_h), + right = beautiful.dpi(margin_h) + } + end + } +} + + +-- Load conditional modules +if conf.backlight_enabled then + desktop.widgets.backlight = require("desktop.widgets.backlight") +end +if conf.battery_enabled then + desktop.widgets.battery = require("desktop.widgets.battery") +end +if conf.mpc_enabled then + desktop.widgets.mpc = require("desktop.widgets.mpc") +end + + + +-- If timed wallpaper is enabled, load timed manager +if (type(beautiful.wallpaper) == "table") then + desktop.wallpaper = require("desktop.wallpaper") + screen.connect_signal("property::geometry", desktop.wallpaper.update) + desktop.wallpaper.update() + desktop.wallpaper.start() +else + + -- Otherwise, set static wallpaper on each screen + -- We loop over screens to prevent the wallpaper from being stretched over + -- all displays. If, for some reason, you want that to happen, use a single + -- call of "gears.wallpaper.maximized(beautiful.wallpaper)" instead of + -- this loop. + + for s in screen do + gears.wallpaper.maximized(beautiful.wallpaper, s) + end +end + +-- Set a timer that will update the tag indicators of all screens. +-- Even if we do not want continuous updates, we still need a timer: +-- there must be a significant delay (1ish second) before awesome prepares +-- all clients +desktop.screen_timer = gears.timer { + timeout = 2, + call_now = false, + autostart = true, + single_shot = not conf.continuous_tag_updates, + + callback = function() + for s in screen do + s.tagger:update_widget() + end + end +} + +-- Prepare each screen +awful.screen.connect_for_each_screen( + function(s) + -- s: the screen this function is being called for + -- Create tag table + + s.tagger = desktop.Tagger:new(s) + desktop.widgets.tagindicator(s) + + + -- Create a promptbox for each s + s.mypromptbox = awful.widget.prompt() + + -- Create the bar + s.bar = awful.wibar({ + position = conf.bar_position, + screen = s, + --bg = "#00000000", + bg = beautiful.color.bar.color, + border_width = 0, + height = beautiful.dpi(conf.bar_height), + type = "desktop" + }) + + s.systray = wibox.widget.systray() + s.systraysep = desktop.widgets.separator(2, 5, 3) + s.bar:connect_signal("button::press", + function(_, _, _, button, mods) + + -- Middle-click + if (button == 2) then + s.systray.visible = not s.systray.visible + s.systraysep.visible = s.systray.visible + end + end) + + -- Create shortcut list from config value + if (#conf.bar_shortcuts > 0) then + s.shortcuts = { + layout = wibox.layout.fixed.horizontal, + desktop.widgets.separator(2, 5, 3), + desktop.widgets.space(6) + } + for k, v in pairs(conf.bar_shortcuts) do + s.shortcuts[#s.shortcuts + 1] = desktop.widgets.shortcut:new(v[1], v[2]) + end + end + + + + -- Assemble left bar widgets + + rightside = { + layout = wibox.layout.fixed.horizontal, + spacing = 0 + } + + rightside = gears.table.join(rightside, { + desktop.widgets.space(10), + s.systraysep, + desktop.widgets.space(10), + { + s.systray, + top = beautiful.dpi(3), + bottom = beautiful.dpi(3), + left = 0, right = 0, + layout = wibox.container.margin, + }, + desktop.widgets.separator(2, 5, 3), + desktop.widgets.space(10), + }) + + if (conf.mpc_enabled) then + rightside = gears.table.join(rightside, { + desktop.widgets.mpc, + desktop.widgets.space(5), + desktop.widgets.separator(2, 5, 3), + desktop.widgets.space(15), + + }) + end + + rightside = gears.table.join(rightside, { + desktop.widgets.textclock, + desktop.widgets.space(8), + + desktop.widgets.battery, + desktop.widgets.backlight, + desktop.widgets.volume, + desktop.widgets.space(8), + + desktop.widgets.keymap, + desktop.widgets.space(8), + desktop.widgets.mdadm, + desktop.widgets.space(8) + + }) + + + + s.bar:setup { + layout = wibox.container.margin, + margins = beautiful.dpi(conf.bar_margin), + + { + layout = wibox.layout.align.horizontal, + { + layout = wibox.layout.fixed.horizontal, + + desktop.widgets.space(8), + + + desktop.widgets.launcher, + + desktop.widgets.space(18), + s.tagindicator, + desktop.widgets.layoutbox(s), + + s.shortcuts, + + desktop.widgets.space(6), + desktop.widgets.separator(2, 5, 3), + desktop.widgets.space(18), + desktop.widgets.tasklist(s), + }, + + s.mypromptbox, + rightside + } + } + end +) + +return desktop diff --git a/desktop/popups/language.lua b/desktop/popups/language.lua new file mode 100644 index 0000000..f8d8390 --- /dev/null +++ b/desktop/popups/language.lua @@ -0,0 +1,110 @@ +local language = {} + + +language.language_list = conf.ibus_language_list + + +language.widget = wibox.widget { + homogeneous = false, + vertical_homogeneous = true, + horizontal_homogeneous = false, + vertical_spacing = beautiful.dpi(10), + horizontal_spacing = beautiful.dpi(0), + min_cols_size = beautiful.dpi(20), + min_rows_size = beautiful.dpi(20), + layout = wibox.layout.grid +} + + +for k, l in pairs(language.language_list) do + + l["widget_checkbox"] = wibox.widget { + checked = false, + border_width = beautiful.dpi(3), + paddings = beautiful.dpi(4), + margins = beautiful.dpi(5), + color = beautiful.color.bar.active, + border_color = beautiful.color.bar.inactive, + widget = wibox.widget.checkbox, + forced_height = beautiful.dpi(30), + forced_width = beautiful.dpi(30), + shape = gears.shape.circle, + } + + language.widget:add_widget_at(l["widget_checkbox"], k, 1, 1, 1) + + language.widget:add_widget_at(wibox.widget { + markup = "" .. l["title"] .. "", + align = "left", + valign = "center", + font = "Comfortaa 23", + widget = wibox.widget.textbox + }, k, 2, 0, 1) +end + +language.next = function() + if (language.popup.visible) then + wrapper.ibus.next(function() + language.update_checks() + end) + else + language.update_checks() + end + + language.show_popup() +end + +language.update_checks = function() + for _, l in pairs(language.language_list) do + l["widget_checkbox"].checked = (wrapper.ibus.current_engine == l["ibus_engine"]) + end +end + +language.show_popup = function() + language.popup.screen = awful.screen.focused() + language.popup.visible = true + + language.popup_timer:again() +end + +language.popup = awful.popup { + widget = { + { + language.widget, + margins = 10, + widget = wibox.container.margin + }, + bg = "#000000", + opacity = 1, + widget = wibox.container.background + }, + border_color = "#000000", + border_width = 0, + opacity = 1, + + type = "menu", + ontop = true, + visible = false, + hide_on_right_click = true, + + shape = gears.shape.rounded_rect, + placement = function(d) + return awful.placement.centered(d, { + honor_workarea = true + }) + end, +} + +language.popup_timer = gears.timer { + timeout = 1, + autostart = false, + call_now = false, + single_shot = true, + + callback = function() + language.popup.visible = false + end +} + + +return language diff --git a/desktop/tagger.lua b/desktop/tagger.lua new file mode 100755 index 0000000..e5623bc --- /dev/null +++ b/desktop/tagger.lua @@ -0,0 +1,141 @@ +-- Tag grid manager + +local Tagger = { + screen = nil, rows = 2, cols = 3 +} +Tagger.__index = Tagger + +function Tagger:new(screen) + local t = {} + setmetatable(t, Tagger) + t.screen = screen + + -- Create tags on this Tagger's screen + for r=1, t.rows do + for c=1, t.cols do + awful.tag.add("(" .. tostring(r) .. ", " .. tostring(c) .. ")", { + layout = layoutmanager:default_layout(), + screen = t.screen, + + gap_single_client = false, + gap = beautiful.useless_gap, + volatile = false, + + -- Only select the first tag + selected = ((r == 1) and (c == 1)) + }) + end + end + return t +end + + +function Tagger:get_tag() + return self.screen.selected_tag.index +end + +-- Return current column +function Tagger:get_col() + return ( (self:get_tag() - 1) % self.cols ) + 1 +end + +-- Return current row +function Tagger:get_row() + return math.floor( (self:get_tag() - self:get_col()) / self.cols ) + 1 +end + +-- Select a tag by position +function Tagger:setpos(row, col) + local target_absolute = (self.cols * (row - 1)) + col + local target_relative = target_absolute - self.screen.selected_tag.index + awful.tag.viewidx(target_relative) + + self:update_widget() +end + +-- Update this tagger's screen's tagindicator +function Tagger:update_widget() + local clients + local tgs = self.screen.tags + + for i=1, #tgs do + clients = tgs[i]:clients() + + -- Each tag indicator is a "checkbox" widget. + -- Make that the currently active tag is checked and that all + -- others are not. + if (tgs[i].index == self.screen.selected_tag.index) then + self.screen.tagindicators[i].checked = true + else + self.screen.tagindicators[i].checked = false + end + + -- Highlight tags that are not empty + if (#clients == 0) then + self.screen.tagindicators[i].border_color = beautiful.color.bar.inactive + else + self.screen.tagindicators[i].border_color = beautiful.color.bar.active + end + end +end + +-- Navigation +function Tagger:up() + local row = self:get_row() - 1 + local col = self:get_col() + + if (row >= 1) then + self:setpos(row, col) + end +end + +function Tagger:down() + local row = self:get_row() + 1 + local col = self:get_col() + + if (row <= self.rows) then + self:setpos(row, col) + end +end + +function Tagger:right() + local row = self:get_row() + local col = self:get_col() + 1 + + if (col <= self.cols) then + self:setpos(row, col) + end +end + +function Tagger:left() + local row = self:get_row() + local col = self:get_col() - 1 + + if (col >= 1) then + self:setpos(row, col) + end +end + + + +-- Moving clients +function Tagger:move_client(client, direction) + if direction == "up" then + self:up() + elseif direction == "down" then + self:down() + elseif direction == "left" then + self:left() + elseif direction == "right" then + self:right() + end + + if client.first_tag.layout == awful.layout.suit.floating then + client.floating = true + end + + client:move_to_tag(self.screen.selected_tag) + self:update_widget() +end + +return Tagger diff --git a/desktop/wallpaper.lua b/desktop/wallpaper.lua new file mode 100755 index 0000000..5bf171a --- /dev/null +++ b/desktop/wallpaper.lua @@ -0,0 +1,62 @@ +local wallpaper = {} + +wallpaper.active = -1 + +-- How many minutes have passed since 00:00 +wallpaper.timenow = function() + local time = {} + + local t + for t in string.gmatch(os.date("%H:%M"), "[^:]+") do + table.insert(time, t) + end + + return (tonumber(time[1]) * 60) + tonumber(time[2]) +end + + +-- Return wallpaper's start time in minutes since 00:00 +wallpaper.get_start_time = function(entry) + return (entry.start_time[1] * 60) + entry.start_time[2] +end + + +-- Set the ith wallpaper +wallpaper.set = function(i) + local path = beautiful.wallpaper[i].file + wallpaper.active = i + + -- Set wallpaper maximized on each display + for s in screen do + gears.wallpaper.maximized(path, s) + end +end + + +-- Which image should be scheduled now? +wallpaper.current = function() + local i + for i = #beautiful.wallpaper, 1, -1 do + if wallpaper.get_start_time(beautiful.wallpaper[i]) <= wallpaper.timenow() then + return i + end + end +end + + +wallpaper.update = function() + local current = wallpaper.current() + + if current ~= wallpaper.active then + wallpaper.set(current) + end + + return true +end + + +wallpaper.start = function() + window.timer = gears.timer.start_new(10, wallpaper.update) +end + +return wallpaper diff --git a/desktop/widgets/backlight.lua b/desktop/widgets/backlight.lua new file mode 100755 index 0000000..d474ba1 --- /dev/null +++ b/desktop/widgets/backlight.lua @@ -0,0 +1,101 @@ +local backlight = {} + + +backlight.icon = wibox.widget { + id = "icon", + image = beautiful.icons.brightness.i, + resize = true, + widget = wibox.widget.imagebox, +} + +backlight.arc = wibox.widget { + { + backlight.icon, + top = beautiful.dpi(1), + bottom = beautiful.dpi(1), + layout = wibox.container.margin, + }, + max_value = 100, + thickness = beautiful.dpi(4), + start_angle = 4.71238898, -- 2pi*3/4 + --forced_height = beautiful.dpi(16), + --forced_width = beautiful.dpi(16), + colors = {"#27D4CC", "#00446B"}, + bg = "#FFFFFF30", + paddings = beautiful.dpi(2), + widget = wibox.container.arcchart +} + + +backlight.widget = wibox.widget { + { + { -- Right space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + { -- Main indicator. Can be replaced with backlight.arc + backlight.arc, + top = beautiful.dpi(2), + bottom = beautiful.dpi(2), + layout = wibox.container.margin, + }, + { -- Left space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + +backlight.widget:connect_signal("mouse::enter", function(result) + backlight.widget.bg = beautiful.color.bar.hover_bg + +end) + +backlight.widget:connect_signal("mouse::leave", function(result) + backlight.widget.bg = beautiful.color.transparent +end) + +backlight.widget:connect_signal("button::press", + function(_, _, _, button, mods) + -- Scroll up + if (button == 4) then + wrapper.backlight.up() + -- Scroll down + elseif (button == 5) then + wrapper.backlight.down() + end + end +) + +backlight.update = function(value) + backlight.arc.value = value + + --[[if value > 90 then backlight.icon.image = beautiful.icons.brightness.i + elseif value > 80 then backlight.icon.image = beautiful.icons.brightness.h + elseif value > 70 then backlight.icon.image = beautiful.icons.brightness.g + elseif value > 60 then backlight.icon.image = beautiful.icons.brightness.f + elseif value > 50 then backlight.icon.image = beautiful.icons.brightness.e + elseif value > 40 then backlight.icon.image = beautiful.icons.brightness.d + elseif value > 30 then backlight.icon.image = beautiful.icons.brightness.c + elseif value > 20 then backlight.icon.image = beautiful.icons.brightness.b + elseif value <= 10 then backlight.icon.image = beautiful.icons.brightness.a end + --]] + +end + + +-- Add various hooks +wrapper.backlight.add_hook(backlight.update) +bin.backlight.watch( + 5, + function() + wrapper.backlight.read(backlight.update) + end, + backlight.widget +) + +return backlight.widget diff --git a/desktop/widgets/battery.lua b/desktop/widgets/battery.lua new file mode 100755 index 0000000..feae5f5 --- /dev/null +++ b/desktop/widgets/battery.lua @@ -0,0 +1,214 @@ +local battery = {} + +-- Percentages to warn at +-- (must be in order least -> greatest) +battery.warnings = { + 5, 10, 25, 50 +} + +battery.warninglog = {} + +for i=1, #battery.warnings do + battery.warninglog[i] = false +end + +battery.image_path = beautiful.icons.battery.missing +battery.icon = wibox.widget { + image = beautiful.icons.battery.missing, + resize = true, + widget = wibox.widget.imagebox, +} + + +battery.progressbar = wibox.widget { + max_value = 100, + widget = wibox.widget.progressbar, + paddings = beautiful.dpi(2), + color = beautiful.color.bar.active, + background_color = beautiful.color.transparent, + border_color = beautiful.color.bar.active, + border_width = beautiful.dpi(1), + margins = beautiful.dpi(3) +} + +battery.arc = wibox.widget { + { + battery.icon, + top = beautiful.dpi(1), + bottom = beautiful.dpi(1), + layout = wibox.container.margin, + }, + max_value = 100, + thickness = beautiful.dpi(4), + start_angle = 4.71238898, -- 2pi*3/4 + --forced_height = beautiful.dpi(16), + --forced_width = beautiful.dpi(16), + colors = {"#27D4CC", "#00446B"}, + bg = "#FFFFFF30", + paddings = beautiful.dpi(2), + widget = wibox.container.arcchart +} + + +battery.rotator = wibox.widget { + battery.progressbar, + forced_width = beautiful.dpi(15), + direction = "east", + layout = wibox.container.rotate, +} + + +battery.widget = wibox.widget { + { + { -- Right space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + { + battery.arc, + top = beautiful.dpi(2), + bottom = beautiful.dpi(2), + layout = wibox.container.margin, + }, + { -- Left space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + +battery.widget:connect_signal("mouse::enter", function(result) + battery.widget.bg = beautiful.color.bar.hover_bg +end) + +battery.widget:connect_signal("mouse::leave", function(result) + battery.widget.bg = beautiful.color.transparent +end) + +battery.update = function(stdout) + local batpec = string.match(stdout, "(%d?%d?%d)%%") + batpec = tonumber(string.format("% 3d", batpec)) + + local discharging = string.match(stdout, "discharging") or false + + -- Handle low power notifications + if discharging then + for i=1, #battery.warnings do + v = battery.warnings[i] + if (batpec <= v) and (not battery.warninglog[i]) then + battery.warninglog[i] = true + + naughty.notify({ + title = "Low power", + text = "Battery is at " .. tostring(batpec) .. "%", + icon = beautiful.icons.battery.caution, + + timeout = 5, + ignore_suspend = true, + + border_color = beautiful.color.battery.danger, + preset = beautiful.notification_templates.bottom_right + }) + break + end + end + else + for i=1, #battery.warnings do + if (batpec >= battery.warnings[i]) then + battery.warninglog[i] = false + end + end + end + + + battery.progressbar.value = batpec + battery.arc.value = batpec + + if batpec > 60 then + battery.progressbar.color = beautiful.color.battery.good + elseif batpec > 40 then + battery.progressbar.color = beautiful.color.battery.low + elseif batpec <= 40 then + battery.progressbar.color = beautiful.color.battery.danger + end + + + battery.image_path = beautiful.icons.battery.missing + -- Set current battery icon + if (not discharging) then + if batpec > 80 then battery.image_path = beautiful.icons.battery.charging.full + elseif batpec > 60 then battery.image_path = beautiful.icons.battery.charging.good + elseif batpec > 40 then battery.image_path = beautiful.icons.battery.charging.low + elseif batpec > 20 then battery.image_path = beautiful.icons.battery.charging.caution + elseif batpec <= 20 then battery.image_path = beautiful.icons.battery.charging.empty end + else + if batpec > 80 then battery.image_path = beautiful.icons.battery.full + elseif batpec > 60 then battery.image_path = beautiful.icons.battery.good + elseif batpec > 40 then battery.image_path = beautiful.icons.battery.low + elseif batpec > 20 then battery.image_path = beautiful.icons.battery.caution + elseif batpec <= 20 then battery.image_path = beautiful.icons.battery.empty end + end + battery.icon.image = battery.image_path + + if (not discharging) and (batpec > 90) then + battery.progressbar.border_color = beautiful.color.battery.good + elseif (discharging) and (batpec <= 25) then + battery.progressbar.border_color = beautiful.color.battery.danger + else + battery.progressbar.border_color = beautiful.color.bar.active + end + + if discharging then + battery.rotator.direction = "east" + else + battery.rotator.direction = "west" + end +end + +battery.readupdate = function() + bin.battery.status( + function(stdout, stderr, exitreason, exitcode) + battery.update(stdout) + end + ) +end + + +battery.widget:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 1) then + bin.battery.status( + function(stdout, stderr, exitreason, exitcode) + local batpec = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) + local batstat = string.match(stdout, "discharging") or false + + if batstat then + batstat = "Discharging, " + else + batstat = "Charging, " + end + + local out = naughty.notify({ + title = "Battery:", + text = batstat .. batpec .. "%", + icon = battery.image_path, + replaces_id = battery.notid, + ignore_suspend = true, + + preset = beautiful.notification_templates.bottom_right + }) + battery.notid = out.id + end + ) + end + end +) + +bin.battery.watch(10, function(_, stdout) battery.update(stdout) end, battery.widget) + +return battery.widget diff --git a/desktop/widgets/keymap.lua b/desktop/widgets/keymap.lua new file mode 100755 index 0000000..848b6c9 --- /dev/null +++ b/desktop/widgets/keymap.lua @@ -0,0 +1,41 @@ +local keymap = {} + + +keymap.widget = wibox.widget { + { + { -- Right spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + wibox.widget { + wrapper.ibus.ibus_indicator_text, + wrapper.ibus.xkb_indicator_text, + + forced_num_cols = 1, + forced_num_rows = 2, + homogeneous = true, + expand = true, + layout = wibox.layout.grid + }, + { -- Left spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + + +-- Change background when mouse is over widget +keymap.widget:connect_signal("mouse::enter", function(result) + keymap.widget.bg = beautiful.color.bar.hover_bg +end) + +keymap.widget:connect_signal("mouse::leave", function(result) + keymap.widget.bg = beautiful.color.transparent +end) +return keymap.widget diff --git a/desktop/widgets/launcher.lua b/desktop/widgets/launcher.lua new file mode 100644 index 0000000..ceab4fa --- /dev/null +++ b/desktop/widgets/launcher.lua @@ -0,0 +1,52 @@ +local widget = {} + + +widget.icon = wibox.widget { + resize = true, + image = beautiful.icons.launcher, + widget = wibox.widget.imagebox +} + +widget.widget = wibox.widget { + { + { -- Right space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + { + widget.icon, + top = beautiful.dpi(2), + bottom = beautiful.dpi(2), + layout = wibox.container.margin, + }, + { -- Left space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + +widget.widget:connect_signal("mouse::enter", function(result) + widget.widget.bg = beautiful.color.bar.hover_bg + +end) + +widget.widget:connect_signal("mouse::leave", function(result) + widget.widget.bg = beautiful.color.transparent +end) + +widget.widget:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 1) then + bin.rofi.launcher() + end + end +) + +wrapper.volume.commands:get(widget.update) + +return widget.widget diff --git a/desktop/widgets/layoutbox.lua b/desktop/widgets/layoutbox.lua new file mode 100755 index 0000000..21f5d74 --- /dev/null +++ b/desktop/widgets/layoutbox.lua @@ -0,0 +1,38 @@ +local layoutbox = {} + +layoutbox.make = function(screen) + local widget + + widget = wibox.widget { + { + awful.widget.layoutbox(screen), + margins = beautiful.dpi(3), + layout = wibox.container.margin, + }, + layout = wibox.container.background, + } + + -- Setup buttons + widget:buttons( + gears.table.join( + awful.button({ }, 1, function () layoutmanager:next_alt() end), + awful.button({ }, 3, function () layoutmanager:prev_alt() end), + awful.button({ }, 4, function () layoutmanager:next() end), + awful.button({ }, 5, function () layoutmanager:prev() end) + ) + ) + + + -- Change background when mouse is over widget + widget:connect_signal("mouse::enter", function(result) + widget.bg = beautiful.color.bar.hover_bg + end) + + widget:connect_signal("mouse::leave", function(result) + widget.bg = beautiful.color.transparent + end) + + return widget +end + +return layoutbox.make diff --git a/desktop/widgets/mdadm.lua b/desktop/widgets/mdadm.lua new file mode 100644 index 0000000..629bbd8 --- /dev/null +++ b/desktop/widgets/mdadm.lua @@ -0,0 +1,49 @@ +local raidw = {} + + +raidw.title_text = wibox.widget.textbox("Raid") +raidw.title_text.valign = "center" +raidw.title_text.align = "center" +raidw.title_text.font = "Hack NF 10" + +raidw.widget = wibox.widget { + { + { -- Right spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + wibox.widget { + raidw.title_text, + wrapper.mdadm.indicator_text, + + forced_num_cols = 1, + forced_num_rows = 2, + homogeneous = true, + expand = true, + layout = wibox.layout.grid + }, + + { -- Left spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + + +-- Change background when mouse is over widget +raidw.widget:connect_signal("mouse::enter", function(result) + raidw.widget.bg = beautiful.color.bar.hover_bg +end) + +raidw.widget:connect_signal("mouse::leave", function(result) + raidw.widget.bg = beautiful.color.transparent +end) + +return raidw.widget diff --git a/desktop/widgets/mpc.lua b/desktop/widgets/mpc.lua new file mode 100644 index 0000000..efee19d --- /dev/null +++ b/desktop/widgets/mpc.lua @@ -0,0 +1,193 @@ +local mpc_widget = {} + +mpc_widget.title = wibox.widget.textbox("MPD is not") +mpc_widget.title.valign = "center" +mpc_widget.title.align = "left" +mpc_widget.title.font = "Hack NF 12" +mpc_widget.title.ellipsize = "end" +mpc_widget.title.forced_width = beautiful.dpi(conf.mpc_width) + +mpc_widget.artist = wibox.widget.textbox("connected") +mpc_widget.artist.valign = "center" +mpc_widget.artist.align = "left" +mpc_widget.artist.font = "Hack NF 12" +mpc_widget.artist.ellipsize = "end" +mpc_widget.artist.forced_width = beautiful.dpi(conf.mpc_width) + +mpc_widget.volume = wibox.widget.textbox("??") +mpc_widget.volume.valign = "center" +mpc_widget.volume.align = "left" +mpc_widget.volume.font = "Hack NF 10" +mpc_widget.volume.ellipsize = "end" +mpc_widget.volume.forced_width = beautiful.dpi(10) + + +mpc_widget.icon_play = wibox.widget { + resize = true, + image = beautiful.icons.music.blue.play, + widget = wibox.widget.imagebox +} + + + +mpc_widget.left = wibox.widget { + wibox.widget { + { + mpc_widget.icon_play, + top = beautiful.dpi(2), + bottom = beautiful.dpi(2), + left = 0, right = 0, + layout = wibox.container.margin, + }, + mpc_widget.volume, + + forced_num_cols = 1, + forced_num_rows = 2, + homogeneous = true, + expand = true, + layout = wibox.layout.grid + }, + layout = wibox.container.background +} + +mpc_widget.right = wibox.widget { + wibox.widget { + mpc_widget.title, + mpc_widget.artist, + + forced_num_cols = 1, + forced_num_rows = 2, + homogeneous = true, + expand = true, + layout = wibox.layout.grid + }, + layout = wibox.container.background, +} + + +mpc_widget.widget = wibox.widget { + { + { -- Right spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + mpc_widget.left, + mpc_widget.right, + + { -- Left spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + + +mpc_widget.widget:connect_signal("mouse::enter", function(result) + mpc_widget.widget.bg = beautiful.color.bar.hover_bg +end) + +mpc_widget.widget:connect_signal("mouse::leave", function(result) + mpc_widget.widget.bg = beautiful.color.transparent +end) + + +mpc_widget.widget:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 3) or (button == 1)then + bin.mpc.command("toggle") + end + mpc_widget.readupdate() + end +) + + +mpc_widget.right:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 4) then -- Scroll up + bin.mpc.command("prev") + elseif (button == 5) then -- Scroll down + bin.mpc.command("next") + end + + mpc_widget.readupdate() + end +) + + +mpc_widget.left:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 4) then -- Scroll up + bin.mpc.command("volume +5") + elseif (button == 5) then -- Scroll down + bin.mpc.command("volume -5") + end + mpc_widget.readupdate() + end +) + + +mpc_widget.update = function(stdout) + if (stdout == "") then + return + end + + mpc_widget.title.markup = string.match(stdout, "title=(.*)artist=") + mpc_widget.artist.markup = string.match(stdout, "artist=(.*)") + + +end + + +mpc_widget.update_status = function(stdout) + play = string.match(stdout, "(%[playing)") or false + pause = string.match(stdout, "(%[paused)") or false + stop = not (play or pause) + + if (play) then + mpc_widget.icon_play.image = beautiful.icons.music.blue.play + elseif (pause) then + mpc_widget.icon_play.image = beautiful.icons.music.blue.pause + elseif (stop) then + mpc_widget.icon_play.image = beautiful.icons.music.blue.stop + end + + volume = string.match(stdout, "volume: (%d?%d?%d)%%") + if (volume) then + mpc_widget.volume.markup = volume .. "%" + else + mpc_widget.volume.markup = "" + end +end + +mpc_widget.readupdate = function() + bin.mpc.command("current --format \"title=%title% artist=%artist%\"", + function(stdout, stderr, exitreason, exitcode) + mpc_widget.update(stdout) + end + ) + + bin.mpc.command("status", + function(stdout, stderr, exitreason, exitcode) + mpc_widget.update_status(stdout) + end + ) +end + + +-- The time here is super short because the --wait option is used in mpc. +-- It will not return a response until changes are seen. +bin.mpc.watch("current --wait", 0.01, function(_, stdout) mpc_widget.readupdate() end, mpc_widget.widget) +bin.mpc.watch("current", 1, function(_, stdout) mpc_widget.readupdate() end, mpc_widget.widget) + + +-- Make sure you do an initial read, though, otherwise the widget will +-- not update until a change occurs. +mpc_widget.readupdate() + + +return mpc_widget.widget diff --git a/desktop/widgets/shortcut.lua b/desktop/widgets/shortcut.lua new file mode 100644 index 0000000..762ac87 --- /dev/null +++ b/desktop/widgets/shortcut.lua @@ -0,0 +1,51 @@ +local shortcuts = {} + +function shortcuts:new(command, icon) + widget = wibox.widget { + { + { -- Right space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + { + wibox.widget { + resize = true, + image = conf.app_icon_dir .. icon, + widget = wibox.widget.imagebox + }, + top = beautiful.dpi(3), + bottom = beautiful.dpi(3), + layout = wibox.container.margin, + }, + { -- Left space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background + } + + widget:connect_signal("mouse::enter", function(result) + result.bg = beautiful.color.bar.hover_bg + end) + + widget:connect_signal("mouse::leave", function(result) + result.bg = beautiful.color.transparent + end) + + + widget:connect_signal("button::press", + function(_, _, _, button, mods) + if (button == 1) then + awful.spawn(command, false) + end + end + ) + + return widget +end + +return shortcuts diff --git a/desktop/widgets/tagindicator.lua b/desktop/widgets/tagindicator.lua new file mode 100755 index 0000000..698a873 --- /dev/null +++ b/desktop/widgets/tagindicator.lua @@ -0,0 +1,68 @@ +local tagindicator = {} + +tagindicator.make = function(screen) + local widget + + -- Create tag tagindicators + -- We're using flex.vertical and flex.horizontal layouts because the grid + -- layout doesn't expand things properly. + screen.tagindicators = {} + screen.tagindicator = wibox.widget { + homogeneous = true, + spacing = beautiful.dpi(2), + min_cols_size = 10, + min_rows_size = 10, + layout = wibox.layout.grid + } + + local tmp_row + for r=1, screen.tagger.rows do + for c=1, screen.tagger.cols do + screen.tagindicators[(c + (screen.tagger.cols * (r - 1)))] = wibox.widget { + checked = false, + border_width = beautiful.dpi(2), + paddings = beautiful.dpi(3), + color = beautiful.color.bar.active, + border_color = beautiful.color.bar.inactive, + widget = wibox.widget.checkbox + } + + -- Calculate checkbox size limit + local cbox_maxsize = beautiful.dpi(conf.bar_height) + cbox_maxsize = cbox_maxsize - (2 * beautiful.dpi(conf.bar_margin)) + cbox_maxsize = cbox_maxsize - (screen.tagger.rows - 1)*(beautiful.dpi(screen.tagindicator.spacing)) + + if ((conf.bar_position == "bottom") or (conf.bar_position == "top")) then + cbox_maxsize = cbox_maxsize / screen.tagger.rows + else + cbox_maxsize = cbox_maxsize / screen.tagger.cols + end + + screen.tagindicator:add_widget_at( + -- The constraint container is VERY necessary here! + -- Otherwise, the checkboxes will fill all the height that is available to them. + wibox.container.constraint( + screen.tagindicators[(c + (screen.tagger.cols * (r - 1)))], + "exact", cbox_maxsize, cbox_maxsize + ), r, c) + end + end + + widget = wibox.widget { + screen.tagindicator, + layout = wibox.container.background + } + + -- Change background when mouse is over widget + widget:connect_signal("mouse::enter", function(result) + widget.bg = beautiful.color.bar.hover_bg + end) + + widget:connect_signal("mouse::leave", function(result) + widget.bg = beautiful.color.transparent + end) + + return widget +end + +return tagindicator.make diff --git a/desktop/widgets/tasklist.lua b/desktop/widgets/tasklist.lua new file mode 100755 index 0000000..4809343 --- /dev/null +++ b/desktop/widgets/tasklist.lua @@ -0,0 +1,119 @@ +local tasklist = {} + +--[[ Create a tasklist widget +s.mytasklist = awful.widget.tasklist { + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + buttons = tasklist_buttons +} ]]-- + +local 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 + ) +) + + +tasklist.make = function(screen) + return awful.widget.tasklist({ + screen = screen, + filter = awful.widget.tasklist.filter.currenttags, + buttons = buttons, + layout = { + spacing_widget = { + { + forced_width = beautiful.dpi(2), + forced_height = beautiful.dpi(12), + thickness = beautiful.dpi(1), + color = "#000000FF", --beautiful.color.bar.spacer, + widget = wibox.widget.separator + }, + valign = "center", + halign = "center", + widget = wibox.container.place, + }, + spacing = 1, + layout = wibox.layout.fixed.horizontal + }, + + -- Notice that there is *NO* wibox.wibox prefix, it is a template, + -- not a widget instance. + widget_template = { + { + wibox.widget.base.make_widget(), + forced_height = beautiful.dpi(3), + id = "top_tab", + widget = wibox.container.background, + }, + { + { + { + id = "clienticon", + widget = awful.widget.clienticon, + }, + margins = beautiful.dpi(3), + widget = wibox.container.margin + }, + id = "background", + widget = wibox.container.background, + }, + nil, + + + -- The create callback is only called once, when the task indicator + -- is created. + create_callback = function(self, c, index, objects) + -- Set indicator icon + self:get_children_by_id("clienticon")[1].client = c + + -- Change background when mouse is over widget + self:connect_signal("mouse::enter", function(result) + self:get_children_by_id("top_tab")[1].bg = "#2DA0DA" + self:get_children_by_id("background")[1].bg = beautiful.color.bar.hover_bg + + end) + + self:connect_signal("mouse::leave", function(result) + self:get_children_by_id("background")[1].bg = beautiful.color.transparent + + if c == client.focus then + self:get_children_by_id("top_tab")[1].bg = "#2DA0FF" + elseif c.minimized then + self:get_children_by_id("top_tab")[1].bg = "#2DA0DA77" + else + self:get_children_by_id("top_tab")[1].bg = beautiful.color.transparent + end + end) + end, + + -- The update callback is called every time the icon needs updating. + update_callback = function(self, c, index, objects) + + -- Update indicator icon + self:get_children_by_id("clienticon")[1].client = c + + -- Update top color + if c == client.focus then + self:get_children_by_id("top_tab")[1].bg = "#2DA0DA" + elseif c.minimized then + self:get_children_by_id("top_tab")[1].bg = "#2DA0DA77" + else + self:get_children_by_id("top_tab")[1].bg = beautiful.color.transparent + end + end, + layout = wibox.layout.align.vertical, + }, + }) +end + +return tasklist.make diff --git a/desktop/widgets/textclock.lua b/desktop/widgets/textclock.lua new file mode 100755 index 0000000..aca440f --- /dev/null +++ b/desktop/widgets/textclock.lua @@ -0,0 +1,49 @@ +local textclock = {} + + + + +textclock.widget = wibox.widget { + { + { -- Right spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + wibox.widget { + wibox.widget.textclock("%m/%d"), + wibox.widget.textclock("%I:%M", 60), + + -- Long format: + -- wibox.widget.textclock("%m/%d/%y"), + -- wibox.widget.textclock("%I:%M:%S", 1), + -- %H - 24-hour time + -- %I - 12-hour time + + forced_num_cols = 1, + forced_num_rows = 2, + homogeneous = true, + expand = true, + layout = wibox.layout.grid + }, + { -- Left spacer + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + +-- Change background when mouse is over widget +textclock.widget:connect_signal("mouse::enter", function(result) + textclock.widget.bg = beautiful.color.bar.hover_bg +end) + +textclock.widget:connect_signal("mouse::leave", function(result) + textclock.widget.bg = beautiful.color.transparent +end) + +return textclock.widget diff --git a/desktop/widgets/volume.lua b/desktop/widgets/volume.lua new file mode 100755 index 0000000..2261532 --- /dev/null +++ b/desktop/widgets/volume.lua @@ -0,0 +1,142 @@ +local widget = {} + + +widget.icon = wibox.widget { + resize = true, + image = beautiful.icons.volume.mute, + widget = wibox.widget.imagebox +} + +widget.arc = wibox.widget { + { + widget.icon, + top = beautiful.dpi(1), + bottom = beautiful.dpi(1), + layout = wibox.container.margin, + }, + max_value = 1, + thickness = beautiful.dpi(4), + start_angle = 4.71238898, -- 2pi*3/4 + --forced_height = beautiful.dpi(16), + --forced_width = beautiful.dpi(16), + colors = {"#27D4CC", "#00446B"}, + bg = "#FFFFFF30", + paddings = beautiful.dpi(2), + widget = wibox.container.arcchart +} + +widget.bar = wibox.widget { + max_value = 100, + value = 0, + --forced_height = 20, + forced_width = beautiful.dpi(50), + paddings = 0, + border_width = 0, + color = { + type = "linear", + from = {0, 0}, to = {beautiful.dpi(50), 0}, + stops = { { 0, "#27D4CC" }, { 1, "#00446B" }} + }, + background_color = "#FFFFFF30", + widget = wibox.widget.progressbar, + shape = gears.shape.rounded_bar, +} + + +widget.widget = wibox.widget { + { + { -- Right space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + { + widget.arc, + top = beautiful.dpi(2), + bottom = beautiful.dpi(2), + layout = wibox.container.margin, + }, + { -- Left space + widget = wibox.widget.separator, + color = beautiful.color.transparent, + forced_width = beautiful.dpi(3) + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.container.background, +} + +widget.widget:connect_signal("mouse::enter", function(result) + widget.widget.bg = beautiful.color.bar.hover_bg + +end) + +widget.widget:connect_signal("mouse::leave", function(result) + widget.widget.bg = beautiful.color.transparent +end) + +widget.widget:connect_signal("button::press", + function(_, _, _, button, mods) + + -- Right-click + if (button == 3) then + wrapper.volume.togglemute() + + -- Scroll up + elseif (button == 4) then + wrapper.volume.up() + + -- Scroll down + elseif (button == 5) then + wrapper.volume.down() + end + end +) + +widget.update = function(status) + + if (status.value == false) then + widget.icon.image = beautiful.icons.volume.error + widget.arc.value = 100; + widget.bar.value = 100; + return + end + + widget.arc.value = status.value / 100; + widget.bar.value = status.value; + + + if (status.mute) then + -- Set muted icon + widget.icon.image = beautiful.icons.volume.mute + else + -- Set icon by value + if status.value > 70 then + widget.icon.image = beautiful.icons.volume.high + elseif status.value > 40 then + widget.icon.image = beautiful.icons.volume.medium + elseif status.value > 0 then + widget.icon.image = beautiful.icons.volume.low + elseif status.value == 0 then + widget.icon.image = beautiful.icons.volume.off + end + end +end + + + +-- Add various hooks + +wrapper.volume.add_hook(widget.update) +wrapper.volume.commands:watch( + 5, + function() + wrapper.volume.commands:get(widget.update) + end, + widget.widget +) + +-- Update volume widget at start +wrapper.volume.commands:get(widget.update) + +return widget.widget diff --git a/errors.lua b/errors.lua new file mode 100755 index 0000000..5bdd357 --- /dev/null +++ b/errors.lua @@ -0,0 +1,30 @@ +-- Check if awesome encountered an error during startup and fell back to +-- another config (This code will only ever execute for the fallback config) +if awesome.startup_errors then + naughty.notify({ + preset = naughty.config.presets.critical, + title = "Oops, there were errors during startup!", + text = awesome.startup_errors + }) +end + +-- Handle runtime errors after startup +do + local in_error = false + awesome.connect_signal( + "debug::error", + function (err) + -- Make sure we don't go into an endless error loop + if in_error then return end + in_error = true + + naughty.notify({ + preset = naughty.config.presets.critical, + title = "Oops, an error happened!", + text = tostring(err) + }) + + in_error = false + end + ) +end diff --git a/layoutmanager.lua b/layoutmanager.lua new file mode 100644 index 0000000..d1acc72 --- /dev/null +++ b/layoutmanager.lua @@ -0,0 +1,86 @@ +-- Client layout manager + +local LayoutManager = { + layouts = nil, -- Table of groups + -- current state is kept in each tag, as tag.layout. +} + +-- screen.layouts, awful.layouts, and tag.layouts are all ignored. +-- This module replaces the standard layout functions. + + + + +-- Get group from layout +-- We assume that this layout is in LayoutManager.layouts +function LayoutManager:get_group(layout) + for k, v in pairs(self.layouts) do + for l, m in pairs(v) do + if (layout == m) then + return k + end + end + end +end + +function LayoutManager:get_alt(layout) + for k, v in pairs(self.layouts) do + for l, m in pairs(v) do + if (layout == m) then + return l + end + end + end +end + + + +function LayoutManager:default_layout() + return self.layouts[1][1] +end + +-- Change layout group +function LayoutManager:group(step) + local s = awful.screen.focused() + local tag = s.selected_tag -- Multiple selected tags are NOT supported! + local layout = tag.layout + + -- Subtract 1, 'cuz lua doesn't start at 0 + local group = self:get_group(layout) - 1 + + + group = ((group + step) % #self.layouts) + 1 + + awful.layout.set(self.layouts[group][1], tag) +end + +-- Change layout alternate +function LayoutManager:alt(step) + local s = awful.screen.focused() + local tag = s.selected_tag -- Multiple selected tags are NOT supported! + local layout = tag.layout + + -- Subtract 1, 'cuz lua doesn't start at 0 + local alt = self:get_alt(layout) - 1 + local group = self:get_group(layout) + + + alt = ((alt + step) % #self.layouts[group]) + 1 + + awful.layout.set(self.layouts[group][alt], tag) +end + +function LayoutManager:next() + self:group(1) +end +function LayoutManager:prev() + self:group(-1) +end +function LayoutManager:next_alt() + self:alt(1) +end +function LayoutManager:prev_alt() + self:alt(-1) +end + +return LayoutManager diff --git a/rc.lua b/rc.lua new file mode 100755 index 0000000..11d1cda --- /dev/null +++ b/rc.lua @@ -0,0 +1,79 @@ +-- Load libaries. +-- We only need to load these once. +-- These are global variables, all scripts can access them +gears = require("gears") +awful = require("awful") +naughty = require("naughty") +beautiful = require("beautiful") +menubar = require("menubar") +wibox = require("wibox") +configuration_dir = gears.filesystem.get_configuration_dir() +require("awful.autofocus") + + + +-- Quick debug function +debug_message = function(msg) + naughty.notify({title = "Debug message:", text = tostring(msg)}) +end + + +-- These must be loaded in order. +-- Make sure you've created conf.lua! +conf = require("conf") +conf.sound_dir = configuration_dir .. "theme/resources/sounds/" +conf.icon_dir = configuration_dir .. "theme/resources/icons/" + +layoutmanager = require("layoutmanager") +layoutmanager.layouts = conf.layouts + +bin = require("bin") +wrapper = require("wrapper") +wrapper.ibus.set(1) + +beautiful.init(require("theme")) + +desktop = require("desktop") + +-------------- +-- Autostart-- +-------------- +bin.backlight.redshift_reset() + +-- Start compositor (compton tryone fork) +--awful.spawn("killall compton", false) +--awful.spawn("compton --daemon --config " .. configuration_dir .. "/bin/configs/compton.conf", false) + +-- Start ibus (advanced multilanguage input manager) +awful.spawn("ibus-daemon --daemonize --replace --xim", false) + +-- Redshift +bin.backlight.redshift(5600) + + +-- Enable hotkeys help widget for VIM and other apps +-- when client with a matching name is opened: +--require("awful.hotkeys_popup.keys") + + +-- Check for errors +dofile(configuration_dir .. "errors.lua") + + +terminal = conf.terminal +menubar.utils.terminal = terminal + + +------------------ +-- Load Modules -- +------------------ +-- Load key bindings +local binds = require("binds") +root.keys(binds.keys) +root.buttons(binds.buttons) + + +-- Load client methods +awful.rules.rules = require("clients.rules") +dofile(configuration_dir .. "clients/signals.lua") +require("clients.render") diff --git a/theme/bar.lua b/theme/bar.lua new file mode 100755 index 0000000..385028a --- /dev/null +++ b/theme/bar.lua @@ -0,0 +1,36 @@ +local overrides = function(theme) + theme.tasklist_fg_normal = theme.color.bar.active + theme.tasklist_bg_normal = theme.color.bar.color + + theme.tasklist_fg_focus = theme.color.white + theme.tasklist_bg_focus = theme.color.bar.color + + theme.tasklist_fg_urgent = theme.color.white + theme.tasklist_bg_urgent = theme.color.bar.color + + theme.tasklist_fg_occupied = theme.color.white + theme.tasklist_bg_occupied = theme.color.bar.color + + theme.tasklist_fg_empty = theme.color.white .. "00" + theme.tasklist_bg_empty = theme.color.bar.color + + theme.tasklist_fg_volatile = theme.color.white + theme.tasklist_bg_volatile = theme.color.bar.color + + + + theme.prompt_font = "Comfortaa 14" + theme.prompt_fg = theme.color.white + theme.prompt_bg = "#00000000" + theme.prompt_fg_cursor = theme.color.black + theme.prompt_bg_cursor = "#EC5250" + + + -- Tags are managed with a custom script, so awesome + -- tag theming is unnecessary. + -- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile] + + return theme +end + +return overrides diff --git a/theme/clients.lua b/theme/clients.lua new file mode 100755 index 0000000..b3e2f42 --- /dev/null +++ b/theme/clients.lua @@ -0,0 +1,16 @@ +local overrides = function(theme) + theme.rounded_corners = false + theme.corner_radius = theme.dpi(3) + + theme.titlebar_spacing = theme.dpi(5) + theme.titlebar_margins = theme.dpi(5) + + theme.titlebar_bg_normal = theme.color.bar.color --.. "BB" + theme.titlebar_fg_normal = theme.color.bar.active + theme.titlebar_bg_focus = theme.color.bar.color -- .. "BB" + theme.titlebar_fg_focus = theme.color.bar.active + + return theme +end + +return overrides diff --git a/theme/color.lua b/theme/color.lua new file mode 100755 index 0000000..70c241b --- /dev/null +++ b/theme/color.lua @@ -0,0 +1,46 @@ +local color = { + black = "#050505", + lblack = "#1D1F21", + + dgrey = "#555555", + grey = "#D0D0D0", + white = "#F8F8F2", + + red1 = "#FF6600", + red2 = "#FFAA00", + + green1 = "#B4EC85", + green2 = "#A8FF60", + + yellow1 = "#FFFFB6", + yellow2 = "#F1FF52", + + blue1 = "#0087AF", + blue2 = "#87DFFF", + + magenta1 = "#BD99FF", + magenta2 = "#985EFF", + + cyan1 = "#87DFEB", + cyan2 = "#24D1E7", + + transparent = "#00000000", +} + +return gears.table.join({ + + bar = { + color = color.black, + hover_bg = "#FFFFFF10", + spacer = color.dgrey, + + active = color.white, + inactive = color.white .. "AA", + }, + + battery = { + good = "#53E2AE", + warn = "#F1FF52", + danger = "#EE4F84" + } +}, color) diff --git a/theme/init.lua b/theme/init.lua new file mode 100755 index 0000000..4b33ff8 --- /dev/null +++ b/theme/init.lua @@ -0,0 +1,59 @@ +--------------------------- +-- Default awesome theme -- +--------------------------- + + +local bar = require("theme.bar") +local clients = require("theme.clients") +local resources = require("theme.resources") +local notifications = require("theme.notifications") + +local theme = {} +theme.dpi = beautiful.xresources.apply_dpi +theme.color = require("theme.color") + +-- Execute overrides +local theme = resources(theme) -- Must be first! +local theme = bar(theme) +local theme = clients(theme) +local theme = notifications(theme) + +theme.font = "Hack NF 12" + +theme.wallpaper = conf.wallpaper + +theme.bg_normal = theme.color.lblack +theme.bg_focus = theme.color.black +theme.bg_urgent = theme.color.red1 +theme.bg_minimize = "#444444" +theme.bg_systray = theme.color.bar.color + +theme.fg_focus = theme.color.white +theme.fg_normal = theme.color.white .. "AA" +theme.fg_urgent = theme.color.white +theme.fg_minimize = theme.color.white + +theme.useless_gap = theme.dpi(0) +theme.border_width = theme.dpi(0) +theme.border_normal = theme.color.black +theme.border_focus = theme.color.dgrey +theme.border_marked = theme.color.red + + +-- Additional variable sets: +-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color] +-- mouse_finder_[color|timeout|animate_timeout|radius|factor] + +-- Menu theming +theme.menu_bg_focus = theme.color.lblack +theme.menu_bg_normal = theme.color.lblack +theme.menu_fg_focus = theme.color.white +theme.menu_fg_normal = theme.color.white + +theme.menu_border_color = theme.color.lblack +theme.menu_border_width = theme.dpi(0) + +theme.menu_width = theme.dpi(120) +theme.menu_height = theme.dpi(15) + +return theme diff --git a/theme/notifications.lua b/theme/notifications.lua new file mode 100755 index 0000000..307eeb6 --- /dev/null +++ b/theme/notifications.lua @@ -0,0 +1,66 @@ +local overrides = function(theme) + -- Keyhelpmenu theming + theme.hotkeys_description_font = "Comfortaa" + --theme.hotkeys_font = "sans" + + theme.hotkeys_border_width = 0 + -- theme.hotkeys_border_color = + + theme.hotkeys_bg = theme.color.black .. "AA" + theme.hotkeys_fg = theme.color.white + + theme.hotkeys_label_bg = theme.color.blue1 + theme.hotkeys_label_fg = theme.color.white + theme.hotkeys_modifiers_fg = theme.color.green1 .. "AA" + + theme.hotkeys_opacity = 1 + --theme.hotkeys_group_magin = 5 + + -- Notification theming + theme.notification_font = "Comfortaa 8" + theme.notification_bg = theme.color.black + theme.notification_fg = theme.color.white + + --theme.notification_width = + --theme.notification_height = + + theme.notification_margin = 0 + theme.notification_padding = theme.dpi(8) + theme.notification_border_color = theme.color.white + theme.notification_border_width = 2 + theme.notification_opacity = 1 + theme.notification_corner_radius = theme.dpi(25) + + -- Generate notification shape + theme.notification_shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, theme.notification_corner_radius, theme.notification_corner_radius) + end + + + -- Notification presets + theme.notification_templates = { + bottom_right = { + icon_size = theme.dpi(25), + timeout = 5, + max_height = theme.dpi(80), + max_width = theme.dpi(200), + position = "bottom_right", + } + } + + -- Default notification + naughty.config.defaults = { + timeout = 5, + text = 5, + ontop = true, + margin = theme.dpi(5), + border_width = theme.dpi(1), + position = "top_middle" + + --screen int Defaults to awful.screen.focused. (optional) + } + + return theme +end + +return overrides diff --git a/theme/resources/icons.lua b/theme/resources/icons.lua new file mode 100755 index 0000000..8d63497 --- /dev/null +++ b/theme/resources/icons.lua @@ -0,0 +1,176 @@ +local brightnessdir = conf.icon_dir .. "brightness/clockwise/" +local layoutdir = conf.icon_dir .. "layout/" +local batterydir = conf.icon_dir .. "battery/" +local volumedir = conf.icon_dir .. "volume/" +local tagdir = conf.icon_dir .. "tags/" +local titlebardir = conf.icon_dir .. "titlebar/" + +return { + submenu = conf.icon_dir .. "submenu.svg", + launcher = conf.icon_dir .. "arch.svg", + + music = { + grey = { + play = conf.icon_dir .. "music/play-grey.svg", + pause = conf.icon_dir .. "music/pause-grey.svg", + stop = conf.icon_dir .. "music/stop-grey.svg" + }, + + blue = { + play = conf.icon_dir .. "music/play-blue.svg", + pause = conf.icon_dir .. "music/pause-blue.svg", + stop = conf.icon_dir .. "music/stop-blue.svg" + } + }, + + -- Layout icons + layout = { + cornerne = layoutdir .. "cornerne.svg", + cornernw = layoutdir .. "cornernw.svg", + cornerse = layoutdir .. "cornerse.svg", + cornersw = layoutdir .. "cornersw.svg", + dwindle = layoutdir .. "dwindle.svg", + fairh = layoutdir .. "fairh.svg", + fairv = layoutdir .. "fairv.svg", + floating = layoutdir .. "floating.svg", + fullscreen = layoutdir .. "fullscreen.svg", + magnifier = layoutdir .. "magnifier.svg", + max = layoutdir .. "max.svg", + spiral = layoutdir .. "spiral.svg", + tile = layoutdir .. "tile.svg", + tilebottom = layoutdir .. "tilebottom.svg", + tileleft = layoutdir .. "tileleft.svg", + tiletop = layoutdir .. "tiletop.svg" + }, + + -- Battery icons + battery = { + missing = batterydir .. "missing.svg", + + charging = { + full = batterydir .. "full-charging.svg", + good = batterydir .. "good-charging.svg", + low = batterydir .. "low-charging.svg", + caution = batterydir .. "caution-charging.svg", + empty = batterydir .. "empty-charging.svg" + }, + + full = batterydir .. "full.svg", + good = batterydir .. "good.svg", + low = batterydir .. "low.svg", + caution = batterydir .. "caution.svg", + empty = batterydir .. "empty.svg" + }, + + -- Volume indicator + volume = { + high = volumedir .. "high.svg", + medium = volumedir .. "medium.svg", + low = volumedir .. "low.svg", + off = volumedir .. "off.svg", + mute = volumedir .. "mute-red.svg", + error = volumedir .. "error.svg" + }, + + -- Brightness icons + brightness = { + a = brightnessdir .. "brightness-0.svg", + b = brightnessdir .. "brightness-1.svg", + c = brightnessdir .. "brightness-2.svg", + d = brightnessdir .. "brightness-3.svg", + e = brightnessdir .. "brightness-4.svg", + f = brightnessdir .. "brightness-5.svg", + g = brightnessdir .. "brightness-6.svg", + h = brightnessdir .. "brightness-7.svg", + i = brightnessdir .. "brightness-8.svg" + }, + + -- RAID status + raid = { + healthy = { + normal = conf.icon_dir .. "raid/healthy.svg", + recover = conf.icon_dir .. "raid/healthy-recover.svg" + }, + degraded = { + normal = conf.icon_dir .. "raid/degraded.svg", + recover = conf.icon_dir .. "raid/degraded-recover.svg" + } + }, + + -- Icons shown on window bars + titlebar = { + close = { + focus_hover = titlebardir .. "hover/close.svg", + normal_hover = titlebardir .. "hover/close.svg", + focus = titlebardir .. "regular/close.svg", + normal = titlebardir .. "regular/close.svg" + }, + + floating = { + inactive = { + focus_hover = titlebardir .. "hover/float.svg", + normal_hover = titlebardir .. "hover/float.svg", + focus = titlebardir .. "regular/float.svg", + normal = titlebardir .. "regular/float.svg" + }, + active = { + focus_hover = titlebardir .. "regular/float.svg", + normal_hover = titlebardir .. "regular/float.svg", + focus = titlebardir .. "hover/float.svg", + normal = titlebardir .. "hover/float.svg" + } + }, + + maximize = { + inactive = { + focus_hover = titlebardir .. "hover/maximize.svg", + normal_hover = titlebardir .. "hover/maximize.svg", + focus = titlebardir .. "regular/maximize.svg", + normal = titlebardir .. "regular/maximize.svg" + }, + active = { + focus_hover = titlebardir .. "regular/maximize.svg", + normal_hover = titlebardir .. "regular/maximize.svg", + focus = titlebardir .. "hover/maximize.svg", + normal = titlebardir .. "hover/maximize.svg" + } + }, + + minimize = { + focus_hover = titlebardir .. "hover/minimize.svg", + normal_hover = titlebardir .. "hover/minimize.svg", + focus = titlebardir .. "regular/minimize.svg", + normal = titlebardir .. "regular/minimize.svg" + }, + + ontop = { + inactive = { + focus_hover = titlebardir .. "hover/ontop.svg", + normal_hover = titlebardir .. "hover/ontop.svg", + focus = titlebardir .. "regular/ontop.svg", + normal = titlebardir .. "regular/ontop.svg" + }, + active = { + focus_hover = titlebardir .. "regular/ontop.svg", + normal_hover = titlebardir .. "regular/ontop.svg", + focus = titlebardir .. "hover/ontop.svg", + normal = titlebardir .. "hover/ontop.svg" + } + }, + + sticky = { + inactive = { + focus_hover = titlebardir .. "hover/stick.svg", + normal_hover = titlebardir .. "hover/stick.svg", + focus = titlebardir .. "regular/stick.svg", + normal = titlebardir .. "regular/stick.svg" + }, + active = { + focus_hover = titlebardir .. "regular/stick.svg", + normal_hover = titlebardir .. "regular/stick.svg", + focus = titlebardir .. "hover/stick.svg", + normal = titlebardir .. "hover/stick.svg" + } + } + } +} diff --git a/theme/resources/icons/arch.svg b/theme/resources/icons/arch.svg new file mode 100755 index 0000000..e192c0c --- /dev/null +++ b/theme/resources/icons/arch.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/theme/resources/icons/battery/caution-charging.svg b/theme/resources/icons/battery/caution-charging.svg new file mode 100755 index 0000000..8e7e534 --- /dev/null +++ b/theme/resources/icons/battery/caution-charging.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/battery/caution.svg b/theme/resources/icons/battery/caution.svg new file mode 100755 index 0000000..0134075 --- /dev/null +++ b/theme/resources/icons/battery/caution.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/battery/empty-charging.svg b/theme/resources/icons/battery/empty-charging.svg new file mode 100755 index 0000000..2120862 --- /dev/null +++ b/theme/resources/icons/battery/empty-charging.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/battery/empty.svg b/theme/resources/icons/battery/empty.svg new file mode 100755 index 0000000..9492e95 --- /dev/null +++ b/theme/resources/icons/battery/empty.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/battery/full-charging.svg b/theme/resources/icons/battery/full-charging.svg new file mode 100755 index 0000000..8107a11 --- /dev/null +++ b/theme/resources/icons/battery/full-charging.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/battery/full.svg b/theme/resources/icons/battery/full.svg new file mode 100755 index 0000000..f95eec6 --- /dev/null +++ b/theme/resources/icons/battery/full.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/battery/good-charging.svg b/theme/resources/icons/battery/good-charging.svg new file mode 100755 index 0000000..7a50a7c --- /dev/null +++ b/theme/resources/icons/battery/good-charging.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/battery/good.svg b/theme/resources/icons/battery/good.svg new file mode 100755 index 0000000..59b6f18 --- /dev/null +++ b/theme/resources/icons/battery/good.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/battery/low-charging.svg b/theme/resources/icons/battery/low-charging.svg new file mode 100755 index 0000000..e3a9854 --- /dev/null +++ b/theme/resources/icons/battery/low-charging.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/battery/low.svg b/theme/resources/icons/battery/low.svg new file mode 100755 index 0000000..bfdd470 --- /dev/null +++ b/theme/resources/icons/battery/low.svg @@ -0,0 +1,90 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/battery/missing.svg b/theme/resources/icons/battery/missing.svg new file mode 100755 index 0000000..7109494 --- /dev/null +++ b/theme/resources/icons/battery/missing.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-0.svg b/theme/resources/icons/brightness/clockwise/brightness-0.svg new file mode 100755 index 0000000..9155794 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-0.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-1.svg b/theme/resources/icons/brightness/clockwise/brightness-1.svg new file mode 100755 index 0000000..e7d1ed9 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-1.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-2.svg b/theme/resources/icons/brightness/clockwise/brightness-2.svg new file mode 100755 index 0000000..a34915c --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-2.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-3.svg b/theme/resources/icons/brightness/clockwise/brightness-3.svg new file mode 100755 index 0000000..091fbf3 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-3.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-4.svg b/theme/resources/icons/brightness/clockwise/brightness-4.svg new file mode 100755 index 0000000..4521273 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-4.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-5.svg b/theme/resources/icons/brightness/clockwise/brightness-5.svg new file mode 100755 index 0000000..f17315e --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-5.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-6.svg b/theme/resources/icons/brightness/clockwise/brightness-6.svg new file mode 100755 index 0000000..bbe0801 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-6.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-7.svg b/theme/resources/icons/brightness/clockwise/brightness-7.svg new file mode 100755 index 0000000..84fcf61 --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-7.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/clockwise/brightness-8.svg b/theme/resources/icons/brightness/clockwise/brightness-8.svg new file mode 100755 index 0000000..7e786ab --- /dev/null +++ b/theme/resources/icons/brightness/clockwise/brightness-8.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-0.svg b/theme/resources/icons/brightness/counterclockwise/brightness-0.svg new file mode 100755 index 0000000..9155794 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-0.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-1.svg b/theme/resources/icons/brightness/counterclockwise/brightness-1.svg new file mode 100755 index 0000000..d2c824f --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-1.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-2.svg b/theme/resources/icons/brightness/counterclockwise/brightness-2.svg new file mode 100755 index 0000000..5b4fd86 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-2.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-3.svg b/theme/resources/icons/brightness/counterclockwise/brightness-3.svg new file mode 100755 index 0000000..1acddce --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-3.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-4.svg b/theme/resources/icons/brightness/counterclockwise/brightness-4.svg new file mode 100755 index 0000000..a0de5e4 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-4.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-5.svg b/theme/resources/icons/brightness/counterclockwise/brightness-5.svg new file mode 100755 index 0000000..f319148 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-5.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-6.svg b/theme/resources/icons/brightness/counterclockwise/brightness-6.svg new file mode 100755 index 0000000..53371d7 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-6.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-7.svg b/theme/resources/icons/brightness/counterclockwise/brightness-7.svg new file mode 100755 index 0000000..5cf456e --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-7.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/brightness/counterclockwise/brightness-8.svg b/theme/resources/icons/brightness/counterclockwise/brightness-8.svg new file mode 100755 index 0000000..eb9aa53 --- /dev/null +++ b/theme/resources/icons/brightness/counterclockwise/brightness-8.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/cornerne.svg b/theme/resources/icons/layout/cornerne.svg new file mode 100755 index 0000000..a765b3e --- /dev/null +++ b/theme/resources/icons/layout/cornerne.svg @@ -0,0 +1,105 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/cornernw.svg b/theme/resources/icons/layout/cornernw.svg new file mode 100755 index 0000000..a99ad55 --- /dev/null +++ b/theme/resources/icons/layout/cornernw.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/cornerse.svg b/theme/resources/icons/layout/cornerse.svg new file mode 100755 index 0000000..18dea33 --- /dev/null +++ b/theme/resources/icons/layout/cornerse.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/cornersw.svg b/theme/resources/icons/layout/cornersw.svg new file mode 100755 index 0000000..825bf2f --- /dev/null +++ b/theme/resources/icons/layout/cornersw.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/dwindle.svg b/theme/resources/icons/layout/dwindle.svg new file mode 100755 index 0000000..aa008b0 --- /dev/null +++ b/theme/resources/icons/layout/dwindle.svg @@ -0,0 +1,97 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/fairh.svg b/theme/resources/icons/layout/fairh.svg new file mode 100755 index 0000000..641f480 --- /dev/null +++ b/theme/resources/icons/layout/fairh.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/fairv.svg b/theme/resources/icons/layout/fairv.svg new file mode 100755 index 0000000..fe79c25 --- /dev/null +++ b/theme/resources/icons/layout/fairv.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/floating.svg b/theme/resources/icons/layout/floating.svg new file mode 100755 index 0000000..c5714b0 --- /dev/null +++ b/theme/resources/icons/layout/floating.svg @@ -0,0 +1,72 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/theme/resources/icons/layout/fullscreen.svg b/theme/resources/icons/layout/fullscreen.svg new file mode 100755 index 0000000..781ea35 --- /dev/null +++ b/theme/resources/icons/layout/fullscreen.svg @@ -0,0 +1,65 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/layout/magnifier.svg b/theme/resources/icons/layout/magnifier.svg new file mode 100755 index 0000000..33292ca --- /dev/null +++ b/theme/resources/icons/layout/magnifier.svg @@ -0,0 +1,89 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/max.svg b/theme/resources/icons/layout/max.svg new file mode 100755 index 0000000..bafc109 --- /dev/null +++ b/theme/resources/icons/layout/max.svg @@ -0,0 +1,65 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/theme/resources/icons/layout/spiral.svg b/theme/resources/icons/layout/spiral.svg new file mode 100755 index 0000000..bf3c996 --- /dev/null +++ b/theme/resources/icons/layout/spiral.svg @@ -0,0 +1,101 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/tile.svg b/theme/resources/icons/layout/tile.svg new file mode 100755 index 0000000..6dfe407 --- /dev/null +++ b/theme/resources/icons/layout/tile.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/tilebottom.svg b/theme/resources/icons/layout/tilebottom.svg new file mode 100755 index 0000000..0bb3102 --- /dev/null +++ b/theme/resources/icons/layout/tilebottom.svg @@ -0,0 +1,116 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/tileleft.svg b/theme/resources/icons/layout/tileleft.svg new file mode 100755 index 0000000..3965b51 --- /dev/null +++ b/theme/resources/icons/layout/tileleft.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/layout/tiletop.svg b/theme/resources/icons/layout/tiletop.svg new file mode 100755 index 0000000..1b19b14 --- /dev/null +++ b/theme/resources/icons/layout/tiletop.svg @@ -0,0 +1,117 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/music/pause-blue.svg b/theme/resources/icons/music/pause-blue.svg new file mode 100755 index 0000000..659e284 --- /dev/null +++ b/theme/resources/icons/music/pause-blue.svg @@ -0,0 +1,79 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/theme/resources/icons/music/pause-grey.svg b/theme/resources/icons/music/pause-grey.svg new file mode 100755 index 0000000..83e5ce2 --- /dev/null +++ b/theme/resources/icons/music/pause-grey.svg @@ -0,0 +1,80 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/theme/resources/icons/music/play-blue.svg b/theme/resources/icons/music/play-blue.svg new file mode 100755 index 0000000..a401065 --- /dev/null +++ b/theme/resources/icons/music/play-blue.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/theme/resources/icons/music/play-grey.svg b/theme/resources/icons/music/play-grey.svg new file mode 100755 index 0000000..aaf720e --- /dev/null +++ b/theme/resources/icons/music/play-grey.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/theme/resources/icons/music/stop-blue.svg b/theme/resources/icons/music/stop-blue.svg new file mode 100755 index 0000000..1e09626 --- /dev/null +++ b/theme/resources/icons/music/stop-blue.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/theme/resources/icons/music/stop-grey.svg b/theme/resources/icons/music/stop-grey.svg new file mode 100755 index 0000000..9048dcd --- /dev/null +++ b/theme/resources/icons/music/stop-grey.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/theme/resources/icons/raid/degraded-recover.svg b/theme/resources/icons/raid/degraded-recover.svg new file mode 100644 index 0000000..7c4a6f4 --- /dev/null +++ b/theme/resources/icons/raid/degraded-recover.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/raid/degraded.svg b/theme/resources/icons/raid/degraded.svg new file mode 100644 index 0000000..9dfdffe --- /dev/null +++ b/theme/resources/icons/raid/degraded.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/raid/healthy-recover.svg b/theme/resources/icons/raid/healthy-recover.svg new file mode 100644 index 0000000..7a1092c --- /dev/null +++ b/theme/resources/icons/raid/healthy-recover.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/raid/healthy.svg b/theme/resources/icons/raid/healthy.svg new file mode 100755 index 0000000..12798b4 --- /dev/null +++ b/theme/resources/icons/raid/healthy.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/titlebar/hover/close.svg b/theme/resources/icons/titlebar/hover/close.svg new file mode 100755 index 0000000..3b5bb8f --- /dev/null +++ b/theme/resources/icons/titlebar/hover/close.svg @@ -0,0 +1,37 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/hover/float.svg b/theme/resources/icons/titlebar/hover/float.svg new file mode 100755 index 0000000..cd4fba4 --- /dev/null +++ b/theme/resources/icons/titlebar/hover/float.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/hover/maximize.svg b/theme/resources/icons/titlebar/hover/maximize.svg new file mode 100755 index 0000000..5a95783 --- /dev/null +++ b/theme/resources/icons/titlebar/hover/maximize.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/hover/minimize.svg b/theme/resources/icons/titlebar/hover/minimize.svg new file mode 100755 index 0000000..7a5619d --- /dev/null +++ b/theme/resources/icons/titlebar/hover/minimize.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/hover/ontop.svg b/theme/resources/icons/titlebar/hover/ontop.svg new file mode 100755 index 0000000..3082e95 --- /dev/null +++ b/theme/resources/icons/titlebar/hover/ontop.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/hover/stick.svg b/theme/resources/icons/titlebar/hover/stick.svg new file mode 100755 index 0000000..bc608fa --- /dev/null +++ b/theme/resources/icons/titlebar/hover/stick.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/close.svg b/theme/resources/icons/titlebar/regular/close.svg new file mode 100755 index 0000000..d81c096 --- /dev/null +++ b/theme/resources/icons/titlebar/regular/close.svg @@ -0,0 +1,37 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/float.svg b/theme/resources/icons/titlebar/regular/float.svg new file mode 100755 index 0000000..83f4be3 --- /dev/null +++ b/theme/resources/icons/titlebar/regular/float.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/maximize.svg b/theme/resources/icons/titlebar/regular/maximize.svg new file mode 100755 index 0000000..c42e6a0 --- /dev/null +++ b/theme/resources/icons/titlebar/regular/maximize.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/minimize.svg b/theme/resources/icons/titlebar/regular/minimize.svg new file mode 100755 index 0000000..83ce7c9 --- /dev/null +++ b/theme/resources/icons/titlebar/regular/minimize.svg @@ -0,0 +1,39 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/ontop.svg b/theme/resources/icons/titlebar/regular/ontop.svg new file mode 100755 index 0000000..3550c3b --- /dev/null +++ b/theme/resources/icons/titlebar/regular/ontop.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/titlebar/regular/stick.svg b/theme/resources/icons/titlebar/regular/stick.svg new file mode 100755 index 0000000..42fbaa8 --- /dev/null +++ b/theme/resources/icons/titlebar/regular/stick.svg @@ -0,0 +1,36 @@ + + + + + + diff --git a/theme/resources/icons/volume/error.svg b/theme/resources/icons/volume/error.svg new file mode 100755 index 0000000..5a72be7 --- /dev/null +++ b/theme/resources/icons/volume/error.svg @@ -0,0 +1,259 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/high.svg b/theme/resources/icons/volume/high.svg new file mode 100755 index 0000000..5b965cc --- /dev/null +++ b/theme/resources/icons/volume/high.svg @@ -0,0 +1,253 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/low.svg b/theme/resources/icons/volume/low.svg new file mode 100755 index 0000000..5b29bd0 --- /dev/null +++ b/theme/resources/icons/volume/low.svg @@ -0,0 +1,253 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/medium.svg b/theme/resources/icons/volume/medium.svg new file mode 100755 index 0000000..0894584 --- /dev/null +++ b/theme/resources/icons/volume/medium.svg @@ -0,0 +1,253 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/mute-red.svg b/theme/resources/icons/volume/mute-red.svg new file mode 100755 index 0000000..bf1ec5c --- /dev/null +++ b/theme/resources/icons/volume/mute-red.svg @@ -0,0 +1,257 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/mute.svg b/theme/resources/icons/volume/mute.svg new file mode 100755 index 0000000..16b048e --- /dev/null +++ b/theme/resources/icons/volume/mute.svg @@ -0,0 +1,257 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/icons/volume/off.svg b/theme/resources/icons/volume/off.svg new file mode 100755 index 0000000..df5f79f --- /dev/null +++ b/theme/resources/icons/volume/off.svg @@ -0,0 +1,253 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/theme/resources/init.lua b/theme/resources/init.lua new file mode 100755 index 0000000..7021d7b --- /dev/null +++ b/theme/resources/init.lua @@ -0,0 +1,86 @@ +local sounds = require("theme.resources.sounds") +local icons = require("theme.resources.icons") + +local overrides = function(theme) + theme.sounds = sounds + theme.icons = icons + + -- Generate Awesome icon + --theme.awesome_icon = beautiful.theme_assets.awesome_icon( + -- theme.menu_height, + -- theme.color.blue1, + -- theme.color.white + --) + + -- Icon variables + + theme.menu_submenu_icon = icons.submenu + + theme.layout_cornerne = icons.layout.cornerne + theme.layout_cornernw = icons.layout.cornernw + theme.layout_cornerse = icons.layout.cornerse + theme.layout_cornersw = icons.layout.cornersw + theme.layout_dwindle = icons.layout.dwindle + theme.layout_fairh = icons.layout.fairh + theme.layout_fairv = icons.layout.fairv + theme.layout_floating = icons.layout.floating + theme.layout_fullscreen = icons.layout.fullscreen + theme.layout_magnifier = icons.layout.magnifier + theme.layout_max = icons.layout.max + theme.layout_spiral = icons.layout.spiral + theme.layout_tile = icons.layout.tile + theme.layout_tilebottom = icons.layout.tilebottom + theme.layout_tileleft = icons.layout.tileleft + theme.layout_tiletop = icons.layout.tiletop + + + theme.titlebar_close_button_focus_hover = icons.titlebar.close.focus_hover + theme.titlebar_close_button_focus = icons.titlebar.close.focus + theme.titlebar_close_button_normal_hover = icons.titlebar.close.normal_hover + theme.titlebar_close_button_normal = icons.titlebar.close.normal + + theme.titlebar_floating_button_focus_inactive_hover = icons.titlebar.floating.inactive.focus_hover + theme.titlebar_floating_button_focus_inactive = icons.titlebar.floating.inactive.focus + theme.titlebar_floating_button_normal_inactive_hover = icons.titlebar.floating.inactive.normal_hover + theme.titlebar_floating_button_normal_inactive = icons.titlebar.floating.inactive.normal + theme.titlebar_floating_button_focus_active_hover = icons.titlebar.floating.active.focus_hover + theme.titlebar_floating_button_focus_active = icons.titlebar.floating.active.focus + theme.titlebar_floating_button_normal_active_hover = icons.titlebar.floating.active.normal_hover + theme.titlebar_floating_button_normal_active = icons.titlebar.floating.active.normal + + theme.titlebar_maximized_button_focus_inactive_hover = icons.titlebar.maximize.inactive.focus_hover + theme.titlebar_maximized_button_focus_inactive = icons.titlebar.maximize.inactive.focus + theme.titlebar_maximized_button_normal_inactive_hover = icons.titlebar.maximize.inactive.normal_hover + theme.titlebar_maximized_button_normal_inactive = icons.titlebar.maximize.inactive.normal + theme.titlebar_maximized_button_focus_active_hover = icons.titlebar.maximize.active.focus_hover + theme.titlebar_maximized_button_focus_active = icons.titlebar.maximize.active.focus + theme.titlebar_maximized_button_normal_active_hover = icons.titlebar.maximize.active.normal_hover + theme.titlebar_maximized_button_normal_active = icons.titlebar.maximize.active.normal + + theme.titlebar_minimize_button_focus_hover = icons.titlebar.minimize.focus_hover + theme.titlebar_minimize_button_focus = icons.titlebar.minimize.focus + theme.titlebar_minimize_button_normal_hover = icons.titlebar.minimize.normal_hover + theme.titlebar_minimize_button_normal = icons.titlebar.minimize.normal + + theme.titlebar_ontop_button_focus_inactive_hover = icons.titlebar.ontop.inactive.focus_hover + theme.titlebar_ontop_button_focus_inactive = icons.titlebar.ontop.inactive.focus + theme.titlebar_ontop_button_normal_inactive_hover = icons.titlebar.ontop.inactive.normal_hover + theme.titlebar_ontop_button_normal_inactive = icons.titlebar.ontop.inactive.normal + theme.titlebar_ontop_button_focus_active_hover = icons.titlebar.ontop.active.focus_hover + theme.titlebar_ontop_button_focus_active = icons.titlebar.ontop.active.focus + theme.titlebar_ontop_button_normal_active_hover = icons.titlebar.ontop.active.normal_hover + theme.titlebar_ontop_button_normal_active = icons.titlebar.ontop.active.normal + + theme.titlebar_sticky_button_focus_inactive_hover = icons.titlebar.sticky.inactive.focus_hover + theme.titlebar_sticky_button_focus_inactive = icons.titlebar.sticky.inactive.focus + theme.titlebar_sticky_button_normal_inactive_hover = icons.titlebar.sticky.inactive.normal_hover + theme.titlebar_sticky_button_normal_inactive = icons.titlebar.sticky.inactive.normal + theme.titlebar_sticky_button_focus_active_hover = icons.titlebar.sticky.active.focus_hover + theme.titlebar_sticky_button_focus_active = icons.titlebar.sticky.active.focus + theme.titlebar_sticky_button_normal_active_hover = icons.titlebar.sticky.active.normal_hover + theme.titlebar_sticky_button_normal_active = icons.titlebar.sticky.active.normal + + return theme +end + +return overrides diff --git a/theme/resources/sounds.lua b/theme/resources/sounds.lua new file mode 100755 index 0000000..ca8eb5a --- /dev/null +++ b/theme/resources/sounds.lua @@ -0,0 +1,4 @@ +return { + volume_up = conf.sound_dir .. "volumeup-click.mp3", + volume_down = conf.sound_dir .. "volumedown-click.mp3" +} diff --git a/theme/resources/sounds/accept.ogg b/theme/resources/sounds/accept.ogg new file mode 100755 index 0000000000000000000000000000000000000000..8cbd20436d931d23348839c021a33d6fdea71352 GIT binary patch literal 21662 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 Qn*eS#;5g?);RAr{1`xbWZ2$lO literal 0 HcmV?d00001 diff --git a/theme/resources/sounds/hover.ogg b/theme/resources/sounds/hover.ogg new file mode 100755 index 0000000000000000000000000000000000000000..cbd695d4423fdae1287436f06113a3b8bfaae222 GIT binary patch literal 4826 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 bQckZ{X*10@%_g6_Dc%|LLR|fzT={{X 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 literal 0 HcmV?d00001 diff --git a/theme/resources/sounds/type.ogg b/theme/resources/sounds/type.ogg new file mode 100755 index 0000000000000000000000000000000000000000..8d77a74e4da95caa05af4ef3e56601e8b7434489 GIT binary patch literal 4797 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 B*P8$U literal 0 HcmV?d00001 diff --git a/theme/resources/sounds/volumeup-click.mp3 b/theme/resources/sounds/volumeup-click.mp3 new file mode 100755 index 0000000000000000000000000000000000000000..490df8615668199d9edbd5b943a1ce426fb08bbf GIT binary patch literal 1917 zcmeZtF=l1}0ojml8W^zbgtgWR#BliC~pVBUu{^8~=gN4pM?8a;P z>>gx2m!92p|CVLZkxJcc=>?ON*YAJ%=7#s%f0oBNQu&^JeG+o)|NWMe%h-OqR9#zq zxTr{JlivL8+pl?S582bQ{-{@#RoC`RTVR`Q`7WfJWmVp!6dm6DC2Lb}wXX{fTWu}3Xx{R3S!-*GPCpem zw$l2opQ-s&^@7U>RUM_(T2A=`!{Mv_8pHqfUu%2Sn3xzi7}yvY7kcgsk@D>9nIvKH zuz_nvgJy4!l4nDsSnXMl%hm>_8z!@`8ki@G@eA-s6uLU4CH?FW?eca$ve2u6aj8V+ z3_VtfhN-^}xVBkv)MU(Xkt+p`MI}`rYXT`P!N!q>B4GopFn0Yirj{J#|c8$FG zYU8Y}@v&YjO239le$LYj+U$~`Y*H^ZYgU8UAHT(y`OQD*M)YQuxG9T1GoAl>%6aX& z8=9#_mEXPi_19!B*}ioxN7Loq2CaE6S&_jBwGXaF?UTQE^{$?1X62XbpQhU1to#1w z|Nmb%CIL$u9yTWC|BpU>IP^p0z$?M{{vel+_x~I@Ixl8I=l)=c=$}%z?tfi%{{Pjr k@KP*v6b!Nu`2Snr$m0gqie!lyVhzAJHEC{OV4;B<0dnNRm;e9( literal 0 HcmV?d00001 diff --git a/wrapper/backlight.lua b/wrapper/backlight.lua new file mode 100755 index 0000000..0b9c85f --- /dev/null +++ b/wrapper/backlight.lua @@ -0,0 +1,36 @@ +local backlight = {} + + +backlight.hooks = {} +backlight.add_hook = function(callback) + backlight.hooks[#backlight.hooks + 1] = callback +end + +backlight.exec_hooks = function() + backlight.read(function(status) + for i=1, #backlight.hooks do + backlight.hooks[i](status) + end + end) +end + +backlight.read = function(callback) + bin.backlight.get( + function(stdout, stderr, exitreason, exitcode) + callback(tonumber(stdout)) + end + ) +end + + +backlight.up = function() + bin.backlight.up() + backlight.exec_hooks() +end + +backlight.down = function() + bin.backlight.down() + backlight.exec_hooks() +end + +return backlight diff --git a/wrapper/ibus.lua b/wrapper/ibus.lua new file mode 100644 index 0000000..b0c3051 --- /dev/null +++ b/wrapper/ibus.lua @@ -0,0 +1,102 @@ +local ibus = {} + + +ibus.current_engine = "" +ibus.current_engine_index = nil + +ibus.ibus_indicator_text = wibox.widget.textbox("??") +ibus.ibus_indicator_text.valign = "center" +ibus.ibus_indicator_text.align = "center" +ibus.ibus_indicator_text.font = "Hack NF 14" + +ibus.xkb_indicator_text = wibox.widget.textbox("??") +ibus.xkb_indicator_text.valign = "center" +ibus.xkb_indicator_text.align = "center" +ibus.xkb_indicator_text.font = "Hack NF 10" + + +ibus.get = function(callback) + awful.spawn.easy_async("ibus engine", function(stdout, stderr, exitreason, exitcode) + -- Get current ibus engine, remove newlines from output. + ibus.current_engine = string.gsub(stdout, "\n", "") + ibus.current_engine_index = nil + + -- Find the current engine's index in conf.ibus_language_list. + -- If it is not there, ibus.current_engine_index will be nil. + for k, v in pairs(conf.ibus_language_list) do + if (v["ibus_engine"] == ibus.current_engine) then + ibus.current_engine_index = k + end + end + + if callback then + callback() + end + end) +end + + +ibus.update_indicator = function() + -- Update indicators + awful.spawn.easy_async("setxkbmap -query" , function(stdout, stderr, exitreason, exitcode) + ibus.ibus_indicator_text.markup = conf.ibus_language_list[ibus.current_engine_index]["indicator_code"] + ibus.xkb_indicator_text.markup = string.match(stdout, "layout:%s+(%w+)") + end) +end + +ibus.set = function(language_index, callback) + -- engine is an index of the language list above + + engine = conf.ibus_language_list[language_index]["ibus_engine"] + + -- Get required engine, if one is given + local requires_engine + for k, v in pairs(conf.ibus_language_list) do + if (v["ibus_engine"] == engine) then + requires_engine = v["requires_engine"] + end + end + + -- If a required xkb engine is given, but it is not active, switch to it before switching to the target + if (requires_engine ~= ibus.current_engine) and (requires_engine ~= nil) then + awful.spawn.easy_async("ibus engine " .. requires_engine, function(stdout, stderr, exitreason, exitcode) + awful.spawn.easy_async("ibus engine " .. engine, function(stdout, stderr, exitreason, exitcode) + ibus.update_indicator() + ibus.get(callback) + end) + end) + else + awful.spawn.easy_async("ibus engine " .. engine, function(stdout, stderr, exitreason, exitcode) + ibus.update_indicator() + ibus.get(callback) + end) + end +end + + +ibus.next = function(callback) + if (ibus.current_engine_index == nil) or (ibus.current_engine_index == #conf.ibus_language_list) then + ibus.current_engine_index = 1 + else + ibus.current_engine_index = ibus.current_engine_index + 1 + end + ibus.set(ibus.current_engine_index, callback) +end + +-- Update the language indicator +ibus.update_timer = gears.timer { + timeout = 2, + call_now = false, + autostart = true, + single_shot = false, + + callback = function() + ibus.get( + function() + ibus.update_indicator() + end + ) + end +} + +return ibus diff --git a/wrapper/init.lua b/wrapper/init.lua new file mode 100755 index 0000000..f1b56ef --- /dev/null +++ b/wrapper/init.lua @@ -0,0 +1,7 @@ +return { + backlight = require("wrapper.backlight"), + volume = require("wrapper.volume"), + sound = require("wrapper.sound"), + ibus = require("wrapper.ibus"), + mdadm = require("wrapper.mdadm") +} diff --git a/wrapper/mdadm.lua b/wrapper/mdadm.lua new file mode 100644 index 0000000..43eced4 --- /dev/null +++ b/wrapper/mdadm.lua @@ -0,0 +1,38 @@ +local mdadm = {} + +mdadm.get = function(callback) + awful.spawn.easy_async("awk '/^md/ {printf \"%s: \", $1}; /blocks/ {print $NF}' /proc/mdstat", + function(stdout, stderr, exitreason, exitcode) + status = string.match(stdout, "%[(.*)%]") + callback(status) + + end) +end + + + +mdadm.indicator_text = wibox.widget.textbox("??") +mdadm.indicator_text.valign = "center" +mdadm.indicator_text.align = "center" +mdadm.indicator_text.font = "Hack NF 10" + + +mdadm.update_indicator = function(status) + mdadm.indicator_text.markup = status +end + +-- Update the indicator +mdadm.update_timer = gears.timer { + timeout = 2, + call_now = false, + autostart = true, + single_shot = false, + + callback = function() + mdadm.get( + mdadm.update_indicator + ) + end +} + +return mdadm diff --git a/wrapper/sound.lua b/wrapper/sound.lua new file mode 100644 index 0000000..ceb4a7c --- /dev/null +++ b/wrapper/sound.lua @@ -0,0 +1,22 @@ +local sound = {} + +sound.counter = 0 + +sound.play = function(sound_key) + if (beautiful.sounds[sound_key] == nil) then + naughty.notify({ + title = "Sound play error:", + text = "There is no sound with key " .. sound_key + }) + else + if (sound.counter > 5) then + return + end + sound.counter = sound.counter + 1 + awful.spawn.easy_async("play -q \"" .. beautiful.sounds[sound_key] .. "\"", function() + sound.counter = sound.counter - 1 + end) + end +end + +return sound diff --git a/wrapper/volume.lua b/wrapper/volume.lua new file mode 100755 index 0000000..7802165 --- /dev/null +++ b/wrapper/volume.lua @@ -0,0 +1,146 @@ +local volume = {} +volume.commands = {} + + +-- Create pamixer option string +volume.pamixer_options = "" +if (conf.pamixer_sink ~= "") then + volume.pamixer_options = volume.pamixer_options .. " --sink " .. conf.pamixer_sink +end + +function volume.commands:up() + awful.spawn("pamixer --increase 5" .. volume.pamixer_options, false) +end + +function volume.commands:down() + awful.spawn("pamixer --decrease 5" .. volume.pamixer_options, false) +end + +function volume.commands:set(value) + awful.spawn("pamixer --set_volume" .. tostring(value) .. " " .. volume.pamixer_options, false) +end + +function volume.commands:mute() + awful.spawn("pamixer --mute" .. volume.pamixer_options, false) +end + +function volume.commands:unmute() + awful.spawn("pamixer --unmute" .. volume.pamixer_options, false) +end + +function volume.commands:get(callback) + local muted + local value + + awful.spawn.easy_async("pamixer --get-mute --get-volume" .. volume.pamixer_options, + function(stdout, stderr, exitreason, exitcode) + muted = string.match(stdout, "(%w%w%w%w%w?) ") -- "true" or "false" + muted = (muted == "true") + + value = string.match(stdout, "(%d?%d?%d)") -- (\d?\d?\d)\%) + + if (value == nil) then + value = false + else + value = tonumber(string.format("% 3d", value)) + end + + callback({ + mute = muted, + value = value + }) + end) +end + +function volume.commands:watch(timeout, callback, widget) + awful.widget.watch( + "pamixer --get-mute --get-volume " .. volume.pamixer_options, + timeout, scallback, widget + ) +end + + + +volume.hooks = {} +volume.add_hook = function(callback) + volume.hooks[#volume.hooks + 1] = callback +end + +volume.exec_hooks = function() + volume.commands:get(function(status) + for i=1, #volume.hooks do + volume.hooks[i](status) + end + end) +end + +volume.up = function() + if volume.muted then + volume.unmute() + end + + volume.commands:up() + wrapper.sound.play("volume_up") + + volume.exec_hooks() +end + +volume.down = function() + if volume.muted then + volume.unmute() + end + + volume.commands:down() + wrapper.sound.play("volume_down") + + volume.exec_hooks() +end + +volume.mute = function() + volume.commands:mute() + volume.muted = true + + -- Spawn notification + local n = naughty.notify({ + title = "Volume muted", + text = "Silence!", + timeout = 1, + replaces_id = volume.notificationid + }) + + volume.notificationid = n.id + + volume.exec_hooks() +end + +volume.unmute = function() + volume.commands:unmute() + volume.muted = false + + -- Spawn notification + local n = naughty.notify({ + title = "Volume unmuted", + text = "Loud.", + timeout = 1, + replaces_id = volume.notificationid + }) + + volume.notificationid = n.id + + volume.exec_hooks() +end + +volume.togglemute = function() + volume.commands:get(function(status) + if status.mute then + volume.unmute() + else + volume.mute() + end + end) +end + +-- Make sure volume is unmuted at startup +volume.commands:unmute() + +return volume