LINUX.ORG.RU

StumpWM как вершина ручного тайлинга

 , , ,


3

3

StumpWM — это ручной тайловый менеджер, написанный на Common Lisp. Со стороны эта фраза ничего не значит, но на деле это оконный менеджер с огромным потенциалом для превращения его в удобную рабочую среду, альтернатив которой почти нет (если есть вообще).

Прежде всего, что такое ручной тайлинг (или manual tiling, или static tiling). Это тайлинг, где расположением окон управляет пользователь, а не оконный менеджер. В случае со StumpWM, пользователь делает сетку из фреймов (или тайлов), куда будут распологаться окна. Окна распологаются друг над другом и занимают фрейм полностью. Можно привести аналогию с картами, где окно — это карта и эта карта складывается в общую пачку в виде фрейма и, эти несколько пачек, располагающиеся напротив друг друга — это итоговая сетка из фреймов. По опыту, это самое безболезненное решение из всех, если окон очень много.

Сам оконный менеджер написан на Common Lisp и, благодаря этому, позволяет переконфигурировать его на лету через Emacs+SLIME/Sly. Сам конфиг тоже на лиспе, что удобно. У меня, например, накопилось около 2000 строк кода. WM позиционирует себя как Emacs среди оконных менеджеров. Не в плане того, что может полностью зависнуть, если какой-то из плагинов будет долго думать, а в плане способствования хакам.

Кстати об имаксе. Как и у Emacs, у StumpWM хоткеи работают по принципу цепочки аккордов (chord chain). Например, можно реализовать такой хоткей: нажатие Ctrl+C, отпускание и нажатие таба — это может считаться одним хоткеем и быть забиндено на, скажем, вызов терминала. В конфиге выглядеть это будет примерно так:

(set-prefix-key (kbd "C-c"))
(define-key *root-map* (kbd "Tab") "run-shell-command sakura")

Из кода получается, что при нажатии на Ctrl+C оконный менеджер переключит лейаут клавиатуры на root-map и будет ожидать следующей клавиши. А на этом лейауте будет таб, при нажатии на который будет вызываться команда sakura. Мап, по факту, является раскладкой клавиатуры для оконного менеджера, на котором расположены бинды команд для него. И подобных map-ов может быть, в целом, до бесконечности и можно даже подсунуть мап в хоткей другого мапа:

(set-prefix-key (kbd "C-c"))
(register-kmap *layout-map* nil)
(define-key *root-map* (kbd "w") '*layout-map*)

Тут при переходе на рутовый мап мы можем нажать на W и перейти на следующий мап — layout-map.

Говоря простым языком, мы можем определять потенциально бесконечное число цепочек аккордов для хоткея. И это замечательно в плане эргономики — руки меньше напрягаются для хоткеев.

Я использую патченный StumpWM, т.к. мне не удалось найти, можно ли в лиспе в рантайме менять атрибуты класса. Но у патчей есть свои предпосылки. Ванильный StumpWM для перемещения по лейауту предлагает переключение фреймов по принципу «ближайший в заданном направлении», что неудобно и занимает время при переключении (особенно на мультимониторных конфигурациях). Так что мне удалось встроить в StumpWM свой принцип переключения фреймов, который заключается в тегировании фреймов. Схему в общем виде можно наблюдать на второй пикче. Суть в том, что на фрейм накладывается определённый тег, который привязывается к определённому хоткею. И, соответственно, при нажатии будет немедленное переключение на соответствующий тег. Патч был нужен лишь для добавления атрибута тега в класс фрейма. Функции по работе с этим реализованы на уровне конфига. Теги создаются динамически и также динамически привязываются к хоткеям. Они могут по-разному называться и их может быть до бесконечности.

Весь этот текст — фиксация того, что можно найти в StumpWM, т.к. с него я ухожу. Это один из лучших оконных менеджеров, но в нём есть свои проблемы:

  • Плохая поддержка мультимониторной конфигурации. Если в каком-нибудь herbstluftwm на один монитор даётся один воркспейс, то у StumpWM один воркспейс на все мониторы. Это порождает разного рода проблемы, например, если второй монитор служит информационным дисплеем, то при переключении воркспейсов, воркспейс переключается на всех мониторах, соответственно, убирая информацию со второго монитора.

  • Позиционирование а-ля имакс. Субъективщина, но модульность кажется более лучшим решением, чем всё в одном решении.

  • Мне не удалось придумать как решить проблему, если в воркспейсе накопилось слишком много окон. Ты начинаешь в них утопать, переключая в поисках нужного. То, как это всё реализовано в StumpWM сейчас — лучшее из того, что мне доводилось пробовать. Но хочется лучше. У меня была идея делать субворкспейсы — это обычные воркспейсы, но они условно привязаны к какому-либо из воркспейсов. По типу того, что есть воркспейс anyame и мы создаём подворкспейсы: anyame1, anyame2, etc… И все окна раскидываем по ним. Главное тут во всём: переключение подворкспейсов должно быть максимально доступным, как Alt+Tab, только в два хоткея: вперёд по цепочке и обратно. Но вся идея упёрлась в первый пункт проблем. И это стало малоиспользуемым, по итогу.

  • Просто мелкие баги, которые могут доставлять дискомфорт. Например, может быть так, что WM может застрять между двумя воркспейсами и показывать окна с них одновременно — лечится переключением обратно.

Проблема с большим количеством окон для меня сильно актуальна, т.к. я стараюсь отказываться от табов в приложении в пользу отдельных окон, т.к. окнами должен управлять оконный менеджер. И у меня уже есть идея улучшенного тайлинга, который должен быть лучше классического. Но это если и будет, то не на тайловом WM.

А так, в плане кастомизации под свои нужды, этот WM — вершина ручного тайлинга.

Дальнейшие ресурсы для изучения:



Проверено: hobbit ()
Последнее исправление: rhubear (всего исправлений: 2)

с него я ухожу

И куда же?

А по содержательности материала – может, это не в галерею, а сразу в статьи? В статьях тоже можно иллюстрации делать.

hobbit ★★★★★
()
Ответ на: комментарий от hobbit

И куда же?

Хочется попробовать сделать связку из berry wm и sxhkd, но нужно сделать ещё звено, которое отвечало бы за сам тайлинг.

А по содержательности материала – может, это не в галерею, а сразу в статьи? В статьях тоже можно иллюстрации делать.

Тут не знаю. Кажется, что тут много субъективщины, которая конструктива не приносит для статьи, такой типа опыт конкретного человечка.

rhubear
() автор топика
Последнее исправление: rhubear (всего исправлений: 1)

Emacs среди оконных менеджеров

WM окнами не управляет

Ну логично, в Emacs текстовый редактор тоже не завезли.

Bfgeshka ★★★★★
()
Ответ на: комментарий от Bfgeshka

открою-ка я окно

*весь лейаут перехерачивается*

Ну, управление, да.

rhubear
() автор топика
Ответ на: комментарий от cetjs2

Пока на связку из разного, но там поляна ещё не подготовлена, нужно самостоятельно допилить будет.

rhubear
() автор топика

Emacs среди оконных менеджеров.

Emacs среди оконных менеджеров – это exwm.

hateyoufeel ★★★★★
()

А можно несколько вопросов?

  1. Что с несколькими мониторами?
  2. Что с наличием нескольких workspace/window?
Silerus ★★★★★
()
Ответ на: комментарий от Silerus

Что с несколькими мониторами?

Можно пользоваться, но WM накладывает некоторые ограничения на это (см. первый пункт проблем), из-за чего теряется некоторая гибкость.

Что с наличием нескольких workspace/window?

Ну, у меня в конфиге под сотню воркспейсов инициализируется (изначально под субворкспейсы оно планировалось, но не взлетело). Под окнами не знаю что конкретно подразумевается, но работать приятно так-то с ними. Можно листать окна в рамках фрейма, можно мб ещё что реализовать — тут вроде бы не так много ограничений.

rhubear
() автор топика
Ответ на: комментарий от Silerus

Инициализация воркспейсов у меня примерно так выглядит:

(loop for group-name in groups-list do
  (progn
	  (setf (gethash (read-from-string group-name) subgroups-list)
			(list (concatenate 'string group-name "|1")
				  (concatenate 'string group-name "|2")
				  (concatenate 'string group-name "|3")
				  (concatenate 'string group-name "|4")
				  (concatenate 'string group-name "|5")
				  (concatenate 'string group-name "|6")
				  (concatenate 'string group-name "|7")
				  (concatenate 'string group-name "|8")
				  (concatenate 'string group-name "|9")
				  (concatenate 'string group-name "|10")
				  (concatenate 'string group-name "|11")
				  (concatenate 'string group-name "|12")
				  (concatenate 'string group-name "|13")
				  (concatenate 'string group-name "|14")
				  (concatenate 'string group-name "|15")))
      (loop for subgroup-name in (gethash (read-from-string group-name) subgroups-list) do
			(gnewbg subgroup-name))
	  ))

Нужно будет создать список с названиями для воркспейсов (groups-list) перед исполнением этого кода, конечно.

rhubear
() автор топика
Последнее исправление: rhubear (всего исправлений: 1)

с огромным потенциалом для превращения его в удобную рабочую среду

Наверное для этого нужен потанцевал. Умеет StumpWM во вкладки, чтобы не замыкаться на тайлинге?

dmitry237 ★★★★★
()
Ответ на: комментарий от dmitry237

Умеет StumpWM во вкладки, чтобы не замыкаться на тайлинге?

Есть открытый Issue на этот счёт, правда, с wontfix тегом. Но там же есть какая-то реализация. При желании можно попробовать использовать и подпилить в случае чего.

Btw, там же подсказывают другое уже готовое решение в виде списка окон для конкретного воркспейса. Работает примерно так. Безусловно команду (windowlist) можно повесить на хоткей, а не вписывать ручками. Но это просто пример.

rhubear
() автор топика

вершина

Переверни картинку, ты дно царапаешь.

bdrbt
()

Ванильный StumpWM для перемещения по лейауту предлагает переключение фреймов по принципу «ближайший в заданном направлении», что неудобно и занимает время при переключении (особенно на мультимониторных конфигурациях). Так что мне удалось встроить в StumpWM свой принцип переключения фреймов, который заключается в тегировании фреймов

Я что-то не понял, или патч дублирует изкоробочный fselect?

skiminok1986 ★★★★★
()
Ответ на: комментарий от skiminok1986

fselect

Кстати, удалось забыть про её существование почему-то. Но, энивей, если правильно понимаю функционал этой команды, то не совсем дублирует: fselect генерирует номера фреймов на ходу и они могут быть разными на фрейм. В моей же реализации тег присваивается вручную по прихоти пользователя. Ещё, если правильно понимаю, в мультимониторной конфигурации оно не работает нормально (у меня есть пересечение номеров фреймов с фреймами другого монитора, но тут возможно проблема на моей стороне).

Возьму свой случай использования тегов. У меня есть устоявшийся лейаут окон, и на каждый фрейм идёт свой устоявшийся тег, к которому привязан определённый хоткей. Т.е. нажимая определённый хоткей, я точно знаю какой тег/фрейм будет выбран.

А так, fselect тоже выглядит хорошо. Правда, есть вопрос в том, как он работает если фреймов количество тегов больше или равно 10. Например, тех же тегов у меня используется как раз десяток.

rhubear
() автор топика
Последнее исправление: rhubear (всего исправлений: 1)
Ответ на: комментарий от rhubear

А так, fselect тоже выглядит хорошо. Правда, есть вопрос в том, как он работает если фреймов количество тегов больше или равно 10. Например, тех же тегов у меня используется как раз десяток.

Надо пробовать, а мне лень ставить stumpwm :)

skiminok1986 ★★★★★
()

Спасибо, друг! Иключительно вовремя. Как раз искал нечто подобное, всерьёз занялся lispом, хочу освоить emacs и GNU guix, теперь и stumpwm тоже!

BACR
()
(kbd "C-c")

Всё бы хорошо, если бы в Имакс это не было биндом. Казалось бы, сделано на лиспе. Лисп - это автоматически Emacs. Но не же! Надо навесить самый основной стандартный кейбинд, который используется в Emacs. А какой навесить? Может C-x? C-d? C-f? C-v? C-w? C-g? Ахахах, да они же все заняты в Emacs. А что же тогда навешивать?

WM хороший, но синхронный. Это означает, что если что-то в нём выполняется и залипло, то залип весь WM

Что там с переходом на wayland? А то понаписал такой конфиг, а иксы дропнули и куда потом девать этот прекрасный конфиг?

bryak ★★★★
()
Последнее исправление: bryak (всего исправлений: 3)
Ответ на: комментарий от bryak

Всё бы хорошо, если бы в Имакс это не было биндом

В посте рандомный пример.

А что же тогда навешивать?

У меня, например, в качестве префикс-кея используется рандомная неиспользуемая мультимедийная клавиша XF86Search (реализовано через клавиатурные слои — доступно на клавиатурках с QMK/ZMK-прошивкой, либо реализуемо через софт).

WM хороший, но синхронный. Это означает, что если что-то в нём выполняется и залипло, то залип весь WM

Не доводилось с этим сталкиваться, в отличие от имакса.

Что там с переходом на wayland?

Пилится отдельный проект — mahogany. Судя по коммитам, довольно активно. Как понимаю, сам stumpwm никуда не денется, если оно дойдёт до рабочего состояния.

rhubear
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.