воскресенье, 15 февраля 2009 г.

EeePC, Debian,Xmonad с яблочным вкусом, заметки ламера :)

Итак, господа, кажется свершилось и "lenny" таки зарелизили. Не то чтобы на меня этот факт сильно уж повлиял: на рабочем десктопе у меня вялообновляемый unstable, на домашнем сервере "etch", который пока нет никакого желания и большой необходимости обновлять, "lenny" фактически только на EeePC, вот там его таки надо будет обновить до актуального состояния: 49 пакетов требующих обновления набежало. Но все-равно как-то приятно, что любимый дистрибъютив живет, и развивается в своем традиционном ключе.

Выходные выдались на удивление тихими, хотя оживленная рабочая неделя обещала совсем другое, и я продолжил играться с EeePC, в ключе "стянуть привычные вещи с Мака", на этот раз существенной корректировке подвергся конфиг Xmonad'а.

1. Фактически, активно пользоваться множеством рабочих столов я начал только в OS X - в Leopard'е они называются Spaces, и почему-то эти Spaces мне понравились и я нашел им достойное применение. По-умолчанию рабочих стола четыре, на каждом из которых я стараюсь запускать лишь определенные приложения: на первом - IM-клиент, на втором - терминал(ы), на третьем - почтовый клиент, на четвертом - различные браузеры. Такой расклад сложился исторически, и я к нему привык. Остальные приложения запускаются где прийдется, особой стратегии нет.

Что в этом плане прежде всего хотелось от Xmonad'а? - привязать запуск конкретного приложения к конкретному рабочему столу, для каждого рабочего стола установить свои специфические Layout'ы, которые подходят для запускаемых на нем приложений. Оказывается, сделать это достаточно просто. Допустим у нас четыре рабочих стола:

myWorkspaces = ["1","2","3","4"]

Для того чтобы firefox(iceweasel в дебиане) запускался на четвертом, в ManageHooks надо добавить что-то типа:

className =? "Iceweasel" --> doF(W.shift "4")

className можно подсмотреть в выводе утилиты xprop:

diesel@xenocefal:~$ xprop | grep WM_CLASS
WM_CLASS(STRING) = "xterm", "XTerm"

после запуска этой строчки курсор изменит форму и нужно будет щелкнуть им по окну WM_CLASS которого мы хотим узнать.

Вторая задача: каждому воркспейсу по своему Layout'у решается с помощью расширения XMonad.Layout.PerWorkspace, соответствующий import нужно добавить в начало конфига, а затем в layoutHook настройки будут выглядеть следующим образом:

myLayout = avoidStruts $
onWorkspace "1" (( windowNavigation $ (mytabs ****|* mytabs)) ||| mytabs) $
onWorkspaces ["2","3"] mytabs $
onWorkspace "4" (noBorders Full ||| mytabs)$
noBorders Full

я думаю комментировать тут особо нечего.

2. Apple'овцы для своих Spaces, кроме казалось бы логичной схемы переключения между рабочими столами а-ля Alt+F1, or smth like, когда нужно четко указать рабочий стол на который хочешь переключится, сделали еще одну, которой я активно пользуюсь. Основана эта схема переключения на, скажем так, задании относительного пути :) Допустим наша схема расположения рабочих столов выглядит вот так:




12
34

тогда, допустим если я нахожусь на рабочем столе за нумером два, и жму Ctrl + Down - я попадаю на рабочий стол за нумером четыре, Ctrl+Right - приведет на рабочий стол за нумером 3, а Ctrl+Up никуда не приведет, ну и так далее. При четырех рабочих столах, в принципе такими сочетаниями клавиш можно попасть с любого рабочего стола на любой. И хотя, вроде бы, такой способ переключения перечит заветам интерфейсостроителей в плане "хорошо, когда какое-нибудь действие приводит всегда к одному и тому же результату", что в нашем случае можно интерпретировать как "приводит на вполне определенный за каждым конкретным хоткеем рабочий стол", но тем не менее, как я уже сказал, подобную схему нахожу удобной.

Очевидный способ, частного решения данной задачи для четырех рабочих столов достаточно прост - зададим функцию которая, скажем по названию рабочего стола, и коду нажатой клавиши будет возвращать нам название рабочего стола на который требуется перейти. Получится что-то типа:

switchSpace "1" 2 = "1"
switchSpace "1" 4 = "4"
switchSpace "1" 6 = "2"
switchSpace "1" 8 = "3"
switchSpace "2" 2 = "2"
switchSpace "2" 4 = "1"
switchSpace "2" 6 = "3"
switchSpace "2" 8 = "4"
switchSpace "3" 2 = "1"
switchSpace "3" 4 = "2"
switchSpace "3" 6 = "4"
switchSpace "3" 8 = "3"
switchSpace "4" 2 = "2"
switchSpace "4" 4 = "3"
switchSpace "4" 6 = "1"
switchSpace "4" 8 = "4"

не очень красиво, но жить можно, если не понадобится больше рабочих столов. 2,4,6,8 - здесь, это отфонарные коэфициенты для стрелочек, на основе того как они на NumPad'е есть.

Когда такая функция в конфиге появится, в хоткеи можно дописать строчки типа:

((modMask, xK_Right), withWindowSet $ \s -> do windows $ W.view (switchSpace ( W.tag . W.workspace . W.current $ s ) 6))

и если мы ничего не напутали с цифрами - все будет работать. Попробуем немного упростить эту строчку, и сделать так чтобы нам было меньше писать:

((modMask, xK_Right), switchFrom 6)

где switchFrom объявим отдельно как:

switchFrom x = withWindowSet $ \s -> do windows $ W.view (switchSpace (currentTag s) x)
currentTag s = W.tag . W.workspace . W.current $ s

currentTag здесь возвращает название текущего воркспейса, которое нам нужно дать switchSpace для определения воркспейса на который мы хотим переключится, а собственно в функции switchFrom происходит переключение.

Допустим, что рабочих столов будет больше, очевидно нужно немного изменить поведение функции switchSpace для того чтобы она более разумно выдавала следующий рабочий стол. Итак:

switchSpace w x = myWorkspaces!!((myNextIndex w x)-1)

в переводе на человеческий: вытащить из списка myWorkspaces элемент за нумером, который получится в результате выполнения функции myNextIndex, ну вернее (myNextIndex-1). w - имя текущего воркспейса, x - "номер ассоциированный со стрелочкой".

myNextIndex w x = myNextWorkspace ( (myElemIndex w myWorkspaces)+1 ) x

здесь myElemIndex находит под каким индексом в списке myWorkspaces спрятано имя текущего десктоп, прибавляет к нему единицу(мне не хочется считать десктопы с нуля), и отдает на съедение myNextWorkspace:

myNextWorkspace current turn | current + turn > 0 && current + turn <= rows * cols = current + turn
| current + turn == 0 && turn == -1 = rows*cols
| current + turn == rows+cols + 1 && turn == 1 = 1
| otherwise = current

myNextWorkspace самая главная функция. Логика работы следующая, мы немного меняем циферки которые передаются при нажатии каждой клавиши:

Up = (-колличество строк)
Down = колличество строк
Left = -1
Up = +1

и.... пробуем: если сумма номера текущего рабочего стола влазит в количество рабочих столов - возвращаем эту сумму, если не влазит - возвращаем другие странные значения. Все вместе это выглядит примерно так. Хоткеи:

[ ((modMask, xK_Right), switchFrom 1)
,((modMask, xK_Left), switchFrom (-1))
,((modMask, xK_Up), switchFrom (-rows))
,((modMask, xK_Down), switchFrom rows) ]



Прочая ерунда:

switchFrom x = withWindowSet $ \s -> do windows $ W.view (switchSpace (currentTag s) x)
currentTag s = W.tag . W.workspace . W.current $ s
rows = 2
cols = 2
myNextWorkspace :: Int->Int->Int
myNextWorkspace current turn | current + turn > 0 && current + turn <= rows * cols = current + turn
| current + turn == 0 && turn == -1 = rows*cols
| current + turn == rows+cols + 1 && turn ==1=1
| otherwise = current myElemIndex :: Eq a => a -> [a] -> Int
myElemIndex x a = head (elemIndices x a)
myNextIndex w x = myNextWorkspace ( (myElemIndex w myWorkspaces)+1 ) x
switchSpace w x = myWorkspaces!!((myNextIndex w x)-1)


Я не силен в haskell'е - много раз начинал разбираться, но кажется надо очень много свободного времени для таких разборок... и этот десяток строк занял у мну достаточно много времени на разбирательства, хотя не скажу что было скучно и неинтересно. Уверен, что можно это записать как-то более разумно, но я рад получить хоть и ugly, но работающий вариант. :)

суббота, 7 февраля 2009 г.

gnome-settings-daemon, good bye

Не отпускает тема скриншотов: одним из традиционных комментариев на ЛОРе по поводу шрифтов, как известно, является уже ставшее классикой: "шрифты гавно". Действительно с шрифтами в Линуксе не все так просто и хорошо как хотелось бы, и очень часто "из коробки" они выглядят страшновато. Правда, это как обычно дело вкуса и привычек - в данном случае у меня вкуса нет - а привычки сложились исторически, не помню уже как. Во всяком случае последние пару лет, пользуясь Гномом я предпочитал выставлять Smoothing в Grayscale, Hinting в Slight, и радоваться жизни. Для других WM'ов неизменной строчкой в .xinitrc служил запуск gnome-setting-daemon'а, для того чтобы иметь привычный вид в GTK-приложениях. Сколько ни пытался написать в ~/.fonsts.conf что-то, что сделает тоже самое - ничерта разумного не получалось.

Но на EeePC ставить и запускать кусок Гнома, ради того чтобы рулить шрифтами - как-то не сильно хочется. И вот буквально сегодня нагуглил решение проблемы.

------------------ начало цитаты ------------------------
Таким образом, если у вас в gnome-appearance-properties в настройках сглаживания шрифтов стоят опции
Resolution = 96
Smoothing = Grayscale
Hinting = Slight
то ~/.Xresources должен содержать следующие строки:

Xft.dpi: 96.0
Xft.hinting: true
Xft.hintstyle: hintslight
Xft.antialias: true
Xft.rgba: none

------------------ конец цитаты --------------------------

У меня предпочтения те же, и рецепт действительно работает! Если у Вас предпочтения другие, но желания те же :) - по ссылке найдете короткое описание соответствие Х-ресурсов Xft, и настроек Гнома, и еще небольшой бонус в виде описания того как через .gtkrc установить тему(я предпочитаю для этого gtk-theme-switch).

воскресенье, 1 февраля 2009 г.

Linux like Mac: keyboard ...

Как-то недавно заметил, что скриншоты Windows, хотя ОС и сторонний софт дает возможность кастомайзить интерфейс как тебе захочется, не просто похожи один на другой, но еще и какие-то совсем неинтересные, чтобы не сказать безвкусные. Стандартная тема, или классическая тема, на рабочем столе склад иконок, а вместо валлпейпера машина или голая девка. Я, конечно немного утрирую, но вобщем-то не далеко от истины - могу сказать точно, что на редкий виндовый рабочий стол приятно смотреть, если видел что-то другое. Возможно виндузятники чувствует что-то похожее по отношению к маководам и линуксоидам, не знаю. На Маке возможности настройки внешнего вида существенно ограничены(я про Leopard): можно сменить картинку на рабочем столе, повертеть доком, если сильно захотеть - немного настроить внешний вид дока, да и все... но поскольку изначальный внешний вид вполне пристойный - смотреть скриншоты с Мака одно удовольствие, сугубое IMHO конечно. Линуксовые десктопы на редкость разнообразны, впрочем, при обилии DE, и WM'ов на все случаи жизни ожидать чего-нибудь другого и не приходится.

Правда, к сожалению, или к счастью, линуксоиды не всегда оригинальны и любят копировать внешний вид с других систем. Сам грешен: моя любимая цветовая схема уже несколько лет - это вариации на тему того что в KDE3 называлось Solaris - я так понимаю эти цвета должны напоминать пользователям олдскульный CDE.

Но все же любимой забавой линуксоидов являются закосы под Мак. Не проходит и месяца, чтобы на сайтах где я смотрю скриншоты, кто-нить не запостил очередной закос под интерфейс OS X. Иногда, совсем похоже, но чаще - это просто вариация на тему "вот так мне кажется в Маке все и есть". Объяснять, что наличие эмулятора дока и круглых кнопок - это еще не все не очень интересно, да и не каждый поверит. Но в конце-концов есть же еще:
- строка меню приложения расположенная вверху экрана. Ее можно было относительно просто включить в КДЕ 3, но только для КДЕ-приложений, что не очень интересно. В GTK-софте, насколько я знаю, прямого способа нет, а патчить ГТК - перебор. Повторюсь наверное, - общее меню - это не просто прикольно, потому что не как у всех - это еще и очень удобно: всегда, в одном месте, ты видишь меню активного окна - для того чтобы выбрать какой-то пункт меню нужно всего лишь дернуть мышей вверх, и там уже выбирать, в отличии от виндо-линукс-приложений, когда надо еще точно выбрать нужную высоту :)
- док, не не тот док, который скорее похож на кнопки быстрого запуска. Док, тот который трей, совмещенный с кнопками быстрого запуска.
- горячие клавиши. это то что не покажешь на скриншоте:), но одновременно, это то, без чего никакая эмуляция ОС Х не будет полной. Большая часть приложений имеет одинаковые клавиатурные сокращения - это означает, что "настройки", - это всегда Cmd+, (их еще и всегда в одном и том же месте в меню можно найти), а создать таб - Cmd+t, ну и так далее. Выучив похожие по-смыслу действия в одном приложении, ты сможешь ими воспользоваться во всех остальных. Тем, кто пытается "сохранить и выйти" с помощью :wq, или удалить слово с помощью Ctrl+w(что срабатывает чаще чем :wq :-)) полезность такой однообразности просто таки очевидна.

Можно обойтись без общей на всех строки меню, некоторые приложения, которыми я пользуюсь, ее совсем не имеют, в других - не так часто приходится туда лезть. Без дока и expose, обойтись сложнее, - я например рефлекторно двигаю мышкой в левый верхний угол желая увидеть превьюшки рабочих столов :), но тоже можно. А вот с хоткеями совсем беда - с одной стороны, уж очень упрощают жизнь, с другой - работая чаще всего на Маке, но иногда таки на Линуксе, когда в Линуксе нажимаешь привычное Cmd+t (то есть в переводе на PC-шную клавиатуру - Alt+t), и не получаешь открытого таба - очень расстраиваешься :) Посему, особенно после покупки EeePC, стала посещать меня мысль привести хоткеи в своем линуксовом окружении к тому, к чему я (ну очень быстро) привык, и активно использую, в Маке. На самом деле, не так уж и много этих хоткеев, которые активно используются.

Одно из важнейших отличий Маковских хоткеев, кроется в особенностях маковской клавиатуры: в ней наличествует клавиша Command, расположенная там, где на PC-клавиатурах Alt, и именно она активно используется, вместо PC'шного Ctrl(хотя и он тоже имеется в наличии). То есть, например, копирование/вставка - это Cmd+C/Cmd+V, создание нового таба - Cmd+T и так далее. Сначала это достаточно необычно и непривычно, но через некоторое время оказывается что это чрезвычайно удобно, и возвращаться на традиционный Ctrl не очень то и хочется. Да и не особо нужно: в принципе, для большинства случаев, нужно переназначить Ctrl на "ту клавишу, которая рядом с пробелом", а Alt перенести в какой-нить другое место. Делается это достаточно просто: в файле /usr/share/X11/xkb/keycodes/xfree86 находим что-то типа:

<LALT> = 37;
<LCTL> = 64;
<SPCE> = 65;
<RCTL> = 109;
<RALT> = 113;
// Microsoft keyboard extra keys
<LWIN> = 115;
<RWIN> = 116;
<MENU> = 117;

устанавливаем циферки как нам хочется, и радуемся жизни. Правда, надо еще подумать на тему что делать с терминалом и vim'ом, в которых такая замена совсем не нужна.

Еще всплывает вопрос о настройке переключалки клавиатуры, чтобы было "везде одинаково". В Линуксе мне нравилось, когда английский язык включался тыцаньем на Caps Lock, а русский - на Shift+Caps Lock. К сожалению, как сделать такое в Маке я так и не узнал, и немного попривык к тамошнему странному Cmd+Space - для двух языков не так уж оно и не неудобно :) Памятуя замену: LALT - LCTL, задача стоит как "Cделать переключение языков по Ctrl+Space".

Про кастомнизауию переключения раскладки я уже несколько раз писал, в этот раз, заглянув за инструкцией в свой последний пост, к своему разочарованию, увидел что инструкция собственно не работает в Debian Lenny, который у меня на EeePC:


diesel@xenocefal:~$ /usr/bin/X11/xkbcomp $HOME/.xkb.my $DISPLAY
Error: Can't find file ".xkbgroup.my" for symbols include
Exiting
Abandoning symbols file "raq104"

Решение, фактически, нашел методом тыка, как-то ничего разумного гугл по сему странному поводу не выдал. Решение следующее: создаем директорию $HOME/.xkb/symbols/, в нее кладем модифицированный соответствующим образом /usr/share/X11/xkb/symbols/group, и xkbcomp стартуем как:
/usr/bin/X11/xkbcomp -I$HOME/.xkb/ $HOME/.xkb/.xkb.my $DISPLAY

Вот тогда все отрабатывает как надо. Собственно для того чтобы был Ctrl+Space, нужно дописать что-то типа:

partial modifier_keys
xkb_symbols "ctrl_space_keys" {
key <spce> {
type[Group1]="PC_CONTROL_LEVEL2",
symbols[Group1]= [ space, ISO_Next_Group ]
};
};

ну и соответствующим образом изменить .xkb.my, если считать что модифицированный group это .xkbgoup:


diesel@xenocefal:~$ cat .xkb/.xkb.my
xkb_keymap "raq104" {
xkb_keycodes { include "xfree86" };
xkb_types { include "complete" };
xkb_compatibility { include "complete" };
xkb_symbols {
include "pc(pc105)"
include "us"
include "ru(winkeys):2"
include ".xkbgroup.my(ctrl_space_keys)"

};
xkb_geometry { include "pc(pc105)"};
};



Ну и завершая на сегодня тему хоткеев, околохоткейный hint. Одной из "фишек", которая, обычно нравится вновь прибывающим на linux является наличие двух буферов обмена - "мышиного"(тот который "выделяем что-нибудь, и вставляем средней кнопкой"), и "клавиатурного"(тот который почти везде работает по Ctrl+C/Ctrl+V). Так уже сложилось, что моим любимым эмулятором терминала c давних времен является xterm. Хотя он не умеет табы, не становится прозрачным, и скорее всего еще много всяких странных вещей не умеет, мне его всегда хватало, и не очень сильно своим привычкам хочется изменять. Проблема в том, что в Xterm'е "буффер клавиатуры" никак не задействован, то есть по-умолчанию скопировать в него чего-нить из терминала нельзя. А жаль, поскольку за отсутствием средней кнопки мыши, да и вообще мыши, когда есть только странный EeePC'шный тачпад, нажать "среднюю кнопку" весьма сложно, а Shift+Insert вставляет из мышиного буфера не везде. Оказывается, есть выход - заставить xterm вместо буфера мыши, копировать в буфер клавиатуры, и тогда можно с легкостью использовать привычный нам Ctrl+V для вставки чего-нить в тот же firefox. Делается это вот такой вот строчкой в ~/.Xresources:

*xterm*VT100.selectToClipboard: true

В xterm'е, правда, вставлять все-равно через Shift+Insert надо. Если кто знает как побороть - расскажите :)

PS: хех, с привычным расположением клавиш писать на EeePC гораздо приятнее :-).