Как я могу перезагрузить настройки com.apple.systemuiserver в приложение SystemUIServer? - PullRequest
4 голосов
/ 28 февраля 2011

Для моего приложения Mac OSX у меня есть функция, которая удаляет системные часы в верхнем правом углу экрана при нажатии кнопки.Настройки, управляющие отображением системных меню (включая системные часы), хранятся в ~ / Library / Preferences / com.apple.systemuiserver.plist.Мне удалось обновить соответствующие настройки в этом файле, чтобы удалить системные часы.Однако приложение SystemUIServer необходимо перезапустить, чтобы можно было перезагрузить новые настройки и удалить часы.Вот код, который я использовал для перезапуска SystemUIServer.

NSTask *killSystemUITask = [[NSTask alloc] init];
NSMutableArray *args = [NSMutableArray array];
[args addObject:@"SystemUIServer"];
[killSystemUITask setLaunchPath:@"/usr/bin/killall"];
[killSystemUITask setArguments:args];
[killSystemUITask launch];

Когда SystemUIServer убит, OSX автоматически перезапускает его.Приведенный выше код работает, но удаление системных часов не так чисто, как хотелось бы.Вся системная панель удаляется на секунду.Может кто-нибудь придумать лучший способ перезагрузить настройки в SystemUIServer?В идеале я хотел бы, чтобы удаление системных часов было таким же чистым, как и функция отображения часов в настройках даты и времени приложения «Системные настройки».

1 Ответ

2 голосов
/ 28 декабря 2011

Рассматривали ли вы попытку управления самой панелью с помощью AppleEvents / OSAScript?В то время как панель Network prefs кажется единственной с полностью встроенной возможностью написания сценариев, вы можете управлять любым пользовательским интерфейсом с помощью системных событий.Было достаточно легко создать прототип в AppleScript.Вот что я придумал:

tell application "System Preferences"
    reveal pane "Date & Time"
    reveal anchor "ClockPref" of pane "Date & Time"
    tell application "System Events"            
        tell tab group 1 of window 1 of process "System Preferences"
            repeat with cbIndex from 0 to count of checkboxes
                tell checkbox cbIndex
                    if title contains "menu bar" then
                        click
                        exit repeat
                    end if
                end tell
            end repeat
        end tell
    end tell
    quit
end tell

Вы можете использовать его как есть, используя объект NSAppleScript, или, если вы чувствуете себя мазохистом, вы можете погрузиться в мелочи, чтобы выяснить, как правильноAppleEvents для отправки.(Я рекомендую первый подход для здравомыслия, но последний будет выполняться быстрее во время выполнения.)

Плюсы: Легко.

Минусы: Запускает Системные настройки (которые можно увидеть как отскакивающие вDock), требует «Включить доступ для вспомогательных устройств» (как и многие другие)

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

Что касается избавления от скачка дока, этот вопрос здесь упоминает, как заставить вещизапускать без значка док-станции.К этому я могу добавить, что в прошлом я сталкивался с этой проблемой, и решение, которое я нашел, было на высоком уровне:

  • Получить уникальный / безопасный временный каталог
  • Сделать только жесткие ссылки зеркалом всего пакета рассматриваемого приложения (pax -rwl поможет в этом)
  • Заменить жестко связанный Info.plist реальной копиейInfo.plist
  • Отредактируйте копию согласно указаниям в другом вопросе.(Примечание: здесь есть и другие варианты, кроме установки NSUIElement = true, но я оставляю их в качестве упражнения для читателя и Google.)
  • Используйте приложение из временного каталога
  • Удалите темпdirectory.

Этот подход оказался достаточно надежным для меня при попытке запуска сторонних приложений.Я предполагаю, что в будущем вы можете столкнуться с проблемами с системными приложениями, которые подписаны / помещены в песочницу.(т.е. изменение их Info.plist изменяет подпись, они могут отказаться от запуска.) Кроме того, естественно, что любое изолированное приложение будет требовать определенного разрешения или исключения для отправки AppleEvents вообще, но я бы предположил, что это также верно для уничтожения системных процессов.(если это вообще возможно сделать из изолированного приложения.)

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

...