Фильтровать окна по приложению, заголовку, расположению на экране и многое другое, а также легко подписываться на события этих окон
Предупреждение: этот модуль все еще находится в стадии разработки. Если у вас возникнут какие-либо проблемы, пожалуйста, сообщите о них на https://github.com/Hammerspoon/hammerspoon/issues или #hammerspoon на irc.libera.chat.
Windowfilters отслеживают все окна при их создании, закрытии, перемещении и т. д. и выбирают некоторые (или ни одного) из этих окон в соответствии с определенными правилами фильтрации. Эти правила фильтрации специфичны для приложения, т. е. они начинают с выбора всех окон, принадлежащих определенному приложению (но вы также можете определить фильтры по умолчанию и переопределяющие - см. :setAppFilter(), :setDefaultFilter(), :setOverrideFilter()) и могут разрешать или отклонять окна на основе:
видимости, фокусировки и/или полноэкранного режима
длины заголовка или шаблонов в заголовке
положения на экране (внутри или вне определенной области или экрана)
роли доступности (стандартное окно, диалоговое окно и т. д.)
находится ли оно в текущем пространстве Mission Control или нет
Фильтрация происходит автоматически в фоновом режиме; затем windowfilters:
генерируют динамический список окон, которые в настоящее время соответствуют правилам фильтрации (см. :getWindows())
очищают и предоставляют все соответствующие события этих окон (см. :subscribe() и модульные константы со всеми событиями)
Фильтрация окон по умолчанию (не путать с фильтром по умолчанию внутри фильтра окон) предоставляется для удобства; она исключает некоторые известные приложения и окна, которые носят временный характер, поэтому вряд ли представляют «интерес» для, например, управления окнами. hs.window.filter.new() (без аргументов) возвращает копию фильтра окон по умолчанию, которую вы можете дополнительно настроить в соответствии со своими потребностями - см. hs.window.filter.default и hs.window.filter.new() для получения дополнительной информации.
Примеры использования:
local wf=hs.window.filter
-- alter the default windowfilter
wf.default:setAppFilter('My IDE',{allowTitles=1}) -- ignore no-title windows (e.g. transient autocomplete suggestions) in My IDE
-- set the exact scope of what you're interested in - see hs.window.filter:setAppFilter()
wf_terminal = wf.new{'Terminal','iTerm2'} -- all visible terminal windows
wf_timewaster = wf.new(false):setAppFilter('Safari',{allowTitles='reddit'}) -- any Safari windows with "reddit" anywhere in the title
wf_leftscreen = wf.new{override={visible=true,fullscreen=false,allowScreens='-1,0',currentSpace=true}}
-- all visible and non-fullscreen windows that are on the screen to the left of the primary screen in the current Space
wf_editors_righthalf = wf.new{'TextEdit','Sublime Text','BBEdit'}:setRegions(hs.screen.primaryScreen():fromUnitRect'0.5,0/1,1')
-- text editor windows that are on the right half of the primary screen
wf_bigwindows = wf.new(function(w)return w:frame().area>3000000 end) -- only very large windows
wf_notif = wf.new{['Notification Center']={allowRoles='AXNotificationCenterAlert'}} -- notification center alerts
-- subscribe to events
wf_terminal:subscribe(wf.windowFocused,some_fn) -- run a function whenever a terminal window is focused
wf_timewaster:subscribe(wf.hasWindow,startAnnoyingMe):subscribe(wf.hasNoWindows,stopAnnoyingMe) -- fight procrastination :)
Обзор API
Константы - Полезные значения, которые нельзя изменить
Фильтр окон по умолчанию; он фильтрует приложения, окна которых имеют временный характер, поэтому они вряд ли (и часто)
Примечания
Хотя вы можете настроить фильтр окон по умолчанию, обычно рекомендуется вносить свои изменения в локальную копию через mywf=hs.window.filter.new(); фильтр окон по умолчанию потенциально может использоваться в нескольких модулях Hammerspoon, и его изменение может привести к непредвиденным последствиям. Общие настройки:
для исключения полноэкранных окон: nofs_wf=hs.window.filter.new():setOverrideFilter{fullscreen=false}
для включения невидимых окон: inv_wf=windowfilter.new():setDefaultFilter{}
Если вы все же хотите изменить фильтр окон по умолчанию:
вероятно, вы должны применить свои настройки в начале вашего init.lua, или, во всяком случае, до создания других фильтров окон; таким образом, копии, созданные через hs.window.filter.new(nil,...), унаследуют ваши изменения
чтобы просмотреть известные исключения: hs.inspect(hs.window.filter.default:getFilters()) из консоли
чтобы добавить исключение: hs.window.filter.default:rejectApp'Cool New Launcher'
чтобы добавить правило, специфичное для приложения: hs.window.filter.default:setAppFilter('My IDE',1); игнорировать всплывающие подсказки/автозаполнение (пустой заголовок) в моем IDE
чтобы удалить исключение (например, если вы хотите получить доступ к окнам Spotlight): hs.window.filter.default:allowApp'Spotlight'; для специализированных задач вы можете создать специфический фильтр окон с помощью myfilter=hs.window.filter.new'Spotlight'
Порядок сортировки для hs.window.filter:getWindows(): окна сортируются по времени создания, старейшее сначала (см. также hs.window.filter:setSortOrder())
Порядок сортировки для hs.window.filter:getWindows(): окна сортируются по времени создания, новейшее сначала (см. также hs.window.filter:setSortOrder())
Порядок сортировки для hs.window.filter:getWindows(): окна сортируются в порядке получения фокуса, от наименее до наиболее свежего (см. также hs.window.filter:setSortOrder())
Порядок сортировки для hs.window.filter:getWindows(): окна сортируются в порядке получения фокуса, от наиболее свежего до наименее свежего (см. также hs.window.filter:setSortOrder())
Notes
Это порядок сортировки по умолчанию для всех windowfilters
Псевдособытие для hs.window.filter:subscribe(): список разрешенных окон (согласно windowfilter:getWindows()) изменился
Notes
обработчики этого события получат (в качестве первого аргумента) либо случайное окно из числа разрешенных в данный момент, либо nil, если windowfilter отклоняет все окна
аналогично, второй аргумент, передаваемый обработчикам (имя приложения окна), будет nil, если windowfilter отклоняет все окна
это псевдособытие будет испускаться послефактического события(й), которые привели к изменению списка разрешенных окон
Указывает всем модулям windowfilters, необходимо ли обновлять все окна при переключении пользователя на другое пространство Mission Control.
Примечания
Если вы определили один или несколько модулей windowfilters, учитывающих пространства (т. е. когда поле currentSpace фильтра присутствует), окна все равно необходимо обновлять при каждом переключении пространства, поэтому эта переменная игнорируется.
Таблица имён приложений (в соответствии с hs.application:name()), которые всегда игнорируются этим модулем.
Примечания
Как следует из названия, даже пустой фильтр windowfilter (позволяющий все) будет игнорировать эти приложения.
Вам не нужно обновлять эту таблицу, так как приложения без графического интерфейса просто никогда не появятся; эта таблица используется как корневой фильтр для улучшения производительности (на очень небольшую величину).
Обработчик событий, чтобы оповестить все windowfilters о переключении пользователя на (номерированное) пространство Mission Control.
Параметры
space - номер пространства, на которое переключается пользователь
Возвращаемое значение
Примечания
Используйте эту функцию только если «Дисплеи имеют отдельные пространства» и «Автоматически переупорядочивать пространства» выключены в Системные настройки>Mission Control
Вызов этой функции установит hs.window.filter.forceRefreshOnSpaceChange в false
Если вы определили один или несколько модулей windowfilters, учитывающих пространства (т. е. когда поле currentSpace фильтра присутствует), окна все равно необходимо обновлять при каждом переключении пространства, поэтому использование этого обработчика событий не приведет к улучшению производительности
См. hs.window.filter.forceRefreshOnSpaceChange для обзора ограничений пространства в Hammerspoon. Если вы часто (или всегда) меняете пространство с помощью «номерированных» клавиатурных сочетаний Mission Control (по умолчанию ctrl-1 и т. д.), вы можете вызвать эту функцию из своего init.lua при перехвате этих сочетаний; например:
hs.hotkey.bind('ctrl','1',nil,function()hs.window.filter.switchedToSpace(1)end)
hs.hotkey.bind('ctrl','2',nil,function()hs.window.filter.switchedToSpace(2)end)
-- etc.
Использование этого обработчика событий приводит к немного лучшей производительности, чем установка forceRefreshOnSpaceChange в true, так как уже посещённые пространства запоминаются, и обновление не требуется при переключении обратно в эти пространства.
если nil, возвращает копию фильтра по умолчанию для окна, включая все внесённые вами настройки; вы можете дополнительно сузить или расширить его
если true, возвращает пустой фильтр для всех окон
если false, возвращает фильтр, отбрасывающий все окна по умолчанию
если строка или таблица строк, возвращает фильтр, пропускающий только видимые окна указанных приложений, согласно hs.application:name()
если таблица, позволяет полностью определить фильтр без вызова методов после создания; таблица должна быть структурирована согласно hs.window.filter:setFilters(); если в таблице не указано, то по умолчанию новый фильтр будет отбрасывать все окна
в противном случае, это должна быть функция, принимающая объект hs.window и возвращающая true если окно разрешено или false в противном случае; таким образом, вы можете определить полностью настраиваемый фильтр
logname - (необязательно) имя экземпляра hs.logger для нового фильтра окна; если опущено, используется логгер класса
loglevel - (необязательно) уровень логирования для экземпляра hs.logger для нового фильтра окна
hs.window.filter:getWindows([sortOrder]) -> list of hs.window objects
Тип
Метод
Описание
Возвращает текущие окна, разрешённые этим фильтром окон
Параметры
sortOrder - (необязательно) одна из констант hs.window.filter.sortBy..., определяющая порядок сортировки возвращаемого списка; если опущено, используется порядок сортировки фильтра окон по hs.window.filter:setSortOrder() (по умолчанию sortByFocusedLast)
Останавливает подписки на события windowfilter; больше не будут вызываться обратные вызовы событий, но подписки остаются нетронутыми для последующего вызова hs.window.filter:resume()
Устанавливает подробные правила фильтрации окон для определенного приложения
Параметры
appname — имя приложения, согласно hs.application:name()
filter — если false, отклонить приложение; если true, nil, или опущено, разрешить все видимые окна (в любом пространстве) для приложения; в противном случае это должен быть массив, описывающий правила фильтрации для приложения, через следующие поля:
visible — если true, разрешить только видимые окна (в любом пространстве); если false, отклонить видимые окна; если опущено, это правило игнорируется
currentSpace — если true, разрешить только окна в текущем пространстве Mission Control (включаются минимизированные и скрытые окна, поскольку они считаются принадлежащими всем пространствам); если false, отклонить окна в текущем пространстве (включая все минимизированные и скрытые окна); если опущено, это правило игнорируется
fullscreen — если true, разрешить только полноэкранные окна; если false, отклонить полноэкранные окна; если опущено, это правило игнорируется
hasTitlebar — если true, разрешить только окна с панелью заголовков; если false, отклонить окна с панелью заголовков; если опущено, это правило игнорируется
focused — если true, разрешить только окно во время фокусировки; если false, отклонить фокусированное окно; если опущено, это правило игнорируется
activeApplication — разрешить любое окно этого приложения, пока оно (если true) или оно не (если false) активное приложение; если опущено, это правило игнорируется
allowTitles * если число, разрешить только окна, заголовок которых имеет не менее указанного количества символов; например, передать 1 для фильтрации окон с пустым заголовком * если строка или массив строк, разрешить только окна, заголовок которых соответствует (одному из) шаблона(ов), согласно string.match * если опущено, это правило игнорируется
rejectTitles — если строка или массив строк, отклонить окна, заголовки которых соответствуют (одному из) шаблона(ов), согласно string.match; если опущено, это правило игнорируется
allowRegions — hs.geometry прямоугольник или аргумент конструктора, или список их, обозначающий(ие) экранную(ые) «область(и)» в абсолютных координатах: разрешить только окна, которые «покрывают» по крайней мере 50% (одной из) области(ей), и/или окна, у которых по крайней мере 50% поверхности находятся внутри (одной из) области(ей); если опущено, это правило игнорируется
rejectRegions — hs.geometry прямоугольник или аргумент конструктора, или список их, обозначающий(ие) экранную(ые) «область(и)» в абсолютных координатах: отклонить окна, которые «покрывают» по крайней мере 50% (одной из) области(ей), и/или окна, у которых по крайней мере 50% поверхности находятся внутри (одной из) области(ей); если опущено, это правило игнорируется
allowScreens — допустимый аргумент для hs.screen.find(), или список их, указывающий одну (или несколько) экран(ов): разрешить только окна, которые (в основном) лежат на (одном из) экран(ов); если опущено, это правило игнорируется
rejectScreens — допустимый аргумент для hs.screen.find(), или список их, указывающий одну (или несколько) экран(ов): отклонить окна, которые (в основном) лежат на (одном из) экран(ов); если опущено, это правило игнорируется
allowRoles * если строка или массив строк, разрешить только эти роли окна, согласно hs.window:subrole() * если специальная строка '*', это правило игнорируется (т.е. разрешаются все роли окна, включая пустые) * если опущено, используются стандартные разрешенные роли (определенные в hs.window.filter.allowedWindowRoles)
Возвращаемое значение
объект hs.window.filter для цепочки методов
Примечания
Передача focused=true в filter приведет (естественно) к тому, что windowfilter будет разрешать не более 1 окна
Если вы хотите разрешить все окна приложения, включая невидимые, передайте пустой массив для filter
У windowfilter, учитывающего пространства, может наблюдаться (иногда значительная) задержка после каждого переключения пространств, поскольку (из-за ограничений OS X) ему необходимо повторно запросить список всех окон в текущем пространстве каждый раз.
Если в Системных настройках > Пространства > Отображения включена опция разделения пространств, текущее пространство определяется как объединение всех пространств, которые в данный момент видны
Эта таблица объясняет последствия разных комбинаций visible и currentSpace, показывая, какие окна будут разрешены:
|visible= nil | true | false |
|currentSpace|------------------------------------------|------------------------------|--------------|
| nil |all |visible in ANY space |min and hidden|
| true |visible in CURRENT space+min and hidden |visible in CURRENT space |min and hidden|
| false |visible in OTHER space only+min and hidden|visible in OTHER space only |none |
Устанавливает, следует ли windowfilter разрешать (или отклонять) окна только в текущем пространстве Mission Control
Параметры
val — булево значение; если true, разрешить только окна в текущем пространстве Mission Control, плюс минимизированные и скрытые окна; если false, отклонить их; если nil, игнорировать пространства Mission Control
Возвращаемое значение
объект hs.window.filter для цепочки методов
Примечания
Это просто обертка для установки поля currentSpace в фильтре override (другие поля останутся без изменений); фильтры по приложениям сохранят своё поле currentSpace, если оно присутствует, как есть
У windowfilter, учитывающего пространства, может наблюдаться (иногда значительная) задержка после каждого переключения пространств, поскольку (из-за ограничений OS X) ему необходимо повторно запросить список всех окон в текущем пространстве каждый раз.
filters — массив, каждый элемент установит фильтр приложения; эти элементы должны: - иметь ключ типа строка, обозначающий имя приложения, согласно hs.application:name() - если значение является булевым значением, приложение будет разрешено или отклонено соответственно - см. hs.window.filter:allowApp() и hs.window.filter:rejectApp() - если значение является массивом, оно должно содержать правила принятия/отклонения для приложения в виде пар «ключ/значение»; допустимые ключи и значения описаны в hs.window.filter:setAppFilter() - ключ может быть одной из специальных строк "default" и "override", которые установят фильтр по умолчанию и переопределение соответственно - ключ может быть специальной строкой "sortOrder"; значение должно быть одним из констант sortBy... согласно hs.window.filter:setSortOrder()
Возвращаемое значение
объект hs.window.filter для цепочки методов
Примечания
каждое определение фильтра в filters перезапишет существующее для соответствующего приложения, если оно присутствует; это также относится к специальным фильтрам по умолчанию и переопределению, если они включены
Устанавливает разрешённые области экрана для этого фильтра окон
Parameters
regions - прямоугольник hs.geometry или аргумент конструктора, или список таких, указывающий разрешённую область(и) для этого фильтра окон
Returns
объект hs.window.filter для цепочки методов
Notes
Это просто обёртка для установки поля allowRegions в фильтре override (другие поля останутся без изменений); фильтры для отдельных приложений сохранят свои поля allowRegions и rejectRegions, если они присутствуют
Устанавливает разрешённые экраны для этого фильтра окон
Parameters
regions - допустимый аргумент для hs.screen.find(), или список таких, указывающий разрешённый(ые) экран(ы) для этого фильтра окон
Returns
объект hs.window.filter для цепочки методов
Notes
Это просто обёртка для установки поля allowScreens в фильтре override (другие поля останутся без изменений); фильтры для отдельных приложений сохранят свои поля allowScreens и rejectScreens, если они присутствуют
Подписаться на один или несколько событий на разрешённых окнах
Parameters
event - строка или список строк, события для подписки (см. константы hs.window.filter); альтернативно, это может быть карта {event1=fn1,event2=fn2,...}, где fnN будет подписан на eventN, а параметр fn будет проигнорирован
fn - функция или список функций, колбэки для добавления для события(ей); каждый получит 3 параметра
объект hs.window, ссылающийся на окно события
строку с именем приложения (window:application():name()) для удобства
строку с событием, которое вызвало колбэк, т.е. одно из событий, на которые вы подписались
immediate - (необязательно) если true, также вызвать все колбэки немедленно для окон, соответствующих критериям события(ей)
Returns
объект hs.window.filter для цепочки методов
Notes
Передача списков означает, что все колбэки будут вызваны, когда любое из событий fn сработает, поэтому это не сокращение для подписки на разные колбэки на разные события; для этого используйте карту или цепочку вызовов :subscribe.
Будьте осторожны с immediate; например, если вы подписываетесь на hs.window.filter.windowUnfocused, колбэки fn будут вызваны для всех окон, кроме текущего активного.
Если фильтр окон был приостановлен с помощью hs.window.filter:pause(), вызов этого возобновит его.
event - строка или список строк, события для отписки; если опущено, колбэки fn будут отписаны от всех событий; альтернативно, это может быть карта {event1=fn1,event2=fn2,...}, где fnN будет отписан от eventN, а параметр fn будет проигнорирован
fn - функция или список функций, колбэки для удаления; если опущено, все колбэки будут отписаны от event(ей)
Returns
объект hs.window.filter для цепочки методов
Notes
Вы должны передать по крайней мере один из event или fn
Если вы вызываете это для стандартного (или любого другого общего) фильтра окон, не передавайте события, поскольку это удалит все колбэки для событий, включая те, на которые подписались где-то ещё, о которых вы можете не знать. Вместо этого сохраняйте ссылки на ваши функции и передавайте их.
hs.window.filter:windowsToEast(window, frontmost, strict) -> list of hs.window objects
Type
Method
Description
Получает все видимые окна, разрешённые этим фильтром окон, которые лежат к востоку от данного окна
Parameters
window - (необязательно) объект hs.window; если nil, используется hs.window.frontmostWindow()
frontmost - (необязательно) булево значение; если true, неперекрытые окна будут помещены перед перекрытыми в списке результатов
strict - (необязательно) булево значение; если true, учитываются только окна под углом от 45° до -45° по оси к востоку
Returns
Список объектов hs.window, представляющих все окна, расположенные к востоку (т.е. справа) от окна в порядке возрастания расстояния
Notes
Это обёртка, которая возвращает hs.window.windowsToEast(window,self:getWindows(),...)
Вероятно, вам потребуется добавить :setCurrentSpace(true) к фильтру окон, используемому для этого вызова метода (или просто использовать hs.window.filter.defaultCurrentSpace)
hs.window.filter:windowsToNorth(window, frontmost, strict) -> list of hs.window objects
Type
Method
Description
Получает все видимые окна, разрешённые этим фильтром окон, которые лежат к северу от данного окна
Parameters
window - (необязательно) объект hs.window; если nil, используется hs.window.frontmostWindow()
frontmost - (необязательно) булево значение; если true, неперекрытые окна будут помещены перед перекрытыми в списке результатов
strict - (необязательно) булево значение; если true, учитываются только окна под углом от 45° до -45° по оси к северу
Returns
Список объектов hs.window, представляющих все окна, расположенные к северу (т.е. вверх) от окна в порядке возрастания расстояния
Notes
Это обёртка, которая возвращает hs.window.windowsToNorth(window,self:getWindows(),...)
Вероятно, вам потребуется добавить :setCurrentSpace(true) к фильтру окон, используемому для этого вызова метода (или просто использовать hs.window.filter.defaultCurrentSpace)
hs.window.filter:windowsToSouth(window, frontmost, strict) -> list of hs.window objects
Тип
Метод
Описание
Получает все видимые окна, разрешенные этим фильтром окон, которые лежат к югу от заданного окна
Параметры
окно - (необязательно) объект hs.window; если nil, будет использовано hs.window.frontmostWindow()
frontmost - (необязательно) булево значение; если true, неперекрытые окна будут помещены перед перекрытыми в списке результатов
strict - (необязательно) булево значение; если true, будут учитываться только окна под углом между 45° и -45° по оси на юг
Возвращает
Список объектов hs.window, представляющих все окна, расположенные к югу (т. е. вниз) от окна, в порядке возрастания расстояния
Примечания
Это удобная обертка, которая возвращает hs.window.windowsToSouth(window,self:getWindows(),...)
Вероятно, вам нужно добавить :setCurrentSpace(true) к фильтру окон, используемому для этого вызова метода (или просто использовать hs.window.filter.defaultCurrentSpace)
hs.window.filter:windowsToWest(window, frontmost, strict) -> list of hs.window objects
Тип
Метод
Описание
Получает все видимые окна, разрешенные этим фильтром окон, которые лежат к западу от заданного окна
Параметры
окно - (необязательно) объект hs.window; если nil, будет использовано hs.window.frontmostWindow()
frontmost - (необязательно) булево значение; если true, неперекрытые окна будут помещены перед перекрытыми в списке результатов
strict - (необязательно) булево значение; если true, будут учитываться только окна под углом между 45° и -45° по оси на запад
Возвращает
Список объектов hs.window, представляющих все окна, расположенные к западу (т. е. слева) от окна, в порядке возрастания расстояния
Примечания
Это удобная обертка, которая возвращает hs.window.windowsToWest(window,self:getWindows(),...)
Вероятно, вам нужно добавить :setCurrentSpace(true) к фильтру окон, используемому для этого вызова метода (или просто использовать hs.window.filter.defaultCurrentSpace)