Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e45d64ee0 |
No files matched your search
@@ -41,8 +41,6 @@ A área de transferência pode ter senhas, tokens e dados pessoais, então o Cop
|
|||||||
pasta do Copiado são descartadas.
|
pasta do Copiado são descartadas.
|
||||||
- **Não usa rede** e não executa nada do que foi copiado.
|
- **Não usa rede** e não executa nada do que foi copiado.
|
||||||
|
|
||||||
Para apagar tudo, inclusive os fixados: `copiado esquecer`
|
|
||||||
|
|
||||||
O instalador confere o checksum SHA-256 do pacote antes de instalar, e a esteira
|
O instalador confere o checksum SHA-256 do pacote antes de instalar, e a esteira
|
||||||
de CI/CD roda o [Trivy](https://trivy.dev) (vulnerabilidades, segredos e configurações)
|
de CI/CD roda o [Trivy](https://trivy.dev) (vulnerabilidades, segredos e configurações)
|
||||||
em todo push, em toda release e toda segunda-feira. Os resultados ficam na aba
|
em todo push, em toda release e toda segunda-feira. Os resultados ficam na aba
|
||||||
@@ -54,16 +52,16 @@ em todo push, em toda release e toda segunda-feira. Os resultados ficam na aba
|
|||||||
curl -fsSL https://raw.githubusercontent.com/lucasrguerra/copiado/main/desinstalar.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/lucasrguerra/copiado/main/desinstalar.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
## Se algo der errado
|
## Comandos
|
||||||
|
|
||||||
- **Win+V não abre nada:** faça o Cinnamon recarregar os atalhos:
|
| Comando | Para quê |
|
||||||
```bash
|
|---|---|
|
||||||
gsettings set org.cinnamon.desktop.keybindings custom-list "[]"; gsettings set org.cinnamon.desktop.keybindings custom-list "['custom0']"
|
| `copiado consertar` | **Win+V não abre ou o histórico está vazio?** Recria o atalho, faz o Cinnamon recarregá-lo e inicia o app se estiver parado. |
|
||||||
```
|
| `copiado esquecer` | Apaga todo o histórico, inclusive os fixados. |
|
||||||
Se ainda assim não abrir, veja se outro atalho usa Win+V em
|
| `copiado ajuda` | Lista os comandos. |
|
||||||
*Configurações do Sistema → Teclado → Atalhos*.
|
|
||||||
- **Abre, mas o histórico está vazio:** o app pode não estar rodando. Rode
|
Se mesmo depois do `copiado consertar` o Win+V não abrir, veja se outro atalho usa
|
||||||
`copiado &`
|
Win+V em *Configurações do Sistema → Teclado → Atalhos*.
|
||||||
|
|
||||||
## Publicar uma versão nova
|
## Publicar uma versão nova
|
||||||
|
|
||||||
|
|||||||
+112
-4
@@ -2,9 +2,11 @@
|
|||||||
"""Copiado: histórico da área de transferência no estilo Windows 11 (Win+V).
|
"""Copiado: histórico da área de transferência no estilo Windows 11 (Win+V).
|
||||||
|
|
||||||
Uso:
|
Uso:
|
||||||
copiado.py inicia em segundo plano (vigia o Ctrl+C)
|
copiado inicia em segundo plano (vigia o Ctrl+C)
|
||||||
copiado.py show abre a janelinha do histórico
|
copiado show abre a janelinha do histórico
|
||||||
copiado.py esquecer apaga todo o histórico, inclusive os fixados
|
copiado esquecer apaga todo o histórico, inclusive os fixados
|
||||||
|
copiado consertar recria o atalho Win+V e inicia o app se estiver parado
|
||||||
|
copiado ajuda mostra esta ajuda
|
||||||
"""
|
"""
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
@@ -406,5 +408,111 @@ class App(Gtk.Application):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- comandos de manutenção (não abrem janela) ----------
|
||||||
|
ATALHOS = "org.cinnamon.desktop.keybindings"
|
||||||
|
CAMINHO_ATALHO = "/org/cinnamon/desktop/keybindings/custom-keybindings/{}/"
|
||||||
|
|
||||||
|
|
||||||
|
def gsettings(*args):
|
||||||
|
return subprocess.run(["gsettings", *args], capture_output=True,
|
||||||
|
text=True, check=True).stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
|
def ler_lista(valor):
|
||||||
|
# gsettings devolve algo como "['custom0']" ou "@as []"
|
||||||
|
return json.loads(valor.replace("@as ", "").replace("'", '"'))
|
||||||
|
|
||||||
|
|
||||||
|
def esquema(ident):
|
||||||
|
return f"{ATALHOS}.custom-keybinding:" + CAMINHO_ATALHO.format(ident)
|
||||||
|
|
||||||
|
|
||||||
|
def configurar_atalho():
|
||||||
|
"""Cria (ou corrige) o atalho Win+V e faz o Cinnamon recarregá-lo."""
|
||||||
|
lista = ler_lista(gsettings("get", ATALHOS, "custom-list"))
|
||||||
|
ident = next((i for i in lista
|
||||||
|
if gsettings("get", esquema(i), "binding") == "['<Super>v']"), None)
|
||||||
|
if ident is None:
|
||||||
|
ident = next(f"custom{n}" for n in range(1000) if f"custom{n}" not in lista)
|
||||||
|
lista.append(ident)
|
||||||
|
gsettings("set", esquema(ident), "name", "Copiado")
|
||||||
|
gsettings("set", esquema(ident), "command", "copiado show")
|
||||||
|
gsettings("set", esquema(ident), "binding", "['<Super>v']")
|
||||||
|
# o Cinnamon só relê os atalhos quando a lista muda
|
||||||
|
gsettings("set", ATALHOS, "custom-list", "[]")
|
||||||
|
time.sleep(0.5)
|
||||||
|
gsettings("set", ATALHOS, "custom-list", json.dumps(lista).replace('"', "'"))
|
||||||
|
return ident
|
||||||
|
|
||||||
|
|
||||||
|
def remover_atalho():
|
||||||
|
lista = ler_lista(gsettings("get", ATALHOS, "custom-list"))
|
||||||
|
nossos = [i for i in lista if "copiado" in gsettings("get", esquema(i), "command")]
|
||||||
|
for ident in nossos:
|
||||||
|
gsettings("reset-recursively", esquema(ident))
|
||||||
|
restantes = [i for i in lista if i not in nossos]
|
||||||
|
gsettings("set", ATALHOS, "custom-list", json.dumps(restantes).replace('"', "'"))
|
||||||
|
|
||||||
|
|
||||||
|
def esta_rodando():
|
||||||
|
bus = Gio.bus_get_sync(Gio.BusType.SESSION)
|
||||||
|
resp = bus.call_sync("org.freedesktop.DBus", "/org/freedesktop/DBus",
|
||||||
|
"org.freedesktop.DBus", "NameHasOwner",
|
||||||
|
GLib.Variant("(s)", ("io.github.copiado",)),
|
||||||
|
GLib.VariantType("(b)"), Gio.DBusCallFlags.NONE, -1, None)
|
||||||
|
return resp.unpack()[0]
|
||||||
|
|
||||||
|
|
||||||
|
def iniciar_em_segundo_plano():
|
||||||
|
subprocess.Popen([sys.executable, os.path.realpath(__file__)],
|
||||||
|
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL, start_new_session=True)
|
||||||
|
for _ in range(30):
|
||||||
|
time.sleep(0.2)
|
||||||
|
if esta_rodando():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def consertar():
|
||||||
|
try:
|
||||||
|
ident = configurar_atalho()
|
||||||
|
print(f"✓ Atalho Win+V configurado e recarregado ({ident}).")
|
||||||
|
except (OSError, subprocess.CalledProcessError) as erro:
|
||||||
|
print(f"✗ Não consegui configurar o atalho: {erro}")
|
||||||
|
return 1
|
||||||
|
if esta_rodando():
|
||||||
|
print("✓ O Copiado já está rodando.")
|
||||||
|
elif iniciar_em_segundo_plano():
|
||||||
|
print("✓ O Copiado estava parado e foi iniciado.")
|
||||||
|
else:
|
||||||
|
print("✗ Não consegui iniciar o Copiado. Rode 'copiado' para ver o erro.")
|
||||||
|
return 1
|
||||||
|
print("Pronto! Aperte Win+V.")
|
||||||
|
print("Se ainda não abrir, veja se outro atalho usa Win+V em")
|
||||||
|
print("Configurações do Sistema → Teclado → Atalhos.")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
comando = argv[1] if len(argv) > 1 else ""
|
||||||
|
if comando in ("ajuda", "-h", "--help"):
|
||||||
|
print(__doc__.strip())
|
||||||
|
return 0
|
||||||
|
if comando == "consertar":
|
||||||
|
return consertar()
|
||||||
|
if comando == "instalar-atalho":
|
||||||
|
configurar_atalho()
|
||||||
|
return 0
|
||||||
|
if comando == "remover-atalho":
|
||||||
|
remover_atalho()
|
||||||
|
return 0
|
||||||
|
if comando not in ("", "show", "esquecer"):
|
||||||
|
print(f"Comando desconhecido: {comando}\n")
|
||||||
|
print(__doc__.strip())
|
||||||
|
return 2
|
||||||
|
return App().run(argv)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(App().run(sys.argv))
|
sys.exit(main(sys.argv))
|
||||||
+1
-10
@@ -1,15 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Remove o Copiado e o atalho Win+V
|
# Remove o Copiado e o atalho Win+V
|
||||||
BASE=org.cinnamon.desktop.keybindings
|
command -v copiado >/dev/null && copiado remover-atalho
|
||||||
LISTA=$(gsettings get $BASE custom-list)
|
|
||||||
for ID in $(python3 -c "import ast,sys; print(' '.join(ast.literal_eval(sys.argv[1].replace('@as ',''))))" "$LISTA"); do
|
|
||||||
SCHEMA="$BASE.custom-keybinding:/org/cinnamon/desktop/keybindings/custom-keybindings/$ID/"
|
|
||||||
if gsettings get "$SCHEMA" command | grep -q copiado; then
|
|
||||||
LISTA=$(python3 -c "import ast,sys; l=ast.literal_eval(sys.argv[1].replace('@as ','')); print([x for x in l if x!='$ID'])" "$LISTA")
|
|
||||||
gsettings set $BASE custom-list "$LISTA"
|
|
||||||
gsettings reset-recursively "$SCHEMA"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
pkill -f "/usr/bin/copiado" 2>/dev/null
|
pkill -f "/usr/bin/copiado" 2>/dev/null
|
||||||
sudo apt-get remove -y copiado
|
sudo apt-get remove -y copiado
|
||||||
rm -rf "$HOME/.local/share/copiado"
|
rm -rf "$HOME/.local/share/copiado"
|
||||||
|
|||||||
+3
-25
@@ -2,7 +2,6 @@
|
|||||||
# Instala (ou atualiza) o Copiado a partir do pacote publicado no GitHub
|
# Instala (ou atualiza) o Copiado a partir do pacote publicado no GitHub
|
||||||
set -e
|
set -e
|
||||||
URL="https://github.com/lucasrguerra/copiado/releases/latest/download"
|
URL="https://github.com/lucasrguerra/copiado/releases/latest/download"
|
||||||
BASE=org.cinnamon.desktop.keybindings
|
|
||||||
TMP=$(mktemp -d)
|
TMP=$(mktemp -d)
|
||||||
trap 'rm -rf "$TMP"' EXIT
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
@@ -34,31 +33,10 @@ if [ -f "$HOME/.local/share/clipboard-winv/historico.json" ]; then
|
|||||||
rm -rf "$HOME/.local/share/clipboard-winv"
|
rm -rf "$HOME/.local/share/clipboard-winv"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "==> Criando atalho Win+V..."
|
echo "==> Criando atalho Win+V e iniciando..."
|
||||||
LISTA=$(gsettings get $BASE custom-list)
|
pkill -f "/usr/bin/copiado" 2>/dev/null || true
|
||||||
ID=""
|
|
||||||
for i in $(python3 -c "import ast,sys; print(' '.join(ast.literal_eval(sys.argv[1].replace('@as ',''))))" "$LISTA"); do
|
|
||||||
B=$(gsettings get "$BASE.custom-keybinding:/org/cinnamon/desktop/keybindings/custom-keybindings/$i/" binding)
|
|
||||||
[ "$B" = "['<Super>v']" ] && ID=$i && break
|
|
||||||
done
|
|
||||||
if [ -z "$ID" ]; then
|
|
||||||
for i in $(seq 0 99); do
|
|
||||||
echo "$LISTA" | grep -q "'custom$i'" || { ID="custom$i"; break; }
|
|
||||||
done
|
|
||||||
LISTA=$(python3 -c "import ast,sys; l=ast.literal_eval(sys.argv[1].replace('@as ','')); l.append('$ID'); print(l)" "$LISTA")
|
|
||||||
fi
|
|
||||||
SCHEMA="$BASE.custom-keybinding:/org/cinnamon/desktop/keybindings/custom-keybindings/$ID/"
|
|
||||||
gsettings set "$SCHEMA" name "Copiado"
|
|
||||||
gsettings set "$SCHEMA" command "copiado show"
|
|
||||||
gsettings set "$SCHEMA" binding "['<Super>v']"
|
|
||||||
# só agora registra a lista (e força o Cinnamon a recarregar os atalhos)
|
|
||||||
gsettings set $BASE custom-list "[]"
|
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
gsettings set $BASE custom-list "$LISTA"
|
copiado consertar >/dev/null
|
||||||
|
|
||||||
echo "==> Iniciando..."
|
|
||||||
pkill -x copiado 2>/dev/null || pkill -f "/usr/bin/copiado" 2>/dev/null || true
|
|
||||||
setsid copiado >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Pronto! Versão instalada: $(dpkg-query -W -f='${Version}' copiado). Aperte Win+V."
|
echo "Pronto! Versão instalada: $(dpkg-query -W -f='${Version}' copiado). Aperte Win+V."
|
||||||
Reference in new issue
Block a user