понедельник, 12 марта 2012 г.

Интерактивные conky


О том, как задействовать мышь в конки


Недавно на форуме http://crunchbanglinux.org/ большой любитель conky mrpeachy продемонстрировал несколько примеров

http://youtu.be/bnLjaVPU_Ds
http://youtu.be/AQsWeU3u1HQ
http://youtu.be/DhHUTjQObnI

и мой вариант

http://youtu.be/yg_PgFebm3U

Всё это основано на одной функции, написанной на LUA, которую можно добавить в любой скрипт. Вот эта функция

function clickfunction()
-- запускаем опрос мыши
if start == 1 then
-- проверяем запуск xdotool
xdot = conky_parse("${if_running xdotool}1${else}0${endif}")
-- останавливаем, если работает
if xdot == "1" then
os.execute("/usr/bin/killall xdotool && echo 'xdo killed' &")
end
-- ждем клика мыши в окне и записываем данные в /tmp
os.execute("xdotool search --name weather behave %@ mouse-click getmouselocation >> /tmp/weather &")
-- сбрасываем значение запуска
-- для включения опроса мыши во время каждого обновления conky
start = nil
-- определяем координаты мыши
local f = io.popen("xwininfo -name 'weather' | grep 'Absolute'")
geometry = f:read("*a")
f:close()
geometry = string.gsub(geometry,"[\n]","")
s,f,abstlx = string.find(geometry,"X%p%s*(%d*)")
s,f,abstly = string.find(geometry,"Y%p%s*(%d*)")
end
-- считываем данные из /tmp
local f = io.open("/tmp/weather")
click = f:read()
f:close()
-- если данные есть, то стираем их для следующей записи
if click ~= nil then
local f = io.open("/tmp/weather","w")
f:write("")
f:close() 
end
-- если данных нет, обнуляем координаты
-- для вывода координат за пределы окна
if click == nil then click = "x:0 y:0 " end
-- забираем координаты мыши
s,f,mousex = string.find(click,"x%p(%d*)%s")
s,f,mousey = string.find(click,"y%p(%d*)%s")
-- переводим в числовое значение
mousex = tonumber(mousex)
mousey = tonumber(mousey)
-- корректируем координаты мыши относительно окна
localx = mousex-abstlx
localy = mousey-abstly
-- возвращаем координаты
return localx,localy
end

Для работы функции необходимы xdotool и libxdo2. Версии должны быть не ниже xdotool 2.20110530.1 libxdo2 2.20110530.1-3, у меня в Ubuntu-11.10 запустилось сразу, а в Cranchbang-10 пришлось устанавливать более новые версии. Последние версии для 64 и 32 можно взять здесь http://dl.dropbox.com/u/22038871/new.tar.gz

Теперь как это всё прикрутить к conky. Сначала необходимо отредактировать conkyrc, строки

own_window yes
own_window_class Conky 
own_window_transparent yes 
own_window_type override 
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager 

необходимо привести к такому виду

own_window yes
own_window_class Conky 
own_window_transparent yes
#own_window_type override
own_window_type normal
own_window_title weather
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager

В строке

own_window_title weather

вместо weather можно использовать любое название окна, но тогда в фукции необходимо будет в следующих строках

os.execute("xdotool search --name weather behave %@ mouse-click getmouselocation >> /tmp/weather &")
local f = io.popen("xwininfo -name 'weather' | grep 'Absolute'")

заменить weather на ваше название окна.


Далее берем скрипт в который добавляем эту функцию, я добавил функцию в конец моего скрипта main.lua, отвечающего за вывод изображений и текстов, после последнего end

В начале скрипта добавляем следующие строки, пример для двух кнопок

require "cairo"
-- запуск проверки состояния кнопок мыши
start = 1
-- координаты и размер кнопок
-- формат: координаты x; координаты y; ширина; высота
-- 1-я кнопка
button_1_x = 10; button_1_y = 10; button_1_w = 100; button_1_h = 30
-- 2-я кнопка
button_2_x = 120; button_2_y = 10; button_2_w = 100; button_2_h = 30
--цвет надписей в кнопках
colour_off = {{0, 0x555555, 0.3},{0.5, 0xcfcfcf, 0.5},{1, 0x555555, 0.3}}
colour_on = {{0, 0x001155, 1},{0.5, 0xaaaaff, 1},{1, 0x001155, 1}}

Ниже строк

if conky_window == nil then return end

local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)
-- получаем данные от действия мыши
localx,localy=clickfunction()

и строки обрабатывающие данные, для первой кнопки

-- 1-я кнопка
if localx >= button_1_x and localx <= button_1_x + button_1_w and localy >= button_1_y and localy <= button_1_y + button_1_h and button_1 ~= 1 then
button_1 = 1
button_2 = 0
elseif localx >= button_1_x and localx <= button_1_x + button_1_w and localy >= button_1_y and localy <= button_1_y + button_1_h and button_1 == 1 then
button_1 = 0
button_2 = 0
end


if button_1 == 1 then

Первое нажатие кнопки дает значение 1, второе нажатие этой же кнопки сбрасывает значение на 0

Далее помещаем команды которые необходимо выполнить, например для запуска плейера VLC пишем

-- проверяем, работает ли vlc
local start_stop = conky_parse("${if_running vlc}1${else}0${endif}")
-- если не работает, запускаем
if button_1 == 1 and start_stop ~= "1" then
os.execute("vlc &")
end
-- выключаем
if button_1 == 0 and start_stop == "1" then
os.execute("killall vlc &")
end

Для вывода текста я использую скрипт text.lua написанный wlourf, в скрипте main.lua текст выводится такой командой

-- вывод текстов
for i,v in pairs(settings_text_now) do
cr = cairo_create (cs)
display_text(v)
cairo_destroy(cr)
end

Для вывода изображения кнопок я использую скрипт box.lua также написанный wlourf. Для детального ознакомления с работой кнопок можете взять мой скрипт вывода погоды, ссылка на работу скрипта в начале поста. Ссылка на conky http://dl.dropbox.com/u/22038871/weather_interactiv.tar.gz

3 комментария:

  1. Как то через раз работает, не все клики что ли ловит. Как то это лечится?

    ОтветитьУдалить
    Ответы
    1. Это зависит от времени обновления conky. Чем чаще обновления, тем лучше работают. У меня обновления 1 раз в секунду и приходится ждать срабатывания. Чем чаще обновления, тем больше нагрузка на процессор.

      Удалить
    2. Ага, спасибо! Заметил, что если не просто кликать, а нажать и задержать на некоторое время то срабатывает почти всегда.

      Удалить