commit 554573c69b7fa59ae5cb881fb1c5f4e0899f0c63 Author: kuben Date: Tue Jul 2 21:47:58 2019 +0200 First commit. Add .i3 directory diff --git a/.i3/.autostart b/.i3/.autostart new file mode 100644 index 0000000..8caa782 --- /dev/null +++ b/.i3/.autostart @@ -0,0 +1,10 @@ +sleep 2 +conky -c ~/.conky/arch/.conkyrc-arch & +conky -c ~/.conky/gmail/.conkyrc-gmail & +conky -c ~/.conky/weather/.conkyrc-weather1 & +conky -c ~/.conky/weather/.conkyrc-weather2 & +conky -c ~/.conky/music/.conkyrc-music & +python ~/.conky/music/playerctl_listen.py & +sh ~/.conky/music/launcher.sh & +python ~/.i3/lemonbar/i3_lemonbar_launcher.py --debug >> /tmp/kuba_lemonbar_launcher.log & +compton -b # --config=/home/kuba/.compton.conf diff --git a/.i3/config b/.i3/config new file mode 100644 index 0000000..56a0aab --- /dev/null +++ b/.i3/config @@ -0,0 +1,288 @@ +# 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 +set $TERMINAL terminator +#set $CONKY /home/kuba/git/conky/build/src/conky symlink instead +set $w1 1 main +set $w2 2 web +set $w3 3 mu +set $w4 4 work +set $w5 5 terms +set $w6 6 stats +set $w7 7 +set $w8 8 +set $w9 9 +set $w10 10 games + +set $below_barY 24 +#set $volX 1400 +#set $brX 1485 +#set $calX 1650 +set $htopX 400 +set $pavuX 800 + +# 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:FontAwesome 11 +# 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 + +#### +# Global Settings +#### + +focus_follows_mouse no +mouse_warping none +for_window [class="Terminator"] border pixel 0 +for_window [class="YADWIN"] floating enable +for_window [class="FLOAT_PAVU"] floating enable +for_window [class="FLOAT_PAVU"] resize set 800 540 +for_window [class="FLOAT_PAVU"] border pixel 3 +for_window [class="FLOAT_PAVU"] move absolute position $pavuX px $below_barY px +for_window [window_role="FLOAT_TERM"] floating enable +for_window [window_role="FLOAT_TERM"] move absolute position $htopX px $below_barY px +for_window [window_role="FLOAT_TERM"] border pixel 3 +for_window [title="Memory"] floating enable +for_window [class="Matplotlib"] floating enable +for_window [class="Chromium"] border pixel 0 +for_window [class="^.*"] border pixel 0 +for_window [window_type="toolbar"] border pixel 3 +for_window [window_type="splash"] border pixel 3 +for_window [window_type="dialog"] border pixel 3 +for_window [window_type="utility"] border pixel 3 +for_window [window_role="pop-up"] floating enable +for_window [title="VMD 1.9.3 OpenGL Display"] floating enable +for_window [title="Figure *"] floating enable +#for_window [title="VMD"] floating enable +workspace_auto_back_and_forth yes +#force_display_urgency_hint 500 ms + +assign [class="Firefox"] → $w2 +assign [class="Chromium"] → $w2 +for_window [class="Spotify"] move to workspace $w3 +#Spotify bug, assign doesn't work +assign [class="libreoffice*"] → $w4 +assign [class="soffice*"] → $w4 +assign [class="MATLAB*"] → $w4 +assign [window_role="ranger"] → $w1 +assign [window_role="terms"] → $w5 +assign [window_role="stats"] → $w6 +assign [class="Minecraft*"] → $w10 +assign [title="Feed The Beast Launcher*"] → $w10 + + + + +#### +# gaps settings +#### + +gaps inner 0 +gaps outer 0 + +workspace 1 gaps inner 10 +workspace 5 gaps inner 10 +workspace 6 gaps inner 60 + +#### +# Bindings +#### + +# pulse audio volume control +bindsym XF86AudioRaiseVolume exec ~/.i3/scripts/level.sh -v up +bindsym XF86AudioLowerVolume exec ~/.i3/scripts/level.sh -v down +bindsym XF86AudioMute exec ~/.i3/scripts/level.sh -v toggle +#bindsym XF86Launch1 exec /usr/bin/pactl play-sample that_was_easy +#bindsym XF86MonBrightnessDown exec /usr/bin/kbdlight down 20 +bindsym XF86MonBrightnessUp exec ~/.i3/scripts/level.sh -b up +bindsym XF86MonBrightnessDown exec ~/.i3/scripts/level.sh -b down +bindsym $mod+F8 exec playerctl play-pause +bindsym $mod+F9 exec playerctl next +bindsym $mod+F7 exec playerctl previous +bindsym XF86AudioPlay exec playerctl play +bindsym XF86AudioPause exec playerctl pause +bindsym XF86AudioNext exec playerctl next +bindsym XF86AudioPrevious exec playerctl previous + + + +# start a terminal +#bindsym $mod+Return exec 'i3-sensible-terminal border pixel 0' +bindsym $mod+Return exec $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+Shift+d exec --no-startup-id i3-dmenu-desktop + +# change focus +bindsym $mod+j focus left +bindsym $mod+k focus down +bindsym $mod+l focus up +bindsym $mod+semicolon 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+j move left +bindsym $mod+Shift+k move down +bindsym $mod+Shift+l move up +bindsym $mod+Shift+semicolon 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+h split h + +# split in vertical orientation +bindsym $mod+v split v + +# 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 + +# focus the child container +#bindsym $mod+d focus child + +bindsym $mod+m exec sh ~/.i3/scripts/lang.sh next + +# switch to workspace +bindsym $mod+1 workspace number $w1 +bindsym $mod+2 workspace number $w2 +bindsym $mod+3 workspace number $w3 +bindsym $mod+4 workspace number $w4 +bindsym $mod+5 workspace number $w5 +bindsym $mod+6 workspace number $w6 +bindsym $mod+7 workspace number $w7 +bindsym $mod+8 workspace number $w8 +bindsym $mod+9 workspace number $w9 +bindsym $mod+0 workspace number $w10 + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace number $w1 +bindsym $mod+Shift+2 move container to workspace number $w2 +bindsym $mod+Shift+3 move container to workspace number $w3 +bindsym $mod+Shift+4 move container to workspace number $w4 +bindsym $mod+Shift+5 move container to workspace number $w5 +bindsym $mod+Shift+6 move container to workspace number $w6 +bindsym $mod+Shift+7 move container to workspace number $w7 +bindsym $mod+Shift+8 move container to workspace number $w8 +bindsym $mod+Shift+9 move container to workspace number $w9 +bindsym $mod+Shift+0 move container to workspace number $w10 + +bindsym $mod+o move workspace to output right + +# 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'" + +bindsym XF86Sleep exec sh ~/.i3/i3exit.sh lock +bindsym Print exec scrot '%Y-%m-%d-%T_$wx$h_scrot.png' -e 'mv $f ~/Obrazy/screenshots/' +bindsym Shift + Print exec scrot -s '%Y-%m-%d-%T_$wx$h_scrot.png' -e 'mv $f ~/Obrazy/screenshots/' + +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 .i3/i3exit.sh lock, mode "default" + bindsym e exec --no-startup-id .i3/i3exit.sh logout, mode "default" + bindsym s exec --no-startup-id .i3/i3exit.sh suspend, mode "default" + bindsym h exec --no-startup-id .i3/i3exit.sh hibernate, mode "default" + bindsym r exec --no-startup-id .i3/i3exit.sh reboot, mode "default" + bindsym Shift+s exec --no-startup-id .i3/i3exit.sh shutdown, mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default"; exec sh .i3/lemonbar/set_mode.sh mode normal + bindsym Escape mode "default"; exec sh .i3/lemonbar/set_mode.sh mode normal +} +bindsym XF86PowerOff mode "$mode_system"; exec sh .i3/lemonbar/set_mode.sh mode power + +# 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 width 10 px or 10 ppt + bindsym k resize grow height 10 px or 10 ppt + bindsym l resize shrink height 10 px or 10 ppt + bindsym semicolon 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" +#### +# layout settings +#### +bindsym $mod+u exec feh --bg-scale /home/kuba/Obrazy/Wallpapers/AxEcN\ -\ Imgur.jpg +#exec compton -b +#workspace 1 main +exec --no-startup-id $TERMINAL --role "ranger" -x ranger + +#exec --no-startup-id i3-msg 'workspace 5 terms" +exec --no-startup-id $TERMINAL -p terms --role "terms" +exec --no-startup-id $TERMINAL -p terms --role "terms" + +#workspace 6 stats; +exec --no-startup-id i3-msg 'append_layout /home/kuba/.i3/workspace_6.json; rename workspace to "6 stats"' +#Set appropriate background image before starting conkys +exec --no-startup-id feh --bg-scale /home/kuba/Obrazy/Wallpapers/6_stats + +#Start conky's in .i3/.autostart +exec sh ~/.i3/.autostart diff --git a/.i3/i3exit.sh b/.i3/i3exit.sh new file mode 100644 index 0000000..31ce143 --- /dev/null +++ b/.i3/i3exit.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +lock() { + # Credit: https://github.com/petvas/i3lock-blur + # TODO Handle several screens + TMPBG=/tmp/screen_locked.png + LOCK=~/.i3/lock.png + RES=$(xrandr | grep 'current' | sed -E 's/.*current\s([0-9]+)\sx\s([0-9]+).*/\1x\2/') + + #ffmpeg -f x11grab -video_size $RES -y -i $DISPLAY -i $LOCK -filter_complex \ + # "boxblur=5:1,overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" \ + # -vframes 1 $TMPBG -loglevel quiet + ffmpeg -f x11grab -video_size $RES -y -i $DISPLAY -filter_complex \ + "boxblur=5:1" -vframes 1 $TMPBG -loglevel quiet + i3lock -i $TMPBG + rm $TMPBG +} + +case "$1" in + lock) + lock + ;; + logout) + i3-msg exit + ;; + suspend) + lock && sudo pm-suspend + ;; + lidclose) + lock && sudo pm-suspend + ;; + hibernate) + lock && sudo pm-hibernate + ;; + reboot) + systemctl reboot + ;; + shutdown) + systemctl poweroff + ;; + *) + echo "Usage: $0 {lock|logout|suspend|hibernate|reboot|shutdown}" + exit 2 +esac + +exit 0 diff --git a/.i3/lemonbar/cache/credentials.json b/.i3/lemonbar/cache/credentials.json new file mode 100644 index 0000000..28801a2 --- /dev/null +++ b/.i3/lemonbar/cache/credentials.json @@ -0,0 +1 @@ +{"username":"kuben-","auth_type":1,"auth_data":"QVFDYzhMY0tnZ2g2M2N1czFhcXI4c0xRMkQzc3pRdXlFZVVVeEVzN0xRRE1VSnItVmw3Z05XWWhRVUNCX2pqS25mSXhGcVRyV0RFcGtTWVFMR3pzSG1jZVdTY0JnNnJFT0hDdFptdzM="} \ No newline at end of file diff --git a/.i3/lemonbar/cache/volume b/.i3/lemonbar/cache/volume new file mode 100644 index 0000000..6ffbe60 --- /dev/null +++ b/.i3/lemonbar/cache/volume @@ -0,0 +1 @@ +49151 \ No newline at end of file diff --git a/.i3/lemonbar/conky_fast b/.i3/lemonbar/conky_fast new file mode 100644 index 0000000..d18237a --- /dev/null +++ b/.i3/lemonbar/conky_fast @@ -0,0 +1,27 @@ + -- Conky for external bar + -- out simple text to console + +conky.config = { + background=false, + update_interval=0.2, + total_run_times=0, + override_utf8_locale=true, + short_units=true, + uppercase=false, + out_to_console=true, + out_to_x=false, + if_up_strictness='address', + format_human_readable=true, +} + +conky.text = [[ +CNK_FAST \ +${time %a %d %b %H:%M:%S} \ +${exec ~/.i3/lemonbar/get_vol.sh} \ +${if_up wlp3s0}${downspeedf wlp3s0} ${upspeedf wlp3s0}\ +${else}down down${endif}\ + \ +${if_up enp2s0}${downspeedf enp2s0} ${upspeedf enp2s0}\ +${else}down down${endif}\ + \ +]] diff --git a/.i3/lemonbar/conky_slow b/.i3/lemonbar/conky_slow new file mode 100644 index 0000000..47b10c7 --- /dev/null +++ b/.i3/lemonbar/conky_slow @@ -0,0 +1,26 @@ + -- Conky for external bar + -- out simple text to console + +conky.config = { + background=false, + update_interval=5, + total_run_times=0, + override_utf8_locale=true, + short_units=true, + uppercase=false, + out_to_console=true, + out_to_x=false, + if_up_strictness='address', + format_human_readable=true, +} + +conky.text = [[ +CNK_SLOW \ +${cpu} \ +${mem} \ +${fs_used_perc /} \ +${fs_used_perc /home} \ +${exec ~/.i3/lemonbar/get_bat.sh} \ +${exec brillo} \ +${exec /home/kuba/.i3/scripts/lang.sh show} +]] diff --git a/.i3/lemonbar/get_bat.sh b/.i3/lemonbar/get_bat.sh new file mode 100644 index 0000000..df85522 --- /dev/null +++ b/.i3/lemonbar/get_bat.sh @@ -0,0 +1,5 @@ +#!/bin/bash +acpi | head -n 1 | awk '{pct = substr($4, 1, length($4)-2);\ + if($3 ~ "Dis") print "D"pct;\ + else if($3 ~ "Cha") printf "C"pct;\ + else print "F"substr($5, 1, length($5)-1);}' diff --git a/.i3/lemonbar/get_vol.sh b/.i3/lemonbar/get_vol.sh new file mode 100644 index 0000000..f67f3b6 --- /dev/null +++ b/.i3/lemonbar/get_vol.sh @@ -0,0 +1,8 @@ +#!/bin/bash +RTN=$(amixer get Master | grep "Front Left: Playback" | \ + awk -F'[]%[]' '{if ($5 == "off") {print "MUTE"} else {printf "%d", $2}}') +if [[ -z $RTN ]]; then + echo "NONE" +else + echo "$RTN" +fi diff --git a/.i3/lemonbar/i3_lemonbar_common.py b/.i3/lemonbar/i3_lemonbar_common.py new file mode 100644 index 0000000..963506a --- /dev/null +++ b/.i3/lemonbar/i3_lemonbar_common.py @@ -0,0 +1,95 @@ +import subprocess +from enum import Enum + +import i3_lemonbar_config as config + +p_bluetooth = None +kill_on_unfocus = [] + +class bar_mode(Enum): + power, normal, control = range(-1,2) # Don't cycle through power + + def cycle(self): + try: + return bar_mode(self.value + 1) + except ValueError: + return bar_mode(0) + +mode = bar_mode.normal + +floatterm_args = lambda prog : ['terminator', '-r', 'FLOAT_TERM', '-p' + , 'dark', '-e', 'echo kill_unfocus $$ > {}; exec {}'.format( + config.fifo_file_executor, prog)] +def date_comm(args): + subprocess.Popen(['yad', '--no-buttons', '--calendar', '--sticky' + , '--on-top' , '--class' , '"YADWIN"', '--posx=1650', '--posy=24' + , '--close-on-unfocus']) + +def pavu_comm(args): + global kill_on_unfocus + p = subprocess.Popen(['pavucontrol', '--class=FLOAT_PAVU']) + kill_on_unfocus.append(p.pid) + +def htop_comm(args): + subprocess.Popen(floatterm_args('htop')) + +def nmtui_comm(args): + subprocess.Popen(floatterm_args('nmtui')) +def lang_comm(args): + subprocess.Popen(['sh', '/home/kuba/.i3/scripts/lang.sh', 'next']) +def dpms_comm(args): + subprocess.Popen(['sh', '/home/kuba/.i3/scripts/dpmsctl.sh']) +def adj_br(args): + subprocess.Popen(['/home/kuba/.i3/scripts/adjbr.sh', '-b', config.fifo_file_executor]) +def i3msg_comm(args): + subprocess.Popen(args.split()) +def add_tokill(args): + global kill_on_unfocus + kill_on_unfocus.append(int(args.split()[1])) +def set_mode(args): + global mode + new_mode = args.split()[1] + if new_mode == "cycle": + mode = mode.cycle() + + for m in bar_mode: + if new_mode == m.name: + mode = m + break +def bluetooth(args): + btcargs = args.split()[1:] + btcargs = [a.replace('pxc550', '00:16:94:22:29:0E') for a in btcargs] + btcargs.append('\n') + inp = ' '.join(btcargs) + p_bluetooth.stdin.write(inp) + p_bluetooth.stdin.flush() + +show_secs = False +def toggle_secs(args): + global show_secs + show_secs = not show_secs + +# Keymaps +def_keymap = 'pl' +keymaps = {'Firefox': 'se'} +cur_class = '' +def set_lang(args): + global keymaps + lang = args.split()[1] + keymaps[cur_class] = lang + +commands_dict = {'toggle_secs': toggle_secs + ,'date': date_comm + ,'pavu': pavu_comm + ,'load': htop_comm + ,'wlan': nmtui_comm + ,'dpms': dpms_comm + ,'i3-msg': i3msg_comm + ,'switch_lang': lang_comm + ,'kill_unfocus': add_tokill + ,'mode': set_mode + ,'adj_br': adj_br + ,'setlang': set_lang + ,'bluetooth': bluetooth + } + diff --git a/.i3/lemonbar/i3_lemonbar_config.py b/.i3/lemonbar/i3_lemonbar_config.py new file mode 100644 index 0000000..6635cb9 --- /dev/null +++ b/.i3/lemonbar/i3_lemonbar_config.py @@ -0,0 +1,86 @@ +import subprocess +import getpass + +pid_file = '/tmp/i3_lemonbar_launcher.pid' +fifo_file_status = '/tmp/i3_lemonbar1_{}'.format(getpass.getuser()) +fifo_file_executor= '/tmp/i3_lemonbar2_{}'.format(getpass.getuser()) +health_file = '/tmp/i3_lemonbar_health.info' + +path="/home/kuba/.i3/lemonbar/" +logpath="/home/kuba/lemonbar.log" # Write here on exceptions +geometry="x24" +#font="xos4 Terminess Powerline:pixelsize=12:style=Bold" +#iconfont="-misc-font awesome 5 free-medium-r-normal--0-0-0-0-p-0-iso10646-1" +fonts = ["Hack:pixelsize=12" #":style=Bold" + ,"Font Awesome 5 Free Solid:pixelsize=16" + ,"Font Awesome 5 Brands:pixelsize=16"] + +cpu_alert = 75 +net_alert = 5 + +# color definitions +color_back="#FF1D1F21" # Default background +color_fore="#FFC5C8C6" # Default foreground +color_poweropts = "#FF620A00" +color_head="#FFB5BD68" # Background for first element +color_sec_b1="#FF282A2E" # Background for section 1 +color_sec_b2="#FF454A4F" # Background for section 2 +color_sec_b3="#FF60676E" # Background for section 3 +color_vga="#FF3F8C0F" +color_hdmi="#FFDD5435" +color_icon="#FF979997" # For icons +color_cpu="#FF5F819D" # Background color for cpu alert +color_net="#FF5E8D87" # Background color for net alert +color_disable="#FF1D1F21" # Foreground for disable elements +color_wsp="#FF8C9440" # Background for selected workspace + +lemonbar_args = ['lemonbar', '-p', '-g', geometry, '-B', color_back + , '-F', color_fore, '-a' '20'] +for font in fonts: + lemonbar_args.append('-f') + lemonbar_args.append(font) + +#default space between sections +#if [ ${res_w} -gt 1024 ]; then +# stab=' ' +#else +# stab=' ' +#fi + +# Char glyps for powerline fonts +sep_left="" # Powerline separator left alt.  +sep_right=" " # Powerline separator right +sep_l_left="  " # Powerline light separator left +sep_l_right="  " # Powerline light sepatator right + +# Icon glyphs from Terminusicons2 +icon_clock="" # Clock icon +icon_cpu=""# " # CPU icon alt.  +icon_mem="" # MEM icon +icon_dl="" # Download icon +icon_ul="" # Upload icon +icon_vol="" # Volume icon +icon_vol_low="" # Volume icon +icon_vol_mute="" # Volume icon +icon_hd=" [/]" # HD / icon +icon_home=" [/home]" # HD /home icon +icon_mail="" # Mail icon +icon_chat="Ò" # IRC/Chat icon +icon_music="Î" # Music icon +icon_prog="" # Window icon alt.  +icon_contact="Á" # Contact icon +icon_wsp="" # Workspace icon +icon_wlan="" +icon_eth="" +icon_lang="" +icon_keyset="" +icon_bright="" +icon_brightness='☼' +icon_charged=" " #alt.  +icon_charging="" #alt.  +icon_batt_0="" +icon_batt_1="" +icon_batt_2="" +icon_batt_3="" +icon_batt_4="" +icon_bluetooth="" diff --git a/.i3/lemonbar/i3_lemonbar_launcher.py b/.i3/lemonbar/i3_lemonbar_launcher.py new file mode 100644 index 0000000..836d628 --- /dev/null +++ b/.i3/lemonbar/i3_lemonbar_launcher.py @@ -0,0 +1,262 @@ +import fcntl, sys, os, time, logging +import signal, atexit +import subprocess +import contextlib +from threading import Thread +import argparse +import re # regexp + +import i3_lemonbar_config as config +import i3_lemonbar_common as common +import i3_lemonbar_parser as lemonparser +import i3_workspaces as wspaces + +p_conky_slow = None +p_conky_fast = None +p_lemonbar = None +i3_ws_obj = None + +def assert_only_instance(): + """ + If PID file exists: + Look for process with given PID + If found: + Exit program + If not found: + Delete PID file and continue + + Look for fifo file + If exists: + Delete it + """ + + try: + pid = None + with open(config.pid_file, 'r') as fp: + pid = int(fp.read()) + except IOError: + logger.debug('Could not open PID file. Assuming non existent') + except ValueError: + logger.debug('''PID file contents broken''') + try: + os.remove(config.pid_file) + logger.debug('''Deleted old PID file, continuing as usual''') + except OSError: + logger.debug('''Failed deleting old PID file.''') + os._exit(1) + + + if pid is not None: + try: + logger.debug('''Found old PID file. Looking for owner''') + os.kill(pid, 0) + logger.debug('''Owner exists''') + logger.debug('''Failed, another instance of the launcher is running +(PID {})'''.format(pid)) + os._exit(1) + except ProcessLookupError: + logger.debug('''Owner does not exist''') + try: + os.remove(config.pid_file) + logger.debug('''Deleted old PID file, continuing as usual''') + except OSError: + logger.debug('''Failed deleting old PID file.''') + os._exit(1) + + with open(config.pid_file, 'w+') as fp: + fp.write('{:d}'.format(os.getpid())) + logger.debug('''Created and wrote to PID file''') + + create_new_fifo(config.fifo_file_status) + create_new_fifo(config.fifo_file_executor) + +def create_new_fifo(fifo_file): + """ + Create new fifo file, removing old one if it exists + """ + try: + os.remove(fifo_file) + logger.debug('''Removed old fifo file''') + except OSError: + logger.debug('''No old fifo file, good''') + + try: + os.mkfifo(fifo_file) + except OSError: + logger.error('''Failed, couldn't create fifo file''') + os.remove(config.pid_file) # Clean up own PID file + sys.exit(0) + + + +def handle_exit(signum, frame): + logger.info('Signal handler called with signal {}'.format(signum)) + logger.info('Calling os._exit(0)') + os._exit(0) + +# Terminates process p nicely +def nice_term(p): + if p is not None: + p.terminate() + +def nice_delete(f): + with contextlib.suppress(FileNotFoundError): + os.remove(f) + +def clean_up(): + logger.debug('Cleaning up') + nice_delete(config.pid_file) + nice_delete(config.fifo_file_status) + nice_delete(config.fifo_file_executor) + nice_term(p_conky_slow) + nice_term(p_conky_fast) + nice_term(common.p_bluetooth) + if i3_ws_obj is not None: + i3_ws_obj.quit() + sys.exit(0) + +def write_sys_status(): + global p_conky_slow, p_conky_fast, i3_ws_obj + with open(config.fifo_file_status, 'w') as fifo: + p_conky_slow = subprocess.Popen(['conky', '-c', config.path+'conky_slow'], # Use communicate + stdout=fifo, stderr=fifo) + logger.debug('Started conky slow') + p_conky_fast = subprocess.Popen(['conky', '-c', config.path+'conky_fast'], + stdout=fifo, stderr=fifo) + logger.debug('Started conky fast') + i3_ws_obj = wspaces.i3ws(fifo_file=config.fifo_file_status) + +def parse_status(): + global p_lemonbar + with open(config.fifo_file_executor, 'w') as fifo_write: + p_lemonbar = subprocess.Popen(config.lemonbar_args + ,stdin=subprocess.PIPE, stdout=fifo_write, text=True) + with open(config.fifo_file_status, 'r', buffering=1) as fifo_read: + # Let parser read from fifo + logger.debug("FIFO {} opened for reading".format(config.fifo_file_status)) + lemonparser.parse_line('WSPINA1___main INA2___web FOC5___terms INA6___stats ') + while True: + try: + data = fifo_read.readline() # Blocking read + if len(data) == 0: + logger.debug("Writer closed") + break + psd = lemonparser.parse_line(data) + p_lemonbar.stdin.write(lemonparser.parse_line(data) + '\n') + p_lemonbar.stdin.flush() + #logger.debug('Read: "{0}"'.format(data)) + #logger.debug('Parsed "{0}"'.format(psd)) + except BrokenPipeError: + logger.debug('Broken pipe in parse status thread, exiting') + clean_up() + except: + logger.debug('Unknown exception in parse status thread, exiting') + clean_up() + +def exec_commands(): + with open(config.fifo_file_executor, 'r', buffering=1) as fifo_read: + logger.debug("FIFO {} opened for reading".format(config.fifo_file_executor)) + while True: + try: + data = fifo_read.readline() + logger.debug('Trying reading: "{0}"'.format(data.strip('\n'))) + try: + for key,func in common.commands_dict.items(): + l = len(key) + if data[:l] == key: + func(data) + break + + except: + logger.debug('Exception occured executing command\n Line in: {}\n Data: {}'.format(line_in, line_in[l:].split())) + if len(data) == 0: + logger.debug("Lemonbar output closed") + break + logger.debug('Read: "{0}"'.format(data.strip('\n'))) + except BrokenPipeError: + logger.debug('Broken pipe in exec commands thread, exiting') + clean_up() + except: + logger.debug('Unknown exception in exec commands thread, exiting') + raise + clean_up() +def strip_ansi_unicode(s): + # ANSI escape sequences are for colors in terminal and similar + ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]') + strip_ansi = ansi_escape.sub('', s) + strip_unicode = (strip_ansi.encode('ascii', 'ignore')).decode('utf-8') + return strip_unicode + +def handle_bluetooth(): + common.p_bluetooth = subprocess.Popen('bluetoothctl' + ,stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True) + for line in common.p_bluetooth.stdout: + #try: + logger.debug('Bluetooth read line {}'.format(line.strip('\n'))) + with open(config.fifo_file_status, 'w') as fifo: + clean_line = strip_ansi_unicode(line) + if (not clean_line.startswith('[bluetooth]') + and not clean_line.startswith('[CHG]') + and not clean_line.isspace()): + fifo.write('RESP [bluetoothctl] ' + clean_line) + #except: + # raise + +class i3_thread: + """ Helper class to start and stop threads""" + all_threads = [] # Static, contains all started threads + + def __init__(self, target, desc): + self.thread = Thread(target = target) + self.desc = desc + + self.all_threads.append(self) + self.thread.start() + + def join_threads(): + for i3_th in i3_thread.all_threads: + i3_th.thread.join() + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Blah blah blah.') + parser.add_argument('--debug', action='store_true') + args = parser.parse_args() + if(args.debug): + debuglvl = logging.DEBUG + else: + debuglvl = logging.INFO + + # Setup logger to stdout + formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') + handler = logging.StreamHandler(sys.stdout) + handler.setFormatter(formatter) + + logger = logging.getLogger('Normal logger') + logger.setLevel(debuglvl) + logger.addHandler(handler) + + # Setup health logger to file in tmp + formatter = logging.Formatter('%(asctime)s %(message)s') + handler = logging.FileHandler(config.health_file) + handler.setFormatter(formatter) + + health_logger = logging.getLogger('Health logger') + health_logger.addHandler(handler) + +# logger.basicConfig(stream=sys.stdout, level=debuglvl) + assert_only_instance() # Creates pid file and fifo file + atexit.register(clean_up) + signal.signal(signal.SIGTERM, handle_exit) + signal.signal(signal.SIGINT, handle_exit) + + # Start writing and reading threads + # Create readers before writers + i3_thread(target = exec_commands, desc='Exec commands thread') + i3_thread(target = parse_status, desc='Parse status thread') + i3_thread(target = write_sys_status, desc='Write sys status thread') + i3_thread(target = handle_bluetooth, desc='Bluetooth thread') + + logger.debug('Threads started') + i3_thread.join_threads() + + logger.debug('Reached end') diff --git a/.i3/lemonbar/i3_lemonbar_parser.py b/.i3/lemonbar/i3_lemonbar_parser.py new file mode 100644 index 0000000..e9c58cf --- /dev/null +++ b/.i3/lemonbar/i3_lemonbar_parser.py @@ -0,0 +1,290 @@ +import sys +from enum import Enum +import i3_lemonbar_config as conf +import i3_lemonbar_common as common + +displays = '' +workspaces = '' +win_title = '' +sys_load = '' +net_load = '' +volume = '' +brightness = '' +battery = '' +date = '' +language = '' +time = '' +response = '%{r}' + +blank = ' ' + +sr = conf.sep_right +slr = conf.sep_l_right +sl = conf.sep_left +sll = conf.sep_l_left + +def block(fg = None, bg = None, font = None, click = None, append=''): + # Remeber that clickable blocks need to be closed + rtn = [] + if click is not None: + if click == '': + rtn.append('A') + else: + rtn.append('A:'+click+':') + if fg is not None: + rtn.append('F'+fg) + if bg is not None: + rtn.append('B'+bg) + if font is not None: + rtn.append('T'+font) + return ''.join(['%{', ' '.join(rtn), '}', append]) + +reset = block(fg='-', bg='-') +reset_power = block(fg='-', bg=conf.color_poweropts) + +class COLOR_SCHEME(Enum): + A1 = (conf.color_sec_b1, conf.color_fore, conf.color_icon) + A2 = (conf.color_sec_b2, conf.color_fore, conf.color_icon) + A1_INA = (conf.color_sec_b1, conf.color_disable, conf.color_disable) + A2_INA = (conf.color_sec_b2, conf.color_disable, conf.color_disable) + CPU_ALERT= (conf.color_cpu, conf.color_back, conf.color_back) + NET_ALERT= (conf.color_net, conf.color_back, conf.color_back) + SPECIAL = (conf.color_head, conf.color_back, conf.color_back) + def __init__(self, back_color, text_color, icon_color): + self.back_color = back_color + self.text_color = text_color + self.icon_color = icon_color + +def single_sect(icon='', text='', click=None, alt=COLOR_SCHEME.A1): + # If there is an action we need to close the block + close = block(click='') if click is not None else '' + if icon != '': + icon = ' ' + icon + return ' '.join([block(fg=alt.back_color, append=sl) + , block(click=click, fg=alt.icon_color, bg=alt.back_color + , font='2', append=icon) + , block(fg=alt.text_color, font='1', append=text) + , close]) + +def double_sect(text1 = '', text2 = '', icon1 = '', icon2 = '', click = None + , alt=COLOR_SCHEME.A1): + # If text_color None then icon_color will apply + close = block(click='') if click is not None else '' + return ''.join([block(fg=alt.back_color, append=sl), ' ' + , block(click=click, fg=alt.icon_color, bg=alt.back_color, font='2') + , ' ', icon1, block(fg=alt.text_color, font='1'), ' ', text1 + , block(fg=alt.icon_color), sll, block(font='2') + , icon2, block(fg=alt.text_color, font='1'), ' ', text2, ' ', close]) + +def control_sect(sec_color=None, head='', buttons=[], actions=[]): + rtn = head + for button, action in zip(buttons, actions): + # If there is an action we need to close the block + close = block(click='') if action is not None else '' + rtn += ' '.join([block(click=action), button, close]) + return rtn + +# Constants +power_opts = ''.join([block(fg=conf.color_fore, bg=conf.color_poweropts) + , ' Abort (Esc) | System (l) lock, (e) logout, (s) suspend, (h) hibernate' + , ', (r) reboot, (Shift+s) shutdown %{r}']) +controls = ' '.join([block(fg=conf.color_head, bg=conf.color_sec_b2) + , conf.sep_right, block(fg=conf.color_head, bg=conf.color_sec_b2, click='mode cycle') + , conf.icon_prog + , block(fg=conf.color_sec_b2, bg='-', click='') + , control_sect(head='', buttons=['on', 'off'] + , actions=['bluetooth power on', 'bluetooth power off']) + , control_sect(head='PXC 550', buttons=['conn.', 'disc.'] + , actions=['bluetooth connect pxc550', 'bluetooth disconnect pxc550']) + ]) +def update_response(data): + global response + resp = ' '.join(data) + response= ''.join(['%{r}', single_sect(text=resp)]) + +def update_displays(data): + global displays + + dsp_array = data[0].split(':') + parsed_list = [block(click='displays', font='2')] + for dsp in dsp_array[1:]: + if dsp == 'eDP1': + col_head = conf.color_head + elif dsp == 'DP1': + col_head = conf.color_vga + elif dsp == 'HDMI2': + col_head = conf.color_hdmi + else: + col_head = '#00000000' # Undefined + parsed_list.append(block(fg=conf.color_back, bg=col_head)) + parsed_list.append(conf.icon_wsp) + parsed_list.append(block(click='')) + + displays = ' '.join(parsed_list) + +def update_workspaces(data): + global workspaces + prefix = block(font='1', fg=conf.color_back, bg=conf.color_head) + prefix_foc = ''.join([block(fg = conf.color_head, bg=conf.color_wsp) + , conf.sep_right + , block(fg=conf.color_back, bg=conf.color_wsp, font='1')]) + prefix_ina = block(fg=conf.color_back, bg=conf.color_head, font='1') + wspces = [] + for entry in data: # entry for example FOC5___terms + status = entry[0:3] # FOC or INA + num = entry[3] + name = entry[7:] + full_name = ' '.join(['', num, name]) + current = ''.join([block(click=('i3-msg workspace' + full_name)) + , full_name, block(click='')]) + if status == "FOC": + wspces.append(''.join([prefix_foc, current])) + else: + wspces.append(''.join([prefix_ina, current])) + + workspaces = ''.join([prefix, ' '.join(wspces)]) + +def update_conky_slow(data): + global sys_load, battery + # System load + if int(data[0]) > int(conf.cpu_alert): + cpu_alt = COLOR_SCHEME.CPU_ALERT + else: + cpu_alt = COLOR_SCHEME.A2 + + sys_load = ''.join(['%{r}' + , double_sect(text1 = (data[0] + '%'), text2 = data[1], icon1 = conf.icon_cpu + , icon2 = conf.icon_mem, alt=cpu_alt , click = 'load') + , double_sect(text1 = (data[2] + '%'), text2 = (data[3] + '%') + , icon1 = conf.icon_hd, icon2 = conf.icon_home, alt=COLOR_SCHEME.A1) + ]) # cpu mem disk_r disk_home + + #sec_color = conf.color_sec_b1 if (b == 1) else conf.color_sec_b2 + + (batt_stat, batt) = (data[4][0], int(data[4][1:])) + icon_batt = conf.icon_charging if batt_stat == 'C' else \ + conf.icon_charged if batt_stat == 'F' else \ + conf.icon_batt_0 if batt < 20 else \ + conf.icon_batt_1 if batt < 40 else \ + conf.icon_batt_2 if batt < 60 else \ + conf.icon_batt_3 if batt < 80 else \ + conf.icon_batt_4 + battery = single_sect(icon=icon_batt, click='dpms', text=(str(batt)+'%') + , alt=COLOR_SCHEME.A2) + update_bright([data[5]]) + update_lang([data[6]]) + +def update_lang(data): + global language + language = single_sect(icon=conf.icon_lang, click='lang', text=data[0] + , alt=COLOR_SCHEME.A2) + +def update_bright(data): + global brightness + brtxt = str(int(float(data[0]))) + brightness = single_sect(icon=conf.icon_bright, click='adj_br' + , text=(brtxt+'%'), alt=COLOR_SCHEME.A1) + +def update_conky_fast(data): + global date, time, volume + mute = data[4] == 'MUTE' or data[4] == 'NONE' + (vol,vols) = (-1,'×') if mute else (int(data[4]), data[4]+'%') + icon_v = conf.icon_vol_mute if vol == 0 else \ + conf.icon_vol_low if vol < 50 else conf.icon_vol + volume = single_sect(icon=icon_v, click='pavu', text=vols + , alt=COLOR_SCHEME.A2) + + tme = data[3] if common.show_secs else data[3][:-3] + date = single_sect(icon=conf.icon_clock, click='date' + , text=' '.join(data[0:3]), alt=COLOR_SCHEME.A1) + time = single_sect(click='toggle_secs', text=tme, alt=COLOR_SCHEME.SPECIAL) + + update_net(data[5:9]) + +def update_net(data): + global net_load + + if data[0] == 'down': # wlan + (wland_v, wlanu_v) = ('x', 'x') + wlan_alt = COLOR_SCHEME.A2_INA + else: + (wland_v, wlanu_v) = (data[0],data[1]) + if max(float(wland_v), float(wlanu_v)) > float(conf.net_alert): + wlan_alt = COLOR_SCHEME.NET_ALERT + else: + wlan_alt = COLOR_SCHEME.A2 + + if data[2] == 'down': # eth + (ethd_v, ethu_v) = ('x', 'x') + eth_alt = COLOR_SCHEME.A1_INA + else: + (ethd_v, ethu_v) = (data[2],data[3]) + if max(float(ethd_v), float(ethu_v)) > float(conf.net_alert): + eth_alt = COLOR_SCHEME.NET_ALERT + else: + eth_alt = COLOR_SCHEME.A1 + + net_load = ''.join([ + double_sect(click = 'wlan', alt=wlan_alt, text1 = wland_v, text2 = wlanu_v, + icon1 = (conf.icon_wlan + conf.icon_dl), icon2 = conf.icon_ul) + , double_sect(click = 'eth', alt=eth_alt, text1 = ethd_v, text2 = ethu_v, + icon1 = (conf.icon_eth + conf.icon_dl), icon2 = conf.icon_ul) + ]) # wlan_d wlan_u eth_d eth_u + + +def update_title(data): + global win_title + win_title = ' '.join([block(fg=conf.color_head, bg=conf.color_sec_b2) + , conf.sep_right, block(fg=conf.color_head, bg=conf.color_sec_b2, click='mode cycle') + , conf.icon_prog + , block(fg=conf.color_sec_b2, bg='-') + , ' '.join(data)]) + +def format_line(): + # Need to end with a reset block, otherwise the color fills the %{r} spacer + if common.mode == common.bar_mode.normal: + return ''.join(['%{l}', reset, displays, workspaces, win_title, sys_load, net_load + , volume, brightness, battery, date, language, time, reset]) + elif common.mode == common.bar_mode.power: + return ''.join(['%{l}', reset, power_opts, sys_load, net_load + , volume, brightness, battery, date, language, time, reset_power]) + elif common.mode == common.bar_mode.control: + return ''.join(['%{l}', reset, displays, workspaces, controls, response, time, reset]) + else: + return ''.join(['%{l}', reset, displays, workspaces, 'Not normal' , time, reset]) + +parsers_dict = { 'CNK_FAST':update_conky_fast + ,'CNK_SLOW':update_conky_slow + ,'WSP':update_workspaces + ,'LANG':update_lang + ,'BRIGHT':update_bright + ,'WIN':update_title + ,'DISP':update_displays + ,'RESP':update_response + } + +def parse_line(line_in): + ''' Lines are + + CNK_FAST Fri 21 Sep 19:45:18 VolXXX wlan_d wlan_u eth_d eth_u + CNK_SLOW cpu mem disk_root disk_home batt bri lang disp + WSPINA1___main INA2___web FOC5___terms INA6___stats + ''' + + try: + for key,func in parsers_dict.items(): + l = len(key) + if line_in[:l] == key: + func(line_in[l:].split()) + break + + except: + print('Exception occured\n Line in: {}\n Data: {}'.format(line_in, line_in[l:].split())) + raise + + #return '%s\n' + format_line() # Done this way in .sh + return format_line() + +if __name__ == "__main__": + for line in sys.stdin: + print(parse_line(line)) diff --git a/.i3/lemonbar/i3_workspaces.py b/.i3/lemonbar/i3_workspaces.py new file mode 100644 index 0000000..02e2eec --- /dev/null +++ b/.i3/lemonbar/i3_workspaces.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# +# Print i3 workspaces on every change. +# +# Format: +# For every workspace (x = workspace name) +# - "FOCx" -> Focused workspace +# - "INAx" -> Inactive workspace +# - "ACTx" -> Ative workspace +# - "URGx" -> Urgent workspace +# +# Based in wsbar.py en examples dir +# +# 16 feb 2015 - Electro7 + + +import sys, os, signal +import logging +import time +from subprocess import call +import i3ipc + +import i3_lemonbar_config as config +import i3_lemonbar_common as common + +def img_path(num): + dir = '/home/kuba/Obrazy/Wallpapers/' + return dir + { + 1: '1_main', + 2: '2_web', + 3: '3_music', + 4: '4_work', + 5: '5_terms', + 6: '6_stats', + 7: '7', + 8: '8', + 9: '9', + }.get(int(num), 'default') + +class State(object): + # workspace states + focused = 'FOC' + active = 'ACT' + inactive = 'INA' + urgent = 'URG' + + def get_state(self, workspace, output): + if workspace['focused']: + if output['current_workspace'] == workspace['name']: + return self.focused + else: + return self.active + if workspace['urgent']: + return self.urgent + else: + return self.inactive + + +class i3ws(object): + ws_format = '%s%s ' + end_format = 'WSP%s' + state = State() + backgrounds = {} + + fifo = None + + def __init__(self, state=None, fifo_file=None): + if state: + self.state = state + if fifo_file: + self.fifo = open(fifo_file, 'w') + # conn + self.conn = i3ipc.Connection() + + + # Run call backs once + self.change(self.conn, None) + self.win_focused(self.conn, None) + + self.conn.on('workspace::focus', self.change) + self.conn.on('workspace::init', self.change) + self.conn.on('workspace::empty', self.change) + self.conn.on('window::focus', self.win_focused) + logging.debug('Started i3 workspaces manager') + try: + self.conn.main() + except BrokenPipeError: + logging.debug('Broken pipe in i3 workspaces thread, exiting') + except: + logging.debug('Unknown exception in i3 workspaces thread, exiting') + + def change(self, i3, e): + # Receives event and workspace data + outputs = i3.get_outputs() + active = ['DISP'] + for output in outputs: + if output.name != 'xroot-0': + active.append(output.name) + self.backgrounds[output.name] = img_path(1) + self.display(':'.join(active)) + workspaces = i3.get_workspaces() + text = self.format(workspaces, outputs) + self.display(text) + self.set_bg() + + def win_focused(self, i3, e): + win = i3.get_tree().find_focused() + name = win.name + role = win.window_role + wclass = win.window_class + + text = 'WIN{}'.format(name) + self.display(text) + + common.cur_class = wclass + + # Kill floating windows + if role != 'FLOAT_TERM' and wclass != 'FLOAT_PAVU' and wclass != 'YADWINBR': + # Is there a window that the bar has opened? + for pid in common.kill_on_unfocus: + try: + os.kill(pid, signal.SIGTERM) + except ProcessLookupError: + logging.debug('Tried killing process {} but it doesn\'t exist'.format(pid)) + common.kill_on_unfocus = [] + + # Set correct keymap + if wclass in common.keymaps: + new_km = common.keymaps[wclass] + logging.debug('Setting {} as keymap for {}'.format(new_km, wclass)) + else: + new_km = common.def_keymap + logging.debug('Setting default keymap {} for {}'.format(common.def_keymap, wclass)) + call(['/home/kuba/.i3/scripts/lang.sh', 'qset', new_km]) + + + def format(self, workspaces, outputs): + # Formats the text according to the workspace data given. + out = '' + for workspace in workspaces: + output = None + for output_ in outputs: + if output_['name'] == workspace['output']: + output = output_ + break + if not output: + continue + st = self.state.get_state(workspace, output) + if st == 'FOC': + self.backgrounds[output['name']] = img_path(workspace['name'].partition(' ')[0]) + name = workspace['name'].replace(" ","___") + item= self.ws_format % (st, name) + out += item + return self.end_format % out + + def display(self, text): + if self.fifo is not None: + self.fifo.write(text + '\n') + self.fifo.flush() + else: + # Displays the text in stout + print(text) + sys.stdout.flush() + + def set_bg(self): + args = '' + for key in self.backgrounds.keys(): + args += ' ' + key + ' ' + self.backgrounds[key] + call(['sh', '/home/kuba/.i3/lemonbar/set_bg.sh', args]) + + def quit(self): + if self.fifo is not None: + try: + self.fifo.close() + except BrokenPipeError: + pass + +if __name__ == '__main__': + ws = i3ws() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + print('') # force new line +# finally: + # ws.quit() diff --git a/.i3/lemonbar/set_bg.sh b/.i3/lemonbar/set_bg.sh new file mode 100644 index 0000000..d32f92d --- /dev/null +++ b/.i3/lemonbar/set_bg.sh @@ -0,0 +1,24 @@ +#!/bin/bash +function get_index(){ + for i in "${!xra_out[@]}"; do + if [[ "${xra_out[$i]}" = "$value" ]]; then + echo "${i}"; + break + fi + done +} + +xra_out=($(xrandr | grep ' connected' | awk '{print $1}')) +in=($@) +for i in `seq 0 2 ${#in[@]}`; do + value="${in[$i]}" + idx=$(get_index) + if [ ! -z "$idx" ]; then + screen_idx="$idx" + #"${xra_out[$idx-1]}" + paths[${screen_idx%:}]="--bg-scale ${in[$i+1]}" + fi +done +#echo "${paths[@]}" +str=`printf -v var "%s\n" "${System[@]}"` +sh -c "feh ${paths[@]}" diff --git a/.i3/lemonbar/set_mode.sh b/.i3/lemonbar/set_mode.sh new file mode 100644 index 0000000..705541d --- /dev/null +++ b/.i3/lemonbar/set_mode.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +if [[ -p /tmp/i3_lemonbar2_$USER ]]; then + echo "$@" > /tmp/i3_lemonbar2_$USER +fi diff --git a/.i3/lock.png b/.i3/lock.png new file mode 100644 index 0000000..283f14c Binary files /dev/null and b/.i3/lock.png differ diff --git a/.i3/scripts/adjbr.sh b/.i3/scripts/adjbr.sh new file mode 100644 index 0000000..0612ca3 --- /dev/null +++ b/.i3/scripts/adjbr.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Launches a yad window to change the brightness (or volume, not in use) +panel_fifo="/tmp/i3_lemonbar1_${USER}" +panel_commands="/tmp/i3_lemonbar2_${USER}" + +if [ "$1" == "-b" ]; then + CLASS="YADWINBR" + ICON='☼' + COLOR='yellow' +elif [ "$1" == "-v" ]; then + CLASS="YADWINV" + ICON='🔈' + COLOR='white' +else + exit 1 +fi +LEVEL=$(bc <<< "scale=0; $(brillo -G)/1") +[[ "$3" == "-t" ]] && TIMER="--timeout=1" + +declare -a YADARGS=("--sticky" "--undecorated" "--on-top" "--class=$CLASS" + "--scale" "--text='$ICON'" + "--value" "$LEVEL" "--no-buttons" + "--geometry=15x150" "--vertical" "--text-align" "center" "$TIMER" "--print-partial") +YARGS=${YADARGS[@]} + +FIFO="$2" + +(echo "kill_unfocus $BASHPID" > $FIFO; exec sh -c "yad $YARGS") | \ +while read out; do + ~/.i3/scripts/level.sh -b set $out +done diff --git a/.i3/scripts/dpmsctl.sh b/.i3/scripts/dpmsctl.sh new file mode 100644 index 0000000..d40c707 --- /dev/null +++ b/.i3/scripts/dpmsctl.sh @@ -0,0 +1,9 @@ +#!/bin/sh +STATUS=`xset q | awk '{for (I=1;I<=NF;I++) if ($I == "DPMS" && $(I+1) == "is") {print $(I+2)};}'` +if [ "$STATUS" == "Enabled" ]; then + xset -dpms + yad --timeout 1 --text "DPMS Disabled" --no-buttons --sticky --on-top +else + xset dpms + yad --timeout 1 --text "DPMS Enabled" --no-buttons --sticky --on-top +fi diff --git a/.i3/scripts/lang.sh b/.i3/scripts/lang.sh new file mode 100644 index 0000000..df0147d --- /dev/null +++ b/.i3/scripts/lang.sh @@ -0,0 +1,34 @@ +#!/bin/bash +panel_fifo="/tmp/i3_lemonbar1_${USER}" +panel_commands="/tmp/i3_lemonbar2_${USER}" + +function show(){ + setxkbmap -print -display :0 | grep xkb_symbols | awk '{print $4}' | awk -F"+" '{print $2}' +} +if [ $# -lt 1 ]; then + echo LANG$(show) +fi +if [ "$1" == "next" ]; then + cur=$(show) + next='se' + if [ "$cur" == "se" ]; then + next='pl' + fi + setxkbmap -display :0 $next + if [ -e $panel_fifo ]; then + echo -e "LANG$next\n" > "${panel_fifo}" + fi + if [ -e $panel_commands ]; then + echo -e "setlang $next\n" > "${panel_commands}" + fi +elif [ "$1" == "qset" ]; then + next=$2 + setxkbmap -display :0 $next + if [ -e $panel_fifo ]; then + echo -e "LANG$next\n" > "${panel_fifo}" + fi +elif [ "$1" == "show" ]; then + show +else + exit 1 +fi diff --git a/.i3/scripts/level.sh b/.i3/scripts/level.sh new file mode 100644 index 0000000..8545745 --- /dev/null +++ b/.i3/scripts/level.sh @@ -0,0 +1,33 @@ +#!/bin/bash +panel_fifo="/tmp/i3_lemonbar1_${USER}" +panel_commands="/tmp/i3_lemonbar2_${USER}" + +if [[ "$1" == "-b" ]]; then + icon="-s /usr/share/pixmaps/volnoti/display-brightness-symbolic.svg" + if [[ "$2" == "up" ]]; then + level=$(brillo -A 5 -u 100000; brillo) + elif [[ "$2" == "down" ]]; then + level=$(brillo -U 5 -u 100000; brillo) + elif [[ "$2" == "set" ]]; then + level=$(brillo -S $3; brillo) + fi + echo "BRIGHT$level" > $panel_fifo +elif [[ "$1" == "-v" ]]; then + if [[ "$2" == "up" ]]; then + amixer -q set Master 5%+ + elif [[ "$2" == "down" ]]; then + amixer -q set Master 5%- + elif [[ "$2" == "toggle" ]]; then + amixer -q set Master toggle + fi + level=$(~/.i3/lemonbar/get_vol.sh) + if [[ "$level" == "MUTE" ]]; then + level="-m" + elif [[ "$level" == "NONE" ]]; then + echo "Missing" + fi +fi + +if [[ "$2" != "set" ]]; then + volnoti-show $icon $level +fi diff --git a/.i3/scripts/vol.sh b/.i3/scripts/vol.sh new file mode 100644 index 0000000..179ffc9 --- /dev/null +++ b/.i3/scripts/vol.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +[[ "$1" == "up" ]] && amixer set Master 5%+ +[[ "$1" == "down" ]] && amixer set Master 5%- +[[ "$1" == "mute" ]] && amixer sset Master toggle + +VOL=$(amixer get Master | grep 'Front Left:' | cut -c 31-33) +[[ $(amixer get Master | grep "\[off\]") ]] && sudo -u kuba volnoti-show -m $VOL && exit +sudo -u kuba volnoti-show $VOL diff --git a/.i3/workspace_6.json b/.i3/workspace_6.json new file mode 100644 index 0000000..5aec8a8 --- /dev/null +++ b/.i3/workspace_6.json @@ -0,0 +1,127 @@ +{ +"layout": "splith", +"nodes": [ +{ + "border": "normal", + "floating": "auto_off", + "layout": "splitv", + "percent": 0.65, + "type": "con", + "nodes": [ + { + "border": "normal", + "floating": "auto_off", + "layout": "splith", + "percent": 0.5, + "type": "con", + "nodes": [ + { + "border": "none", + "current_border_width": 2, + "floating": "auto_off", + "geometry": { + "height": 10, + "width": 10, + "x": 0, + "y": 0 + }, + "name": "Conky (kuba-Arch)", + "percent": 1, + "swallows": [ + { + "class": "Conky-arch" + } + ], + "type": "con" + } + ] + }, + { + "border": "none", + "current_border_width": 2, + "floating": "auto_off", + "geometry": { + "height": 434, + "width": 722, + "x": 0, + "y": 0 + }, + "name": "Conky (kuba-Arch)", + "percent": 0.5, + "swallows": [ + { + "class": "Conky-gmail" + } + ], + "type": "con" + } + ] +}, +{ + "border": "normal", + "floating": "auto_off", + "layout": "splitv", + "percent": 0.35, + "type": "con", + "nodes": [ + { + "border": "none", + "current_border_width": 2, + "floating": "auto_off", + "geometry": { + "height": 32, + "width": 32, + "x": 0, + "y": 0 + }, + "name": "Conky (kuba-Arch)", + "percent": 0.20, + "swallows": [ + { + "class": "Conky-weather" + } + ], + "type": "con" + }, + { + "border": "none", + "current_border_width": 2, + "floating": "auto_off", + "geometry": { + "height": 32, + "width": 32, + "x": 0, + "y": 0 + }, + "name": "Conky (kuba-Arch)", + "percent": 0.20, + "swallows": [ + { + "class": "Conky-weather" + } + ], + "type": "con" + }, + { + "border": "none", + "current_border_width": 2, + "floating": "auto_off", + "geometry": { + "height": 10, + "width": 10, + "x": 0, + "y": 0 + }, + "name": "Conky (kuba-Arch)", + "percent": 0.60, + "swallows": [ + { + "class": "Conky-music" + } + ], + "type": "con" + } + ] +} +] +}