New theme: ephemeral, anti-aliased corners, app drawer, lock screen,

evil daemon system, dependency list update, README improvements.
This commit is contained in:
elenapan 2019-08-01 02:17:59 +03:00
parent 544fb16561
commit db310f8e49
759 changed files with 25406 additions and 4310 deletions

23
.xfiles/ephemeral Normal file
View file

@ -0,0 +1,23 @@
*background: #323F4E
*foreground: #F8F8F2
*cursorColor: #F8F8F2
*color0: #3D4C5F
*color1: #F48FB1
*color2: #A1EFD3
*color3: #F1FA8C
*color4: #92B6F4
*color5: #BD99FF
*color6: #87DFEB
*color7: #F8F8F2
*color8: #56687E
*color9: #EE4F84
*color10: #53E2AE
*color11: #F1FF52
*color12: #6498EF
*color13: #985EFF
*color14: #24D1E7
*color15: #E5E5E5

109
README.md
View file

@ -1,63 +1,80 @@
# dotfiles
## Some details
+ **OS**: Antergos
+ **WM**: Awesome
+ **Terminal**: xst (fork of Suckless terminal)
+ **OS**: Ubuntu 18.04
+ **WM**: AwesomeWM
+ **Terminal**: Kitty
+ **File Manager**: Nemo for GUI, Ranger for terminal
+ **Bar Icons**: Typicons Font
+ **Launcher**: Rofi
+ **Editor**: Vim
+ **Org editor**: [Remacs](https://github.com/remacs/remacs)
+ **Browser**: Firefox
## Latest preview
![Screenshot](./previews/skyfall.png?raw=true "Latest")
![Screenshot](https://i.redd.it/ddrd1bbxzpd31.png)
## Dependencies
Here is a list of dependencies needed for making these themes work.
Here is a complete list of dependencies needed for making these themes work.
If you install all of them you will have a (mostly) smooth out of the box experience.
Of course, not all of them actually do something useful (see `fortune-mod` dependency).
Also if you are willing to edit a few configuration files, **which you will have to do** at some point, most of these dependencies can be replaced. For example you can replace `i3lock` with your own command, `rofi` with `dmenu`, my `screenshot.sh` script with `scrot`.
Also if you are willing to edit a few configuration files, **which you will have to do** at some point, most of these dependencies can be replaced. For example you can replace `rofi` with `dmenu`,`maim` with `scrot`.
If you notice that something is missing, please open an issue so I can add the dependency to this table.
| Dependency | Description | Why/Where is it needed? |
| --- | --- | --- |
| `awesome` v4.2+ | Window manager | (explains itself) |
<!-- | `awesome` v4.3+ | Window manager | (explains itself) | -->
| `awesome` (git `master` branch) | Window manager | (explains itself) |
| `rofi` | Window switcher, application launcher and dmenu replacement | (explains itself) |
| `xorg-xbacklight` | Gets/Sets screen brightness (intel GPU only) | brightness widget |
| `lm_sensors` | CPU temperature sensor | CPU temperature widget |
| `upower` | Abstraction for enumerating power devices, listening to device events and more | battery widget |
| `pulseaudio`, `libpulse` | Sound system **(You probably already have these)** | volume widget, [bin/volume-control.sh](./bin/volume-control.sh) script |
| [bin/volume-control.sh](./bin/volume-control.sh) in your `$PATH` | Commands to control your volume | volume buttons, volume widget |
| `jq` | Parses `json` output | weather widget |
| `fortune-mod` | Displays random quotations (fortune cookies) | fortune widget |
| `mpd` | Server-side application for playing music | **sidebar** music widget |
| `mpc` | Minimalist command line interface to MPD | **sidebar** music widget |
| `i3lock` | Screen locker | exit screen lock command |
| `maim` | Takes screenshots (improved `scrot`) | [bin/screenshot.sh](./bin/screenshot.sh) script |
| [bin/screenshot.sh](./bin/screenshot.sh) in your `$PATH` | Commands to take/view screenshots | screenshot button |
| `feh` | Image viewer and wallpaper setter | screenshot previews, wallpapers |
| *Typicons* font | Icon font | text exit screen, text weather icons, *skyfall* bar |
| Any *Nerd Font* | Icon font | *manta* bar icons, *skyfall* taglist icons |
| [openweathermap](https://openweathermap.org/) key | Provides weather data | weather widgets |
| `light` | Gets/Sets screen brightness | Brightness keybinds |
| `lm_sensors` | CPU temperature sensor | CPU temperature widgets |
| `upower` | Abstraction for enumerating power devices, listening to device events and more | Battery widgets |
| `acpid` | Daemon for delivering ACPI events | Charger notifications |
| `pulseaudio`, `libpulse` | Sound system **(Installed by default on most distros)** | Volume widgets and keybinds |
| `jq` | Parses `json` output | Weather widgets |
| `fortune-mod` | Displays random quotations (fortune cookies) | Fortune widget |
| `redshift` | Controls screen temperature | Night mode command |
| `mpd` | Server-side application for playing music | Music widgets |
| `mpc` | Minimalist command line interface to MPD | Music widgets |
| `maim` | Takes screenshots (improved `scrot`) | Screenshot keybinds |
| `feh` | Image viewer and wallpaper setter | Screenshot previews, wallpapers |
| [openweathermap](https://openweathermap.org/) key | Provides weather data | Weather widgets |
### Fonts
##### Icon fonts
+ **Typicons**
+ **Material Icons**
+ **Icomoon**
+ **Nerd Fonts**
##### Monospace
+ **Iosevka**
+ **Anka/Coder**
##### Fancy
+ **Scriptina**
##### Sans
+ **Google Sans**
+ **Roboto Condensed**
+ **San Francisco Display**
## Things to do after you set up dependencies
+ Backup your current `~/.config/awesome` directory if you have one and copy this repo's `config/awesome` directory in its place.
+ Configure default applications
+ Configure user preferences
In `rc.lua` there is a section where default applications such as terminal, editor and file manager are defined.
In `rc.lua` there is a *User variables and preferences* section where user preferences and default applications are defined. There include the terminal, editor, file manager, screenshot directory, weather widget configuration and more.
You should change those to your liking.
+ Configure autostart applications in `autostart.sh`
The commands in `autostart.sh` will run every time AwesomeWM restarts. If you would like to run something only once on login, I suggest you create the file `~/.xprofile`, make it executable and put the commands you want there.
+ *(Optional)* Load any `Xresources` colorscheme (`xrdb -merge <colorscheme file>`). In the [.xfiles](.xfiles) directory I provide you with a few of my own colorschemes, but you can also use your favorite one. All of my AwesomeWM themes take their colors from `xrdb`.
+ Have a general idea of what my keybinds do
My keybinds will most probably not suit you, but on your first login you might need to know how to navigate the desktop.
See the **Basic keybinds** section for more details.
See the [Basic keybinds](#basic-keybinds) section for more details.
**You are now ready to login with AwesomeWM!**
@ -76,19 +93,25 @@ If you notice that something is missing, please open an issue so I can add the d
- `cava` - Audio visualizer
## AwesomeWM configuration: File structure
+ I have split my `rc.lua` into multiple files for organization purposes.
I have split my `rc.lua` into multiple files for organization purposes.
+ The `noodle` directory contains widgets that usually take up more than 50 lines of code.
I prefer not filling my `bars.lua` with a ton of widget configurations, but also not making a seperate file for every widget.
I prefer not filling my files with a ton of widget configurations, but also not making a seperate file for every widget.
+ The `evil` directory contains daemons (processes that run in the background) which emit system info.
They provide an easy way of writing widgets that rely on external information. All you need to do is subscribe to the signal a daemon provides.
No need to remember which shell command gives you the necessary info or bother about killing orphan processes. Evil takes care of everything.
+ In `themes` you can find a directory for each available theme.
Such a directory should include at least a `theme.lua` and optionally icons, wallpaper, and whatever asset you need that is theme-specific.
+ In `bar_themes` you can find a `.lua` file for each available bar or bar group.
+ In `bars` you can find a `.lua` file for each available bar or bar group.
Multiple bars can be created in one file.
Every bar theme provides the global functions `toggle_wibars()` and `toggle_tray()` which you can bind to any keys you want.
## Basic keybinds
@ -105,9 +128,7 @@ I use `super` AKA Windows key as my main modifier.
+ `super + s` - Tiling layout
+ `super + shift + s` - Floating layout
+ `super + w` - Maximized / Monocle layout
+ `super + [arrow keys]` - Change focus by direction
+ `super + j/k` - Cycle through clients
+ `super + h/l` - Add / remove clients to / from master area
+ `super + [arrow keys] / hjkl` - Change focus by direction
+ `super + shift + [arrow keys] / [hjkl]` - Move client by direction. Move to edge if it is floating.
+ `super + control + [arrow keys] / [hjkl]` - Resize
+ `super + f` - Toggle fullscreen
@ -163,7 +184,7 @@ I use `super` AKA Windows key as my main modifier.
## More details about the sidebar
+ Can be toggled with `super+grave`.
+ Can be activated by moving the mouse to the edge of the screen and hidden by moving the mouse out of it (these settings can be easily enabled/disabled in your `theme.lua`).
+ Can be activated by moving the mouse to the edge of the screen and hidden by moving the mouse out of it (these settings can be easily enabled/disabled in your `user` preferences in rc.lua).
+ By default it is always above windows, and does not grab your keyboard (so you can have it open while doing something else, or just toggle it for a second to check your battery while you are watching something in fullscreen).
+ Most widgets (volume, search, exit, music...) are clickable.
+ Volume and music update only when they need to, as they are subscribed to pulse and mpd events respectively.
@ -188,19 +209,19 @@ I use `super` AKA Windows key as my main modifier.
+ If you are new to AwesomeWM...
I suggest you start from the default configuration and add pieces you like to it instead of trying to modify someone else's configuration even if you feel really comfortable with that specific config.
Otherwise you will have no idea how anything works and how you can modify things to your own liking. Trust me, I've been there.
I suggest you start from the default configuration and add pieces you like to it instead of trying to modify someone else's configuration.
Even if you feel really comfortable with that specific config, you will realize that you have no idea how anything works and how you can modify things to your own liking. Trust me, I've been there.
+ Don't forget to use the [API Documentation for AwesomeWM](https://awesomewm.org/apidoc/index.html).
It is well written and has plenty of examples.
## Theme previews
### Lovelace
![Screenshot](./previews/lovelace.png?raw=true "lovelace theme")
+ You can also post your questions on [/r/awesomewm](https://www.reddit.com/r/awesomewm/)
### Manta
![Screenshot](./previews/manta.png?raw=true "manta theme")
### Reasons
![Screenshot](./previews/reasons.png?raw=true "reasons theme")
## Older theme previews
| Theme | Preview | Reddit post |
| --- | --- | --- |
| Skyfall | ![Screenshot](https://i.redd.it/kobla5v7r5i21.png "Skyfall theme") | [Skyfall](https://www.reddit.com/r/unixporn/comments/atkn5b) |
| Lovelace | ![Screenshot](https://i.redd.it/glzrkk83f4621.png "Lovelace theme") | [Mechanical Love](https://www.reddit.com/comments/a900p7) |
| Manta | ![Screenshot](https://i.imgur.com/5pV3Xxa.png "Manta theme") | [Cake Day](https://www.reddit.com/r/unixporn/comments/9ji6uu/awesome_cake_day/) |
| Reasons | ![Screenshot](https://i.imgur.com/MdAN8jT.png "Reasons theme") | [25 reasons why you need a tiling WM](https://www.reddit.com/r/unixporn/comments/8jxpxc) |

12
bin/performance_mode Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Toggle compton
# Requires that you have allowed cpufreq-set to run without password.
if pgrep compton; then
pkill compton
sudo cpufreq-set -g performance
echo "ON"
else
compton --config ~/.config/compton/compton.conf &
sudo cpufreq-set -g powersave
echo "OFF"
fi

16
bin/scratchpad Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
SCRATCHPAD_SESSION="$(tmux ls | grep scratchpad)"
SCRATCHPAD_WINDOW="$(xdotool search --classname scratchpad)"
# If there is no such window
# (Checking for the window should not be necessary if AwesomeWM does it already)
if [ ${#SCRATCHPAD_WINDOW} -eq "0" ]; then
# If the session does not exist, create a new one
if [ ${#SCRATCHPAD_SESSION} -eq "0" ]; then
kitty -1 --class scratchpad -e tmux new-session -s scratchpad &
# Else attach to the session
else
kitty -1 --class scratchpad -e tmux attach -t scratchpad &
fi
fi

4
bin/visualizer Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
# Toggle visualizer:
# Kill it if it is running or spawn it if it does not running
xdotool search --class Visualizer &>/dev/null && (ps x | grep "kitty --class Visualizer" | grep -v grep | awk '{print $1}' | xargs kill) || kitty --class Visualizer -o background_opacity=0 -o font_size=6 -o window_margin_width=0 -e cava &

View file

@ -0,0 +1 @@
-/.png

View file

@ -4,7 +4,8 @@
# Use "program &" to run it regardless
# ---
# NOTE: This script runs with every restart of AwesomeWM
# TODO: run_once
# If you would like to run a command *once* on login,
# you can use ~/.xprofile
function run {
if ! pgrep $1 > /dev/null ;
@ -14,16 +15,17 @@ function run {
}
# Music
run mpd ~/.config/mpd/mpd.conf
# run mpd
# (Alternatively, enable the mpd service so mpd runs on login)
# Emacs daemon
#run emacs --daemon
# Load terminal colorscheme and settings
#xrdb ~/.Xresources
xrdb ~/.Xresources
# Urxvt daemon
#run urxvtd -q -o -f
# run urxvtd -q -o -f
# Mpv input file
if [ ! -e /tmp/mpv.fifo ]; then
@ -34,21 +36,15 @@ fi
#run compton --config ~/.config/compton/compton.conf
# Enable numlock on login
# Required numlockx to be installed
run numlockx
# Battery notifications
# run battery_daemon
# Network manager tray icon
run nm-applet
# Keyboard layout
# setxkbmap -layout "us,gr" -option "grp:alt_shift_toggle" &
# setxkbmap -layout "us,de" -option "grp:alt_shift_toggle" &
# setxkbmap -layout "us,gr,ru" -option "grp:alt_shift_toggle"
# Kill redshift processes
# pkill redshift
# Caps Lock is Escape (Escape remains as is)
# setxkbmap -option caps:escape
# Scratchpad
# scratchpad
# Wallpaper
# (Already set to run in rc.lua)
# ~/.fehbg

View file

@ -1,13 +0,0 @@
#!/bin/bash
# Noodle Cleanup Script
# Some of my widgets (mpd, volume) rely on scripts that have to be
# run persistently in the background.
# They sleep until mpd/volume state changes, in an infinite loop.
# As a result when awesome restarts, they keep running in background, along with the new ones that are created after the restart.
# This script cleans up the old processes.
# Mpd widget
ps aux | grep "mpc idleloop player" | grep -v grep | awk '{print $2}' | xargs kill
#ps aux | grep "mpc idle player" | grep -v grep | awk '{print $2}' | xargs kill
# Volume widget
ps aux | grep "pactl subscribe" | grep -v grep | awk '{print $2}' | xargs kill

View file

@ -1,361 +0,0 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
--local xrdb = xresources.get_current_theme()
local helpers = require("helpers")
local keys = require("keys")
-- {{{ Widgets
local desktop_control = require("noodle.desktop_control")
local minimal_tasklist = require("noodle.minimal_tasklist")
local icon_taglist = require("noodle.icon_taglist")
-- Start button widget (can toggle sidebar, tray, scratchpad)
start_widget = wibox.widget.imagebox(beautiful.start_icon)
start_widget:buttons(gears.table.join(
-- Left click - Toggle sidebar
awful.button({ }, 1, function ()
sidebar.visible = not sidebar.visible
end),
-- Middle click - Toggle scratchpad
awful.button({ }, 2, function ()
helpers.toggle_scratchpad()
end),
-- Right click - Toggle tray
awful.button({ }, 3, function ()
local traybox = awful.screen.focused().traybox
traybox.visible = not traybox.visible
end)
))
-- Keyboard map indicator and switcher
-- keyboardlayout_prefix = wibox.widget.textbox(" ")
-- keyboardlayout_prefix.markup = helpers.colorize_text(keyboardlayout_prefix.text, beautiful.prefix_fg)
-- mykeyboardlayout = awful.widget.keyboardlayout()
-- Create a textclock widget that shows date
-- date_prefix = wibox.widget.textbox(" ")
-- date_prefix.markup = helpers.colorize_text(date_prefix.text, beautiful.prefix_fg)
--mytextdate = wibox.widget.textclock("%a %d %B")
-- mytextdate = wibox.widget.textclock("%j days around the sun") --HAHA very useful
-- Create a textclock widget
-- clock_prefix = wibox.widget.textbox(" ")
-- clock_prefix.markup = helpers.colorize_text(clock_prefix.text, beautiful.prefix_fg)
-- mytextclock = wibox.widget.textclock("%H:%M")
-- Create item separator
textseparator = wibox.widget.textbox()
textseparator.text = beautiful.separator_text
textseparator.font = "hurmit nerd font bold 14"
textseparator.markup = helpers.colorize_text(textseparator.text, beautiful.separator_fg)
-- Create padding
pad = wibox.widget.textbox(" ")
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t)
-- Tag back and forth
local current_tag = awful.screen.focused().selected_tag
if t == current_tag then
awful.tag.history.restore()
else
t:view_only()
end
-- t:view_only()
end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
-- awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ }, 3, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ modkey }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end)
)
local tasklist_buttons = gears.table.join(
awful.button({ }, 1,
function (c)
if c == client.focus then
c.minimized = true
else
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
-- Middle mouse button closes the window
awful.button({ }, 2, function (c) c:kill() end),
awful.button({ }, 3, helpers.client_menu_toggle()),
awful.button({ }, 4, function ()
awful.client.focus.byidx(-1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(1)
end)
)
-- }}}
awful.screen.connect_for_each_screen(function(s)
-- Create a promptbox for each screen
-- s.mypromptbox = awful.widget.prompt({prompt = " Run: ", fg = beautiful.prompt_fg})
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
-- We need one layoutbox per screen.
-- s.mylayoutbox = awful.widget.layoutbox(s)
-- s.mylayoutbox:buttons(gears.table.join(
-- awful.button({ }, 1, function () awful.layout.inc( 1) end),
-- awful.button({ }, 3, function () awful.layout.inc(-1) end),
-- awful.button({ }, 4, function () awful.layout.inc( 1) end),
-- awful.button({ }, 5, function () awful.layout.inc(-1) end)))
-- -- Create a taglist widget
-- s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
-- s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.noempty, taglist_buttons)
-- s.mytaglist.font = beautiful.font
-- Create a tasklist widget
-- s.mytasklist = awful.widget.tasklist {
-- screen = s,
-- filter = awful.widget.tasklist.filter.currenttags,
-- buttons = tasklist_buttons,
-- layout = {
-- spacing_widget = {
-- {
-- forced_width = 5,
-- forced_height = 24,
-- thickness = 1,
-- color = '#777777',
-- 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 = 5,
-- id = 'background_role',
-- widget = wibox.container.background,
-- },
-- {
-- {
-- id = 'clienticon',
-- widget = awful.widget.clienticon,
-- },
-- margins = 5,
-- color = '#777777',
-- widget = wibox.container.margin
-- },
-- nil,
-- create_callback = function(self, c, index, objects) --luacheck: no unused args
-- self:get_children_by_id('clienticon')[1].client = c
-- end,
-- layout = wibox.layout.align.vertical,
-- },
-- }
-- s.mytasklist = awful.widget.tasklist {
-- screen = s,
-- filter = awful.widget.tasklist.filter.currenttags,
-- buttons = tasklist_buttons,
-- style = {
-- shape_border_width = 4,
-- shape_border_color = beautiful.bg_minimize,
-- shape = gears.shape.rounded_bar,
-- },
-- layout = {
-- spacing = 10,
-- spacing_widget = {
-- {
-- forced_width = 5,
-- shape = gears.shape.circle,
-- widget = wibox.widget.separator
-- },
-- valign = 'center',
-- halign = 'center',
-- widget = wibox.container.place,
-- },
-- layout = wibox.layout.flex.horizontal
-- },
-- -- Notice that there is *NO* wibox.wibox prefix, it is a template,
-- -- not a widget instance.
-- widget_template = {
-- {
-- {
-- {
-- {
-- id = 'icon_role',
-- widget = wibox.widget.imagebox,
-- },
-- margins = 5,
-- widget = wibox.container.margin,
-- },
-- {
-- id = 'text_role',
-- widget = wibox.widget.textbox,
-- },
-- layout = wibox.layout.fixed.horizontal,
-- },
-- left = 10,
-- right = 10,
-- widget = wibox.container.margin
-- },
-- id = 'background_role',
-- widget = wibox.container.background,
-- },
-- }
-- Outer gaps
--awful.screen.padding(awful.screen.focused(),{left = 28, right = 28, top = 28, bottom = 28})
-- Create a system tray widget
s.systray = wibox.widget.systray()
-- Wibar detached - Method: Transparent useless bar
-- Requires compositor
if beautiful.wibar_detached then
s.useless_wibar = awful.wibar({ position = beautiful.wibar_position, screen = s, height = beautiful.screen_margin * 2, opacity = 0 })
--TODO
--s.useless_wibar:buttons(keys.desktopbuttons)
end
-- Create the wibox
s.mywibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- Wibar items
-- Add or remove widgets here
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
pad,
start_widget,
textseparator,
-- s.mytaglist,
icon_taglist,
textseparator
-- minimal_tasklist
},
{ -- Middle widgets
layout = wibox.layout.fixed.horizontal,
--s.mypromptbox,
-- textseparator,
-- s.mytasklist,
-- minimal_tasklist
desktop_control
},
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
--mpdarc_widget,
--textseparator,
--volumebar_prefix,
--volumebar_widget,
--textseparator,
--keyboardlayout_prefix,
--mykeyboardlayout,
--textseparator,
-- s.systray,
--minimal_tasklist,
-- textseparator,
--date_prefix,
-- mytextdate,
-- textseparator,
--clock_prefix,
-- mytextclock,
-- textseparator,
-- s.mylayoutbox,
pad
},
}
-- Only set them if they exist, else they overwrite the position variable
if beautiful.wibar_x then
s.mywibox.x = beautiful.wibar_x
end
if beautiful.wibar_y then
s.mywibox.y = beautiful.wibar_y
end
-- Create a wibox that will only show the tray
-- Hidden by default. Can be toggled with a keybind.
s.traybox = wibox({visible = false, ontop = true, shape = helpers.rbar(), type = "dock"})
s.traybox.width = dpi(150)
s.traybox.height = dpi(38)
s.traybox.x = beautiful.screen_margin * 2
-- s.traybox.x = s.geometry.width - s.traybox.width - beautiful.screen_margin * 2
s.traybox.y = s.geometry.height - s.traybox.height - beautiful.screen_margin * 2
s.traybox.bg = beautiful.bg_systray
s.traybox:setup {
-- wibox.widget.textbox("test"),
pad,
s.systray,
pad,
layout = wibox.layout.align.horizontal
}
s.traybox:buttons(gears.table.join(
-- Middle click - Hide traybox
awful.button({ }, 2, function ()
s.traybox.visible = false
end)
))
-- TODO
-- s.mytaskwibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- s.mytaskwibox.x = s.mywibox.x
-- s.mytaskwibox.y = s.mywibox.y
-- s.mytaskwibox.visible = false
-- s.mytaskwibox:setup {
-- layout = wibox.layout.align.horizontal,
-- { -- Left widgets
-- layout = wibox.layout.fixed.horizontal,
-- s.mytasklist
-- },
-- { -- Middle widgets
-- layout = wibox.layout.fixed.horizontal,
-- },
-- { -- Right widgets
-- layout = wibox.layout.fixed.horizontal,
-- textseparator,
-- mytextclock,
-- textseparator,
-- pad
-- },
-- }
-- awesome.connect_signal("dummy", function (c)
-- if s.mywibox.visible then
-- s.mytaskwibox.visible = true
-- s.mywibox.visible = false
-- else
-- s.mywibox.visible = true
-- s.mytaskwibox.visible = false
-- end
-- end)
end)

View file

@ -1,281 +0,0 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
--local xresources = require("beautiful.xresources")
--local xrdb = xresources.get_current_theme()
local helpers = require("helpers")
local keys = require("keys")
-- {{{ Widgets
local desktop_mode_widget = require("noodle.desktop_mode_widget")
local minimal_tasklist = require("noodle.minimal_tasklist")
-- Volume widget prefix
volumebar_prefix = wibox.widget.textbox("")
volumebar_prefix.markup = helpers.colorize_text(volumebar_prefix.text, beautiful.prefix_fg)
-- Keyboard map indicator and switcher
keyboardlayout_prefix = wibox.widget.textbox("")
keyboardlayout_prefix.markup = helpers.colorize_text(keyboardlayout_prefix.text, beautiful.prefix_fg)
mykeyboardlayout = awful.widget.keyboardlayout()
-- Create a textclock widget that shows date
date_prefix = wibox.widget.textbox("")
date_prefix.markup = helpers.colorize_text(date_prefix.text, beautiful.prefix_fg)
--mytextdate = wibox.widget.textclock("%a %d %B")
mytextdate = wibox.widget.textclock("%j days around the sun") --HAHA very useful
-- Create a textclock widget
clock_prefix = wibox.widget.textbox("")
clock_prefix.markup = helpers.colorize_text(clock_prefix.text, beautiful.prefix_fg)
mytextclock = wibox.widget.textclock("%H:%M")
-- Create item separator
textseparator = wibox.widget.textbox()
textseparator.text = beautiful.separator_text
textseparator.markup = helpers.colorize_text(textseparator.text, beautiful.separator_fg)
-- Create padding
pad = wibox.widget.textbox(" ")
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
-- awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ }, 3, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ modkey }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end)
)
local tasklist_buttons = gears.table.join(
awful.button({ }, 1,
function (c)
if c == client.focus then
c.minimized = true
else
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
-- Middle mouse button closes the window
awful.button({ }, 2, function (c) c:kill() end),
awful.button({ }, 3, helpers.client_menu_toggle()),
awful.button({ }, 4, function ()
awful.client.focus.byidx(-1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(1)
end)
)
-- }}}
awful.screen.connect_for_each_screen(function(s)
-- Create a promptbox for each screen
s.mypromptbox = awful.widget.prompt({prompt = " Run: ", fg = beautiful.prompt_fg})
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
-- Create a taglist widget
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
s.mytaglist.font = beautiful.font
-- Create a tasklist widget
-- Show all clients
-- s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
-- Show only focused client
--s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.focused, tasklist_buttons)
-- Show only minimized clients
--s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.minimizedcurrenttags, tasklist_buttons)
-- TODO doesn't work
-- s.mytasklist.layout = wibox.layout.flex.horizontal
-- Outer gaps
--awful.screen.padding(awful.screen.focused(),{left = 28, right = 28, top = 28, bottom = 28})
-- Create a system tray widget
s.systray = wibox.widget.systray()
s.systray.visible = false -- can be toggled by a keybind
-- Wibar detached - Method: Transparent useless bar
-- Requires compositor
if beautiful.wibar_detached then
s.useless_wibar = awful.wibar({ position = beautiful.wibar_position, screen = s, height = beautiful.screen_margin * 2, opacity = 0 })
--TODO
--s.useless_wibar:buttons(keys.desktopbuttons)
end
-- Create the wibox
s.mywibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- Wibar items
-- Add or remove widgets here
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
--s.mylayoutbox,
--mylauncher,
s.mytaglist,
textseparator,
minimal_tasklist
},
{ -- Middle widgets
layout = wibox.layout.fixed.horizontal,
--s.mypromptbox,
--textseparator,
--s.mytasklist,
--minimal_tasklist
},
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
--mpdarc_widget,
--textseparator,
--volumebar_prefix,
--volumebar_widget,
--textseparator,
--keyboardlayout_prefix,
--mykeyboardlayout,
--textseparator,
s.systray,
--minimal_tasklist,
textseparator,
--date_prefix,
mytextdate,
textseparator,
--clock_prefix,
mytextclock,
textseparator,
desktop_mode_widget,
pad,
pad
},
}
-- Second (alternate panel)
if beautiful.wibar_alt_enabled then
if beautiful.wibar_alt_detached then
s.useless_wibar_alt = awful.wibar({ position = beautiful.wibar_alt_position, screen = s, height = beautiful.screen_margin * 2, opacity = 0 })
s.useless_wibar_alt:buttons(gears.table.join(
--TODO
--keys.desktopbuttons
))
end
s.mywibox_alt = awful.wibox({ position = beautiful.wibar_alt_position, screen = s, width = beautiful.wibar_alt_width, height = beautiful.wibar_alt_height, shape = helpers.rrect(beautiful.wibar_alt_border_radius)})
-- Only set them if they exist, else they overwrite the position variable
if beautiful.wibar_alt_x then
s.mywibox_alt.x = beautiful.wibar_alt_x
end
if beautiful.wibar_alt_y then
s.mywibox_alt.y = beautiful.wibar_alt_y
end
-- Second wibar items
-- Add or remove widgets here
s.mywibox_alt:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
--pad,
--s.mylayoutbox,
--mylauncher,
},
{ -- Middle widgets
layout = wibox.layout.fixed.horizontal,
--s.mypromptbox,
--s.mytasklist,
--textseparator,
},
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
--mpdarc_widget,
--textseparator,
--volumebar_prefix,
--volumebar_widget,
--textseparator,
--keyboardlayout_prefix,
--mykeyboardlayout,
--textseparator,
-- s.systray,
minimal_tasklist,
textseparator,
date_prefix,
mytextdate,
textseparator,
clock_prefix,
mytextclock,
textseparator,
desktop_mode_widget,
pad
},
}
end
-- Only set them if they exist, else they overwrite the position variable
if beautiful.wibar_x then
s.mywibox.x = beautiful.wibar_x
end
if beautiful.wibar_y then
s.mywibox.y = beautiful.wibar_y
end
-- s.mytaskwibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- s.mytaskwibox.x = s.mywibox.x
-- s.mytaskwibox.y = s.mywibox.y
-- s.mytaskwibox.visible = false
-- s.mytaskwibox:setup {
-- layout = wibox.layout.align.horizontal,
-- { -- Left widgets
-- layout = wibox.layout.fixed.horizontal,
-- s.mytasklist
-- },
-- { -- Middle widgets
-- layout = wibox.layout.fixed.horizontal,
-- },
-- { -- Right widgets
-- layout = wibox.layout.fixed.horizontal,
-- textseparator,
-- mytextclock,
-- textseparator,
-- desktop_mode_widget,
-- pad
-- },
-- }
-- awesome.connect_signal("dummy", function (c)
-- if s.mywibox.visible then
-- s.mytaskwibox.visible = true
-- s.mytaskwibox.ontop = true
-- s.mywibox.visible = false
-- else
-- s.mywibox.visible = true
-- s.mywibox.ontop = true
-- s.mytaskwibox.visible = false
-- end
-- end)
end)

View file

@ -0,0 +1,358 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local keys = require("keys")
local helpers = require("helpers")
local pad = helpers.pad
-- Helper function that creates a button widget
local create_button = function (symbol, color, bg_color, hover_color)
local widget = wibox.widget {
font = "icomoon 14",
align = "center",
id = "text_role",
valign = "center",
markup = helpers.colorize_text(symbol, color),
widget = wibox.widget.textbox()
}
local section = wibox.widget {
widget,
forced_width = dpi(70),
bg = bg_color,
widget = wibox.container.background
}
-- Hover animation
section:connect_signal("mouse::enter", function ()
section.bg = hover_color
end)
section:connect_signal("mouse::leave", function ()
section.bg = bg_color
end)
-- helpers.add_hover_cursor(section, "hand1")
return section
end
local exit = create_button("", beautiful.xcolor6, beautiful.xcolor8.."C0",beautiful.xcolor8.."E0")
exit:buttons(gears.table.join(
awful.button({ }, 1, function ()
exit_screen_show()
end)
))
local volume_symbol = ""
local volume_muted_color = beautiful.xcolor8
local volume_unmuted_color = beautiful.xcolor5
local volume = create_button(volume_symbol, volume_unmuted_color, beautiful.xcolor8.."30", beautiful.xcolor8.."50")
volume:buttons(gears.table.join(
-- Left click - Mute / Unmute
awful.button({ }, 1, function ()
helpers.volume_control(0)
end),
-- Right click - Run or raise pavucontrol
awful.button({ }, 3, function ()
helpers.run_or_raise({class = 'Pavucontrol'}, true, "pavucontrol")
end),
-- Scroll - Increase / Decrease volume
awful.button({ }, 4, function ()
helpers.volume_control(5)
end),
awful.button({ }, 5, function ()
helpers.volume_control(-5)
end)
))
awesome.connect_signal("evil::volume", function(_, muted)
local t = volume:get_all_children()[1]
if muted then
t.markup = helpers.colorize_text(volume_symbol, volume_muted_color)
else
t.markup = helpers.colorize_text(volume_symbol, volume_unmuted_color)
end
end)
local microphone_symbol = ""
local microphone_muted_color = beautiful.xcolor8
local microphone_unmuted_color = beautiful.xcolor3
local microphone = create_button(microphone_symbol, microphone_unmuted_color, beautiful.xcolor8.."60", beautiful.xcolor8.."80")
microphone:buttons(gears.table.join(
awful.button({ }, 1, function ()
awful.spawn.with_shell("amixer -D pulse sset Capture toggle &> /dev/null")
end)
))
awesome.connect_signal("evil::microphone", function(muted)
local t = microphone:get_all_children()[1]
if muted then
t.markup = helpers.colorize_text(microphone_symbol, microphone_muted_color)
else
t.markup = helpers.colorize_text(microphone_symbol, microphone_unmuted_color)
end
end)
local music = create_button("", beautiful.xcolor4, beautiful.xcolor8.."90", beautiful.xcolor8.."B0")
music:buttons(gears.table.join(
awful.button({ }, 1, function ()
helpers.run_or_raise({class = "music"}, true, user.music_client)
end),
awful.button({ }, 3, function ()
helpers.run_or_raise({class = "music"}, true, user.music_client)
end)
))
local sandwich = create_button("", beautiful.xcolor1, beautiful.xcolor8.."30", beautiful.xcolor8.."50")
sandwich:buttons(gears.table.join(
awful.button({ }, 1, function ()
app_drawer_show()
end),
awful.button({ }, 2, function ()
helpers.toggle_scratchpad()
end),
awful.button({ }, 3, function ()
toggle_tray()
end)
))
-- Helper function that updates a tasklist item
local update_tasklist = function (task, c)
local background = task:get_children_by_id('bg_role')[1]
local text = task:get_children_by_id('text_role')[1]
if c.minimized then
color = "#00000000"
else
if c.class == "email" then
color = beautiful.xcolor2
elseif c.class == "Firefox" then
color = beautiful.xcolor1
elseif c.class == "music" then
color = beautiful.xcolor5
elseif c.class == "TelegramDesktop" then
color = beautiful.xcolor2
elseif c.class == "Thunar" then
color = beautiful.xcolor3
elseif c.class == "mpv" then
color = beautiful.xcolor6
elseif c.class == "Alacritty" then
color = beautiful.xcolor4
else
color = beautiful.xcolor7
end
end
if client.focus == c then
text.markup = helpers.colorize_text(text.text, color)
-- background.bg = color
background.border_color = color
background.bg = beautiful.xbackground.."AA"
else
text.markup = helpers.colorize_text(text.text, beautiful.xforeground)
background.bg = color
background.border_color = "#00000000"
end
end
local tag_colors_empty = { "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", "#00000000", }
local tag_colors_urgent = {
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7,
beautiful.xcolor7
}
local tag_colors_focused = {
beautiful.xcolor1,
beautiful.xcolor5,
beautiful.xcolor4,
beautiful.xcolor6,
beautiful.xcolor2,
beautiful.xcolor3,
beautiful.xcolor1,
beautiful.xcolor5,
beautiful.xcolor4,
beautiful.xcolor6,
}
local tag_colors_occupied = {
beautiful.xcolor1.."55",
beautiful.xcolor5.."55",
beautiful.xcolor4.."55",
beautiful.xcolor6.."55",
beautiful.xcolor2.."55",
beautiful.xcolor3.."55",
beautiful.xcolor1.."55",
beautiful.xcolor5.."55",
beautiful.xcolor4.."55",
beautiful.xcolor6.."55",
}
-- Helper function that updates a taglist item
local update_taglist = function (item, tag, index)
if tag.selected then
item.bg = tag_colors_focused[index]
elseif tag.urgent then
item.bg = tag_colors_urgent[index]
elseif #tag:clients() > 0 then
item.bg = tag_colors_occupied[index]
else
item.bg = tag_colors_empty[index]
end
end
awful.screen.connect_for_each_screen(function(s)
-- Create a taglist for every screen
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
buttons = keys.taglist_buttons,
layout = wibox.layout.flex.horizontal,
widget_template = {
widget = wibox.container.background,
create_callback = function(self, tag, index, _)
update_taglist(self, tag, index)
end,
update_callback = function(self, tag, index, _)
update_taglist(self, tag, index)
end,
}
}
-- Create a tasklist for every screen
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = keys.tasklist_buttons,
style = {
font = beautiful.tasklist_font,
bg = beautiful.xcolor0,
},
layout = {
layout = wibox.layout.flex.horizontal
},
widget_template = {
{
{
id = 'text_role',
align = "center",
widget = wibox.widget.textbox,
},
forced_width = dpi(220),
left = dpi(15),
right = dpi(15),
-- Add margins to top and bottom in order to force the
-- text to be on a single line, if needed. Might need
-- to adjust them according to font size.
top = dpi(4),
bottom = dpi(4),
widget = wibox.container.margin
},
id = "bg_role",
widget = wibox.container.background,
},
}
-- Create the wibox
s.mywibox = awful.wibar({visible = true, ontop = true, type = "dock", position = "bottom"})
s.mywibox.height = beautiful.wibar_height
-- s.mywibox.width = beautiful.wibar_width
s.mywibox.bg = beautiful.xcolor0
-- Bar placement
awful.placement.maximize_horizontally(s.mywibox)
-- Wibar items
-- Add or remove widgets here
s.mywibox:setup {
sandwich,
s.mytasklist,
{
volume,
microphone,
music,
exit,
layout = wibox.layout.fixed.horizontal
},
-- expand = "none",
layout = wibox.layout.align.horizontal
}
-- Create the top bar
s.mytopwibox = awful.wibar({visible = true, ontop = false, type = "dock", position = "top", height = dpi(5)})
-- Bar placement
awful.placement.maximize_horizontally(s.mytopwibox)
s.mytopwibox.bg = "#00000000"
s.mytopwibox:setup {
widget = s.mytaglist,
}
-- Create a system tray widget
s.systray = wibox.widget.systray()
-- Create a wibox that will only show the tray
-- Hidden by default. Can be toggled with a keybind.
s.traybox = wibox({visible = false, ontop = true, type = "normal"})
s.traybox.width = dpi(120)
s.traybox.height = beautiful.wibar_height
awful.placement.bottom_left(s.traybox, {honor_workarea = true, margins = beautiful.screen_margin * 2})
s.traybox.bg = "#00000000"
s.traybox:setup {
s.systray,
bg = beautiful.bg_systray,
shape = helpers.rrect(beautiful.border_radius),
widget = wibox.container.background()
}
s.traybox:buttons(gears.table.join(
-- Middle click - Hide traybox
awful.button({ }, 2, function ()
s.traybox.visible = false
end)
))
-- Hide traybox when mouse leaves
s.traybox:connect_signal("mouse::leave", function ()
s.traybox.visible = false
end)
end)
-- We have set the wibar(s) to be ontop, but we do not want it to be above fullscreen clients
local function no_wibar_ontop(c)
local s = awful.screen.focused()
if c.fullscreen then
s.mywibox.ontop = false
else
s.mywibox.ontop = true
end
end
client.connect_signal("focus", no_wibar_ontop)
client.connect_signal("unfocus", no_wibar_ontop)
client.connect_signal("property::fullscreen", no_wibar_ontop)
-- Every bar theme should provide these fuctions
function toggle_wibars()
local s = awful.screen.focused()
s.mywibox.visible = not s.mywibox.visible
s.mytopwibox.visible = not s.mytopwibox.visible
end
function toggle_tray()
local s = awful.screen.focused()
s.traybox.visible = not s.traybox.visible
end

View file

@ -0,0 +1,131 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
--local xrdb = xresources.get_current_theme()
local helpers = require("helpers")
local keys = require("keys")
-- {{{ Widgets
local desktop_control = require("noodle.desktop_control")
local minimal_tasklist = require("noodle.minimal_tasklist")
-- Start button widget (can toggle sidebar, tray, scratchpad)
start_widget = wibox.widget.imagebox(icons.start)
start_widget:buttons(gears.table.join(
-- Left click - Toggle sidebar
awful.button({ }, 1, function ()
sidebar.visible = not sidebar.visible
end),
-- Middle click - Toggle scratchpad
awful.button({ }, 2, function ()
helpers.toggle_scratchpad()
end),
-- Right click - Toggle tray
awful.button({ }, 3, function ()
local traybox = awful.screen.focused().traybox
traybox.visible = not traybox.visible
end)
))
-- Create item separator
textseparator = wibox.widget.textbox()
textseparator.text = beautiful.separator_text
textseparator.font = "hurmit nerd font bold 14"
textseparator.markup = helpers.colorize_text(textseparator.text, beautiful.separator_fg)
-- Create padding
pad = wibox.widget.textbox(" ")
-- }}}
local update_taglist = function (item, tag, index)
if tag.selected then
item.image = beautiful.taglist_icons_focused[index]
elseif tag.urgent then
item.image = beautiful.taglist_icons_urgent[index]
elseif #tag:clients() > 0 then
item.image = beautiful.taglist_icons_occupied[index]
else
item.image = beautiful.taglist_icons_empty[index]
end
end
awful.screen.connect_for_each_screen(function(s)
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
layout = wibox.layout.fixed.horizontal,
widget_template = {
widget = wibox.widget.imagebox,
-- Add support for hover colors and an index label
create_callback = function(self, tag, index, objects)
update_taglist(self, tag, index)
end,
update_callback = function(self, tag, index, objects)
update_taglist(self, tag, index)
end,
},
buttons = keys.taglist_buttons
}
-- Create a system tray widget
s.systray = wibox.widget.systray()
-- Create the wibox
s.mywibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- Wibar items
-- Add or remove widgets here
s.mywibox:setup {
layout = wibox.layout.fixed.horizontal,
pad,
start_widget,
textseparator,
s.mytaglist,
textseparator,
desktop_control,
pad
}
-- Only set them if they exist, else they overwrite the position variable
if beautiful.wibar_x then
s.mywibox.x = beautiful.wibar_x
end
if beautiful.wibar_y then
s.mywibox.y = beautiful.wibar_y
end
-- Create a wibox that will only show the tray
-- Hidden by default. Can be toggled with a keybind.
s.traybox = wibox({visible = false, ontop = true, shape = gears.shape.rounded_bar, type = "dock"})
s.traybox.width = dpi(150)
s.traybox.height = dpi(38)
s.traybox.x = beautiful.screen_margin * 2
-- s.traybox.x = s.geometry.width - s.traybox.width - beautiful.screen_margin * 2
s.traybox.y = s.geometry.height - s.traybox.height - beautiful.screen_margin * 2
s.traybox.bg = beautiful.bg_systray
s.traybox:setup {
-- wibox.widget.textbox("test"),
pad,
s.systray,
pad,
layout = wibox.layout.align.horizontal
}
s.traybox:buttons(gears.table.join(
-- Middle click - Hide traybox
awful.button({ }, 2, function ()
s.traybox.visible = false
end)
))
end)
-- Every bar theme should provide these fuctions
function toggle_wibars()
local s = awful.screen.focused()
s.mywibox.visible = not s.mywibox.visible
end
function toggle_tray()
local s = awful.screen.focused()
s.traybox.visible = not s.traybox.visible
end

View file

@ -0,0 +1,111 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
--local xrdb = xresources.get_current_theme()
local helpers = require("helpers")
local keys = require("keys")
-- {{{ Widgets
local desktop_mode_widget = require("noodle.desktop_mode_widget")
local minimal_tasklist = require("noodle.minimal_tasklist")
-- Volume widget prefix
volumebar_prefix = wibox.widget.textbox("")
volumebar_prefix.markup = helpers.colorize_text(volumebar_prefix.text, beautiful.prefix_fg)
-- Keyboard map indicator and switcher
keyboardlayout_prefix = wibox.widget.textbox("")
keyboardlayout_prefix.markup = helpers.colorize_text(keyboardlayout_prefix.text, beautiful.prefix_fg)
mykeyboardlayout = awful.widget.keyboardlayout()
-- Create a textclock widget that shows date
date_prefix = wibox.widget.textbox("")
date_prefix.markup = helpers.colorize_text(date_prefix.text, beautiful.prefix_fg)
--mytextdate = wibox.widget.textclock("%a %d %B")
mytextdate = wibox.widget.textclock("%j days around the sun") --HAHA very useful
-- Create a textclock widget
clock_prefix = wibox.widget.textbox("")
clock_prefix.markup = helpers.colorize_text(clock_prefix.text, beautiful.prefix_fg)
mytextclock = wibox.widget.textclock("%H:%M")
-- Create item separator
textseparator = wibox.widget.textbox()
textseparator.text = beautiful.separator_text
textseparator.markup = helpers.colorize_text(textseparator.text, beautiful.separator_fg)
-- Create padding
pad = wibox.widget.textbox(" ")
-- }}}
-- Create a wibox for each screen and add it
awful.screen.connect_for_each_screen(function(s)
-- Create a promptbox for each screen
s.mypromptbox = awful.widget.prompt({prompt = " Run: ", fg = beautiful.prompt_fg})
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
-- We need one layoutbox per screen.
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
-- Create a taglist widget
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, keys.taglist_buttons)
s.mytaglist.font = beautiful.font
-- Create a system tray widget
s.systray = wibox.widget.systray()
s.systray.visible = false -- can be toggled by a keybind
-- Create the wibox
s.mywibox = awful.wibar({ position = beautiful.wibar_position, screen = s, width = beautiful.wibar_width, height = beautiful.wibar_height, shape = helpers.rrect(beautiful.wibar_border_radius)})
-- Wibar items
-- Add or remove widgets here
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
layout = wibox.layout.fixed.horizontal,
s.mytaglist,
textseparator,
minimal_tasklist
},
{ -- Middle widgets
layout = wibox.layout.fixed.horizontal,
--s.mypromptbox,
--textseparator,
--s.mytasklist,
--minimal_tasklist
},
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
s.systray,
textseparator,
mytextdate,
textseparator,
mytextclock,
textseparator,
desktop_mode_widget,
pad,
pad
},
}
-- Place bar at the bottom and add margins
awful.placement.bottom(s.mywibox, {margins = beautiful.useless_gap * 2})
-- Also add some screen padding so that clients do not stick to the bar
s.padding = { bottom = s.padding.bottom + beautiful.useless_gap * 2 }
end)
-- Every bar theme should provide these fuctions
function toggle_wibars()
local s = awful.screen.focused()
s.mywibox.visible = not s.mywibox.visible
end
function toggle_tray()
local s = awful.screen.focused()
s.systray.visible = not s.systray.visible
end

View file

@ -2,67 +2,47 @@ local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
local keys = require("keys")
local helpers = require("helpers")
local pad = helpers.pad
-- {{{ Widgets
-- Helper function that updates a taglist item
local update_taglist = function (item, tag, index)
if tag.selected then
item.markup = helpers.colorize_text(beautiful.taglist_text_focused[index], beautiful.taglist_text_color_focused[index])
elseif tag.urgent then
item.markup = helpers.colorize_text(beautiful.taglist_text_urgent[index], beautiful.taglist_text_color_urgent[index])
elseif #tag:clients() > 0 then
item.markup = helpers.colorize_text(beautiful.taglist_text_occupied[index], beautiful.taglist_text_color_occupied[index])
else
item.markup = helpers.colorize_text(beautiful.taglist_text_empty[index], beautiful.taglist_text_color_empty[index])
end
end
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
-- awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ }, 3, function(t)
if client.focus then
client.focus:move_to_tag(t)
end
end),
awful.button({ modkey }, 3, function(t)
if client.focus then
client.focus:toggle_tag(t)
end
end),
awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end),
awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end)
)
local tasklist_buttons = gears.table.join(
awful.button({ }, 1,
function (c)
if c == client.focus then
c.minimized = true
else
-- Without this, the following
-- :isvisible() makes no sense
c.minimized = false
if not c:isvisible() and c.first_tag then
c.first_tag:view_only()
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end),
-- Middle mouse button closes the window
awful.button({ }, 2, function (c) c:kill() end),
awful.button({ }, 3, function (c) c.minimized = true end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(-1)
end),
awful.button({ }, 5, function ()
awful.client.focus.byidx(1)
end)
)
-- }}}
awful.screen.connect_for_each_screen(function(s)
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
layout = wibox.layout.fixed.horizontal,
widget_template = {
widget = wibox.widget.textbox,
create_callback = function(self, tag, index, _)
self.align = "center"
self.valign = "center"
self.forced_width = dpi(25)
self.font = beautiful.taglist_text_font
update_taglist(self, tag, index)
end,
update_callback = function(self, tag, index, _)
update_taglist(self, tag, index)
end,
},
buttons = keys.taglist_buttons
}
-- Create a system tray widget
s.systray = wibox.widget.systray()
@ -92,23 +72,14 @@ awful.screen.connect_for_each_screen(function(s)
s.traybox.visible = false
end)
-- Create a taglist widget
-- s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
-- Create an icon taglist
-- local icon_taglist = require("noodle.icon_taglist")
-- Create a custom text taglist
local text_taglist = require("noodle.text_taglist")
-- Create text weather widget
local text_weather = require("noodle.text_weather")
local weather_widget_icon = text_weather:get_all_children()[1]
> local weather_widget_icon = text_weather:get_all_children()[1]
weather_widget_icon.font = "Typicons 11"
local weather_widget_text = text_weather:get_all_children()[2]
weather_widget_text.font = "sans 9"
-- Create a widget that displays window buttons (close, maximize, minimize)
-- Create a window control widget
local close_button = wibox.widget.textbox()
close_button.font = "Typicons 11"
close_button.markup = helpers.colorize_text("", beautiful.xcolor1)
@ -153,7 +124,7 @@ awful.screen.connect_for_each_screen(function(s)
}
window_buttons:buttons(gears.table.join(
awful.button({ }, 2, function ()
awful.spawn.with_shell("rofi -show windowcd")
awful.spawn.with_shell("rofi -matching fuzzy -show windowcd")
end),
awful.button({ }, 4, function ()
awful.client.focus.byidx(-1)
@ -176,7 +147,7 @@ awful.screen.connect_for_each_screen(function(s)
spacing = dpi(12),
layout = wibox.layout.fixed.horizontal
},
text_taglist,
s.mytaglist,
window_buttons,
expand = "none",
layout = wibox.layout.align.horizontal
@ -185,9 +156,18 @@ end)
local s = mouse.screen
-- Show traybox when the mouse touches the rightmost edge of the wibar
-- TODO fix for wibar_position = "top"
traybox_activator = wibox({ x = s.geometry.width - 1, y = s.geometry.height - beautiful.wibar_height, height = beautiful.wibar_height, width = 1, opacity = 0, visible = true, bg = beautiful.wibar_bg })
traybox_activator:connect_signal("mouse::enter", function ()
-- awful.screen.focused().traybox.visible = true
s.traybox.visible = true
end)
-- Every bar theme should provide these fuctions
function toggle_wibars()
local s = awful.screen.focused()
s.mywibox.visible = not s.mywibox.visible
end
function toggle_tray()
local s = awful.screen.focused()
s.traybox.visible = not s.traybox.visible
end

View file

@ -0,0 +1,51 @@
-- Provides:
-- evil::battery
-- percentage (integer)
-- evil::charger
-- plugged (boolean)
--
local awful = require("awful")
local update_interval = 30
local battery_script = [[
sh -c "
upower -i $(upower -e | grep BAT) | grep percentage | awk '{print $2}'
"]]
-- Subscribe to power supply status changes with acpi_listen
local charger_script = [[
sh -c '
acpi_listen | grep --line-buffered ac_adapter
']]
-- Periodically get battery info
awful.widget.watch(battery_script, update_interval, function(widget, stdout)
local battery = stdout:gsub("%%", "")
awesome.emit_signal("evil::battery", tonumber(battery))
end)
local emit_charger_info = function()
awful.spawn.easy_async_with_shell("cat /sys/class/power_supply/*/online", function (out)
status = tonumber(out)
if status == 1 then
awesome.emit_signal("evil::charger", true)
else
awesome.emit_signal("evil::charger", false)
end
end)
end
-- Run once to initialize widgets
emit_charger_info()
-- Kill old acpi_listen process
awful.spawn.easy_async_with_shell("ps x | grep \"acpi_listen\" | grep -v grep | awk '{print $1}' | xargs kill", function ()
-- Update charger status with each line printed
awful.spawn.with_line_callback(charger_script, {
stdout = function(_)
emit_charger_info()
end
})
end)

View file

@ -0,0 +1,38 @@
-- Provides:
-- evil::brightness
-- percentage (integer)
local awful = require("awful")
-- Subscribe to backlight changes
-- Requires inotify-tools
local brightness_subscribe_script = [[
bash -c "
while (inotifywait -e modify /sys/class/backlight/?**/brightness -qq) do echo; done
"]]
local brightness_script = [[
sh -c "
light -G
"]]
local emit_brightness_info = function()
awful.spawn.with_line_callback(brightness_script, {
stdout = function(line)
percentage = math.floor(tonumber(line))
awesome.emit_signal("evil::brightness", percentage)
end
})
end
-- Run once to initialize widgets
emit_brightness_info()
-- Kill old inotifywait process
awful.spawn.easy_async_with_shell("ps x | grep \"inotifywait -e modify /sys/class/backlight\" | grep -v grep | awk '{print $1}' | xargs kill", function ()
-- Update brightness status with each line printed
awful.spawn.with_line_callback(brightness_subscribe_script, {
stdout = function(_)
emit_brightness_info()
end
})
end)

View file

@ -0,0 +1,18 @@
-- Provides:
-- evil::cpu
-- used percentage (integer)
local awful = require("awful")
local update_interval = 5
local cpu_idle_script = [[
sh -c "
vmstat 1 2 | tail -1 | awk '{printf \"%d\", $15}'
"]]
-- Periodically get cpu info
awful.widget.watch(cpu_idle_script, update_interval, function(widget, stdout)
-- local cpu_idle = stdout:match('+(.*)%.%d...(.*)%(')
local cpu_idle = stdout
cpu_idle = string.gsub(cpu_idle, '^%s*(.-)%s*$', '%1')
awesome.emit_signal("evil::cpu", 100 - tonumber(cpu_idle))
end)

View file

@ -0,0 +1,12 @@
-- evil = {}
require("evil.volume")
require("evil.battery")
require("evil.cpu")
require("evil.temperature")
require("evil.ram")
require("evil.weather")
require("evil.mpd")
require("evil.brightness")
-- return evil

View file

@ -0,0 +1,46 @@
-- Provides:
-- evil::mpd
-- artist (string)
-- song (string)
-- paused (boolean)
local awful = require("awful")
local function emit_info()
awful.spawn.easy_async({"mpc", "-f", "[[%artist%@@%title%@]]"},
function(stdout)
local artist = stdout:match('(.*)@@')
local title = stdout:match('@@(.*)@')
title = string.gsub(title, '^%s*(.-)%s*$', '%1')
local status = stdout:match('%[(.*)%]')
status = string.gsub(status, '^%s*(.-)%s*$', '%1')
local paused
if status == "playing" then
paused = false
else
paused = true
end
awesome.emit_signal("evil::mpd", artist, title, paused)
end
)
end
-- Run once to initialize widgets
emit_info()
-- Sleeps until mpd changes state (pause/play/next/prev)
local mpd_script = [[
sh -c '
mpc idleloop player
']]
-- Kill old mpc idleloop player process
awful.spawn.easy_async_with_shell("ps x | grep \"mpc idleloop player\" | grep -v grep | awk '{print $1}' | xargs kill", function ()
-- Emit song info with each line printed
awful.spawn.with_line_callback(mpd_script, {
stdout = function(line)
emit_info()
end
})
end)

View file

@ -0,0 +1,20 @@
-- Provides:
-- evil::ram
-- used (integer - mega bytes)
-- total (integer - mega bytes)
local awful = require("awful")
local update_interval = 20
-- Returns the used amount of ram in percentage
local ram_script = [[
sh -c "
free -m | grep 'Mem:' | awk '{printf \"%d@@%d@\", $7, $2}'
"]]
-- Periodically get ram info
awful.widget.watch(ram_script, update_interval, function(widget, stdout)
local available = stdout:match('(.*)@@')
local total = stdout:match('@@(.*)@')
local used = tonumber(total) - tonumber(available)
awesome.emit_signal("evil::ram", used, tonumber(total))
end)

View file

@ -0,0 +1,15 @@
-- Provides:
-- evil::temperature
-- temperature (integer - in Celcius)
local awful = require("awful")
local update_interval = 15
local temp_script = [[
sh -c "
sensors | grep Package | awk '{print $4}' | cut -c 2-3
"]]
-- Periodically get temperature info
awful.widget.watch(temp_script, update_interval, function(widget, stdout)
awesome.emit_signal("evil::temperature", tonumber(stdout))
end)

View file

@ -0,0 +1,74 @@
-- Provides:
-- evil::volume
-- volume percentage (integer)
-- muted (boolean)
-- evil::microphone
-- muted (boolean)
local awful = require("awful")
local function emit_volume_info()
-- Get volume info
awful.spawn.easy_async("pactl list sinks",
function(stdout)
local volume = stdout:match('(%d+)%% /')
local muted = stdout:match('Mute:(%s+)[yes]')
if muted ~= nil then
awesome.emit_signal("evil::volume", tonumber(volume), true)
else
awesome.emit_signal("evil::volume", tonumber(volume), false)
end
end
)
end
local function emit_microphone_info()
-- Use tail to grab the last line of the output (which refers to the microphone)
awful.spawn.easy_async_with_shell("pacmd list-sources | grep muted | tail -1 | awk '{print $2}'",
function(stdout)
-- Remove trailing whitespace
muted = stdout:gsub('^%s*(.-)%s*$', '%1')
if muted == "yes" then
awesome.emit_signal("evil::microphone", true)
else
awesome.emit_signal("evil::microphone", false)
end
end
)
end
-- Run once to initialize widgets
emit_volume_info()
emit_microphone_info()
-- Sleeps until pactl detects an event (volume up/down/toggle mute)
local volume_script = [[
bash -c '
pactl subscribe 2> /dev/null | grep --line-buffered "sink"
']]
-- Sleeps until pactl detects an event (microphone volume up / down / (un)mute)
local microphone_script = [[
bash -c '
pactl subscribe 2> /dev/null | grep --line-buffered "source"
']]
-- Kill old pactl subscribe processes
awful.spawn.easy_async_with_shell("ps x | grep \"pactl subscribe\" | grep -v grep | awk '{print $1}' | xargs kill", function ()
-- Run emit_volume_info() with each line printed
awful.spawn.with_line_callback(volume_script, {
stdout = function(line)
emit_volume_info()
end
})
-- Run emit_microphone_info() with each line printed
awful.spawn.with_line_callback(microphone_script, {
stdout = function(line)
emit_microphone_info()
end
})
end)

View file

@ -0,0 +1,50 @@
-- Provides:
-- evil::weather
-- temperature (integer)
-- description (string)
-- icon_code (string)
local awful = require("awful")
-- Configuration
local key = user.openweathermap_key
local city_id = user.openweathermap_city_id
local units = user.weather_units
-- Don't update too often, because your requests might get blocked for 24 hours
local update_interval = 1200
local weather_details_script = [[
bash -c '
KEY="]]..key..[["
CITY="]]..city_id..[["
UNITS="]]..units..[["
weather=$(curl -sf "http://api.openweathermap.org/data/2.5/weather?APPID=$KEY&id=$CITY&units=$UNITS")
if [ ! -z "$weather" ]; then
weather_temp=$(echo "$weather" | jq ".main.temp" | cut -d "." -f 1)
weather_icon=$(echo "$weather" | jq -r ".weather[].icon" | head -1)
weather_description=$(echo "$weather" | jq -r ".weather[].description" | head -1)
echo "$weather_icon" "$weather_description"@@"$weather_temp"
else
echo "..."
fi
']]
-- Periodically get weather info
awful.widget.watch(weather_details_script, update_interval, function(widget, stdout)
local icon_code = string.sub(stdout, 1, 3)
local weather_details = string.sub(stdout, 5)
weather_details = string.gsub(weather_details, '^%s*(.-)%s*$', '%1')
-- Replace "-0" with "0" degrees
weather_details = string.gsub(weather_details, '%-0', '0')
-- Capitalize first letter of the description
weather_details = weather_details:sub(1,1):upper()..weather_details:sub(2)
local description = weather_details:match('(.*)@@')
local temperature = weather_details:match('@@(.*)')
if icon_code == "..." then
awesome.emit_signal("evil::weather", 999, "Weather unavailable", "")
else
awesome.emit_signal("evil::weather", tonumber(temperature), description, icon_code)
end
end)

View file

@ -1,3 +1,5 @@
-- Functions that you use more than once and in different files would
-- be nice to define here.
local awful = require("awful")
local gears = require("gears")
local beautiful = require("beautiful")
@ -5,48 +7,20 @@ local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
local wibox = require("wibox")
local naughty = require("naughty")
local helpers = {}
-- Create rounded rectangle shape
-- Create rounded rectangle shape (in one line)
helpers.rrect = function(radius)
return function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, radius)
--gears.shape.octogon(cr, width, height, radius)
--gears.shape.rounded_bar(cr, width, height)
end
end
helpers.rbar = function()
return function(cr, width, height)
gears.shape.rounded_bar(cr, width, height)
end
end
helpers.prrect = function(radius, tl, tr, br, bl)
return function(cr, width, height)
gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius)
end
end
-- Create info bubble shape
-- TODO
helpers.infobubble = function(radius)
return function(cr, width, height)
gears.shape.infobubble(cr, width, height, radius)
end
end
-- Create rectangle shape
helpers.rect = function()
return function(cr, width, height)
gears.shape.rectangle(cr, width, height)
end
end
-- Create circle shape
helpers.circle = function()
return function(cr, width, height)
gears.shape.circle(cr, width, height)
gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius)
end
end
@ -77,99 +51,77 @@ function helpers.pad(size)
end
function helpers.move_to_edge(c, direction)
local workarea = awful.screen.focused().workarea
local client_geometry = c:geometry()
-- local workarea = awful.screen.focused().workarea
-- local client_geometry = c:geometry()
if direction == "up" then
c:geometry({ nil, y = workarea.y + beautiful.screen_margin * 2, nil, nil })
local old_x = c:geometry().x
awful.placement.top(c, {honor_padding = true, honor_workarea = true, honor_padding = true})
c.x = old_x
-- c:geometry({ nil, y = workarea.y + beautiful.screen_margin * 2, nil, nil })
elseif direction == "down" then
c:geometry({ nil, y = workarea.height + workarea.y - client_geometry.height - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil })
local old_x = c:geometry().x
awful.placement.bottom(c, {honor_padding = true, honor_workarea = true, honor_padding = true})
c.x = old_x
-- c:geometry({ nil, y = workarea.height + workarea.y - client_geometry.height - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil })
elseif direction == "left" then
c:geometry({ x = workarea.x + beautiful.screen_margin * 2, nil, nil, nil })
local old_y = c:geometry().y
awful.placement.left(c, {honor_padding = true, honor_workarea = true, honor_padding = true})
c.y = old_y
-- c:geometry({ x = workarea.x + beautiful.screen_margin * 2, nil, nil, nil })
elseif direction == "right" then
c:geometry({ x = workarea.width + workarea.x - client_geometry.width - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil, nil })
local old_y = c:geometry().y
awful.placement.right(c, {honor_padding = true, honor_workarea = true, honor_padding = true})
c.y = old_y
-- c:geometry({ x = workarea.width + workarea.x - client_geometry.width - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil, nil })
end
end
function helpers.create_titlebar(c, titlebar_buttons, titlebar_position, titlebar_size)
awful.titlebar(c, {font = beautiful.titlebar_font, position = titlebar_position, size = titlebar_size}) : setup {
{
buttons = titlebar_buttons,
layout = wibox.layout.fixed.horizontal
},
{
buttons = titlebar_buttons,
layout = wibox.layout.fixed.horizontal
},
{
buttons = titlebar_buttons,
layout = wibox.layout.fixed.horizontal
},
layout = wibox.layout.align.horizontal
}
end
local double_tap_timer = nil
function helpers.single_double_tap(single_tap_function, double_tap_function)
if double_tap_timer then
double_tap_timer:stop()
double_tap_timer = nil
double_tap_function()
-- naughty.notify({text = "We got a double tap"})
return
end
double_tap_timer =
gears.timer.start_new(0.20, function()
double_tap_timer = nil
-- naughty.notify({text = "We got a single tap"})
single_tap_function()
return false
end)
end
function helpers.toggle_scratchpad()
local screen = awful.screen.focused()
-- Get rid of it if it is focused
if client.focus ~= nil and client.focus.class == "scratchpad" then
-- 1. Minimize scratchpad - Does not work?
-- client.focus.minimized = true
-- 2. Move scratchpad to "Miscellaneous" tag
local tag = screen.tags[10]
if tag then
client.focus:move_to_tag(tag)
end
if double_tap_timer then
double_tap_timer:stop()
double_tap_timer = nil
double_tap_function()
-- naughty.notify({text = "We got a double tap"})
return
end
-- Move scratchpad to current tag
local current_tag = screen.selected_tag
local scratchpad_client = function (c)
return awful.rules.match(c, {class = "scratchpad"})
end
for c in awful.client.iterate(scratchpad_client) do
c.minimized = false
c:move_to_tag(current_tag)
client.focus = c
c:raise()
end
-- if client.focus ~= nil and client.focus.class == "scratchpad" then
-- client.focus.minimized = true
-- return
-- end
-- local matcher = function (c)
-- return awful.rules.match(c, {class = 'scratchpad'})
-- end
-- awful.client.run_or_raise( "scratchpad" , matcher)
double_tap_timer =
gears.timer.start_new(0.20, function()
double_tap_timer = nil
-- naughty.notify({text = "We got a single tap"})
if single_tap_function then
single_tap_function()
end
return false
end)
end
-- Add a clickable effect on a widget by changing the cursor on mouse::enter and mouse::leave
function helpers.add_clickable_effect(w)
-- Used as a custom command in rofi to move a window into the current tag
-- instead of following it.
-- Rofi has access to the X window id of the client.
function helpers.rofi_move_client_here(window)
local win = function (c)
return awful.rules.match(c, {window = window})
end
for c in awful.client.iterate(win) do
c.minimized = false
c:move_to_tag(mouse.screen.selected_tag)
client.focus = c
c:raise()
end
end
-- Add a hover cursor to a widget by changing the cursor on
-- mouse::enter and mouse::leave
-- You can find the names of the available cursors by opening any
-- cursor theme and looking in the "cursors folder"
-- For example: "hand1" is the cursor that appears when hovering over
-- links
function helpers.add_hover_cursor(w, hover_cursor)
local original_cursor = "left_ptr"
local hover_cursor = "hand1"
w:connect_signal("mouse::enter", function ()
local w = _G.mouse.current_wibox
@ -186,4 +138,320 @@ function helpers.add_clickable_effect(w)
end)
end
-- Tag back and forth:
-- If you try to focus the same tag you are at, go back to the previous tag.
-- Useful for quick switching after for example checking an incoming chat
-- message at tag 2 and coming back to your work at tag 1 with the same
-- keypress
function helpers.tag_back_and_forth(tag_index)
local s = mouse.screen
local tag = s.tags[tag_index]
if tag then
if tag == s.selected_tag then
awful.tag.history.restore()
else
tag:view_only()
end
end
end
-- Resize DWIM (Do What I Mean)
-- Resize client or factor
-- Constants --
local floating_resize_amount = dpi(20)
local tiling_resize_factor= 0.05
---------------
function helpers.resize_dwim(c, direction)
if awful.layout.get(mouse.screen) == awful.layout.suit.floating or (c and c.floating) then
if direction == "up" then
c:relative_move( 0, 0, 0, -floating_resize_amount)
elseif direction == "down" then
c:relative_move( 0, 0, 0, floating_resize_amount)
elseif direction == "left" then
c:relative_move( 0, 0, -floating_resize_amount, 0)
elseif direction == "right" then
c:relative_move( 0, 0, floating_resize_amount, 0)
end
else
if direction == "up" then
awful.client.incwfact(-tiling_resize_factor)
elseif direction == "down" then
awful.client.incwfact( tiling_resize_factor)
elseif direction == "left" then
awful.tag.incmwfact(-tiling_resize_factor)
elseif direction == "right" then
awful.tag.incmwfact( tiling_resize_factor)
end
end
end
-- Move client to screen edge, respecting the screen workarea
function helpers.move_to_edge(c, direction)
local workarea = awful.screen.focused().workarea
if direction == "up" then
c:geometry({ nil, y = workarea.y + beautiful.useless_gap * 2, nil, nil })
elseif direction == "down" then
c:geometry({ nil, y = workarea.height + workarea.y - c:geometry().height - beautiful.useless_gap * 2 - beautiful.border_width * 2, nil, nil })
elseif direction == "left" then
c:geometry({ x = workarea.x + beautiful.useless_gap * 2, nil, nil, nil })
elseif direction == "right" then
c:geometry({ x = workarea.width + workarea.x - c:geometry().width - beautiful.useless_gap * 2 - beautiful.border_width * 2, nil, nil, nil })
end
end
-- Move client DWIM (Do What I Mean)
-- Move to edge if the client / layout is floating
-- Swap by index if maximized
-- Else swap client by direction
function helpers.move_client_dwim(c, direction)
if c.floating or (awful.layout.get(mouse.screen) == awful.layout.suit.floating) then
helpers.move_to_edge(c, direction)
elseif awful.layout.get(mouse.screen) == awful.layout.suit.max then
if direction == "up" or direction == "left" then
awful.client.swap.byidx(-1, c)
elseif direction == "down" or direction == "right" then
awful.client.swap.byidx(1, c)
end
else
awful.client.swap.bydirection(direction, c, nil)
end
end
-- Make client floating and snap to the desired edge
function helpers.float_and_edge_snap(c, direction)
-- if not c.floating then
-- c.floating = true
-- end
naughty.notify({ text = "double tap"})
c.floating = true
local workarea = awful.screen.focused().workarea
if direction == "up" then
local axis = 'horizontally'
local f = awful.placement.scale
+ awful.placement.top
+ (axis and awful.placement['maximize_'..axis] or nil)
local geo = f(client.focus, {honor_padding = true, honor_workarea=true, to_percent = 0.5})
elseif direction == "down" then
local axis = 'horizontally'
local f = awful.placement.scale
+ awful.placement.bottom
+ (axis and awful.placement['maximize_'..axis] or nil)
local geo = f(client.focus, {honor_padding = true, honor_workarea=true, to_percent = 0.5})
elseif direction == "left" then
local axis = 'vertically'
local f = awful.placement.scale
+ awful.placement.left
+ (axis and awful.placement['maximize_'..axis] or nil)
local geo = f(client.focus, {honor_padding = true, honor_workarea=true, to_percent = 0.5})
elseif direction == "right" then
local axis = 'vertically'
local f = awful.placement.scale
+ awful.placement.right
+ (axis and awful.placement['maximize_'..axis] or nil)
local geo = f(client.focus, {honor_padding = true, honor_workarea=true, to_percent = 0.5})
end
end
-- Rounds a number to any number of decimals
function helpers.round(number, decimals)
local power = 10 ^ decimals
return math.floor(number * power) / power
end
local volume_get_cmd = "pactl list sinks | grep -m 1 'Volume:' | awk '{print $5}' | cut -d '%' -f1 "
local muted_get_cmd = "pactl list sinks | grep -m 1 'Mute:' | awk '{printf \"%s\", $2}'"
local volume_notif
function helpers.volume_control(step)
local cmd
if step == 0 then
-- Toggle mute
cmd = "pactl set-sink-mute @DEFAULT_SINK@ toggle && "..muted_get_cmd
awful.spawn.with_shell(cmd)
-- awful.spawn.easy_async_with_shell(cmd, function(out)
-- local text
-- if out:match('yes') then
-- text = "Muted"
-- else
-- text = "Unmuted"
-- end
-- if not sidebar.visible then
-- if volume_notif and not volume_notif.is_expired then
-- volume_notif.message = text
-- else
-- volume_notif = naughty.notification({ title = "Volume", message = text, timeout = 2 })
-- end
-- end
-- end)
else
if step > 0 then
sign = "+"
else
sign = ""
end
cmd = "pactl set-sink-mute @DEFAULT_SINK@ 0 && pactl set-sink-volume @DEFAULT_SINK@ "..sign..tostring(step).."% && "..volume_get_cmd
awful.spawn.easy_async_with_shell(cmd, function(out)
print(out)
out = out:gsub('^%s*(.-)%s*$', '%1')
print(out)
if not sidebar.visible then
if volume_notif and not volume_notif.is_expired then
volume_notif.message = out
else
volume_notif = naughty.notification({ title = "Volume", message = out, timeout = 2 })
end
end
end)
end
end
-- TODO: notification action buttons
function helpers.screenshot(action, delay)
local cmd
local timestamp = os.date("%Y.%m.%d-%H.%M.%S")
local filename = user.screenshot_dir..timestamp..".screenshot.png"
-- local filename = user.screenshot_dir.."screenshot"..timestamp..".png"
local maim_args = "-u -b 3 -m 5"
local icon = icons.screenshot
local prefix
if delay then
prefix = "sleep "..tostring(delay).." && "
else
prefix = ""
end
if action == "full" then
cmd = prefix.."maim "..maim_args.." "..filename
print(filename)
awful.spawn.easy_async_with_shell(cmd, function(_, __, ___, ____)
naughty.notify({ title = "Screenshot", message = "Screenshot taken", icon = icon })
end)
elseif action == "selection" then
cmd = "maim "..maim_args.." -s "..filename
naughty.notify({ title = "Screenshot", message = "Select area to capture.", icon = icon })
awful.spawn.easy_async_with_shell(cmd, function(_, __, ___, exit_code)
if exit_code == 0 then
naughty.notify({ title = "Screenshot", message = "Selection captured", icon = icon })
end
end)
elseif action == "clipboard" then
naughty.notify({ title = "Screenshot", message = "Select area to copy to clipboard.", icon = icon })
cmd = "maim "..maim_args.." -s /tmp/maim_clipboard && xclip -selection clipboard -t image/png /tmp/maim_clipboard && rm /tmp/maim_clipboard"
awful.spawn.easy_async_with_shell(cmd, function(_, __, ___, exit_code)
if exit_code == 0 then
naughty.notify({ title = "Screenshot", message = "Copied selection to clipboard", icon = icon })
end
end)
elseif action == "browse" then
awful.spawn.with_shell("cd "..user.screenshot_dir.." && feh $(ls -t)")
elseif action == "gimp" then
awful.spawn.with_shell("cd "..user.screenshot_dir.." && gimp $(ls -t | head -n1)")
naughty.notify({ message = "Opening last screenshot with GIMP", icon = icon })
end
end
local prompt_font = beautiful.prompt_font or "sans bold 8"
function helpers.prompt(action, textbox, prompt, callback)
if action == "run" then
awful.prompt.run {
prompt = prompt,
-- prompt = "<b>Run: </b>",
textbox = textbox,
font = prompt_font,
done_callback = callback,
exe_callback = awful.spawn,
completion_callback = awful.completion.shell,
history_path = awful.util.get_cache_dir() .. "/history"
}
elseif action == "web_search" then
awful.prompt.run {
prompt = prompt,
-- prompt = '<b>Web search: </b>',
textbox = textbox,
font = prompt_font,
history_path = awful.util.get_cache_dir() .. "/history_web",
done_callback = callback,
exe_callback = function(input)
if not input or #input == 0 then return end
awful.spawn(user.web_search_cmd.."\""..input.."\"")
naughty.notify { title = "Searching the web for", text = input, icon = icons.firefox }
end
}
end
end
function helpers.run_or_raise(match, move, spawn_cmd, spawn_args)
local matcher = function (c)
return awful.rules.match(c, match)
end
-- Find and raise
local found = false
for c in awful.client.iterate(matcher) do
found = true
c.minimized = false
if move then
c:move_to_tag(mouse.screen.selected_tag)
client.focus = c
c:raise()
else
c:jump_to()
end
-- -- Return if found
-- return
-- -- This would normally work, but some terminals (*cough* termite)
-- -- create 2 instances of the same class, for just one window.
-- -- So it is not reliable. We will use the helper variable "found"
-- -- instead in order to determine if we have raised the window.
end
-- Spawn if not found
if not found then
awful.spawn(spawn_cmd, spawn_args)
end
end
function helpers.toggle_scratchpad()
local screen = awful.screen.focused()
-- Get rid of it if it is focused
local cf = client.focus
if cf and cf.class == "scratchpad" then
-- 1. Minimize scratchpad
cf.minimized = true
-- 2. Move scratchpad to "Miscellaneous" tag
-- local tag = screen.tags[10]
-- if tag then
-- client.focus:move_to_tag(tag)
-- end
else
helpers.run_or_raise({class = "scratchpad"}, true, "scratchpad")
end
end
function helpers.toggle_night_mode()
local cmd = "pgrep redshift > /dev/null && (pkill redshift && echo 'OFF') || (echo 'ON' && redshift -l 0:0 -t 3700:3700 -r &>/dev/null &)"
awful.spawn.easy_async_with_shell(cmd, function(out)
if out:match('ON') then
naughty.notify({ title = "Night mode", message = "Activated!" })
else
naughty.notify({ title = "Night mode", message = "Deactivated!" })
end
end)
end
function helpers.float_and_resize(c, width, height)
c.width = width
c.height = height
awful.placement.centered(c,{honor_workarea=true, honor_padding = true})
awful.client.property.set(c, 'floating_geometry', c:geometry())
c.floating = true
c:raise()
end
return helpers

View file

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before After
Before After

View file

@ -0,0 +1,96 @@
local gears = require("gears")
local function file_exists(path)
-- Try to open it
local f = io.open(path)
if f then
f:close()
return true
end
return false
end
local icons = {}
-- TODO layout icons
-- TODO tag icons
-- Available icons
local icon_names = {
"playerctl_toggle",
"playerctl_prev",
"playerctl_next",
"stats",
"search",
"volume",
"muted",
"mpd",
"firefox",
"youtube",
"reddit",
"discord",
"telegram",
"steam",
"games",
"files",
"manual",
"keyboard",
"appearance",
"editor",
"redshift",
"gimp",
"terminal",
"mail",
"music",
"temperature",
"battery",
"battery_charging",
"cpu",
"compositor",
"start",
"ram",
"screenshot",
"home",
"alarm",
"alarm_off",
"alert",
"submenu",
-- Weather icons
"cloud",
"dcloud",
"ncloud",
"sun",
"star",
"rain",
"snow",
"mist",
"storm",
"whatever",
-- Exit screen icons
"exit",
"poweroff",
"reboot",
"suspend",
"lock",
}
-- Path to icons
local p
-- Assumes all the icon files end in .png
-- Which they should if you need transparency
local function set_icon(icon_name)
local i = p..icon_name..".png"
icons[icon_name] = i
end
-- Set all the icon variables
function icons.init(theme_name)
-- Set the path to icons
p = gears.filesystem.get_configuration_dir().."icons/"..theme_name.."/"
for i = 1, #icon_names do
set_icon(icon_names[i])
end
end
return icons

View file

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before After
Before After

Some files were not shown because too many files have changed in this diff Show more