{"allowContribute":false,"item":{"artifactHtml":"\u003cstyle\u003e\n:root{--paper:#F7F8F5;--ink:#17201C;--ink-2:#55605A;--accent:#0E6B5E;--soft:#E2F0EB;--hair:#D9E2DD;--warn:#B45309;--warnsoft:#FBF0DC;}\n:root[data-theme=\"dark\"]{--paper:#111615;--ink:#E8EDEB;--ink-2:#A9B5B0;--accent:#5FD3BB;--soft:#14332C;--hair:#2A3431;--warn:#F5B453;--warnsoft:#3A2C12;}\n.doc{background:var(--paper);color:var(--ink);padding:28px 30px;font:16px/1.72 -apple-system,\"PingFang TC\",\"Noto Sans TC\",sans-serif;}\n.eyebrow{font:600 11px ui-monospace,monospace;letter-spacing:.16em;color:var(--accent);}\nh1{font-size:28px;line-height:1.25;letter-spacing:-.015em;margin:12px 0 0;}\n.lede{color:var(--ink-2);margin:10px 0 0;max-width:64ch;}\n.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:18px 0;}\n.stat{background:var(--soft);border-radius:8px;padding:12px 14px;}\n.stat .k{font-size:12px;color:var(--accent);}\n.stat .v{font-size:20px;font-weight:700;margin-top:4px;}\n.stat .n{font-size:12px;color:var(--ink-2);margin-top:2px;}\nh2{font-size:19px;margin:26px 0 8px;}\np{color:var(--ink-2);max-width:66ch;}\nul,ol{color:var(--ink-2);max-width:66ch;}\ncode{font:13px ui-monospace,SFMono-Regular,Menlo,monospace;background:var(--soft);padding:2px 6px;border-radius:4px;color:var(--ink);}\npre{background:var(--soft);border-radius:8px;padding:14px 16px;overflow-x:auto;font:13px/1.6 ui-monospace,Menlo,monospace;color:var(--ink);}\n.callout{display:flex;gap:13px;padding:14px 16px;background:var(--soft);border-radius:6px;margin:18px 0;}\n.callout .tag{flex:none;font:700 11px ui-monospace,monospace;letter-spacing:.08em;color:var(--accent);padding-top:3px;}\n.callout.warn{background:var(--warnsoft);}\n.callout.warn .tag{color:var(--warn);}\ntable{border-collapse:collapse;width:100%;font-size:14px;}\nth,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--hair);color:var(--ink-2);}\nth{font:600 11px ui-monospace,monospace;letter-spacing:.06em;}\n@media (max-width:640px){.doc{padding:20px 18px;}h1{font-size:22px;}}\n\u003c/style\u003e\u003cdiv class=\"doc\"\u003e\u003cheader\u003e\u003cdiv class=\"eyebrow\"\u003e需求規格 / PLUGIN NATIVE API\u003c/div\u003e\u003ch1\u003e桌機 App 原生截圖能力需求 — 一鍵截圖接宿主 API\u003c/h1\u003e\u003cp class=\"lede\"\u003e我的插件「一鍵截圖」懸浮鈕在網頁版正常，在桌機 App 被 Chromium 直接拒絕。插件沙箱拿不到桌面畫面，需要宿主開一條原生截圖能力。\u003c/p\u003e\u003c/header\u003e\u003csection data-cube=\"stats\" class=\"stats\"\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e發生環境\u003c/div\u003e\u003cdiv class=\"v\"\u003e桌機 App\u003c/div\u003e\u003cdiv class=\"n\"\u003e網頁版正常 / 桌機失敗\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e錯誤訊息\u003c/div\u003e\u003cdiv class=\"v\"\u003eNot supported\u003c/div\u003e\u003cdiv class=\"n\"\u003e截圖失敗：Not supported\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e插件版本\u003c/div\u003e\u003cdiv class=\"v\"\u003e1.4.2\u003c/div\u003e\u003cdiv class=\"n\"\u003e我的插件 de910ca0…\u003c/div\u003e\u003c/div\u003e\u003c/section\u003e\u003cdiv class=\"callout warn\"\u003e\u003cspan class=\"tag\"\u003e結論\u003c/span\u003e\u003cdiv\u003e這不是插件 bug，是宿主能力缺口：Electron renderer 沒有實作 \u003ccode\u003egetDisplayMedia\u003c/code\u003e，插件又被 validator 禁止碰 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e，沙箱內無路可走。\u003c/div\u003e\u003c/div\u003e\u003ch2\u003e一、使用者要什麼\u003c/h2\u003e\u003cp\u003e在「我的插件」設定打開「一鍵截圖」後，右下角出現相機懸浮鈕。點一下就把當前 App 畫面拍下來，自動存進檔案庫（檔名為截圖日期時間），並跳提示「已存進檔案庫」。全程一次點擊，不應每次都跳系統分享選窗。\u003c/p\u003e\u003ch2\u003e二、現況與證據\u003c/h2\u003e\u003ctable\u003e\u003ctr\u003e\u003cth\u003e環境\u003c/th\u003e\u003cth\u003e行為\u003c/th\u003e\u003cth\u003e結果\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e瀏覽器網頁版\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 跳分享選窗\u003c/td\u003e\u003ctd\u003e可截圖、可存檔\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e桌機 App\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 直接 throw\u003c/td\u003e\u003ctd\u003e截圖失敗：Not supported，連選窗都不出現\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u003cp\u003e使用者在桌機 App 實測錄影：按下相機鈕後直接顯示失敗提示。桌面 App 的 Chromium 對插件 iframe 拒絕螢幕分享，前端 \u003ccode\u003ecanvas.toBlob\u003c/code\u003e 之前的取流步驟就已陣亡，後面的存檔流程根本跑不到。\u003c/p\u003e\u003ch2\u003e三、為什麼插件自己修不好\u003c/h2\u003e\u003col\u003e\u003cli\u003e宿主內部其實有路：旅途錄影用主行程 \u003ccode\u003edesktopCapturer\u003c/code\u003e 取 \u003ccode\u003esourceId\u003c/code\u003e，再用 \u003ccode\u003egetUserMedia({ chromeMediaSource: 'desktop' })\u003c/code\u003e 取流，證明 Electron 端取得到自己視窗。\u003c/li\u003e\u003cli\u003e但這條路插件走不得：validator 明確禁止 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e（host 內部 IPC，不在 plugin contract），帶 \u003ccode\u003ejourneyRecorderSource\u003c/code\u003e 的版本直接被退回。\u003c/li\u003e\u003cli\u003eDOM 轉 canvas（html2canvas 類）不是正解：跨 iframe、Canvas 指紋、捲動裁切都會破圖，且拿不到視窗外系統層級畫面。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e四、需求提案：宿主開一條截圖 API\u003c/h2\u003e\u003cp\u003e建議在 \u003ccode\u003e@cubelv/sdk\u003c/code\u003e 新增一個前端 API，例如：\u003c/p\u003e\u003cpre\u003ecaptureScreenshot({ source?: 'current-window' | 'screen' }): Promise\u0026lt;File\u0026gt;\n// 或直接回 FILE：Promise\u0026lt;{ fileId: string; downloadURL: string }\u0026gt;\u003c/pre\u003e\u003cul\u003e\u003cli\u003e實作由宿主在主行程用 \u003ccode\u003edesktopCapturer\u003c/code\u003e 抓當前視窗（預設 \u003ccode\u003ecurrent-window\u003c/code\u003e，免除每次選窗），renderer 只收 PNG bytes。\u003c/li\u003e\u003cli\u003e回傳 \u003ccode\u003eFile\u003c/code\u003e 或直接建好 FILE item，與現有 \u003ccode\u003ecreateLibraryFile\u003c/code\u003e 銜接，配額、縮圖、落「插件檔案」資料夾沿用現制。\u003c/li\u003e\u003cli\u003e必須在使用者手勢（click）內觸發，符合隱私要求；多螢幕時截 App 所在的那一屏即可。\u003c/li\u003e\u003cli\u003eWeb 版可沿用現行 \u003ccode\u003egetDisplayMedia\u003c/code\u003e 流程，行動端回明確不支援，呼叫端照現有 fallback 提示用系統截圖。\u003c/li\u003e\u003c/ul\u003e\u003ch2\u003e五、驗收標準\u003c/h2\u003e\u003col\u003e\u003cli\u003e桌機 App 點相機鈕：不跳選窗、不報 Not supported，一次點擊產出一張 PNG 進檔案庫。\u003c/li\u003e\u003cli\u003e無痕／離線／多螢幕下行為明確：失敗時回可讀原因（無可截視窗、被拒、編碼失敗），不吞錯。\u003c/li\u003e\u003cli\u003eValidator 放行：插件只用 SDK 公開 API，不碰 \u003ccode\u003eelectronAPI\u003c/code\u003e 即可過。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e六、目前替代做法\u003c/h2\u003e\u003cp\u003e新版插件已上線誠實 fallback：桌機 App 點按鈕會提示「桌機 App 暫不支援直接取畫面，請用系統截圖後上傳到檔案庫」。Windows 用 Win+Shift+S，Mac 用 Cmd+Shift+4，截完丟進檔案庫即可。此做法只是止血，宿主 API 上線後可無縫接回一鍵流程。\u003c/p\u003e\u003c/div\u003e","content":"\u003cdiv class=\"doc\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e發生環境\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e桌機 App\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e網頁版正常 / 桌機失敗\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e錯誤訊息\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003eNot supported\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e截圖失敗：Not supported\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e插件版本\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e1.4.2\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e我的插件 de910ca0…\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cdiv class=\"callout warn\"\u003e\u003cspan class=\"tag\"\u003e結論\u003c/span\u003e\u003cdiv\u003e這不是插件 bug，是宿主能力缺口：Electron renderer 沒有實作 \u003ccode\u003egetDisplayMedia\u003c/code\u003e，插件又被 validator 禁止碰 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e，沙箱內無路可走。\u003c/div\u003e\u003c/div\u003e\u003ch2\u003e一、使用者要什麼\u003c/h2\u003e\u003cp\u003e在「我的插件」設定打開「一鍵截圖」後，右下角出現相機懸浮鈕。點一下就把當前 App 畫面拍下來，自動存進檔案庫（檔名為截圖日期時間），並跳提示「已存進檔案庫」。全程一次點擊，不應每次都跳系統分享選窗。\u003c/p\u003e\u003ch2\u003e二、現況與證據\u003c/h2\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003cth\u003e環境\u003c/th\u003e\u003cth\u003e行為\u003c/th\u003e\u003cth\u003e結果\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e瀏覽器網頁版\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 跳分享選窗\u003c/td\u003e\u003ctd\u003e可截圖、可存檔\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e桌機 App\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 直接 throw\u003c/td\u003e\u003ctd\u003e截圖失敗：Not supported，連選窗都不出現\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e使用者在桌機 App 實測錄影：按下相機鈕後直接顯示失敗提示。桌面 App 的 Chromium 對插件 iframe 拒絕螢幕分享，前端 \u003ccode\u003ecanvas.toBlob\u003c/code\u003e 之前的取流步驟就已陣亡，後面的存檔流程根本跑不到。\u003c/p\u003e\u003ch2\u003e三、為什麼插件自己修不好\u003c/h2\u003e\u003col\u003e\u003cli\u003e宿主內部其實有路：旅途錄影用主行程 \u003ccode\u003edesktopCapturer\u003c/code\u003e 取 \u003ccode\u003esourceId\u003c/code\u003e，再用 \u003ccode\u003egetUserMedia({ chromeMediaSource: 'desktop' })\u003c/code\u003e 取流，證明 Electron 端取得到自己視窗。\u003c/li\u003e\u003cli\u003e但這條路插件走不得：validator 明確禁止 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e（host 內部 IPC，不在 plugin contract），帶 \u003ccode\u003ejourneyRecorderSource\u003c/code\u003e 的版本直接被退回。\u003c/li\u003e\u003cli\u003eDOM 轉 canvas（html2canvas 類）不是正解：跨 iframe、Canvas 指紋、捲動裁切都會破圖，且拿不到視窗外系統層級畫面。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e四、需求提案：宿主開一條截圖 API\u003c/h2\u003e\u003cp\u003e建議在 \u003ccode\u003e@cubelv/sdk\u003c/code\u003e 新增一個前端 API，例如：\u003c/p\u003e\u003cpre\u003ecaptureScreenshot({ source?: 'current-window' | 'screen' }): Promise\u0026lt;File\u0026gt;\n// 或直接回 FILE：Promise\u0026lt;{ fileId: string; downloadURL: string }\u0026gt;\u003c/pre\u003e\u003cul\u003e\u003cli\u003e實作由宿主在主行程用 \u003ccode\u003edesktopCapturer\u003c/code\u003e 抓當前視窗（預設 \u003ccode\u003ecurrent-window\u003c/code\u003e，免除每次選窗），renderer 只收 PNG bytes。\u003c/li\u003e\u003cli\u003e回傳 \u003ccode\u003eFile\u003c/code\u003e 或直接建好 FILE item，與現有 \u003ccode\u003ecreateLibraryFile\u003c/code\u003e 銜接，配額、縮圖、落「插件檔案」資料夾沿用現制。\u003c/li\u003e\u003cli\u003e必須在使用者手勢（click）內觸發，符合隱私要求；多螢幕時截 App 所在的那一屏即可。\u003c/li\u003e\u003cli\u003eWeb 版可沿用現行 \u003ccode\u003egetDisplayMedia\u003c/code\u003e 流程，行動端回明確不支援，呼叫端照現有 fallback 提示用系統截圖。\u003c/li\u003e\u003c/ul\u003e\u003ch2\u003e五、驗收標準\u003c/h2\u003e\u003col\u003e\u003cli\u003e桌機 App 點相機鈕：不跳選窗、不報 Not supported，一次點擊產出一張 PNG 進檔案庫。\u003c/li\u003e\u003cli\u003e無痕／離線／多螢幕下行為明確：失敗時回可讀原因（無可截視窗、被拒、編碼失敗），不吞錯。\u003c/li\u003e\u003cli\u003eValidator 放行：插件只用 SDK 公開 API，不碰 \u003ccode\u003eelectronAPI\u003c/code\u003e 即可過。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e六、目前替代做法\u003c/h2\u003e\u003cp\u003e新版插件已上線誠實 fallback：桌機 App 點按鈕會提示「桌機 App 暫不支援直接取畫面，請用系統截圖後上傳到檔案庫」。Windows 用 Win+Shift+S，Mac 用 Cmd+Shift+4，截完丟進檔案庫即可。此做法只是止血，宿主 API 上線後可無縫接回一鍵流程。\u003c/p\u003e\u003c/div\u003e","createdAt":1789406833497,"displayMode":"artifact","embedRenders":{},"embedRendersDark":{},"id":"632bcefd11bb6d3238d66f9c","isNew":false,"isPublic":true,"itemType":"NOTE","name":"桌機 App 原生截圖能力需求 — 一鍵截圖接宿主 API","parents":{"96c5af370bbc43e29e286a65":1789406833497},"updatedAt":1789406976630,"updatedBy":{"userId":"6a47c1c0008abf935412de","userName":"崴立"},"version":4},"ownerName":"崴立","subtree":[{"artifactHtml":"\u003cstyle\u003e\n:root{--paper:#F7F8F5;--ink:#17201C;--ink-2:#55605A;--accent:#0E6B5E;--soft:#E2F0EB;--hair:#D9E2DD;--warn:#B45309;--warnsoft:#FBF0DC;}\n:root[data-theme=\"dark\"]{--paper:#111615;--ink:#E8EDEB;--ink-2:#A9B5B0;--accent:#5FD3BB;--soft:#14332C;--hair:#2A3431;--warn:#F5B453;--warnsoft:#3A2C12;}\n.doc{background:var(--paper);color:var(--ink);padding:28px 30px;font:16px/1.72 -apple-system,\"PingFang TC\",\"Noto Sans TC\",sans-serif;}\n.eyebrow{font:600 11px ui-monospace,monospace;letter-spacing:.16em;color:var(--accent);}\nh1{font-size:28px;line-height:1.25;letter-spacing:-.015em;margin:12px 0 0;}\n.lede{color:var(--ink-2);margin:10px 0 0;max-width:64ch;}\n.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:18px 0;}\n.stat{background:var(--soft);border-radius:8px;padding:12px 14px;}\n.stat .k{font-size:12px;color:var(--accent);}\n.stat .v{font-size:20px;font-weight:700;margin-top:4px;}\n.stat .n{font-size:12px;color:var(--ink-2);margin-top:2px;}\nh2{font-size:19px;margin:26px 0 8px;}\np{color:var(--ink-2);max-width:66ch;}\nul,ol{color:var(--ink-2);max-width:66ch;}\ncode{font:13px ui-monospace,SFMono-Regular,Menlo,monospace;background:var(--soft);padding:2px 6px;border-radius:4px;color:var(--ink);}\npre{background:var(--soft);border-radius:8px;padding:14px 16px;overflow-x:auto;font:13px/1.6 ui-monospace,Menlo,monospace;color:var(--ink);}\n.callout{display:flex;gap:13px;padding:14px 16px;background:var(--soft);border-radius:6px;margin:18px 0;}\n.callout .tag{flex:none;font:700 11px ui-monospace,monospace;letter-spacing:.08em;color:var(--accent);padding-top:3px;}\n.callout.warn{background:var(--warnsoft);}\n.callout.warn .tag{color:var(--warn);}\ntable{border-collapse:collapse;width:100%;font-size:14px;}\nth,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--hair);color:var(--ink-2);}\nth{font:600 11px ui-monospace,monospace;letter-spacing:.06em;}\n@media (max-width:640px){.doc{padding:20px 18px;}h1{font-size:22px;}}\n\u003c/style\u003e\u003cdiv class=\"doc\"\u003e\u003cheader\u003e\u003cdiv class=\"eyebrow\"\u003e需求規格 / PLUGIN NATIVE API\u003c/div\u003e\u003ch1\u003e桌機 App 原生截圖能力需求 — 一鍵截圖接宿主 API\u003c/h1\u003e\u003cp class=\"lede\"\u003e我的插件「一鍵截圖」懸浮鈕在網頁版正常，在桌機 App 被 Chromium 直接拒絕。插件沙箱拿不到桌面畫面，需要宿主開一條原生截圖能力。\u003c/p\u003e\u003c/header\u003e\u003csection data-cube=\"stats\" class=\"stats\"\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e發生環境\u003c/div\u003e\u003cdiv class=\"v\"\u003e桌機 App\u003c/div\u003e\u003cdiv class=\"n\"\u003e網頁版正常 / 桌機失敗\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e錯誤訊息\u003c/div\u003e\u003cdiv class=\"v\"\u003eNot supported\u003c/div\u003e\u003cdiv class=\"n\"\u003e截圖失敗：Not supported\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e插件版本\u003c/div\u003e\u003cdiv class=\"v\"\u003e1.4.2\u003c/div\u003e\u003cdiv class=\"n\"\u003e我的插件 de910ca0…\u003c/div\u003e\u003c/div\u003e\u003c/section\u003e\u003cdiv class=\"callout warn\"\u003e\u003cspan class=\"tag\"\u003e結論\u003c/span\u003e\u003cdiv\u003e這不是插件 bug，是宿主能力缺口：Electron renderer 沒有實作 \u003ccode\u003egetDisplayMedia\u003c/code\u003e，插件又被 validator 禁止碰 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e，沙箱內無路可走。\u003c/div\u003e\u003c/div\u003e\u003ch2\u003e一、使用者要什麼\u003c/h2\u003e\u003cp\u003e在「我的插件」設定打開「一鍵截圖」後，右下角出現相機懸浮鈕。點一下就把當前 App 畫面拍下來，自動存進檔案庫（檔名為截圖日期時間），並跳提示「已存進檔案庫」。全程一次點擊，不應每次都跳系統分享選窗。\u003c/p\u003e\u003ch2\u003e二、現況與證據\u003c/h2\u003e\u003ctable\u003e\u003ctr\u003e\u003cth\u003e環境\u003c/th\u003e\u003cth\u003e行為\u003c/th\u003e\u003cth\u003e結果\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e瀏覽器網頁版\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 跳分享選窗\u003c/td\u003e\u003ctd\u003e可截圖、可存檔\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e桌機 App\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 直接 throw\u003c/td\u003e\u003ctd\u003e截圖失敗：Not supported，連選窗都不出現\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\u003cp\u003e使用者在桌機 App 實測錄影：按下相機鈕後直接顯示失敗提示。桌面 App 的 Chromium 對插件 iframe 拒絕螢幕分享，前端 \u003ccode\u003ecanvas.toBlob\u003c/code\u003e 之前的取流步驟就已陣亡，後面的存檔流程根本跑不到。\u003c/p\u003e\u003ch2\u003e三、為什麼插件自己修不好\u003c/h2\u003e\u003col\u003e\u003cli\u003e宿主內部其實有路：旅途錄影用主行程 \u003ccode\u003edesktopCapturer\u003c/code\u003e 取 \u003ccode\u003esourceId\u003c/code\u003e，再用 \u003ccode\u003egetUserMedia({ chromeMediaSource: 'desktop' })\u003c/code\u003e 取流，證明 Electron 端取得到自己視窗。\u003c/li\u003e\u003cli\u003e但這條路插件走不得：validator 明確禁止 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e（host 內部 IPC，不在 plugin contract），帶 \u003ccode\u003ejourneyRecorderSource\u003c/code\u003e 的版本直接被退回。\u003c/li\u003e\u003cli\u003eDOM 轉 canvas（html2canvas 類）不是正解：跨 iframe、Canvas 指紋、捲動裁切都會破圖，且拿不到視窗外系統層級畫面。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e四、需求提案：宿主開一條截圖 API\u003c/h2\u003e\u003cp\u003e建議在 \u003ccode\u003e@cubelv/sdk\u003c/code\u003e 新增一個前端 API，例如：\u003c/p\u003e\u003cpre\u003ecaptureScreenshot({ source?: 'current-window' | 'screen' }): Promise\u0026lt;File\u0026gt;\n// 或直接回 FILE：Promise\u0026lt;{ fileId: string; downloadURL: string }\u0026gt;\u003c/pre\u003e\u003cul\u003e\u003cli\u003e實作由宿主在主行程用 \u003ccode\u003edesktopCapturer\u003c/code\u003e 抓當前視窗（預設 \u003ccode\u003ecurrent-window\u003c/code\u003e，免除每次選窗），renderer 只收 PNG bytes。\u003c/li\u003e\u003cli\u003e回傳 \u003ccode\u003eFile\u003c/code\u003e 或直接建好 FILE item，與現有 \u003ccode\u003ecreateLibraryFile\u003c/code\u003e 銜接，配額、縮圖、落「插件檔案」資料夾沿用現制。\u003c/li\u003e\u003cli\u003e必須在使用者手勢（click）內觸發，符合隱私要求；多螢幕時截 App 所在的那一屏即可。\u003c/li\u003e\u003cli\u003eWeb 版可沿用現行 \u003ccode\u003egetDisplayMedia\u003c/code\u003e 流程，行動端回明確不支援，呼叫端照現有 fallback 提示用系統截圖。\u003c/li\u003e\u003c/ul\u003e\u003ch2\u003e五、驗收標準\u003c/h2\u003e\u003col\u003e\u003cli\u003e桌機 App 點相機鈕：不跳選窗、不報 Not supported，一次點擊產出一張 PNG 進檔案庫。\u003c/li\u003e\u003cli\u003e無痕／離線／多螢幕下行為明確：失敗時回可讀原因（無可截視窗、被拒、編碼失敗），不吞錯。\u003c/li\u003e\u003cli\u003eValidator 放行：插件只用 SDK 公開 API，不碰 \u003ccode\u003eelectronAPI\u003c/code\u003e 即可過。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e六、目前替代做法\u003c/h2\u003e\u003cp\u003e新版插件已上線誠實 fallback：桌機 App 點按鈕會提示「桌機 App 暫不支援直接取畫面，請用系統截圖後上傳到檔案庫」。Windows 用 Win+Shift+S，Mac 用 Cmd+Shift+4，截完丟進檔案庫即可。此做法只是止血，宿主 API 上線後可無縫接回一鍵流程。\u003c/p\u003e\u003c/div\u003e","content":"\u003cdiv class=\"doc\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e發生環境\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e桌機 App\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e網頁版正常 / 桌機失敗\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e錯誤訊息\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003eNot supported\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e截圖失敗：Not supported\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e插件版本\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e1.4.2\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e我的插件 de910ca0…\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cdiv class=\"callout warn\"\u003e\u003cspan class=\"tag\"\u003e結論\u003c/span\u003e\u003cdiv\u003e這不是插件 bug，是宿主能力缺口：Electron renderer 沒有實作 \u003ccode\u003egetDisplayMedia\u003c/code\u003e，插件又被 validator 禁止碰 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e，沙箱內無路可走。\u003c/div\u003e\u003c/div\u003e\u003ch2\u003e一、使用者要什麼\u003c/h2\u003e\u003cp\u003e在「我的插件」設定打開「一鍵截圖」後，右下角出現相機懸浮鈕。點一下就把當前 App 畫面拍下來，自動存進檔案庫（檔名為截圖日期時間），並跳提示「已存進檔案庫」。全程一次點擊，不應每次都跳系統分享選窗。\u003c/p\u003e\u003ch2\u003e二、現況與證據\u003c/h2\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003cth\u003e環境\u003c/th\u003e\u003cth\u003e行為\u003c/th\u003e\u003cth\u003e結果\u003c/th\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e瀏覽器網頁版\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 跳分享選窗\u003c/td\u003e\u003ctd\u003e可截圖、可存檔\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e桌機 App\u003c/td\u003e\u003ctd\u003e\u003ccode\u003egetDisplayMedia\u003c/code\u003e 直接 throw\u003c/td\u003e\u003ctd\u003e截圖失敗：Not supported，連選窗都不出現\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e使用者在桌機 App 實測錄影：按下相機鈕後直接顯示失敗提示。桌面 App 的 Chromium 對插件 iframe 拒絕螢幕分享，前端 \u003ccode\u003ecanvas.toBlob\u003c/code\u003e 之前的取流步驟就已陣亡，後面的存檔流程根本跑不到。\u003c/p\u003e\u003ch2\u003e三、為什麼插件自己修不好\u003c/h2\u003e\u003col\u003e\u003cli\u003e宿主內部其實有路：旅途錄影用主行程 \u003ccode\u003edesktopCapturer\u003c/code\u003e 取 \u003ccode\u003esourceId\u003c/code\u003e，再用 \u003ccode\u003egetUserMedia({ chromeMediaSource: 'desktop' })\u003c/code\u003e 取流，證明 Electron 端取得到自己視窗。\u003c/li\u003e\u003cli\u003e但這條路插件走不得：validator 明確禁止 \u003ccode\u003ewindow.electronAPI\u003c/code\u003e（host 內部 IPC，不在 plugin contract），帶 \u003ccode\u003ejourneyRecorderSource\u003c/code\u003e 的版本直接被退回。\u003c/li\u003e\u003cli\u003eDOM 轉 canvas（html2canvas 類）不是正解：跨 iframe、Canvas 指紋、捲動裁切都會破圖，且拿不到視窗外系統層級畫面。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e四、需求提案：宿主開一條截圖 API\u003c/h2\u003e\u003cp\u003e建議在 \u003ccode\u003e@cubelv/sdk\u003c/code\u003e 新增一個前端 API，例如：\u003c/p\u003e\u003cpre\u003ecaptureScreenshot({ source?: 'current-window' | 'screen' }): Promise\u0026lt;File\u0026gt;\n// 或直接回 FILE：Promise\u0026lt;{ fileId: string; downloadURL: string }\u0026gt;\u003c/pre\u003e\u003cul\u003e\u003cli\u003e實作由宿主在主行程用 \u003ccode\u003edesktopCapturer\u003c/code\u003e 抓當前視窗（預設 \u003ccode\u003ecurrent-window\u003c/code\u003e，免除每次選窗），renderer 只收 PNG bytes。\u003c/li\u003e\u003cli\u003e回傳 \u003ccode\u003eFile\u003c/code\u003e 或直接建好 FILE item，與現有 \u003ccode\u003ecreateLibraryFile\u003c/code\u003e 銜接，配額、縮圖、落「插件檔案」資料夾沿用現制。\u003c/li\u003e\u003cli\u003e必須在使用者手勢（click）內觸發，符合隱私要求；多螢幕時截 App 所在的那一屏即可。\u003c/li\u003e\u003cli\u003eWeb 版可沿用現行 \u003ccode\u003egetDisplayMedia\u003c/code\u003e 流程，行動端回明確不支援，呼叫端照現有 fallback 提示用系統截圖。\u003c/li\u003e\u003c/ul\u003e\u003ch2\u003e五、驗收標準\u003c/h2\u003e\u003col\u003e\u003cli\u003e桌機 App 點相機鈕：不跳選窗、不報 Not supported，一次點擊產出一張 PNG 進檔案庫。\u003c/li\u003e\u003cli\u003e無痕／離線／多螢幕下行為明確：失敗時回可讀原因（無可截視窗、被拒、編碼失敗），不吞錯。\u003c/li\u003e\u003cli\u003eValidator 放行：插件只用 SDK 公開 API，不碰 \u003ccode\u003eelectronAPI\u003c/code\u003e 即可過。\u003c/li\u003e\u003c/ol\u003e\u003ch2\u003e六、目前替代做法\u003c/h2\u003e\u003cp\u003e新版插件已上線誠實 fallback：桌機 App 點按鈕會提示「桌機 App 暫不支援直接取畫面，請用系統截圖後上傳到檔案庫」。Windows 用 Win+Shift+S，Mac 用 Cmd+Shift+4，截完丟進檔案庫即可。此做法只是止血，宿主 API 上線後可無縫接回一鍵流程。\u003c/p\u003e\u003c/div\u003e","createdAt":1789406833497,"displayMode":"artifact","embedRenders":{},"embedRendersDark":{},"id":"632bcefd11bb6d3238d66f9c","isNew":false,"isPublic":true,"itemType":"NOTE","name":"桌機 App 原生截圖能力需求 — 一鍵截圖接宿主 API","parents":{"96c5af370bbc43e29e286a65":1789406833497},"updatedAt":1789406976630,"updatedBy":{"userId":"6a47c1c0008abf935412de","userName":"崴立"},"version":4}]}