2 pontos por GN⁺ 2024-05-19 | 1 comentários | Compartilhar no WhatsApp
  • Biblioteca que permite a desenvolvedores Go criar uma GUI de modo imediato para vários sistemas operacionais e WebAssembly
  • Suporta Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD e WebAssembly, com amplo alcance de plataformas
  • Projetada para reduzir dependências, usando bibliotecas de plataforma para gerenciamento de janelas, entrada e renderização por GPU
  • A renderização inclui o renderizador vetorial Pathfinder baseado em OpenGL ES e Direct3D 11, e está migrando para um renderizador de compute shader baseado em piet-gpu
  • Texto e formas são renderizados por contornos, sem serem pré-gravados em texturas, oferecendo suporte a animações, desenho com transformações e independência da resolução em pixels

Objetivo e escopo de suporte do Gio

  • Gio é uma biblioteca para criar GUIs eficientes, fluidas e portáveis em Go
  • As plataformas suportadas são Linux, macOS, Windows, Android, iOS, FreeBSD, OpenBSD e WebAssembly
  • Há uma demo WebAssembly para testes rápidos, e é necessário um navegador com suporte a WebAssembly para executá-la
  • O código-fonte de exemplo pode ser visto no projeto Kitchen

Instalação e caminho de aprendizado

  • O Gio foi projetado com foco em poucas dependências
  • Você pode verificar as dependências necessárias na documentação de instalação de cada plataforma
  • Após a instalação, é possível começar pela documentação Learn e pelo Hello World
  • O showcase inclui godcr, Tailscale, gotraceui, Sointu, Protonet e outros

Tecnologia de renderização

  • O Gio combina a flexibilidade do paradigma gráfico de modo imediato com tecnologias modernas de gráficos 2D
  • O renderizador vetorial é baseado no projeto Pathfinder e implementado sobre OpenGL ES e Direct3D 11
  • O renderizador está migrando para um renderizador baseado em compute shader mais eficiente, construído sobre piet-gpu
  • Texto e formas são renderizados usando apenas contornos, sem pré-gravação em imagens de textura
    • Suporta animações eficientes
    • É adequado para desenho com transformações
    • Pode manter independência da resolução em pixels

Modelo de financiamento

  • O desenvolvimento do Gio é financiado por patrocínio
  • Se o projeto for útil, você pode considerar apoiar o projeto Gio no OpenCollective ou patrocinar diretamente o desenvolvedor

1 comentários

 
GN⁺ 2024-05-19
Opiniões no Hacker News
  • Usando na prática, foi impossível criar com isso um app complexo sério
    Ele não tem componentes que outras plataformas oferecem por padrão, como vídeo, mapas e rich text, e também não há um caminho claro e fácil para adicioná-los por conta própria
    A API quebra a cada poucos meses, e também não há uma forma de aplicar temas
    Gráficos em modo imediato são bons até você precisar gerenciar estado complexo, mas a partir daí acaba tendo que implementar seu próprio sistema de gráficos em modo retido, trazendo de volta problemas que foram resolvidos há muito tempo
    O renderizador sofisticado baseado em piet-gpu também só aceita pontos de controle de curvas de Bézier como entrada e faz a tesselação de tudo; a ideia é interessante, mas, para desenhar um círculo de verdade, você acaba dependendo de uma aproximação com 4 curvas de Bézier
    Wasm parece mais uma prova de conceito que a equipe de compilação ainda precisaria lapidar por anos em termos de engenharia para chegar a nível de produto; no geral, parece ok quando desenvolvedores Go querem criar uma UI simples, com algo como listas e campos de entrada

    • Dá para criar qualquer coisa com isso, e na v0.6 esses problemas ficaram muito menos difíceis
      Há também tema Material Design e modos claro/escuro
      Um ótimo exemplo de app gioui com modos claro/escuro e tema customizado é https://github.com/chapar-rest/chapar
      No Mac ou no Windows, basta go run .
      Kerning de texto, texto fluindo ao longo de arcos e RTL/LTR também são possíveis graças a github.com/go-text/typesetting
      Widgets complexos, como seletores giratórios de calendário ou diagramas, também existem no GitHub, mas falta um esforço para reuni-los
      Se essas coisas forem agregadas, acho que haverá incentivo suficiente para mais desenvolvedores entrarem
    • Mudanças de API que quebram tudo a cada poucos meses aparecem com uma frequência deprimente em código do Google
      Parece não haver uma cultura que valorize não quebrar o código dos usuários
    • Se Wasm for importante, o Uno Platform oferece um suporte bastante bom, e também há o AvaloniaUI
      Ambos hoje são estáveis e têm um conjunto de controles e bibliotecas relativamente rico
  • Na web, parece renderizar tudo em um canvas, como o Flutter, e essa abordagem é conhecida por ter problemas de acessibilidade e de sensação nativa

    • Na web, definitivamente não parece nativo e a acessibilidade também não é boa
      Não dá para navegar com Tab entre botões de opção; no macOS, CMD+A não seleciona todo o conteúdo do campo de texto, enquanto CTRL+A funciona
    • Fico curioso se existe uma variação que mantenha um DOM invisível ao lado do canvas para fins de acessibilidade
      Parece possível, mas também exigiria bastante trabalho
    • No iPhone, nem copiar ou colar funciona
    • Isso, para começo de conversa, não é um framework de app web, mas sim um toolkit de GUI nativo, mais próximo de algo que tem um backend web
  • Fugindo um pouco do assunto, mas tenho curiosidade sobre qual é hoje a melhor forma de criar apps multiplataforma para mobile e web
    Seja compartilhando tanto a lógica de negócio quanto a UI, seja compartilhando só a lógica de negócio
    Fiquei em dúvida entre opções como gomobile, Rust e TypeScript
    Por um tempo, TypeScript pareceu a tecnologia mais portátil, então pensei em usá-lo para toda a lógica de negócio, mas descobri que não há uma boa forma de rodar JavaScript no iOS com desempenho decente

    • Hoje, talvez Flutter seja a melhor opção: https://flutter.dev/
      Se você não se importar em escrever a UI nativa e compartilhar apenas a lógica de negócio, Kotlin também é uma opção: https://kotlinlang.org/docs/multiplatform.html#kotlin-multip...
      Com Compose, também é possível criar a UI em Kotlin: https://www.jetbrains.com/lp/compose-multiplatform/
      Porém, o suporte a iOS ainda está em alfa e o da web é “experimental”; então, se você não quiser aceitar a possibilidade de ter de mudar código conforme o framework evolui, Flutter, que já é bastante estável em todas as plataformas, é a escolha certa
      Se você já conhece TypeScript e React, também pode considerar React Native, mas é difícil garantir o desempenho no iOS ou em outros lugares: https://reactnative.dev/
    • Para apps que precisam de acabamento, UI nativa é o caminho
      Já passei por frameworks demais que prometiam resolver tudo e não cumpriam
      No começo você começa mais rápido, mas logo acaba remendando bibliotecas centrais depois de uma atualização do OS para chegar a FPS próximo do nativo ou para deixar as animações do sistema mais parecidas
      Você só economiza tempo quando não lapida a UI
      A lógica central pode ser compartilhada
      Uso gomobile e gosto bastante no geral, mas o overhead de runtime é de 3 MB, então não serve para web
      Kotlin Multiplatform parecia bom, mas faltavam bibliotecas básicas e, talvez por elas já existirem no Kotlin Android, pouca gente fazia equivalentes multiplataforma
      Rust e a camada de bindings de linguagem da Mozilla também parecem bons, mas ainda não experimentei
    • Recomendo a combinação React Native com Expo
      Flutter também não é ruim, mas na web ele renderiza em canvas, o que é ruim em termos de sensação de uso e acessibilidade
      O iOS também ainda tem problemas de latência mesmo depois da introdução do motor de renderização Impeller
      Olhando para o cliente do Bluesky, o desempenho é bom em todas as plataformas suportadas e ele usa uma única base de código
      https://github.com/bluesky-social/social-app
    • Existe o Uno(https://platform.uno)
      É open source e tem como alvo Android, iOS, Windows, Mac e Linux: https://platform.uno/platforms/
      Usa C# e implementa automaticamente views e controles com o framework de UI nativo de cada plataforma
      Também tem bom suporte a IDEs como Visual Studio, VS Code e Rider, e não fica limitado a outras ferramentas
      Há também um plugin para Figma voltado à colaboração de design
    • Nós usamos Tauri, mas é importante dizer que usamos apenas para ferramentas internas
      Não sei se é uma boa ferramenta também para produtos de consumo
      Para o nosso uso, funciona bem o suficiente, principalmente porque são ferramentas para técnicos de usinas solares, e usar TypeScript multiplataforma em ambientes com internet ruim ficou pesado demais para uma equipe pequena
  • Estou criando um app de streaming com gioui, e é muito fácil; os upgrades também são sempre tranquilos
    Porque é Go e os desenvolvedores principais tratam mudanças com bastante seriedade
    Quando preciso de uma GUI web, uso este sistema de plugins do gioui: https://github.com/gioui-plugins/gio-plugins
    É surpreendente que o WebView funcione na web, no desktop e no mobile
    Deep links também funcionam: ao enviar links por e-mail ou em notificações do Monike, o app do usuário abre exatamente na posição correta da GUI
    Também há notificações e extensões de compartilhamento para todos os sistemas operacionais, então acho que é realmente algo próximo de um sistema completo
    Concordo que dar suporte a todos os sistemas operacionais é difícil, mas no mundo de hoje a diversidade é o padrão
    Gosto do fato de poder fazer tudo isso só com Go, sem ficar alternando entre várias tecnologias
    Sempre escrevo o backend em Go para funcionar tanto com gio quanto com HTML
    Se preciso de SEO ou reprodução de vídeo, trato isso no WebView, e também consigo atender ao SEO do Google no lado web do gio
    Coloco Markdown no Hugo para que o SEO do Google enxergue

  • Do ponto de vista de alguém iniciante em Go, esta parte da documentação me deixou curioso
    Diz que o motivo para usar op.ColorOp{Color: red}.Add(ops) em vez de ops.Add(ColorOp{Color: red}) é evitar alocações na chamada, fazendo com que o método Add não receba um argumento de tipo interface, e que isso é central no design de “zero allocation” do Gio
    Gostaria de entender por que surge uma alocação, o que é alocado e como isso é economizado

    • Isso acontece por causa da forma como Go lida com tipos dinâmicos por meio de interfaces e de como structs se encaixam nisso
      Quando uma função recebe um argumento de tipo interface e você passa para ela uma struct pura, Go cria um wrapper em volta dela, e essa é a alocação mencionada na citação
      Esse wrapper é um par de ponteiros formado por um ponteiro de tipo/vtable e um ponteiro para os dados da struct
      Isso permite inferência de tipo em tempo de execução e extensão implícita de interfaces
      Ou seja, para implementar uma interface basta implementar os métodos, sem precisar declarar explicitamente o tipo como em ByteReader extends Reader
      Você só paga esse custo quando usa isso, então muito código em caminhos rápidos usa apenas structs sempre que possível
    • Em Go, quando você faz v := interfaceType(concreteTypeValue), em baixo nível acontece mais ou menos isto
      Algo como dataPtr := &concreteTypeValue, typePtr := typeData[concreteType](), e então é criado um valor de interface com o ponteiro de dados e o ponteiro de tipo
      A primeira linha aqui é a alocação, porque, pela regra que lembro, ponteiros em Go não apontam para valores na stack, então concreteTypeValue precisa ser alocado no heap
      A regra de ponteiros não apontarem para a stack existe para facilitar o crescimento dinâmico das stacks das goroutines
      Veja https://go.dev/doc/faq#stack_or_heap
    • Na primeira forma, ColorOp{Color: red} precisa ser encaixotado e alocado no heap
      Isso porque ops.Add normalmente recebe um ponteiro “gordo” para um valor que implementa uma certa interface, e não um valor de tipo concreto
    • As outras respostas já responderam à pergunta em si, mas, separadamente, op.ColorOp{Color: red}.Add(ops) soa estranho de ler
      Para mim, parece “adicionar ops ao resultado de op.ColorOp{Color: red}
      Por isso eu daria à função o nome AddTo: op.ColorOp{Color: red}.AddTo(ops)
      Ainda não é exatamente idiomático, mas pelo menos sinaliza que o argumento da função é modificado
    • https://stackoverflow.com/questions/39492539/go-implicit-con...
  • É interessante que a demo em WASM da primeira página, em um PC bem comum com Windows 10 e Chrome, renderiza apenas quadrados pretos onde deveria haver texto
    No Chrome de um celular Android, renderizou corretamente

    • Não fui só eu
      Além disso, rodou extremamente devagar
    • Mesma coisa no Edge do Windows 11
  • Fiz um pequeno app em Go usando Fyne e não pretendo usar de novo
    Tanto Gio quanto Fyne carecem muito do polimento e dos recursos que o Flutter oferece
    Decidi fazer a lógica principal em Golang e embrulhá-la em um app Android, mas a GUI parecia ter saído de 2003 e as opções para consertar isso eram limitadas

    • Uma outra opção é Wails
      Você pode escrever toda a lógica em Go e a UI em HTML, usando ou não um framework web
      É parecido com Electron, mas mais leve porque não distribui o Chrome junto e usa o visualizador web do sistema
      [1] https://github.com/wailsapp/wails
    • Interessante
      Seria ótimo se você pudesse explicar como embrulhou isso como app Android
  • Por que todas essas GUIs multiplataforma parecem ter sido desenhadas 50 anos atrás?

    • Gostaria de saber o que exatamente você estava usando em 1974 para isso parecer daquela época
  • A demo não funciona para mim
    No Chromium do Win 11, alguns botões aparecem, mas a maior parte está toda preta

  • Ao contrário do Fyne, é um bom sinal que esta biblioteca tenha passado no primeiro teste que joguei nela: renderização de texto CJK
    O Fyne não consegue fazer isso a menos que você forneça uma única fonte customizada para renderizar tudo
    Boa sorte para encontrar uma única fonte que inclua de forma satisfatória todos os sistemas de escrita comuns no mundo inteiro, além de emojis
    Então, quando estou criando algo que tenha conteúdo gerado por usuários, conteúdo web ou qualquer possibilidade de localização, por menor que seja, o Fyne está imediatamente fora para mim

    • Nesse aspecto, Noto Sans é muito boa