2 points par GN⁺ 2024-05-19 | 1 commentaires | Partager sur WhatsApp
  • Il s’agit d’une bibliothèque qui permet aux développeurs Go de créer des GUI en mode immédiat ciblant plusieurs systèmes d’exploitation ainsi que WebAssembly
  • Elle prend en charge Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD et WebAssembly, avec une large couverture de plateformes
  • Sa conception vise à réduire les dépendances et s’appuie sur les bibliothèques de plateforme pour la gestion des fenêtres, les entrées et le rendu GPU
  • Le rendu inclut le moteur de rendu vectoriel Pathfinder basé sur OpenGL ES et Direct3D 11, avec une transition en cours vers un moteur à compute shaders fondé sur piet-gpu
  • Le texte et les formes sont rendus sous forme de contours plutôt que précalculés en textures, ce qui permet les animations, le dessin avec transformations et l’indépendance vis-à-vis de la résolution en pixels

Objectif et périmètre de prise en charge de Gio

  • Gio est une bibliothèque destinée à créer en Go des GUI efficaces, fluides et portables
  • Les plateformes prises en charge sont Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD et WebAssembly
  • Une démo WebAssembly rapide est disponible ; pour l’exécuter, un navigateur compatible WebAssembly est nécessaire
  • Le code source d’exemple est disponible dans le projet Kitchen

Installation et parcours d’apprentissage

  • Gio est conçu avec l’objectif de limiter les dépendances
  • La documentation d’installation propre à chaque plateforme permet de vérifier les dépendances nécessaires
  • Après l’installation, on peut commencer avec la documentation Learn et Hello World
  • La vitrine comprend notamment godcr, Tailscale, gotraceui, Sointu et Protonet

Technologies de rendu

  • Gio combine la flexibilité du paradigme graphique en mode immédiat avec les technologies graphiques 2D modernes
  • Le moteur de rendu vectoriel est basé sur le projet Pathfinder et implémenté sur OpenGL ES et Direct3D 11
  • Le moteur évolue vers un rendu à base de compute shaders plus efficace, construit sur piet-gpu
  • Le texte et les formes ne sont pas précuits sous forme d’images de texture, mais rendus uniquement à partir de contours
    • Cela permet des animations efficaces
    • Cela convient au dessin transformé
    • Cela permet de conserver l’indépendance vis-à-vis de la résolution en pixels

Modèle de financement

  • Le développement de Gio est financé par des soutiens
  • Si le projet vous est utile, vous pouvez envisager de soutenir le projet Gio sur OpenCollective ou de faire un don directement au développeur

1 commentaires

 
GN⁺ 2024-05-19
Avis Hacker News
  • Après l’avoir utilisé en pratique, il m’a semblé impossible de créer avec ça une application complexe sérieuse
    Il manque des composants fournis par défaut sur d’autres plateformes, comme la vidéo, les cartes ou le texte riche, et il n’existe pas de voie claire et simple pour les ajouter soi-même
    L’API casse tous les quelques mois, et il n’y a pas non plus de moyen d’appliquer des thèmes
    Les graphismes en mode immédiat sont agréables jusqu’au moment où il faut gérer un état complexe ; à partir de là, on finit par devoir implémenter soi-même un mode conservé, ce qui ramène un problème résolu depuis longtemps
    Même le moteur de rendu sophistiqué basé sur piet-gpu, qui ne prend en entrée que des points de contrôle de courbes de Bézier et tesselle tout, est élégant conceptuellement, mais pour dessiner un vrai cercle, on dépend en pratique d’une approximation avec quatre courbes de Bézier
    Wasm ressemble davantage à une preuve de concept qu’une équipe de compilation devrait encore peaufiner pendant des années pour atteindre un niveau produit ; globalement, ça paraît correct pour un développeur Go qui veut créer une UI simple avec des listes et des champs de saisie

    • On peut créer n’importe quoi avec, et en v0.6 ces problèmes sont devenus bien moins pénibles
      Il y a aussi un thème Material Design, ainsi que des modes clair/sombre
      Un bon exemple d’application gioui avec mode clair/sombre et thèmes personnalisés est https://github.com/chapar-rest/chapar
      Sur Mac ou Windows, go run . suffit
      Le crénage du texte, le texte suivant un arc, ainsi que le RTL/LTR sont également possibles grâce à github.com/go-text/typesetting
      On trouve aussi sur GitHub des widgets complexes comme des sélecteurs de calendrier ou des diagrammes, mais il manque un effort pour les rassembler
      Si ces éléments étaient réunis, cela donnerait sans doute beaucoup plus envie à davantage de développeurs de s’y mettre
    • Les changements d’API cassants tous les quelques mois se voient de façon déprimante dans le code Google
      Il ne semble pas y avoir de culture accordant de l’importance au fait de ne pas casser le code des utilisateurs
    • Si Wasm est important, Uno Platform le prend plutôt bien en charge, et il y a aussi AvaloniaUI
      Les deux sont désormais stables et disposent d’un ensemble de contrôles et de bibliothèques relativement riche
  • Sur le Web, cela semble tout rendre dans un canvas, comme Flutter, mais cette approche est connue pour poser des problèmes d’accessibilité et de ressenti natif

    • Sur le Web, cela ne donne clairement pas une impression native et l’accessibilité n’est pas bonne
      On ne peut pas passer d’un bouton radio à l’autre avec Tab, sur macOS CMD+A ne sélectionne pas tout le contenu d’un champ texte alors que CTRL+A le fait
    • Je me demande s’il existe une variante qui, pour l’accessibilité, place aussi un DOM invisible à côté du canvas
      Cela semble possible, mais représenterait probablement pas mal de travail
    • Sur iPhone, même copier-coller ne fonctionne pas du tout
    • Ce n’est pas vraiment un framework d’applications web au départ, mais plutôt un toolkit GUI natif avec un backend web
  • C’est un peu hors sujet, mais je me demande quelle est aujourd’hui la meilleure façon de créer des apps mobiles et web multiplateformes
    Que l’on partage à la fois la logique métier et l’UI, ou seulement la logique métier
    J’ai hésité entre des options comme gomobile, Rust ou TypeScript
    À une époque, TypeScript me semblait être la technologie la plus portable et je voulais l’utiliser pour toute la logique métier, mais j’ai compris qu’il n’existait pas vraiment de bonne façon de faire tourner JavaScript sur iOS avec des performances correctes

    • Aujourd’hui, Flutter est probablement la meilleure option : https://flutter.dev/
      Si cela vous convient d’écrire l’UI en natif et de ne partager que la logique métier, Kotlin est aussi une option : https://kotlinlang.org/docs/multiplatform.html#kotlin-multip...
      Avec Compose, on peut aussi créer l’UI en Kotlin : https://www.jetbrains.com/lp/compose-multiplatform/
      Mais la prise en charge d’iOS est encore en alpha et le web est « experimental » ; donc si vous ne voulez pas vous retrouver à devoir modifier votre code au fil de l’évolution du framework, Flutter, déjà assez stable sur toutes les plateformes, est le bon choix
      Si vous connaissez déjà TypeScript et React, React Native peut aussi être envisagé, mais il est difficile de garantir les performances sur iOS ou ailleurs : https://reactnative.dev/
    • Pour une app qui doit être vraiment aboutie, il faut une UI native
      J’ai vu trop de frameworks promettre de tout résoudre sans tenir leurs promesses
      Au début, on démarre plus vite, mais très vite on se retrouve à patcher des bibliothèques cœur après une mise à jour d’OS pour rapprocher les FPS du natif ou mieux imiter les animations système
      On ne gagne du temps que lorsqu’on ne peaufine pas l’UI
      La logique cœur peut être partagée
      J’utilise gomobile et je l’aime globalement bien, mais son overhead d’exécution est de 3 Mo, donc ce n’est pas adapté au web
      Kotlin Multiplatform semblait prometteur, mais il manquait des bibliothèques de base et, comme elles existent déjà pour Kotlin Android, peu de gens semblaient créer leurs équivalents multiplateformes
      Rust et la couche de bindings de Mozilla ont aussi l’air intéressants, mais je ne les ai pas encore essayés
    • Je recommande la combinaison React Native et Expo
      Flutter n’est pas mauvais, mais sur le web il rend dans un canvas, ce qui est médiocre en termes de feeling et d’accessibilité
      Sur iOS aussi, même après l’introduction du moteur de rendu Impeller, il reste des problèmes de latence
      Le client Bluesky montre de bonnes performances sur l’ensemble des plateformes prises en charge, avec une base de code unique
      https://github.com/bluesky-social/social-app
    • Il y a Uno (https://platform.uno)
      C’est open source et cela cible Android, iOS, Windows, Mac et Linux : https://platform.uno/platforms/
      Il utilise C# et implémente automatiquement les vues et contrôles avec le framework UI natif de chaque plateforme
      Le support des IDE comme Visual Studio, VS Code et Rider est bon, sans être limité à ces outils
      Il existe aussi un plugin Figma pour la collaboration design
    • Nous utilisons Tauri, mais il est important de préciser que nous ne l’utilisons que pour des outils internes
      Je ne sais pas si c’est aussi un bon outil pour des produits grand public
      Pour notre usage, il convient très bien : ce sont surtout des outils destinés à des techniciens de centrales solaires, et utiliser du TypeScript multiplateforme dans des conditions Internet difficiles devenait trop lourd pour une petite équipe
  • Je développe une app de streaming avec gioui, et c’est très facile ; les mises à jour se passent toujours sans douleur
    Parce que c’est du Go et que les développeurs principaux prennent les changements assez au sérieux
    Quand j’ai besoin d’une GUI web, j’utilise ce système de plugins gioui : https://github.com/gioui-plugins/gio-plugins
    C’est étonnant de voir que WebView fonctionne sur le web, le desktop et le mobile
    Les deep links fonctionnent aussi : si l’on envoie un lien par e-mail ou via une notification Monike, l’app de l’utilisateur s’ouvre exactement au bon endroit dans la GUI
    Il y a aussi les notifications et les extensions de partage pour tous les OS, donc je trouve que c’est vraiment proche d’un système complet
    Je suis d’accord sur le fait qu’il est difficile de prendre en charge tous les OS, mais dans le monde actuel la diversité est la norme
    J’aime le fait de pouvoir faire tout cela uniquement en Go, sans passer d’une technologie à l’autre
    J’écris toujours le backend Go pour qu’il fonctionne à la fois avec gio et avec HTML
    Si j’ai besoin de SEO ou de lecture vidéo, je le gère dans WebView, et le côté web de gio peut aussi satisfaire le SEO de Google
    Je mets du Markdown dans Hugo pour que Google SEO puisse le voir

  • Du point de vue d’un débutant en Go, cette partie de la documentation m’intrigue
    La raison pour laquelle on utilise op.ColorOp{Color: red}.Add(ops) au lieu de ops.Add(ColorOp{Color: red}) serait d’éviter les allocations à l’appel, en faisant en sorte que la méthode Add ne prenne pas d’argument de type interface, et c’est présenté comme essentiel dans la conception « zero allocation » de Gio
    J’aimerais comprendre pourquoi une allocation se produit, ce qui est alloué, et comment elle est économisée

    • C’est dû à la manière dont Go traite les types dynamiques via les interfaces, et à la façon dont les structures s’y imbriquent
      Quand une fonction prend un argument de type interface et qu’on lui passe une structure pure, Go crée un wrapper autour ; c’est l’allocation dont parle la citation
      Ce wrapper est une paire de pointeurs composée d’un pointeur de type/vtable et d’un pointeur vers les données de la structure
      Cela permet l’inférence de type à l’exécution et l’extension implicite des interfaces
      Autrement dit, pour implémenter une interface, il suffit d’implémenter ses méthodes, sans avoir à déclarer explicitement le type comme dans ByteReader extends Reader
      Comme ce coût n’est payé qu’à l’utilisation, beaucoup de chemins rapides essaient autant que possible de n’utiliser que des structures
    • En Go, quand on fait v := interfaceType(concreteTypeValue), à bas niveau il se passe à peu près ceci
      dataPtr := &concreteTypeValue, typePtr := typeData[concreteType](), puis création d’une valeur d’interface contenant le pointeur de données et le pointeur de type
      Ici, la première ligne correspond à l’allocation, car d’après la règle dont je me souviens, en Go les pointeurs ne pointent pas vers des valeurs sur la pile, donc concreteTypeValue doit être alloué sur le tas
      La règle selon laquelle les pointeurs ne pointent pas vers la pile facilite la croissance dynamique des piles de goroutines
      Voir https://go.dev/doc/faq#stack_or_heap
    • Dans la première approche, ColorOp{Color: red} doit être boxé et alloué sur le tas
      Parce que ops.Add reçoit généralement un pointeur « large » vers une valeur qui implémente une certaine interface, plutôt qu’une valeur de type concret
    • D’autres réponses ont répondu à la question elle-même, mais séparément, op.ColorOp{Color: red}.Add(ops) se lit bizarrement
      Pour moi, ça se lit comme « ajouter ops au résultat de op.ColorOp{Color: red} »
      Du coup, j’aurais envie de nommer la fonction AddTo : op.ColorOp{Color: red}.AddTo(ops)
      Ce n’est toujours pas vraiment idiomatique, mais au moins ça signale que l’argument de la fonction est modifié
    • https://stackoverflow.com/questions/39492539/go-implicit-con...
  • Il est intéressant de voir que, sur un PC assez banal avec Windows 10 et Chrome, la démo WASM de la première page ne rend que des carrés noirs aux endroits où il devrait y avoir du texte
    Sur Chrome sur un téléphone Android, le rendu était correct

    • Je n’étais pas le seul
      En plus, ça tournait extrêmement lentement
    • Même chose dans Edge sur Windows 11
  • J’ai créé une petite application en Go avec Fyne, et je ne compte plus jamais l’utiliser
    Gio comme Fyne sont très loin du niveau de finition et des fonctionnalités qu’offre Flutter
    J’ai décidé de faire la logique principale en Golang et de l’envelopper dans une application Android, mais l’interface semblait sortie de 2003 et les possibilités de la corriger étaient limitées

    • Une autre option est Wails
      On peut écrire toute la logique en Go et l’UI en HTML, avec ou sans framework web
      C’est similaire à Electron, mais plus léger parce qu’il ne distribue pas Chrome avec l’application et utilise la vue web du système
      [1] https://github.com/wailsapp/wails
    • Intéressant
      J’aimerais bien que tu expliques comment tu l’as enveloppée dans une application Android
  • Pourquoi toutes ces GUI multiplateformes ont-elles l’air d’avoir été conçues il y a 50 ans ?

    • J’aimerais savoir ce qu’on utilisait exactement en 1974 pour que ça ait l’air de dater de cette époque
  • La démo ne fonctionne pas chez moi
    Dans Chromium sur Win 11, je vois quelques boutons, mais la plupart des éléments sont entièrement noirs

  • Contrairement à Fyne, le fait que cette bibliothèque ait réussi mon premier test, le rendu de texte CJK, est bon signe
    Fyne n’y arrive pas à moins qu’on lui fournisse une police personnalisée unique pour tout rendre
    Bon courage pour trouver une seule police qui couvre correctement tous les systèmes d’écriture couramment utilisés dans le monde, sans parler des emoji
    Donc dès qu’il y a le moindre contenu généré par les utilisateurs, contenu web ou possibilité de localisation, Fyne est immédiatement éliminé pour moi

    • Sur ce point, Noto Sans est plutôt bonne