Привет, Хабр! Хочу поделиться очень интересным инструментом для «приручения» положения окон в OS X. Если кратко, то вот ссылка на репозиторий с замечательным приложением Slate. За подробностями, добро пожаловать под кат.

image

Я столкнулся с проблемой расположения (и, что самое главное, сохранения этой позиции!) окон на нескольких мониторах в OS X. Особенно эта проблема актуальна в случае, если основная рабочая машина – это ноутбук, а работать приходится много, и, соответственно, подключать разные мониторы и в разном количестве. У меня, например, стоит довольно большой монитор в офисе, по-меньше дома, а в дороге – возможности подключить второй монитор нет вообще. В итоге, каждый мой рабочий сеанс начинается с включения IDE и расположения всех окон-инструментов (терминал, история версий, структура проекта, инспектор класса и т.д.) IDE по мониторам. Этот процесс сильно ускоряется такими приложениями как ShiftIt, но все равно приходится тратить время на точное расположение каждого окна. Хочется просто нажать заветную комбинацию клавиш и наблюдать как окна сами располагаются по заранее заданным позициям.

И вот сегодня я нашёл решение, которое покрывает все мои потребности с головой и хочу поделиться им с вами.

Собственно, приложение называется Slate. Вот ссылка на гитхаб. Это приложение позволяет создавать свои собственные конфигурации расположения окон на мониторах в виде JS файла с конфигурацией. Slate предоставляет очень мощный и в то же время простой для понимания API для манипуляции с окнами, позволяет байндить события на сочетания клавиш, имеет отличную документацию и (что самое главное) работает!

Для создания своей собственной конфигурации необходимо создать файл ~/.slate.js и описать там расположение окон.

Вот так, например, получилось у меня:

// При нажатии на ctrl+alt+cmd+shift+1 будем расставлять окна на место
slate.bind("1:ctrl,alt,cmd,shift", function() {
        // Пока что не будем обрабатывать ситуацию, когда количество мониторов не равно 2-м.
	if (slate.screenCount() !== 2) {
		return;
	}
        // Выберем более большой по размеру монитор как главный, а второй как дополнительный
	var screen0 = slate.screenForRef('0');
	var screen1 = slate.screenForRef('1');
	var mainScreen = null,
		additionalScreen = null;
	if (screen0.rect().width * screen0.rect().height > screen1.rect().width * screen1.rect().height) {
		mainScreen = screen0;
		additionalScreen = screen1;
	} else {
		mainScreen = screen1;
		additionalScreen = screen0;
	}
        
        // Пробежимся по всем открытым приложениям
	slate.eachApp(function(app) {
                // Но работать будем только с окнами IntelliJ IDEA
		var appName = app.name();
		if (appName !== 'IntelliJ IDEA') {
			return;
		}
		app.eachWindow(function(win) {
                        //В зависимости от названия окна - инструмента IntelliJ IDEA зададим ему позицию, размеры и монитор
			var w, h, xOffset, yOffset, screen;
			switch (win.title()) {
				case 'Terminal':
					w = 5;
					h = 5;
					xOffset = 7;
					yOffset = 7;
					screen = mainScreen;
					break;
				case 'Version Control':
					w = 5;
					h = 5;
					xOffset = 7;
					yOffset = 2;
					screen = mainScreen;
					break;
				case 'Database':
					w = 3;
					h = 2;
					xOffset = 9;
					yOffset = 0;
					screen = mainScreen;
					break;
				case 'Workspaces':
					w = 2;
					h = 2;
					xOffset = 7;
					yOffset = 0;
					screen = mainScreen;
					break;
				case 'Project':
					w = 6;
					h = 12;
					xOffset = 0;
					yOffset = 0;
					screen = additionalScreen;
					break;
				case 'Structure':
					w = 6;
					h = 12;
					xOffset = 6;
					yOffset = 0;
					screen = additionalScreen;
					break;
				default:
					w = 7;
					h = 12;
					xOffset = 0;
					yOffset = 0;
					screen = mainScreen;
			}
                        // Применим изменения к окну
			win.doOperation(slate.operation('move', {
				'x': 'screenOriginX+screenSizeX/12*' + xOffset,
				'y': 'screenOriginY+screenSizeY/12*' + yOffset,
				'width': 'screenSizeX/12*' + w,
				'height': 'screenSizeY/12*' + h,
				'screen': screen
			}));
		});
	});
});

И вот такой результат:

image

image

Спасибо за внимание!
Поделиться с друзьями
-->

Комментарии (38)


  1. Filippok
    25.10.2016 17:14
    +2

    Немного не в тему, но может кто в курсе, есть ли под osx что-то на подобии i3/xmonad?


    1. kuznetsovin
      25.10.2016 17:26
      +1

      Лучшее, что мне встречалось это Amethyst


    1. Snay
      25.10.2016 17:27

      посмотрите на https://github.com/ianyh/Amethyst. приятная и ненавязчивая вещь, я до этого с тайлингом не дружил совсем. возможно, не такая гибкая как i3/xmonad. насколько я помню, даже горячие клавиши назначены близко с i3


    1. OutPunk
      25.10.2016 21:28
      +1

      1. Valery4
        25.10.2016 23:42

        У него ещё форк есть.
        Hammerspoon


        1. theli
          26.10.2016 03:08

          Hammerspoon это форк Mjolnir а не kwm


  1. DrPass
    25.10.2016 17:18
    +2

    > Это приложение позволяет создавать свои собственные конфигурации расположения окон на мониторах
    > в виде JS файла с конфигурацией.
    Судя по вашему файлу конфигурации, это не приложение, а библиотека. Для того, чтобы располагать окна на мониторах, приложение предлагается написать пользователю :)


    1. kaduev13
      26.10.2016 00:11

      Мне кажется, что это и то и другое. В плане написания конфигураций – это библиотека, в плане их запуска – это приложение =) Ну и у Slate ещё пара функций есть дополнительно.
      image


  1. Scalar
    25.10.2016 17:29

    Спасибо за статью!
    Лично мне slate показался довольно сложным, поэтому я пользуюсь BetterTouchTool: оно не про окна и их конфигурацию, а про горячие клавиши и жесты.
    Там легко настроить горячие клавиши на расположение окна по углам или по половинам экрана, на разных мониторах, перетаскивание между рабочими столами и т.д.


  1. Mastak_A
    25.10.2016 17:42
    +1

    Moom умеет запоминать положение окон, в том числе на разных мониторах и рабочих пространствах.


    1. kaduev13
      26.10.2016 00:21

      Спасибо за наводку. Когда гуглил layout manager osx, то встречал ссылку на эту программу. Правда, не стал её запускать, так как были сомнения по поводу функционала и гибкости. Сейчас смотрю подробнее – вполне удобная штука. Спасибо! =)


  1. maxtm
    25.10.2016 17:42
    +2

    Советую попробовать Spectale, просто замечательнейшая софтина.

    Пара хоткеев, и вы просто гуру расположения окно на нескольких мониторов.


    1. Mastak_A
      25.10.2016 17:47

      Spectacle не умеет сохранять расположение окон, а именно эта функциональность необходима автору статьи.


      1. maxtm
        25.10.2016 17:49
        -2

        У меня при подключении монитора все окна встают на этот экран, которые были открыты там на момент отсоединения монитора. Отлично работает с двумя мониторами.
        Что я делаю не так?


        1. Mastak_A
          25.10.2016 17:54

          Если с помощью Spectacle можно реализовать расположение окон (и запоминание позиции) как на 1-м скриншоте результатов автора, то забираю свои слова обратно.


          1. maxtm
            25.10.2016 17:58

            Эта нативная функциональность ОСи, для этого Spectacle не нужен.

            Довольно странно, почему для дефолтной функциональности потребовались танцы с бубном :)

            Сейчас проверил, вытащил диалог VC на один из мониторов, отсоединил его, окно улетело на центральный монитор.
            Подсоединил обратно — окно вернулось на прежний монитор, сохранив размер/положение.


            1. Mastak_A
              25.10.2016 18:12
              +2

              Мы немного о разных вещах говорим.

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

              Поэтому выше я и упомянул Moom, которая это умеет (и практически все, что реализовано в Spectacle тоже).


            1. kaduev13
              26.10.2016 00:31
              +1

              Возможно, я проблему не совсем понятно описал.

              Задача такая: придумать способ быстро (за 1 хоткей) восстанавливать заранее заготовленный layout для целой кучи окошек. При этом нужно, чтобы эти layout-ы были разными, в зависимости от количества и размера мониторов.

              У меня довольно часто ломается layout при подключении второго монитора. Плюс, я могу нечаянно (сам, руками, курсором) сдвинуть одно из окон, и хотел бы иметь возможность быстро его вернуть обратно.


  1. 12sd
    25.10.2016 17:42

    Поздравляю, вы придумали i3wm :)


    1. poxu
      25.10.2016 18:17
      +2

      Который конечно есть под OSX ?


  1. AreD
    25.10.2016 17:50
    +1

    Более простое приложение для тайлинга окон Spectacle особенно удобно использовать когда монтиров больше одного
    image
    PS, пока писал коммент, меня опередил maxtm выше


    1. maggg
      25.10.2016 21:12

      Я пробовал Spectacle, он приятный и простой, но в нём не хватает возможности возврата к исходному размеру окна, развёрнутого, например, по ??<, в любой момент времени. То есть не просто undo последнего действия. Или я не нашёл?


      1. AreD
        26.10.2016 08:30

        Нет, такой фичи в нем нет


  1. CB9TOIIIA
    25.10.2016 18:52

    Я могу порекомендовать Divvy: для винды и мака: http://mizage.com/

    image


    1. ad1Dima
      25.10.2016 19:05

      Стандартный тайлинг на винде выглядит хоть и менее функционально, но более удобно: меньше действий требуется.


      1. poxu
        25.10.2016 19:21

        Стандартный тайлинг это возможность поместить окно вбок? Или там ещё по умолчанию есть функции?


        1. ad1Dima
          25.10.2016 19:33

          Последовательные нажатия win+cтрелка переснапить окно на следующий монитор.
          В 10ке можно по 4м углам рассовать и мышкой и последовательным нажатием win+cтрелка_вбок и win+cтрелка_вверх(вниз)
          А ещё приснапленые окна ресайзятся одновременно за общую грань, но работает это только с 2мя окнами.


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


  1. xGromMx
    25.10.2016 18:55

    Юзаю Flexiglass вроде норм =)


    1. ad1Dima
      25.10.2016 19:51

      Судя по всему, его год не обновляли и в комментах пишут про баги. Оно на Сиерре нормально работает?


      1. xGromMx
        25.10.2016 23:34

        я пока не решился обновлятся до сиерры


  1. 0x18h
    25.10.2016 22:36

    Так Slate вроде закончился и больше не поддерживается и не разрабатывается. Его сначала заменил mjolnir, а когда и тот закончился то пришел hammerspoon


    1. kaduev13
      26.10.2016 00:37

      Спасибо за ссылку. Про hammerspoon не слышал до этого, попробую на досуге =)


  1. HabraBabra
    26.10.2016 00:12

    Отличная библиотека, как раз то, что искал!


  1. sel_star
    26.10.2016 00:38

    Ах. Раз тут перепись виндоцс менеджеров, то вот еще чуть-чуть:
    phoenix https://github.com/kasper/phoenix
    kwm https://github.com/koekeishiya/kwm


  1. penguin32
    26.10.2016 03:21
    -1

    Функционал прельщает. Хотелось бы получить нечто похожее для Ubuntu (Compiz).
    Что-то менее общее, чем CompizConfig; нацеленное именно на pin программ к мониторам и workspace'ам.


  1. kamenevn
    26.10.2016 08:31

    А есть нечто подобное как в винде(мышкой)? Что-то вроде липких краев


    1. isden
      26.10.2016 09:54

      BetterSnapTool так умеет. Вроде бы и Divvy тоже, но тут не уверен, его только издалека видел.


  1. chemistmail
    26.10.2016 10:35

    И конфигурация наподобие, но без js.

    config defaultToCurrentScreen true
    config nudgePercentOf screenSize
    config resizePercentOf screenSize
    layout develop 'Safari' push left bar-resize:screenSizeX/2 | push right bar-resize:screenSizeX/2
    layout develop 'iTerm2' push right bar-resize:screenSizeX/2 | push left bar-resize:screenSizeX/2
    layout macDevelop 'Safari' push left bar-resize:screenSizeX/2 | push right bar-resize:screenSizeX/2
    layout macDevelop 'Xcode' push right bar-resize:screenSizeX/2 | push left bar-resize:screenSizeX/2
    
    bind 1:cmd focus 'iTerm2'
    bind 2:cmd focus 'Safari'
    bind 3:cmd focus 'Dash'
    bind 4:cmd focus 'Finder'
    bind 0:cmd focus 'Firefox'
    bind 1:ctrl layout develop
    bind 2:ctrl layout macDevelop
    bind 5:cmd focus 'Xcode'
    


    До mac использовал linux c xmonad, slate конечно не xmonad, но очень близко, и бесплатно.