i3 の設定


Related Index Debian

始めに

スペックがあまり潤沢ではない機材を使うため, 軽量な wm として i3 を使い始めた.

元々常にtmuxを全画面にして作業しているので, 「タイル型wmの恩恵を受けられるのか?」という疑問はあったのだが, 使ってみたら「綺麗」かつ「驚きの軽さ」ということで, すっかり気にいってしまった.

i3 と一緒に使っているもの

とりあえず現状では以下:

  • ターミナル関連: urxvt と tmux → Terminal生活
  • ファイルマネージャ: pcmanfm
  • ブラウザ: firefox + vimium-ff
  • ランチャ: rofi

他にも

  • Compositor: compton
  • ネットワーク: Network Manager
  • 音: pulseaudio

といった所はそのまま, かな?

i3 の設定

設定ファイルは末尾に掲載している.

xdg-open と run-mailcap

いわゆる GNOME や KDE といった Desktop 環境ではないので, たとえば xdg-open の挙動が変わります.

それ自体は問題無いのですが, 以下の様に

applications/*; xdg-open "%s"
image/*; xdg-open %s;
video/*; xdg-open %s;

~/.mailcapxdg-open に丸投げしていて, さらに $DISPLAY (もしくは $WAYLAND_DISPLAY)が無い場合には, xdg-openrun-mailcap を呼ぶ→ run-mailcapxdg-open を呼び, といった 無限ループが発生します. run-mailcapを抜けば良い, という話もありますが, これ=mime-support=パッケージで提供されているので, 抜くとpython が抜けて大変な目に会います

というわけで, 安直には xdg-open を修正すれば良いですね:

--- /usr/bin/xdg-open.orig	2015-10-06 04:19:48.000000000 +0900
+++ /usr/bin/xdg-open	2017-07-24 21:18:32.191564009 +0900
@@ -787,20 +787,9 @@
         if [ -n "$DISPLAY" ]; then
             filetype=`xdg-mime query filetype "$file" | sed "s/;.*//"`
             open_generic_xdg_mime "$file" "$filetype"
-        fi
-
-        if which run-mailcap 2>/dev/null 1>&2; then
-            run-mailcap --action=view "$file"
-            if [ $? -eq 0 ]; then
-                exit_success
-            fi
-        fi
-
-        if [ -n "$DISPLAY" ] && mimeopen -v 2>/dev/null 1>&2; then
-            mimeopen -L -n "$file"
-            if [ $? -eq 0 ]; then
-                exit_success
-            fi
+        else
+            echo "can't handle: please set mime type via xdg-mime"
+            exit_failure_operation_failed
         fi
     fi

あと, ~/.local/share/applications/mimeapps.list から ~/.config/mimeapps.list へ symbolic link を作成しておきます.

Rofi: ランチャ

Rofi は良い感じのランチャ.

設定ファイルは ~/.config/rofi/config~/.Xresources で行なう. 今はこんな塩梅:

! -*- mode:conf-xdefaults; coding: utf-8 -*-
!! Rofi
rofi.modi: run,window,,windowcd,drun,ssh
rofi.combi-modi: windowcd,drun
rofi.lines: 6
rofi.font: FSMRMP 24
rofi.bw: 2
rofi.location: 0
rofi.padding: 5
rofi.sidebar-mode: true
rofi.hide-scrollbar: true
rofi.fixed-num-lines: true
rofi.kb-row-up: Up,Control+p,Shift+Tab,Alt+Tab
rofi.kb-row-down: Down,Control+n
rofi.kb-cancel: Escape,Control+g,Control+bracketleft,Control+c
rofi.kb-mode-next: Shift+Right,Control+i,Control+Tab
rofi.kb-mode-previous: Shift+Left,Control+Shift+i
rofi.color-enabled: true
rofi.color-window: #3a4c54, #2a373e, #c3c6c8
rofi.color-normal: #455a64, #fafbfc, #455a64, #00bcd4, #fafbfc
rofi.color-active: #455a64, #00bcd4, #455a64, #009688, #fdf6e3
rofi.color-urgent: #455a64, #ff5252, #455a64, #ff5252, #fdf6e3

i3の方では Alt+Shift+Tab で呼び出せるようにしている:

bindsym $Alt+Shift+Tab $execi sh -c "rofi -show window"

Alt+Tab は https://github.com/yoshimoto/i3-alt-tab.py をありがたく使わせて貰っている.

i3bar

i3barは背景透過した上で,

  • i3statusでバッテリ情報と日付
  • primary display に system tray を出す

だけ.

status ラインは以下の通り

# status bar
bar {
    output eDP1
    position top
    tray_output eDP1
    tray_padding -4
    font xft:Inconsolata,Xft:FontAwesome 18
    i3bar_command i3bar --transparency
    status_command i3status -c $HOME/.config/i3/i3status.conf
    binding_mode_indicator yes
    colors {
      background #02020200
      statusline #F6F3E8
      separator  #111822
      focused_workspace  #111822 #222244 #F6F3E8
      active_workspace   #555555 #555555 #F6F3E8
      inactive_workspace #020202 #242424 #888888
      urgent_workspace   #A00000 #900000 #F6F3E8
      binding_mode       #A00000 #900000 #f6f3e8
    }
}

i3status は以下

general {
        colors = true
        interval = 1
        output_format = i3bar
        markup ="pango"
}
order += "tztime local"
tztime local {
        align = left
        min_width = "2020/12/31(木) 23:59:59"
        format = "%Y/%m/%d(%a) %H:%M:%S"
}
order += "battery all"
battery all {
        align = left
        min_width = " 80.00%"
        format = "<span color='#ffbf7f'>%status %percentage</span>"
        status_unk = 
        status_full = 
        status_chr = 
        status_bat = 
}

conky

system load を表示させている.

-- -*- mode: lua; coding: utf-8 -*-
conky.config = {
   --########################
   -- Global config section #
   --########################
   -- Update interval in seconds
   update_interval = 1,
   -- This is the number of times Conky will update before quitting
   -- (0: unlimited)
   total_run_times = 0,
   -- number of net samples to average (1: disable averaging)
   net_avg_samples = 1,
   -- number of cpu samples to average (1: disable averaging)
   cpu_avg_samples = 1,

   imlib_cache_size = 0,
   -- Use double buffering (reduces flicker, may not work for everyone)
   double_buffer = true,
   -- Subtract file system buffers from used memory?
   no_buffers = true,

   --################
   -- Text settings #
   --################
   -- Force UTF8? note that UTF8 support required XFT
   override_utf8_locale = true,
   use_xft = true,
   font = 'FSMRMP:style=Bold:size=4',
   -- use_xft =  false,
   -- font='-shinonome-gothic-medium-r-normal--14-130-75-75-c-70-iso8859-1',

   --##################
   -- Window settings #
   --##################
   -- Create own window instead of using desktop (required in nautilus)
   own_window_class = 'conky',
   own_window = true,
   own_window_type = 'override',
   own_window_transparent = true,
   own_window_hints = 'undecorated,below,sticky,skip_pager,skip_taskbar',
   -- Text alignment, other possible values are commented top_left,
   -- top_right, top_middle, bottom_left, bottom_right, bottom_middle,
   -- middle_left, middle_middle, middle_right, or none (also can be
   -- abreviated as tl, tr, tm, bl, br, bm, ml, mm, mr)
   alignment = 'tl',
   -- Gap between borders of screen and text
   -- same thing as passing -x at command line
   gap_x = 200,
   gap_y = 0,
   -- Minimum size of text area
   minimum_width = 1440,
   maximum_width = 1440,

   --####################
   -- Graphics settings #
   --####################
   default_bar_width = 0,
   default_bar_height = 0,
   -- Draw shades?
   draw_shades = false,
   -- Draw outlines?
   draw_outline = false,
   -- Draw borders around text
   draw_borders = false,
   draw_graph_borders = true,
   default_color = '#ffffff',
   -- default_shade_color = '#242424',
};
conky.text = [[
${font FSMRMP:size=16.5}${color #f09000}CPU${color}: ${cpu cpu0}%${font}\
${voffset   8}\
${goto      0}${color #ff0000}${cpubar cpu1 8,24} ${cpubar cpu3 8,24}${color}\
${goto     54}${color #ff0000}${cpubar cpu2 8,24} ${cpubar cpu4 8,24}${color}\
${voffset -20}\
${goto    108}${color 888888}${cpugraph cpu0 28,50 ff0000 ff0000}${color}\
${goto    164}\
${voffset  -2}\
${font FSMRMP:size=16.5}${color #f09000}RAM${color}: $memperc%${font}\
${voffset   9}\
${goto    164}\
${color #0000ff}${membar 8,85}${color}\
${voffset -20}\
${goto    256}${color 888888}${memgraph 28,50 0000ff 0000ff}${color}\
${voffset  -2}\
${goto    310}\
${font FSMRMP:size=16.5}${color #f09000}DISK${color}: ${fs_used_perc /}%${font}\
${voffset   9}\
${goto    310}${color #aaaaaa}${fs_bar 8,95 /}${color}\
${voffset -20}\
${goto    413}\
${color 888888}${diskiograph_read /dev/dm-0 28,50 FCAF3E FCAF3E} \
${color 888888}${diskiograph_write /dev/dm-0 28,50 FFFF4C FFFF4C}\
${if_existing /proc/net/route tun0}\
${voffset  -2}\
${goto    520}\
${font FSMRMP:size=13.5}${color #4cff4c} VPN${color}${font}\
${voffset   4}\
${goto    520}\
${font FSMRMP:size=15}${color #ffffff}${addr tun0}${font}${color}\
${voffset -24}\
${goto    675}\
${color 888888}\
${upspeedgraph wlp2s0 28,50 4CFFFF 7FFFFF} \
${downspeedgraph wlp2s0 28,50 4CFF4C 7FFF7F}${color}\
${else}\
${if_existing /proc/net/route wlp2s0}\
${voffset  -2}\
${goto    520}\
${font FSMRMP:size=13.5}${color #4cff4c} Wifi${color}${font}\
${voffset   4}\
${goto    520}\
${font FSMRMP:size=15}${color #ffffff}${addr wlp2s0}${font}${color}\
${voffset -24}\
${goto    675}\
${color 888888}\
${upspeedgraph wlp2s0 28,50 4CFFFF 4CFFFF} \
${downspeedgraph wlp2s0 28,50 4CFF4C 4CFF4C}${color}\
${else}\
${if_existing /proc/net/route enp0s31f6}\
${voffset  -2}\
${goto    520}\
${font FSMRMP:size=13.5}${color #4cff4c} LAN${color}${font}\
${voffset   4}\
${goto    520}\
${font FSMRMP:size=15}${color #ffffff}${addr enp0s31f6}${font}${color}\
${voffset -24}\
${goto    675}\
${color 888888}\
${upspeedgraph enp0s31f6 28,50 4CFFFF 4CFFFF} \
${downspeedgraph enp0s31f6 28,50 4CFF4C 4CFF4C}${color}\
${else}\
${voffset  -2}\
${goto    520}\
${font FSMRMP:size=13.5}${color #aaaaaa} --- ${color}${font}\
${voffset   4}\
${goto    520}\
${font FSMRMP:size=15}${color #aaaaaa}---.---.---.---${color}${font}\
${endif}${endif}${endif}
]];

screen lock: i3lock の設定

suspend → resume した時に i3lock を走らせたいので /etc/systemd/system/i3lock.service:

[Unit]
Description=Starts i3lock at suspend time
After=sleep.target

[Service]
User=uwabami
Type=forking
Environment=DISPLAY=:0
ExecStart=/usr/bin/i3lock -p win -c 444444

[Install]
WantedBy=sleep.target

を作成して有効にしておく.

i3 の設定ファイル

設定ファイル全体は以下の通り

#-*- mode:conf-space ; coding: utf-8 -*-
# macro
set $mod Mod4
set $Alt Mod1
set $execi exec --no-startup-id
# set $execa exec_always
# set $execai exec_always --no-startup-id

# font
font xft:FSMRMP 16.5

# startup
#$execi /usr/libexec/gsd-xsettings --gtk-no-debug=All --gdk-no-debug=all
$execi xrdb -merge $HOME/.Xresources
$execi picom -bcCG
$execi nm-applet
$execi blueman-applet
$execi /usr/libexec/gpaste/gpaste-daemon
$execi feh --bg-fill $HOME/Pictures/desktop.png --image-bg black --no-fehbg
$execi conky -c $HOME/.config/i3/conkyrc
$execi nextcloud

# screensaver and power management
$execi xset -dpms   # disable DPMS
$execi xset s off   # disable auto screensaver
bindsym $mod+Shift+l $execi sh -c "i3lock -n -c 020202"

# start a terminal: rxvt-unicide daemon mode
bindsym Control+Shift+n exec urxvtcd
# start launcher: rofi @see ~/.Xresources
bindsym $Alt+F2 $execi sh -c "rofi -show run"

# change focus
bindsym $Alt+Tab $execi sh -c "rofi -show window"
# set $i3t_alt_tab ~/.config/i3/i3-alt-tab.py
# bindsym $Alt+Tab exec $i3t_alt_tab n all 2>&1 1>/dev/null
# bindsym $Alt+Shift+Tab exec $i3t_alt_tab n 2>&1 1>/dev/null

# change focus
bindsym $mod+j focus left
bindsym $mod+Control+Left focus left
bindsym $mod+k focus right
bindsym $mod+Control+Down focus down
bindsym $mod+l focus down
bindsym $mod+Control+Right focus right
bindsym $mod+Control+Up focus Up

# kill focused window
bindsym $Alt+F4 kill

# toggle tiling / floating
bindsym $Alt+Return floating toggle
# enter fullscreen mode for the focused container
bindsym $mod+F12 fullscreen toggle

# move focused window
bindsym $mod+Left move left
bindsym $mod+Down move down
bindsym $mod+Up move up
bindsym $mod+Right move right

# change container layout (tabbed, stacked, toggle split)
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+t layout toggle split
workspace_layout tabbed

# focus the parent container
bindsym $mod+a focus parent
# focus the child container
bindsym $mod+d focus child

# resize window (you can also use the mouse for that)
bindsym $mod+r mode "resize"
mode "resize" {
        # These bindings trigger as soon as you enter the resize mode
        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"
}
# switch to workspace
bindsym $Alt+1 workspace 1
bindsym $Alt+2 workspace 2
bindsym $Alt+3 workspace 3
bindsym $Alt+4 workspace 4
bindsym $Alt+5 workspace 5
bindsym $Alt+6 workspace 6
bindsym $Alt+7 workspace 7
bindsym $Alt+8 workspace 8
bindsym $Alt+9 workspace 9

bindsym $Alt+Control+Left workspace prev
bindsym $Alt+Control+Right workspace next

# move focused container to workspace
bindsym $Alt+Shift+1 move container to workspace 1
bindsym $Alt+Shift+2 move container to workspace 2
bindsym $Alt+Shift+3 move container to workspace 3
bindsym $Alt+Shift+4 move container to workspace 4
bindsym $Alt+Shift+5 move container to workspace 5
bindsym $Alt+Shift+6 move container to workspace 6
bindsym $Alt+Shift+7 move container to workspace 7
bindsym $Alt+Shift+8 move container to workspace 8
bindsym $Alt+Shift+9 move container to workspace 9

# reload the configuration file
bindsym $mod+Shift+c reload
# restart i3 inplace
bindsym $mod+Shift+r restart
# exit
# bindsym $mod+Shift+e exec i3-msg exit

# media key
bindsym XF86AudioRaiseVolume $execi pactl set-sink-volume 0 +5%
bindsym XF86AudioLowerVolume $execi pactl set-sink-volume 0 -5%
bindsym XF86AudioMute $execi pactl set-sink-mute 0 toggle
bindsym XF86MonBrightnessUp $execi light -A 5
bindsym XF86MonBrightnessDown $execi light -U 5

# status bar
bar {
    mode dock
    output eDP-1
    position top
    tray_output eDP-1
    tray_padding 0
    font xft:FSMRMP 19.5
    i3bar_command i3bar --transparency
    status_command i3status -c $HOME/.config/i3/i3status.conf
    binding_mode_indicator yes
    colors {
      background #02020200
      statusline #F6F3E8
      separator  #111822
      focused_workspace  #111844 #222244 #F6F3E8
      active_workspace   #555555 #555555 #F6F3E8
      inactive_workspace #020202 #242424 #888888
      urgent_workspace   #A00000 #900000 #F6F3E8
      binding_mode       #A00000 #900000 #f6f3e8
    }
}

# class                 border  bground text    indicator child_border
client.focused          #111866 #333366 #F6F3E8 #2B2B2B   #2B2B2B
client.focused_inactive #020202 #242424 #F6F3E8 #2B2B2B   #2B2B2B
client.unfocused        #020202 #242424 #F6F3E8 #2B2B2B   #2B2B2B
client.urgent           #A00000 #900000 #F6F3E8 #2B2B2B   #2B2B2B
client.placeholder      #000000 #0C0C0C #FFFFFF #000000   #0C0C0C

# specific window settings
for_window [window_role="pop-up"] floating enable
for_window [window_role="task_dialog"] floating enable
for_window [class="(?i)feh"] floating enable
# for_window [class="(?i)vlc"] floating enable
for_window [class="(?i)firefox"] floating enable
for_window [class="(?i)zotero"] floating enable
for_window [class="(?i)zooom"] floating enable
for_window [class="(?i)teams"] floating enable
for_window [class="(?i)slack"] floating enable
for_window [class="(?i)ruby"] floating enable

# startup
assign [class="(?i)evince" ] 2
assign [class="(?i)nautilus" ] 2
assign [class="(?i)zotero" ] 2
assign [class="(?i)slack" ] 3
assign [class="(?i)firefox"] 4
assign [class="(?i)teams" ] 5
assign [class="(?i)remmina" ] 6
assign [class="(?i)zoom" ] 6