Запускать приложения в определенной рабочей области, если они еще не запущены там

Вкратце: когда я переключаюсь на рабочее пространство X, я хочу, чтобы некоторые программы запускались автоматически, но только если они еще не запущены.

Это отличается от запуска XMonad в разных рабочих областях, поскольку я не хочу перемещать окна в определенные рабочие области (например, всегда перемещать xterm в рабочую область 2).
У меня это тоже не работает: xmonad появляется при запуске в другой рабочей области. Я не хочу, чтобы все приложения запускались сразу после входа в систему, также это не будет автоматически запускаться, например. xterm, если я закрою его и снова переключусь на рабочее пространство 2.


Хватит о том, что не работает, вот что работает:
(почти)

В моем списке рабочих областей я держу кортежи с именем рабочей области и списком программ, запускаемых при переключении туда:

myWorkspaces = [ ("VIM", ["gvim"]), ("TERM",[myTerminal ++ " -e tmux"]) ]

-- In my keybindings:
[ ((mod4Mask, key), loadWorkspace workspace cmd)
  | (key, (workspace, cmd)) <- zip [xK_1..] myWorkspaces
]

Я определил функцию для переключения в рабочее пространство и запуска данных программ:

loadWorkspace :: String -> [String] -> X()
loadWorkspace workspace commands =
    do windows $ W.greedyView workspace
       mapM_ spawn filtered_commands
           where filtered_commands :: X [String]
                 filtered_commands = filterM isNotOpen commands

                 isNotOpen :: String -> X Bool
                 isNotOpen command = return True

(По какой-то причине mapM_ требует, чтобы второй аргумент был String вместо [String]. Я хочу сопоставить spawn со строками в filtered_commands. , есть идеи, почему это не работает?)

Последняя недостающая часть — это функция isNotOpen, которая должна искать className окон в текущей рабочей области и возвращать, есть ли уже command.


Мне чрезвычайно сложно (по сравнению с другими языками и технологиями) искать способ работы с XMonad. В этом случае я смог найти только способ получить окна в текущем WS - https://superuser.com/a/852152/481701 . Хорошо, я думаю, это дает мне объект Window, я могу запросить у него некоторые атрибуты.

Но нет. Окно на самом деле... псевдоним для Word64!!! Хорошо, я думаю. Google xmonad получает атрибуты окна. Ничего такого. xmonad получает имя класса из идентификатора окна. Ничего такого. информация об окне xmonad. И дюжина других способов сказать что-то подобное — без толку. Все, что я получаю, это домашняя страница xmonad, часто задаваемые вопросы или «советы по настройке Xmonad».
Я попробовал это и в hayoo!, и самое близкое, что я смог получить, это «fromClassName — Colorize a window в зависимости от его className.». Ха-ха.

Итак, как я могу получить className окна (или любые другие атрибуты) вне ManageHook?


person Al.G.    schedule 27.08.2017    source источник


Ответы (2)


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

Я хочу отобразить появление строк в filtered_commands, есть идеи, почему это не работает?

Да, вам нужно поднять mapM_ для обработки монадического аргумента (в отличие от монадической функции или возвращаемого значения). Таким образом:

filtered_commands >>= mapM_ spawn

Или, поскольку вы уже находитесь в блоке do:

result_of_filtered_commands <- filtered_commands
mapM_ spawn result_of_filtered_commands

Итак, как я могу получить className окна (или любые другие атрибуты) за пределами ManageHook?

Посмотрите на источник className:

className = ask >>= (\w -> liftX $ withDisplay $ \d -> fmap resClass $ io $ getClassHint d w)

Вы можете принять только аргумент liftX как действие X, а не действие Query. Ключевая функция: getClassHint из пакета X11, который также предлагает доступ к другим атрибутам окон.

person Daniel Wagner    schedule 28.08.2017
comment
Большое спасибо за каждую часть вашего столь подробного ответа! - person Al.G.; 28.08.2017

Установить wmctrl

sudo apt install wmctrl

И создайте скрипт (в этом примере Thunderbird на второй рабочей области (-t 1)):

#!/bin/sh

 (thunderbird &)  & sleep 5 && 
sh -c "wmctrl -i -r `wmctrl -l | grep Thunderbird` -t 1"

Чтобы узнать имя вашего приложения на wmctrl, вы можете просмотреть его, нажав на своем терминале:

wmctrl -l

И замените его правильным именем в скрипте.

Будьте осторожны с заглавной буквой ("Thunderbird", а не "thunderbird")!!

Другой пример с Firefox в рабочей области 3D (-t 2):

#!/bin/sh
(firefox &)  & sleep 5 && 
sh -c "wmctrl -i -r `wmctrl -l | grep Firefox` -t 2"

Бонус:

Вот команда, которую нужно выполнить при запуске:

sh -c "thunderbird  & sleep 5 && wmctrl -i -r `wmctrl -l | grep Thunderbird` -t 1"

Работайте над Debain 10 с Cinnamon. Но должно работать для всех

person Pierre    schedule 13.03.2020