diff --git a/README.md b/README.md deleted file mode 100644 index 57423f4..0000000 --- a/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Vincent Bernat's awesome configuration - -This is my [awesome](http://awesome.naquadah.org) configuration. It -does not exactly feature the same keybindings as the default -configuration. I don't recommend using it by you can pick anything you -need in it. - -This configuration is for _awesome_ 3.4. I did not update to 3.5 -yet. Have a look at -[@P-EB pull request](https://github.com/vincentbernat/awesome-configuration/pull/5) -for 3.5 support. - -Here some of the things you may be interested in: - - - It is modular. I am using `config` as a table to pass different - things between "modules". - - - I use a light transparency effect to tell if a window has the focus - or not. It needs a composite manager. - - - I use a Python script `bin/build-wallpaper` to build the wallpaper - to be displayed. There is a random selection and it works with - multihead setup. It seems that classic tools are now able to change - the wallpaper per screen and therefore, the script may seem a bit - useless but I keep it. - - - I am using `xss-lock` with `i3lock` as a screensaver. It relies on - standard X screensaver handling (and therefore is easy for - application to disable) and also supports systemd - inhibitors. Nothing fancy but I reuse the wallpaper built above. A - notification is sent 10 seconds before starting. - - - In `rc/apparance.lua`, you may be interested by the way I configure - GTK2 and GTK3 to have an unified look. It works and it does not - need `gnome-control-center`. - - - I have rebuilt my own implementation of the Quake console in - `lib/quake.lua`. The common ones didn't like when awesome was - restarted. - - - I am using notifications when changing volume or brightness. I am - also using notifications to change xrandr setup. This is pretty - cool. - - - Keybindings are "autodocumented". See `lib/keydoc.lua` to see how - this works. The list of key bindings can be accessed with Mod4 + - F1. - - - On the debug front, I am quite happy with `dbg()` in - `rc/debug.lua`. - - - Many stuff is handled by systemd. The session is still expected to - be handled by Xsession but we invoke a custom display-specific - `xsession@.target` which binds to a display-specific - `graphical-session@.target`. This is different from the - `graphical-session.target` shipped by distributions because I - wanted it to be display-specific. Also, unit activation is bundled - directly into `graphical-session@.target` while dependencies are - mostly handled in `awesome@.service`. - -Also, I am using my custom terminal (`vbeterm`). You need to change -that in `rc.lua`. You can also find the sources on -[GitHub](https://github.com/vincentbernat/vbeterm). - -Things in `lib/` are meant to be reused. I am using my own `loadrc()` -function to load modules and therefore, I prefix my modules with -`vbe/`. Before reusing a module, you may want to change this. Another -way to load them is to use: - - require("lib/quake") - local quake = package.loaded["vbe/quake"] - -## Requirements - -Required Debian packages to make everything work can be found in my -[Puppet configuration][]. - -[Puppet configuration]: https://github.com/vincentbernat/puppet-workstation/blob/master/local-modules/desktop/manifests/awesome.pp diff --git a/bin/input-event b/bin/input-event index 747dd65..486560b 100755 --- a/bin/input-event +++ b/bin/input-event @@ -9,8 +9,8 @@ name="$4" # Load the given keymap xkb() { - xkbcomp -i ${device} -w 0 -I$HOME/.config/awesome/xkb \ - $HOME/.config/awesome/xkb/$1.xkb ${DISPLAY} + xkbcomp -i ${device} -w 0 -I$HOME/.config/i3/dotfiles/xkb \ + $HOME/.config/i3/dotfiles/xkb/$1.xkb ${DISPLAY} } case $event in @@ -30,7 +30,7 @@ case "$event,$use,$(uname -n),$name" in done ;; *,XISlaveKeyboard,zoro,"AT Translated Set 2 keyboard") - xkb x1 + xkb x1gen2 ;; *,XISlaveKeyboard,*,"ThinkPad Extra Buttons") xkb thinkpad-extra diff --git a/bin/xsettingsd-setup b/bin/xsettingsd-setup index 583afaf..2c0ea2b 100755 --- a/bin/xsettingsd-setup +++ b/bin/xsettingsd-setup @@ -33,15 +33,12 @@ xrandr --dpi $dpi # Build xsettingsd { - cat ~/.config/awesome/xsettingsd + cat ~/.config/i3/xsettingsd echo Xft/DPI $(( $dpi*1024 )) echo Xft/RGBA \"$( [ $dpi -gt 144 ] && echo none || echo rgb )\" echo Gdk/WindowScalingFactor $(( $dpi/96 )) echo Gdk/UnscaledDPI $(( $dpi*1024/($dpi/96) )) } > ~/.xsettingsd -# Signal xsettingsd -systemctl --user reload xsettingsd@$(systemd-escape -- "$DISPLAY").service - # Also use xrdb for very old stuff (you know, LibreOffice) echo Xft.dpi: $dpi | xrdb -merge diff --git a/bin/xss-lock b/bin/xss-lock index a924f19..6fc65f3 100755 --- a/bin/xss-lock +++ b/bin/xss-lock @@ -40,7 +40,7 @@ case "$1" in # First, pause any music player playerctl -a pause # Then, lock screen - i3lock -n -e -i $HOME/.cache/awesome/current-wallpaper-${display}.png -t -f + i3lock -n -e -i $HOME/.cache/i3/current-wallpaper.png -t -f echo "lock: unlock screen" ;; esac diff --git a/config b/config new file mode 100644 index 0000000..688d1b8 --- /dev/null +++ b/config @@ -0,0 +1,119 @@ +# i3 config file (v4) + +set $up k +set $down j +set $left h +set $right l +set $mod Mod4 +set $term vbeterm + +font pango:Terminus 9 + +# Style +default_border pixel 3 +default_floating_border pixel 3 + +# Use pactl to adjust volume in PulseAudio. +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle +bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle + +# use Mouse+$mod to drag floating windows to their wanted position +floating_modifier $mod + +# start a terminal +bindsym $mod+Return exec $term + +# kill focused window +bindsym $mod+x kill + +# execute command +bindsym $mod+r exec --no-startup-id dmenu_run + +# change focus +bindsym $mod+$left focus left +bindsym $mod+$down focus down +bindsym $mod+$up focus up +bindsym $mod+$right focus right + +# move focused window +bindsym $mod+Shift+$left move left +bindsym $mod+Shift+$down move down +bindsym $mod+Shift+$up move up +bindsym $mod+Shift+$right move right + +# resize focused window +bindsym $mod+Ctrl+$left resize shrink width 10 px or 10 ppt +bindsym $mod+Ctrl+$down resize grow height 10 px or 10 ppt +bindsym $mod+Ctrl+$up resize shrink height 10 px or 10 ppt +bindsym $mod+Ctrl+$right resize grow width 10 px or 10 ppt + +# change split orientation +bindsym $mod+v split toggle + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout toggle split + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# focus the parent container +bindsym $mod+a focus parent + +# Define names for default workspaces for which we configure key bindings later on. +# We use variables to avoid repeating the names in multiple places. +set $ws1 "1" +set $ws2 "2" +set $ws3 "3" +set $ws4 "4" +set $ws5 "5" +set $ws6 "6" +set $ws7 "7" +set $ws8 "8" +set $ws9 "9" +set $ws10 "10" + +# switch to workspace +bindsym $mod+1 workspace number $ws1 +bindsym $mod+2 workspace number $ws2 +bindsym $mod+3 workspace number $ws3 +bindsym $mod+4 workspace number $ws4 +bindsym $mod+5 workspace number $ws5 +bindsym $mod+6 workspace number $ws6 +bindsym $mod+7 workspace number $ws7 +bindsym $mod+8 workspace number $ws8 +bindsym $mod+9 workspace number $ws9 +bindsym $mod+0 workspace number $ws10 +bindsym $mod+Tab workspace back_and_forth + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace number $ws1 +bindsym $mod+Shift+2 move container to workspace number $ws2 +bindsym $mod+Shift+3 move container to workspace number $ws3 +bindsym $mod+Shift+4 move container to workspace number $ws4 +bindsym $mod+Shift+5 move container to workspace number $ws5 +bindsym $mod+Shift+6 move container to workspace number $ws6 +bindsym $mod+Shift+7 move container to workspace number $ws7 +bindsym $mod+Shift+8 move container to workspace number $ws8 +bindsym $mod+Shift+9 move container to workspace number $ws9 +bindsym $mod+Shift+0 move container to workspace number $ws10 + +# reload/restart +bindsym $mod+Shift+c reload +bindsym $mod+Shift+r restart + +# Lock screen +bindsym XF86ScreenSaver exec --no-startup-id xset s activate +bindsym $mod+Delete exec --no-startup-id xset s activate + +# start stuff +exec_always --no-startup-id systemctl --user start --no-block wallpaper.service diff --git a/Xresources b/dotfiles/Xresources similarity index 100% rename from Xresources rename to dotfiles/Xresources diff --git a/firefox.js b/dotfiles/firefox.js similarity index 100% rename from firefox.js rename to dotfiles/firefox.js diff --git a/dotfiles/gtkrc-2.0 b/dotfiles/gtkrc-2.0 new file mode 100644 index 0000000..ee7a5f1 --- /dev/null +++ b/dotfiles/gtkrc-2.0 @@ -0,0 +1,27 @@ +gtk-theme-name="Adwaita-dark" +gtk-icon-theme-name="Adwaita" +gtk-cursor-theme-name="Adwaita" +gtk-cursor-theme-size=0 +gtk-font-name="DejaVu Sans 10" +gtk-button-images=1 +gtk-menu-images=1 +gtk-fallback-icon-theme="gnome" +gtk-toolbar-style=GTK_TOOLBAR_BOTH +gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR +gtk-decoration-layout=":menu" +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle="hintslight" +gtk-xft-rgba="rgb" + +gtk-key-theme-name="Emacs" +binding "vbe-text-entry-bindings" { + unbind "b" + unbind "b" + unbind "f" + unbind "f" + unbind "w" + bind "BackSpace" { "delete-from-cursor" (word-ends, -1) } +} +class "GtkEntry" binding "vbe-text-entry-bindings" +class "GtkTextView" binding "vbe-text-entry-bindings" diff --git a/dotfiles/gtkrc-3.0 b/dotfiles/gtkrc-3.0 new file mode 100644 index 0000000..15340ba --- /dev/null +++ b/dotfiles/gtkrc-3.0 @@ -0,0 +1,44 @@ +/* Useless: we cannot override properly by unbinding some keys */ +/* @import url("/usr/share/themes/Emacs/gtk-3.0/gtk-keys.css"); */ + +@binding-set custom-text-entry +{ + bind "b" { "move-cursor" (words, -1, 0) }; + bind "b" { "move-cursor" (words, -1, 1) }; + bind "f" { "move-cursor" (words, 1, 0) }; + bind "f" { "move-cursor" (words, 1, 1) }; + + bind "a" { "move-cursor" (paragraph-ends, -1, 0) }; + bind "a" { "move-cursor" (paragraph-ends, -1, 1) }; + bind "e" { "move-cursor" (paragraph-ends, 1, 0) }; + bind "e" { "move-cursor" (paragraph-ends, 1, 1) }; + + bind "y" { "paste-clipboard" () }; + + bind "d" { "delete-from-cursor" (chars, 1) }; + bind "d" { "delete-from-cursor" (word-ends, 1) }; + bind "k" { "delete-from-cursor" (paragraph-ends, 1) }; + bind "backslash" { "delete-from-cursor" (whitespace, 1) }; + bind "BackSpace" { "delete-from-cursor" (word-ends, -1) }; + + bind "space" { "delete-from-cursor" (whitespace, 1) + "insert-at-cursor" (" ") }; + bind "KP_Space" { "delete-from-cursor" (whitespace, 1) + "insert-at-cursor" (" ") }; +} + +entry, textview +{ + -gtk-key-bindings: custom-text-entry; +} + +.window-frame, .window-frame:backdrop { + box-shadow: 0 0 0 black; + border-style: none; + margin: 0; + border-radius: 0; +} + +.titlebar { + border-radius: 0; +} diff --git a/dotfiles/qt5ct.conf b/dotfiles/qt5ct.conf new file mode 100644 index 0000000..04ed88c --- /dev/null +++ b/dotfiles/qt5ct.conf @@ -0,0 +1,9 @@ +[Appearance] +custom_palette=false +icon_theme=Adwaita +standard_dialogs=gtk3 +style=Adwaita-dark + +[Fonts] +fixed=@Variant(\0\0\0@\0\0\0 \0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s\0 \0M\0o\0n\0o@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10) +general=@Variant(\0\0\0@\0\0\0\x16\0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10) diff --git a/systemd/autorandr@.service b/dotfiles/systemd/autorandr.service similarity index 57% rename from systemd/autorandr@.service rename to dotfiles/systemd/autorandr.service index bf637da..8f59bc6 100644 --- a/systemd/autorandr@.service +++ b/dotfiles/systemd/autorandr.service @@ -1,9 +1,8 @@ [Unit] -Description=Configure monitors on %I -PartOf=graphical-session@%i.target +Description=Configure monitors +PartOf=graphical-session.target [Service] -Environment=DISPLAY=%I ExecStart=/usr/bin/autorandr --change --default default LimitCORE=infinity Type=oneshot diff --git a/dotfiles/systemd/i3.service b/dotfiles/systemd/i3.service new file mode 100644 index 0000000..7dc55b6 --- /dev/null +++ b/dotfiles/systemd/i3.service @@ -0,0 +1,14 @@ +[Unit] +Description=i3 window manager +PartOf=graphical-session.target +After=autorandr.service +After=picom.service +After=xsettingsd.service +After=tmux.service +After=ssh-agent.service +Before=wallpaper.service + +[Service] +ExecStart=/usr/bin/i3 +ExecStopPost=/bin/systemctl --user stop graphical-session.target +Restart=on-failure diff --git a/dotfiles/systemd/inputplug.service b/dotfiles/systemd/inputplug.service new file mode 100644 index 0000000..ef05250 --- /dev/null +++ b/dotfiles/systemd/inputplug.service @@ -0,0 +1,8 @@ +[Unit] +Description=XInput event monitor +PartOf=graphical-session.target + +[Service] +ExecStartPre=/usr/bin/setxkbmap us +ExecStart=%h/.local/bin/inputplug -d -0 -c %h/.config/i3/bin/input-event +Restart=on-failure diff --git a/dotfiles/systemd/misc-x.service b/dotfiles/systemd/misc-x.service new file mode 100644 index 0000000..a0bebc5 --- /dev/null +++ b/dotfiles/systemd/misc-x.service @@ -0,0 +1,11 @@ +[Unit] +Description=Miscellaneous settings for X11 +PartOf=graphical-session.target +After=ssh-agent.service + +[Service] +ExecStart=/usr/bin/xset -b +ExecStart=/usr/bin/xsetroot -cursor_name left_ptr +ExecStart=%h/.config/i3/bin/ssh-add +Type=oneshot +RemainAfterExit=false diff --git a/dotfiles/systemd/picom.service b/dotfiles/systemd/picom.service new file mode 100644 index 0000000..d980334 --- /dev/null +++ b/dotfiles/systemd/picom.service @@ -0,0 +1,12 @@ +[Unit] +Description=Compositor for X11 +PartOf=graphical-session.target + +[Service] +ExecStart=/usr/bin/picom --backend glx \ + --xrender-sync-fence \ + --vsync \ + --opacity-rule 100:fullscreen \ + --opacity-rule 85:!fullscreen \ + --opacity-rule 100:focused +Restart=on-failure diff --git a/systemd/policykit-agent@.service b/dotfiles/systemd/policykit-agent.service similarity index 50% rename from systemd/policykit-agent@.service rename to dotfiles/systemd/policykit-agent.service index 301cfe5..f1eea4e 100644 --- a/systemd/policykit-agent@.service +++ b/dotfiles/systemd/policykit-agent.service @@ -1,8 +1,7 @@ [Unit] -Description=PolicyKit authentication agent on %I -PartOf=graphical-session@%i.target +Description=PolicyKit authentication agent +PartOf=graphical-session.target [Service] -Environment=DISPLAY=%I ExecStart=/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1 Restart=on-failure diff --git a/systemd/redshift@.service b/dotfiles/systemd/redshift.service similarity index 52% rename from systemd/redshift@.service rename to dotfiles/systemd/redshift.service index 91f2210..c3344e4 100644 --- a/systemd/redshift@.service +++ b/dotfiles/systemd/redshift.service @@ -1,8 +1,7 @@ [Unit] -Description=Set color temperature on %I -PartOf=graphical-session@%i.target +Description=Set color temperature +PartOf=graphical-session.target [Service] -Environment=DISPLAY=%I ExecStart=/usr/bin/redshift -l manual:lon=2.35:lat=48.87 -t 6500:3900 Restart=on-failure diff --git a/dotfiles/systemd/ssh-agent.service b/dotfiles/systemd/ssh-agent.service new file mode 100644 index 0000000..c74ba53 --- /dev/null +++ b/dotfiles/systemd/ssh-agent.service @@ -0,0 +1,12 @@ +[Unit] +Description=SSH key agent +Wants=dbus.socket +After=dbus.socket + +[Service] +Type=simple +Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket +ExecStartPre=/usr/bin/dbus-update-activation-environment --systemd SSH_AUTH_SOCK +ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK +ExecStopPost=/usr/bin/dbus-update-activation-environment --systemd SSH_AUTH_SOCK= +Restart=always diff --git a/systemd/tmux.service b/dotfiles/systemd/tmux.service similarity index 100% rename from systemd/tmux.service rename to dotfiles/systemd/tmux.service diff --git a/dotfiles/systemd/wallpaper.service b/dotfiles/systemd/wallpaper.service new file mode 100644 index 0000000..82249da --- /dev/null +++ b/dotfiles/systemd/wallpaper.service @@ -0,0 +1,14 @@ +[Unit] +Description=Build and display wallpaper +PartOf=graphical-session.target + +[Service] +Environment=WALLPAPER_DIRECTORY=%h/.config/i3/wallpapers +Environment=WALLPAPER_OUTPUT=%h/.cache/i3/current-wallpaper.png +ExecStart=/usr/bin/mkdir -p %h/.cache/i3 +ExecStart=%h/.config/i3/bin/build-wallpaper --crop \ + --directory $WALLPAPER_DIRECTORY \ + --target $WALLPAPER_OUTPUT +ExecStart=/usr/bin/fvwm-root -r $WALLPAPER_OUTPUT +Type=oneshot +RemainAfterExit=false diff --git a/dotfiles/systemd/wallpaper.timer b/dotfiles/systemd/wallpaper.timer new file mode 100644 index 0000000..4b8ed60 --- /dev/null +++ b/dotfiles/systemd/wallpaper.timer @@ -0,0 +1,7 @@ +[Unit] +Description=Wallpaper rotation +PartOf=graphical-session.target + +[Timer] +OnUnitActiveSec=2h +RandomizedDelaySec=10m diff --git a/dotfiles/systemd/xiccd.service b/dotfiles/systemd/xiccd.service new file mode 100644 index 0000000..92710e2 --- /dev/null +++ b/dotfiles/systemd/xiccd.service @@ -0,0 +1,7 @@ +[Unit] +Description=X color management +PartOf=graphical-session.target + +[Service] +ExecStart=/usr/bin/xiccd --edid +Restart=on-failure diff --git a/dotfiles/systemd/xsession.target b/dotfiles/systemd/xsession.target new file mode 100644 index 0000000..c49c677 --- /dev/null +++ b/dotfiles/systemd/xsession.target @@ -0,0 +1,17 @@ +[Unit] +Description=X session +BindsTo=graphical-session.target +Wants=autorandr.service +Wants=i3.service +Wants=picom.service +Wants=inputplug.service +Wants=misc-x.service +Wants=policykit-agent.service +Wants=redshift.service +Wants=wallpaper.timer +Wants=xiccd.service +Wants=xsettingsd.service +Wants=xss-lock.service +Wants=tmux.service +Wants=ssh-agent.service +Wants=pulseaudio.service diff --git a/dotfiles/systemd/xsettingsd.service b/dotfiles/systemd/xsettingsd.service new file mode 100644 index 0000000..6372206 --- /dev/null +++ b/dotfiles/systemd/xsettingsd.service @@ -0,0 +1,11 @@ +[Unit] +Description=XSETTINGS daemon +PartOf=graphical-session.target + +[Service] +Environment=SKIP_RELOAD=1 +ExecStartPre=%h/.config/i3/bin/xsettingsd-setup +ExecStart=/usr/bin/xsettingsd -c %h/.xsettingsd +ExecReload=%h/.config/i3/bin/xsettingsd-setup +ExecReload=/usr/bin/kill -HUP $MAINPID +Restart=on-failure diff --git a/dotfiles/systemd/xss-lock.service b/dotfiles/systemd/xss-lock.service new file mode 100644 index 0000000..d8d85d4 --- /dev/null +++ b/dotfiles/systemd/xss-lock.service @@ -0,0 +1,7 @@ +[Unit] +Description=Manage X screen saver +PartOf=graphical-session.target + +[Service] +ExecStart=%h/.config/i3/bin/xss-lock start +Restart=on-failure diff --git a/xkb/default.xkb b/dotfiles/xkb/default.xkb similarity index 100% rename from xkb/default.xkb rename to dotfiles/xkb/default.xkb diff --git a/xkb/symbols/vbe b/dotfiles/xkb/symbols/vbe similarity index 100% rename from xkb/symbols/vbe rename to dotfiles/xkb/symbols/vbe diff --git a/xkb/thinkpad-extra.xkb b/dotfiles/xkb/thinkpad-extra.xkb similarity index 100% rename from xkb/thinkpad-extra.xkb rename to dotfiles/xkb/thinkpad-extra.xkb diff --git a/xkb/x1gen2.xkb b/dotfiles/xkb/x1gen2.xkb similarity index 93% rename from xkb/x1gen2.xkb rename to dotfiles/xkb/x1gen2.xkb index b458e00..2ac972c 100644 --- a/xkb/x1gen2.xkb +++ b/dotfiles/xkb/x1gen2.xkb @@ -16,6 +16,6 @@ xkb_keymap { xkb_compat { include "complete" }; xkb_symbols { include "pc+us+inet(evdev)" include "compose(ralt)+ctrl(nocaps)" - include "vbe(x1)" }; + include "vbe(x1gen2)" }; xkb_geometry { include "pc(pc105)" }; }; diff --git a/dotfiles/xsession b/dotfiles/xsession new file mode 100644 index 0000000..8090fc9 --- /dev/null +++ b/dotfiles/xsession @@ -0,0 +1,38 @@ +#!/bin/sh + +# Ensure we use the appropriate gtkrc-2.0 file +export GTK2_RC_FILES=$HOME/.gtkrc-2.0 + +# We do not want to rely on crappy mailcap +export MAILCAPS=$HOME/.mailcap + +# Make QT automatically scale according to screen DPI +export QT_AUTO_SCREEN_SCALE_FACTOR=1 +export QT_QPA_PLATFORMTHEME=qt5ct + +# GTK3 apps try to contact org.a11y.Bus. Disable that. +export NO_AT_BRIDGE=1 + +# Environment variables +unset LC_ALL +[ -e ~/.zshenv ] && . ~/.zshenv + +# Copy some configuration files +while read source target; do + for t in $target; do + mkdir -p $(dirname $HOME/$t) + ln -nsf ~/.config/i3/dotfiles/$source $HOME/$t + done +done < 0 and docstring then - doc[k[1]] = { help = docstring, - group = currentgroup } - end - - return k -end -awful.key.new = new -- monkey patch - --- Turn a key to a string -local function key2str(key) - local sym = key.key or key.keysym - local translate = { - ["#14"] = "#", - [" "] = "Space", - } - sym = translate[sym] or sym - if not key.modifiers or #key.modifiers == 0 then return sym end - local result = "" - local translate = { - [modkey] = "⊞", - Shift = "⇧", - Control = "Ctrl", - } - for _, mod in pairs(key.modifiers) do - mod = translate[mod] or mod - result = result .. mod .. " + " - end - return result .. sym -end - --- Unicode "aware" length function (well, UTF8 aware) --- See: http://lua-users.org/wiki/LuaUnicode -local function unilen(str) - local _, count = string.gsub(str, "[^\128-\193]", "") - return count -end - --- Start a new group -function group(name) - currentgroup = name - return {} -end - -local function markup(keys) - local result = {} - - -- Compute longest key combination - local longest = 0 - for _, key in ipairs(keys) do - if doc[key] then - longest = math.max(longest, unilen(key2str(key))) - end - end - - local curgroup = nil - for _, key in ipairs(keys) do - if doc[key] then - local help, group = doc[key].help, doc[key].group - local skey = key2str(key) - result[group] = (result[group] or "") .. - ' ' .. - string.format("%" .. (longest - unilen(skey)) .. "s ", "") .. skey .. - ' ' .. - help .. '\n' - end - end - - return result -end - --- Display help in a naughty notification -local nid = nil -function display() - local strings = awful.util.table.join( - markup(capi.root.keys()), - capi.client.focus and markup(capi.client.focus:keys()) or {}) - - local result = "" - for group, res in pairs(strings) do - if #result > 0 then result = result .. "\n" end - result = result .. - '' .. - group .. "\n" .. res - end - nid = naughty.notify({ text = result, - replaces_id = nid, - hover_timeout = 0.1, - timeout = 30 }).id -end diff --git a/lib/quake.lua b/lib/quake.lua deleted file mode 100644 index 090d7e3..0000000 --- a/lib/quake.lua +++ /dev/null @@ -1,140 +0,0 @@ --- Quake like console on top --- Similar to: --- http://git.sysphere.org/awesome-configs/tree/scratch/drop.lua - --- But uses a different implementation. The main difference is that we --- are able to detect the Quake console from its name --- (QuakeConsoleNeedsUniqueName by default). - --- If you have a rule like "awful.client.setslave" for your terminals, --- ensure you use an exception for --- QuakeConsoleNeedsUniqueName. Otherwise, you may run into problems --- with focus. - -local setmetatable = setmetatable -local string = string -local awful = require("awful") -local capi = { mouse = mouse, - screen = screen, - client = client, - timer = timer } - --- I use a namespace for my modules... -module("vbe/quake") - -local QuakeConsole = {} - --- Display -function QuakeConsole:display() - -- First, we locate the terminal - local client = nil - local i = 0 - for c in awful.client.cycle(function (c) - -- c.name may be changed! - return (c.instance == self.name or c.role == self.name) - end) do - client = c - client:tags({}) - break - end - - if not client and not self.visible then - -- The terminal is not here yet but we don't want it yet. Just do nothing. - return - end - - if not client then - -- The client does not exist, we spawn it - awful.util.spawn(self.terminal .. " " .. string.format(self.argname, self.name)) - return - end - - -- Comptute size - local geom = capi.screen[capi.mouse.screen].workarea - local width, height = self.width, self.height - if width <= 1 then width = geom.width * width end - if height <= 1 then height = geom.height * height end - local x, y - if self.horiz == "left" then x = geom.x - elseif self.horiz == "right" then x = geom.width + geom.x - width - else x = geom.x + (geom.width - width)/2 end - if self.vert == "top" then y = geom.y - elseif self.vert == "bottom" then y = geom.height + geom.y - height - else y = geom.y + (geom.height - height)/2 end - - -- Resize - awful.client.floating.set(client, true) - client.border_width = 0 - client.size_hints_honor = false - client:geometry({ x = x, y = y, width = width, height = height }) - - -- Sticky and on top - client.ontop = true - client.above = true - client.skip_taskbar = true - client.sticky = true - - -- This is not a normal window, don't apply any specific keyboard stuff - client:buttons({}) - client:keys({}) - - -- Toggle display - if self.visible then - client.hidden = false - client:raise() - capi.client.focus = client - else - client.hidden = true - end -end - --- Create a console -function QuakeConsole:new(config) - -- The "console" object is just its configuration. - - -- The application to be invoked is: - -- config.terminal .. " " .. string.format(config.argname, config.name) - config.terminal = config.terminal or "xterm" -- application to spawn - config.name = config.name or "QuakeConsoleNeedsUniqueName" -- window name - config.argname = config.argname or "-name %s" -- how to specify window name - - -- If width or height <= 1 this is a proportion of the workspace - config.height = config.height or 0.25 -- height - config.width = config.width or 1 -- width - config.vert = config.vert or "top" -- top, bottom or center - config.horiz = config.horiz or "center" -- left, right or center - - config.visible = config.visible or false -- Initially, not visible - - local console = setmetatable(config, { __index = QuakeConsole }) - capi.client.add_signal("manage", - function(c) - if (c.instance == console.name or c.role == console.name) then - console:display() - end - end) - capi.client.add_signal("unmanage", - function(c) - if (c.instance == console.name or c.role == console.name) then - console.visible = false - end - end) - - -- "Reattach" currently running QuakeConsole. This is in case awesome is restarted. - local reattach = capi.timer { timeout = 0 } - reattach:add_signal("timeout", - function() - reattach:stop() - console:display() - end) - reattach:start() - return console -end - --- Toggle the console -function QuakeConsole:toggle() - self.visible = not self.visible - self:display() -end - -setmetatable(_M, { __call = function(_, ...) return QuakeConsole:new(...) end }) diff --git a/lib/shifty.lua b/lib/shifty.lua deleted file mode 100644 index 9007929..0000000 --- a/lib/shifty.lua +++ /dev/null @@ -1,944 +0,0 @@ ---- Shifty: Dynamic tagging library for awesome3-git --- @author koniu <gkusnierz@gmail.com> --- @author resixian (aka bioe007) <resixian@gmail.com> --- --- http://awesome.naquadah.org/wiki/index.php?title=Shifty --- --- Modified version for my own use (Vincent Bernat) --- --- TODO: --- - Maybe name a tag after first client. - - --- environment -local type = type -local ipairs = ipairs -local table = table -local string = string -local beautiful = require("beautiful") -local awful = require("awful") -local pairs = pairs -local io = io -local tonumber = tonumber -local dbg= dbg -local capi = { - client = client, - tag = tag, - image = image, - screen = screen, - button = button, - mouse = mouse, - root = root, - timer = timer -} - -module("vbe/shifty") - --- variables -config = {} -config.tags = {} -config.apps = {} -config.defaults = {} -config.guess_name = true -config.remember_index = true -config.default_name = "…" -config.prompt_sources = { - "config_tags", - "config_apps", - "existing", - "history" -} -config.prompt_matchers = { - "^", - ":", - "" -} - -local matchp = "" -local index_cache = {} -for i = 1, capi.screen.count() do index_cache[i] = {} end - ---getname: return the "user" name of a tag --- @param t : tag --- @return username of the tag -local function getname(t) - local name = awful.tag.getproperty(t, "shortname") - if name then - return "" .. name - end - return t.name -end - ---setname: set the "user" name of a tag and update its name --- @param t : tag --- @param name : new name -local function setname(t, name) - if name then - local dispname = "" .. name - local pos = awful.tag.getproperty(t, "position") or "?" - awful.tag.setproperty(t, "shortname", name) - if pos then - if "" .. pos ~= "" .. dispname then - dispname = pos .. '↭' .. dispname - end - end - t.name = dispname - end -end - ---freeposition: get a free position -local function freeposition() - local positions = {1, 2, 3, 4, 5, 6, 7, 8, 9} - for k, a in pairs(config.tags) do - if a.startup then - a = awful.util.table.join(a, a.startup) - end - if a.position then - local idx = awful.util.table.hasitem(positions, a.position) - if idx then - table.remove(positions, idx) - end - end - end - for s = 1, capi.screen.count() do - for i, t in ipairs(capi.screen[s]:tags()) do - local pos = awful.tag.getproperty(t, "position") - if pos then - local idx = awful.util.table.hasitem(positions, pos) - if idx then - table.remove(positions, idx) - end - end - end - end - if #positions > 0 then - return positions[1] - end - return nil -end - ---name2tags: matches string 'name' to tag objects --- @param name : tag name to find --- @param scr : screen to look for tags on --- @return table of tag objects or nil -function name2tags(name, scr) - local ret = {} - local a, b = scr or 1, scr or capi.screen.count() - for s = a, b do - for i, t in ipairs(capi.screen[s]:tags()) do - if name == getname(t) then - table.insert(ret, t) - end - end - end - if #ret > 0 then return ret end -end - -function name2tag(name, scr, idx) - local ts = name2tags(name, scr) - if ts then return ts[idx or 1] end -end - ---tag2index: finds index of a tag object --- @param scr : screen number to look for tag on --- @param tag : the tag object to find --- @return the index [or zero] or end of the list -function tag2index(scr, tag) - for i, t in ipairs(capi.screen[scr]:tags()) do - if t == tag then return i end - end -end - ---rename ---@param tag: tag object to be renamed -function rename(tag, no_selectall) - local theme = beautiful.get() - local t = tag or awful.tag.selected(capi.mouse.screen) - local scr = t.screen - local bg = nil - local fg = nil - local text = getname(t) - local before = getname(t) - - if t == awful.tag.selected(scr) then - bg = theme.bg_focus or '#535d6c' - fg = theme.fg_urgent or '#ffffff' - else - bg = theme.bg_normal or '#222222' - fg = theme.fg_urgent or '#ffffff' - end - - awful.prompt.run({ - fg_cursor = fg, bg_cursor = bg, ul_cursor = "single", - text = text, selectall = not no_selectall}, - taglist[scr][tag2index(scr, t) * 2], - function (name) if name:len() > 0 then setname(t, name); end end, - completion, - awful.util.getdir("cache") .. "/history_tags", - nil, - function () - if getname(t) == before then - if awful.tag.getproperty(t, "initial") then del(t) end - else - awful.tag.setproperty(t, "initial", true) - set(t) - end - t:emit_signal("property::name") - end - ) -end - ---send: moves client to tag[idx] --- maybe this isn't needed here in shifty? --- @param idx the tag number to send a client to -function send(idx) - local scr = capi.client.focus.screen or capi.mouse.screen - local sel = awful.tag.selected(scr) - local sel_idx = tag2index(scr, sel) - local tags = capi.screen[scr]:tags() - local target = awful.util.cycle(#tags, sel_idx + idx) - awful.client.movetotag(tags[target], capi.client.focus) - awful.tag.viewonly(tags[target]) -end - -function send_next() send(1) end -function send_prev() send(-1) end - ---pos2idx: translate shifty position to tag index ---@param pos: position (an integer) ---@param scr: screen number -function pos2idx(pos, scr) - local v = 1 - if pos and scr then - for i = #capi.screen[scr]:tags() , 1, -1 do - local t = capi.screen[scr]:tags()[i] - if awful.tag.getproperty(t, "position") and - awful.tag.getproperty(t, "position") <= pos then - v = i + 1 - break - end - end - end - return v -end - ---select : helper function chooses the first non-nil argument ---@param args - table of arguments -function select(args) - for i, a in pairs(args) do - if a ~= nil then - return a - end - end -end - ---tagtoscr : move an entire tag to another screen --- ---@param scr : the screen to move tag to ---@param t : the tag to be moved [awful.tag.selected()] ---@return the tag -function tagtoscr(scr, t) - -- break if called with an invalid screen number - if not scr or scr < 1 or scr > capi.screen.count() then return end - -- tag to move - local otag = t or awful.tag.selected() - - otag.screen = scr - -- set screen and then reset tag to order properly - if #otag:clients() > 0 then - for _ , c in ipairs(otag:clients()) do - if not c.sticky then - c.screen = scr - c:tags({otag}) - else - awful.client.toggletag(otag, c) - end - end - end - return otag -end - ---set : set a tags properties ---@param t: the tag ---@param args : a table of optional (?) tag properties ---@return t - the tag object -function set(t, args) - if not t then return end - if not args then args = {} end - - -- set the name - setname(t, args.name or getname(t)) - - -- attempt to load preset on initial run - local preset = (awful.tag.getproperty(t, "initial") and - config.tags[getname(t)]) or {} - - -- pick screen and get its tag table - local scr = args.screen or - (not t.screen and preset.screen) or - t.screen or - capi.mouse.screen - - local clientstomove = nil - if scr > capi.screen.count() then scr = capi.screen.count() end - if t.screen and scr ~= t.screen then - tagtoscr(scr, t) - t.screen = nil - end - local tags = capi.screen[scr]:tags() - - -- allow preset.layout to be a table to provide a different layout per - -- screen for a given tag - local preset_layout = preset.layout - if preset_layout and preset_layout[scr] then - preset_layout = preset.layout[scr] - end - - -- select from args, preset, getproperty, - -- config.defaults.configs or defaults - local props = { - layout = select{args.layout, preset_layout, - awful.tag.getproperty(t, "layout"), - config.defaults.layout, awful.layout.suit.tile}, - mwfact = select{args.mwfact, preset.mwfact, - awful.tag.getproperty(t, "mwfact"), - config.defaults.mwfact, 0.55}, - nmaster = select{args.nmaster, preset.nmaster, - awful.tag.getproperty(t, "nmaster"), - config.defaults.nmaster, 1}, - ncol = select{args.ncol, preset.ncol, - awful.tag.getproperty(t, "ncol"), - config.defaults.ncol, 1}, - matched = select{args.matched, awful.tag.getproperty(t, "matched")}, - exclusive = select{args.exclusive, preset.exclusive, - awful.tag.getproperty(t, "exclusive"), - config.defaults.exclusive}, - persist = select{args.persist, preset.persist, - awful.tag.getproperty(t, "persist"), - config.defaults.persist}, - nopopup = select{args.nopopup, preset.nopopup, - awful.tag.getproperty(t, "nopopup"), - config.defaults.nopopup}, - leave_kills = select{args.leave_kills, preset.leave_kills, - awful.tag.getproperty(t, "leave_kills"), - config.defaults.leave_kills}, - max_clients = select{args.max_clients, preset.max_clients, - awful.tag.getproperty(t, "max_clients"), - config.defaults.max_clients}, - position = select{args.position, preset.position, - awful.tag.getproperty(t, "position"), freeposition()}, - icon = select{args.icon and capi.image(args.icon), - preset.icon and capi.image(preset.icon), - awful.tag.getproperty(t, "icon"), - config.defaults.icon and capi.image(config.defaults.icon)}, - icon_only = select{args.icon_only, preset.icon_only, - awful.tag.getproperty(t, "icon_only"), - config.defaults.icon_only}, - sweep_delay = select{args.sweep_delay, preset.sweep_delay, - awful.tag.getproperty(t, "sweep_delay"), - config.defaults.sweep_delay}, - } - - -- calculate desired taglist index - local index = args.index or preset.index or config.defaults.index - local rel_index = args.rel_index or - preset.rel_index or - config.defaults.rel_index - local sel = awful.tag.selected(scr) - --TODO: what happens with rel_idx if no tags selected - local sel_idx = (sel and tag2index(scr, sel)) or 0 - local t_idx = tag2index(scr, t) - local limit = (not t_idx and #tags + 1) or #tags - local idx = nil - - if rel_index then - idx = awful.util.cycle(limit, (t_idx or sel_idx) + rel_index) - elseif index then - idx = awful.util.cycle(limit, index) - elseif props.position then - idx = pos2idx(props.position, scr) - if t_idx and t_idx < idx then idx = idx - 1 end - elseif config.remember_index and index_cache[scr][getname(t)] then - idx = index_cache[scr][getname(t)] - elseif not t_idx then - idx = #tags + 1 - end - - -- if we have a new index, remove from old index and insert - if idx then - if t_idx then table.remove(tags, t_idx) end - table.insert(tags, idx, t) - index_cache[scr][getname(t)] = idx - end - - -- set tag properties and push the new tag table - capi.screen[scr]:tags(tags) - for prop, val in pairs(props) do awful.tag.setproperty(t, prop, val) end - - -- execute run/spawn - if awful.tag.getproperty(t, "initial") then - if not args.nospawn then - local spawn = args.spawn or preset.spawn or config.defaults.spawn - local run = args.run or preset.run or config.defaults.run - if spawn and args.matched ~= true then - awful.util.spawn_with_shell(spawn, scr) - end - if run then run(t) end - end - awful.tag.setproperty(t, "initial", nil) - end - - - return t -end - -function shift_next() set(awful.tag.selected(), {rel_index = 1}) end -function shift_prev() set(awful.tag.selected(), {rel_index = -1}) end - ---add : adds a tag ---@param args: table of optional arguments -function add(args) - if not args then args = {} end - local name = args.name or " " - - -- initialize a new tag object and its data structure - local t = capi.tag{name = name} - - -- tell set() that this is the first time - awful.tag.setproperty(t, "initial", true) - - -- apply tag settings - set(t, args) - - -- unless forbidden or if first tag on the screen, show the tag - if not (awful.tag.getproperty(t, "nopopup") or args.noswitch) or - #capi.screen[t.screen]:tags() == 1 then - awful.tag.viewonly(t) - end - - -- get the name or rename - if args.name then - setname(t, args.name) - else - -- FIXME: hack to delay rename for un-named tags for - -- tackling taglist refresh which disabled prompt - -- from being rendered until input - awful.tag.setproperty(t, "initial", true) - local tmr - local f = function() rename(t); tmr:stop() end - tmr = capi.timer({timeout = 0.01}) - tmr:add_signal("timeout", f) - tmr:start() - end - - return t -end - ---del : delete a tag ---@param tag : the tag to be deleted [current tag] -function del(tag) - local scr = (tag and tag.screen) or capi.mouse.screen or 1 - local tags = capi.screen[scr]:tags() - local sel = awful.tag.selected(scr) - local t = tag or sel - local idx = tag2index(scr, t) - - -- return if tag not empty (except sticky) - local clients = t:clients() - local sticky = 0 - for i, c in ipairs(clients) do - if c.sticky then sticky = sticky + 1 end - end - if #clients > sticky then return false end - - -- store index for later - index_cache[scr][getname(t)] = idx - - -- remove tag - t.screen = nil - - return true -end - ---is_client_tagged : replicate behavior in tag.c - returns true if the ---given client is tagged with the given tag -function is_client_tagged(tag, client) - for i, c in ipairs(tag:clients()) do - if c == client then - return true - end - end - return false -end - ---match : handles app->tag matching, a replacement for the manage hook in --- rc.lua ---@param c : client to be matched -function match(c, startup) - local nopopup, intrusive, nofocus, run, slave - local target_tag_names, target_tags = {}, {} - local typ = c.type - local cls = c.class - local inst = c.instance - local role = c.role - local name = c.name - local target_screen = capi.mouse.screen - - -- try matching client to config.apps - for i, a in ipairs(config.apps) do - if a.match then - local matched = false - -- match function - if not matched and a.match.check then - matched = a.match.check(c) - end - - -- match only class - if not matched and cls and a.match.class then - for k, w in ipairs(a.match.class) do - matched = cls:find(w) - if matched then - break - end - end - end - -- match only instance - if not matched and inst and a.match.instance then - for k, w in ipairs(a.match.instance) do - matched = inst:find(w) - if matched then - break - end - end - end - -- match only name - if not matched and name and a.match.name then - for k, w in ipairs(a.match.name) do - matched = name:find(w) - if matched then - break - end - end - end - -- match only role - if not matched and role and a.match.role then - for k, w in ipairs(a.match.role) do - matched = (role == w) - if matched then - break - end - end - end - -- match only type - if not matched and typ and a.match.type then - for k, w in ipairs(a.match.type) do - matched = typ:find(w) - if matched then - break - end - end - end - -- check everything else against all attributes - if not matched then - for k, w in ipairs(a.match) do - matched = (cls and cls:find(w)) or - (inst and inst:find(w)) or - (name and name:find(w)) or - (role and (role == w)) or - (typ and typ:find(w)) - if matched then - break - end - end - end - -- set attributes - if matched then - if a.startup and startup then - a = awful.util.table.join(a, a.startup) - end - if a.screen then target_screen = a.screen end - if a.tag then - if type(a.tag) == "string" then - target_tag_names = {a.tag} - else - target_tag_names = a.tag - end - end - if a.slave ~=nil then slave = a.slave end - if a.nopopup ~=nil then nopopup = a.nopopup end - if a.intrusive ~=nil then - intrusive = a.intrusive - end - if a.nofocus ~= nil then nofocus = a.nofocus end - if a.run ~= nil then run = a.run end - if a.props then - for kk, vv in pairs(a.props) do - awful.client.property.set(c, kk, vv) - end - end - end - end - end - - local sel = awful.tag.selectedlist(target_screen) - if not target_tag_names or #target_tag_names == 0 then - -- if not matched to some names try putting - -- client in c.transient_for or current tags - if c.transient_for then - target_tags = c.transient_for:tags() - elseif #sel > 0 then - for i, t in ipairs(sel) do - local mc = awful.tag.getproperty(t, "max_clients") - if intrusive or c.type == "dialog" or - not (awful.tag.getproperty(t, "exclusive") or - (mc and mc >= #t:clients())) then - table.insert(target_tags, t) - if config.guess_name and cls then - if getname(t) == config.default_name or - getname(t) == "" .. (awful.tag.getproperty(t, "position") or "?") then - setname(t, cls:lower()) - end - end - end - end - end - end - - if (not target_tag_names or #target_tag_names == 0) and - (not target_tags or #target_tags == 0) then - -- if we still don't know any target names/tags guess - -- name from class or use default - if config.guess_name and cls then - target_tag_names = {cls:lower()} - else - target_tag_names = {config.default_name} - end - end - - if #target_tag_names > 0 and #target_tags == 0 then - -- translate target names to tag objects, creating - -- missing ones - for i, tn in ipairs(target_tag_names) do - local res = {} - for j, t in ipairs(name2tags(tn, target_screen) or - name2tags(tn) or {}) do - local mc = awful.tag.getproperty(t, "max_clients") - local tagged = is_client_tagged(t, c) - if intrusive or - not (mc and (((#t:clients() >= mc) and not - tagged) or - (#t:clients() > mc))) or - intrusive then - table.insert(res, t) - end - end - if #res == 0 then - table.insert(target_tags, - add({name = tn, - noswitch = true, - matched = true})) - else - target_tags = awful.util.table.join(target_tags, res) - end - end - end - - -- set client's screen/tag if needed - target_screen = target_tags[1].screen or target_screen - if c.screen ~= target_screen then c.screen = target_screen end - if slave then awful.client.setslave(c) end - c:tags(target_tags) - - local showtags = {} - local u = nil - if #target_tags > 0 and not startup then - -- switch or highlight - for i, t in ipairs(target_tags) do - if not (nopopup or awful.tag.getproperty(t, "nopopup")) then - table.insert(showtags, t) - elseif not startup then - c.urgent = true - end - end - if #showtags > 0 then - local ident = false - -- iterate selected tags and and see if any targets - -- currently selected - for kk, vv in pairs(showtags) do - for _, tag in pairs(sel) do - if tag == vv then - ident = true - end - end - end - if not ident then - awful.tag.viewmore(showtags, c.screen) - end - end - end - - if nofocus then - --focus and raise accordingly or lower if supressed - if (target and target ~= sel) and - (awful.tag.getproperty(target, "nopopup") or nopopup) then - awful.client.focus.history.add(c) - else - capi.client.focus = c - end - c:raise() - else - c:lower() - end - - -- execute run function if specified - if run then run(c, target) end - -end - ---sweep : hook function that marks tags as used, visited, ---deserted also handles deleting used and empty tags -function sweep() - for s = 1, capi.screen.count() do - for i, t in ipairs(capi.screen[s]:tags()) do - local clients = t:clients() - local sticky = 0 - for i, c in ipairs(clients) do - if c.sticky then sticky = sticky + 1 end - end - if #clients == sticky then - if awful.tag.getproperty(t, "used") and - not awful.tag.getproperty(t, "persist") then - if awful.tag.getproperty(t, "deserted") or - not awful.tag.getproperty(t, "leave_kills") then - local delay = awful.tag.getproperty(t, "sweep_delay") - if delay then - local tmr - local f = function() - del(t) - tmr:stop() - end - tmr = capi.timer({timeout = delay}) - tmr:add_signal("timeout", f) - tmr:start() - else - del(t) - end - else - if awful.tag.getproperty(t, "visited") and - not t.selected then - awful.tag.setproperty(t, "deserted", true) - end - end - end - else - awful.tag.setproperty(t, "used", true) - end - if t.selected then - awful.tag.setproperty(t, "visited", true) - end - end - end -end - ---getpos : returns a tag to match position --- @param pos : the index to find --- @return v : the tag (found or created) at position == 'pos' -function getpos(pos, args) - local v = nil - local existing = {} - local selected = nil - local scr = capi.mouse.screen or 1 - local args = args or {} - - -- search for existing tag assigned to pos - for i = 1, capi.screen.count() do - for j, t in ipairs(capi.screen[i]:tags()) do - if awful.tag.getproperty(t, "position") == pos then - table.insert(existing, t) - if t.selected and i == scr then - selected = #existing - end - end - end - end - - if #existing > 0 then - -- if making another of an existing tag, return the end of - -- the list the optional 2nd argument decides if we return - -- only - v = (selected and - existing[awful.util.cycle(#existing, selected + 1)]) or - existing[1] - end - if not v then - -- search for preconf with 'pos' and create it - for i, j in pairs(config.tags) do - if j.position == pos then - v = add({name = i, - position = pos, - noswitch = true, - nospawn = args.nospawn}) - end - end - end - if not v then - -- not existing, not preconfigured - v = add({position = pos, - name = pos, - noswitch = true, - nospawn = args.nospawn}) - end - return v -end - ---init : search shifty.config.tags for initial set of ---tags to open -function init() - local numscr = capi.screen.count() - - for i, j in pairs(config.tags) do - local scr = j.screen or {1} - if type(scr) ~= 'table' then - scr = {scr} - end - for _, s in pairs(scr) do - if j.init and (s <= numscr) then - add({name = i, - persist = true, - screen = s, - layout = j.layout, - mwfact = j.mwfact}) - end - end - end -end - ---count : utility function returns the index of a table element ---FIXME: this is currently used only in remove_dup, so is it really ---necessary? -function count(table, element) - local v = 0 - for i, e in pairs(table) do - if element == e then v = v + 1 end - end - return v -end - ---remove_dup : used by shifty.completion when more than one ---tag at a position exists -function remove_dup(table) - local v = {} - for i, entry in ipairs(table) do - if count(v, entry) == 0 then v[#v+ 1] = entry end - end - return v -end - ---completion : prompt completion --- -function completion(cmd, cur_pos, ncomp, sources, matchers) - - -- get sources and matches tables - sources = sources or config.prompt_sources - matchers = matchers or config.prompt_matchers - - local get_source = { - -- gather names from config.tags - config_tags = function() - local ret = {} - for n, p in pairs(config.tags) do - table.insert(ret, n) - end - return ret - end, - -- gather names from config.apps - config_apps = function() - local ret = {} - for i, p in pairs(config.apps) do - if p.tag then - if type(p.tag) == "string" then - table.insert(ret, p.tag) - else - ret = awful.util.table.join(ret, p.tag) - end - end - end - return ret - end, - -- gather names from existing tags, starting with the - -- current screen - existing = function() - local ret = {} - for i = 1, capi.screen.count() do - local s = awful.util.cycle(capi.screen.count(), - capi.mouse.screen + i - 1) - local tags = capi.screen[s]:tags() - for j, t in pairs(tags) do - table.insert(ret, getname(t)) - end - end - return ret - end, - -- gather names from history - history = function() - local ret = {} - local f = io.open(awful.util.getdir("cache") .. - "/history_tags") - for name in f:lines() do table.insert(ret, name) end - f:close() - return ret - end, - } - - -- if empty, match all - if #cmd == 0 or cmd == " " then cmd = "" end - - -- match all up to the cursor if moved or no matchphrase - if matchp == "" or - cmd:sub(cur_pos, cur_pos+#matchp) ~= matchp then - matchp = cmd:sub(1, cur_pos) - end - - -- find matching commands - local matches = {} - for i, src in ipairs(sources) do - local source = get_source[src]() - for j, matcher in ipairs(matchers) do - for k, name in ipairs(source) do - if name:find(matcher .. matchp) then - table.insert(matches, name) - end - end - end - end - - -- no matches - if #matches == 0 then return cmd, cur_pos end - - -- remove duplicates - matches = remove_dup(matches) - - -- cycle - while ncomp > #matches do ncomp = ncomp - #matches end - - -- put cursor at the end of the matched phrase - if #matches == 1 then - cur_pos = #matches[ncomp] + 1 - else - cur_pos = matches[ncomp]:find(matchp) + #matchp - end - - -- return match and position - return matches[ncomp], cur_pos -end - --- signals -capi.client.add_signal("manage", match) -capi.client.add_signal("unmanage", sweep) -capi.client.remove_signal("manage", awful.tag.withcurrent) - -for s = 1, capi.screen.count() do - awful.tag.attached_add_signal(s, "property::selected", sweep) - awful.tag.attached_add_signal(s, "tagged", sweep) -end - diff --git a/lib/spotify.lua b/lib/spotify.lua deleted file mode 100644 index 2301212..0000000 --- a/lib/spotify.lua +++ /dev/null @@ -1,76 +0,0 @@ --- Drive spotify through playerctl. - --- Spotify uses the MPRIS D-BUS interface. See more information here: --- http://specifications.freedesktop.org/mpris-spec/latest/ - --- To get the complete interface: --- busctl --user introspect org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 - -local awful = require("awful") -local dbg = dbg -local pairs = pairs -local os = os -local capi = { - client = client -} - -module("vbe/spotify") - --- Get spotify window -local function spotify() - local clients = capi.client.get() - for k, c in pairs(clients) do - if awful.rules.match(c, { instance = "spotify", - class = "Spotify" }) then - return c - end - end - return nil -end - --- Send a command to spotify -local function cmd(command) - awful.util.spawn("playerctl -p spotify " .. command, false) -end - --- Show spotify -function show() - local client = spotify() - if client then - if not client:isvisible() then - awful.tag.viewonly(client:tags()[1]) - end - capi.client.focus = client - client:raise() - else - awful.util.spawn("spotify") - end -end - -function playpause() - cmd("play-pause") -end - -function play() - cmd("play") -end - -function pause() - cmd("pause") -end - -function stop() - cmd("stop") -end - -function next() - cmd("next") -end - -function previous() - cmd("previous") -end - -function mixer() - awful.util.spawn("pavucontrol") -end diff --git a/lib/volume.lua b/lib/volume.lua deleted file mode 100644 index e2618a5..0000000 --- a/lib/volume.lua +++ /dev/null @@ -1,70 +0,0 @@ --- Handle volume (through pulseaudio) - -local awful = require("awful") -local naughty = require("naughty") -local tonumber = tonumber -local string = string -local os = os - --- A bit odd, but... -require("lib/icons") -local icons = package.loaded["vbe/icons"] - -module("vbe/volume") - -local volid = nil -local running = true -local function current(what) - local out = awful.util.pread("amixer -D pulse sget " .. what) - local vol, mute = out:match("([%d]+)%%.*%[([%l]*)") - return vol, mute -end - -local function change(what, how) - if how ~= 0 then - local vol, mute = current(what) - how = string.format("%d%%", vol+how) - else - how = "toggle" - end - os.execute("amixer -q -D pulse sset " .. what .. " " .. how, false) - - local vol, mute = current(what) - vol = tonumber(vol) - local icon = "high" - if mute ~= "on" or vol == 0 then - icon = "muted" - elseif vol < 30 then - icon = "low" - elseif vol < 60 then - icon = "medium" - end - local prefix = "audio-volume" - if what == "Capture" then - prefix = "microphone-sensitivity" - end - icon = icons.lookup({name = prefix .. "-" .. icon, - type = "status"}) - - volid = naughty.notify({ text = string.format("%3d %%", vol), - icon = icon, - font = "Free Sans Bold 24", - replaces_id = volid }).id -end - -function increase(what) - change(what, 2) -end - -function decrease(what) - change(what, -2) -end - -function toggle(what) - change(what, 0) -end - --- run pavucontrol -function mixer() - awful.util.spawn("pavucontrol", false) -end diff --git a/rc.lua b/rc.lua deleted file mode 100644 index 4c61a72..0000000 --- a/rc.lua +++ /dev/null @@ -1,75 +0,0 @@ -require("awful") -require("awful.autofocus") -require("awful.rules") -require("beautiful") -require("naughty") - --- Simple function to load additional LUA files from rc/. -function loadrc(name, mod) - local success - local result - - -- Which file? In rc/ or in lib/? - local path = awful.util.getdir("config") .. "/" .. - (mod and "lib" or "rc") .. - "/" .. name .. ".lua" - - -- If the module is already loaded, don't load it again - if mod and package.loaded[mod] then return package.loaded[mod] end - - -- Execute the RC/module file - success, result = pcall(function() return dofile(path) end) - if not success then - naughty.notify({ title = "Error while loading an RC file", - text = "When loading `" .. name .. - "`, got the following error:\n" .. result, - preset = naughty.config.presets.critical - }) - return print("E: error loading RC file '" .. name .. "': " .. result) - end - - -- Is it a module? - if mod then - return package.loaded[mod] - end - - return result -end - -loadrc("errors") -- errors and debug stuff - --- Create cache directory -os.execute("mkdir -p " .. awful.util.getdir("cache")) - --- Setup xsettings -os.execute("~/.config/awesome/bin/xsettingsd-setup") -os.execute("systemctl --user start --no-block wallpaper@$(systemd-escape -- ${DISPLAY%.0})") - --- Global configuration -modkey = "Mod4" -config = {} -config.terminal = "vbeterm" -config.termclass = "Vbeterm" -config.layouts = { - awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.fair, - awful.layout.suit.floating, -} -config.hostname = awful.util.pread('uname -n'):gsub('\n', '') - --- Remaining modules -loadrc("appearance") -- theme and appearance settings -loadrc("debug") -- debugging primitive `dbg()` - -loadrc("bindings") -- keybindings -loadrc("widgets") -- widgets configuration -loadrc("tags") -- tags handling -loadrc("xlock") -- lock screen -loadrc("signals") -- window manager behaviour -loadrc("rules") -- window rules -loadrc("quake") -- quake console -loadrc("xrandr") -- xrandr menu - -root.keys(config.keys.global) diff --git a/rc/appearance.lua b/rc/appearance.lua deleted file mode 100644 index f9d5173..0000000 --- a/rc/appearance.lua +++ /dev/null @@ -1,120 +0,0 @@ --- Theme -beautiful.init(awful.util.getdir("config") .. "/rc/theme.lua") - --- Also have a look at `xsettingsd` which is used for GTK 3. At some --- point, when we don't need GTK 2, we can use only xsettingsd and --- avoid duplication. -local gtk2 = io.open(os.getenv("HOME") .. "/.gtkrc-2.0", "w") -gtk2:write([[ -gtk-theme-name="Adwaita-dark" -gtk-icon-theme-name="Adwaita" -gtk-cursor-theme-name="Adwaita" -gtk-cursor-theme-size=0 -gtk-font-name="DejaVu Sans 10" -gtk-button-images=1 -gtk-menu-images=1 -gtk-fallback-icon-theme="gnome" -gtk-toolbar-style=GTK_TOOLBAR_BOTH -gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR -gtk-decoration-layout=":menu" -gtk-xft-antialias=1 -gtk-xft-hinting=1 -gtk-xft-hintstyle="hintslight" -gtk-xft-rgba="rgb" - -gtk-key-theme-name="Emacs" -binding "vbe-text-entry-bindings" { - unbind "b" - unbind "b" - unbind "f" - unbind "f" - unbind "w" - bind "BackSpace" { "delete-from-cursor" (word-ends, -1) } -} -class "GtkEntry" binding "vbe-text-entry-bindings" -class "GtkTextView" binding "vbe-text-entry-bindings" -]]) -gtk2:close() - -os.execute("mkdir -p ~/.config/gtk-3.0") -os.execute("rm -f ~/.config/gtk-3.0/settings.ini") -local gtk3 = io.open(os.getenv("HOME") .. "/.config/gtk-3.0/gtk.css", "w") -gtk3:write([[ -/* Useless: we cannot override properly by unbinding some keys */ -/* @import url("/usr/share/themes/Emacs/gtk-3.0/gtk-keys.css"); */ - -@binding-set custom-text-entry -{ - bind "b" { "move-cursor" (words, -1, 0) }; - bind "b" { "move-cursor" (words, -1, 1) }; - bind "f" { "move-cursor" (words, 1, 0) }; - bind "f" { "move-cursor" (words, 1, 1) }; - - bind "a" { "move-cursor" (paragraph-ends, -1, 0) }; - bind "a" { "move-cursor" (paragraph-ends, -1, 1) }; - bind "e" { "move-cursor" (paragraph-ends, 1, 0) }; - bind "e" { "move-cursor" (paragraph-ends, 1, 1) }; - - bind "y" { "paste-clipboard" () }; - - bind "d" { "delete-from-cursor" (chars, 1) }; - bind "d" { "delete-from-cursor" (word-ends, 1) }; - bind "k" { "delete-from-cursor" (paragraph-ends, 1) }; - bind "backslash" { "delete-from-cursor" (whitespace, 1) }; - bind "BackSpace" { "delete-from-cursor" (word-ends, -1) }; - - bind "space" { "delete-from-cursor" (whitespace, 1) - "insert-at-cursor" (" ") }; - bind "KP_Space" { "delete-from-cursor" (whitespace, 1) - "insert-at-cursor" (" ") }; -} - -entry, textview -{ - -gtk-key-bindings: custom-text-entry; -} - -.window-frame, .window-frame:backdrop { - box-shadow: 0 0 0 black; - border-style: none; - margin: 0; - border-radius: 0; -} - -.titlebar { - border-radius: 0; -} -]]) -gtk3:close() - --- For QT, use qt5ct -os.execute("mkdir -p ~/.config/qt5ct") -local qt5ct = io.open(os.getenv("HOME") .. "/.config/qt5ct/qt5ct.conf", "w") -qt5ct:write([[ -[Appearance] -custom_palette=false -icon_theme=Adwaita -standard_dialogs=gtk3 -style=Adwaita-dark - -[Fonts] -fixed=@Variant(\0\0\0@\0\0\0 \0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s\0 \0M\0o\0n\0o@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10) -general=@Variant(\0\0\0@\0\0\0\x16\0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10) -]]) -qt5ct:close() - --- The systray is a bit complex. We need to configure it to display --- the right colors. Here is a link with more background about this: --- http://thread.gmane.org/gmane.comp.window-managers.awesome/9028 -xprop = assert(io.popen("xprop -root _NET_SUPPORTING_WM_CHECK")) -wid = xprop:read():match("^_NET_SUPPORTING_WM_CHECK.WINDOW.: window id # (0x[%S]+)$") -xprop:close() -if wid then - wid = tonumber(wid) + 1 - os.execute("xprop -id " .. wid .. " -format _NET_SYSTEM_TRAY_COLORS 32c " .. - "-set _NET_SYSTEM_TRAY_COLORS " .. - "65535,65535,65535,65535,8670,8670,65535,32385,0,8670,65535,8670") -end - --- Set cursor theme -os.execute("xsetroot -cursor_name left_ptr") diff --git a/rc/bindings.lua b/rc/bindings.lua deleted file mode 100644 index 3e00c81..0000000 --- a/rc/bindings.lua +++ /dev/null @@ -1,317 +0,0 @@ -config.keys = {} -config.mouse = {} -local volume = loadrc("volume", "vbe/volume") -local brightness = loadrc("brightness", "vbe/brightness") -local keydoc = loadrc("keydoc", "vbe/keydoc") - -local function screenshot() - awful.util.spawn_with_shell("flameshot gui -r | xclip -selection clipboard -t image/png", - false) -end - - --- Function to toggle a given window to the currently selected and --- focused tag. We need a filter. This function can be used to focus a --- particular window. When the filter is unable to select something, --- we undo previous actions (hence "toggle"). This function returns a --- function that will effectively toggle things. -local function toggle_window(filter) - local undo = {} -- undo stack - client.add_signal('unmanage', - function(c) - -- If the client is in the undo stack, remove it - while true do - idx = awful.util.table.hasitem(undo, c) - if not idx then break end - table.remove(undo, idx) - end - end) - local toggle = function() - -- "Current" screen - local s = client.focus and client.focus.screen or mouse.screen - local cl = filter() -- Client to toggle - if cl and client.focus ~= cl then - -- So, we have a client. - if not cl:isvisible() then - -- But it is not visible. So we will add it to the current - -- tag of the screen where it currently is - local t = assert(awful.tag.selected(cl.screen)) - -- Add our tag to the client - undo[#undo + 1] = { cl, t } - awful.client.toggletag(t, cl) - end - - -- Focus and raise the client - if s ~= cl.screen then - mouse.screen = cl.screen - end - client.focus = cl - cl:raise() - else - -- OK, we need to restore the previously pushed window to its - -- original state. - local i = #undo - while i > 0 do - local cl, t = unpack(undo[i]) - -- We only handle visible clients that are attached to the - -- appropriate tag. Otherwise, we try the next one. - if cl and cl:isvisible() and t.selected and - awful.util.table.hasitem(cl:tags(), t) then - awful.client.toggletag(t, cl) - table.remove(undo, i) - return - end - i = i - 1 - end - -- Clean up... - while #undo > 10 do - table.remove(undo, 1) - end - end - end - return toggle -end - --- Toggle IM conversation window -local toggle_im = toggle_window( - (function () - local adding = true - local choose = function() - local cls = client.get() - local focus = client.focus - local rules = { { class = "Pidgin", - role = "conversation" }, - { class = "Skype", - role = "ConversationsWindow" } } - -- Score. We want a Pidgin window. Then: - -- 1. Urgent, visible, not focused - -- 2. Urgent, not visible, not focused. - -- 3. Not urgent, not visible, not focused - -- 4. Focused - -- 5. Visible, not focused - local function score(cl) - local found = false - for _, rule in pairs(rules) do - if awful.rules.match(cl, rule) then - found = true - break - end - end - if not found then return -10 end - - local urgent = cl.urgent - local focused = (focus == cl) - local visible = cl:isvisible() - if urgent and visible and not focused then return 100 end - if urgent and not visible and not focused then return 90 end - if not adding and focused then return 80 end - if adding and not urgent and not visible then return 70 end - if focused then return 50 end - if not urgent and not visible then return 40 end - return 10 - end - table.sort(cls, function(c1, c2) - local s1 = score(c1) - local s2 = score(c2) - return s1 > s2 - end) - local candidate = cls[1] - if candidate == nil then return nil end - local found = false - for _, rule in pairs(rules) do - if awful.rules.match(candidate, rule) then - found = true - break - end - end - if not found then return nil end - - -- Maybe we need to switch direction - if candidate == focus and adding then adding = false - elseif candidate ~= focus and not adding then adding = true end - - return candidate - end - return choose - end)()) - --- Toggle urgent window -local toggle_urgent = toggle_window(awful.client.urgent.get) - --- Focus a relative screen (similar to `awful.screen.focus_relative`) -local function screen_focus(i) - local s = awful.util.cycle(screen.count(), mouse.screen + i) - local c = awful.client.focus.history.get(s, 0) - mouse.screen = s - if c then client.focus = c end -end - -local music = loadrc("spotify", "vbe/spotify") - -local display_nmaster_ncol = - (function() - local nid = nil - return function() - local nmaster = awful.tag.getnmaster() - local ncol = awful.tag.getncol() - nid = naughty.notify( - { title = "Tag configuration", - timeout = 5, - text = "Number of masters: " .. nmaster .. - "\nNumber of columns: " .. ncol, - replaces_id = nid }).id - end - end)() - -config.keys.global = awful.util.table.join( - keydoc.group("Focus"), - awful.key({ modkey, }, "j", - function () - awful.client.focus.byidx( 1) - if client.focus then - client.focus:raise() - end - end, - "Focus next window"), - awful.key({ modkey, }, "k", - function () - awful.client.focus.byidx(-1) - if client.focus then - client.focus:raise() - end - end, - "Focus previous window"), - awful.key({ modkey, }, "u", toggle_im, - "Toggle Pidgin conversation window"), - awful.key({ modkey, "Control" }, "j", function () - screen_focus(-1) - end, - "Jump to next screen"), - awful.key({ modkey, "Control" }, "k", function () - screen_focus( 1) - end), - - keydoc.group("Layout manipulation"), - awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end, - "Increase master-width factor"), - awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end, - "Decrease master-width factor"), - awful.key({ modkey, "Shift" }, "l", function () - awful.tag.incnmaster(1) - display_nmaster_ncol() - end, - "Increase number of masters"), - awful.key({ modkey, "Shift" }, "h", function () - awful.tag.incnmaster(-1) - display_nmaster_ncol() - end, - "Decrease number of masters"), - awful.key({ modkey, "Control" }, "l", function () - awful.tag.incncol(1) - display_nmaster_ncol() - end, - "Increase number of columns"), - awful.key({ modkey, "Control" }, "h", function () - awful.tag.incncol(-1) - display_nmaster_ncol() - end, - "Decrease number of columns"), - awful.key({ modkey, }, "space", function () awful.layout.inc(config.layouts, 1) end, - "Next layout"), - awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(config.layouts, -1) end, - "Previous layout"), - awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end, - "Swap with next window"), - awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end, - "Swap with previous window"), - - keydoc.group("Misc"), - - -- Spawn a terminal - awful.key({ modkey, }, "Return", function () awful.util.spawn(config.terminal) end, - "Spawn a terminal"), - - -- Screenshot - awful.key({}, "Print", screenshot), - -- Restart awesome - awful.key({ modkey, "Control" }, "r", awesome.restart), - - -- Multimedia keys - awful.key({ }, "XF86MonBrightnessUp", brightness.increase), - awful.key({ }, "XF86MonBrightnessDown", brightness.decrease), - awful.key({ }, "XF86AudioRaiseVolume", function() volume.increase("Master") end), - awful.key({ }, "XF86AudioLowerVolume", function() volume.decrease("Master") end), - awful.key({ }, "XF86AudioMute", function() volume.toggle("Master") end), - awful.key({ }, "XF86AudioMicMute", function() volume.toggle("Capture") end), - - awful.key({ }, "XF86AudioPlay", music.playpause), - awful.key({ }, "XF86AudioPause", music.pause), - awful.key({ }, "XF86AudioStop", music.stop), - awful.key({ }, "XF86AudioNext", music.next), - awful.key({ }, "XF86AudioPrev", music.previous), - - awful.key({ modkey }, "s", function() - keygrabber.run(function(mod, key, event) - if event == "release" then - return true - end - keygrabber.stop() - if key == "z" then music.previous() - elseif key == "x" then music.play() - elseif key == "c" then music.pause() - elseif key == "v" then music.stop() - elseif key == "b" then music.next() - elseif key == "s" then music.show() - elseif key == "m" then music.mixer() - end - return true - end) - end), - - -- Help - awful.key({ modkey, }, "F1", keydoc.display) -) - -config.keys.client = awful.util.table.join( - keydoc.group("Window-specific bindings"), - awful.key({ modkey, }, "f", - function (c) - c.sticky = false - c.fullscreen = not c.fullscreen - c:raise() - end, - "Fullscreen"), - awful.key({ modkey, }, "x", function (c) c:kill() end, - "Close"), - awful.key({ modkey, }, "o", - function (c) - if screen.count() == 1 then return nil end - local s = awful.util.cycle(screen.count(), c.screen + 1) - if awful.tag.selected(s) then - c.screen = s - client.focus = c - c:raise() - end - end, "Move to the other screen"), - awful.key({ modkey, "Control" }, "s", function (c) c.sticky = not c.sticky end, "Toggle stickyness"), - awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle, "Toggle floating"), - awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end, - "Switch with master window"), - awful.key({ modkey, }, "i", dbg, - "Get client-related information"), - awful.key({ modkey, }, "m", - function (c) - c.sticky = false - c.maximized_horizontal = not c.maximized_horizontal - c.maximized_vertical = not c.maximized_vertical - c:raise() - end, - "Maximize") -) - -keydoc.group("Misc") - -config.mouse.client = awful.util.table.join( - awful.button({ }, 1, function (c) client.focus = c; c:raise() end), - awful.button({ modkey }, 1, awful.mouse.client.move), - awful.button({ modkey }, 3, awful.mouse.client.resize)) diff --git a/rc/debug.lua b/rc/debug.lua deleted file mode 100644 index 2dd128a..0000000 --- a/rc/debug.lua +++ /dev/null @@ -1,104 +0,0 @@ -local colors = { - header = theme.fg_widget_clock, - count = theme.fg_widget_label, - index = theme.fg_widget_label, - name = theme.fg_widget_value_important, -} - -local function client_info(c) - local v = "" - - -- object - local c = c or client.focus - v = v .. tostring(c) - - -- geometry - local cc = c:geometry() - local signx = (cc.x > 0 and "+") or "" - local signy = (cc.y > 0 and "+") or "" - v = v .. " @ " .. cc.width .. 'x' .. cc.height .. signx .. cc.x .. signy .. cc.y .. "\n\n" - - local inf = { - "name", "icon_name", "type", "class", "role", "instance", "pid", - "skip_taskbar", "id", "group_window", "leader_id", "machine", - "screen", "hidden", "minimized", "size_hints_honor", "titlebar", "urgent", - "focus", "opacity", "ontop", "above", "below", "fullscreen", "transient_for", - "maximixed_horizontal", "maximixed_vertical", "sticky", "modal", "focusable" - } - - for i = 1, #inf do - v = v .. string.format('%2s: %-20s = %s\n', - i, - beautiful.fg_widget_label, inf[i], - beautiful.fg_widget_value, tostring(c[inf[i]])) - end - - naughty.notify{ text = string.format('%s', v:sub(1,#v-1)), - timeout = 0, margin = 10, screen = c.screen } -end - -local function dbg_get(var, depth, indent) - local a = "" - local text = "" - local name = "" - local vtype = type(var) - local vstring = tostring(var) - - if vtype == "table" or vtype == "userdata" then - if vtype == "userdata" then var = getmetatable(var) end - -- element count and longest key - local count = 0 - local longest_key = 3 - for k,v in pairs(var) do - count = count + 1 - longest_key = math.max(#tostring(k), longest_key) - end - text = text .. vstring .. " #" .. count .. "" - -- descend a table - if depth > 0 then - -- sort keys FIXME: messes up sorting number - local sorted = {} - for k, v in pairs(var) do table.insert(sorted, { k, v }) end - table.sort(sorted, function(a, b) return tostring(a[1]) < tostring(b[1]) end) - -- go through elements - for _, p in ipairs(sorted) do - local key = p[1]; local value = p[2] - -- don't descend _M - local d; if key ~= "_M" then d = depth - 1 else d = 0 end - -- get content and add to output - local content = dbg_get(value, d, indent + longest_key + 1) - text = text .. '\n' .. string.rep(" ", indent) .. - string.format("%-"..longest_key.."s %s", - tostring(key), content) - end - end - else - if vtype == "tag" or vtype == "client" then - name = " [" .. (var.name or '…'):sub(1,10) .. "]" - end - text = text .. vstring .. name or "" - end - - return text -end - -function dbg(...) - local num = table.maxn(arg) - local text = "dbg #"..num.."" - local depth = 2 - local clients = 0 - - for i = 1, num do - local desc = dbg_get(arg[i], depth, 3) - text = text .. string.format("\n%2d %s", i, desc) - if type(arg[i]) == "client" then - client_info(arg[i]) - clients = clients + 1 - end - end - - -- Display only if we don't have only clients to be displayed - if clients ~= num then - naughty.notify{ text = text, timeout = 0, hover_timeout = 2, screen = screen.count() } - end -end diff --git a/rc/errors.lua b/rc/errors.lua deleted file mode 100644 index 3ec5ee0..0000000 --- a/rc/errors.lua +++ /dev/null @@ -1,14 +0,0 @@ --- Handle runtime errors after startup -do - local in_error = false - awesome.add_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 = err }) - in_error = false - end) -end diff --git a/rc/quake.lua b/rc/quake.lua deleted file mode 100644 index 01fca4d..0000000 --- a/rc/quake.lua +++ /dev/null @@ -1,10 +0,0 @@ -local quake = loadrc("quake", "vbe/quake") -local quakeconsole = quake({ terminal = config.terminal, - argname = "--name %s", - height = 0.3 }) - -config.keys.global = awful.util.table.join( - config.keys.global, - awful.key({ modkey }, "`", - function () quakeconsole:toggle() end, - "Toggle Quake console")) diff --git a/rc/rules.lua b/rc/rules.lua deleted file mode 100644 index 322affb..0000000 --- a/rc/rules.lua +++ /dev/null @@ -1,62 +0,0 @@ -local icons = loadrc("icons", "vbe/icons") - -awful.rules.rules = { - -- All clients will match this rule. - { rule = { }, - properties = { border_width = beautiful.border_width, - border_color = beautiful.border_normal, - focus = true, - maximized_vertical = false, - maximized_horizontal = false, - keys = config.keys.client, - buttons = config.mouse.client }}, - -- i3lock - { rule = { name = "i3lock" }, - properties = { ontop = true } }, - -- Browser stuff - { rule = { role = "browser" }, - callback = function(c) - if not c.icon then - local icon = icons.lookup({ name = "web-browser", - type = "apps" }) - if icon then - c.icon = image(icon) - end - end - end }, - { rule = { class = config.termclass }, - properties = { icon = image(icons.lookup({ name = "gnome-terminal", - type = "apps" })) } }, - { rule_any = { class = { "Iceweasel", "Firefox", "Chromium", "Conkeror", "Google-chrome" } }, - callback = function(c) - -- All windows should be slaves, except the browser windows. - if c.role ~= "browser" then awful.client.setslave(c) end - end }, - -- See also tags.lua - -- Pidgin - { rule = { class = "Pidgin" }, - except = { role = "buddy_list" }, - properties = { }, callback = awful.client.setslave }, - { rule = { class = "Pidgin", role = "buddy_list" }, - properties = { }, callback = awful.client.setmaster }, - -- Shadow - { rule = { class = "Shadow" }, - properties = { fullscreen = true }}, - -- Zoom dialogs should not have focus - { rule = { class = "zoom", type = "dialog" }, - properties = { focus = false }}, - -- Should not be master - { rule_any = { class = - { config.termclass, - "Transmission-gtk" - }, instance = { "Download" }}, - except = { icon_name = "QuakeConsoleNeedsUniqueName" }, - properties = { }, - callback = awful.client.setslave }, - -- Picture in picture - { rule = { name = "Picture-in-Picture" }, - properties = { floating = true, ontop = true } }, - -- Floating windows - { rule_any = { class = { "Display.im6", "Key-mon" } }, - properties = { floating = true }}, -} diff --git a/rc/signals.lua b/rc/signals.lua deleted file mode 100644 index c5637cc..0000000 --- a/rc/signals.lua +++ /dev/null @@ -1,92 +0,0 @@ -local icons = loadrc("icons", "vbe/icons") - --- Did we get the focus because of sloppy focus? -local focus_from_mouse = false -local function mouse_follow_focus(c) - -- Move the mouse to the top left corner - if c.type ~= "dialog" then - local cc = c:geometry() - local _, x, y = awful.mouse.client.corner(nil, "top_left") - if x and y then - mouse.coords({ x = x + 20 , y = y + cc.height / 2 }, true) - end - end -end - --- Signal function to execute when a new client appears. -client.add_signal("manage", - function (c, startup) - -- Enable sloppy focus - c:add_signal("mouse::enter", - function(c) - -- If magnifier suit, only give sloppy focus to master window - if ((awful.layout.get(c.screen) ~= awful.layout.suit.magnifier or - awful.client.getmaster(c.screen) == c) - -- Don't give focus to a client already having focus - and client.focus ~= c - -- Don't give focus to a window that does not want focus - and awful.client.focus.filter(c)) then - focus_from_mouse = c - client.focus = c - end - end) - - -- If a window change its geometry, track it with the mouse - c:add_signal("property::geometry", - function() - -- Check if the current focused client is our - if client.focus ~=c then return end - -- Check that no button is pressed - local buttons = mouse.coords().buttons - for _, state in pairs(buttons) do - if state then return end - end - mouse_follow_focus(c) - end) - - -- If this is Spotify and it sets the urgent property, unset it - if c.instance == "spotify" then - c.urgent = false - c:add_signal("property::urgent", - function() - c.urgent = false - end) - end - - -- Setup icon if none exists - if not c.icon then - local icon = icons.lookup({ name = { c.class, c.instance }, - type = "apps" }) - if icon then - c.icon = image(icon) - end - end - - if not startup then - -- Put windows in a smart way, only if they does not set an initial position. - if not c.size_hints.user_position and not c.size_hints.program_position then - awful.placement.no_overlap(c) - awful.placement.no_offscreen(c) - end - c:raise() - end - end) - -client.add_signal("focus", function(c) - c.border_color = beautiful.border_focus - c.opacity = 1 - - if focus_from_mouse ~= c then - mouse_follow_focus(c) - c:raise() - end - focus_from_mouse = false - end) -client.add_signal("unfocus", function(c) - c.border_color = beautiful.border_normal - if (not c.fullscreen and - not awful.rules.match_any(c, { name = { "Picture-in-Picture" }, - class = { "zoom" }})) then - c.opacity = 0.85 - end - end) diff --git a/rc/tags.lua b/rc/tags.lua deleted file mode 100644 index ad4c262..0000000 --- a/rc/tags.lua +++ /dev/null @@ -1,164 +0,0 @@ --- Tags - -local shifty = loadrc("shifty", "vbe/shifty") -local keydoc = loadrc("keydoc", "vbe/keydoc") - -local tagicon = function(icon) - if screen.count() > 1 then - return beautiful.icons .. "/taglist/" .. icon .. ".png" - end - return nil -end - -shifty.config.tags = { - www = { - position = 3, - mwfact = 0.7, - exclusive = true, - max_clients = 1, - screen = math.min(screen.count(), 2), - spawn = "xdg-open about:newtab", - icon = tagicon("web") - }, - emacs = { - position = 2, - mwfact = 0.6, - exclusive = true, - screen = 1, - spawn = "emacs", - icon = tagicon("dev"), - }, - xterm = { - position = 1, - layout = awful.layout.suit.fair, - exclusive = true, - slave = true, - spawn = config.terminal, - icon = tagicon("main"), - }, - spotify = { - screen = 1, - exclusive = true - } -} - --- Also, see rules.lua -shifty.config.apps = { - { - match = { role = { "browser" } }, - tag = "www", - }, - { - match = { "emacs" }, - tag = "emacs", - }, - { - match = { class = { "Spotify" } }, - tag = "spotify" - }, - { - match = { config.termclass }, - startup = { - tag = "xterm" - }, - intrusive = true, -- Display even on exclusive tags - }, - { - match = { class = { "Key[-]mon" }, - role = { "pop[-]up" }, - name = { "Firebug", "Picture-in-Picture" }, - instance = { "plugin[-]container", "exe" } }, - intrusive = true, - }, -} - -shifty.config.defaults = { - layout = config.layouts[1], - mwfact = 0.6, - ncol = 1, - sweep_delay = 1, -} - -shifty.taglist = config.taglist -- Set in widget.lua -shifty.init() - -local tag_del_or_rename = function(tag) - if not shifty.del(tag) then - shifty.rename(tag) - end -end - -config.keys.global = awful.util.table.join( - config.keys.global, - keydoc.group("Tag management"), - awful.key({ modkey }, "Tab", awful.tag.history.restore, "Switch to previous tag"), - awful.key({ modkey }, "Left", awful.tag.viewprev), - awful.key({ modkey }, "Right", awful.tag.viewnext), - awful.key({ modkey, "Shift"}, "o", - function() - if screen.count() == 1 then return nil end - local t = awful.tag.selected() - if t == nil then return nil end - local s = awful.util.cycle(screen.count(), t.screen + 1) - awful.tag.history.restore() - t = shifty.tagtoscr(s, t) - awful.tag.viewonly(t) - end, - "Send tag to next screen"), - awful.key({ modkey, "Control", "Shift"}, "o", - function() - if screen.count() == 1 then return nil end - local t = awful.tag.selected() - if t == nil then return nil end - local o = t.screen - local s = awful.util.cycle(screen.count(), o + 1) - for _, t in pairs(screen[o]:tags()) do - shifty.tagtoscr(s, t) - end - end, - "Send all tags to next screen"), - awful.key({ modkey }, 0, shifty.add, "Create a new tag"), - awful.key({ modkey, "Shift" }, 0, tag_del_or_rename), - awful.key({ modkey, "Control" }, 0, tag_del_or_rename, "Rename or delete tag")) - --- Bind all key numbers to tags. --- Be careful: we use keycodes to make it works on any keyboard layout. --- This should map on the top row of your keyboard, usually 1 to 9. -for i = 1, (shifty.config.maxtags or 9) do - config.keys.global = awful.util.table.join( - config.keys.global, - keydoc.group("Tag management"), - awful.key({ modkey }, i, - function () - local t = shifty.getpos(i) - local s = t.screen - local c = awful.client.focus.history.get(s, 0) - awful.tag.viewonly(t) - mouse.screen = s - if c then client.focus = c end - end, - i == 5 and "Display only this tag" or nil), - awful.key({ modkey, "Control" }, i, - function () - local t = shifty.getpos(i) - t.selected = not t.selected - end, - i == 5 and "Toggle display of this tag" or nil), - awful.key({ modkey, "Shift" }, i, - function () - local c = client.focus - if c then - local t = shifty.getpos(i, {nospawn = true }) - awful.client.movetotag(t, c) - end - end, - i == 5 and "Move window to this tag" or nil), - awful.key({ modkey, "Control", "Shift" }, i, - function () - if client.focus then - awful.client.toggletag(shifty.getpos(i, {nospawn = true})) - end - end, - i == 5 and "Toggle this tag on this window" or nil), - keydoc.group("Misc")) -end diff --git a/rc/theme.lua b/rc/theme.lua deleted file mode 100644 index ff6d24a..0000000 --- a/rc/theme.lua +++ /dev/null @@ -1,74 +0,0 @@ --- Small modifications to anrxc's zenburn theme - -local na = awful.util.color_strip_alpha -local icons = awful.util.getdir("config") .. "/icons" - -local function scale() - local xrdb = io.popen("xrdb -query") - if xrdb then - for line in xrdb:lines() do - output = line:match("^Xft.dpi:\t(%d+)$") - if output then - xrdb:close() - return tonumber(output)/96 - end - end - xrdb:close() - end - return 1 -end - -theme = {} -theme.scale = scale() -theme.icons = icons -theme.wallpaper_cmd = { "/bin/true" } -theme.font = "Terminus " .. 9 * theme.scale -theme.tasklist_font = "DejaVu Sans " .. 8 * theme.scale - -theme.bg_normal = "#22222299" -theme.bg_focus = "#d8d8d8bb" -theme.bg_urgent = "#d02e5499" -theme.bg_minimize = "#44444499" - -theme.fg_normal = "#cccccc" -theme.fg_focus = "#000000" -theme.fg_urgent = "#ffffff" -theme.fg_minimize = "#ffffff" - -theme.border_width = 4 -theme.border_normal = "#00000000" -theme.border_focus = "#FF7F00" -theme.border_marked = "#91231c66" - --- Widget stuff -theme.bg_widget = "#000000BB" -theme.fg_widget_label = "#737d8c" -theme.fg_widget_value = na(theme.fg_normal) -theme.fg_widget_value_important = "#E80F28" -theme.fg_widget_border = theme.fg_widget_label -theme.fg_widget_clock = na(theme.border_focus) - --- Taglist -theme.taglist_squares_sel = icons .. "/taglist/squarefw.png" -theme.taglist_squares_unsel = icons .. "/taglist/squarew.png" - --- Layout icons -for _, l in pairs(config.layouts) do - theme["layout_" .. l.name] = icons .. "/layouts/" .. l.name .. ".png" -end - --- Naughty -naughty.config.presets.normal.bg = "#111111" -for _, preset in pairs({"normal", "low", "critical"}) do - naughty.config.presets[preset].font = "DejaVu Sans " .. 10 * theme.scale - naughty.config.presets[preset].margin = 12 * theme.scale - naughty.config.presets[preset].border_width = 3 * theme.scale -end -naughty.config.notify_callback = function(args) - if args.icon ~= nil and type(args.icon) ~= "string" then - args.icon = nil - end - return args -end - -return theme diff --git a/rc/widgets.lua b/rc/widgets.lua deleted file mode 100644 index 3e3d885..0000000 --- a/rc/widgets.lua +++ /dev/null @@ -1,318 +0,0 @@ --- Widgets - -require("vicious") -local icons = loadrc("icons", "vbe/icons") - --- Separators -local sepopen = widget({ type = "imagebox" }) -sepopen.image = image(beautiful.icons .. "/widgets/left.png") -local sepclose = widget({ type = "imagebox" }) -sepclose.image = image(beautiful.icons .. "/widgets/right.png") -local spacer = widget({ type = "imagebox" }) -spacer.image = image(beautiful.icons .. "/widgets/spacer.png") - --- Date -local datewidget = widget({ type = "textbox" }) -local dateformat = "%a %d/%m, %H:%M" -vicious.register(datewidget, vicious.widgets.date, - '' .. - dateformat .. '') -local dateicon = widget({ type = "imagebox" }) -dateicon.image = image(beautiful.icons .. "/widgets/clock.png") -local cal = ( - function() - local calendar = nil - local offset = 0 - - local remove_calendar = function() - if calendar ~= nil then - naughty.destroy(calendar) - calendar = nil - offset = 0 - end - end - - local add_calendar = function(inc_offset) - local save_offset = offset - remove_calendar() - offset = save_offset + inc_offset - local curdate = os.date("*t") - local datespec = curdate.year * 12 + curdate.month - 1 + offset - datespec = (datespec % 12 + 1) .. " " .. math.floor(datespec / 12) - local cal = awful.util.pread("ncal -h -w -m " .. datespec) - -- Highlight the current date and month - if offset == 0 then - cal, n = cal:gsub(string.format("( %d)([ \n])", curdate.day), - string.format('%%1%%2', - beautiful.fg_widget_clock), - 1) - end - -- Month and year - cal = cal:gsub("^( +[^ ]+ [0-9]+) *", - string.format('%%1', - beautiful.fg_widget_clock)) - -- Turn anything other than days in labels - cal = cal:gsub("(\n[^%d ]+)", - string.format('%%1', - beautiful.fg_widget_label)) - cal = cal:gsub("([%d ]+)\n?$", - string.format('%%1', - beautiful.fg_widget_label)) - calendar = naughty.notify( - { - text = string.format('%s', - theme.font, - cal:gsub(" +\n","\n")), - timeout = 0, hover_timeout = 0.5, - width = 160 * theme.scale, - screen = mouse.screen, - }) - end - - return { add = add_calendar, - rem = remove_calendar } - end)() - -datewidget:add_signal("mouse::enter", function() cal.add(0) end) -datewidget:add_signal("mouse::leave", cal.rem) -datewidget:buttons(awful.util.table.join( - awful.button({ }, 3, function() cal.add(-1) end), - awful.button({ }, 1, function() cal.add(1) end))) - --- CPU usage -local cpuwidget = widget({ type = "textbox" }) -vicious.register(cpuwidget, vicious.widgets.cpu, - function (widget, args) - return string.format('%2d%%', - args[1]) - end, 7) -local cpuicon = widget({ type = "imagebox" }) -cpuicon.image = image(beautiful.icons .. "/widgets/cpu.png") - --- Battery -local batwidget = { widget = "" } -if awful.util.table.hasitem({"guybrush", "zoro"}, config.hostname) then - local bat = "BAT0" - batwidget.widget = widget({ type = "textbox" }) - vicious.register(batwidget.widget, vicious.widgets.bat, - function (widget, args) - local color = beautiful.fg_widget_value - local current = args[2] - if current < 10 and args[1] == "-" then - color = beautiful.fg_widget_value_important - -- Maybe we want to display a small warning? - if current ~= batwidget.lastwarn then - batwidget.lastid = naughty.notify( - { title = "Battery low!", - preset = naughty.config.presets.critical, - timeout = 20, - text = "Battery level is currently " .. - current .. "%.\n" .. args[3] .. - " left before running out of power.", - icon = icons.lookup({name = "battery-caution", - type = "status"}), - replaces_id = batwidget.lastid }).id - batwidget.lastwarn = current - end - end - return string.format('%s%d%%', args[1], current) - end, - 59, bat) -end -local baticon = widget({ type = "imagebox" }) -baticon.image = image(beautiful.icons .. "/widgets/bat.png") - --- Network -local netup = widget({ type = "textbox" }) -local netdown = widget({ type = "textbox" }) -local netupicon = widget({ type = "imagebox" }) -netupicon.image = image(beautiful.icons .. "/widgets/up.png") -local netdownicon = widget({ type = "imagebox" }) -netdownicon.image = image(beautiful.icons .. "/widgets/down.png") - -local netgraph = awful.widget.graph() -netgraph:set_width(80 * theme.scale):set_height(16 * theme.scale) -netgraph:set_stack(true):set_scale(true) -netgraph:set_border_color(beautiful.fg_widget_border) -netgraph:set_stack_colors({ "#EF8171", "#cfefb3" }) -netgraph:set_background_color("#00000033") -vicious.register(netup, vicious.widgets.net, - function (widget, args) - -- We sum up/down value for all interfaces - local up = 0 - local down = 0 - local iface - for name, value in pairs(args) do - iface = name:match("^{(%S+) down_b}$") - if iface and iface ~= "lo" then down = down + value end - iface = name:match("^{(%S+) up_b}$") - if iface and iface ~= "lo" then up = up + value end - end - -- Update the graph - netgraph:add_value(up, 1) - netgraph:add_value(down, 2) - -- Format the string representation - local format = function(val) - if val > 500000 then - return string.format("%.1f MB", val/1000000.) - elseif val > 500 then - return string.format("%.1f KB", val/1000.) - end - return string.format("%d B", val) - end - -- Down - netdown.text = string.format('%08s', format(down)) - -- Up - return string.format('%08s', format(up)) - end, 3) - --- Memory usage -local memwidget = widget({ type = "textbox" }) -vicious.register(memwidget, vicious.widgets.mem, - '$1%', - 19) -local memicon = widget({ type = "imagebox" }) -memicon.image = image(beautiful.icons .. "/widgets/mem.png") - --- Volume level -local volwidget = widget({ type = "textbox" }) -vicious.register(volwidget, vicious.widgets.volume, - '$2 $1%', - 17, "-D pulse Master") -volume = loadrc("volume", "vbe/volume") -volwidget:buttons(awful.util.table.join( - awful.button({ }, 1, volume.mixer), - awful.button({ }, 3, function() volume.toggle("Master") end), - awful.button({ }, 4, function() volume.increase("Master") end), - awful.button({ }, 5, function() volume.decrease("Master") end))) - --- File systems -local fs = { "/", - "/home", - "/var", - "/usr", - "/tmp", - "/var/lib/systems" } -local fsicon = widget({ type = "imagebox" }) -fsicon.image = image(beautiful.icons .. "/widgets/disk.png") -local fswidget = widget({ type = "textbox" }) -vicious.register(fswidget, vicious.widgets.fs, - function (widget, args) - local result = "" - for _, path in pairs(fs) do - local used = args["{" .. path .. " used_p}"] - local color = beautiful.fg_widget_value - if used then - if used > 90 then - color = beautiful.fg_widget_value_important - end - local name = string.gsub(path, "[%w/]*/(%w+)", "%1") - if name == "/" then name = "root" end - result = string.format( - '%s%s%s: ' .. - '%2d%%', - result, #result > 0 and " " or "", name, used) - end - end - return result - end, 53, "-lx fuse -x aufs") - -local notifications = widget({ type = "imagebox" }) -notifications.image = image(beautiful.icons .. "/widgets/notifications-enabled.png") -notifications:buttons(awful.util.table.join( - awful.button({ }, 1, - function() - local state = "enabled" - naughty.toggle() - if naughty.is_suspended() then - state = "disabled" - end - notifications.image = image(beautiful.icons .. "/widgets/notifications-" .. state .. ".png") - end))) - -local systray = widget({ type = "systray" }) - --- Wibox initialisation -local wibox = {} -local promptbox = {} -local layoutbox = {} - -local taglist = {} -local tasklist = {} -tasklist.buttons = awful.util.table.join( - awful.button({ }, 1, function (c) - if not c:isvisible() then - awful.tag.viewonly(c:tags()[1]) - end - -- This will also un-minimize - -- the client, if needed - client.focus = c - c:raise() -end)) - -for s = 1, screen.count() do - promptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright }) - layoutbox[s] = awful.widget.layoutbox(s) - tasklist[s] = awful.widget.tasklist( - function(c) - local title, color, _, icon = awful.widget.tasklist.label.currenttags(c, s) - return title, color, nil, icon - end, tasklist.buttons) - - -- Create the taglist - taglist[s] = awful.widget.taglist.new(s, - awful.widget.taglist.label.all) - -- Create the wibox - wibox[s] = awful.wibox({ screen = s, - fg = beautiful.fg_normal, - bg = beautiful.bg_widget, - position = "top", - height = 16 * theme.scale, - }) - -- Add widgets to the wibox - local on = function(n, what) - if s == n or n > screen.count() then return what end - return "" - end - - wibox[s].widgets = { - { - screen.count() > 1 and sepopen or "", - taglist[s], - screen.count() > 1 and spacer or "", - layoutbox[s], - screen.count() > 1 and sepclose or "", - promptbox[s], - layout = awful.widget.layout.horizontal.leftright - }, - on(1, systray), - on(1, notifications), - sepclose, datewidget, screen.count() > 1 and dateicon or "", spacer, - on(2, volwidget), on(2, spacer), - - on(2, batwidget.widget), - on(2, batwidget.widget ~= "" and baticon or ""), - on(2, batwidget.widget ~= "" and spacer or ""), - - on(2, fswidget), screen.count() > 1 and on(2, fsicon) or "", - screen.count() > 1 and on(2, sepopen) or on(2, spacer), - - screen.count() > 1 and on(1, netgraph.widget) or "", - on(1, netdownicon), on(1, netdown), - on(1, netupicon), on(1, netup), on(1, spacer), - - on(1, memwidget), on(1, memicon), on(1, spacer), - on(1, cpuwidget), on(1, cpuicon), on(1, sepopen), - tasklist[s], - layout = awful.widget.layout.horizontal.rightleft } -end - -config.keys.global = awful.util.table.join( - config.keys.global, - awful.key({ modkey }, "r", function () promptbox[mouse.screen]:run() end, - "Prompt for a command")) - -config.taglist = taglist diff --git a/rc/xlock.lua b/rc/xlock.lua deleted file mode 100644 index 4249b5a..0000000 --- a/rc/xlock.lua +++ /dev/null @@ -1,10 +0,0 @@ --- Lockscreen - -local lock = function() - os.execute("xset s activate") -end - -config.keys.global = awful.util.table.join( - config.keys.global, - awful.key({}, "XF86ScreenSaver", lock), - awful.key({ modkey, }, "Delete", lock)) diff --git a/rc/xrandr.lua b/rc/xrandr.lua deleted file mode 100644 index 5c36be7..0000000 --- a/rc/xrandr.lua +++ /dev/null @@ -1,66 +0,0 @@ --- Menu with autorandr choices - -local icons = loadrc("icons", "vbe/icons") - --- Build available choices -local function menu() - return { - { "Autodetect", "autorandr --change" }, - { "Clone", "autorandr --load common" }, - { "Horizontal", "autorandr --load horizontal" }, - { "Vertical", "autorandr --load vertical" }, - { "Keep current configuration", nil }, - } -end - --- Display xrandr notifications from choices -local state = { iterator = nil, - timer = nil, - cid = nil } -local function xrandr() - -- Stop any previous timer - if state.timer then - state.timer:stop() - state.timer = nil - end - - -- Build the list of choices - if not state.iterator then - state.iterator = awful.util.table.cycle( - menu(), - function() return true end) - end - - -- Select one and display the appropriate notification - local next = state.iterator() - local label, action - if not next then - state.iterator = nil - return xrandr() - else - label, action = unpack(next) - end - state.cid = naughty.notify({ text = label, - icon = icons.lookup({ name = "display", type = "devices" }), - timeout = 4, - screen = mouse.screen, -- Important, not all screens may be visible - font = "Free Sans 18", - replaces_id = state.cid }).id - - -- Setup the timer - state.timer = timer { timeout = 4 } - state.timer:add_signal("timeout", - function() - state.timer:stop() - state.timer = nil - state.iterator = nil - if action then - awful.util.spawn(action, false) - end - end) - state.timer:start() -end - -config.keys.global = awful.util.table.join( - config.keys.global, - awful.key({}, "XF86Display", xrandr)) diff --git a/systemd/awesome@.service b/systemd/awesome@.service deleted file mode 100644 index ea63bf9..0000000 --- a/systemd/awesome@.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Awesome window manager for %I -PartOf=graphical-session@%i.target -After=autorandr@%i.service -After=picom@%i.service -After=xsettingsd@%i.service -After=tmux.service -After=ssh-agent.service -Before=nm-applet@%i.service -Before=wallpaper@%i.service - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/awesome -ExecStopPost=/bin/systemctl --user stop graphical-session@%i.target -Restart=on-failure diff --git a/systemd/graphical-session@.target b/systemd/graphical-session@.target deleted file mode 100644 index 4b2bac5..0000000 --- a/systemd/graphical-session@.target +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Graphical user session for %I -StopWhenUnneeded=yes -Wants=autorandr@%i.service -Wants=awesome@%i.service -Wants=picom@%i.service -Wants=inputplug@%i.service -Wants=misc-x@%i.service -Wants=nm-applet@%i.service -Wants=policykit-agent@%i.service -Wants=redshift@%i.service -Wants=wallpaper@%i.timer -Wants=xiccd@%i.service -Wants=xsettingsd@%i.service -Wants=xss-lock@%i.service -Wants=tmux.service -Wants=ssh-agent.service -Wants=pulseaudio.service diff --git a/systemd/inputplug@.service b/systemd/inputplug@.service deleted file mode 100644 index 2f5982f..0000000 --- a/systemd/inputplug@.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=XInput event monitor for %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStartPre=/usr/bin/setxkbmap us -ExecStart=%h/.local/bin/inputplug -d -0 -c %h/.config/awesome/bin/input-event -Restart=on-failure diff --git a/systemd/misc-x@.service b/systemd/misc-x@.service deleted file mode 100644 index 2342de3..0000000 --- a/systemd/misc-x@.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Miscellaneous settings for X11 on %I -PartOf=graphical-session@%i.target -After=ssh-agent.service - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/xset -b -ExecStart=%h/.config/awesome/bin/ssh-add -Type=oneshot -RemainAfterExit=false diff --git a/systemd/nm-applet@.service b/systemd/nm-applet@.service deleted file mode 100644 index fd3c7e8..0000000 --- a/systemd/nm-applet@.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Network Manager applet for %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/nm-applet -Restart=on-failure diff --git a/systemd/picom@.service b/systemd/picom@.service deleted file mode 100644 index cc06401..0000000 --- a/systemd/picom@.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Compositor for X11 on %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/picom --backend glx \ - --xrender-sync-fence \ - --vsync -Restart=on-failure diff --git a/systemd/ssh-agent.service b/systemd/ssh-agent.service deleted file mode 100644 index 0991ea1..0000000 --- a/systemd/ssh-agent.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=SSH key agent - -[Service] -Type=simple -Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket -ExecStartPre=/usr/bin/dbus-update-activation-environment SSH_AUTH_SOCK -ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK -Restart=always diff --git a/systemd/wallpaper@.service b/systemd/wallpaper@.service deleted file mode 100644 index 7c2dd09..0000000 --- a/systemd/wallpaper@.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Build a wallpaper for %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -Environment=WALLPAPER_DIRECTORY=%h/.config/awesome/wallpapers -Environment=WALLPAPER_OUTPUT=%h/.cache/awesome/current-wallpaper-%i.png -ExecStart=%h/.config/awesome/bin/build-wallpaper --crop \ - --directory $WALLPAPER_DIRECTORY \ - --target $WALLPAPER_OUTPUT -ExecStart=/usr/bin/fvwm-root -r $WALLPAPER_OUTPUT -Type=oneshot -RemainAfterExit=false diff --git a/systemd/wallpaper@.timer b/systemd/wallpaper@.timer deleted file mode 100644 index 490e3f3..0000000 --- a/systemd/wallpaper@.timer +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Wallpaper rotation for %I -PartOf=graphical-session@%i.target - -[Timer] -OnUnitActiveSec=2h -RandomizedDelaySec=10m diff --git a/systemd/xiccd@.service b/systemd/xiccd@.service deleted file mode 100644 index c5c4baf..0000000 --- a/systemd/xiccd@.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=X color management for %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/xiccd --edid -Restart=on-failure diff --git a/systemd/xsession@.target b/systemd/xsession@.target deleted file mode 100644 index 7614d8b..0000000 --- a/systemd/xsession@.target +++ /dev/null @@ -1,3 +0,0 @@ -[Unit] -Description=X session on %I -BindsTo=graphical-session@%i.target diff --git a/systemd/xsettingsd@.service b/systemd/xsettingsd@.service deleted file mode 100644 index b189d65..0000000 --- a/systemd/xsettingsd@.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=XSETTINGS daemon for %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStart=/usr/bin/xsettingsd -c %h/.xsettingsd -ExecReload=/usr/bin/kill -HUP $MAINPID -Restart=on-failure diff --git a/systemd/xss-lock@.service b/systemd/xss-lock@.service deleted file mode 100644 index 26d0fe8..0000000 --- a/systemd/xss-lock@.service +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Manage X screen saver on %I -PartOf=graphical-session@%i.target - -[Service] -Environment=DISPLAY=%I -ExecStart=%h/.config/awesome/bin/xss-lock start -Restart=on-failure diff --git a/xsession b/xsession index 79c1921..bc68080 100644 --- a/xsession +++ b/xsession @@ -3,9 +3,6 @@ # Ensure we use the appropriate gtkrc-2.0 file export GTK2_RC_FILES=$HOME/.gtkrc-2.0 -# Java incompatibility with awesome -export _JAVA_AWT_WM_NONREPARENTING=1 - # We do not want to rely on crappy mailcap export MAILCAPS=$HOME/.mailcap @@ -20,9 +17,20 @@ export NO_AT_BRIDGE=1 unset LC_ALL [ -e ~/.zshenv ] && . ~/.zshenv +# Copy dotfiles +while read source target; do + mkdir -p $(dirname $target) + ln -sf ~/.config/i3/dotfiles/$source $HOME/$target +done <