objective-c cocoa macos plugins finder

objective c - Cómo escribir el complemento de OS X Finder



objective-c cocoa (8)

Aquí hay una solución completa para las insignias de iconos de Finder y los menús contextuales de León y León de montaña usando las técnicas descritas por Les Nie.

Liferay Nativity proporciona un paquete de secuencias de comandos que mezclará los métodos relevantes de Finder y un cliente Java para configurar los íconos y los menús contextuales. También incluye proyectos equivalentes para Windows y Linux.

El proyecto es de código abierto bajo LGPL, ¡así que no dude en contribuir con cualquier corrección de errores o mejoras!

Estoy buscando una guía o código de muestra para escribir complementos de Mac OS X Finder. Le gustaría saber cómo hacer algunas acciones simples:

  1. agregar capas de imagen a iconos
  2. agregar elementos del menú contextual
  3. escucha los cambios de archivos

Encontré los siguientes dos recursos:

Estoy tentado de revisar el código de SCPlugin , pero esperaba encontrar una muestra más fácil de digerir.


El proyecto de ejemplo Finder Icon Overlay representa un ejemplo pequeño y muy básico pero realmente funcional de la respuesta a continuación.

https://github.com/lesnie/Finder-Icon-Overlay

Sé que esto es muy viejo, pero algunos todavía pueden estar interesados ​​en el tema (?)

Esto es lo que he hecho bajo Leopard (10.6). Al principio se necesitan los encabezados adecuados de Finder. Use la herramienta de volcado de clase para obtenerlo. Luego, escriba su código como un complemento SIMBL (consulte la documentación sobre cómo hacerlo), modificando algunos métodos. Por ejemplo, para dibujar algo sobre un ícono en ListView, drawIconWithFrame: el método de TIconAndTextCell debe ser reemplazado.

Aquí está el código para el método Swizzling:

+ (void) Plugin_load { Method old, new; Class self_class = [self class]; Class finder_class = [objc_getClass("TIconAndTextCell") class]; class_addMethod(finder_class, @selector(FT_drawIconWithFrame:), class_getMethodImplementation(self_class, @selector(FT_drawIconWithFrame:)),"v@:{CGRect={CGPoint=dd}{CGSize=dd}}"); old = class_getInstanceMethod(finder_class, @selector(drawIconWithFrame:)); new = class_getInstanceMethod(finder_class, @selector(FT_drawIconWithFrame:)); method_exchangeImplementations(old, new); }

Estoy anulando el método "drawIconWFrame:" con mi método "FT_drawIconWithFrame:". A continuación se muestra la implementación de este método.

- (void) FT_drawIconWithFrame:(struct CGRect)arg1 { [self FT_drawIconWithFrame:arg1]; if ([self respondsToSelector:@selector(node)]) { if ([[[[NSClassFromString(@"FINode") nodeWithFENode:[(TNodeIconAndNameCell *)self node]] fullPath] lastPathComponent] hasPrefix:@"A"]) [myPrettyIconOverlayImage drawInRect:NSMakeRect(arg1.origin.x, arg1.origin.y, arg1.size.height, arg1.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; } }

Esencialmente dibuja "myPrettyIconOverlayImage" sobre cada ícono para que el archivo con nombre de archivo comience con la letra "A". Esta lógica depende de ti.

Preste atención a esta línea: [self FT_drawIconWithFrame:arg1]; así es como se llama ''super'' para obtener un icono y un nombre normales, etc. Lo sé, se ve raro, como bucle, pero en realidad no lo es. Luego envuelve el plugin SIMBL, instala SIMBL y ... ejecuta.

Debido a los cambios en Lion, se debe realizar algún trabajo desde el principio (crear un nuevo archivo "Finder.h" con todas las declaraciones necesarias, encontrar la clase y los métodos adecuados para anular), pero esta técnica aún funciona.

¡Feliz hacking!


Lamentablemente, la programación de un complemento de Finder en realidad todavía requiere ensuciarse las manos con COM. Si observa el subproyecto SCFinderPlugin del proyecto SCPlugin, encontrará que sigue exactamente las mismas técnicas descritas en su primer enlace, incluida la configuración de un vtable para COM, la escritura de funciones AddRef / ReleaseRef, y así sucesivamente. Escribir un complemento, en el que simultáneamente está administrando la gestión de memoria Carbon de la vieja escuela, la gestión de memoria estilo COM y la gestión de memoria Carbon de Cocoa / estilo nuevo, puede ser un dolor increíble, y eso ignora por completo el hecho de que estará interactuando en tres o más API radicalmente diferentes, con diferentes convenciones de nomenclatura y semántica de llamadas. Llamar a la situación histéricamente pobre sería una gran subestimación.

En el lado bueno, el Finder en Mac OS X 10.6 Snow Leopard ha sido completamente reescrito en Cocoa, y con eso vienen interfaces de plugins enormemente superiores. Si tienes la suerte de estar en una situación en la que solo puedes apuntar a Snow Leopard, probablemente deberías obtener un ADC Premier o una membresía superior, descargar las compilaciones preliminares y codificar contra eso. Además, su plugin puede no funcionar en 10.6 de todos modos sin una reescritura de Cocoa, por lo que podría tener sentido echar un vistazo a Snow Leopard antes de que se lance, independientemente.


Las ganancias son escasas; nunca ha sido realmente claro para mí si Finder Plugins es realmente compatible. Algunas pistas más, sin embargo:

  • SampleCMPlugIn - SampleCMPlugIn carbono, por supuesto, ya que también lo es Finder. Tenga en cuenta que casi cualquier complemento de Finder probablemente dejará de funcionar con 10.6.
  • Automator puede guardar cosas como un "complemento Finder". Es una versión más compatible de lo que está discutiendo, pero por supuesto menos flexible.

No hay un sistema de complemento oficial o compatible para el Finder. A partir de OS X 10.6, necesitará inyectar código en el proceso del Finder y anular los métodos del objetivo C en el proceso del Finder.

He hecho esto para un proyecto propietario. Puedo decirte que la razón por la que no hay ejemplos o tutoriales para esto es porque es una tarea de desarrollo significativamente difícil y que requiere mucho tiempo. Por esta razón, hay muchos incentivos para que las personas u organizaciones que lo hayan logrado guarden estrechamente los detalles de su proceso.

Si hay alguna manera de que pueda lograr su objetivo utilizando la API de servicios, hágalo. Escribir un complemento Finder le llevará 1-2 meses sólidos de desarrollo concienzudo y un conocimiento razonablemente profundo de los elementos internos C y Objective-C.

Si todavía estás convencido de que quieres hacer esto, agarra mach_star . Buena suerte.


Para Yosemite (MacOS 10.10 y posteriores), puede usar el marco FinderSync de Apple, que permite a las extensiones del Finder:

  • Expresar interés en jerarquías de carpetas específicas
  • Proporcione "insignias" para indicar el estado de los elementos dentro de esas jerarquías
  • Proporcionar elementos de menú dinámico en los menús contextuales de Finder, cuando los elementos seleccionados (o el objetivo de la ventana) están en esas jerarquías
  • Proporcione un elemento de la barra de herramientas que muestre un menú con elementos dinámicos (incluso si la selección no está relacionada)

Para agregar superposiciones de iconos Buscador / Explorador de archivos y menús contextuales, en una plataforma cruzada, desde Java, eche un vistazo a la biblioteca Liferay Nativity .

También menciono esto en otra publicación SO , que también contiene enlaces a documentos y API ''Finder Sync'' de Apple.


Por lo que sé, no hay una arquitectura de complemento oficial para Finder. Es posible que pueda agregar superposiciones de imágenes a iconos a través de una aplicación externa sin tener que enganchar en el Finder, aunque no sería sobre la marcha. No creo que haya una manera de agregar elementos de menú contextual aparte de Acciones de carpeta y Automator. También puede buscar escribir una aplicación externa para supervisar los cambios en el Sistema de archivos utilizando la API de FSEvents .