Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/i18n/en/desktop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const desktop = {
stoppedBody: (bot: string) => `${bot} cannot read or use your apps until you let it go on.`,
emptyTitle: (bot: string) => `${bot} has not used your desktop yet`,
emptyBody: "When it reads or uses a window of an app you allowed, the window shows here, live.",
shortcut: "Ctrl+Alt+End stops every bot on your desktop, even with Botloft closed.",
shortcut: "Ctrl+Alt+Esc stops every bot on your desktop, even with Botloft closed.",
waiting: "Waiting for the picture…",
read: "Read the window",
click: (target: string) => `Clicked "${target}"`,
Expand Down
2 changes: 1 addition & 1 deletion app/src/i18n/es/desktop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const desktop: Messages["desktop"] = {
emptyBody:
"Cuando lea o use una ventana de una app que permitiste, la ventana aparece aquí, en vivo.",
shortcut:
"Ctrl+Alt+Fin detiene a todos los bots en tu escritorio, incluso con Botloft cerrado.",
"Ctrl+Alt+Esc detiene a todos los bots en tu escritorio, incluso con Botloft cerrado.",
waiting: "Esperando la imagen…",
read: "Leyó la ventana",
click: (target) => `Hizo clic en "${target}"`,
Expand Down
2 changes: 1 addition & 1 deletion app/src/i18n/pt-BR/desktop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const desktop: Messages["desktop"] = {
emptyTitle: (bot) => `${bot} ainda não usou seu desktop`,
emptyBody:
"Quando ele ler ou usar uma janela de um app que você liberou, a janela aparece aqui, ao vivo.",
shortcut: "Ctrl+Alt+End para todos os bots no seu desktop, mesmo com o Botloft fechado.",
shortcut: "Ctrl+Alt+Esc para todos os bots no seu desktop, mesmo com o Botloft fechado.",
waiting: "Esperando a imagem…",
read: "Leu a janela",
click: (target) => `Clicou em "${target}"`,
Expand Down
2 changes: 1 addition & 1 deletion crates/botloftd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn run(paths: Paths, config: Config, config_path: PathBuf, scheduled: bool) -> a
});
// No bot process survived the last run, so nobody waits for these.
approvals::expire_all(&daemon);
// Ctrl+Alt+End stops every bot on the desktop, app open or not (spec 24.9).
// Ctrl+Alt+Esc stops every bot on the desktop, app open or not (spec 24.9).
let stopping = Arc::clone(&daemon);
match platform::desktop::on_stop_key(move || botloftd::service::desktop::stop_all(&stopping)) {
Ok(()) | Err(platform::desktop::DesktopError::Unavailable) => {}
Expand Down
2 changes: 2 additions & 0 deletions crates/botloftd/src/platform/desktop/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ mod tests {
"Alt+Tab",
"Alt+Shift+Tab",
"Alt+Esc",
// The owner's own key to stop every bot (spec 24.9).
"Ctrl+Alt+Esc",
"Ctrl+Esc",
"Ctrl+Alt+Delete",
"Ctrl+Alt+Del",
Expand Down
2 changes: 1 addition & 1 deletion crates/botloftd/src/platform/desktop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ pub fn windows() -> Result<Vec<Window>, DesktopError> {
}
}

/// Calls `stop` each time the owner presses Ctrl+Alt+End, from now on
/// Calls `stop` each time the owner presses Ctrl+Alt+Esc, from now on
/// (spec 24.9). Refused when another program holds the shortcut.
pub fn on_stop_key(stop: impl Fn() + Send + 'static) -> Result<(), DesktopError> {
#[cfg(windows)]
Expand Down
6 changes: 3 additions & 3 deletions crates/botloftd/src/platform/desktop/windows/stop_key.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! The shortcut that stops every bot on the desktop, Ctrl+Alt+End (spec
//! The shortcut that stops every bot on the desktop, Ctrl+Alt+Esc (spec
//! 24.9): registered for the whole session on a thread of its own, so it
//! works with the app closed.

use std::sync::mpsc;

use windows::Win32::UI::Input::KeyboardAndMouse::{
MOD_ALT, MOD_CONTROL, MOD_NOREPEAT, RegisterHotKey, VK_END,
MOD_ALT, MOD_CONTROL, MOD_NOREPEAT, RegisterHotKey, VK_ESCAPE,
};
use windows::Win32::UI::WindowsAndMessaging::{GetMessageW, MSG, WM_HOTKEY};

Expand All @@ -27,7 +27,7 @@ pub fn on_stop_key(stop: impl Fn() + Send + 'static) -> Result<(), DesktopError>
None,
STOP,
MOD_CONTROL | MOD_ALT | MOD_NOREPEAT,
u32::from(VK_END.0),
u32::from(VK_ESCAPE.0),
)
};
let ok = held.is_ok();
Expand Down
4 changes: 2 additions & 2 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -1760,11 +1760,11 @@ No servidor `botloft` (11), como as do navegador.

### 24.9 App

- **Painel "Desktop"** ao lado do chat, o quarto lugar do dock do computador do bot (navegador, terminal, arquivos e desktop, 15.1), com a mesma largura: a foto ao vivo da janela que o bot leu ou em que agiu por último, sobre a mesa na cor do bot, o nome do app e o título da janela, e a linha do que ele acabou de fazer, no idioma do dono ("Clicou em "Save"", "Escreveu em "Nome"", "Escolheu "Large"", "Leu a janela"). No cabeçalho, "Ao vivo" com a foto chegando e **Parar**; parado, o selo "Parado" e um aviso com **Deixar continuar**. Sem janela ainda, o painel explica que ela aparece ali quando o bot ler ou usar um app liberado. Embaixo, a dica do atalho Ctrl+Alt+End. As linhas das tools `desktop_*` no chat têm o botão de tela que abre o painel, como as do navegador abrem o dele.
- **Painel "Desktop"** ao lado do chat, o quarto lugar do dock do computador do bot (navegador, terminal, arquivos e desktop, 15.1), com a mesma largura: a foto ao vivo da janela que o bot leu ou em que agiu por último, sobre a mesa na cor do bot, o nome do app e o título da janela, e a linha do que ele acabou de fazer, no idioma do dono ("Clicou em "Save"", "Escreveu em "Nome"", "Escolheu "Large"", "Leu a janela"). No cabeçalho, "Ao vivo" com a foto chegando e **Parar**; parado, o selo "Parado" e um aviso com **Deixar continuar**. Sem janela ainda, o painel explica que ela aparece ali quando o bot ler ou usar um app liberado. Embaixo, a dica do atalho Ctrl+Alt+Esc. As linhas das tools `desktop_*` no chat têm o botão de tela que abre o painel, como as do navegador abrem o dele.
- **O que o daemon guarda** (`DesktopState`, em memória, por bot): a janela (`id`, título, app), a última ação (`DesktopAction`: clicar, escrever, escolher ou rolar, o nome do controle e a opção escolhida; nada depois de só ler), que o app diz no idioma do dono, quando foi, e se o dono o parou. Cada leitura, foto ou ação o atualiza e sai a notificação `desktop.changed` para todos os apps.
- **Foto ao vivo:** `desktop.watch {botId}` devolve o estado e a foto mais nova (`DesktopView`) e, enquanto alguma conexão assiste aquele bot, o daemon fotografa a janela dele quatro vezes por segundo (`PrintWindow`, como `desktop_screenshot`) e manda `desktop.frame` só quando a foto mudou, só para quem assiste, como os quadros do navegador (21.7): um app lento recebe a mais nova. Quando a última conexão para (`desktop.unwatch`, outro `desktop.watch` ou a conexão caindo), as fotos param.
- **Parar:** `desktop.stop {botId}` marca o bot como parado e `desktop.resume {botId}` o deixa continuar; os dois devolvem o `DesktopState`. Parado, toda tool `desktop_*` dele recusa, de novo depois de esperar o dono ou a vez no desktop, com o aviso de que o dono o parou e que ele deve contar no chat o que fazia. Uma ação já em andamento termina (ela dura no máximo 5 s, 24.5). Parado fica até o dono deixar continuar. Isso vive na memória: um daemon que reinicia começa com ninguém parado.
- **Parar tudo:** o atalho global `Ctrl+Alt+End`, que o daemon registra ao subir (`RegisterHotKey` num thread com fila própria, `MOD_NOREPEAT`), para todos os bots no desktop, mesmo com o app fechado. Se outro programa já tem o atalho (outro daemon do Botloft, de dev, por exemplo), o daemon avisa no log e segue sem ele.
- **Parar tudo:** o atalho global `Ctrl+Alt+Esc`, que o daemon registra ao subir (`RegisterHotKey` num thread com fila própria, `MOD_NOREPEAT`), para todos os bots no desktop, mesmo com o app fechado. Esc está em todo teclado, até nos compactos (60% e 70% não têm End), e o Windows não usa Ctrl+Alt+Esc (os dele são Ctrl+Shift+Esc, Alt+Esc e Ctrl+Esc); um bot não o aperta, porque Alt+Esc está entre as teclas do sistema (24.7). Se outro programa já tem o atalho (outro daemon do Botloft, de dev, por exemplo), o daemon avisa no log e segue sem ele.
- O cartão de permissão no chat (24.2) diz "<bot> quer ver <app>" com o ícone de tela, o porquê do bot ("<bot> diz: ..."), o caminho do executável e o que ver deixa fazer (ler as janelas do app e fotografá-las com o dono no computador, nunca senhas, e onde tirar). Respondido, vira uma linha: "<bot> pode ver <app>", "<bot> não pode ver <app>" com a nota, ou sem resposta. As tools `desktop_*` aparecem no chat com o ícone de tela e o porquê como resumo.

### 24.10 Permissões no app
Expand Down
Loading