/ / Como posso recarregar as preferências com.apple.systemuiserver no aplicativo SystemUIServer? - objetivo-c, cacau, macos, nstask

Como posso recarregar as preferências com.apple.systemuiserver no aplicativo SystemUIServer? - objetivo-c, cacau, macos, nstask

Para meu aplicativo Mac OSX, eu tenho um recurso queremove o relógio do sistema no canto superior direito da tela quando um botão é clicado. As preferências que controlam quais menus do sistema são exibidos (incluindo o relógio do sistema) são armazenadas em ~ / Library / Preferences / com.apple.systemuiserver.plist. Consegui atualizar as preferências relevantes nesse arquivo para remover o relógio do sistema. No entanto, o aplicativo SystemUIServer precisa ser reiniciado para que as novas preferências possam ser recarregadas e o relógio possa ser removido. Aqui está o código que usei para reiniciar o SystemUIServer.

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

Quando SystemUIServer é eliminado, o OSX automaticamentereinicia isso. O código acima funciona, mas a remoção do relógio do sistema não é tão limpa quanto eu gostaria. Toda a barra do sistema é removida por um segundo. Alguém pode pensar em uma maneira melhor de recarregar as preferências no SystemUIServer? Idealmente, eu gostaria que a remoção do relógio do sistema ficasse tão limpa quanto a função de exibição do relógio nas Preferências de data e hora do aplicativo System Preferences.

Respostas:

2 para resposta № 1

Já pensou em tentar dirigir o painel pref?se usando AppleEvents / OSAScript? Embora o painel de prefs de rede pareça ser o único com capacidade de script totalmente incorporada, você pode direcionar qualquer interface do usuário com os eventos do sistema. Foi fácil fazer protótipos no AppleScript. Aqui está o que eu criei:

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

Você pode usá-lo como está usando umObjeto NSAppleScript, ou se você está se sentindo masoquista, você pode mergulhar na minúcia de descobrir apenas os AppleEvents certos para enviar (eu recomendo a primeira abordagem para sanidade, mas a última será executada mais rapidamente em tempo de execução).

Prós: fácil.

Contras: Inicia as Preferências do Sistema (que podem ser vistas como saltando no Dock), Requer "Ativar o Acesso para Dispositivos Auxiliares" para ser ativado (como muitas outras coisas)

Difícil dizer se isso é visualmente melhor ou pior que matar SystemUIServer, mas é quase Certamente gentil com qualquer outro componente que possa estar interagindo com o SystemUIServer.

Quanto a se livrar do salto da doca, este pergunta aqui menciona como fazer com que as coisas sejam iniciadas sem um ícone de encaixe. Para isso, posso acrescentar que, no passado, eu me envolvi com esse problema, e a solução que obtive foi, em alto nível, a seguinte:

  • Obter um diretório temporário exclusivo / seguro
  • Tornar um link apenas para hard-links de todo o pacote do aplicativo em questão (pax -rwl vai ajudar com isso)
  • Substitua o Info.plist de hard-link por uma cópia real do Info.plist
  • Edite a cópia de acordo com as instruções da outra pergunta. (Nota: Existem outras opções além da configuração NSUIElement = true aqui, mas deixo isso como um exercício para o leitor e para o google.)
  • Use o aplicativo do diretório temporário
  • Exclua o diretório temporário.

Esta abordagem provou ser bastante robusta para mim quandotentando direcionar aplicativos de terceiros. Eu estou supondo que você pode, no futuro, ter problemas com aplicações do sistema que são assinadas / sandboxed. (Ou seja, alterando seu Info.plist muda a assinatura, eles podem se recusar a executar.) Além disso, naturalmente, qualquer aplicativo sandbox Exigir um direito específico ou exceção para enviar AppleEvents em tudo, mas eu acho que isso também é verdade de matar processos do sistema (se é mesmo possível fazer a partir de um aplicativo em sandbox em tudo).

Por fim, você deveria arquivar um relatório de bug com a Apple solicitando uma API ou scriptability de primeira classe para isso, se você achar importante.