Chrome extension that prevents tab switching during video playback or AI chatbot response generation.
Requirements: Chrome or Chromium-based browser
- Download or clone this repository
- Open
chrome://extensions/ - Enable Developer mode (top right)
- Click Load unpacked and select the
focus-guardfolder
When a video is playing or an AI is generating a response, you can't switch tabs. The extension silently keeps you on the locked tab until the action completes.
| Trigger | Behavior |
|---|---|
| Video playing | Tab locked (except YouTube Music) |
| AI generating | Tab locked until response completes |
| Tab switch attempt | Instantly returns to locked tab |
| Action completes | Tab automatically unlocks |
Click the Focus Guard icon in the toolbar to open the popup, where you can toggle each guard independently:
| Toggle | Description | Default |
|---|---|---|
| Video lock | Lock tab while videos play | On |
| AI lock | Lock tab while an AI generates a response | On |
Changes apply instantly — disabling a toggle releases its locks immediately, and re-enforcing resumes as soon as it's turned back on.
Works on any site with <video> elements, except music.youtube.com (so you can listen to music while working).
| Platform | URL |
|---|---|
| Claude | claude.ai |
| ChatGPT | chatgpt.com, chat.openai.com |
| Gemini | gemini.google.com |
| Perplexity | perplexity.ai |
| Grok | x.com/i/grok, grok.x.ai |
| Google AI Studio | aistudio.google.com |
The extension uses multiple strategies to detect when AI is generating:
| Method | Description |
|---|---|
| Stop button | Visible only during generation |
| Streaming indicators | DOM elements with streaming/loading classes |
| Disabled inputs | Send button disabled during processing |
| MutationObserver | Watches for DOM changes in real-time |
| Polling fallback | Checks every 300ms as backup |
focus-guard/
├── manifest.json # Extension configuration
├── background.js # Tab lock management
├── popup.html # Toolbar popup (toggles)
├── popup.js # Popup toggle logic
├── content-scripts/
│ ├── video-detector.js # Video playback detection
│ ├── claude-detector.js # Claude.ai
│ ├── chatgpt-detector.js # ChatGPT
│ ├── gemini-detector.js # Gemini
│ ├── perplexity-detector.js # Perplexity
│ ├── grok-detector.js # Grok
│ └── aistudio-detector.js # Google AI Studio
└── icons/
├── icon16.png
├── icon48.png
└── icon128.png
AI platforms frequently update their UI. If detection stops working:
- Open the AI site and trigger a response
- Open DevTools (
F12) → Elements tab - Look for the Stop button and note its selector
- Open an issue with the selector info
Create a new detector in content-scripts/ following the existing pattern:
(function() {
'use strict';
const POLLING_INTERVAL = 300;
let lastState = null;
function isGenerating() {
// Your detection logic here
return false;
}
function checkAndReport() {
const generating = isGenerating();
if (generating !== lastState) {
lastState = generating;
chrome.runtime.sendMessage({
type: 'LOCK_STATE_CHANGED',
source: 'your-site-name',
isLocked: generating
}).catch(() => {});
}
}
// MutationObserver + polling setup...
})();Then add the match pattern to manifest.json.
MIT