Apps são uma gambiarra - estudando a loja de apps do elementary OS

Um pouco de contexto antes de começar

Poucas pessoas percebem que o conceito de apps (ou programas) com interface gráfica parece ter algo muito errado por trás, basicamente de uma maneira genérica uma interface desktop é basicamente isso:

As áreas-chave

Por vezes erroneamente chamadas de ‘hot corners’ são áreas de mais fácil localização, essas áreas são usadas para pares de ações importantes do sistema, os menus/grades de apps, o botão “desligar”, o “mostrar áreas de trabalho” tendem a ficar nessas áreas, comumente são usadas 2 em uma mesma linha dentro de um painel ou dock tendo ações psicologicamente opostas, exemplos incluem:

  • Se uma abre janelas, a outra esconde elas
  • Se uma inicia sua atividade no computador, a outra desliga o computador
  • Se uma abre apps a outra fecha

As áreas cromadas

Nesses locais ficam os painéis, barras e docks do sistema, raramente as 4 são utilizadas, sendo o mais comum usar uma ou duas o espaço não utilizados viram áreas de trabalho em potencial

A área de trabalho potencial

É como o nome sugere a área onde você realiza o seu trabalho podendo usar ela toda ou não, daí o potencial inclusive, através de programas que abrem nas:

Janelas de apps

Que por sua vez são sandboxes (não confundir com o isolamento sandbox de chamadas de sistema) isso significa que o conteúdo do app fica preso num retângulo e não sai pra fora desse retângulo, por isso o “sandbox” do inglês caixa de areia


Sabendo disso, vamos pro conteúdo principal

Ponto 1: Os problema do isolamento

Você deve ter notado que eu disse que o conteúdo da janela simplesmente não vaza de uma janela pra outra, pode parecer estranho mais isso é significativamente problemático, vamos supor que eu vá desenvolver um projeto em Vala pra loja do elementary OS, se presume que eu vá precisar de algumas coisas:

Ignore o fato de alguns apps não existirem mais por um instante, note que pra cada coisa eu preciso de um app diferente, o mesmo vale pra edição de imagens, se eu quiser fazer uma captura de tela, fazer múltiplas edições e usar como papel de parede:

Nesse momento você pode me questionar: Tal programa tem todas as ferramentas em um lugar só e se não tiver as outras ferramentas vão te permitir realizar a modificação com relativa facilidade, por que não usa ele?

E a resposta é: se pra mim fazer coisas que teoricamente são algo sequencial eu tenho que usar um programa que faz tudo, porque existem apps individuais? Não seria mais lógico e gastaria >MUITO< menos tempo e energia fazer blocos (também chamado de plugin) pra esse programa unificado?

Resolvendo em partes

Curiosamente, se a ação for sequencial é possível resolver esse problema parcialmente, sabendo onde um app salva suas configurações e os diretórios de sistema podemos usar o strace pra criar um fluxo, a ideia é simples:

  1. Mapear onde o primeiro programa salvou o arquivo
  2. Chamar o próximo programa da lista com o arquivo
  3. Repetir o passo 2 até o último programa da lista

Exemplo de caso simples só pra ilustrar o conceito:

  • Tirar um screenshot com o spectacle
  • Abrir no GIMP
  • Abrir no Gwenview
#!/bin/bash
arquivos_acessados_pelo_spectacle=$(mktemp)
# Rastreia os arquivos acessados e criados pelo spetacle
strace -e file -o "${arquivos_acessados_pelo_spectacle}" spectacle
# Filtramos os arquivos que existem e que foi usada o newfstatat
possiveis_arquivos_criados=$(grep -Ev ENOENT "${arquivos_acessados_pelo_spectacle}" | grep "^newfstatat" | cut -d\" -f2 | sort | uniq)
# Filtramos dessa lista os diretórios típicos do sistema, a pasta .config e a pasta .cache e a pasta .local
# ao fim dessa filtragem teremos uma lista do que ele realmente tentou criar
arquivos_ou_pastas_criados=($(echo "${possiveis_arquivos_criados}" | grep -Ev "^/usr|^/etc|^/dev|^/run|^/run|^/sys|^/$|^${HOME}$|^${HOME}/.cache|^${HOME}/.config|^${HOME}/.local|^/boot"))
# Agora dos resultados é só ver quais são arquivos e pegar o último
# sim, o último porque alguns programas carregam o arquivo anterior
arquivo_criado=$(for arquivo in ${arquivos_ou_pastas_criados[@]} ; do [ -f "${arquivo}" ] && { echo "${arquivo}"; } ; done)
# Agora é só abrir cada programa sequencialmente:
gimp "${arquivo_criado}" 
gwenview "${arquivo_criado}" 

E pronto, você pode criar fluxos de trabalho assim, mas ainda tem poréns, os apps GUI não são pensados pra serem usados com esse sistema (conhecido como piping) várias problemáticas surgem o que torna esse método pouco eficiente quando se generaliza:

  • Se um programa de nível 2 ou mais baixo salvar o arquivo com um nome diferente o script pode começar a ter problemas, como um bom ser pensante pode concluir: é só rodar os passos em cada sub-nível e é aí que entra o segundo problema:
  • Esse processo é lento, em termos leigos: basicamente nós injetamos um código na memória do programa que faz um log de cada acesso a um arquivo ou pasta que o programa fizer, pode não parecer em casos simples, mas experimenta fazer em softwares mais complexos como Kdenlive ou qualquer editor tipo MLT…
  • Por fim o usuário pode salvar o arquivo e realizar uma exportação de camadas no GIMP por exemplo… qual arquivo é o verdadeiro?

Então mesmo que dê pra fazer fluxos usando truques assim, não importa muito o que você faça, você não consegue paralelizar os apps de maneira assíncrona (é por isso que a barra de tarefas/dock é considerada uma inovação tão grande) e mesmo de maneira sequencial você tem limitações severas, uma solução óbvia é adicionar um parâmetro --pipe-mode que quando passado forçaria o programa a desativar funções de exportação e faria com que a saída do programa seja o arquivo trabalhado, mas isso depende de cada app, e como cada app tem um desenvolvedor diferente é bem improvável que o modelo de apps consiga implementar isso, mas porque?

A origem do isolamento de apps

Por mais que tudo pareça ter sido planejado, a GUI não só nasceu de um experimento (na Xerox) como foi rapidamente jogada para uma briga entre Steve Jobs e Bill Gates onde nenhum nem outro podiam perder tempo pensando no usuário, como resultado nos seus primórdios o GUI nada mais foi que uma releitura do TUI de sistemas mono-tarefa (DOS, ProDOS e SOS) e quando tudo se acalmou se tinha milhões de apps com essa mentalidade então essa é origem do isolamento de apps em janelas intransponíveis: uma briga pra quem vendia um produto experimental mais rápido

Ponto 2 - Muito app pra mesma coisa, só que diferente

Outro problema dos apps, é que você pode ter soluções que fazem coisas parecidas de jeitos levemente diferentes e , por exemplo edição de texto, vamos supor que eu esteja escrevendo esse artigo no elementaryOS, convém que eu tenha um editor de textos, mas qual?

Cada um deles tem suas particularidades, o TypeWriter por exemplo é saveless, ou seja, se eu fechar o app por engano, eu vou ter os dados salvos, o Quilter possui um sistema de preview, se eu quero ver como o artigo está ficando eu tenho essa aba, e o Code que me permite um controle melhor de como o Editor se comporta… porque não posso ter as 3 funções no mesmo app já que os 3 fazem a mesma coisa em suma? Isso aliado ao fato de que como você pode notar nesse artigo tem códigos e vários assuntos o que me faz achar interessante um formatador de código e um dicionário de sinônimos mas apesar de existirem excelentes apps eu não só volto no ponto 1 como tem mais de 1 opção que faz recair no ponto 2, esse ponto é bizarramente complexo de resolver a solução mais óbvia é usar de plugins e extensões mas isso será discutido mais a frente, mas outra solução é começar em um (por exemplo o Typewriter que me permite escrever sem ter que me preocupar em ter que salvar, depois passo pro Quilter e faço ajustes visuais com uma ferramenta formatadora de código e um dicionário do lado, assim:

É nítido que esse uso não é natural, e torna a execução da tarefa incrivelmente lenta

Ponto 3 - App pra um lado, sistema pro outro

Esse é um dos pontos que deixam nítido porque foi necessário usar o elementaryOS de exemplo, como eu disse os apps ficam em janelas e essas janelas ficam descoladas uma da outra e do sistema, isso trás umas consequências que geralmente a gente passa raiva, ainda pegando o exemplo anterior, vamos supor que eu esteja digitando em uma janela se você clicar em qualquer lugar da tela que não seja o app você perde o foco da janela e se você for do tipo de pessoa que precisa olhar pro teclado pra digitar você pode passar um bom tempo sem perceber e o sentimento de frustação vai ser longo, mas esse não é o foco, vamos supor que o App faça requisições na internet, e esse app precise de uma token que obviamente não pode estar no código fonte, e essa API seja apenas de fachada, ela apenas retorna o valor passado, supondo que esse app tenha uma função copiar e colar, o que impede esse app de trocar uma chave de criptomoedas do usuário por outra, ou injetar comandos quando ele identificar que existem comandos na pilha? Viver em um mundo digital sem poder copiar e colar é bem triste, porém de alguma forma em algum momento acreditamos que os apps deveriam ter o poder de controlar essas duas ações bizarramente poderosas, mesmo o Wayland é incapaz de barrar isso, problemas de acesso ao clipboard somente podem ser controlados por um app rodando em background o tempo todo, tal qual esse app faz lindamente mas ainda sim, há limitações por exemplo você pode bloquear apenas um app inteiro, e não é uma limitação do app mas da forma como o cliboard funciona, essa e inúmeras outras funções não deveriam estar no poder dos apps, outras incluem mas não se limitam a:

  • Agenda de contatos
    • Roubar informações pessoais e vender especialmente para telemarketing
    • Enviar spam e phishing como se fosse a própria pessoa
    • Criar “listas de disparo” e fazer disparos por terceiros
  • Agenda de calendário
    • Acessar informações sensíveis e até confidenciais
    • Manipular compromissos importantes sem autorização
    • Enviar notificações de spam
  • Controle se a tela deve estar ligada ou não
    • Desligar a tela enquanto se está em uma tarefa importante
    • Deixar a tela ligada até drenar a bateria do dispositivo.
    • Usar como zumbi de anúncios
  • Captura de tela
    • Screen logger
  • Alterar o papel de parede
    • Exibir imagens pornográficas, gore ou outro conteúdo repulsivo
    • Injetar propaganda
  • Manipulação de senhas
    • Roubar as senhas
    • Injetar ou perder a senha
    • Gerar senhas propositadamente fracas
  • Lançar outros outros apps e programas CLI
    • Injetar malware
    • Controlar configurações “por baixo”
  • Controle de volume e mixer
    • injetar audios trolls (vide “gemidão do zap”)
    • Alterar o volume com objetivo de ferir o ouvido

Imagine quantos ataques são possíveis com cada uma dessas “permissões” e pior, um bom app se integra ao sistema isso confunde o usuário pensando ser uma ação legítima do sistema em si, mesmo com sandboxes agressivos a maioria desses apps só possui utilidade se eles tiverem permissões, adivinha o que o usuário vai fazer? Exato, um furo na sandbox, você pode se perguntar “isso ainda não aconteceu, porque isso importa?” e o problema é que não aconteceu no Linux, no Windows e até Mac tem a rodo, não seria questão te tempo até começar a afetar o pinguim?

Ponto 4 - O problema dos plugins, extensões e similares

Acho que o primeiro e mais óbvio questionamento é: para qual app? E o segundo mais óbvio é: e se o app acabar?

Outro motivo para escolher o elementaryOS é o fato dele ter uma quantidade muito menor de apps registrados em sua base em relação aos seus concorrentes mesmo considerando apenas o mundo Linux, porém desde já temos 261 apps que passaram ou estão disponíveis, e nisso podemos tirar um dado importante: desses apenas 121 ou 46% estão com estado ativo, isso faz com que o índice de descontinuidade seja relativamente alta o que torna difícil dizer se realmente seria interessante seguir com essa abordagem (note que isso é uma tendência comum a todos os ecossistemas, mas passando pelo primeiro desafio escolhemos o app principal e vamos transformar os similares em plugins/extensões, por exemplo:

  • Pallete que serve criar pletas de cores

  • ColorMate que serve converter cores entre diferentes representações

  • Harvey que serve para testar o contraste entre duas cores

  • Picker que serve para escolher uma cor da tela

Se você testar vai notar que alguns desses apps já estão presentes em outros, ignore isso por hora, o foco agora é como unir esses apps em um, podemos elencar duas possibilidades: Plugins e Extensões

Plugins

São códigos de terceiros que rodam com capacidade total são uma função dispara quando algum evento acontece, o problema com os plugins é que essa função roda exatamente como se fosse um software aplicativo completo um plugin por definição poderia por exemplo disparar um ataque de Ransonware sem precisar de executar nenhum exploit , dado os traumas com a segurança do Flash e Java Applets não acho que seria interessante, além de como você vai notar eles adicionam um problema a mais

Extensões

Extensões usualmente são uma linguagem de script com uma interface API limitada por escopo, então, quando bem implementadas extensões não oferecem riscos de seguranças por violação de escopo uma vez que todas as ações são filtradas além de serem limitadas, mas note o “se bem implementadas”. Mas ainda assim não são perfeitas, cada app vai ter sua própria sintaxe, com sua própria API e isso leva a dois casos possíveis e recorrentes:

  • O app base morre: se isso acontecer, todo o código das extensões fica inútil, já que extensões são contextualizadas

  • O app muda a API: como resultado parte das extensões é perdida porque no meio do caminho, quebras de API inclusive o que torna apps incompatíveis com novas versões do sistema operacional

Nesse caso se pode pensar que delegando isso ao sistema operacional resolveria o problema, nesse cenário leva ao seguinte questionamento: qual a função dos apps?

Módulos?

Num cenário onde os apps são extensões do sistemas operacionais, ainda que estejam dispostos a janelas emulando o comportamento antigo por não serem mais independentes e funcionarem apenas no contexto do sistema operacional em si, eles seriam módulos não apps

Além disso o que realmente impediria o sistema operacional de sofrer o mesmo mal? Exatamente, nenhum, a menos que seja uma espécie de padrão aberto isso não funcionaria, ainda que explorássemos a ideia de módulos assumindo que o sistema operacional não quebraria a API das extensões, faz algum sentido a solução para manter os apps sem esse problema é abandonar o conceito de apps? Na minha visão não faz mas uma mudança dessas é naturalmente complexa e levará tempo

Conclusão

Os apps faziam sentido antes quando os computadores não tinham capacidade de adicionar recursos dinamicamente mas hoje em dia se tornou extremamente simples fazer isso, isso indica que talvez estejamos vendo os últimos anos de uma era na computação, quem seria o novo paradigma? Eu tô ansioso porque nunca foi proposto uma alternativa mesmo integrações com IAs parecem mais “faça meu trabalho” que uma real mudança de paradigma… E pra quem diz “você criticou e tal, por que não faz alguma coisa?” eu digo: quem disse que não tô fazendo? Só porque não publiquei não significa que eu não estou trabalhando em algo ;)

Palavras finais do autor:

Apesar de em momento algum eu ter atacado ou menosprezado o projeto elementary OS da elementary, Inc., os diversos apps citados ao longo do texto ou seus autores, venho ressaltar que não é o objetivo desse artigo, assim sendo qualquer impressão de ter causado a impressão de ter atacado qualquer um dos supracitados não foi intencional, a falta de citação de outros app e projeto se deve unicamente devido ao escopo do artigo e/ou seção, não significando que o autor menospreze ou despreze qualquer trabalho realizado por terceiros. O objetivo desse artigo é única e exclusivamente analisar como o conceito de software aplicativo, também conhecido como programas, aplicativos ou ainda como supracitadamente, apps, não foi pensado para serem estendidos ou para trabalhos em forma de fluxo

5 curtidas

Abordagem interessante. É possível reformular a maneira como usamos o computador.
Mas creio que em alguns casos é necessário que cada aplicativo tenha uma única função, pois ele poderá ser reutilizado por outros aplicativos ou quando preciso somente daquela funcionalidade específica e dessa forma não preciso abrir um programa complexo para obter a funcionalidade desejada.

Por exemplo, não é interessante rodar o Gimp exclusivamente para obter capturas de tela, ainda que ele tenha uma função específica para isso. Melhor é rodar um aplicativo específico para capturas de telas, exceto se eu desejo obter as funcionalidades de tratamento de imagens que o Gimp oferece.

Uma visão interessante, que poderia ser direcionado a automoveis, por exemplo.
Se comparar os primeiros automoveis com os atuais, veremos que basicamente são iguais, usam a mesma abordagem, com diferencial no avanço da tecnologia, isso inclui os eletricos também.
E porque não temos apenas um tipo de automovel para cada função (transportar pessoas(uso particular e/ou coletivo), transportar produtos, etc…?