Tungsten Edge 是一款原生 Swift 编写的 macOS 任务栏,把 Dock 按应用切换的逻辑改成按窗口切换。每个窗口在屏幕底部对应一张卡片,点击即可切换或最小化;单窗口应用收成紧凑图标,最小化的窗口卡片留在原位。它支持原生标签页合并、应用抽屉收纳、拖拽排序、类似 Dock 堆栈的文件夹固定、多显示器独立任务栏与边缘自动隐藏,并用毛玻璃外观贴合系统风格。窗口识别与卡片状态是工程重点,卡片不会跳动、闪烁或残留;全屏切换前会预先移出快照以避免闪帧。界面提供十种语言,需 macOS 12 及以上并授予辅助功能权限。
brew install --cask tungsten-edge![]()
A per-window taskbar for macOS — switch to any window in one click, Windows-style clarity without the clutter.
English · 中文
Ready-to-run builds live on the official website. This repository holds the source.

Open enough windows and every Mac user hits the same thing: getting back to that one window takes a search. Click a Dock icon and every window leaps out at once; the right-click list means open, find, pick — every time, in an order that keeps shifting. Anyone who has used Windows knows this could be a glance and a click.
Apple knows too: Mission Control and Stage Manager are their answers — but they tidy your desktop, not your switching. Tungsten Edge takes a different route: it brings "every window one click away" to the bottom of your Mac.
The drawer, unread badges for messaging apps, pinned folders, a taskbar on every display, blink-free full screen — all there; see the features below.
⌥⇧⌘D toggles between always-visible and your last auto-hide delay.Control-Command-F full-screen transition, Tungsten Edge moves its panels out of the transition snapshot. This is enabled by default and can be turned off in Settings.Note: the interface ships in ten languages — English, 简体中文, 繁體中文, 日本語, Deutsch, Français, Español, Português, Italiano and 한국어 (Spanish and Portuguese each in two regional variants) — and follows your system language. To pick one explicitly, use Settings ▸ General ▸ Language in Tungsten Edge.
Entering a native full-screen Space lets the system's transition snapshot catch the taskbar, which shows up as a one-frame blink. Removing it requires hiding the taskbar before your input reaches the target app, so Tungsten Edge observes global left-click, key-down and trackpad gesture events. It recognizes only these four:
Control-Command-F shortcutControl-Left / Control-Right (when switching into an adjacent full-screen Space)Ordinary input is not recorded, logged, modified, or sent anywhere. The listener is enabled by default; turn off Predict full-screen transitions to prevent taskbar flicker under Advanced in Settings to disable it completely.
Separately, when Reverse mouse scroll direction (Settings › General, off by default) is on, a second event tap watches scroll-wheel events and inverts the direction values of discrete mouse-wheel ones — that inversion is the whole feature; trackpad and Magic Mouse events pass through untouched, and nothing is recorded or sent anywhere. The tap exists only while the switch is on. Kill switch for diagnostics: launch with DOCK_SCROLL_REVERSER=0.
macOS suppresses key events from global event taps while Secure Input is active, such as in a protected password field. During that time the keyboard shortcuts cannot be recognized in advance; green-button and trackpad-gesture detection are unaffected.
.dmg from the official website.brew install --cask tungsten-edge
Tungsten Edge is in the official Homebrew cask registry. The older command
brew install --cask moonbai-studio/tungsten-edge/tungsten-edgestill works and installs the same official cask.
As of v0.9.0 Tungsten Edge is signed and notarized by Apple, so it opens with a plain double-click — no right-click workaround needed.
One step remains: Tungsten Edge needs Accessibility permission to read and manage your windows, and it guides you through this on first run:
Upgrading from v0.8.0 or earlier: v0.9.0 switched to a proper Developer ID signature, so macOS treats it as a different app and your old Accessibility grant no longer applies. Quit Tungsten Edge, select the old Tungsten Edge entry in the Accessibility list and remove it with the − button, then reopen Tungsten Edge and grant it again. One time only; future updates will not need this.
Preferences live in two places, and the split is deliberate: the status menu carries only what you flip mid-session, the settings window carries everything else.
Always Visible, 0.1s–3.0s, or Never Wake. The global ⌥⇧⌘D shortcut switches between always-visible and your last auto-hide delay; it is the Dock's ⌥⌘D plus Shift, which also releases the older ⌥⌘E back to Safari and Finder. You can record a different combination in Settings → General. If the shortcut cannot be registered, the menu simply stops showing the key hint.⌥⌘D belongs to macOS, so it is named here as plain text rather than claimed as a shortcut. Its slider sets the Dock's wake delay (Always Visible, 0.1s–3.0s, Never Wake — drag to Never Wake and the Dock stops popping up at the screen edge entirely). Moving it stages a draft and reveals a confirm row; nothing is written until you press it, because every write restarts the Dock and flashes the screen.Open it from Settings… in the status menu, or by right-clicking the drawer capsule at the right end of the taskbar. The window is organized as five toolbar tabs — General, Advanced, License, Feedback, About — and its title follows the selected tab. (⌘, does not work in normal operation: Tungsten Edge runs as a menu-bar app and has no menu bar of its own to hang it on.)
⌥⇧⌘D; Reset to Default brings it back). Combinations that would clash with macOS — ⌥⌘D, Option-only, Control-Option without Command — are rejected with an explanation, and if another app already owns the combination the previous shortcut stays active.Writing Dock preferences requires a non-sandboxed build, because sandboxed apps cannot write Dock preferences or restart Dock. Opening the settings pane works in either environment.
On first run, if the Dock is not already set to hide itself, Tungsten Edge offers three checkboxes — hide the Dock, use the scale minimize effect, and minimize windows into their app icon — all ticked, applied in one click. You will not see that prompt if you have already hidden the Dock; the rest of this section is the manual route.
If your Dock lives on the side or top of the screen, minimizing a window flies the animation toward the Dock — out of sync with this bottom taskbar. Move the Dock back to the bottom and set it to auto-hide; the minimize animation will then shrink toward the bottom, matching Tungsten Edge:
To keep the Dock from ever reappearing, drag the Dock slider in the status menu to Never Wake: hovering at the screen edge will no longer wake it.
Two more settings under System Settings → Desktop & Dock pair well with a bottom taskbar:
Issues vs Discussions — Issues are for bug reports and concrete feature requests. For questions about how to use Tungsten Edge, installation help or general discussion, please use Discussions.
Issues and discussions are answered in English and Chinese alike — write in whichever you prefer.
Discord — Join the server for announcements and support in English (Chinese is welcome too).
WeChat Group (for Chinese-speaking users)

The QR code is updated weekly. If it has expired, please leave a message in Issues and I'll renew it promptly.
Tungsten Edge recognizes and thanks the LINUX DO community for providing a place for discussion and feedback.
If Tungsten Edge is useful to you, a GitHub star still helps. Thanks to everyone who already starred: your stars got Tungsten Edge into the official Homebrew cask registry, so it now installs with brew install --cask tungsten-edge, no repository name to type.
Free today. From 1.0, Tungsten Edge is a one-time purchase — no subscription. Everyone who confirms their email on the founding-user list before then keeps it free forever.
Copyright (C) 2026 Moonbai Studio.
Tungsten Edge is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later). See LICENSE.
The application source code, build scripts, and assets required to build it are published in this repository. Code-signing certificates, notarization credentials, account credentials, and other secrets are not source code and are never included.
The license covers the source code; it does not require official signed/notarized binaries or related services to be provided free of charge.
The names "Tungsten Edge" and "钨极" and the logo are trademarks and are not covered by the GPL. Forks and self-built binaries must use a different name and icon — see TRADEMARK.md.
Release notes for every version are archived under Docs/Archive/Releases/.
Build & run (kills any running instance, builds Debug, re-signs, launches — never run a bare xcodebuild + open, the app's Accessibility grant follows the signing identity):
./Scripts/build_and_run.sh # dev loop
./Scripts/build_and_run.sh --lab # window-lab diagnostic CLI
Tests (1,300 XCTest cases, ~40 s; the same command CI runs on every push):
xcodebuild test -project macos-dock-cc-v2.xcodeproj -scheme macos-dock-cc-v2 \
-derivedDataPath build/DerivedData -destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO
python3 Scripts/check_localization.py # every String(localized:) has a zh-Hans entry
python3 Scripts/check_debug_switches.py # every DOCK_* env switch is registered
How the code is laid out — one Xcode target, four folders that only point downward:
| Folder | What lives there | Rule of thumb |
|---|---|---|
Core/ | Pure decisions: identity rules, placement, lifecycle planning, ~50 small …Decision / …Plan / …Policy types in Core/Support | No AppKit, no AX. If a behaviour can be expressed as a pure function of facts, it goes here and gets a unit test. |
Platform/ | The system adapters: Accessibility (AXWindowReader, AccessibilitySource), CoreGraphics window lists, the fullscreen / Spaces event taps, Finder | Talks to macOS, hands facts up to Core. AppTracker here is the single window-inventory authority. |
App/ | Composition and UI: AppDelegate wires the object graph, PanelCoordinator owns the five NSPanels, DockStripView renders the strip, the …Store classes persist user choices in UserDefaults | Big types are split by responsibility into Type+Topic.swift extension files. |
Tools/WindowLab/ | A replay CLI for window-identity scenarios; the old observation pipeline lives only here | Not part of the shipping app. |
Two habits keep it maintainable: decision logic is extracted into Core/Support before it is wired into a view or controller (that is why the test suite is large without a UI harness), and every DOCK_* environment switch is declared in Core/Support/DebugSwitch.swift with its polarity and purpose.
Signing. The Xcode project signs with a local certificate on purpose; the real Developer ID signature, hardened runtime, notarization and packaging happen in Scripts/package_release.sh (fail-closed: it will not produce dist/ unless every check passes). Scripts/install_local_release.sh installs the same signed build into /Applications for daily use.
Contributing. Open an issue first for anything beyond a small fix — the bug template asks for the details that make window-identification problems reproducible. English is the source language and the UI ships in twelve localizations; a new user-facing string needs a value in every one of them (Scripts/check_localization.py fails otherwise).
A note on the source comments. They are written in Chinese. Everything facing a user or a reporter — the UI strings, this README, the release notes, the issue templates — is bilingual, but the in-code rationale is not, and it is where most of the why lives. If a specific area blocks you, open an issue naming the files and I'll translate that part.
内容由编辑整理,部分信息来自 GitHub 与项目官网,版权归原作者所有。发现错误?报告问题