Initial i3 configuration
This is derived from my Awesome configuration. Still a lot to do from a WM perspective. The organization is a bit different and I am giving it up on the per-display systemd units as it does not really work due to the fact we only have one user DBus and one environment.
78
README.md
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
119
config
Normal file
|
@ -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
|
27
dotfiles/gtkrc-2.0
Normal file
|
@ -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 "<ctrl>b"
|
||||
unbind "<shift><ctrl>b"
|
||||
unbind "<ctrl>f"
|
||||
unbind "<shift><ctrl>f"
|
||||
unbind "<ctrl>w"
|
||||
bind "<alt>BackSpace" { "delete-from-cursor" (word-ends, -1) }
|
||||
}
|
||||
class "GtkEntry" binding "vbe-text-entry-bindings"
|
||||
class "GtkTextView" binding "vbe-text-entry-bindings"
|
44
dotfiles/gtkrc-3.0
Normal file
|
@ -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 "<alt>b" { "move-cursor" (words, -1, 0) };
|
||||
bind "<shift><alt>b" { "move-cursor" (words, -1, 1) };
|
||||
bind "<alt>f" { "move-cursor" (words, 1, 0) };
|
||||
bind "<shift><alt>f" { "move-cursor" (words, 1, 1) };
|
||||
|
||||
bind "<ctrl>a" { "move-cursor" (paragraph-ends, -1, 0) };
|
||||
bind "<shift><ctrl>a" { "move-cursor" (paragraph-ends, -1, 1) };
|
||||
bind "<ctrl>e" { "move-cursor" (paragraph-ends, 1, 0) };
|
||||
bind "<shift><ctrl>e" { "move-cursor" (paragraph-ends, 1, 1) };
|
||||
|
||||
bind "<ctrl>y" { "paste-clipboard" () };
|
||||
|
||||
bind "<ctrl>d" { "delete-from-cursor" (chars, 1) };
|
||||
bind "<alt>d" { "delete-from-cursor" (word-ends, 1) };
|
||||
bind "<ctrl>k" { "delete-from-cursor" (paragraph-ends, 1) };
|
||||
bind "<alt>backslash" { "delete-from-cursor" (whitespace, 1) };
|
||||
bind "<alt>BackSpace" { "delete-from-cursor" (word-ends, -1) };
|
||||
|
||||
bind "<alt>space" { "delete-from-cursor" (whitespace, 1)
|
||||
"insert-at-cursor" (" ") };
|
||||
bind "<alt>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;
|
||||
}
|
9
dotfiles/qt5ct.conf
Normal file
|
@ -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)
|
|
@ -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
|
14
dotfiles/systemd/i3.service
Normal file
|
@ -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
|
8
dotfiles/systemd/inputplug.service
Normal file
|
@ -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
|
11
dotfiles/systemd/misc-x.service
Normal file
|
@ -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
|
12
dotfiles/systemd/picom.service
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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
|
12
dotfiles/systemd/ssh-agent.service
Normal file
|
@ -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
|
14
dotfiles/systemd/wallpaper.service
Normal file
|
@ -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
|
7
dotfiles/systemd/wallpaper.timer
Normal file
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Wallpaper rotation
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Timer]
|
||||
OnUnitActiveSec=2h
|
||||
RandomizedDelaySec=10m
|
7
dotfiles/systemd/xiccd.service
Normal file
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=X color management
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/xiccd --edid
|
||||
Restart=on-failure
|
17
dotfiles/systemd/xsession.target
Normal file
|
@ -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
|
11
dotfiles/systemd/xsettingsd.service
Normal file
|
@ -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
|
7
dotfiles/systemd/xss-lock.service
Normal file
|
@ -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
|
|
@ -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)" };
|
||||
};
|
38
dotfiles/xsession
Normal file
|
@ -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 <<EOF
|
||||
Xresources .Xresources
|
||||
gtkrc-2.0 .gtkrc-2.0
|
||||
gtkrc-3.0 .config/gtk-3.0/settings.ini
|
||||
qt5ct.conf .config/qt5ct/qt5ct.conf
|
||||
systemd .config/systemd/user
|
||||
firefox.js .mozilla/firefox/*/user.js
|
||||
EOF
|
||||
|
||||
# Services are started with systemd
|
||||
systemctl --user import-environment
|
||||
systemctl --user daemon-reload
|
||||
exec systemctl --user start --wait xsession.target
|
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 173 B |
Before Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 204 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 173 B |
Before Width: | Height: | Size: 169 B |
Before Width: | Height: | Size: 179 B |
Before Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 193 B |
Before Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 163 B |
Before Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 198 B |
Before Width: | Height: | Size: 173 B |
Before Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 160 B |
Before Width: | Height: | Size: 791 B |
Before Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 287 B |
Before Width: | Height: | Size: 168 B |
|
@ -1,41 +0,0 @@
|
|||
-- Handle brightness (with brightnessctl)
|
||||
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local math = math
|
||||
local tonumber = tonumber
|
||||
local string = string
|
||||
local os = os
|
||||
local dbg = dbg
|
||||
|
||||
-- A bit odd, but...
|
||||
require("lib/icons")
|
||||
local icons = package.loaded["vbe/icons"]
|
||||
|
||||
module("vbe/brightness")
|
||||
|
||||
local nid = nil
|
||||
local function change(value)
|
||||
-- Set new value
|
||||
os.execute("brightnessctl -m s " .. value)
|
||||
|
||||
-- Get and display current value
|
||||
current = awful.util.pread("brightnessctl -m i")
|
||||
current = tonumber(string.match(current, ",(%d+)%%,"))
|
||||
|
||||
local icon = icons.lookup({name = "display-brightness",
|
||||
type = "status"})
|
||||
|
||||
nid = naughty.notify({ text = string.format("%3d %%", current),
|
||||
icon = icon,
|
||||
font = "Free Sans Bold 24",
|
||||
replaces_id = nid }).id
|
||||
end
|
||||
|
||||
function increase()
|
||||
change("5%+")
|
||||
end
|
||||
|
||||
function decrease()
|
||||
change("5%-")
|
||||
end
|
|
@ -1,63 +0,0 @@
|
|||
-- Lookup function for icons
|
||||
|
||||
local paths = {
|
||||
"/usr/share/icons/Adwaita",
|
||||
"/usr/share/icons/gnome",
|
||||
"/usr/share/icons/hicolor",
|
||||
"/usr/share/icons/HighContrast",
|
||||
"/usr/share/fvwm-crystal/fvwm/icons/Default",
|
||||
}
|
||||
local sizes = {
|
||||
'32x32',
|
||||
'24x24',
|
||||
'22x22',
|
||||
'16x16',
|
||||
}
|
||||
local types = {
|
||||
'apps',
|
||||
'actions',
|
||||
'devices',
|
||||
'status',
|
||||
}
|
||||
local formats = {
|
||||
".png",
|
||||
".xpm"
|
||||
}
|
||||
|
||||
local assert = assert
|
||||
local type = type
|
||||
local pairs = pairs
|
||||
local awful = require("awful")
|
||||
|
||||
module("vbe/icons")
|
||||
|
||||
-- Lookup for an icon. Return full path.
|
||||
function lookup(arg)
|
||||
local inames = assert(arg.name)
|
||||
local isizes = arg.size or sizes
|
||||
local itypes = arg.type or types
|
||||
local ipaths = paths
|
||||
local iformats = formats
|
||||
if type(isizes) ~= "table" then isizes = { isizes } end
|
||||
if type(itypes) ~= "table" then itypes = { itypes } end
|
||||
if type(inames) ~= "table" then inames = { inames } end
|
||||
|
||||
for _, path in pairs(ipaths) do
|
||||
for _, size in pairs(isizes) do
|
||||
for _, t in pairs(itypes) do
|
||||
for _, name in pairs(inames) do
|
||||
if name then
|
||||
for _, name in pairs({name, name:lower()}) do
|
||||
for _, ext in pairs(iformats) do
|
||||
local icon = path .. "/" .. size .. "/" .. t .. "/" .. name .. ext
|
||||
if awful.util.file_readable(icon) then
|
||||
return icon
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
124
lib/keydoc.lua
|
@ -1,124 +0,0 @@
|
|||
-- Document key bindings
|
||||
|
||||
local awful = require("awful")
|
||||
local table = table
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local math = math
|
||||
local string = string
|
||||
local type = type
|
||||
local modkey = modkey
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local theme = beautiful.get()
|
||||
local capi = {
|
||||
root = root,
|
||||
client = client
|
||||
}
|
||||
|
||||
module("vbe/keydoc")
|
||||
|
||||
local doc = { }
|
||||
local currentgroup = "Misc"
|
||||
local orig = awful.key.new
|
||||
|
||||
-- Replacement for awful.key.new
|
||||
local function new(mod, key, press, release, docstring)
|
||||
-- Usually, there is no use of release, let's just use it for doc
|
||||
-- if it's a string.
|
||||
if press and release and not docstring and type(release) == "string" then
|
||||
docstring = release
|
||||
release = nil
|
||||
end
|
||||
local k = orig(mod, key, press, release)
|
||||
-- Remember documentation for this key (we take the first one)
|
||||
if k and #k > 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 "") ..
|
||||
'<span font="DejaVu Sans Mono ' .. 10 * theme.scale .. '" color="' .. beautiful.fg_widget_clock .. '"> ' ..
|
||||
string.format("%" .. (longest - unilen(skey)) .. "s ", "") .. skey ..
|
||||
'</span> <span color="' .. beautiful.fg_widget_value .. '">' ..
|
||||
help .. '</span>\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 ..
|
||||
'<span weight="bold" color="' .. beautiful.fg_widget_value_important .. '">' ..
|
||||
group .. "</span>\n" .. res
|
||||
end
|
||||
nid = naughty.notify({ text = result,
|
||||
replaces_id = nid,
|
||||
hover_timeout = 0.1,
|
||||
timeout = 30 }).id
|
||||
end
|
140
lib/quake.lua
|
@ -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 })
|
944
lib/shifty.lua
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
75
rc.lua
|
@ -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)
|
|
@ -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 "<ctrl>b"
|
||||
unbind "<shift><ctrl>b"
|
||||
unbind "<ctrl>f"
|
||||
unbind "<shift><ctrl>f"
|
||||
unbind "<ctrl>w"
|
||||
bind "<alt>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 "<alt>b" { "move-cursor" (words, -1, 0) };
|
||||
bind "<shift><alt>b" { "move-cursor" (words, -1, 1) };
|
||||
bind "<alt>f" { "move-cursor" (words, 1, 0) };
|
||||
bind "<shift><alt>f" { "move-cursor" (words, 1, 1) };
|
||||
|
||||
bind "<ctrl>a" { "move-cursor" (paragraph-ends, -1, 0) };
|
||||
bind "<shift><ctrl>a" { "move-cursor" (paragraph-ends, -1, 1) };
|
||||
bind "<ctrl>e" { "move-cursor" (paragraph-ends, 1, 0) };
|
||||
bind "<shift><ctrl>e" { "move-cursor" (paragraph-ends, 1, 1) };
|
||||
|
||||
bind "<ctrl>y" { "paste-clipboard" () };
|
||||
|
||||
bind "<ctrl>d" { "delete-from-cursor" (chars, 1) };
|
||||
bind "<alt>d" { "delete-from-cursor" (word-ends, 1) };
|
||||
bind "<ctrl>k" { "delete-from-cursor" (paragraph-ends, 1) };
|
||||
bind "<alt>backslash" { "delete-from-cursor" (whitespace, 1) };
|
||||
bind "<alt>BackSpace" { "delete-from-cursor" (word-ends, -1) };
|
||||
|
||||
bind "<alt>space" { "delete-from-cursor" (whitespace, 1)
|
||||
"insert-at-cursor" (" ") };
|
||||
bind "<alt>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")
|
317
rc/bindings.lua
|
@ -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))
|
104
rc/debug.lua
|
@ -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: <span color="%s">%-20s</span> = <span color="%s">%s</span>\n',
|
||||
i,
|
||||
beautiful.fg_widget_label, inf[i],
|
||||
beautiful.fg_widget_value, tostring(c[inf[i]]))
|
||||
end
|
||||
|
||||
naughty.notify{ text = string.format('<span font="' .. theme.font .. '">%s</span>', 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 .. " <span color='"..colors.count.."'>#" .. count .. "</span>"
|
||||
-- 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("<span color='"..colors.index.."'>%-"..longest_key.."s</span> %s",
|
||||
tostring(key), content)
|
||||
end
|
||||
end
|
||||
else
|
||||
if vtype == "tag" or vtype == "client" then
|
||||
name = " [<span color='"..colors.name.."'>" .. (var.name or '…'):sub(1,10) .. "</span>]"
|
||||
end
|
||||
text = text .. vstring .. name or ""
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
function dbg(...)
|
||||
local num = table.maxn(arg)
|
||||
local text = "<span color='"..colors.header.."'>dbg</span> <span color='"..colors.count.."'>#"..num.."</span>"
|
||||
local depth = 2
|
||||
local clients = 0
|
||||
|
||||
for i = 1, num do
|
||||
local desc = dbg_get(arg[i], depth, 3)
|
||||
text = text .. string.format("\n<span color='"..colors.index.."'>%2d</span> %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
|
|
@ -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
|
10
rc/quake.lua
|
@ -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"))
|
62
rc/rules.lua
|
@ -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 }},
|
||||
}
|
|
@ -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)
|
164
rc/tags.lua
|
@ -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
|
74
rc/theme.lua
|
@ -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
|
318
rc/widgets.lua
|
@ -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,
|
||||
'<span color="' .. beautiful.fg_widget_clock .. '">' ..
|
||||
dateformat .. '</span>')
|
||||
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('<span color="%s">%%1</span>%%2',
|
||||
beautiful.fg_widget_clock),
|
||||
1)
|
||||
end
|
||||
-- Month and year
|
||||
cal = cal:gsub("^( +[^ ]+ [0-9]+) *",
|
||||
string.format('<span color="%s">%%1</span>',
|
||||
beautiful.fg_widget_clock))
|
||||
-- Turn anything other than days in labels
|
||||
cal = cal:gsub("(\n[^%d ]+)",
|
||||
string.format('<span color="%s">%%1</span>',
|
||||
beautiful.fg_widget_label))
|
||||
cal = cal:gsub("([%d ]+)\n?$",
|
||||
string.format('<span color="%s">%%1</span>',
|
||||
beautiful.fg_widget_label))
|
||||
calendar = naughty.notify(
|
||||
{
|
||||
text = string.format('<span font="%s">%s</span>',
|
||||
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('<span color="' .. beautiful.fg_widget_value .. '">%2d%%</span>',
|
||||
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('<span color="' .. color ..
|
||||
'">%s%d%%</span>', 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('<span color="' .. beautiful.fg_widget_value ..
|
||||
'">%08s</span>', format(down))
|
||||
-- Up
|
||||
return string.format('<span color="' .. beautiful.fg_widget_value ..
|
||||
'">%08s</span>', format(up))
|
||||
end, 3)
|
||||
|
||||
-- Memory usage
|
||||
local memwidget = widget({ type = "textbox" })
|
||||
vicious.register(memwidget, vicious.widgets.mem,
|
||||
'<span color="' .. beautiful.fg_widget_value .. '">$1%</span>',
|
||||
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,
|
||||
'<span color="' .. beautiful.fg_widget_value .. '">$2 $1%</span>',
|
||||
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<span color="' .. beautiful.fg_widget_label .. '">%s: </span>' ..
|
||||
'<span color="' .. color .. '">%2d%%</span>',
|
||||
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
|
10
rc/xlock.lua
|
@ -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))
|
|
@ -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))
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,7 +0,0 @@
|
|||
[Unit]
|
||||
Description=Wallpaper rotation for %I
|
||||
PartOf=graphical-session@%i.target
|
||||
|
||||
[Timer]
|
||||
OnUnitActiveSec=2h
|
||||
RandomizedDelaySec=10m
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
[Unit]
|
||||
Description=X session on %I
|
||||
BindsTo=graphical-session@%i.target
|
|
@ -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
|
|
@ -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
|
20
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 <<EOF
|
||||
Xresources .Xresources
|
||||
gtkrc-2.0 .gtkrc-2.0
|
||||
gtkrc-3.0 .config/gtk-3.0/settings.ini
|
||||
qt5ct.conf .config/qt5ct/qt5ct.conf
|
||||
systemd .config/systemd/user
|
||||
firefox.js .mozilla/firefox/*/user.js
|
||||
EOF
|
||||
|
||||
# Services are started with systemd
|
||||
systemctl --user import-environment
|
||||
mkdir -p ~/.config/systemd
|
||||
ln -nsf ~/.config/awesome/systemd ~/.config/systemd/user
|
||||
systemctl --user daemon-reload
|
||||
exec systemctl --user start --wait xsession@$(systemd-escape -- "$DISPLAY").target
|
||||
exec systemctl --user start --wait xsession.target
|
||||
|
|