An open API service indexing awesome lists of open source software.

https://github.com/mjun0812/chrome-vertical-tab-toggle-hammerspoon

Hammerspoon script to toggle Chrome's native vertical tab sidebar via keyboard shortcut or left-edge mouse hover (macOS)
https://github.com/mjun0812/chrome-vertical-tab-toggle-hammerspoon

chrome hammerspoon lua macos productivity vertical-tabs

Last synced: 10 days ago
JSON representation

Hammerspoon script to toggle Chrome's native vertical tab sidebar via keyboard shortcut or left-edge mouse hover (macOS)

Awesome Lists containing this project

README

          

# Chrome Vertical Tab Sidebar Toggle (Hammerspoon)

A [Hammerspoon](https://www.hammerspoon.org) script that toggles Chrome's **vertical tab sidebar** with a keyboard shortcut or by hovering the mouse at the left edge of the screen.

It drives Chrome through the macOS Accessibility API — no extension, no DevTools attachment, no JavaScript injection.

[日本語版 / Japanese version](./README_ja.md)

![demo](./assets/demo.gif)

## Features

- **Keyboard trigger** — toggle the sidebar with a keyboard shortcut (default: `Cmd+B`) while Chrome is the active window.
- **Mouse-edge trigger** — hovering the left edge of the Chrome window expands the sidebar; moving the cursor past the sidebar's right edge collapses it. Sidebars opened any other way (keyboard trigger, Chrome's own UI, etc.) are left alone.
- **Language-agnostic detection** — localized button labels pulled directly from the Chromium source are baked in, so the script works regardless of system language.
- **Multi-Chromium support** — Google Chrome, Beta, Canary, Dev, and Chromium are recognized by default. Add others via `TARGET_APPS`.
- **Robust lifecycle handling** — survives Chrome focus changes, launch / quit, and system sleep / wake. A watchdog automatically revives the mouse-edge feature if monitoring stops.
- **No shortcut hijacking** — key events are only intercepted while Chrome is the active window, so the shortcut keeps working in every other app.

## Requirements

- macOS
- [Hammerspoon](https://www.hammerspoon.org) (install via Homebrew: `brew install --cask hammerspoon`)
- Accessibility permission granted to Hammerspoon
(System Settings → Privacy & Security → Accessibility)
- **Google Chrome with vertical tabs enabled.** Right-click the tab bar and choose "Show tabs vertically", or enable the corresponding flag in `chrome://flags`.

## Quick Install

```bash
curl -fsSL https://raw.githubusercontent.com/mjun0812/chrome-vertical-tab-toggle-hammerspoon/main/install.sh | bash
```

- Downloads `chrome-vertical-tab-toggle.lua` to `~/.hammerspoon/chrome-vertical-tab-toggle.lua`.
- Appends `require("chrome-vertical-tab-toggle")` to `~/.hammerspoon/init.lua` (creates the file if missing).
- Backs up any pre-existing file as `*.backup-YYYYMMDD-HHMMSS`.

For non-interactive runs such as `curl ... | bash`, set `ASSUME_YES=1` to skip the "overwrite existing module?" confirmation prompt.

## Manual Install

1. Save this repo's `chrome-vertical-tab-toggle.lua` to `~/.hammerspoon/chrome-vertical-tab-toggle.lua`.
2. Add the following line to `~/.hammerspoon/init.lua` (create the file if it doesn't exist):

```lua
require("chrome-vertical-tab-toggle")
```

3. Open Hammerspoon and choose **Reload Config** (or press your reload shortcut).
4. The first time the script runs you may be prompted to grant Accessibility permission.

## Configuration

All tunables live at the top of `chrome-vertical-tab-toggle.lua`.

- **Shortcut**: `TOGGLE_MODS`, `TOGGLE_KEY`
- **Enable / disable a trigger**: `FEATURES`
- **Target apps**: `TARGET_APPS`
- **Reaction speed / sensitivity**: `EDGE`
- **Language coverage**: `SIDEBAR_LABELS` (add your language if it isn't already covered)
- **`GRACE` / `DELAY` / `WATCHDOG`**: rarely need to be touched

### 🚦 `FEATURES` — which triggers are active

| Field | Default | Meaning |
| ----------------- | ------- | ------------------------------------------------- |
| `keyboardToggle` | `true` | Set to `false` to disable the keyboard trigger. |
| `mouseEdgeToggle` | `true` | Set to `false` to disable the mouse-edge trigger. |

### 🔘 `TOGGLE_MODS` / `TOGGLE_KEY` — keyboard shortcut

| Field | Default | Meaning |
| ------------ | ------- | --------- |
| `cmd` | `true` | Cmd key |
| `ctrl` | `false` | Ctrl key |
| `alt` | `false` | Alt key |
| `shift` | `false` | Shift key |
| `TOGGLE_KEY` | `"b"` | Main key |

Match is **strict**: with the defaults, only plain `Cmd+B` fires — `Cmd+Shift+B` does not.

### 🌐 `TARGET_APPS` — which apps count as "Chrome"

Names of the apps for which the script should be active. Add the name of any Chromium-based browser you want to support.

### 🏷️ `SIDEBAR_LABELS` — localized button labels

Dictionary of localized strings for the sidebar toggle button.
It is sourced from Chromium's translation files (message IDs `IDS_EXPAND_VERTICAL_TABS` / `IDS_COLLAPSE_VERTICAL_TABS`) for about 80 locales.
Matching is case-insensitive.

- `collapsed`: labels shown when the sidebar is currently closed (e.g. English "Expand tabs", Japanese "タブを開く").
- `expanded`: labels shown when the sidebar is currently open (e.g. English "Collapse tabs", Japanese "タブを閉じる").

### 🖱️ `EDGE` — mouse-edge trigger

| Field | Default | Meaning |
| --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `enterPx` | `5` | How many pixels from the window's left edge count as "on the edge". |
| `waitSeconds` | `0.08` | Hover time before the sidebar expands. Lower = snappier but more prone to misfires. |
| `pollSeconds` | `0.05` | Mouse-position check interval. Lower = more responsive but more CPU. |
| `exitMarginPx` | `30` | How far past the sidebar's right edge the cursor must move to collapse it. Grazing the boundary doesn't close it. |
| `measureDelaySeconds` | `0.2` | Stabilization wait before measuring the sidebar's width after expand. |

### 🐶 `WATCHDOG` — auto-recovery monitoring

Auto-recovery settings for the mouse-edge feature in case it stops responding after events like a system wake. Usually no need to change.

| Field | Default | Meaning |
| ------------------ | ------- | ---------------------------------------------------------- |
| `intervalSeconds` | `2` | Health-check interval (seconds). |
| `heartbeatTimeout` | `5` | Seconds without a heartbeat before auto-recovery kicks in. |

### ⏸️ `GRACE` — trigger suppression windows

Suppression durations (seconds) that prevent accidental firing right after app switches, system wake, etc. Usually no need to change.

| Field | Default | Meaning |
| -------------- | ------- | ---------------------------------------------------- |
| `onActivate` | `0.3` | Suppression right after Chrome becomes active. |
| `onDeactivate` | `1` | Suppression right after Chrome stops being active. |
| `onLaunch` | `1.0` | Suppression right after Chrome launches. |
| `onWake` | `2.5` | Suppression right after the system wakes from sleep. |
| `onInit` | `2` | Suppression right after the script is loaded. |

### ⏱️ `DELAY` — start / stop timing

Delays (seconds) between lifecycle events and starting / stopping the feature. Usually no need to change.

| Field | Default | Meaning |
| --------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `startAfterActivate` | `0.2` | Delay between Chrome becoming active and starting the feature. |
| `stopAfterDeactivate` | `0.3` | Delay between Chrome being deactivated and stopping the feature. Prevents flicker if focus returns. |
| `restartAfterWake` | `2` | Delay between system wake and restarting the feature. |
| `restartGap` | `0.5` | Gap between stop and start during a restart. |
| `init` | `2` | Delay between script load and the initial start. |

## Troubleshooting

- **Pressing the keyboard shortcut does nothing.**
Check the Hammerspoon Console for a `Sidebar button … not found` warning. Make sure the vertical tab strip is actually enabled in Chrome.
- **The shortcut works but Chrome's own `Cmd+B` (bookmarks bar) also fires.**
This is expected — Chrome's built-in `Cmd+B` toggles the bookmarks bar. Change `TOGGLE_KEY` to something Chrome hasn't already bound.
- **A new Chrome locale isn't detected.**
Add the exact button label strings to `SIDEBAR_LABELS.collapsed` / `expanded`. When the button can't be found, a warning is logged at most once every 30 seconds.

## References

-
-