Skip to main content
Tabby includes comprehensive desktop automation capabilities that enable system-level control and window management. These features power the invisible typing, text capture, and window focus restoration that make Tabby feel like a natural extension of your operating system.

Core Technologies

Tabby’s desktop automation is built on two powerful libraries:
  • @nut-tree-fork/nut-js - Cross-platform keyboard and mouse automation
  • node-window-manager - Window management and focus control

Window Management

Active Window Capture

Tabby automatically captures the last active window before showing its interface, ensuring text is always pasted back to the correct application.
// frontend/electron/src/services/text-handler.ts:15
export async function captureLastActiveWindow(): Promise<void> {
  const activeWindow = windowManager.getActiveWindow();
  lastActiveWindowId = activeWindow?.id ?? null;
}

Focus Restoration

After processing text or accepting suggestions, Tabby seamlessly returns focus to your original application:
// frontend/electron/src/services/text-handler.ts:49
async function restoreFocusToLastWindow(): Promise<boolean> {
  if (lastActiveWindowId) {
    const targetWindow = windowManager
      .getWindows()
      .find((w) => w.id === lastActiveWindowId);
    
    if (targetWindow) {
      targetWindow.bringToTop();
      return true;
    }
  }
  return false;
}

Keyboard Automation

Text Capture

Tabby can capture selected text from any application using programmatic keyboard control:
1

Release Modifier Keys

Ensures no interfering key states from previous shortcuts
2

Simulate Ctrl+C

Programmatically copies selected text to clipboard
3

Extract and Restore

Reads the copied text and restores the original clipboard content
// frontend/electron/src/services/text-handler.ts:25
export async function captureSelectedText(): Promise<string> {
  const original = clipboard.readText();
  
  // Release modifiers
  await keyboard.releaseKey(Key.LeftAlt, Key.RightAlt, ...);
  
  // Copy selected text
  await keyboard.pressKey(Key.LeftControl);
  await keyboard.pressKey(Key.C);
  await keyboard.releaseKey(Key.C);
  await keyboard.releaseKey(Key.LeftControl);
  
  await new Promise(r => setTimeout(r, 150));
  
  const selected = clipboard.readText();
  clipboard.writeText(original); // Restore
  
  return selected;
}

Standard Paste Mode

The default output mode uses clipboard-based pasting:
// frontend/electron/src/services/text-handler.ts:64
export async function pasteToLastWindow(text: string): Promise<void> {
  const originalClipboard = clipboard.readText();
  
  await restoreFocusToLastWindow();
  
  clipboard.writeText(text);
  
  // Simulate Ctrl+V
  await keyboard.pressKey(Key.LeftControl);
  await keyboard.pressKey(Key.V);
  await keyboard.releaseKey(Key.V);
  await keyboard.releaseKey(Key.LeftControl);
  
  clipboard.writeText(originalClipboard);
}
Standard paste mode is fast and reliable, but some applications (like online coding platforms) may detect automated clipboard operations.

Configuration

Keyboard automation uses configurable timing to ensure compatibility across different applications:
keyboard.config.autoDelayMs = 5; // Minimal delay between key events

Global Shortcuts

Tabby’s automation powers these system-wide shortcuts:
ShortcutActionImplementation
Ctrl+\Capture text & open menucaptureLastActiveWindow() + captureSelectedText()
Ctrl+SpaceGet AI suggestioncaptureSelectedText() → AI → suggestion window
Shift+TabAccept ghost textsendTextToLastWindow() with selected mode
Shift+EscapeCancel typingImmediately stops all automation
Desktop automation requires appropriate system permissions. On Windows, Tabby may need to run with administrator privileges to control certain protected applications.

Text Output Modes

Tabby supports multiple output modes that can be configured in settings:
export type TextOutputMode = "paste" | "typewriter" | "typewriter-leetcode";

export async function sendTextToLastWindow(
  text: string,
  mode: TextOutputMode = "paste"
): Promise<void> {
  if (mode === "typewriter") {
    await typeSimpleToLastWindow(text);
  } else if (mode === "typewriter-leetcode") {
    await typeLeetCodeToLastWindow(text);
  } else {
    await pasteToLastWindow(text);
  }
}
See Typewriter Mode for details on undetectable character-by-character typing.

Emergency Stop

Tabby includes a panic button to immediately stop all automation:
let isTypingCancelled = false;

export function cancelTyping(): void {
  isTypingCancelled = true;
  console.log("Typing cancelled by user");
}
Press Shift+Escape at any time to cancel ongoing automation and hide all Tabby UI elements.

Build docs developers (and LLMs) love