1年の5%終わってるって知りました.年明けたばっかでは...?
年明けの瞬間は大晦日に購入したポケモンでコオリッポ探しをしてたし,ほんとなにもしてないです.

今回はシステムモニターツールのconkyの話.
調べてみると,前のバージョン用のconky設定ファイルの日本語ブログが多いこと多いこと. 最近conky使ってる日本人少ないんですかね.

でも,conkyで画像検索すると,かっこいいやつが多いですね.
特にconky luaで検索すると,ほとんどかっこいいやつです.

というわけで,先人たちの知恵を活用して作ったのが以下のようなやつです.

image

Usage

にて公開しています.

あくまで,上図は2020-01-21時点のやつなので,ちょくちょく変えて行く予定です.

というか,全部luaで書けよって話ですよね...
なんか面倒くさくなってちょいちょいconky.confの方に甘えてます.

説明

グラフ

Graph Widget
こちらを使わして頂きました.
ただ,sourceがDeviantArtの方で公開されており,登録が必要です.Graph Widget for Conky 1.1
個人的に困ったことがあって,,valueがmaxを超えた時,普通に上限突破してグラフを描画してくるのでそこはmaxを上限に描画するようにしています.
CPUとかmemoryとか通信速度のグラフには,このグラフとは別に普通に描画しています.(時間あったらこの機能も付け加えておきます.)

テキスト

luaで普通にテキストの類を描画する時,

text = 'Hello'
cairo_move_to(cr, x, y)
cairo_show_text(cr, text)

ってな感じに書きますが,x,yの座標はテキストの左上を指定しており,右揃えとかやりたい時に死ぬので,

text = 'Hello'
local te = cairo_text_extents_t:create()
local fe = cairo_font_extents_t:create()
cairo_text_extents(cr, text, te)
cairo_font_extents(cr, fe)
-- 指定場所がテキストの右側になるように
x = x - te.width - te.x_bearing
-- 指定場所がテキストの中央になるように
x = x - te.width/2 - te.x_bearing
-- 下
y = y - fe.descent
-- 中央
y = y + te.height/2
-- 上
y = y + fe.ascent
cairo_move_to(cr, x, y)
cairo_show_text(cr, text)

という感じでやります.

カレンダー

これだけのために新たにluaで書くの面倒くさいので,conky.confの方のexecで出力しています.
こいつに関してgotoとかをすると,1行目だけ吹っ飛んで行くので,sedをかけてます.(そのためのexecpi)

${execpi 3600 gcal --type=standard -s 1 | sed 's/^/${goto 410}/' | sed -e 's/</ ${color red}/' -e 's/>/${color1} /'}

前者のsedでずれの調整をしてください.
後者のsedは色のない日常にせめて日付だけでも色をつけようとしているだけです.

バー

conky-drawを使用しています.
GUI版で設定ファイルを作成することも出来るそうなので便利

充電残量とか充電状態とかはupowerコマンドを使っています.

状態

upower -i $(upower -e | grep BAT0) | grep state | awk '{print $2}'

私の環境だとバッテリーが2つついていて,BAT1の方を優先的に使用するので,grep BAT1にしています.
残量に関してはこちらのスクリプトを使用しています.

#!/bin/bash
filelist=`upower -e | grep BAT`
energy=0
energyfull=0
while read line
do
    energy=$(echo $energy + `echo $(upower -i $line | grep energy: | awk '{print $2}')`| bc )
    energyfull=$(echo $energyfull + `echo $(upower -i $line | grep energy-full: | awk '{print $2}')`| bc )
done <<END
$filelist
END
percentage=`echo "scale=2; $energy *100 / $energyfull" | bc`
echo $percentage%

と思っていましたが,なんか専用の増えてますね.
バッテリーが複数の場合,それぞれの容量と残量を総計して,全体の残量を計算していましたが,DisplayDeviceでできそうです.
こっちの方が楽で良さげです.

> upower -i $(upower -e | grep DisplayDevice) | grep percentage | awk '{print $2}'

で同様の結果が得られました.
状態に関してはicon-nameを使うことにします.
icon-nameは,

  • ac-adapter-symbolic
  • battery-missing-symbolic
  • battery-empty-symbolic
  • battery-full-charged-symbolic
  • battery-caution-charging-symbolic
  • battery-caution-symbolic
  • battery-low-charging-symbolic
  • battery-low-symbolic
  • battery-good-charging-symbolic
  • battery-good-symbolic
  • battery-full-charging-symbolic
  • battery-full-symbolic

があり,とりあえず,battery-(caution | low | good | full)-*(charged-)symbolicとbattery-full-charged-symbolicだけ考えればいいかなと.

percentchargingdischarging
<10battery-caution-charging-symbolicbattery-caution-symbolic
<30battery-low-charging-symbolicbattery-low-symbolic
<60battery-good-charging-symbolicbattery-good-symbolic
battery-full-charging-symbolicbattery-full-symbolic

これに加えて,battery-full-charged-symbolicとbattery-empty-symbolicがあるそうです.
今はまだ直してませんが,時間がある時にでも直しておきます.

画像

雨雲の動きの取得に関してはただ,curlで取得してるというクソザコっぷりなので置いときます.
画像の表示にはimlib2を用いるのでGentooの場合は,USEフラグにimlibを加えてください.
基本概形はこんな感じです.

require 'imlib2'

file='hoge.png'
x=0
y=0
width=100
height=100

local show = imlib_load_image (file)

if show == nil then return end

imlib_context_set_image (show)
local scaled = imlib_create_cropped_scaled_image (0, 0, imlib_image_get_width (), imlib_image_get_height (), width, height)
imlib_free_image ()
imlib_context_set_image (scaled)
imlib_render_image_on_drawable (x, y)
imlib_free_image ()
show = nil

ところでここ,pngを用いる場合は注意が必要で,透過情報を持ったpngを使うと,conkyの枠自体同じくらい全部透けます. 透過部分だけじゃなくて全部透けます.

Wikiのレナ画像を用意して,

> convert Lenna.png Lenna.jpg
> convert Lenna.png -define png:color-type=6 Lenna-trans.png

で,jpgとpng(color typeが2,6の2種類)を作成して表示させると,

Lenna.jpg image
Lenna.png(Color Type: 2) image
Lenna-trans.png(Color Type: 6) image
Color Type:6 のpngはconkyと一緒に透けます. Color Typeは,
> identify -verbose hoge.png | grep color_type

で見れます.

音楽

audacious以外の場合はわかりません.
やっぱshellで状態取得出来るの楽だわ...
というかつい最近知ったんですが,音楽のサムネイル画像ってaudaciousだと,/tmp/以下にaudacious-??????という名前で居るんですね.
サムネイルの画像を枠の中央に配置させたい場合は,imlib_image_get_width (), imlib_image_get_height ()などで画像のサイズを取得し,x座標またはy座標をずらして表示させることで,中央に表示させるようにしています.

audacious_elements = {
  audacious = {
    pos={0,545},
    text='audacious',
    align={'left','center'},
    size=16,
  },
  status = {
    pos={30,940},
    font='Font Awesome',
    text='',
    align={'left','top'},
    size=48,
  },
  title = {
    pos={320,930},
    font='IPAPGothic',
    size=20,
    sh='audtool current-song',
    align={'center','middle'},
  },
  artist = {
    pos={640,950},
    font='IPAPGothic',
    size=14,
    sh='audtool current-song-tuple-data artist',
    align={'right','middle'},
  },
  time = {
    pos={640,970},
    sh='echo $(audtool current-song-output-length) / $(audtool current-song-length)',
    align={'right','middle'},
    size=18,
  },
  thumbnail = {
    x = 0,
    y = 550,
    h = 360,
    w = 640,
    align = 'center',
    file = '',
  }
}


local music_status = io.popen('audtool playback-status'):read("*a")
music_status = string.gsub(music_status, "\n", "")
if music_status ~= '' then
    cairo_set_line_width(display, 2)
    cairo_move_to (display,65,543)
    cairo_line_to (display,640,543)
    cairo_stroke (display)
    local status_icon = {
      playing = '',
      paused = '',
      stoppped = '',
    }
    audacious_elements['status']['text'] = status_icon[music_status]

    for i in pairs(audacious_elements) do
        if i == 'thumbnail' then
            local path = io.popen('ls /tmp | grep audacious-temp'):read("*a")
            path = string.gsub(path, "\n", "")
            if path ~= '' then
                audacious_elements['thumbnail']['file'] = '/tmp/' .. path
                image(audacious_elements['thumbnail'])
            end
        else
            write_text(display, audacious_elements[i], updates)
        end
    end
end


function image (im)
    local x = (im.x or 0)
    local y = (im.y or 0)
	local w = (im.w or 0)
	local h = (im.h or 0)
	local file = tostring (im.file) or nil
	if file ~= nil then
    local show = imlib_load_image (file)
    if show == nil then return end
        imlib_context_set_image (show)
    if im.align == 'center' then
        width = imlib_image_get_width ()
        height = imlib_image_get_height ()
        local aspect_width = height*w/h
        if width <= aspect_width then
            -- 縦長
            width = width * h / height
            height = tonumber (h)
            x = x + (w-width)/2
        else
            -- 横長
            height = height * w / width
            width = tonumber (w)
            y = y + (h-height)/2
        end
    else
        if tonumber (w) == 0 then
            width = imlib_image_get_width ()
        else
            width = tonumber (w)
        end
        if tonumber (h) == 0 then
            height = imlib_image_get_height ()
        else
            height = tonumber (h)
        end
    end
    imlib_context_set_image (show)
    local scaled = imlib_create_cropped_scaled_image (0, 0,
                                                      imlib_image_get_width (),
                                                      imlib_image_get_height (),
                                                      width, height)
    imlib_free_image ()
    imlib_context_set_image (scaled)
    imlib_render_image_on_drawable (x, y)
    imlib_free_image ()
    show = nil
  end
end