diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 05c2f96..38f78f3 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -7,9 +7,9 @@ on: - "DemoLab/**" - "Localization/**" - "docs/**" - - "README*.md" - - "NOTICE*.md" - - "THIRD_PARTY_NOTICES*.md" + - "README.md" + - "NOTICE.md" + - "THIRD_PARTY_NOTICES.md" - "web/**" - ".github/workflows/tools.yml" workflow_dispatch: diff --git a/DemoLab/README.md b/DemoLab/README.md index 9643640..7edc45a 100644 --- a/DemoLab/README.md +++ b/DemoLab/README.md @@ -1,5 +1,5 @@ -[English](README.md) · [한국어](ko/README.md) · [日本語](ja/README.md) · [简体中文](zh-Hans/README.md) · [繁體中文](zh-Hant/README.md) +[English](README.md) · [한국어](docs/ko/README.md) · [日本語](docs/ja/README.md) · [简体中文](docs/zh-Hans/README.md) · [繁體中文](docs/zh-Hant/README.md) # Tatami Demo Lab @@ -123,6 +123,8 @@ the image, with a chapter label at the upper left and actual keystrokes at the upper right. Translucent backgrounds keep text readable over light and dark apps. The colors come from the website palette; changing presentation needs no new capture. +Poster frames use `posterSeconds` or `posterCaptionIndex` from `publication.json`. Choose a frame after the feature has taken effect. Poster URLs use the image hash so replacing a still does not require re-encoding its video. + Caption edits may reuse an original only when every recorded action, typed input, assertion and delay is unchanged. The exporter verifies the frozen scene hash and compares those actions before replacing narration on the original timeline. diff --git a/DemoLab/docs/SCENES.md b/DemoLab/docs/SCENES.md index db2a7d2..cfef2b5 100644 --- a/DemoLab/docs/SCENES.md +++ b/DemoLab/docs/SCENES.md @@ -55,8 +55,8 @@ a reason to correct preparation, not to trim away the unexpected window later. | `virtualDisplay` | `connected` | Connect or disconnect the real guest virtual display helper. | | `configure` | `field`, `value` | Atomically edit an allowed live setting in the lab TOML. | | `clipboard` | `text` | Provide local example text, preserving and restoring all clipboard item types. | -| `closeSettings` | — | Close the native settings window after authoring. | -| `prepareSettings` | — | Size and position the native Tatami settings window before its controls are used. | +| `closeSettings` | No fields | Close the native settings window after authoring. | +| `prepareSettings` | No fields | Size and position the native Tatami settings window before its controls are used. | | `appWindows` | `app`, `count` | Set native window count, primarily for preparation. | There is no `appState` command. Views cannot be jumped to a pre-rendered success diff --git a/DemoLab/ja/README.md b/DemoLab/docs/ja/README.md similarity index 92% rename from DemoLab/ja/README.md rename to DemoLab/docs/ja/README.md index 2879e96..8169807 100644 --- a/DemoLab/ja/README.md +++ b/DemoLab/docs/ja/README.md @@ -1,5 +1,5 @@ -[English](../README.md) · [한국어](../ko/README.md) · [日本語](README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) @@ -10,11 +10,11 @@ ## 公開用動画の規則 -[`publication.json`](../publication.json) が一覧と編集上限です。各場面を Web の区分に結び、時間とサイズを制限します。 +[`publication.json`](../../publication.json) が一覧と編集上限です。各場面を Web の区分に結び、時間とサイズを制限します。 紹介動画はデザイン、執筆、レビュー、借りる操作、自動化から、実際の画面構成変更まで進みます。各動画集では作業、プロファイルと画面、配置とフォーカス、借りる操作、表示方法、CLI・フック、ガイドを扱います。一覧は `publication.json` から生成します。 -主動画は**作業を変えても元の場所に戻れる**ことを示します。機能別は別の活動を扱い、同じ動画を繰り返しません。[範囲と検証の境界](../docs/ja/COVERAGE.md)を参照してください。 +主動画は**作業を変えても元の場所に戻れる**ことを示します。機能別は別の活動を扱い、同じ動画を繰り返しません。[範囲と検証の境界](COVERAGE.md)を参照してください。 ## 録画 → 書き出し → 確認 → ローカル反映 @@ -85,6 +85,8 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 元の MOV には、撮影したデスクトップ全体が含まれます。書き出しは 1920×1200、2 画面の場合は 1920×600 です。説明字幕は映像の下部、章名は左上、実際のキー入力は右上に重ねます。半透明の背景により、明るいアプリでも暗いアプリでも読みやすくなります。色はウェブサイトの配色を使うため、表示の変更に再撮影は必要ありません。 +サムネイルの時点は、`publication.json` の `posterSeconds` または `posterCaptionIndex` で指定します。機能が実際に反映された後のフレームを選んでください。サムネイルの URL には画像のハッシュを使うため、画像だけを差し替える場合に動画を再エンコードする必要はありません。 + 字幕の編集で元映像を再利用できるのは、撮影した操作、入力内容、検証条件、待機時間がすべて同じ場合だけです。書き出しツールは撮影時に固定したシーンのハッシュと操作を検証し、元のタイムライン上の説明文を差し替えます。検証資料には、編集前後のシーンとタイムラインを両方含めます。 各テイクには次のファイルがあります。 @@ -99,7 +101,7 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 書き出しには再生ギャラリー、ポスター、検証用フレーム、元映像と出力のハッシュ、すべての付随ファイルが含まれます。自動検証だけでは実際の動作確認を代替できません。特に共有ウインドウのミラーリングとフォーカス先は目視確認が必要です。ウェブプレイヤーは標準コントロールと `preload="none"` を使い、手動で再生し、同時に再生する動画は一つです。各動画集にはサムネイル一覧、件数、前後のボタンがあります。各動画から関連する設定キーにも移動できます。矢印キー、Home/End、個別動画へのリンクは、一覧を別途展開せずに使えます。 -2 画面ではゲストに実際の仮想画面を接続し、別々に録画して最初の時刻で揃えます。[確認済み構成](../docs/ja/MULTI-DISPLAY.md)を参照してください。 +2 画面ではゲストに実際の仮想画面を接続し、別々に録画して最初の時刻で揃えます。[確認済み構成](MULTI-DISPLAY.md)を参照してください。 ## 一つの場面を調整する @@ -132,10 +134,10 @@ DEMOLAB_LOCALIZATION_DIR="$PWD/DemoLab/.build/DemoLab/Localization" \ swift test --package-path DemoLab ``` -- [場面の語彙](../docs/ja/SCENES.md) -- [VM の準備](../docs/ja/VM-TART.md) -- [権限](../docs/ja/PERMISSIONS.md) -- [実際の複数画面録画](../docs/ja/MULTI-DISPLAY.md) +- [場面の語彙](SCENES.md) +- [VM の準備](VM-TART.md) +- [権限](PERMISSIONS.md) +- [実際の複数画面録画](MULTI-DISPLAY.md) ## 5 言語での制作 diff --git a/DemoLab/docs/ja/SCENES.md b/DemoLab/docs/ja/SCENES.md index 53362f9..9d6b6d0 100644 --- a/DemoLab/docs/ja/SCENES.md +++ b/DemoLab/docs/ja/SCENES.md @@ -48,8 +48,8 @@ |`virtualDisplay`|`connected`|ゲストの実際の仮想画面ヘルパーを接続・切断します。| |`configure`|`field`, `value`|ラボの TOML で許可された設定を原子的に変更します。| |`clipboard`|`text`|クリップボードの全形式を保存・復元し、例文を渡します。| -|`closeSettings`|—|編集後に設定ウインドウを閉じます。| -|`prepareSettings`|—|コントロールを操作する前に、Tatami のネイティブ設定ウインドウのサイズと位置を整えます。| +|`closeSettings`|フィールドなし|編集後に設定ウインドウを閉じます。| +|`prepareSettings`|フィールドなし|コントロールを操作する前に、Tatami のネイティブ設定ウインドウのサイズと位置を整えます。| |`appWindows`|`app`, `count`|主に準備時に、実際のウインドウ数を設定します。| `appState` はありません。用意した成功画面へ飛ばず、通常の操作と `StoryRepository` で文章、レビュー、チェック、タスク、会話を同じ場所に保存します。`seed` でだけ初期化し、作業の切り替えでは戻しません。会話はネット接続のないローカル例です。 @@ -88,4 +88,4 @@ `take` の既定値は `--overlay off` で、テキストは編集可能な ASS と JSON のサイドカーファイルに記録します。書き出した映像では、画面下部に字幕、左上にチャプター、右上に実際のキー入力を重ねます。半透明の背景で読みやすくしていますが、アプリの内容に重なるため、重要なコントロールはその領域を避けて配置してください。`scene` はライブのリハーサルパネルを使い、最終映像とは表示方法が異なります。 -配置と時間・容量上限は [publication.json](../../publication.json)、録画・出力・確認のコマンドは [README.md](../../ja/README.md) を参照してください。 +配置と時間・容量上限は [publication.json](../../publication.json)、録画・出力・確認のコマンドは [README.md](README.md) を参照してください。 diff --git a/DemoLab/ko/README.md b/DemoLab/docs/ko/README.md similarity index 93% rename from DemoLab/ko/README.md rename to DemoLab/docs/ko/README.md index 41f2782..c91da93 100644 --- a/DemoLab/ko/README.md +++ b/DemoLab/docs/ko/README.md @@ -1,5 +1,5 @@ -[English](../README.md) · [한국어](README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) +[English](../../README.md) · [한국어](README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) @@ -10,11 +10,11 @@ ## 공개용 영상 규칙 -[`publication.json`](../publication.json)에 영상 목록과 편집 예산을 정해요. 각 장면을 웹 섹션에 연결하고 길이와 파일 크기를 제한해요. +[`publication.json`](../../publication.json)에 영상 목록과 편집 예산을 정해요. 각 장면을 웹 섹션에 연결하고 길이와 파일 크기를 제한해요. 종합 영상은 디자인 → 글쓰기 → 검토 → 빌려오기 → 자동화에 이어 실제 화면 구성 변경으로 끝나요. 기능별 모음은 작업 공간, 프로필·화면, 타일링·포커스, 빌려오기, 창 표시, CLI·훅, 가이드 설정을 다뤄요. 목록은 `publication.json`에서 만들므로 별도로 중복 관리하지 않아요. -종합 영상은 **작업을 바꿔도 하던 자리를 유지한다**는 약속을 보여줘요. 기능별 영상은 다른 활동을 보여주며 종합 영상을 반복하지 않아요. 전체 범위는 [기능과 검증 범위](../docs/ko/COVERAGE.md)에서 확인해요. +종합 영상은 **작업을 바꿔도 하던 자리를 유지한다**는 약속을 보여줘요. 기능별 영상은 다른 활동을 보여주며 종합 영상을 반복하지 않아요. 전체 범위는 [기능과 검증 범위](COVERAGE.md)에서 확인해요. ## 촬영 → 내보내기 → 검수 → 로컬 반영 @@ -85,6 +85,8 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 원본 MOV에는 촬영한 데스크톱 전체가 담겨요. 내보낼 때는 1920×1200을 유지하고, 두 화면 영상은 1920×600으로 만들어요. 자막은 영상 아래쪽에, 장면 이름은 왼쪽 위에, 실제 키 입력은 오른쪽 위에 겹쳐 표시해요. 반투명 배경으로 밝거나 어두운 앱 위에서도 읽기 쉽게 했어요. 색상은 웹사이트 팔레트를 사용하므로 표현을 바꿀 때 다시 촬영할 필요는 없어요. +썸네일 시점은 `publication.json`의 `posterSeconds` 또는 `posterCaptionIndex`로 정해요. 기능이 실제로 적용된 뒤의 장면을 선택해요. 썸네일 URL에는 이미지 해시를 사용하므로 이미지만 교체할 때 영상을 다시 인코딩할 필요가 없어요. + 자막만 고칠 때는 촬영한 동작, 입력 내용, 검증 조건, 대기 시간이 모두 같아야 원본을 재사용할 수 있어요. 내보내기 도구는 촬영 당시 고정한 장면 파일의 해시와 동작을 검증한 뒤 원래 타임라인의 자막을 교체해요. 증거 자료에는 원본과 수정본의 장면 파일 및 타임라인을 모두 포함해요. 각 테이크에는 다음 파일이 있어요. @@ -99,7 +101,7 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 내보내기 묶음에는 재생 갤러리, 포스터, 추출한 검증 프레임, 원본·결과물 해시와 모든 부가 파일이 들어 있어요. 자동 검증이 실제 동작 확인을 대신하지는 않아요. 특히 공용 창 미러링과 포커스 대상은 화면으로 확인해야 해요. 웹 플레이어는 기본 컨트롤과 `preload="none"`를 사용하며, 직접 재생하고 한 번에 영상 하나만 재생돼요. 각 모음에는 썸네일 목록, 개수, 이전·다음 버튼이 있어요. 영상마다 관련 설정 키로 가는 링크도 제공해요. 방향키, Home/End, 개별 영상 링크는 별도 펼치기 없이 사용할 수 있어요. -두 화면 촬영은 게스트에 실제 가상 디스플레이를 연결하고 각각 녹화한 뒤 첫 프레임 시각으로 맞춰요. [확인한 VM 구성](../docs/ko/MULTI-DISPLAY.md)을 참고하세요. +두 화면 촬영은 게스트에 실제 가상 디스플레이를 연결하고 각각 녹화한 뒤 첫 프레임 시각으로 맞춰요. [확인한 VM 구성](MULTI-DISPLAY.md)을 참고하세요. ## 장면 하나 수정하기 @@ -132,10 +134,10 @@ DEMOLAB_LOCALIZATION_DIR="$PWD/DemoLab/.build/DemoLab/Localization" \ swift test --package-path DemoLab ``` -- [장면 문법](../docs/ko/SCENES.md) -- [VM 설정](../docs/ko/VM-TART.md) -- [권한](../docs/ko/PERMISSIONS.md) -- [실제 두 화면 촬영](../docs/ko/MULTI-DISPLAY.md) +- [장면 문법](SCENES.md) +- [VM 설정](VM-TART.md) +- [권한](PERMISSIONS.md) +- [실제 두 화면 촬영](MULTI-DISPLAY.md) ## 다섯 언어 영상 제작 diff --git a/DemoLab/docs/ko/SCENES.md b/DemoLab/docs/ko/SCENES.md index 2b8f913..4f9242e 100644 --- a/DemoLab/docs/ko/SCENES.md +++ b/DemoLab/docs/ko/SCENES.md @@ -48,8 +48,8 @@ |`virtualDisplay`|`connected`|게스트의 실제 가상 화면 도구를 연결하거나 해제해요.| |`configure`|`field`, `value`|실험용 TOML의 허용한 설정을 원자적으로 바꿔요.| |`clipboard`|`text`|클립보드의 모든 데이터 형식을 백업·복원하며 예시 텍스트를 제공해요.| -|`closeSettings`|—|편집 뒤 네이티브 설정 창을 닫아요.| -|`prepareSettings`|—|컨트롤을 조작하기 전에 Tatami 설정 창의 크기와 위치를 맞춰요.| +|`closeSettings`|필드 없음|편집 뒤 네이티브 설정 창을 닫아요.| +|`prepareSettings`|필드 없음|컨트롤을 조작하기 전에 Tatami 설정 창의 크기와 위치를 맞춰요.| |`appWindows`|`app`, `count`|주로 준비 단계에서 실제 창 수를 정해요.| `appState` 명령은 없어요. 미리 만든 성공 화면으로 이동하지 않고 일반 컨트롤과 `StoryRepository`로 저장한 작업을 공유해요. 문구·검토·검사·할 일·메시지는 같은 제어 폴더에 저장해요. `seed`만 이야기를 초기화하고 공간 전환은 초기화하지 않아요. 대화는 네트워크 없는 로컬 데모예요. @@ -88,4 +88,4 @@ `take`의 기본값은 `--overlay off`이며, 텍스트는 편집 가능한 ASS와 JSON 부가 파일에 기록해요. 내보낸 영상은 화면 아래쪽에 자막을, 왼쪽 위에 챕터를, 오른쪽 위에 실제 키 입력을 겹쳐 보여줘요. 반투명 배경으로 가독성을 높이지만 앱 내용을 가릴 수 있으므로 중요한 컨트롤은 해당 영역을 피해서 배치해요. `scene`는 실시간 리허설 패널을 사용하며, 최종 영상의 표시 방식과는 달라요. -배치 위치와 시간·용량 예산은 [publication.json](../../publication.json), 촬영·출력·검수 명령은 [README.md](../../ko/README.md)를 참고하세요. +배치 위치와 시간·용량 예산은 [publication.json](../../publication.json), 촬영·출력·검수 명령은 [README.md](README.md)를 참고하세요. diff --git a/DemoLab/zh-Hans/README.md b/DemoLab/docs/zh-Hans/README.md similarity index 93% rename from DemoLab/zh-Hans/README.md rename to DemoLab/docs/zh-Hans/README.md index d30332f..92142bb 100644 --- a/DemoLab/zh-Hans/README.md +++ b/DemoLab/docs/zh-Hans/README.md @@ -1,5 +1,5 @@ -[English](../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](README.md) · [繁體中文](../zh-Hant/README.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](README.md) · [繁體中文](../zh-Hant/README.md) @@ -10,11 +10,11 @@ ## 发布约定 -[`publication.json`](../publication.json) 定义视频清单和编辑预算,映射网站区块并限制时长和文件大小。 +[`publication.json`](../../publication.json) 定义视频清单和编辑预算,映射网站区块并限制时长和文件大小。 主视频依次展示设计、写作、评审、借用、自动化,最后实际改变显示器拓扑。专题涵盖工作区、配置方案与显示器、平铺与焦点、借用、窗口模式、CLI/钩子和引导设置。清单由 `publication.json` 生成,无需维护重复列表。 -主视频传达**切换任务,保留工作位置**。专题展示不同活动,不重复主视频。完整范围见[覆盖与证据边界](../docs/zh-Hans/COVERAGE.md)。 +主视频传达**切换任务,保留工作位置**。专题展示不同活动,不重复主视频。完整范围见[覆盖与证据边界](COVERAGE.md)。 ## 录制 → 导出 → 检查 → 本地安装 @@ -85,6 +85,8 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 原始 MOV 包含完整的桌面画面。导出保留 1920×1200 分辨率,双屏视频为 1920×600。说明字幕叠加在画面下方,章节名称位于左上角,实际按键位于右上角。半透明背景确保文字在深浅色应用上都清晰可读。颜色来自网站配色,调整呈现方式无需重新录制。 +缩略图时间由 `publication.json` 中的 `posterSeconds` 或 `posterCaptionIndex` 指定。请选择功能实际生效后的画面。缩略图 URL 使用图片哈希,因此仅替换图片时无需重新编码视频。 + 仅修改字幕时,只有录制的操作、输入内容、断言和等待时间均未改变,才可复用原始视频。导出工具会验证录制时冻结的场景哈希并比较操作,然后替换原时间线上的说明文字。证据资料同时保留原始和编辑后的场景及时间线。 每次录制包含: @@ -99,7 +101,7 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 导出包包含播放图库、海报、抽样验证帧、原始与输出文件的哈希及所有附属文件。自动验收不能替代观看实际操作,尤其是共享窗口镜像和焦点目标仍需目视确认。网页播放器使用原生控件和 `preload="none"`,由用户主动播放,且一次只播放一个视频。每个视频集提供缩略图列表、数量和前后按钮。每个视频还链接到相关配置键。方向键、Home/End 和单独视频链接无需展开额外面板即可使用。 -双屏录制连接实际的虚拟显示器,分别捕获并按首帧时间对齐。见[已验证 VM 配置](../docs/zh-Hans/MULTI-DISPLAY.md)。 +双屏录制连接实际的虚拟显示器,分别捕获并按首帧时间对齐。见[已验证 VM 配置](MULTI-DISPLAY.md)。 ## 调整单个场景 @@ -132,10 +134,10 @@ DEMOLAB_LOCALIZATION_DIR="$PWD/DemoLab/.build/DemoLab/Localization" \ swift test --package-path DemoLab ``` -- [场景语法](../docs/zh-Hans/SCENES.md) -- [VM 设置](../docs/zh-Hans/VM-TART.md) -- [权限](../docs/zh-Hans/PERMISSIONS.md) -- [实际多显示器录制](../docs/zh-Hans/MULTI-DISPLAY.md) +- [场景语法](SCENES.md) +- [VM 设置](VM-TART.md) +- [权限](PERMISSIONS.md) +- [实际多显示器录制](MULTI-DISPLAY.md) ## 五语言制作 diff --git a/DemoLab/docs/zh-Hans/SCENES.md b/DemoLab/docs/zh-Hans/SCENES.md index 2bf3adc..e26aac1 100644 --- a/DemoLab/docs/zh-Hans/SCENES.md +++ b/DemoLab/docs/zh-Hans/SCENES.md @@ -48,8 +48,8 @@ |`virtualDisplay`|`connected`|连接或断开实际虚拟显示器工具。| |`configure`|`field`, `value`|原子修改实验 TOML 中允许的实时设置。| |`clipboard`|`text`|提供本地示例文本,同时保留并恢复所有剪贴板类型。| -|`closeSettings`|—|编辑后关闭原生设置窗口。| -|`prepareSettings`|—|操作控件前,调整 Tatami 原生设置窗口的大小和位置。| +|`closeSettings`|无字段|编辑后关闭原生设置窗口。| +|`prepareSettings`|无字段|操作控件前,调整 Tatami 原生设置窗口的大小和位置。| |`appWindows`|`app`, `count`|设置原生窗口数量,主要用于准备。| 没有 `appState` 命令,视图不能跳到预制成功状态。它们使用普通控件,通过 `StoryRepository` 共享保存的文案、评审、检查、任务和消息。`seed` 重置故事,切换工作区不会。聊天是无网络传输的本地演示。 @@ -88,4 +88,4 @@ `take` 默认为 `--overlay off`,文字保存在可编辑的 ASS 和 JSON 附属文件中。导出的视频会在画面下方叠加字幕、左上角显示章节、右上角显示实际按键。半透明背景提高了可读性,但仍可能遮挡应用内容,因此重要控件应避开这些区域。`scene` 使用实时排练面板,其呈现方式与最终视频不同。 -位置和时间、容量预算见 [publication.json](../../publication.json);录制、导出和检查命令见 [README.md](../../zh-Hans/README.md)。 +位置和时间、容量预算见 [publication.json](../../publication.json);录制、导出和检查命令见 [README.md](README.md)。 diff --git a/DemoLab/zh-Hant/README.md b/DemoLab/docs/zh-Hant/README.md similarity index 93% rename from DemoLab/zh-Hant/README.md rename to DemoLab/docs/zh-Hant/README.md index 7a17f5e..1dcffd1 100644 --- a/DemoLab/zh-Hant/README.md +++ b/DemoLab/docs/zh-Hant/README.md @@ -1,5 +1,5 @@ -[English](../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](README.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](README.md) @@ -10,11 +10,11 @@ ## 發布約定 -[`publication.json`](../publication.json) 定義影片清單與編輯預算,對應網站區塊並限制時間和檔案大小。 +[`publication.json`](../../publication.json) 定義影片清單與編輯預算,對應網站區塊並限制時間和檔案大小。 主影片依序展示設計、撰寫、審閱、借用、自動化,最後實際改變顯示器拓樸。專題涵蓋工作空間、設定組合與顯示器、並排與焦點、借用、視窗模式、CLI/Hook 和引導設定。清單由 `publication.json` 產生,不必維護重複清單。 -主影片傳達**切換工作,保留工作位置**。專題展示不同活動,不重複主影片。完整範圍見[涵蓋與證據界線](../docs/zh-Hant/COVERAGE.md)。 +主影片傳達**切換工作,保留工作位置**。專題展示不同活動,不重複主影片。完整範圍見[涵蓋與證據界線](COVERAGE.md)。 ## 錄製 → 輸出 → 檢查 → 本機安裝 @@ -85,6 +85,8 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 原始 MOV 包含完整的桌面畫面。匯出保留 1920×1200 解析度,雙螢幕影片為 1920×600。說明字幕疊加在畫面下方,章節名稱位於左上角,實際按鍵位於右上角。半透明背景確保文字在深淺色 App 上都清楚可讀。顏色來自網站配色,調整呈現方式不必重新錄製。 +縮圖時間由 `publication.json` 中的 `posterSeconds` 或 `posterCaptionIndex` 指定。請選擇功能實際生效後的畫面。縮圖 URL 使用圖片雜湊,因此只替換圖片時不需要重新編碼影片。 + 只修改字幕時,必須確保錄製的操作、輸入內容、驗證條件及等待時間皆未變更,才能重用原始影片。匯出工具會驗證錄製時固定的場景雜湊並比較操作,再替換原時間軸上的說明文字。驗證資料同時保留原始及編輯後的場景與時間軸。 每次錄製包含: @@ -99,7 +101,7 @@ GUEST_DIR=DemoLab/recordings/publish "$TOOL" vm-fetch-recordings DemoLab/recordi 匯出套件包含播放圖庫、海報、抽樣驗證畫格、原始與輸出檔案的雜湊,以及所有附屬檔案。自動驗收不能取代觀看實際操作,尤其是共用視窗鏡像及焦點目標仍須目視確認。網頁播放器使用原生控制項和 `preload="none"`,由使用者主動播放,且一次只播放一部影片。每個影片集提供縮圖清單、數量及前後按鈕。每部影片也連結至相關設定鍵。方向鍵、Home/End 及個別影片連結,不必展開額外面板即可使用。 -雙螢幕錄製連接實際的虛擬顯示器,分別擷取並依首影格時間對齊。見[已驗證 VM 設定](../docs/zh-Hant/MULTI-DISPLAY.md)。 +雙螢幕錄製連接實際的虛擬顯示器,分別擷取並依首影格時間對齊。見[已驗證 VM 設定](MULTI-DISPLAY.md)。 ## 調整單一場景 @@ -132,10 +134,10 @@ DEMOLAB_LOCALIZATION_DIR="$PWD/DemoLab/.build/DemoLab/Localization" \ swift test --package-path DemoLab ``` -- [場景語法](../docs/zh-Hant/SCENES.md) -- [VM 設定](../docs/zh-Hant/VM-TART.md) -- [權限](../docs/zh-Hant/PERMISSIONS.md) -- [實際多顯示器錄製](../docs/zh-Hant/MULTI-DISPLAY.md) +- [場景語法](SCENES.md) +- [VM 設定](VM-TART.md) +- [權限](PERMISSIONS.md) +- [實際多顯示器錄製](MULTI-DISPLAY.md) ## 五語言製作 diff --git a/DemoLab/docs/zh-Hant/SCENES.md b/DemoLab/docs/zh-Hant/SCENES.md index 9aaf5e2..5fdb05b 100644 --- a/DemoLab/docs/zh-Hant/SCENES.md +++ b/DemoLab/docs/zh-Hant/SCENES.md @@ -48,8 +48,8 @@ |`virtualDisplay`|`connected`|連接或中斷實際虛擬顯示器工具。| |`configure`|`field`, `value`|不可分割地修改實驗 TOML 中允許的即時設定。| |`clipboard`|`text`|提供本機範例文字,同時保留並還原所有剪貼簿類型。| -|`closeSettings`|—|編輯後關閉原生設定視窗。| -|`prepareSettings`|—|操作控制項前,調整 Tatami 原生設定視窗的大小與位置。| +|`closeSettings`|無欄位|編輯後關閉原生設定視窗。| +|`prepareSettings`|無欄位|操作控制項前,調整 Tatami 原生設定視窗的大小與位置。| |`appWindows`|`app`, `count`|設定原生視窗數量,主要用於準備。| 沒有 `appState` 指令,視圖不能跳到預製成功狀態。它們使用一般控制項,透過 `StoryRepository` 共用儲存的文案、審閱、檢查、待辦與訊息。`seed` 重設故事,切換工作空間不會。聊天是沒有網路傳輸的本機示範。 @@ -88,4 +88,4 @@ `take` 預設為 `--overlay off`,文字會儲存在可編輯的 ASS 與 JSON 附屬檔案中。匯出的影片會在畫面下方疊加字幕、左上角顯示章節、右上角顯示實際按鍵。半透明背景提高了可讀性,但仍可能遮住 App 內容,因此重要控制項應避開這些區域。`scene` 使用即時排練面板,呈現方式與最終影片不同。 -位置與時間、容量預算見 [publication.json](../../publication.json);錄製、輸出與檢查指令見 [README.md](../../zh-Hant/README.md)。 +位置與時間、容量預算見 [publication.json](../../publication.json);錄製、輸出與檢查指令見 [README.md](README.md)。 diff --git a/DemoLab/publication.json b/DemoLab/publication.json index 20a43c2..1d5d304 100644 --- a/DemoLab/publication.json +++ b/DemoLab/publication.json @@ -273,7 +273,8 @@ "key": "settings.switching.borrowDefaultEdge", "anchor": "settingsswitching" } - ] + ], + "posterSeconds": 5 }, { "scene": "scratchpad", diff --git a/Localization/Docs.json b/Localization/Docs.json index 90222d5..f7b8906 100644 --- a/Localization/Docs.json +++ b/Localization/Docs.json @@ -34,13 +34,6 @@ "zh-Hans": "[![为整个工作流程腾出空间。]({0})]({1})", "zh-Hant": "[![為整個工作流程騰出空間。]({0})]({1})" }, - "f3500adbf7d3a1b8": { - "en": "**[Watch the complete workflow]({0})** — design, write, review, borrow a follow-up, automate a focus session, and adapt to a second display. Real Tatami window management; demo apps and sample content. The displayed shortcuts are this demo's configured bindings.", - "ko": "**[전체 작업 흐름 보기]({0})**. 디자인, 글쓰기, 검토, 다음 할 일 빌려오기, 집중 환경 자동화, 두 번째 화면 연결까지 이어져요. 실제 Tatami로 창을 관리하며 앱과 내용은 데모용이에요. 표시한 단축키는 이 데모에서 설정한 키예요.", - "ja": "**[一連の作業を見る]({0})**。デザイン、執筆、レビュー、次の作業を借りる操作、集中環境の自動化、2 台目の画面への対応まで紹介します。実際の Tatami を使い、アプリと内容はデモ用です。表示するキーはこのデモの設定です。", - "zh-Hans": "**[观看完整工作流程]({0})**:设计、写作、评审、借用待办事项、自动准备专注环境,再连接第二个显示器。窗口由实际的 Tatami 管理,应用和内容为演示素材。快捷键采用本次演示的配置。", - "zh-Hant": "**[觀看完整工作流程]({0})**:設計、撰寫、審閱、借用待辦事項、自動準備專注環境,再連接第二部顯示器。視窗由實際的 Tatami 管理,App 和內容為示範素材。快速鍵採用本次示範的設定。" - }, "5088d504cc27e8ca": { "en": "Settings and Guided Setup screenshots", "ko": "설정과 시작 안내 스크린샷", @@ -90,13 +83,6 @@ "zh-Hans": "主要功能", "zh-Hant": "主要功能" }, - "272f97cb2b06613c": { - "en": "[![Move between tasks.]({0})]({1})", - "ko": "[![작업 사이를 오가기]({0})]({1})", - "ja": "[![作業を切り替える]({0})]({1})", - "zh-Hans": "[![在任务之间切换]({0})]({1})", - "zh-Hant": "[![在工作之間切換]({0})]({1})" - }, "f06c5df8b334f0ad": { "en": "**Virtual workspaces:** Group apps with per-workspace assignments.", "ko": "**가상 작업 공간:** 작업 공간마다 필요한 앱을 배정해서 모아요.", @@ -132,13 +118,6 @@ "zh-Hans": "**可选切换行为:** 启用循环、跳过空工作区或跟随应用焦点。", "zh-Hant": "**可選切換行為:** 啟用循環、略過空工作空間或跟隨 App 焦點。" }, - "804ab2a6ffa55907": { - "en": "**[Auto-open demo]({0}):** Launch assigned apps when a workspace activates and reopen them on re-entry if their window was closed.", - "ko": "**[자동 열기 데모]({0}):** 작업 공간에 들어가면 배정한 앱이 열려요. 창을 닫아도 다시 들어가면 열어줘요.", - "ja": "**[自動で開くデモ]({0}):** 作業を開くと割り当てたアプリが起動し、閉じたウインドウも入り直すと開きます。", - "zh-Hans": "**[自动打开演示]({0}):** 激活工作区时启动分配的应用,重新进入时打开之前关闭的窗口。", - "zh-Hant": "**[自動開啟示範]({0}):** 啟用工作空間時啟動指派的 App,重新進入時開啟先前關閉的視窗。" - }, "a2a4c7eef067a833": { "en": "**Per-display workspaces:** Pin a workspace to a display or have dynamic workspaces open under the mouse. Each display keeps its own active and recent workspace across relaunches, while next/previous and recent navigation can independently stay local or span every display.", "ko": "**화면별 작업 공간:** 특정 화면에 고정하거나 마우스가 있는 화면에 열 수 있어요. 각 화면은 재실행 후에도 활성·최근 작업 공간을 기억해요. 다음·이전·최근 이동의 범위는 각각 현재 화면이나 전체 화면으로 정할 수 있어요.", @@ -174,13 +153,6 @@ "zh-Hans": "窗口平铺(BSP)", "zh-Hant": "視窗並排(BSP)" }, - "790aa2182df007c9": { - "en": "[![Let new windows find their place.]({0})]({1})", - "ko": "[![새 창이 제자리를 찾도록 하기]({0})]({1})", - "ja": "[![新しいウインドウが自然に収まる]({0})]({1})", - "zh-Hans": "[![让新窗口找到位置]({0})]({1})", - "zh-Hant": "[![讓新視窗找到位置]({0})]({1})" - }, "25c0497cea23b369": { "en": "**Interactive window switching:** Tap the window-switch shortcut for an immediate switch, or hold its modifier for a compact app / window switcher. It stays scoped to the display under the pointer, can include Shared Apps, shows each window's current state, and lets you choose the exact target with the keyboard or pointer.", "ko": "**창 선택:** 전환 단축키를 짧게 누르면 바로 전환하고, 보조키를 길게 누르면 앱·창 목록이 나타나요. 포인터가 있는 화면 안에서 동작하고 공용 앱도 포함할 수 있어요. 각 창의 상태를 보며 키보드나 마우스로 정확히 고를 수 있어요.", @@ -230,13 +202,6 @@ "zh-Hans": "配置方案", "zh-Hant": "設定組合" }, - "049ce189ea067ef4": { - "en": "[Watch the profile and two-display collection]({0}).", - "ko": "[프로필과 두 화면 영상 모음 보기]({0}).", - "ja": "[プロファイルと 2 画面の動画を見る]({0})。", - "zh-Hans": "[观看配置方案与双屏演示]({0})。", - "zh-Hant": "[觀看設定組合與雙螢幕示範]({0})。" - }, "046fb607b89e0122": { "en": "**Independent profiles:** Group workspaces and switch the whole set at once. Each profile keeps its own workspaces, app assignments, and shortcuts.", "ko": "**독립 프로필:** 작업 공간을 묶어 전체 구성을 한 번에 바꿔요. 프로필마다 작업 공간·앱 배정·단축키를 따로 저장해요.", @@ -279,13 +244,6 @@ "zh-Hans": "借用:组合两个工作区", "zh-Hant": "借用:組合兩個工作空間" }, - "1c8ba14ba65d9ee2": { - "en": "[![Bring a conversation alongside.]({0})]({1})", - "ko": "[![대화를 옆으로 가져오기]({0})]({1})", - "ja": "[![会話を横に呼び出す]({0})]({1})", - "zh-Hans": "[![把对话放到旁边]({0})]({1})", - "zh-Hant": "[![把對話放到旁邊]({0})]({1})" - }, "81200624043ee970": { "en": "**Side-by-side composition:** Pull another workspace beside the current one, dock it to any screen edge, and tile both blocks independently. Windows cannot cross the boundary.", "ko": "**나란히 사용:** 다른 작업 공간을 화면 가장자리로 빌려와요. 두 영역은 따로 타일링되며 창은 경계를 넘지 않아요.", @@ -335,13 +293,6 @@ "zh-Hans": "置顶", "zh-Hant": "置頂" }, - "2ba6ee5674637a65": { - "en": "[Watch: one shared monitor above different workspaces]({0}).", - "ko": "[여러 작업 공간 위에서 같은 상태 창 보기]({0}).", - "ja": "[作業が変わっても同じ状態ウインドウを見る]({0})。", - "zh-Hans": "[观看跨工作区的共享状态窗口]({0})。", - "zh-Hant": "[觀看跨工作空間的共用狀態視窗]({0})。" - }, "bb02b50349a30601": { "en": "**Per-workspace or shared:** Keep an app on top in one workspace or add it to Shared Apps to keep it on top everywhere.", "ko": "**작업 공간별 또는 공용:** 한 공간에서만 앱을 항상 위에 두거나 공용 앱으로 추가해 어디서나 볼 수 있어요.", @@ -377,13 +328,6 @@ "zh-Hans": "焦点与指针", "zh-Hant": "焦點與游標" }, - "75b3930ec022a97b": { - "en": "[Watch focus follow the keyboard and pointer]({0}).", - "ko": "[키보드와 포인터에 따른 포커스 이동 보기]({0}).", - "ja": "[キーとポインタに合わせたフォーカス移動を見る]({0})。", - "zh-Hans": "[观看焦点跟随键盘和指针]({0})。", - "zh-Hant": "[觀看焦點跟隨鍵盤和游標]({0})。" - }, "385afb896896c51a": { "en": "**Two explicit focus models:** Focus-follows-mouse gives the window under the pointer keyboard focus. Mouse-follows-focus moves the pointer after Tatami changes windows, including switching to Always on Top, Shared Always on Top, or Leave As Is windows.", "ko": "**두 가지 포커스 방식:** 마우스 따라가기는 포인터 아래 창에 키보드 포커스를 줘요. 포커스 따라가기는 Tatami가 창을 바꿀 때 포인터를 옮겨요. 항상 위·공용 항상 위·그대로 두기 창에서도 동작해요.", @@ -412,13 +356,6 @@ "zh-Hans": "界面与配置", "zh-Hant": "介面與設定" }, - "809bd7992c5d8416": { - "en": "[Watch real CLI commands, hooks and live configuration]({0}).", - "ko": "[실제 CLI·훅·설정 바로 적용 보기]({0}).", - "ja": "[実際の CLI、フック、設定の即時反映を見る]({0})。", - "zh-Hans": "[观看实际 CLI、钩子和实时配置]({0})。", - "zh-Hant": "[觀看實際 CLI、掛鉤與即時設定]({0})。" - }, "bd123cd78d805214": { "en": "**Five interface languages:** Use Tatami in English, Korean, Japanese, Simplified Chinese, or Traditional Chinese, following your macOS app-language preference.", "ko": "**다섯 언어:** macOS 앱 언어 설정에 따라 영어·한국어·일본어·중국어 간체·대만 번체로 쓸 수 있어요.", @@ -496,13 +433,6 @@ "zh-Hans": "设置向导", "zh-Hant": "設定導覽" }, - "78be28a73719fae3": { - "en": "[Watch shortcut practice and proposal review]({0}).", - "ko": "[단축키 연습과 제안 검토 보기]({0}).", - "ja": "[ショートカットの練習と提案の確認を見る]({0})。", - "zh-Hans": "[观看快捷键练习和建议检查]({0})。", - "zh-Hant": "[觀看快速鍵練習與建議檢查]({0})。" - }, "4a814980608feca1": { "en": "**Learn by doing:** First launch walks through Workspaces, switching and gestures, BSP tiling, Borrow and scratchpads, Always on Top / Leave As Is, MFF / FFM, and app / window switching in a safe virtual display.", "ko": "**직접 배우기:** 처음 실행하면 안전한 가상 화면에서 작업 공간, 전환·제스처, BSP 타일링, 빌려오기·임시 공간, 항상 위·그대로 두기, 포커스·포인터 따라가기, 앱·창 전환을 차례로 익혀요.", @@ -5152,5 +5082,96 @@ "ja": "開発用の自動化は、{0} で固定された別のパッケージ群を使います。[開発ツールの依存関係の表示]({1})は原文でご確認ください。", "zh-Hans": "开发自动化使用另一组依赖包,其版本固定在 {0} 中。请阅读原文形式的[开发工具依赖声明]({1})。", "zh-Hant": "開發自動化使用另一組套件,其版本固定在 {0} 中。請閱讀原文形式的[開發工具相依套件聲明]({1})。" + }, + "55eeaa68d1c11f4d": { + "en": "**[Watch the complete workflow]({0})**: design, write, review, borrow a follow-up, automate a focus session, and adapt to a second display. Real Tatami window management; demo apps and sample content. The displayed shortcuts are this demo's configured bindings.", + "ko": "**[전체 작업 흐름 보기]({0})**. 디자인, 글쓰기, 검토, 다음 할 일 빌려오기, 집중 환경 자동화, 두 번째 화면 연결까지 이어져요. 실제 Tatami로 창을 관리하며 앱과 내용은 데모용이에요. 표시한 단축키는 이 데모에서 설정한 키예요.", + "ja": "**[一連の作業を見る]({0})**。デザイン、執筆、レビュー、次の作業を借りる操作、集中環境の自動化、2 台目の画面への対応まで紹介します。実際の Tatami を使い、アプリと内容はデモ用です。表示するキーはこのデモの設定です。", + "zh-Hans": "**[观看完整工作流程]({0})**:设计、写作、评审、借用待办事项、自动准备专注环境,再连接第二个显示器。窗口由实际的 Tatami 管理,应用和内容为演示素材。快捷键采用本次演示的配置。", + "zh-Hant": "**[觀看完整工作流程]({0})**:設計、撰寫、審閱、借用待辦事項、自動準備專注環境,再連接第二部顯示器。視窗由實際的 Tatami 管理,App 和內容為示範素材。快速鍵採用本次示範的設定。" + }, + "4162bdb9d01f2674": { + "en": "No fields", + "ko": "필드 없음", + "ja": "フィールドなし", + "zh-Hans": "无字段", + "zh-Hant": "無欄位" + }, + "66020df68980e3d9": { + "en": "Move between tasks", + "ko": "작업 사이를 오가기", + "ja": "作業を切り替える", + "zh-Hans": "在任务之间切换", + "zh-Hant": "在工作之間切換" + }, + "e2b559681c8ba5ad": { + "en": "Let new windows find their place", + "ko": "새 창이 제자리를 찾도록 하기", + "ja": "新しいウインドウが自然に収まる", + "zh-Hans": "让新窗口找到位置", + "zh-Hant": "讓新視窗找到位置" + }, + "0ed46e81f88e5f75": { + "en": "Switch the complete setup", + "ko": "전체 구성 전환하기", + "ja": "作業環境ごと切り替える", + "zh-Hans": "切换整套配置", + "zh-Hant": "切換整套設定" + }, + "32259433af68fde7": { + "en": "Bring a conversation alongside", + "ko": "대화를 옆으로 가져오기", + "ja": "会話を横に呼び出す", + "zh-Hans": "把对话放到旁边", + "zh-Hant": "把對話放到旁邊" + }, + "5e82e96ee8c8a2ed": { + "en": "One status window across tasks", + "ko": "여러 작업에서 같은 상태 창 보기", + "ja": "作業が変わっても同じ状態ウインドウを使う", + "zh-Hans": "跨任务使用同一个状态窗口", + "zh-Hant": "跨工作使用同一個狀態視窗" + }, + "495cfb550d5d1b8d": { + "en": "Focus follows your intent", + "ko": "내 의도에 따라 포커스 이동하기", + "ja": "意図に合わせてフォーカスを移す", + "zh-Hans": "让焦点跟随你的意图", + "zh-Hant": "讓焦點跟隨你的意圖" + }, + "27faaab644291827": { + "en": "Build a focus session with the CLI", + "ko": "CLI로 집중할 환경 준비하기", + "ja": "CLI で集中できる環境を用意する", + "zh-Hans": "用 CLI 准备专注环境", + "zh-Hant": "用 CLI 準備專注環境" + }, + "dce217589e5c6b16": { + "en": "Learn by doing", + "ko": "직접 사용하며 익히기", + "ja": "使いながら覚える", + "zh-Hans": "边用边学", + "zh-Hant": "邊用邊學" + }, + "dbae3e9ba44b12b1": { + "en": "Watch video", + "ko": "영상 보기", + "ja": "動画を見る", + "zh-Hans": "观看视频", + "zh-Hant": "觀看影片" + }, + "1a48b68d5c98b65b": { + "en": "**Auto-open:** Launch assigned apps when a workspace activates and reopen them on re-entry if their window was closed.", + "ko": "**자동 열기:** 작업 공간으로 전환하면 지정한 앱을 실행하고, 창을 닫았더라도 다시 들어올 때 열어요.", + "ja": "**自動起動:** ワークスペースを開くと割り当てたアプリを起動し、ウインドウを閉じた場合も次に開くときに再び表示します。", + "zh-Hans": "**自动打开:** 激活工作区时启动指定应用;如果关闭了窗口,再次进入时会重新打开。", + "zh-Hant": "**自動開啟:** 啟用工作空間時啟動指定的 App;如果關閉了視窗,再次進入時會重新開啟。" + }, + "b71ef439a9954775": { + "en": "Poster frames use {0} or {1} from {2}. Choose a frame after the feature has taken effect. Poster URLs use the image hash so replacing a still does not require re-encoding its video.", + "ko": "썸네일 시점은 {2}의 {0} 또는 {1}로 정해요. 기능이 실제로 적용된 뒤의 장면을 선택해요. 썸네일 URL에는 이미지 해시를 사용하므로 이미지만 교체할 때 영상을 다시 인코딩할 필요가 없어요.", + "ja": "サムネイルの時点は、{2} の {0} または {1} で指定します。機能が実際に反映された後のフレームを選んでください。サムネイルの URL には画像のハッシュを使うため、画像だけを差し替える場合に動画を再エンコードする必要はありません。", + "zh-Hans": "缩略图时间由 {2} 中的 {0} 或 {1} 指定。请选择功能实际生效后的画面。缩略图 URL 使用图片哈希,因此仅替换图片时无需重新编码视频。", + "zh-Hant": "縮圖時間由 {2} 中的 {0} 或 {1} 指定。請選擇功能實際生效後的畫面。縮圖 URL 使用圖片雜湊,因此只替換圖片時不需要重新編碼影片。" } } diff --git a/NOTICE.md b/NOTICE.md index 35595e0..57e7b9c 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1,5 +1,5 @@ -[English](NOTICE.md) · [한국어](NOTICE.ko.md) · [日本語](NOTICE.ja.md) · [简体中文](NOTICE.zh-Hans.md) · [繁體中文](NOTICE.zh-Hant.md) +[English](NOTICE.md) · [한국어](docs/ko/NOTICE.md) · [日本語](docs/ja/NOTICE.md) · [简体中文](docs/zh-Hans/NOTICE.md) · [繁體中文](docs/zh-Hant/NOTICE.md) # Notice diff --git a/README.md b/README.md index 0f01d3a..7e047cb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · [简体中文](README.zh-Hans.md) · [繁體中文](README.zh-Hant.md) +[English](README.md) · [한국어](docs/ko/README.md) · [日本語](docs/ja/README.md) · [简体中文](docs/zh-Hans/README.md) · [繁體中文](docs/zh-Hant/README.md) # Tatami @@ -20,7 +20,7 @@ scripting required. [![Make room for the whole workflow.](web/tour.jpg)](https://pangmo5.dev/Tatami#demo) -**[Watch the complete workflow](https://pangmo5.dev/Tatami#demo)** — design, write, +**[Watch the complete workflow](https://pangmo5.dev/Tatami#demo)**: design, write, review, borrow a follow-up, automate a focus session, and adapt to a second display. Real Tatami window management; demo apps and sample content. The displayed shortcuts are this demo's configured bindings. @@ -38,29 +38,30 @@ shortcuts are this demo's configured bindings. Borrow
Captured on an earlier version. Some labels have changed since these screenshots.

- ## Features ### Workspaces -[![Move between tasks.](web/workspaces.jpg)](https://pangmo5.dev/Tatami#demo-workspaces) +Move between tasks - **Virtual workspaces:** Group apps with per-workspace assignments. - **Flexible switching:** Use a hotkey, trackpad gesture, or recent-workspace action. - **Configurable gestures:** Bind every direction of a three- or four-finger swipe to any shortcut action, including profile- and workspace-specific commands. - **One key per workspace:** Hold the switch, assign, or borrow modifier with a **key equivalent**. The same keys also drive recent, next, and previous targets, while any action can take an explicit override. - **Optional switching behaviors:** Enable loop-around, skip-empty, or follow-app-focus. -- **[Auto-open demo](https://pangmo5.dev/Tatami#demo-autoopen):** Launch assigned apps when a workspace activates and reopen them on re-entry if their window was closed. +- **Auto-open:** Launch assigned apps when a workspace activates and reopen them on re-entry if their window was closed. - **Per-display workspaces:** Pin a workspace to a display or have dynamic workspaces open under the mouse. Each display keeps its own active and recent workspace across relaunches, while next/previous and recent navigation can independently stay local or span every display. - **Workspace chains:** Link an ordered set of workspaces inside a profile. Switching to any member restores available companions in chain priority, honoring connected display pins and Chain Dynamic placement while focus stays with the workspace you chose. - **Cross-display control:** Jump focus between displays or move the focused app to another workspace. - **Shared apps:** Add apps that should join every workspace. +
+ ### Window tiling (BSP) -[![Let new windows find their place.](web/tiling.jpg)](https://pangmo5.dev/Tatami#demo-tiling) +Let new windows find their place - **Automatic BSP layout:** Insert new windows beside the current insertion target or focused tile. Use the shallowest tile when neither is available. - **Keyboard operations:** With the recommended bindings, use `ctrl + alt` with `h`, `j`, `k`, or `l` to focus, arrow keys to swap, and `=` or `-` to grow or shrink the focused tile. @@ -71,9 +72,11 @@ Captured on an earlier version. Some labels have changed since these screenshots - **Persistent layouts:** Keep each workspace's tree and ratios across workspace switches, relaunches, and system sleep. - **Configurable spacing:** Set inner and outer gaps. +
+ ### Profiles -[Watch the profile and two-display collection](https://pangmo5.dev/Tatami#profiles). +Switch the complete setup - **Independent profiles:** Group workspaces and switch the whole set at once. Each profile keeps its own workspaces, app assignments, and shortcuts. - **Fast profile switching:** Switch by hotkey or from the menu bar. Every display re-tiles for the new profile, and Tatami returns to the right profile after relaunch. @@ -81,9 +84,11 @@ Captured on an earlier version. Some labels have changed since these screenshots - **Profile identity:** Give each profile an SF Symbol shown in the sidebar, menu bar, and profile-switch feedback. - **Reuse an existing setup:** **Copy from** and **Duplicate** share one preview where you keep or skip each workspace, app, setting, and saved layout before anything changes. +
+ ### Borrow: compose two workspaces -[![Bring a conversation alongside.](web/borrow.jpg)](https://pangmo5.dev/Tatami#demo-borrow) +Bring a conversation alongside - **Side-by-side composition:** Pull another workspace beside the current one, dock it to any screen edge, and tile both blocks independently. Windows cannot cross the boundary. - **Live and bidirectional:** The borrowed block is the real workspace, so edits persist back to it. @@ -92,26 +97,32 @@ Captured on an earlier version. Some labels have changed since these screenshots - **Visible ownership:** Borrowed windows show the borrowed workspace's icon. - **Scratchpads:** Borrow-only workspaces stay out of regular switching, never activate alone, and auto-open their apps when summoned. +
+ ### Always on Top -[Watch: one shared monitor above different workspaces](https://pangmo5.dev/Tatami#demo-shared). +One status window across tasks - **Per-workspace or shared:** Keep an app on top in one workspace or add it to Shared Apps to keep it on top everywhere. - **No SIP changes:** Tatami uses always-on-top ScreenCaptureKit mirrors, then hands you the real window when you interact with it. - **Predictable stacking:** Multiple always-on-top windows stack by focus recency. This requires Screen Recording permission. - **Leave As Is:** Keep an app as a workspace member for auto-open, focus, focus-follows-mouse, and window switching while preserving its current position and size. This mode needs no mirroring or Screen Recording. +
+ ### Focus & cursor -[Watch focus follow the keyboard and pointer](https://pangmo5.dev/Tatami#demo-focus). +Focus follows your intent - **Two explicit focus models:** Focus-follows-mouse gives the window under the pointer keyboard focus. Mouse-follows-focus moves the pointer after Tatami changes windows, including switching to Always on Top, Shared Always on Top, or Leave As Is windows. - **Close-window refocus:** Return to the most recently used remaining window. - **Cursor control:** Optionally hide the cursor during a workspace switch. +
+ ### Interface & config -[Watch real CLI commands, hooks and live configuration](https://pangmo5.dev/Tatami#automation). +Build a focus session with the CLI - **Five interface languages:** Use Tatami in English, Korean, Japanese, Simplified Chinese, or Traditional Chinese, following your macOS app-language preference. - **Customizable menu bar:** Show the active workspace icon or name and, when relevant, the active profile icon or name. @@ -124,9 +135,11 @@ Captured on an earlier version. Some labels have changed since these screenshots - **Scriptable CLI:** Use domain commands such as `tatami workspace activate ` and `tatami workspace list`. - **Automatic updates:** Receive releases through Sparkle. +
+ ### Guided setup -[Watch shortcut practice and proposal review](https://pangmo5.dev/Tatami#guided-setup). +Learn by doing - **Learn by doing:** First launch walks through Workspaces, switching and gestures, BSP tiling, Borrow and scratchpads, Always on Top / Leave As Is, MFF / FFM, and app / window switching in a safe virtual display. - **Built from this Mac:** Start from running-app metadata and connected-display geometry, then organize apps around repeatable work rather than generic categories. No screen contents are captured. @@ -134,6 +147,8 @@ Captured on an earlier version. Some labels have changed since these screenshots - **One cumulative practice surface:** Real shortcuts and trackpad gestures control the preview, and every command learned earlier remains available in later lessons. - **Draft first:** Guided Setup does not move real windows or write `config.toml` until **Apply Setup**. Reopen it any time from **Settings → General**. +
+ ## Requirements - macOS 14.0 or later diff --git a/REUSE.toml b/REUSE.toml index 4244bbe..8b71943 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -11,9 +11,6 @@ path = [ "Makefile", "NOTICE.md", "README.md", - "README.*.md", - "NOTICE.*.md", - "THIRD_PARTY_NOTICES.*.md", "Localization/**", "Tools/**", "Resources/**", diff --git a/THIRD_PARTY_NOTICES.ja.md b/THIRD_PARTY_NOTICES.ja.md deleted file mode 100644 index d331040..0000000 --- a/THIRD_PARTY_NOTICES.ja.md +++ /dev/null @@ -1,12 +0,0 @@ - -[English](THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.ko.md) · [日本語](THIRD_PARTY_NOTICES.ja.md) · [简体中文](THIRD_PARTY_NOTICES.zh-Hans.md) · [繁體中文](THIRD_PARTY_NOTICES.zh-Hant.md) - - - -# 外部ライブラリの告知 - -Tatami アプリの依存関係のバージョンとリビジョンは、`Tuist/Package.resolved` に基づいています。 - -[アプリのライセンスと著作権表示の全文](THIRD_PARTY_NOTICES.md)は原文でご確認ください。このページでは概要の説明のみを翻訳しています。 - -開発用の自動化は、`Tools/Package.resolved` で固定された別のパッケージ群を使います。[開発ツールの依存関係の表示](Tools/THIRD_PARTY_NOTICES.md)は原文でご確認ください。 diff --git a/THIRD_PARTY_NOTICES.ko.md b/THIRD_PARTY_NOTICES.ko.md deleted file mode 100644 index de2ce2c..0000000 --- a/THIRD_PARTY_NOTICES.ko.md +++ /dev/null @@ -1,12 +0,0 @@ - -[English](THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.ko.md) · [日本語](THIRD_PARTY_NOTICES.ja.md) · [简体中文](THIRD_PARTY_NOTICES.zh-Hans.md) · [繁體中文](THIRD_PARTY_NOTICES.zh-Hant.md) - - - -# 외부 라이브러리 고지 - -Tatami 앱 의존성의 버전과 리비전은 `Tuist/Package.resolved`을 기준으로 해요. - -[앱의 전체 라이선스 및 저작권 고지](THIRD_PARTY_NOTICES.md)는 원문으로 제공해요. 이 페이지는 개요 설명만 번역해요. - -개발 자동화는 `Tools/Package.resolved`에 고정된 별도의 패키지 집합을 사용해요. [개발 도구 의존성 고지](Tools/THIRD_PARTY_NOTICES.md)는 원문으로 제공해요. diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 985b9c6..ddac08e 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -1,5 +1,5 @@ -[English](THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.ko.md) · [日本語](THIRD_PARTY_NOTICES.ja.md) · [简体中文](THIRD_PARTY_NOTICES.zh-Hans.md) · [繁體中文](THIRD_PARTY_NOTICES.zh-Hant.md) +[English](THIRD_PARTY_NOTICES.md) · [한국어](docs/ko/THIRD_PARTY_NOTICES.md) · [日本語](docs/ja/THIRD_PARTY_NOTICES.md) · [简体中文](docs/zh-Hans/THIRD_PARTY_NOTICES.md) · [繁體中文](docs/zh-Hant/THIRD_PARTY_NOTICES.md) # Third-Party Notices diff --git a/THIRD_PARTY_NOTICES.zh-Hans.md b/THIRD_PARTY_NOTICES.zh-Hans.md deleted file mode 100644 index d26739c..0000000 --- a/THIRD_PARTY_NOTICES.zh-Hans.md +++ /dev/null @@ -1,12 +0,0 @@ - -[English](THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.ko.md) · [日本語](THIRD_PARTY_NOTICES.ja.md) · [简体中文](THIRD_PARTY_NOTICES.zh-Hans.md) · [繁體中文](THIRD_PARTY_NOTICES.zh-Hant.md) - - - -# 第三方声明 - -Tatami 应用依赖项的版本和修订号以 `Tuist/Package.resolved` 为准。 - -请阅读原文形式的[应用完整许可证和版权声明](THIRD_PARTY_NOTICES.md)。本页仅翻译概述说明。 - -开发自动化使用另一组依赖包,其版本固定在 `Tools/Package.resolved` 中。请阅读原文形式的[开发工具依赖声明](Tools/THIRD_PARTY_NOTICES.md)。 diff --git a/Tools/Sources/TatamiToolsKit/Documents.swift b/Tools/Sources/TatamiToolsKit/Documents.swift index dd485e2..16a9764 100644 --- a/Tools/Sources/TatamiToolsKit/Documents.swift +++ b/Tools/Sources/TatamiToolsKit/Documents.swift @@ -21,10 +21,21 @@ struct DocumentBuilder { func destination(_ source: String, _ locale: String) -> URL { let file = workspace.root.at(source) if locale == "en" { return file } - if !source.contains("/") { return file.deletingLastPathComponent().at(file.stem + "." + locale + "." + file.pathExtension) } + if !source.contains("/") { return workspace.root.at("docs").at(locale).at(file.lastPathComponent) } + if source == "DemoLab/README.md" { return workspace.lab.at("docs").at(locale).at(file.lastPathComponent) } return file.deletingLastPathComponent().at(locale).at(file.lastPathComponent) } + func localizedNoticeLink(_ value: String, locale: String) -> String { + guard locale != "en" else { return value } + for source in ["NOTICE.md", "THIRD_PARTY_NOTICES.md"] where value.hasSuffix("/" + source) { + let localized = relativePath(destination(source, locale), from: workspace.root) + if value.hasSuffix("/" + localized) { return value } + return String(value.dropLast(source.count)) + localized + } + return value + } + func languageLinks(_ source: String, _ locale: String) -> String { let parent = destination(source, locale).deletingLastPathComponent() return "\n" + locales.map { "[" + languageNames[$0]! + "](" + relativePath( diff --git a/Tools/Sources/TatamiToolsKit/Publication.swift b/Tools/Sources/TatamiToolsKit/Publication.swift index fb2c4b2..6b7d99f 100644 --- a/Tools/Sources/TatamiToolsKit/Publication.swift +++ b/Tools/Sources/TatamiToolsKit/Publication.swift @@ -46,7 +46,10 @@ struct Publication { else { throw ToolError("Missing collection container: \(section)") } position = div.lowerBound } - text.insert(contentsOf: try "\n " + gallery.collection(section, assets: assets), at: position) + text.insert( + contentsOf: try "\n " + gallery.collection(section, assets: assets, mediaDirectory: workspace.root.at("web")), + at: position, + ) } if !text.contains("src=\"./demos.js\"") { text = text.replacingOccurrences( of: "", @@ -56,9 +59,11 @@ struct Publication { text = replacing(#"(?s).*?"#, in: text) { _ in "" + gallery.settingsLinks(hero) + "" } - for name in [hero["video"].str, hero["poster"].str] { + for kind in ["video", "poster"] { + let name = hero[kind].str + let token = try kind == "poster" ? sha(workspace.root.at("web/" + name)) : hero["sha256"].str text = replacing(NSRegularExpression.escapedPattern(for: name) + #"(?:\?v=[a-f0-9]+)?"#, in: text) { _ in - name + "?v=" + hero["sha256"].str.prefix(12) + name + "?v=" + token.prefix(12) } } try page.write(text) diff --git a/Tools/Sources/TatamiToolsKit/PublicationContract.swift b/Tools/Sources/TatamiToolsKit/PublicationContract.swift index a9b9c06..9a5ad37 100644 --- a/Tools/Sources/TatamiToolsKit/PublicationContract.swift +++ b/Tools/Sources/TatamiToolsKit/PublicationContract.swift @@ -19,6 +19,8 @@ struct PublicationContract: Decodable { let maxSeconds: Double let maxMB: Double let presentation: Presentation? + let posterSeconds: Double? + let posterCaptionIndex: Int? } let assets: [Asset] diff --git a/Tools/Sources/TatamiToolsKit/SiteBuilder.swift b/Tools/Sources/TatamiToolsKit/SiteBuilder.swift index 4482d1a..6b3b16e 100644 --- a/Tools/Sources/TatamiToolsKit/SiteBuilder.swift +++ b/Tools/Sources/TatamiToolsKit/SiteBuilder.swift @@ -60,6 +60,7 @@ struct SiteBuilder { for locale in selectedLocales { guard let manifest = manifests[locale] else { throw ToolError("Missing manifest: \(locale)") } let assets = manifest["assets"].array + let mediaDirectory = workspace.root.at(locale == "en" ? "web" : "web/media/" + locale) let groups = orderedGroups(assets.filter { $0["scene"].str != "tour" }.map { asset in asset.merging([ ("locale", .string(locale)), @@ -80,7 +81,8 @@ struct SiteBuilder { let name = URL(fileURLWithPath: URLComponents(string: poster)?.path ?? poster).stem guard let asset = assets.first(where: { $0["scene"].str == name }) else { throw ToolError("Missing hero asset: \(name)") } - node["poster"] = mediaURL(asset, kind: "poster", locale: locale) + "?v=" + asset["sha256"].str.prefix(12) + node["poster"] = try mediaURL(asset, kind: "poster", locale: locale) + "?v=" + + sha(mediaDirectory.at(asset["poster"].str)).prefix(12) } if node.tag == "source", node["type"] == "video/mp4", let source = node["src"] { let name = URL(fileURLWithPath: URLComponents(string: source)?.path ?? source).stem @@ -112,12 +114,8 @@ struct SiteBuilder { node["href"] = (locale == "en" ? "./" : "../") + "content/" + locale + "/" + URL(fileURLWithPath: href) .lastPathComponent } - if node.tag == "a", locale != "en" { - for notice in ["NOTICE", "THIRD_PARTY_NOTICES"] { - if - let href = node["href"], - href.hasSuffix("/" + notice + ".md") { node["href"] = String(href.dropLast(3)) + "." + locale + ".md" } - } + if node.tag == "a", let href = node["href"] { + node["href"] = DocumentBuilder(workspace: workspace).localizedNoticeLink(href, locale: locale) } for child in node.children { if let child = child.node { try walk(child) } } if node.tag == "div", node["class"] == "nav-inner" { @@ -162,7 +160,7 @@ struct SiteBuilder { text = try replacing(#"
"#, in: text) { match in guard let assets = groups.first(where: { $0.0 == match[1] })?.1 else { throw ToolError("Missing collection: \(match[1])") } - return try gallery.collection(match[1], assets: assets) + return try gallery.collection(match[1], assets: assets, mediaDirectory: mediaDirectory) } output.append(((locale == "en" ? "" : locale + "/") + page, text + "\n")) } diff --git a/Tools/Sources/TatamiToolsKit/VideoExport.swift b/Tools/Sources/TatamiToolsKit/VideoExport.swift index de0fbe0..2f0994b 100644 --- a/Tools/Sources/TatamiToolsKit/VideoExport.swift +++ b/Tools/Sources/TatamiToolsKit/VideoExport.swift @@ -12,6 +12,23 @@ struct VideoExporter { Narration(workspace: workspace) } + static func posterTime(asset: JSON, timeline: JSON, duration: Double) throws -> Double { + try require( + asset["posterSeconds"].isNull || asset["posterCaptionIndex"].isNull, + "Choose either posterSeconds or posterCaptionIndex", + ) + var second = 0.5 + if !asset["posterSeconds"].isNull { second = asset["posterSeconds"].double } + else if !asset["posterCaptionIndex"].isNull { + let captions = timeline["events"].array.filter { $0["track"].str == "caption" && !$0["text"].str.isEmpty } + let index = asset["posterCaptionIndex"].int + try require(captions.indices.contains(index), "Poster caption index out of range") + second = captions[index]["start"].double + 0.3 + } + try require(second.isFinite && second >= 0 && second < duration, "Poster time is outside the film") + return second + } + static func acceptedFrames(_ record: JSON) -> Bool { record["frames"].double > 0 && record["droppedFrames"].double >= 0 && record["droppedFrames"].double / record["frames"] .double <= 0.01 @@ -57,6 +74,7 @@ struct VideoExporter { let opening = timeline["events"].array.first(where: { $0["track"].str == "caption" && !$0["text"].str.isEmpty }), opening["start"].double <= 0.35 else { throw ToolError("\(movie.path): opening narration is late or missing") } + _ = try Self.posterTime(asset: asset, timeline: timeline, duration: duration) return (record, duration) } @@ -122,13 +140,7 @@ struct VideoExporter { try require(Double(bytes) <= asset["maxMB"].double * 1_048_576, "\(target.path): exceeds MB budget") try await runProcess(["ffmpeg", "-v", "error", "-xerror", "-i", target.path, "-f", "null", "-"]) let poster = target.replacingExtension("jpg") - let captions = timeline["events"].array.filter { $0["track"].str == "caption" && !$0["text"].str.isEmpty } - var posterTime = 0.5 - if !asset["posterCaptionIndex"].isNull { - let index = asset["posterCaptionIndex"].int - try require(captions.indices.contains(index), "Poster caption index out of range") - posterTime = captions[index]["start"].double + 0.3 - } + let posterTime = try Self.posterTime(asset: asset, timeline: timeline, duration: duration) try await runProcess([ "ffmpeg", "-v", diff --git a/Tools/Sources/TatamiToolsKit/VideoGallery.swift b/Tools/Sources/TatamiToolsKit/VideoGallery.swift index ff4d239..b08df49 100644 --- a/Tools/Sources/TatamiToolsKit/VideoGallery.swift +++ b/Tools/Sources/TatamiToolsKit/VideoGallery.swift @@ -29,7 +29,7 @@ struct VideoGallery { return "" } - func collection(_ section: String, assets: [JSON], cacheBust: Bool = true) throws -> String { + func collection(_ section: String, assets: [JSON], mediaDirectory: URL, cacheBust: Bool = true) throws -> String { try require(!assets.isEmpty, "Empty video collection: \(section)") let locale = assets[0]["locale"].string ?? "en" let ui = interface[locale] @@ -44,7 +44,8 @@ struct VideoGallery { let title = htmlEscape(asset["title"].str) let suffix = cacheBust ? "?v=" + asset["sha256"].str.prefix(12) : "" let video = htmlEscape(asset["video"].str + suffix) - let poster = htmlEscape(asset["poster"].str + suffix) + let posterSuffix = try cacheBust ? "?v=" + sha(mediaDirectory.at(asset["scene"].str + ".jpg")).prefix(12) : "" + let poster = htmlEscape(asset["poster"].str + posterSuffix) let description = htmlEscape(asset["description"].string ?? asset["title"].str) let duration = String(format: "%d:%02d", asset["durationSeconds"].int / 60, asset["durationSeconds"].int % 60) let aspect = ["dual", "dynamic-dual"].contains(asset["presentation"].str) ? "16 / 5" : "16 / 10" @@ -90,6 +91,7 @@ struct VideoGallery { try "

\(ui["sections"][name].string ?? name)

" + collection( name, assets: assets, + mediaDirectory: destination, cacheBust: false, ) + "
" } @@ -106,6 +108,9 @@ struct VideoGallery { let document = try translateHTML(workspace.root.at("web/" + page).text(), TextCatalog(values: values, locale: locale), page) try document.walk { node in if node.tag == "html" { node["lang"] = locale } + if node.tag == "a", let href = node["href"] { + node["href"] = DocumentBuilder(workspace: workspace).localizedNoticeLink(href, locale: locale) + } if let source = node["data-document-src"] { let name = URL(fileURLWithPath: source).lastPathComponent node["data-document-src"] = "./content/" + name diff --git a/Tools/Tests/TatamiToolsTests/MediaTests.swift b/Tools/Tests/TatamiToolsTests/MediaTests.swift index cb6997c..548b816 100644 --- a/Tools/Tests/TatamiToolsTests/MediaTests.swift +++ b/Tools/Tests/TatamiToolsTests/MediaTests.swift @@ -230,3 +230,37 @@ func `invalid copy cannot remove an existing artifact`() throws { #expect(throws: (any Error).self) { try copy(fixture.directory.at("missing.json"), artifact) } #expect(try artifact.text() == "accepted evidence") } + +@Test +func `replacing poster changes its cache key without changing the video URL`() throws { + let fixture = try TemporaryFixture() + defer { fixture.remove() } + let poster = fixture.directory.at("borrow.jpg") + try poster.write("first poster") + let asset = try JSON + .parse( + #"{"scene":"borrow","locale":"en","title":"Borrow","description":"Borrow","video":"borrow.mp4","poster":"borrow.jpg","sha256":"0123456789abcdef","durationSeconds":14}"# + ) + let gallery = try VideoGallery(workspace: testWorkspace) + let first = try gallery.collection("borrow", assets: [asset], mediaDirectory: fixture.directory) + try poster.write("updated poster") + let second = try gallery.collection("borrow", assets: [asset], mediaDirectory: fixture.directory) + #expect(first != second) + #expect(first.contains("borrow.mp4?v=0123456789ab")) + #expect(second.contains("borrow.mp4?v=0123456789ab")) + #expect(try second.contains("borrow.jpg?v=" + sha(poster).prefix(12))) +} + +@Test +func `poster selection uses the configured time and rejects invalid frames`() throws { + let asset = try JSON.parse(#"{"posterSeconds":5}"#) + #expect(try VideoExporter.posterTime(asset: asset, timeline: .object([]), duration: 14) == 5) + for second in [-1, 14, 20] { + #expect(throws: (any Error).self) { + try VideoExporter.posterTime(asset: .object([("posterSeconds", .integer(second))]), timeline: .object([]), duration: 14) + } + } + #expect(throws: (any Error).self) { + try VideoExporter.posterTime(asset: asset.merging([("posterCaptionIndex", .integer(0))]), timeline: .object([]), duration: 14) + } +} diff --git a/NOTICE.ja.md b/docs/ja/NOTICE.md similarity index 83% rename from NOTICE.ja.md rename to docs/ja/NOTICE.md index b9c6550..afd8383 100644 --- a/NOTICE.ja.md +++ b/docs/ja/NOTICE.md @@ -1,5 +1,5 @@ -[English](NOTICE.md) · [한국어](NOTICE.ko.md) · [日本語](NOTICE.ja.md) · [简体中文](NOTICE.zh-Hans.md) · [繁體中文](NOTICE.zh-Hant.md) +[English](../../NOTICE.md) · [한국어](../ko/NOTICE.md) · [日本語](NOTICE.md) · [简体中文](../zh-Hans/NOTICE.md) · [繁體中文](../zh-Hant/NOTICE.md) @@ -10,9 +10,9 @@ Tatami はフォークではない独立プロジェクトです。次の先行 - 仮想ワークスペースの切り替えは Wojciech Kulik の [FlashSpace](GPL-3.0)に着想を得ました。ソースを複製せず、独自の構成で実装しています。 - タイルのモデルと移動、均等化、回転、反転、境界によるサイズ変更は、MIT の koekeishiya による [yabai] を基にしています。該当する著作権表示を以下に原文で掲載します。 -Tatami は [AGPL-3.0-only](LICENSE) で提供します。FlashSpace、yabai、その作者との提携や承認などの関係はありません。 +Tatami は [AGPL-3.0-only](../../LICENSE) で提供します。FlashSpace、yabai、その作者との提携や承認などの関係はありません。 -依存パッケージのライセンスと著作権の原文は [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) に掲載しています。 +依存パッケージのライセンスと著作権の原文は [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md) に掲載しています。 diff --git a/README.ja.md b/docs/ja/README.md similarity index 80% rename from README.ja.md rename to docs/ja/README.md index 1135596..ff3625c 100644 --- a/README.ja.md +++ b/docs/ja/README.md @@ -1,11 +1,11 @@ -[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · [简体中文](README.zh-Hans.md) · [繁體中文](README.zh-Hant.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) -# Tatami +# Tatami -[![最新リリース](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![ダウンロード](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 以降](https://img.shields.io/badge/macOS-14%2B-blue) [![ライセンス:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](LICENSE) +[![最新リリース](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![ダウンロード](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 以降](https://img.shields.io/badge/macOS-14%2B-blue) [![ライセンス:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](../../LICENSE) BSP タイル表示を備えた macOS 用ワークスペースマネージャです。 @@ -14,7 +14,7 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 ## Tatami の使い方を見る -[![仕事の流れに、必要な場所を。](web/media/ja/tour.jpg)](https://pangmo5.dev/Tatami/ja/#demo) +[![仕事の流れに、必要な場所を。](../../web/media/ja/tour.jpg)](https://pangmo5.dev/Tatami/ja/#demo) **[一連の作業を見る](https://pangmo5.dev/Tatami/ja/#demo)**。デザイン、執筆、レビュー、次の作業を借りる操作、集中環境の自動化、2 台目の画面への対応まで紹介します。実際の Tatami を使い、アプリと内容はデモ用です。表示するキーはこのデモの設定です。 @@ -22,11 +22,10 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 設定とガイドのスクリーンショット

- Tatami のガイド、プロファイルとワークスペースの設定、タイル表示の隣に借りた一時スペースです。 + Tatami のガイド、プロファイルとワークスペースの設定、タイル表示の隣に借りた一時スペースです。

-

元のサイズ:ガイド設定 · ワークスペース · 借りる
以前のバージョンで撮影したため、一部の表記は現在と異なります。

- +

元のサイズ:ガイド設定 · ワークスペース · 借りる
以前のバージョンで撮影したため、一部の表記は現在と異なります。

@@ -35,24 +34,26 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 ### ワークスペース -[![作業を切り替える](web/media/ja/workspaces.jpg)](https://pangmo5.dev/Tatami/ja/#demo-workspaces) +作業を切り替える - **仮想ワークスペース:** 作業ごとに必要なアプリを割り当ててまとめます。 - **使いやすく切り替え:** ショートカット、トラックパッドのジェスチャ、直前のワークスペースへの移動を使えます。 - **ジェスチャ設定:** 3 本指・4 本指の各方向に操作を割り当てられます。特定のプロファイルやワークスペースへの移動も選べます。 - **ワークスペースごとに一つのキー:** 切り替え・割り当て・借りる操作の修飾キーと**ワークスペースキー**を組み合わせます。直前・次・前への移動にも使え、操作別の上書きもできます。 - **切り替え方を選択:** 端での循環、空の作業をスキップ、アプリのフォーカスへの追従を設定できます。 -- **[自動で開くデモ](https://pangmo5.dev/Tatami/ja/#demo-autoopen):** 作業を開くと割り当てたアプリが起動し、閉じたウインドウも入り直すと開きます。 +- **自動起動:** ワークスペースを開くと割り当てたアプリを起動し、ウインドウを閉じた場合も次に開くときに再び表示します。 - **画面ごとの作業:** 特定の画面に固定するか、ポインタのある画面に開けます。再起動後も各画面の現在・直前の作業を記憶し、次・前・直前への移動範囲を個別に設定できます。 - **ワークスペースチェーン:** プロファイル内の作業を順に連結します。どのメンバーを選んでも、優先順・接続中の画面固定・動的配置に従って仲間を復元し、選んだ作業にフォーカスを残します。 - **画面をまたぐ操作:** 別の画面へフォーカスを移したり、選んだアプリを別の作業へ送ったりできます。 - **共有アプリ:** すべてのワークスペースで使うアプリを追加できます。 +
+ ### ウインドウのタイル表示(BSP) -[![新しいウインドウが自然に収まる](web/media/ja/tiling.jpg)](https://pangmo5.dev/Tatami/ja/#demo-tiling) +新しいウインドウが自然に収まる - **自動 BSP 配置:** 新しいウインドウは、現在の挿入先またはフォーカス中のタイルの隣に配置します。どちらもなければ、ツリーで最も浅いタイルを使います。 - **キーボード操作:** 推奨設定では、`ctrl + alt` と `h`、`j`、`k`、`l` でフォーカスを移動し、矢印キーでウインドウを入れ替え、`=` または `-` でフォーカス中のタイルを拡大・縮小します。 @@ -63,10 +64,12 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 - **配置を記憶:** 作業の切り替え、再起動、スリープ後も、ツリーと比率を保ちます。 - **余白の設定:** 内側と外側の余白を選べます。 +
+ ### プロファイル -[プロファイルと 2 画面の動画を見る](https://pangmo5.dev/Tatami/ja/#profiles)。 +作業環境ごと切り替える - **独立したプロファイル:** 作業をまとめ、構成全体を切り替えます。作業、アプリの割り当て、ショートカットを個別に持ちます。 - **すばやい切り替え:** キーやメニューバーで切り替えます。全画面を新しい構成に整え、再起動後も適切なプロファイルに戻ります。 @@ -74,10 +77,12 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 - **プロファイルのアイコン:** サイドバー、メニューバー、切り替え時に表示する SF Symbol を選べます。 - **構成を再利用:** **コピー元**と**複製**は共通のプレビューで確認できます。変更前に作業、アプリ、設定、保存済み配置を含めるか選べます。 +
+ ### 借りる:二つの作業を組み合わせる -[![会話を横に呼び出す](web/media/ja/borrow.jpg)](https://pangmo5.dev/Tatami/ja/#demo-borrow) +会話を横に呼び出す - **並べて使う:** 別の作業を画面の端に借りて、両方を独立して配置します。ウインドウは境界を越えません。 - **実際の作業をそのまま:** 借りた領域は実際の作業なので、編集内容も元の場所に残ります。 @@ -86,29 +91,35 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 - **所属を表示:** 借りたウインドウに、元のワークスペースのアイコンを表示します。 - **一時スペース:** 借りるための作業です。通常の切り替えや単独の有効化には入らず、呼び出すとアプリが開きます。 +
+ ### 常に手前 -[作業が変わっても同じ状態ウインドウを見る](https://pangmo5.dev/Tatami/ja/#demo-shared)。 +作業が変わっても同じ状態ウインドウを使う - **作業別・共有:** 一つの作業だけで手前に置くか、共有アプリにしてどこでも表示できます。 - **SIP 変更不要:** ScreenCaptureKit のミラーを手前に表示し、操作時に実際のウインドウへ渡します。 - **わかりやすい重なり順:** 手前のウインドウは最近選んだ順に重なります。画面収録の許可が必要です。 - **そのまま:** 位置と大きさを保ちながら、自動起動、フォーカス、マウス追従、切り替えに参加します。ミラーや画面収録の許可は不要です。 +
+ ### フォーカスとカーソル -[キーとポインタに合わせたフォーカス移動を見る](https://pangmo5.dev/Tatami/ja/#demo-focus)。 +意図に合わせてフォーカスを移す - **二つの方式:** FFM はポインタの下にキーボードフォーカスを移し、MFF は Tatami が選んだウインドウへポインタを移します。手前・共有の手前・そのままのウインドウにも対応します。 - **閉じた後のフォーカス:** 残った中で最近使ったウインドウへ戻ります。 - **カーソル操作:** ワークスペースの切り替え中にカーソルを隠せます。 +
+ ### 画面と設定 -[実際の CLI、フック、設定の即時反映を見る](https://pangmo5.dev/Tatami/ja/#automation)。 +CLI で集中できる環境を用意する - **5 言語:** macOS のアプリ言語に合わせ、英語・韓国語・日本語・簡体字・繁体字(台湾)で使えます。 - **メニューバーの設定:** 現在の作業のアイコン・名前と、必要に応じてプロファイルの情報を表示できます。 @@ -121,10 +132,12 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 - **CLI 自動化:** `tatami workspace activate ` や `tatami workspace list` などのコマンドをスクリプトで使えます。 - **自動更新:** Sparkle で新しいリリースを受け取れます。 +
+ ### 使いながら設定 -[ショートカットの練習と提案の確認を見る](https://pangmo5.dev/Tatami/ja/#guided-setup)。 +使いながら覚える - **使いながら学ぶ:** 初回起動時に安全な仮想画面で、作業、切り替え・ジェスチャ、BSP、借りる・一時スペース、手前・そのまま、MFF・FFM、アプリ・ウインドウ切り替えを順に学べます。 - **この Mac から開始:** 実行中アプリの情報と接続画面から下書きを作ります。一般的な分類ではなく繰り返す作業に合わせ、画面の内容は取得しません。 @@ -132,6 +145,8 @@ Tatami はアプリを仮想ワークスペースにまとめ、キーや設定 - **続けて練習:** 実際のキーやジェスチャでプレビューを操作し、前のレッスンの操作も続けて使えます。 - **まず下書き:** **設定を適用**するまで実際のウインドウや `config.toml` は変えません。**設定 → 一般**からいつでも再開できます。 +
+ ## 必要な環境 @@ -170,9 +185,9 @@ open Tatami.xcworkspace 設定は `~/.config/tatami/config.toml` に保存され、`[settings.layout]`、`[settings.focus]`、`[settings.gestures]`、`[settings.shortcuts]` などのテーブルに分かれます。作業、アプリ、共有アプリも同じファイルです。フックは**設定 → フック**か `[[hooks]]` で管理します。GUI は `command` をシェル文字列にせず、実行ファイルと引数を分けて扱い、変更を即時反映します。 -全項目、既定値、ショートカットの書き方は [docs/CONFIGURATION.md](docs/ja/CONFIGURATION.md) を参照してください。 +全項目、既定値、ショートカットの書き方は [docs/CONFIGURATION.md](CONFIGURATION.md) を参照してください。 -会議の操作パネルや作業を切り替えたときのピクチャインピクチャなど、アプリ別の動作は[トラブルシューティング](docs/ja/TROUBLESHOOTING.md)を参照してください。 +会議の操作パネルや作業を切り替えたときのピクチャインピクチャなど、アプリ別の動作は[トラブルシューティング](TROUBLESHOOTING.md)を参照してください。 ### コマンドライン @@ -189,7 +204,7 @@ tatami layout balance CLI はプロファイル・作業の管理、フックの確認、安定した JSON 出力に加え、ジェスチャと同じフォーカス、配置、アプリ、タイル表示、切り替え、借りる操作を分類して提供します。Tatami の起動が必要です。 -[CLI の完全なガイド](docs/ja/CLI.md)、または [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/ja/cli.html) の Web 版を参照してください。 +[CLI の完全なガイド](CLI.md)、または [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/ja/cli.html) の Web 版を参照してください。 ## 技術構成 @@ -208,12 +223,12 @@ CLI はプロファイル・作業の管理、フックの確認、安定した ## 参考にしたプロジェクト -Tatami は Wojciech Kulik の [FlashSpace](仮想作業の切り替え)と koekeishiya の [yabai](タイル表示のモデル)を参考にしています。帰属は [NOTICE.md](NOTICE.ja.md)、依存ライセンスは [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) を参照してください。 +Tatami は Wojciech Kulik の [FlashSpace](仮想作業の切り替え)と koekeishiya の [yabai](タイル表示のモデル)を参考にしています。帰属は [NOTICE.md](NOTICE.md)、依存ライセンスは [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md) を参照してください。 ## ライセンス -[AGPL-3.0-only](LICENSE)。 +[AGPL-3.0-only](../../LICENSE)。 [FlashSpace]: https://github.com/wojciech-kulik/FlashSpace [yabai]: https://github.com/koekeishiya/yabai diff --git a/docs/ja/THIRD_PARTY_NOTICES.md b/docs/ja/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..d5a6155 --- /dev/null +++ b/docs/ja/THIRD_PARTY_NOTICES.md @@ -0,0 +1,12 @@ + +[English](../../THIRD_PARTY_NOTICES.md) · [한국어](../ko/THIRD_PARTY_NOTICES.md) · [日本語](THIRD_PARTY_NOTICES.md) · [简体中文](../zh-Hans/THIRD_PARTY_NOTICES.md) · [繁體中文](../zh-Hant/THIRD_PARTY_NOTICES.md) + + + +# 外部ライブラリの告知 + +Tatami アプリの依存関係のバージョンとリビジョンは、`Tuist/Package.resolved` に基づいています。 + +[アプリのライセンスと著作権表示の全文](../../THIRD_PARTY_NOTICES.md)は原文でご確認ください。このページでは概要の説明のみを翻訳しています。 + +開発用の自動化は、`Tools/Package.resolved` で固定された別のパッケージ群を使います。[開発ツールの依存関係の表示](../../Tools/THIRD_PARTY_NOTICES.md)は原文でご確認ください。 diff --git a/NOTICE.ko.md b/docs/ko/NOTICE.md similarity index 84% rename from NOTICE.ko.md rename to docs/ko/NOTICE.md index aa9b3e3..d54aa9d 100644 --- a/NOTICE.ko.md +++ b/docs/ko/NOTICE.md @@ -1,5 +1,5 @@ -[English](NOTICE.md) · [한국어](NOTICE.ko.md) · [日本語](NOTICE.ja.md) · [简体中文](NOTICE.zh-Hans.md) · [繁體中文](NOTICE.zh-Hant.md) +[English](../../NOTICE.md) · [한국어](NOTICE.md) · [日本語](../ja/NOTICE.md) · [简体中文](../zh-Hans/NOTICE.md) · [繁體中文](../zh-Hant/NOTICE.md) @@ -10,9 +10,9 @@ Tatami는 포크가 아닌 독립 프로젝트예요. 다음 선행 작업을 - 가상 작업 공간 전환 개념은 GPL-3.0으로 제공되는 Wojciech Kulik의 [FlashSpace]에서 영감을 받았어요. 소스를 복사하지 않고 Tatami의 구조에서 동작을 다시 구현했어요. - 창 타일링 모델과 이동·균등 배치·회전·뒤집기·경계 기반 크기 조절은 MIT 라이선스인 koekeishiya의 [yabai]를 바탕으로 했어요. 해당 저작권 고지를 아래에 원문으로 실었어요. -Tatami는 [AGPL-3.0-only](LICENSE)로 제공해요. FlashSpace, yabai 또는 저자와 제휴·보증 등의 관계는 없어요. +Tatami는 [AGPL-3.0-only](../../LICENSE)로 제공해요. FlashSpace, yabai 또는 저자와 제휴·보증 등의 관계는 없어요. -패키지 의존성의 라이선스와 저작권 원문은 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)에 실었어요. +패키지 의존성의 라이선스와 저작권 원문은 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)에 실었어요. diff --git a/README.ko.md b/docs/ko/README.md similarity index 80% rename from README.ko.md rename to docs/ko/README.md index 2d2a0bb..f4ddcea 100644 --- a/README.ko.md +++ b/docs/ko/README.md @@ -1,11 +1,11 @@ -[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · [简体中文](README.zh-Hans.md) · [繁體中文](README.zh-Hant.md) +[English](../../README.md) · [한국어](README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](../zh-Hant/README.md) -# Tatami +# Tatami -[![최신 릴리스](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![다운로드](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 이상](https://img.shields.io/badge/macOS-14%2B-blue) [![라이선스: AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](LICENSE) +[![최신 릴리스](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![다운로드](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 이상](https://img.shields.io/badge/macOS-14%2B-blue) [![라이선스: AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](../../LICENSE) BSP 창 타일링을 갖춘 macOS 작업 공간 관리자예요. @@ -14,7 +14,7 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 ## Tatami 사용 모습 -[![모든 작업에 알맞은 자리를 만들어요.](web/media/ko/tour.jpg)](https://pangmo5.dev/Tatami/ko/#demo) +[![모든 작업에 알맞은 자리를 만들어요.](../../web/media/ko/tour.jpg)](https://pangmo5.dev/Tatami/ko/#demo) **[전체 작업 흐름 보기](https://pangmo5.dev/Tatami/ko/#demo)**. 디자인, 글쓰기, 검토, 다음 할 일 빌려오기, 집중 환경 자동화, 두 번째 화면 연결까지 이어져요. 실제 Tatami로 창을 관리하며 앱과 내용은 데모용이에요. 표시한 단축키는 이 데모에서 설정한 키예요. @@ -22,11 +22,10 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 설정과 시작 안내 스크린샷

- Tatami 시작 안내, 프로필과 작업 공간 설정, 타일링한 작업 공간 옆에 빌려온 임시 공간이에요. + Tatami 시작 안내, 프로필과 작업 공간 설정, 타일링한 작업 공간 옆에 빌려온 임시 공간이에요.

-

원본 크기: 가이드 설정 · 작업 공간 · 빌려오기
이전 버전에서 촬영했어요. 일부 문구는 현재 버전과 달라요.

- +

원본 크기: 가이드 설정 · 작업 공간 · 빌려오기
이전 버전에서 촬영했어요. 일부 문구는 현재 버전과 달라요.

@@ -35,24 +34,26 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 ### 작업 공간 -[![작업 사이를 오가기](web/media/ko/workspaces.jpg)](https://pangmo5.dev/Tatami/ko/#demo-workspaces) +작업 사이를 오가기 - **가상 작업 공간:** 작업 공간마다 필요한 앱을 배정해서 모아요. - **편한 방식으로 전환:** 단축키, 트랙패드 제스처, 최근 작업 공간 이동을 사용할 수 있어요. - **제스처 설정:** 세 손가락·네 손가락 쓸기의 모든 방향에 동작을 연결해요. 특정 프로필이나 작업 공간으로 가는 명령도 연결할 수 있어요. - **작업 공간마다 키 하나:** 전환·배정·빌려오기 보조키와 **작업 공간 키**를 함께 눌러요. 같은 키 체계로 최근·다음·이전 작업 공간에도 이동할 수 있고, 각 동작에 별도 단축키를 지정할 수도 있어요. - **전환 방식 선택:** 끝에서 처음으로 돌아가기, 빈 공간 건너뛰기, 앱 포커스 따라가기를 설정할 수 있어요. -- **[자동 열기 데모](https://pangmo5.dev/Tatami/ko/#demo-autoopen):** 작업 공간에 들어가면 배정한 앱이 열려요. 창을 닫아도 다시 들어가면 열어줘요. +- **자동 열기:** 작업 공간으로 전환하면 지정한 앱을 실행하고, 창을 닫았더라도 다시 들어올 때 열어요. - **화면별 작업 공간:** 특정 화면에 고정하거나 마우스가 있는 화면에 열 수 있어요. 각 화면은 재실행 후에도 활성·최근 작업 공간을 기억해요. 다음·이전·최근 이동의 범위는 각각 현재 화면이나 전체 화면으로 정할 수 있어요. - **작업 공간 체인:** 프로필 안의 작업 공간을 순서대로 연결해요. 어느 구성원을 선택해도 체인 우선순위, 연결된 화면 고정, 동적 배치에 따라 함께 놓여요. 포커스는 선택한 작업에 남아요. - **화면 간 조작:** 다른 화면으로 포커스를 옮기거나 포커스한 앱을 다른 작업 공간에 보낼 수 있어요. - **공용 앱:** 모든 작업 공간에서 함께 쓸 앱을 추가해요. +
+ ### 창 타일링(BSP) -[![새 창이 제자리를 찾도록 하기](web/media/ko/tiling.jpg)](https://pangmo5.dev/Tatami/ko/#demo-tiling) +새 창이 제자리를 찾도록 하기 - **자동 BSP 배치:** 새 창을 현재 삽입 지점이나 포커스된 타일 옆에 배치해요. 둘 다 없으면 트리에서 가장 얕은 타일을 사용해요. - **키보드 조작:** 권장 단축키에서는 `ctrl + alt`과 `h`, `j`, `k`, `l`로 포커스를 옮기고, 화살표 키로 창 위치를 바꾸며, `=` 또는 `-`으로 포커스된 타일을 키우거나 줄여요. @@ -63,10 +64,12 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 - **배치 기억:** 작업 공간 전환, 앱 재실행, 시스템 잠자기 후에도 배치 트리와 비율이 남아요. - **여백 설정:** 창 사이와 바깥 여백을 정할 수 있어요. +
+ ### 프로필 -[프로필과 두 화면 영상 모음 보기](https://pangmo5.dev/Tatami/ko/#profiles). +전체 구성 전환하기 - **독립 프로필:** 작업 공간을 묶어 전체 구성을 한 번에 바꿔요. 프로필마다 작업 공간·앱 배정·단축키를 따로 저장해요. - **빠른 프로필 전환:** 단축키나 메뉴 막대에서 전환해요. 모든 화면을 새 구성으로 정리하고 재실행 후에도 알맞은 프로필로 돌아와요. @@ -74,10 +77,12 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 - **프로필 아이콘:** 사이드바·메뉴 막대·전환 알림에 표시할 SF Symbol을 정해요. - **기존 구성 재사용:** **가져오기**와 **복제**에서 같은 미리보기를 사용해요. 변경 전에 작업 공간·앱·설정·저장한 배치를 골라 포함하거나 제외할 수 있어요. +
+ ### 빌려오기: 두 작업 공간 함께 쓰기 -[![대화를 옆으로 가져오기](web/media/ko/borrow.jpg)](https://pangmo5.dev/Tatami/ko/#demo-borrow) +대화를 옆으로 가져오기 - **나란히 사용:** 다른 작업 공간을 화면 가장자리로 빌려와요. 두 영역은 따로 타일링되며 창은 경계를 넘지 않아요. - **실제 작업 그대로:** 빌려온 영역은 실제 작업 공간이에요. 편집한 내용은 원래 공간에도 남아요. @@ -86,29 +91,35 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 - **소속 표시:** 빌려온 창에는 해당 작업 공간의 아이콘이 보여요. - **임시 공간:** 빌려오기로만 쓰는 공간이에요. 일반 전환이나 단독 활성화에는 포함되지 않고, 꺼낼 때 필요한 앱이 열려요. +
+ ### 항상 위 -[여러 작업 공간 위에서 같은 상태 창 보기](https://pangmo5.dev/Tatami/ko/#demo-shared). +여러 작업에서 같은 상태 창 보기 - **작업 공간별 또는 공용:** 한 공간에서만 앱을 항상 위에 두거나 공용 앱으로 추가해 어디서나 볼 수 있어요. - **SIP 변경 불필요:** ScreenCaptureKit 미러를 항상 위에 두고, 조작할 때 실제 창으로 연결해요. - **예측 가능한 순서:** 항상 위에 둔 여러 창은 최근 포커스한 순서로 쌓여요. 화면 기록 권한이 필요해요. - **그대로 두기:** 창의 위치와 크기를 유지하면서 자동 열기·포커스·마우스에 따른 포커스·창 전환에 참여해요. 미러나 화면 기록 권한 없이 사용할 수 있어요. +
+ ### 포커스와 커서 -[키보드와 포인터에 따른 포커스 이동 보기](https://pangmo5.dev/Tatami/ko/#demo-focus). +내 의도에 따라 포커스 이동하기 - **두 가지 포커스 방식:** 마우스 따라가기는 포인터 아래 창에 키보드 포커스를 줘요. 포커스 따라가기는 Tatami가 창을 바꿀 때 포인터를 옮겨요. 항상 위·공용 항상 위·그대로 두기 창에서도 동작해요. - **닫은 뒤 포커스:** 남은 창 중 가장 최근에 쓰던 창으로 돌아가요. - **커서 제어:** 작업 공간을 전환하는 동안 커서를 숨길 수 있어요. +
+ ### 화면과 설정 -[실제 CLI·훅·설정 바로 적용 보기](https://pangmo5.dev/Tatami/ko/#automation). +CLI로 집중할 환경 준비하기 - **다섯 언어:** macOS 앱 언어 설정에 따라 영어·한국어·일본어·중국어 간체·대만 번체로 쓸 수 있어요. - **메뉴 막대 설정:** 활성 작업 공간의 아이콘·이름과 필요한 경우 프로필의 아이콘·이름을 표시해요. @@ -121,10 +132,12 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 - **CLI 자동화:** `tatami workspace activate `, `tatami workspace list` 같은 명령을 스크립트에서 사용할 수 있어요. - **자동 업데이트:** Sparkle로 새 릴리스를 받아요. +
+ ### 시작 안내 -[단축키 연습과 제안 검토 보기](https://pangmo5.dev/Tatami/ko/#guided-setup). +직접 사용하며 익히기 - **직접 배우기:** 처음 실행하면 안전한 가상 화면에서 작업 공간, 전환·제스처, BSP 타일링, 빌려오기·임시 공간, 항상 위·그대로 두기, 포커스·포인터 따라가기, 앱·창 전환을 차례로 익혀요. - **이 Mac에서 시작:** 실행 중인 앱 정보와 연결된 화면을 바탕으로 초안을 만들어요. 일반적인 분류보다 반복하는 작업에 맞춰 구성하고 화면 내용은 수집하지 않아요. @@ -132,6 +145,8 @@ Tatami는 앱을 가상 작업 공간에 모으고, 단축키나 설정한 트 - **이어서 연습:** 실제 단축키와 제스처로 미리보기를 조작해요. 다음 단계에서도 앞서 익힌 명령을 계속 쓸 수 있어요. - **초안 먼저:** **설정 적용** 전에는 실제 창을 움직이거나 `config.toml`에 쓰지 않아요. **설정 → 일반**에서 언제든 다시 열 수 있어요. +
+ ## 필요한 환경 @@ -170,9 +185,9 @@ open Tatami.xcworkspace 설정은 `~/.config/tatami/config.toml`에 저장돼요. `[settings.layout]`, `[settings.focus]`, `[settings.gestures]`, `[settings.shortcuts]` 같은 표로 나뉘며 작업 공간·앱 배정·공용 앱도 같은 파일에 있어요. 훅은 **설정 → 훅**이나 파일의 `[[hooks]]`에서 관리해요. GUI는 `command`을 셸 문자열로 합치지 않고 실행 파일과 각 인자를 따로 다뤄요. 앱이나 파일에서 수정하면 바로 반영돼요. -모든 항목과 기본값, 단축키 문법은 [docs/CONFIGURATION.md](docs/ko/CONFIGURATION.md)에서 확인해요. +모든 항목과 기본값, 단축키 문법은 [docs/CONFIGURATION.md](CONFIGURATION.md)에서 확인해요. -회의 조작 창이나 작업 공간 전환 중 화면 속 화면처럼 앱마다 다른 동작은 [문제 해결](docs/ko/TROUBLESHOOTING.md)에서 확인해요. +회의 조작 창이나 작업 공간 전환 중 화면 속 화면처럼 앱마다 다른 동작은 [문제 해결](TROUBLESHOOTING.md)에서 확인해요. ### 커맨드라인 @@ -189,7 +204,7 @@ tatami layout balance CLI는 프로필·작업 공간 관리, 훅 조회, 안정된 JSON 출력과 제스처로 실행할 수 있는 포커스·배치·앱·타일링·전환·빌려오기 명령을 분야별로 제공해요. Tatami가 실행 중이어야 해요. -[전체 CLI 안내](docs/ko/CLI.md)를 읽거나 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/ko/cli.html)에서 웹으로 확인할 수 있어요. +[전체 CLI 안내](CLI.md)를 읽거나 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/ko/cli.html)에서 웹으로 확인할 수 있어요. ## 기술 구성 @@ -208,12 +223,12 @@ CLI는 프로필·작업 공간 관리, 훅 조회, 안정된 JSON 출력과 제 ## 도움을 준 프로젝트 -Tatami는 Wojciech Kulik의 [FlashSpace]에서 가상 작업 공간 전환 개념을, koekeishiya의 [yabai]에서 창 타일링 방식을 참고했어요. 출처는 [NOTICE.md](NOTICE.ko.md), 의존성 라이선스는 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)에서 확인할 수 있어요. +Tatami는 Wojciech Kulik의 [FlashSpace]에서 가상 작업 공간 전환 개념을, koekeishiya의 [yabai]에서 창 타일링 방식을 참고했어요. 출처는 [NOTICE.md](NOTICE.md), 의존성 라이선스는 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)에서 확인할 수 있어요. ## 라이선스 -[AGPL-3.0-only](LICENSE). +[AGPL-3.0-only](../../LICENSE). [FlashSpace]: https://github.com/wojciech-kulik/FlashSpace [yabai]: https://github.com/koekeishiya/yabai diff --git a/docs/ko/THIRD_PARTY_NOTICES.md b/docs/ko/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..bfc8ef8 --- /dev/null +++ b/docs/ko/THIRD_PARTY_NOTICES.md @@ -0,0 +1,12 @@ + +[English](../../THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.md) · [日本語](../ja/THIRD_PARTY_NOTICES.md) · [简体中文](../zh-Hans/THIRD_PARTY_NOTICES.md) · [繁體中文](../zh-Hant/THIRD_PARTY_NOTICES.md) + + + +# 외부 라이브러리 고지 + +Tatami 앱 의존성의 버전과 리비전은 `Tuist/Package.resolved`을 기준으로 해요. + +[앱의 전체 라이선스 및 저작권 고지](../../THIRD_PARTY_NOTICES.md)는 원문으로 제공해요. 이 페이지는 개요 설명만 번역해요. + +개발 자동화는 `Tools/Package.resolved`에 고정된 별도의 패키지 집합을 사용해요. [개발 도구 의존성 고지](../../Tools/THIRD_PARTY_NOTICES.md)는 원문으로 제공해요. diff --git a/NOTICE.zh-Hans.md b/docs/zh-Hans/NOTICE.md similarity index 84% rename from NOTICE.zh-Hans.md rename to docs/zh-Hans/NOTICE.md index ed6781a..286a2b1 100644 --- a/NOTICE.zh-Hans.md +++ b/docs/zh-Hans/NOTICE.md @@ -1,5 +1,5 @@ -[English](NOTICE.md) · [한국어](NOTICE.ko.md) · [日本語](NOTICE.ja.md) · [简体中文](NOTICE.zh-Hans.md) · [繁體中文](NOTICE.zh-Hant.md) +[English](../../NOTICE.md) · [한국어](../ko/NOTICE.md) · [日本語](../ja/NOTICE.md) · [简体中文](NOTICE.md) · [繁體中文](../zh-Hant/NOTICE.md) @@ -10,9 +10,9 @@ Tatami 是独立项目,并非分支,其设计参考了以下工作: - 虚拟工作区切换概念受到 Wojciech Kulik 的 [FlashSpace](GPL-3.0)启发。Tatami 未复制其源码,而是在自身架构中重新实现相似行为。 - 窗口平铺模型及 BSP 的移动、均衡、旋转、镜像、边界调整操作改编自 koekeishiya 的 MIT 许可项目 [yabai]。相关版权声明原文列于下方。 -Tatami 采用 [AGPL-3.0-only](LICENSE) 许可证,与 FlashSpace、yabai 及其作者不存在关联、背书或其他联系。 +Tatami 采用 [AGPL-3.0-only](../../LICENSE) 许可证,与 FlashSpace、yabai 及其作者不存在关联、背书或其他联系。 -依赖包的许可证与版权声明原文见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。 +依赖包的许可证与版权声明原文见 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)。 diff --git a/README.zh-Hans.md b/docs/zh-Hans/README.md similarity index 78% rename from README.zh-Hans.md rename to docs/zh-Hans/README.md index 8c8ab3e..cf38ac2 100644 --- a/README.zh-Hans.md +++ b/docs/zh-Hans/README.md @@ -1,11 +1,11 @@ -[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · [简体中文](README.zh-Hans.md) · [繁體中文](README.zh-Hant.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](README.md) · [繁體中文](../zh-Hant/README.md) -# Tatami +# Tatami -[![最新版本](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![下载](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 或更新版本](https://img.shields.io/badge/macOS-14%2B-blue) [![许可证:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](LICENSE) +[![最新版本](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![下载](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 或更新版本](https://img.shields.io/badge/macOS-14%2B-blue) [![许可证:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](../../LICENSE) 支持 BSP 窗口平铺的 macOS 工作区管理器。 @@ -14,7 +14,7 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 ## 看看 Tatami 的实际操作 -[![为整个工作流程腾出空间。](web/media/zh-Hans/tour.jpg)](https://pangmo5.dev/Tatami/zh-Hans/#demo) +[![为整个工作流程腾出空间。](../../web/media/zh-Hans/tour.jpg)](https://pangmo5.dev/Tatami/zh-Hans/#demo) **[观看完整工作流程](https://pangmo5.dev/Tatami/zh-Hans/#demo)**:设计、写作、评审、借用待办事项、自动准备专注环境,再连接第二个显示器。窗口由实际的 Tatami 管理,应用和内容为演示素材。快捷键采用本次演示的配置。 @@ -22,11 +22,10 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 设置与设置向导截图

- Tatami 设置向导、配置方案与工作区设置,以及平铺工作区旁借来的暂存区。 + Tatami 设置向导、配置方案与工作区设置,以及平铺工作区旁借来的暂存区。

-

原图:引导设置 · 工作区 · 借用
截图来自较早版本,部分标签已更新。

- +

原图:引导设置 · 工作区 · 借用
截图来自较早版本,部分标签已更新。

@@ -35,24 +34,26 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 ### 工作区 -[![在任务之间切换](web/media/zh-Hans/workspaces.jpg)](https://pangmo5.dev/Tatami/zh-Hans/#demo-workspaces) +在任务之间切换 - **虚拟工作区:** 按工作区分配和组织应用。 - **灵活切换:** 使用快捷键、触控板手势或最近工作区操作。 - **自定义手势:** 为三指、四指滑动的各个方向绑定快捷键操作,也可以指定某个配置方案或工作区。 - **每个工作区一个按键:** 将切换、分配或借用修饰键与**工作区按键**组合使用。同一套按键也用于最近、下一个和上一个目标,每项操作还可以单独覆盖。 - **可选切换行为:** 启用循环、跳过空工作区或跟随应用焦点。 -- **[自动打开演示](https://pangmo5.dev/Tatami/zh-Hans/#demo-autoopen):** 激活工作区时启动分配的应用,重新进入时打开之前关闭的窗口。 +- **自动打开:** 激活工作区时启动指定应用;如果关闭了窗口,再次进入时会重新打开。 - **每个显示器独立管理:** 固定工作区到显示器,或在指针所在屏幕打开动态工作区。各显示器在重启后仍保留当前和最近工作区;前后切换与最近切换可分别限定为当前屏幕或所有屏幕。 - **工作区链:** 在配置方案内按顺序连接工作区。切换到任一成员时,按链优先级恢复可用伙伴,遵守已连接显示器的固定位置和链动态分配,焦点仍留在所选工作区。 - **跨显示器控制:** 在显示器间移动焦点,或把聚焦的应用移到其他工作区。 - **共享应用:** 添加应出现在每个工作区的应用。 +
+ ### 窗口平铺(BSP) -[![让新窗口找到位置](web/media/zh-Hans/tiling.jpg)](https://pangmo5.dev/Tatami/zh-Hans/#demo-tiling) +让新窗口找到位置 - **自动 BSP 布局:** 将新窗口放在当前插入目标或焦点窗口所在区域的旁边。两者都不可用时,使用树中层级最浅的区域。 - **键盘操作:** 使用推荐快捷键时,按住 `ctrl + alt`,配合 `h`、`j`、`k` 或 `l` 移动焦点,配合方向键交换窗口,配合 `=` 或 `-` 放大或缩小焦点窗口所在的区域。 @@ -63,10 +64,12 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 - **持久布局:** 切换工作区、重新启动和系统睡眠后,保留布局树及比例。 - **可调间距:** 设置内部和外部间距。 +
+ ### 配置方案 -[观看配置方案与双屏演示](https://pangmo5.dev/Tatami/zh-Hans/#profiles)。 +切换整套配置 - **独立配置方案:** 分组管理工作区,一次切换整套环境。每个方案分别保存工作区、应用分配和快捷键。 - **快速切换方案:** 通过快捷键或菜单栏切换,所有显示器重新平铺,重启后返回合适的配置方案。 @@ -74,10 +77,12 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 - **方案图标:** 选择显示在侧边栏、菜单栏和切换反馈中的 SF Symbol。 - **复用现有配置:** **复制自**和**复制**共用预览,在更改前选择保留或跳过工作区、应用、设置和保存的布局。 +
+ ### 借用:组合两个工作区 -[![把对话放到旁边](web/media/zh-Hans/borrow.jpg)](https://pangmo5.dev/Tatami/zh-Hans/#demo-borrow) +把对话放到旁边 - **并排组合:** 把另一个工作区借到屏幕任一边缘,两个区域独立平铺,窗口不会越界。 - **实时双向:** 借来的区域就是实际工作区,编辑会保留下来。 @@ -86,29 +91,35 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 - **显示归属:** 借来的窗口显示所属工作区图标。 - **暂存区:** 仅供借用,不参与普通切换,也不会单独激活,调出时自动打开应用。 +
+ ### 置顶 -[观看跨工作区的共享状态窗口](https://pangmo5.dev/Tatami/zh-Hans/#demo-shared)。 +跨任务使用同一个状态窗口 - **单独或共享:** 在一个工作区置顶应用,或加入共享应用后在所有工作区置顶。 - **无需修改 SIP:** 使用置顶的 ScreenCaptureKit 镜像,交互时切换到实际窗口。 - **可预测的堆叠:** 多个置顶窗口按最近焦点顺序堆叠,需要屏幕录制权限。 - **保持原样:** 保留位置和大小,同时参与自动打开、焦点、焦点跟随鼠标和窗口切换,无需镜像或屏幕录制权限。 +
+ ### 焦点与指针 -[观看焦点跟随键盘和指针](https://pangmo5.dev/Tatami/zh-Hans/#demo-focus)。 +让焦点跟随你的意图 - **两种明确的焦点模式:** 焦点跟随鼠标让指针下方的窗口获得键盘焦点;鼠标跟随焦点在 Tatami 切换窗口后移动指针,包含置顶、共享置顶和保持原样窗口。 - **关闭后恢复焦点:** 返回剩余窗口中最近使用的窗口。 - **指针控制:** 可在切换工作区时隐藏指针。 +
+ ### 界面与配置 -[观看实际 CLI、钩子和实时配置](https://pangmo5.dev/Tatami/zh-Hans/#automation)。 +用 CLI 准备专注环境 - **五种界面语言:** 跟随 macOS 应用语言设置,支持英语、韩语、日语、简体中文和繁体中文(台湾)。 - **自定义菜单栏:** 显示当前工作区的图标或名称,并可显示活动配置方案的图标或名称。 @@ -121,10 +132,12 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 - **可脚本化 CLI:** 使用 `tatami workspace activate `、`tatami workspace list` 等领域命令。 - **自动更新:** 通过 Sparkle 获取新版本。 +
+ ### 设置向导 -[观看快捷键练习和建议检查](https://pangmo5.dev/Tatami/zh-Hans/#guided-setup)。 +边用边学 - **边用边学:** 首次启动时,在安全的虚拟桌面依次学习工作区、切换与手势、BSP 平铺、借用与暂存区、置顶与保持原样、MFF/FFM 和应用窗口切换。 - **基于这台 Mac:** 使用运行中应用的信息和已连接显示器的几何数据,按重复进行的任务组织应用,而非套用通用分类。不捕获屏幕内容。 @@ -132,6 +145,8 @@ Tatami 把应用组织到虚拟工作区,通过快捷键或自定义触控板 - **连续练习界面:** 实际快捷键和触控板手势控制预览,之前学过的命令在后续课程中仍可使用。 - **先用草稿:** 点击**应用设置**前,不移动实际窗口或写入 `config.toml`。可随时从**设置 → 通用**重新打开。 +
+ ## 系统要求 @@ -170,9 +185,9 @@ open Tatami.xcworkspace 设置保存在 `~/.config/tatami/config.toml`,分为 `[settings.layout]`、`[settings.focus]`、`[settings.gestures]`、`[settings.shortcuts]` 等表。工作区、应用分配和共享应用也在同一文件中。生命周期钩子可在**设置 → 钩子**或 `[[hooks]]` 中管理。GUI 分别保存可执行文件和各 argv,不把 `command` 当作 shell 字符串。应用内或手动修改都会实时生效。 -完整键、默认值和快捷键语法见 [docs/CONFIGURATION.md](docs/zh-Hans/CONFIGURATION.md)。 +完整键、默认值和快捷键语法见 [docs/CONFIGURATION.md](CONFIGURATION.md)。 -关于各应用的窗口行为,包括浮动会议控件和跨工作区的画中画,请参阅[故障排查](docs/zh-Hans/TROUBLESHOOTING.md)。 +关于各应用的窗口行为,包括浮动会议控件和跨工作区的画中画,请参阅[故障排查](TROUBLESHOOTING.md)。 ### 命令行 @@ -189,7 +204,7 @@ tatami layout balance CLI 按领域提供配置方案与工作区管理、钩子查询、稳定 JSON 输出,以及与手势相同的焦点、布局、应用、平铺、循环切换和借用操作。Tatami 必须正在运行。 -阅读[完整 CLI 参考](docs/zh-Hans/CLI.md),或在 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/zh-Hans/cli.html) 查看网页版本。 +阅读[完整 CLI 参考](CLI.md),或在 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/zh-Hans/cli.html) 查看网页版本。 ## 技术栈 @@ -208,12 +223,12 @@ CLI 按领域提供配置方案与工作区管理、钩子查询、稳定 JSON ## 致谢 -Tatami 受到 Wojciech Kulik 的 [FlashSpace](虚拟工作区切换概念)和 koekeishiya 的 [yabai](窗口平铺模型)启发。署名见 [NOTICE.md](NOTICE.zh-Hans.md),依赖许可证见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。 +Tatami 受到 Wojciech Kulik 的 [FlashSpace](虚拟工作区切换概念)和 koekeishiya 的 [yabai](窗口平铺模型)启发。署名见 [NOTICE.md](NOTICE.md),依赖许可证见 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)。 ## 许可证 -[AGPL-3.0-only](LICENSE)。 +[AGPL-3.0-only](../../LICENSE)。 [FlashSpace]: https://github.com/wojciech-kulik/FlashSpace [yabai]: https://github.com/koekeishiya/yabai diff --git a/docs/zh-Hans/THIRD_PARTY_NOTICES.md b/docs/zh-Hans/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..233e484 --- /dev/null +++ b/docs/zh-Hans/THIRD_PARTY_NOTICES.md @@ -0,0 +1,12 @@ + +[English](../../THIRD_PARTY_NOTICES.md) · [한국어](../ko/THIRD_PARTY_NOTICES.md) · [日本語](../ja/THIRD_PARTY_NOTICES.md) · [简体中文](THIRD_PARTY_NOTICES.md) · [繁體中文](../zh-Hant/THIRD_PARTY_NOTICES.md) + + + +# 第三方声明 + +Tatami 应用依赖项的版本和修订号以 `Tuist/Package.resolved` 为准。 + +请阅读原文形式的[应用完整许可证和版权声明](../../THIRD_PARTY_NOTICES.md)。本页仅翻译概述说明。 + +开发自动化使用另一组依赖包,其版本固定在 `Tools/Package.resolved` 中。请阅读原文形式的[开发工具依赖声明](../../Tools/THIRD_PARTY_NOTICES.md)。 diff --git a/NOTICE.zh-Hant.md b/docs/zh-Hant/NOTICE.md similarity index 85% rename from NOTICE.zh-Hant.md rename to docs/zh-Hant/NOTICE.md index 6d0f063..ec21091 100644 --- a/NOTICE.zh-Hant.md +++ b/docs/zh-Hant/NOTICE.md @@ -1,5 +1,5 @@ -[English](NOTICE.md) · [한국어](NOTICE.ko.md) · [日本語](NOTICE.ja.md) · [简体中文](NOTICE.zh-Hans.md) · [繁體中文](NOTICE.zh-Hant.md) +[English](../../NOTICE.md) · [한국어](../ko/NOTICE.md) · [日本語](../ja/NOTICE.md) · [简体中文](../zh-Hans/NOTICE.md) · [繁體中文](NOTICE.md) @@ -10,9 +10,9 @@ Tatami 是獨立專案,並非分支,其設計參考了以下成果: - 虛擬工作空間切換概念受到 Wojciech Kulik 的 [FlashSpace](GPL-3.0)啟發。Tatami 未拷貝其原始碼,而是在自身架構中重新實作相似行為。 - 視窗並排模型及 BSP 的移動、平均排列、旋轉、鏡像、邊界調整操作改編自 koekeishiya 的 MIT 授權專案 [yabai]。相關著作權聲明原文列於下方。 -Tatami 採用 [AGPL-3.0-only](LICENSE) 授權,與 FlashSpace、yabai 及其作者不存在關聯、背書或其他聯繫。 +Tatami 採用 [AGPL-3.0-only](../../LICENSE) 授權,與 FlashSpace、yabai 及其作者不存在關聯、背書或其他聯繫。 -相依套件的授權與著作權聲明原文見 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。 +相依套件的授權與著作權聲明原文見 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)。 diff --git a/README.zh-Hant.md b/docs/zh-Hant/README.md similarity index 78% rename from README.zh-Hant.md rename to docs/zh-Hant/README.md index 9f25d55..92398e9 100644 --- a/README.zh-Hant.md +++ b/docs/zh-Hant/README.md @@ -1,11 +1,11 @@ -[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · [简体中文](README.zh-Hans.md) · [繁體中文](README.zh-Hant.md) +[English](../../README.md) · [한국어](../ko/README.md) · [日本語](../ja/README.md) · [简体中文](../zh-Hans/README.md) · [繁體中文](README.md) -# Tatami +# Tatami -[![最新版本](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![下載](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 或更新版本](https://img.shields.io/badge/macOS-14%2B-blue) [![授權條款:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](LICENSE) +[![最新版本](https://img.shields.io/github/v/release/PangMo5/Tatami?sort=semver)](https://github.com/PangMo5/Tatami/releases/latest) [![下載](https://img.shields.io/github/downloads/PangMo5/Tatami/total)](https://github.com/PangMo5/Tatami/releases) ![macOS 14 或更新版本](https://img.shields.io/badge/macOS-14%2B-blue) [![授權條款:AGPL-3.0-only](https://img.shields.io/badge/License-AGPL%203.0--only-blue)](../../LICENSE) 支援 BSP 視窗並排的 macOS 工作空間管理工具。 @@ -14,7 +14,7 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 ## 看看 Tatami 的實際操作 -[![為整個工作流程騰出空間。](web/media/zh-Hant/tour.jpg)](https://pangmo5.dev/Tatami/zh-Hant/#demo) +[![為整個工作流程騰出空間。](../../web/media/zh-Hant/tour.jpg)](https://pangmo5.dev/Tatami/zh-Hant/#demo) **[觀看完整工作流程](https://pangmo5.dev/Tatami/zh-Hant/#demo)**:設計、撰寫、審閱、借用待辦事項、自動準備專注環境,再連接第二部顯示器。視窗由實際的 Tatami 管理,App 和內容為示範素材。快速鍵採用本次示範的設定。 @@ -22,11 +22,10 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 設定與設定導覽截圖

- Tatami 設定導覽、設定組合與工作空間設定,以及並排工作空間旁借來的暫存區。 + Tatami 設定導覽、設定組合與工作空間設定,以及並排工作空間旁借來的暫存區。

-

原圖:引導設定 · 工作空間 · 借用
截圖來自較早版本,部分標籤已更新。

- +

原圖:引導設定 · 工作空間 · 借用
截圖來自較早版本,部分標籤已更新。

@@ -35,24 +34,26 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 ### 工作空間 -[![在工作之間切換](web/media/zh-Hant/workspaces.jpg)](https://pangmo5.dev/Tatami/zh-Hant/#demo-workspaces) +在工作之間切換 - **虛擬工作空間:** 依工作空間指派和整理 App。 - **彈性切換:** 使用快速鍵、觸控式軌跡板手勢或最近工作空間操作。 - **自訂手勢:** 為三指、四指滑動的各個方向綁定快速鍵操作,也可以指定某個設定組合或工作空間。 - **每個工作空間一個按鍵:** 將切換、指派或借用輔助鍵與**工作空間按鍵**組合使用。同一套按鍵也用於最近、下一個和上一個目標,每項操作還可以個別覆寫。 - **可選切換行為:** 啟用循環、略過空工作空間或跟隨 App 焦點。 -- **[自動開啟示範](https://pangmo5.dev/Tatami/zh-Hant/#demo-autoopen):** 啟用工作空間時啟動指派的 App,重新進入時開啟先前關閉的視窗。 +- **自動開啟:** 啟用工作空間時啟動指定的 App;如果關閉了視窗,再次進入時會重新開啟。 - **每部顯示器獨立管理:** 固定工作空間到顯示器,或在游標所在螢幕開啟動態工作空間。各顯示器在重新啟動後仍保留目前與最近工作空間;前後切換與最近切換可分別限定為目前螢幕或所有螢幕。 - **工作空間鏈:** 在設定組合內依序連接工作空間。切換到任一成員時,依鏈優先順序還原可用夥伴,遵守已連接顯示器的固定位置與鏈動態分配,焦點仍留在所選工作空間。 - **跨顯示器控制:** 在顯示器間移動焦點,或把聚焦的 App 移到其他工作空間。 - **共用 App:** 新增應出現在每個工作空間的 App。 +
+ ### 視窗並排(BSP) -[![讓新視窗找到位置](web/media/zh-Hant/tiling.jpg)](https://pangmo5.dev/Tatami/zh-Hant/#demo-tiling) +讓新視窗找到位置 - **自動 BSP 配置:** 將新視窗放在目前插入目標或取得焦點的區塊旁。兩者都不可用時,使用樹狀結構中最淺層的區塊。 - **鍵盤操作:** 使用建議快速鍵時,按住 `ctrl + alt`,搭配 `h`、`j`、`k` 或 `l` 移動焦點,搭配方向鍵交換視窗,搭配 `=` 或 `-` 放大或縮小取得焦點的區塊。 @@ -63,10 +64,12 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 - **保留排列:** 切換工作空間、重新啟動與系統睡眠後,保留排列樹及比例。 - **可調間距:** 設定內部與外部間距。 +
+ ### 設定組合 -[觀看設定組合與雙螢幕示範](https://pangmo5.dev/Tatami/zh-Hant/#profiles)。 +切換整套設定 - **獨立設定組合:** 分組管理工作空間,一次切換整套環境。每個組合分別儲存工作空間、App 指派與快速鍵。 - **快速切換組合:** 透過快速鍵或選單列切換,所有顯示器重新並排,重新啟動後返回合適的設定組合。 @@ -74,10 +77,12 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 - **組合圖像:** 選擇顯示在側邊欄、選單列與切換回饋中的 SF Symbol。 - **重複使用設定:** **拷貝自**與**複製**共用預覽,在變更前選擇保留或略過工作空間、App、設定與儲存的排列。 +
+ ### 借用:組合兩個工作空間 -[![把對話放到旁邊](web/media/zh-Hant/borrow.jpg)](https://pangmo5.dev/Tatami/zh-Hant/#demo-borrow) +把對話放到旁邊 - **並排組合:** 把另一個工作空間借到螢幕任一邊緣,兩個區域獨立並排,視窗不會越界。 - **即時雙向:** 借來的區域就是實際工作空間,編輯會保留下來。 @@ -86,29 +91,35 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 - **顯示歸屬:** 借來的視窗顯示所屬工作空間圖像。 - **暫存區:** 僅供借用,不參與一般切換,也不會單獨啟用,叫出時自動開啟 App。 +
+ ### 置頂 -[觀看跨工作空間的共用狀態視窗](https://pangmo5.dev/Tatami/zh-Hant/#demo-shared)。 +跨工作使用同一個狀態視窗 - **個別或共用:** 在一個工作空間置頂 App,或加入共用 App 後在所有工作空間置頂。 - **不必修改 SIP:** 使用置頂的 ScreenCaptureKit 鏡像,互動時切換到實際視窗。 - **可預期的堆疊:** 多個置頂視窗依最近焦點順序堆疊,需要螢幕錄製權限。 - **維持原狀:** 保留位置和大小,同時參與自動開啟、焦點、焦點跟隨游標與視窗切換,不必使用鏡像或螢幕錄製權限。 +
+ ### 焦點與游標 -[觀看焦點跟隨鍵盤和游標](https://pangmo5.dev/Tatami/zh-Hant/#demo-focus)。 +讓焦點跟隨你的意圖 - **兩種明確的焦點模式:** 焦點跟隨游標讓游標下方的視窗取得鍵盤焦點;游標跟隨焦點在 Tatami 切換視窗後移動游標,包含置頂、共用置頂與維持原狀視窗。 - **關閉後還原焦點:** 返回剩餘視窗中最近使用的視窗。 - **游標控制:** 可在切換工作空間時隱藏游標。 +
+ ### 介面與設定 -[觀看實際 CLI、掛鉤與即時設定](https://pangmo5.dev/Tatami/zh-Hant/#automation)。 +用 CLI 準備專注環境 - **五種介面語言:** 跟隨 macOS App 語言設定,支援英文、韓文、日文、簡體中文與繁體中文(台灣)。 - **自訂選單列:** 顯示目前工作空間的圖像或名稱,並可顯示作用中設定組合的圖像或名稱。 @@ -121,10 +132,12 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 - **可指令稿化 CLI:** 使用 `tatami workspace activate `、`tatami workspace list` 等領域指令。 - **自動更新:** 透過 Sparkle 取得新版本。 +
+ ### 設定導覽 -[觀看快速鍵練習與建議檢查](https://pangmo5.dev/Tatami/zh-Hant/#guided-setup)。 +邊用邊學 - **邊用邊學:** 首次啟動時,在安全的虛擬桌面依序學習工作空間、切換與手勢、BSP 並排、借用與暫存區、置頂與維持原狀、MFF/FFM 和 App 視窗切換。 - **基於這部 Mac:** 使用執行中 App 的資訊與已連接顯示器的幾何資料,依重複進行的工作組織 App,而非套用一般分類。不擷取螢幕內容。 @@ -132,6 +145,8 @@ Tatami 把 App 整理到虛擬工作空間,透過快速鍵或自訂觸控式 - **連續練習介面:** 實際快速鍵和觸控式軌跡板手勢控制預覽,之前學過的指令在後續課程中仍可使用。 - **先用草稿:** 點按**套用設定**前,不移動實際視窗或寫入 `config.toml`。可隨時從**設定 → 一般**重新開啟。 +
+ ## 系統需求 @@ -170,9 +185,9 @@ open Tatami.xcworkspace 設定儲存在 `~/.config/tatami/config.toml`,分為 `[settings.layout]`、`[settings.focus]`、`[settings.gestures]`、`[settings.shortcuts]` 等表。工作空間、App 指派與共用 App 也在同一檔案中。生命週期掛鉤可在**設定 → Hook**或 `[[hooks]]` 中管理。GUI 分別儲存執行檔和各 argv,不把 `command` 當作 shell 字串。App 內或手動修改都會即時生效。 -完整鍵、預設值與快速鍵語法請見 [docs/CONFIGURATION.md](docs/zh-Hant/CONFIGURATION.md)。 +完整鍵、預設值與快速鍵語法請見 [docs/CONFIGURATION.md](CONFIGURATION.md)。 -關於各 App 的視窗行為,包含浮動會議控制項與跨工作空間的子母畫面,請參閱[疑難排解](docs/zh-Hant/TROUBLESHOOTING.md)。 +關於各 App 的視窗行為,包含浮動會議控制項與跨工作空間的子母畫面,請參閱[疑難排解](TROUBLESHOOTING.md)。 ### 命令列 @@ -189,7 +204,7 @@ tatami layout balance CLI 依領域提供設定組合與工作空間管理、掛鉤查詢、穩定 JSON 輸出,以及與手勢相同的焦點、排列、App、並排、循環切換與借用操作。Tatami 必須正在執行。 -閱讀[完整 CLI 參考](docs/zh-Hant/CLI.md),或在 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/zh-Hant/cli.html) 查看網頁版本。 +閱讀[完整 CLI 參考](CLI.md),或在 [pangmo5.dev/Tatami](https://pangmo5.dev/Tatami/zh-Hant/cli.html) 查看網頁版本。 ## 技術架構 @@ -208,12 +223,12 @@ CLI 依領域提供設定組合與工作空間管理、掛鉤查詢、穩定 JSO ## 致謝 -Tatami 受到 Wojciech Kulik 的 [FlashSpace](虛擬工作空間切換概念)與 koekeishiya 的 [yabai](視窗並排模型)啟發。歸屬說明見 [NOTICE.md](NOTICE.zh-Hant.md),相依套件授權見 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。 +Tatami 受到 Wojciech Kulik 的 [FlashSpace](虛擬工作空間切換概念)與 koekeishiya 的 [yabai](視窗並排模型)啟發。歸屬說明見 [NOTICE.md](NOTICE.md),相依套件授權見 [THIRD_PARTY_NOTICES.md](../../THIRD_PARTY_NOTICES.md)。 ## 授權條款 -[AGPL-3.0-only](LICENSE)。 +[AGPL-3.0-only](../../LICENSE)。 [FlashSpace]: https://github.com/wojciech-kulik/FlashSpace [yabai]: https://github.com/koekeishiya/yabai diff --git a/THIRD_PARTY_NOTICES.zh-Hant.md b/docs/zh-Hant/THIRD_PARTY_NOTICES.md similarity index 52% rename from THIRD_PARTY_NOTICES.zh-Hant.md rename to docs/zh-Hant/THIRD_PARTY_NOTICES.md index 0bbc559..c3426e2 100644 --- a/THIRD_PARTY_NOTICES.zh-Hant.md +++ b/docs/zh-Hant/THIRD_PARTY_NOTICES.md @@ -1,5 +1,5 @@ -[English](THIRD_PARTY_NOTICES.md) · [한국어](THIRD_PARTY_NOTICES.ko.md) · [日本語](THIRD_PARTY_NOTICES.ja.md) · [简体中文](THIRD_PARTY_NOTICES.zh-Hans.md) · [繁體中文](THIRD_PARTY_NOTICES.zh-Hant.md) +[English](../../THIRD_PARTY_NOTICES.md) · [한국어](../ko/THIRD_PARTY_NOTICES.md) · [日本語](../ja/THIRD_PARTY_NOTICES.md) · [简体中文](../zh-Hans/THIRD_PARTY_NOTICES.md) · [繁體中文](THIRD_PARTY_NOTICES.md) @@ -7,6 +7,6 @@ Tatami App 相依套件的版本與修訂版本以 `Tuist/Package.resolved` 為準。 -請閱讀原文形式的[App 完整授權條款與著作權聲明](THIRD_PARTY_NOTICES.md)。本頁僅翻譯概述說明。 +請閱讀原文形式的[App 完整授權條款與著作權聲明](../../THIRD_PARTY_NOTICES.md)。本頁僅翻譯概述說明。 -開發自動化使用另一組套件,其版本固定在 `Tools/Package.resolved` 中。請閱讀原文形式的[開發工具相依套件聲明](Tools/THIRD_PARTY_NOTICES.md)。 +開發自動化使用另一組套件,其版本固定在 `Tools/Package.resolved` 中。請閱讀原文形式的[開發工具相依套件聲明](../../Tools/THIRD_PARTY_NOTICES.md)。 diff --git a/web/borrow.jpg b/web/borrow.jpg index 4363a6b..78c1d0d 100644 Binary files a/web/borrow.jpg and b/web/borrow.jpg differ diff --git a/web/index.html b/web/index.html index 1050d97..30e8cf3 100644 --- a/web/index.html +++ b/web/index.html @@ -60,7 +60,7 @@

Make room for the whole workflow.

Design, write, review, borrow, and automate. Follow one piece of work through a setup that changes with you.