2 puntos por GN⁺ 2024-05-19 | 1 comentarios | Compartir por WhatsApp
  • Es una biblioteca que permite a los desarrolladores de Go crear GUI de modo inmediato para varios sistemas operativos y WebAssembly
  • Admite una amplia cobertura de plataformas, incluyendo Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD y WebAssembly
  • Está diseñada para reducir dependencias y aprovechar las bibliotecas de cada plataforma para la gestión de ventanas, entrada y dibujo con GPU
  • El renderizado incluye el renderizador vectorial Pathfinder, basado en OpenGL ES y Direct3D 11, y está migrando hacia un renderizador con shaders de cómputo basado en piet-gpu
  • Renderiza texto y formas como contornos, sin convertirlos en texturas, lo que permite animaciones, dibujo con transformaciones e independencia respecto de la resolución de píxeles

Objetivo y alcance de soporte de Gio

  • Gio es una biblioteca para crear GUI eficientes, fluidas y portables en Go
  • Las plataformas compatibles son Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD y WebAssembly
  • Hay una demo en WebAssembly para una prueba rápida; para ejecutarla se necesita un navegador compatible con WebAssembly
  • El código fuente del ejemplo se puede consultar en Kitchen project

Instalación y ruta de aprendizaje

  • Gio está diseñado con el objetivo de tener pocas dependencias
  • Se pueden consultar las dependencias necesarias en la documentación de instalación de cada plataforma
  • Después de instalar, se puede empezar con la documentación de Learn y Hello World
  • El showcase incluye godcr, Tailscale, gotraceui, Sointu, Protonet, entre otros

Tecnología de renderizado

  • Gio combina la flexibilidad del paradigma de gráficos de modo inmediato con tecnologías modernas de gráficos 2D
  • El renderizador vectorial se basa en el Pathfinder project y está implementado sobre OpenGL ES y Direct3D 11
  • El renderizador está migrando hacia un renderizador más eficiente basado en shaders de cómputo, construido sobre piet-gpu
  • El texto y las formas no se preprocesan como imágenes de textura, sino que se renderizan usando solo contornos
    • Permite animaciones eficientes
    • Es adecuado para dibujo con transformaciones
    • Permite mantener independencia respecto de la resolución de píxeles

Modelo de financiamiento

  • El desarrollo de Gio se financia mediante patrocinios
  • Si el proyecto te resulta útil, puedes considerar apoyar el proyecto Gio en OpenCollective o patrocinar directamente a sus desarrolladores

1 comentarios

 
GN⁺ 2024-05-19
Opiniones de Hacker News
  • Tras usarlo en la práctica, me resultó imposible crear con esto una app compleja en serio
    No tiene componentes como video, mapas o texto enriquecido, que otras plataformas incluyen de base, y tampoco hay un camino claro y sencillo para agregarlos uno mismo
    La API se rompe cada pocos meses y tampoco hay forma de aplicar temas
    Los gráficos en modo inmediato están bien hasta que hay que manejar estados complejos; a partir de ahí, terminas teniendo que implementar tus propios gráficos en modo retenido, trayendo de vuelta problemas que se resolvieron hace mucho
    El vistoso renderizador basado en piet-gpu también funciona recibiendo solo puntos de control de curvas Bézier como entrada y teselándolo todo, así que el concepto es genial, pero para dibujar un círculo real terminas dependiendo de una aproximación con 4 curvas Bézier
    Wasm se parece más a una prueba de concepto que necesitaría varios años de refinamiento de ingeniería por parte del equipo del compilador para llegar a nivel de producto, y en general parece estar bien para desarrolladores Go que quieran crear una UI simple con listas y campos de entrada

    • Con esto se puede crear cualquier cosa, y en v0.6 estos problemas se volvieron mucho menos engorrosos
      También tiene temas de Material Design y modo claro/oscuro
      Un excelente ejemplo de app gioui con modo claro/oscuro y temas personalizados es https://github.com/chapar-rest/chapar
      En Mac o Windows basta con go run .
      El kerning de texto, texto que fluye siguiendo un arco y RTL/LTR también son posibles gracias a github.com/go-text/typesetting
      También hay widgets complejos como selectores de calendario o diagramas en GitHub, pero falta esfuerzo para reunirlos en un solo lugar
      Si esas cosas se agruparan, creo que habría incentivos suficientemente grandes para que más desarrolladores se sumen
    • Los cambios de API que rompen todo cada pocos meses se ven con una frecuencia deprimentemente alta en el código de Google
      No parece haber una cultura que valore que el código de los usuarios no se rompa
    • Si Wasm es importante, Uno Platform lo soporta bastante bien, y también está AvaloniaUI
      Ambos son estables hoy y cuentan con un conjunto relativamente rico de controles y bibliotecas
  • En la web parece renderizar todo en un canvas, como Flutter, y se sabe que este enfoque tiene problemas de accesibilidad y de sensación nativa

    • En la web, definitivamente no se siente nativo y la accesibilidad tampoco es buena
      No se puede pasar con Tab entre botones de opción, en macOS CMD+A no selecciona todo el campo de texto, mientras que CTRL+A
    • Me pregunto si existe una variante que, por accesibilidad, mantenga un DOM invisible junto al canvas
      Parece posible, pero también requeriría bastante trabajo
    • En iPhone ni siquiera funciona copiar o pegar
    • Esto no es, para empezar, un framework de apps web, sino un toolkit de GUI nativa, más bien uno que tiene backend web
  • Se sale un poco del tema, pero últimamente me pregunto cuál es la mejor forma de crear apps móviles y web multiplataforma
    Ya sea compartiendo tanto la lógica de negocio como la UI, o solo la lógica de negocio
    Estuve evaluando opciones como gomobile, Rust y TypeScript
    Durante un tiempo TypeScript me pareció la tecnología más portable y quería usarla para toda la lógica de negocio, pero descubrí que en iOS no hay una buena forma de ejecutar JavaScript con un rendimiento decente

    • Ahora probablemente Flutter sea la mejor opción: https://flutter.dev/
      Si te parece bien escribir la UI en nativo y compartir solo la lógica de negocio, Kotlin también es una opción: https://kotlinlang.org/docs/multiplatform.html#kotlin-multip...
      Con Compose también se puede crear la UI en Kotlin: https://www.jetbrains.com/lp/compose-multiplatform/
      Pero el soporte para iOS todavía está en alfa y web es “experimental”, así que si no quieres asumir que tendrás que cambiar código a medida que el framework evolucione, Flutter, que ya es bastante estable en todas las plataformas, es lo indicado
      Si ya conoces TypeScript y React, también podrías considerar React Native, pero es difícil garantizar su rendimiento en iOS u otros entornos: https://reactnative.dev/
    • Para apps que necesitan un buen nivel de acabado, lo correcto es una UI nativa
      Ya vi demasiados frameworks que prometían resolverlo todo y no cumplieron
      Al principio empiezas más rápido, pero pronto terminas parcheando bibliotecas clave para que, después de una actualización del OS, los FPS se acerquen a lo nativo o las animaciones del sistema se parezcan más
      Solo ahorras tiempo cuando no vas a pulir la UI
      La lógica central sí se puede compartir
      Uso gomobile y en general me gusta, pero su overhead de runtime es de 3 MB, así que no sirve para la web
      Kotlin Multiplatform se veía bien, pero le faltaban bibliotecas básicas y, quizá porque ya existen en Kotlin Android, no había mucha gente haciendo equivalentes multiplataforma
      Rust y la capa de bindings de lenguaje de Mozilla también se ven bien, pero todavía no los he probado
    • Recomiendo la combinación de React Native y Expo
      Flutter tampoco está mal, pero en web renderiza en un canvas, así que se siente flojo en cuanto a sensación y accesibilidad
      En iOS también sigue teniendo problemas de latencia incluso después de introducir el motor de renderizado Impeller
      Si miras el cliente de Bluesky, tiene buen rendimiento en todas las plataformas compatibles y usa una sola base de código
      https://github.com/bluesky-social/social-app
    • Existe Uno(https://platform.uno)
      Es open source y apunta a Android, iOS, Windows, Mac y Linux: https://platform.uno/platforms/
      Usa C# e implementa automáticamente vistas y controles con el framework de UI nativo de cada plataforma
      También tiene buen soporte de IDE como Visual Studio, VS Code y Rider, y no te limita a esas herramientas
      Además tiene un plugin de Figma para colaboración en diseño
    • Nosotros usamos Tauri, pero es importante aclarar que solo para herramientas internas
      No sé si también sea una buena herramienta para productos de consumo
      Para nuestro caso encaja bastante bien, porque son principalmente herramientas para técnicos de plantas solares, y usar TypeScript multiplataforma en condiciones de internet deficientes se volvió demasiado pesado para un equipo pequeño
  • Estoy haciendo una app de streaming con gioui, y es muy fácil; además, las actualizaciones siempre son sencillas
    Porque es Go y los desarrolladores principales se toman los cambios bastante en serio
    Cuando necesito una GUI web, uso este sistema de plugins de gioui: https://github.com/gioui-plugins/gio-plugins
    Sorprende que WebView funcione en web, escritorio y móvil
    También hay deep links, así que si envías un enlace por email o de una notificación de Monike, la app del usuario se abre exactamente en la ubicación correcta de la GUI
    También tiene notificaciones y extensiones para compartir para todos los OS, así que realmente lo veo como algo cercano a un sistema completo
    Estoy de acuerdo en que dar soporte a todos los OS es difícil, pero en el mundo actual la diversidad es lo normal
    Me gusta poder hacer todo esto solo con Go, sin estar saltando entre varias tecnologías
    El backend en Go siempre lo escribo para que funcione tanto con gio como con HTML
    Si necesito SEO o reproducción de video, lo manejo en WebView, y también puedo satisfacer el SEO de Google del lado web de gio
    Pongo Markdown en Hugo para que Google SEO lo vea

  • Como principiante en Go, me da curiosidad esta parte de la documentación.
    Dice que la razón para usar op.ColorOp{Color: red}.Add(ops) en lugar de ops.Add(ColorOp{Color: red}) es evitar asignaciones al llamar, haciendo que el método Add no reciba un argumento de tipo interfaz, y que eso es clave en el diseño de “zero allocation” de Gio.
    Quiero entender por qué se produce una asignación, qué se asigna y cómo se ahorra.

    • Esto se debe a cómo Go maneja los tipos dinámicos mediante interfaces y a cómo las estructuras encajan con eso.
      Cuando una función recibe un argumento de tipo interfaz y se le pasa una estructura pura, Go crea un wrapper alrededor; esa es la asignación mencionada en la cita.
      Ese wrapper es un par de punteros: un puntero de tipo/vtable y un puntero a los datos de la estructura.
      Esto permite la inferencia de tipos en tiempo de ejecución y la extensión implícita de interfaces.
      Es decir, para implementar una interfaz basta con implementar sus métodos, y no hace falta declarar explícitamente el tipo como en ByteReader extends Reader.
      Este costo solo se paga cuando se usa, así que mucho código de rutas rápidas usa solo estructuras siempre que puede.
    • En Go, cuando haces v := interfaceType(concreteTypeValue), a bajo nivel ocurre algo más o menos así:
      dataPtr := &concreteTypeValue, typePtr := typeData[concreteType](), y luego se crea un valor de interfaz con el puntero a datos y el puntero de tipo.
      La primera línea es la asignación; según la regla que recuerdo, en Go los punteros no apuntan a valores en la pila, así que concreteTypeValue debe asignarse en el heap.
      La regla de que los punteros no apunten a la pila existe para que las pilas de las goroutines puedan crecer dinámicamente con facilidad.
      Consulta https://go.dev/doc/faq#stack_or_heap
    • En el primer enfoque, ColorOp{Color: red} debe ser boxeado y asignado en el heap.
      Esto se debe a que ops.Add normalmente recibe un puntero “grueso” a un valor que implementa cierta interfaz, no un valor de tipo concreto.
    • Otras respuestas ya respondieron la pregunta en sí, pero, por separado, op.ColorOp{Color: red}.Add(ops) se lee raro.
      Para mí se lee como “agregar ops al resultado de op.ColorOp{Color: red}”.
      Por eso me gustaría llamar a la función AddTo: op.ColorOp{Color: red}.AddTo(ops).
      Sigue sin ser muy idiomático, pero al menos indica que el argumento de la función se modifica.
    • https://stackoverflow.com/questions/39492539/go-implicit-con...
  • Es interesante que en una PC bastante común con Windows 10 y Chrome, la demo de WASM de la primera página renderiza solo rectángulos negros donde debería haber texto.
    En Chrome en un teléfono Android se renderizó correctamente.

    • No era solo yo.
      Además, se ejecutó lentísimo.
    • Lo mismo en Edge sobre Windows 11.
  • Hice una app pequeña en Go usando Fyne y no pienso volver a usarlo.
    Tanto Gio como Fyne están muy lejos del nivel de pulido y funcionalidades que ofrece Flutter.
    Terminé haciendo la lógica central en Golang y envolviéndola en una app Android, pero la GUI parecía salida de 2003 y había pocas formas de arreglarla.

    • Otra opción es Wails.
      Puedes escribir toda la lógica en Go y la UI en HTML, usando o no un framework web.
      Es parecido a Electron, pero más liviano porque no distribuye Chrome junto con la app, sino que usa el visor web del sistema.
      [1] https://github.com/wailsapp/wails
    • Interesante.
      Me gustaría que pudieras explicar cómo la envolviste como app Android.
  • ¿Por qué todas estas GUI multiplataforma parecen haber sido diseñadas hace 50 años?

    • Me gustaría saber qué diablos usabas en 1974 para que eso te parezca de esa época.
  • La demo no me funciona.
    En Chromium sobre Win 11 veo algunos botones, pero la mayor parte está completamente en negro.

  • A diferencia de Fyne, esta biblioteca pasó mi primera prueba: renderizado de texto CJK, lo cual es una buena señal.
    Fyne no puede hacer eso a menos que le des una fuente personalizada única para renderizar todo.
    Encontrar una sola fuente que incluya satisfactoriamente no solo todos los sistemas de escritura de uso común en el mundo, sino también emojis, es cuestión de tener mucha suerte.
    Por eso, para mí Fyne queda descartado de inmediato si voy a crear algo con contenido generado por usuarios, contenido web o la más mínima posibilidad de localización.

    • En ese sentido, Noto Sans es bastante buena