Skip to content

Instantly share code, notes, and snippets.

@david-caro
Last active August 7, 2018 20:09
Show Gist options
  • Save david-caro/c808b363d75d67f108032fdb812ab2e5 to your computer and use it in GitHub Desktop.
Save david-caro/c808b363d75d67f108032fdb812ab2e5 to your computer and use it in GitHub Desktop.
# This file has been auto-generated by i3-config-wizard(1).
# It will not be overwritten, so edit it as you like.
#
# Should you change your keyboard layout some time, delete
# this file and re-run i3-config-wizard(1).
#
# i3 config file (v4)
#
# Please see http://i3wm.org/docs/userguide.html for a complete reference!
set $mod Mod4
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
# This font is widely installed, provides lots of unicode glyphs, right-to-left
# text rendering and scalability on retina/hidpi displays (thanks to pango).
#font pango:DejaVu Sans Mono 8
#font pango:Ubuntu Mono 12
# Before i3 v4.8, we used to recommend this one as the default:
# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# The font above is very space-efficient, that is, it looks good, sharp and
# clear in small sizes. However, its unicode glyph coverage is limited, the old
# X core fonts rendering does not support right-to-left and this being a bitmap
# font, it doesn’t scale on retina/hidpi displays.
# Use Mouse+$mod to drag floating windows to their wanted position
#floating_modifier $mod
# start a terminal
#bindsym $mod+Return exec i3-sensible-terminal
bindsym $mod+Return exec terminator
bindsym $mod+t exec terminator
#bindsym $mod+Return exec gnome-terminal
#bindsym $mod+t exec gnome-terminal
# kill focused window
bindsym $mod+Shift+q kill
# start dmenu (a program launcher)
bindsym $mod+d exec dmenu_run
# There also is the (new) i3-dmenu-desktop which only displays applications
# shipping a .desktop file. It is a wrapper around dmenu, so you need that
# installed.
# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
bindsym $mod+Shift+s exec setxkbmap -layout "es" -option "caps:swapescape"
bindsym $mod+Shift+u exec setxkbmap -layout "us" -option "caps:swapescape"
#bindsym $mod+Shift+d exec setxkbmap -layout "us" -variant "alt-intl"
bindsym $mod+Shift+d exec setxkbmap -layout "us" -variant "dvorak-alt-intl" -option "caps:swapescape"
# change focus
bindsym $mod+h focus left
bindsym $mod+j focus down
bindsym $mod+k focus up
bindsym $mod+l focus right
# alternatively, you can use the cursor keys:
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+h move left
bindsym $mod+Shift+j move down
bindsym $mod+Shift+k move up
bindsym $mod+Shift+l move right
# alternatively, you can use the cursor keys:
#bindsym $mod+Shift+Left move left
#bindsym $mod+Shift+Down move down
#bindsym $mod+Shift+Up move up
#bindsym $mod+Shift+Right move right
# split in horizontal orientation
bindsym $mod+m split h
# split in vertical orientation
bindsym $mod+v split v
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen
# 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
# focus the child container
#bindsym $mod+d focus child
# switch to workspace
bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3
bindsym $mod+4 workspace 4
bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9
bindsym $mod+0 workspace 10
# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace 1
bindsym $mod+Shift+2 move container to workspace 2
bindsym $mod+Shift+3 move container to workspace 3
bindsym $mod+Shift+4 move container to workspace 4
bindsym $mod+Shift+5 move container to workspace 5
bindsym $mod+Shift+6 move container to workspace 6
bindsym $mod+Shift+7 move container to workspace 7
bindsym $mod+Shift+8 move container to workspace 8
bindsym $mod+Shift+9 move container to workspace 9
bindsym $mod+Shift+0 move container to workspace 10
# reload the configuration file
#bindsym $mod+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Shift+r restart
# exit i3 (logs you out of your X session)
#bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {
# These bindings trigger as soon as you enter the resize mode
# Pressing left will shrink the window’s width.
# Pressing right will grow the window’s width.
# Pressing up will shrink the window’s height.
# Pressing down will grow the window’s height.
bindsym j resize shrink height 10 px or 10 ppt
bindsym k resize grow height 10 px or 10 ppt
bindsym h resize shrink width 10 px or 10 ppt
bindsym l resize grow width 10 px or 10 ppt
#
# same bindings, but for the arrow keys
bindsym Left resize shrink width 10 px or 10 ppt
bindsym Down resize grow height 10 px or 10 ppt
bindsym Up resize shrink height 10 px or 10 ppt
bindsym Right resize grow width 10 px or 10 ppt
#
# back to normal: Enter or Escape
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
bindsym $mod+x move workspace to output right
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
bar {
status_command i3status.sh
position bottom
tray_output primary
# mode hide
modifier $mod
}
exec --no-startup-id nm-applet
exec --no-startup-id kdeconnect-indicator
exec --no-startup-id /usr/libexec/kdeconnectd
# Enable touchpad tap to click
exec --no-startup-id xinput set-prop 12 277 1
bindsym $mod+Shift+t exec ~/bin/touchpad_toggle
# Pulse Audio controls
bindsym XF86AudioRaiseVolume exec volume_manage.sh up #increase sound volume
bindsym XF86AudioLowerVolume exec volume_manage.sh down #decrease sound volume
bindsym XF86AudioMute exec volume_manage.sh toggle # mute sound
bindsym XF86Launch1 exec pavucontrol
##
# Multimedia keys
bindsym XF86AudioPlay exec mpc toggle
bindsym XF86AudioPrev exec mpc prev
bindsym XF86AudioNext exec mpc next
# Sreen brightness controls
#bindsym XF86MonBrightnessUp exec xbacklight -inc 5 # increase screen brightness
#bindsym XF86MonBrightnessDown exec xbacklight -dec 5 # decrease screen brightness
bindsym XF86MonBrightnessUp exec sudo /home/dcaro/bin/backlight inc # increase screen brightness
bindsym XF86MonBrightnessDown exec sudo /home/dcaro/bin/backlight dec # decrease screen brightness
exec --no-startup-id feh --bg-scale ~/.background
set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown
mode "$mode_system" {
bindsym l exec --no-startup-id logout.sh lock, mode "default"
bindsym e exec --no-startup-id logout.sh logout, mode "default"
bindsym s exec --no-startup-id logout.sh suspend, mode "default"
bindsym h exec --no-startup-id logout.sh hibernate, mode "default"
bindsym r exec --no-startup-id logout.sh reboot, mode "default"
bindsym Shift+s exec --no-startup-id logout.sh shutdown, mode "default"
# # back to normal: Enter or Escape
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+Shift+e mode "$mode_system"
bindsym $mod+n exec --no-startup-id logout.sh lock
bindsym $mod+y exec --no-startup-id tasklist.py
bindsym $mod+Control+1 exec --no-startup-id ~/.screenlayout/laptop.sh
bindsym $mod+Control+2 exec --no-startup-id ~/.screenlayout/hometv.sh
bindsym $mod+Control+3 exec --no-startup-id ~/.screenlayout/laptop.sh
bindsym $mod+Control+4 exec --no-startup-id ~/.screenlayout/hometv.sh
## screen lock
exec xautolock -time 10 -corners 0-00 -locker 'logout.sh lock' &
## notifications with sound
exec notify.py -p ~/.notifications -p ~/.weechat/.notifications -l &>/tmp/notify.log &
## clipboard
exec parcellite &
## notification manager
exec dunst &
# i3status configuration file.
# see "man i3status" for documentation.
# It is important that this file is edited as UTF-8.
# The following line should contain a sharp s:
# ß
# If the above line is not correctly displayed, fix your editor first!
general {
colors = true
interval = 5
output_format = i3bar
}
#order += "ipv6"
#order += "run_watch DHCP"
order += "wireless wlp2s0"
#order += "ethernet enp0s25"
order += "disk /"
order += "disk /home"
#order += "run_watch VPN"
order += "battery 0"
order += "load"
order += "cpu_usage"
#order += "cpu_temperature 0"
order += "cpu_temperature 1"
order += "cpu_temperature 2"
order += "cpu_temperature 3"
order += "cpu_temperature 4"
order += "tztime local"
wireless wlp2s0 {
format_up = "W: (%quality at %essid) %ip"
format_down = "W: down"
}
ethernet enp0s25 {
format_up = "E: %ip"
format_down = "E: down"
}
battery 0 {
status_full = "☻ FULL"
status_bat = "⚡ BAT"
status_chr = "⚇ CHR"
low_threshold = "30"
threshold_type = "time"
format = "%status %percentage %remaining"
}
run_watch DHCP {
pidfile = "/var/run/dhclient*.pid"
}
run_watch VPN {
pidfile = "/var/run/vpnc/pid"
}
tztime local {
format = "%Y-%m-%d %H:%M:%S"
}
load {
format = "load %1min"
}
cpu_usage {
format = 'cpu %usage%'
}
disk "/" {
format = "/:%avail"
}
disk "/home" {
format = "/home:%avail"
}
cpu_temperature 0 {
format = "T0:%degrees°C"
path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp1_input"
}
cpu_temperature 1 {
format = "T1:%degrees°C"
path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp2_input"
}
cpu_temperature 2 {
format = "T2:%degrees°C"
path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp3_input"
}
cpu_temperature 3 {
format = "T3:%degrees°C"
path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp4_input"
}
cpu_temperature 4 {
format = "T4:%degrees°C"
path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp5_input"
}
#!/bin/bash
BLREADDEV=/sys/class/backlight/intel_backlight/actual_brightness
BLWRITEDEV=/sys/class/backlight/intel_backlight/brightness
STEP=43
MAX=431
cur_brightness() {
cat "$BLREADDEV"
}
next_step_down() {
local cur_lvl="$(cur_brightness)"
if [[ $STEP -gt $cur_lvl ]]; then
echo 0
else
echo $(($cur_lvl - $STEP))
fi
}
next_step_up() {
local cur_lvl="$(cur_brightness)"
local next_lvl="$(($cur_lvl + $STEP))"
if [[ $next_lvl -gt $MAX ]]; then
echo $MAX
else
echo $next_lvl
fi
}
main(){
local action="${1?No action passed}"
if [[ "$action" == "inc" ]]; then
echo "$(next_step_up)" > "$BLWRITEDEV"
elif [[ "$action" == "dec" ]]; then
echo "$(next_step_down)" > "$BLWRITEDEV"
fi
}
main "$@"
[global]
font = Ubuntu Mono 12
# allow a small subset of html markup:
# <b>bold</b>
# <i>italic</i>
# <s>strikethrough<s/>
# <u>underline</u>
#
# for a complete reference see http://developer.gnome.org/pango/stable/PangoMarkupFormat.html
# If markup is not allowed, those tags will be stripped out of the message.
allow_markup = yes
# The format of the message. Possible variables are:
# %a appname
# %s summary
# %b body
# %i iconname (including its path)
# %I iconname (without its path)
# %p progress value if set ([ 0%] to [100%]) or nothing
# Markup is allowed
format = "<b>%a:%s</b>\n%b"
# Sort messages by urgency
sort = yes
# Show how many messages are currently hidden (because of geometry)
indicate_hidden = yes
# alignment of message text.
# Possible values are "left", "center" and "right"
alignment = center
# The frequency with wich text that is longer than the notification
# window allows bounces back and forth.
# This option conflicts with 'word_wrap'.
# Set to 0 to disable
bounce_freq = 0
# show age of message if message is older than show_age_threshold seconds.
# set to -1 to disable
show_age_threshold = 60
# split notifications into multiple lines if they don't fit into geometry
word_wrap = yes
# ignore newlines '\n' in notifications
ignore_newline = no
# the geometry of the window
# geometry [{width}]x{height}][+/-{x}+/-{y}]
# The geometry of the message window.
# The height is measured in number of notifications everything else in pixels. If the width
# is omitted but the height is given ("-geometry x2"), the message window
# expands over the whole screen (dmenu-like). If width is 0,
# the window expands to the longest message displayed.
# A positive x is measured from the left, a negative from the
# right side of the screen. Y is measured from the top and down respectevly.
# The width can be negative. In this case the actual width is the
# screen width minus the width defined in within the geometry option.
geometry = "800x5-0+0"
# The transparency of the window. range: [0; 100]
# This option will only work if a compositing windowmanager is present (e.g. xcompmgr, compiz, etc..)
transparency = 0
# Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds.
# Set to 0 to disable.
idle_threshold = 120
# Which monitor should the notifications be displayed on.
monitor = 0
# Display notification on focused monitor. Possible modes are:
# mouse: follow mouse pointer
# keyboard: follow window with keyboard focus
# none: don't follow anything
#
# "keyboard" needs a windowmanager that exports the _NET_ACTIVE_WINDOW property.
# This should be the case for almost all modern windowmanagers.
#
# If this option is set to mouse or keyboard, the monitor option will be
# ignored.
follow = mouse
# should a notification popped up from history be sticky or
# timeout as if it would normally do.
sticky_history = yes
# The height of a single line. If the height is smaller than the font height,
# it will get raised to the font height.
# This adds empty space above and under the text.
line_height = 0
# Draw a line of 'separatpr_height' pixel height between two notifications.
# Set to 0 to disable
separator_height = 2
# padding between text and separator
padding = 8
# horizontal padding
horizontal_padding = 8
# Define a color for the separator.
# possible values are:
# * auto: dunst tries to find a color fitting to the background
# * foreground: use the same color as the foreground
# * frame: use the same color as the frame.
# * anything else will be interpreted as a X color
separator_color = foreground
# print a notification on startup
# This is mainly for error detection, since dbus (re-)starts dunst
# automatically after a crash.
startup_notification = false
# dmenu path
dmenu = /usr/bin/dmenu -p dunst:
# browser for opening urls in context menu
browser = /usr/bin/firefox -new-tab
[frame]
width = 3
color = "#aaaaaa"
[shortcuts]
# shortcuts are specified as [modifier+][modifier+]...key
# available modifiers are 'ctrl', 'mod1' (the alt-key), 'mod2', 'mod3'
# and 'mod4' (windows-key)
# xev might be helpful to find names for keys
# close notification
close = ctrl+space
# close all notifications
close_all = ctrl+shift+space
# redisplay last message(s)
# On the US keyboard layout 'grave' is normally above TAB and left of '1'.
history = ctrl+grave
# context menu
context = ctrl+shift+period
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the '#' and following would be interpreted as a comment.
background = "#222222"
foreground = "#888888"
timeout = 10
[urgency_normal]
background = "#6B97B9"
foreground = "#ffffff"
timeout = 20
[urgency_critical]
background = "#900000"
foreground = "#ffffff"
timeout = 0
# Every section that isn't one of the above is interpreted as a rules
# to override settings for certain messages.
# Messages can be matched by 'appname', 'summary', 'body' or 'icon'
# and you can override the 'timeout', 'urgency', 'foreground', 'background'
# and 'format'.
# Shell-like globbing will get expanded.
#
# SCRIPTING
# you can specify a script that gets run when the rule matches by setting
# the 'script' option.
# The script will be called as follows:
# script appname summary body icon urgency
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
#
# NOTE: if you don't want a notification to be displayed, set the format to ""
# NOTE: It might be helpful to run dunst -print in a terminal in order to find
# fitting options for rules.
#[espeak]
# summary = "*"
# script = dunst_espeak.sh
#[script-test]
# summary = "*script*"
# script = dunst_test.sh
#[ignore]
## This notification will not be displayed
# summary = "foobar"
# format = ""
#[signed_on]
# appname = Pidgin
# summary = "*signed on*"
# urgency = low
#
#[signed_off]
# appname = Pidgin
# summary = *signed off*
# urgency = low
#
#[says]
# appname = Pidgin
# summary = *says*
# urgency = critical
#
#[twitter]
# appname = Pidgin
# summary = *twitter.com*
# urgency = normal
#
[weechat]
appname = *weechat*
background = "#22ff22"
foreground = "#444400"
#!/bin/bash
vpn(){
if ip addr show tun0 &>/dev/null; then
echo '{"full_text": "VPN: yes", "color": "#00FF00"}'
else
echo '{"full_text": "VPN: no", "color": "#FF0000"}'
fi
}
volume(){
cur_vol=$(volume_manage.sh get_vol)
is_muted=$(volume_manage.sh is_muted)
if [[ "$is_muted" != "yes" ]]; then
echo "{\"full_text\": \"♬:$cur_vol\"}"
else
echo "{\"full_text\": \"♬:muted\", \"color\": \"#FF0000\"}"
fi
}
kerberos(){
account="$(klist -l | tail -n +3 | tail -n1)"
account="${account%% *}"
if [[ "$account" ]]; then
echo "{\"full_text\": \"KRB: $account\", \"color\": \"#00FF00\"}"
else
echo "{\"full_text\": \"KRB: logged out\", \"color\": \"#FF0000\"}"
fi
}
# For colors, your i3status.conf should contain:
# general {
# output_format = i3bar
# }
# i3 config looks like this:
# bar {
# status_command measure-net-speed-i3status.bash
# }
i3status \
| ( \
read line && echo $line \
&& read line && echo $line \
&& while :
do
read line
dat="[ "
dat+="$(kerberos), "
dat+="$(volume),"
dat+="{ \"full_text\": \"$(netspeed.sh)\" },"
dat+="$(vpn),"
echo "${line/[/$dat}" || exit 1
done
)
#!/bin/sh
lock() {
i3lock \
--ignore-empty-password \
--show-failed-attempts \
--image ~/.lock_bg.png \
--dpms
}
case "$1" in
lock)
lock
;;
logout)
i3-msg exit
;;
suspend)
lock && systemctl suspend
;;
hibernate)
lock && systemctl hibernate
;;
reboot)
systemctl reboot
;;
shutdown)
systemctl poweroff
;;
*)
echo "Usage: $0 {lock|logout|suspend|hibernate|reboot|shutdown}"
exit 2
esac
exit 0
#!/bin/bash
# Public Domain
# (someone claimed the next lines would be useful for…
# people. So here goes: © 2012 Stefan Breunig
# stefan+measure-net-speed@mathphys.fsk.uni-heidelberg.de)
# path to store the old results in
path="/tmp/measure-net-speed"
# grabbing data for each adapter.
# You can find the paths to your adapters using
# find /sys/devices -name statistics
# If you have more (or less) than two adapters, simply adjust the script here
# and in the next block.
eth0="$( find /sys/devices/ -iname eth0)/statistics"
wlan_iface="$(iwconfig 2>&1 | grep -v 'no wireless' | grep -o '^\w\+')"
wlan0="$( find /sys/devices/ -iname "$wlan_iface")/statistics"
#read eth0_rx < "${eth0}/rx_bytes"
#read eth0_tx < "${eth0}/tx_bytes"
eth0_rx=0
eth0_tx=0
read wlan0_rx < "${wlan0}/rx_bytes"
read wlan0_tx < "${wlan0}/tx_bytes"
wlan0_rx="$wlan0_rx"
wlan0_tx="$wlan0_tx"
# get time and sum of rx/tx for combined display
time=$(date +%s)
rx=$(( $eth0_rx + $wlan0_rx ))
tx=$(( $eth0_tx + $wlan0_tx ))
# write current data if file does not exist. Do not exit, this will cause
# problems if this file is sourced instead of executed as another process.
if ! [[ -f "${path}" ]]; then
echo "${time} ${rx} ${tx}" > "${path}"
chmod 0666 "${path}"
fi
# read previous state and update data storage
read old < "${path}"
echo "${time} ${rx} ${tx}" > "${path}"
# parse old data and calc time passed
old=(${old//;/ })
time_diff=$(( $time - ${old[0]} ))
# sanity check: has a positive amount of time passed
if [[ "${time_diff}" -gt 0 ]]; then
# calc bytes transferred, and their rate in byte/s
rx_diff=$(( $rx - ${old[1]} ))
tx_diff=$(( $tx - ${old[2]} ))
rx_rate=$(( $rx_diff / $time_diff ))
tx_rate=$(( $tx_diff / $time_diff ))
# shift by 10 bytes to get KiB/s. If the value is larger than
# 1024^2 = 1048576, then display MiB/s instead (simply cut off
# the last two digits of KiB/s). Since the values only give an
# rough estimate anyway, this improper rounding is negligible.
# incoming
rx_kib=$(( $rx_rate >> 10 ))
if [[ "$rx_rate" -gt 1048576 ]]; then
echo -n "${rx_kib:0:-3}.${rx_kib: -3:-2} M↓"
elif [[ "$rx_kib" -gt 0 ]]; then
echo -n "${rx_kib} K↓"
else
echo -n "${rx_rate} b↓"
fi
echo -n " "
# outgoing
tx_kib=$(( $tx_rate >> 10 ))
if [[ "$tx_rate" -gt 1048576 ]]; then
echo -n "${tx_kib:0:-3}.${tx_kib: -3:-2} M↑"
elif [[ "$tx_kib" -gt 0 ]]; then
echo -n "${tx_kib} K↑"
else
echo -n "${tx_rate} b↑"
fi
else
echo -n " ? "
fi
#!/usr/bin/python
#
# Copyright (C) 2012 Paul W. Frields <stickster@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os, sys
try:
from gi.repository import Notify, GObject
except:
print >> sys.stderr, 'Could not locate pygobject'
sys.exit(-1)
import dbus
import dbus.mainloop.glib
from subprocess import call
player = None
for path in os.environ['PATH'].split(os.pathsep):
if os.path.isfile(os.path.join(path, 'canberra-gtk-play')):
player = os.path.join(path, 'canberra-gtk-play')
break
class IrssiListener:
def __init__(self):
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
self.bus = dbus.SessionBus()
self.bus.add_signal_receiver(self.notify,
signal_name='IrssiNotify',
dbus_interface='org.irssi.Irssi',
path='/org/irssi/Irssi')
Notify.init('irssi')
def notify(self, subject, message):
print subject, message
n = Notify.Notification.new(subject.encode('utf-8'),
message.encode('utf-8'),
'dialog-information')
n.show()
# It would be more kosher to do this with GStreamer, but in
# the interest of time:
if player is not None:
retcode = call([player, '-i', 'message-new-instant'])
if retcode < 0:
print "ERROR: Player returned code %d" % (retcode)
def __del__(self):
Notify.uninit()
if __name__ == '__main__':
l = IrssiListener()
loop = GObject.MainLoop()
loop.run()
#!/usr/bin/env python
# encoding: utf-8
import time
import os
import argparse
import logging
from multiprocessing import (
Process,
Queue,
)
import subprocess
class AsynchronousFileReader(Process):
'''
Helper class to implement asynchronous reading of a file
in a separate thread. Pushes read lines on a queue to
be consumed in another thread.
'''
def __init__(self, fname, queue):
super(AsynchronousFileReader, self).__init__()
self._fname = fname
self._queue = queue
def run(self):
'''The body of the tread: read lines and put them on the queue.'''
logging.info('Reader %s starting', self._fname)
while True:
with open(self._fname, 'r') as pipe_fd:
line = pipe_fd.readline()
logging.debug('Reader %s got %s', self._fname, line)
self._queue.put(line)
def play(filename):
if os.path.exists(filename):
logging.debug('Playing ' + filename)
subprocess.Popen([
'paplay',
filename,
])
else:
logging.warn('Sound file %s not found', filename)
def notifier(name, queue):
import pynotify
pynotify.init(name)
logging.info("%d-%s::I'm alive! ", os.getpid(), name)
processes = []
try:
while True:
icon, subject, sound, message = queue.get()
if subject == 'EXIT' and not message:
return
logging.info("%d-%s:: Got %s", os.getpid(), name, subject + message)
if icon:
win = pynotify.Notification(subject, message, icon=icon)
else:
win = pynotify.Notification(subject, message)
win.show()
processes.append(Process(
target=play,
args=(sound,),
))
processes[-1].start()
finally:
for process in processes:
process.terminate()
process.join()
def read_value(readers):
value = None
while value is None:
for queue, _ in readers.values():
if not queue.is_empty():
value = queue.get()
break
else:
time.sleep(.1)
return value
def server(pipes=None):
if pipes is None:
pipes = [os.path.expanduser('~/.notifications')]
logging.info("Server starting on %s" % pipes)
for pname in pipes:
if not os.path.exists(pname):
logging.info("Creating non-existent pipe " + pname)
os.mkfifo(pname)
readers = {}
read_queue = Queue()
for pname in pipes:
readers[pname] = AsynchronousFileReader(pname, read_queue)
for reader in readers.values():
reader.start()
notifiers = {}
try:
while True:
what = read_queue.get()
if not what:
time.sleep(1)
continue
logging.info("Got " + what)
parts = what.split('||', 5)
if len(parts) != 5:
continue
not_name = parts[0]
if not_name not in notifiers:
queue = Queue()
logging.info("Launching notifier process " + not_name)
notifiers[not_name] = (
Process(target=notifier, args=(not_name, queue)),
queue)
notifiers[not_name][0].start()
notifiers[not_name][1].put(parts[1:])
finally:
for name, data in notifiers.iteritems():
proc, queue = data
queue.put(['EXIT', ''])
logging.info("Waiting for notifier " + name)
proc.terminate()
proc.join()
for pname, reader in readers.items():
logging.info("Waiting for reader " + pname)
reader.terminate()
reader.join()
def send_one(message, subject='', app='notifier', icon='',
pname=os.path.expanduser('~/.notifications'),
sound=None):
pname = pname or os.path.expanduser('~/.notifications')
with open(pname, 'w') as pipe:
pipe.write('||'.join([app, icon, subject, sound, message]))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('message', nargs='?', action='store', default='',
help='Subject')
parser.add_argument('-l', '--listen', action='store_true', default=False,
help='Listen for notification')
parser.add_argument('-s', '--subject', action='store', default='',
help='Subject')
parser.add_argument('-i', '--icon', action='store', default='',
help='Icon')
parser.add_argument('-p', '--pipe', action='append',
help='Pipe to send the notificaiton to')
parser.add_argument('-a', '--application', action='store',
default='notification',
help='Application name to use')
parser.add_argument('-S', '--sound', action='store',
default='',
help='sound file to play')
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG)
if args.listen:
server(args.pipe)
else:
send_one(
message=args.message,
subject=args.subject,
app=args.application,
icon=args.icon,
pname=args.pipe[0] if args.pipe else None,
sound=args.sound,
)
#!/bin/bash -eu
handle_gnome() {
local cur_status=$(\
gsettings get org.gnome.desktop.peripherals.touchpad send-events \
)
if [[ "$cur_status" == "'enabled'" ]]; then
action=disabled
else
action=enabled
fi
gsettings set org.gnome.desktop.peripherals.touchpad send-events "$action"
}
xinput_enable() {
local touchpad_dev="${1?}"
local enable_prop_num="${2?}"
local click_prop_num=$(\
xinput list-props "$touchpad_dev"\
| grep -i 'tapping enabled (' \
| grep -o '(\w\+)' \
| grep -o '\w\+' \
)
xinput set-prop "$touchpad_dev" "$enable_prop_num" 1
xinput set-prop "$touchpad_dev" "$click_prop_num" 1
}
xinput_disable() {
local touchpad_dev="${1?}"
local enable_prop_num="${2?}"
xinput set-prop "$touchpad_dev" "$enable_prop_num" 0
}
handle_xinput() {
local touchpad_dev=$(\
xinput \
| grep -i touchpad \
| grep -vi synaptics \
| grep -o 'id=\w\+' \
| cut -d'=' -f2 \
| tail -n 1 \
)
local enable_prop_num=$(\
xinput list-props "$touchpad_dev"\
| grep -i 'device enabled' \
| grep -o '(\w\+)' \
| grep -o '\w\+' \
)
local enable_prop_status=$(\
xinput list-props "$touchpad_dev"\
| grep -i 'device enabled' \
| grep -o '\w$' \
)
case $enable_prop_status in
1) xinput_disable "$touchpad_dev" "$enable_prop_num";;
0) xinput_enable "$touchpad_dev" "$enable_prop_num";;
esac
}
main() {
if [[ "$DESKTOP_SESSION" == "i3" ]]; then
handle_xinput
else
handle_gnome
fi
}
main "$@"
#!/bin/bash
help() {
cat <<EOF
Usage: $0 [up|down|toggle|list_ins|list_outs|set_out|choose_out|help]
Manages the system volume for all the active sinks
EOF
exit
}
get_sinks(){
pactl list sinks \
| grep "^Sink" \
| awk '{ print $2 }' \
| grep -o '[[:digit:]]\+'
}
get_current_sink(){
pacmd list-sinks \
| egrep -e "\* index:" \
| grep -o '[[:digit:]]*'
}
up(){
local sink
for sink in $(get_sinks); do
pactl set-sink-volume $sink +5%
done
}
down(){
local sink
for sink in $(get_sinks); do
pactl set-sink-volume $sink -5%
done
}
mute_toggle(){
local sink
for sink in $(get_sinks); do
pactl set-sink-mute $sink toggle
done
}
get_vol(){
local cur_sink
cur_sink=$(get_current_sink)
pacmd list-sinks \
| egrep -e "(index: $cur_sink|^[[:space:]]*volume:)" \
| sed -n "/index: $cur_sink/,/volume:/p" \
| grep -o '[[:digit:]]\+%' \
| head -n1
}
is_muted(){
local cur_sink
cur_sink=$(get_current_sink)
pacmd list-sinks \
| egrep -e "(index: $cur_sink|^[[:space:]]*muted:)" \
| sed -n "/index: $cur_sink/,/muted:/p" \
| grep "muted:" \
| egrep -o "(yes|no)" \
| head -n1
}
list_ins(){
local outs index name line out
inputs=()
index=''
client=''
while read line; do
case $line in
index*) index="${line#*: }" ;;
\*\ index*) index="*${line#*: }" ;;
client*)
client="${line#*: }"
inputs+=("$index: $client")
index=''
;;
esac
done< <(pacmd list-sink-inputs | egrep -e "(index:|client:)")
for input in "${inputs[@]}"; do
echo "$input"
done
}
list_outs(){
local outs index name line out
outs=()
index=''
name=''
while read line; do
case $line in
index*) index="${line#*: }" ;;
\*\ index*) index="*${line#*: }" ;;
name*)
name="${line#*: }"
outs+=("$index: $name")
index=''
;;
esac
done< <(pacmd list-sinks | egrep -e "(index:|name:)")
for out in "${outs[@]}"; do
echo "$out"
done
}
set_out(){
local to_set input_id
to_set="${1?}"
pacmd set-default-sink "$to_set"
while read input; do
input_id="${input%%:*}"
pacmd move-sink-input "$input_id" "$to_set"
done< <(list_ins)
}
is_in() {
local what where
what="${1?}"
shift
for where in "$@"; do
if [[ "$where" == "$what" ]]; then
return 0
fi
done
return 1
}
choose_out(){
local out_ids out ans
out_ids=()
while read out; do
out="${out%%:*}"
out_ids+=("${out#\*}")
done< <(list_outs)
while true; do
echo "Available outs:"
list_outs
echo "Pick one: "
read ans
ans="${ans: -1}"
if is_in "${ans}" "${out_ids[@]}"; then
set_out "$ans"
return 0
fi
echo -n "Wrong answer. "
done
}
choose_out_gui(){
local outs out_id out id
outs=()
while read out; do
out_id="${out%%:*}"
outs+=("" "${out#\*}" "${out%%*: }")
done< <(list_outs)
id="$(
zenity \
--title="Select out device" \
--list \
--radiolist \
--column="" \
--column="ids" \
--column="names" \
--hide-column="2" \
"${outs[@]}"
)"
if [[ "$id" ]]; then
id="${id#\*}"
set_out "${id%%:*}"
return 0
fi
}
if ! [[ "$1" ]]; then
choose_out_gui
exit
fi
case $1 in
up) up;;
down) down;;
toggle) mute_toggle;;
get_vol) get_vol;;
is_muted) is_muted;;
list_outs) list_outs;;
list_ins) list_ins;;
set_out) set_out "$2";;
choose_out) choose_out;;
*) help;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment