Steven
Steven1 分で読める

画面録画がなぜ間違ったモニターを撮るのか(そして私たちの修正)

デュアルモニター環境で、GeekByeはあなたがどちらの画面で作業していようとプライマリディスプレイを録画・スクリーンショットしていました。修正は小さな関数ひとつ — でもその最初のバージョンは間違っていて、コードレビューがその理由を見抜きました。

画面録画
マルチディスプレイ
エンジニアリング
GeekByeリリース
画面録画がなぜ間違ったモニターを撮るのか(そして私たちの修正)

これはモニターを2台持っている場合にだけ存在するバグ — だからこそしばらく静かに生き延びていました。サイドのディスプレイで作業をしていて、GeekByeの録画を始めると、録画されるのはプライマリモニターです。メニューバーのある方。あなたが見ていなかった方。

同じ欠陥が、より静かに、より厄介な形で、GeekByeがコンテキストとしてAIに送るスクリーンショットも直撃しました。2枚目のモニターでスクリーンショットのショートカットを押すと、AIは1枚目の画像を受け取ります。目に見える手がかりはなく — アシスタントはただ間違った画面について答え、あなたはなぜ混乱しているのかと首をかしげることになります。GeekBye v2.0.10は両方を修正しました。

2つのパイプライン、1つの怠けたデフォルト

デスクトップの画面キャプチャは2つの別々のコードパスで、どちらも独立してプライマリディスプレイを選んでいました:

  • 動画録画は利用可能な画面ソースを列挙し、最初の1つ — sources[0] を取っていました。macOSでは、それは事実上いつもメインディスプレイです。ピッカーもなければ、実際にどこにいたかを考えるロジックもありません。私たち自身のコードのコメントには、文字どおり*「最初の画面ソースを自動選択」*と書いてありました。
  • スクリーンショットはmacOSのscreencaptureコマンドを-mフラグ付きで使っていました。このフラグの意味はただ一つ: メインディスプレイのみ。 ハードコードでした。

どちらのパスも、肝心の問いを一度も尋ねませんでした: ユーザーはどの画面にいるのか?

決して壊れていなかったことを一つ、勘違いされがちなので明確にしておきます: 同じモニター上でmacOSのSpacesを切り替えるのは常に正しく動いていました。キャプチャはディスプレイ単位で起こり — 選ばれたディスプレイに表示されているSpaceを、そのまま掴みます。このバグはSpacesの話ではありませんでした。ずっと、間違った物理ディスプレイを選ぶ話だったのです。

明白に見えた修正 — そしてそれは間違いだった

正しいシグナルは簡単そうに見えます: ユーザーがいるディスプレイをキャプチャする。私たちの最初の実装は、GeekByeのオーバーレイウィンドウを基準にしました — オーバーレイが存在するディスプレイをキャプチャする、というものです。

コードレビューがそれを、正しく葬りました。GeekByeのオーバーレイは、プライマリディスプレイ上に、位置(0,0)で、作業領域いっぱいのウィンドウとして作られます。あなたがそのピルを物理的に別のモニターへドラッグしたときにだけ移動し — そして、それを動かすキーボードショートカットはプライマリディスプレイの寸法にクランプされるため、2枚目のモニターへはまったく動かせません。オーバーレイを基準にキャプチャするということは、つまり: 作業画面にオーバーレイをたまたまドラッグしていなかったすべてのユーザーにとって、その「修正」はまっすぐプライマリディスプレイへ戻ってしまうのです。ほとんど誰も直らなかったでしょう — それでいて、シングルモニターの開発機での手早いテストでは、動いているように見えたのです。

正しい基準はカーソルです。マウスがある場所、それがあなたの作業しているディスプレイです — そしてそれは、キャプチャが始まるあらゆる経路で正しい: キーボードショートカットはあなたが指している場所で発火し、Recordボタンをクリックすれば、定義上あなたのカーソルはそのディスプレイにあります。最終的な修正は2行の関数です: カーソルに最も近いディスプレイ。動画は自身のキャプチャソースをそのディスプレイのidに合わせ; スクリーンショットは-mのメインディスプレイフラグの代わりに、そのディスプレイの境界をscreencapture -R(特定の矩形)へ渡します。

私たちは意図して-R(グローバル画面座標での明示的な矩形)を-D(ディスプレイのインデックス)より選びました: OSのディスプレイインデックスはフレームワークのディスプレイ順序と対応する保証がなく、インデックスでは二段目の当てずっぽうになってしまうからです。実際のディスプレイ境界から来る矩形は曖昧さがありません — そして出荷前に、プライマリの左に配置されたディスプレイの負座標を含めて、このフラグの挙動を実機のマルチモニター環境で検証しました。

なぜこれが良い「教材バグ」なのか

  1. 「画面をキャプチャする」は一つの決定を隠している。 シングルディスプレイでは決定がないので、その決定は設計されることがなく — デフォルトで済まされます。マルチモニターこそ、あらゆる暗黙のデフォルトが表面化する場所です。
  2. 静かに間違っているのは、目に見えて間違っているより厄介。 動画のバグは人を苛立たせました。スクリーンショットのバグはAIを、目に見えない形で誤誘導しました。モデルにコンテキストを供給する機能を作るとき、間違った入力はどこにもエラーを出さないまま、自信満々に間違った出力を生みます。それこそ、最も執念深く狩る価値のある失敗です。
  3. 自分のマシンで通る修正が、他のみんなのマシンでは落ちることがある。 オーバーレイ基準のバージョンは、シングルモニターのテストでは動きました。バグの本質はまさに複数モニターです — そしてレビュアーは、緑のテストを信じる代わりに、ウィンドウの実際の位置について推論しました。レビューは動いているコードへのゴム印ではありません; それはコードがなぜ動くのかについての、二つ目のモデルなのです。

GeekBye v2.0.10は、録画とスクリーンショットの両方にカーソルベースの修正を出荷します。複数のディスプレイを使っているなら、キャプチャは今、あなたについてきます。

このシリーズの近隣リリースについては、AIノートテイカーはなぜ会議の途中で録音を止めるのか(v2.0.9)とAI文字起こしはなぜ専門用語を聞き間違えるのか(v2.0.11)をご覧ください。通話中にオーバーレイがどう振る舞うかは、画面共有中に不可視のままでいる方法をどうぞ。

関連記事

ファイアウォールがWebSocketを塞ぐとき、リアルタイム文字起こしはどうなるか
Steven
Steven1 分で読める

ファイアウォールがWebSocketを塞ぐとき、リアルタイム文字起こしはどうなるか

企業ネットワークはHTTPSは通すくせに、WebSocketのアップグレードをこっそり殺すのが大好きです。それがリアルタイム文字起こしを黙って壊します。GeekBye v2.0.8は自動でピュアHTTPSトランスポートへフォールバックする — そしてそれを出荷する過程で、機能全体を無意味にしかねないバグが見つかりました。

文字起こし
ネットワーク
エンジニアリング
アプリが自分自身にDDoSを仕掛けた日
Steven
Steven1 分で読める

アプリが自分自身にDDoSを仕掛けた日

起動時に一気に放たれた保留中アップロードの滞留が、あらゆるGeekByeクライアントを、自社サーバーへの小さなサービス拒否攻撃へと変えました。その修正 — そしてそれが私たちに作らせた接続生存性のはしご — は、v2が教えてくれた最も役立つことの一つです。

信頼性
ネットワーク
エンジニアリング
バージョン2に本当に必要なもの: 206コミット分の正直な状態
Steven
Steven1 分で読める

バージョン2に本当に必要なもの: 206コミット分の正直な状態

GeekBye v2は機能リリースではありませんでした。それは、たった一つの考えに向けられた206のコミットでした — アプリは自分自身の状態について決して嘘をつくべきではない、と。それが何を要求するのか、ここに記します — 私たちがそれを一切出荷できなくなりかけた、あの一行のロックファイルの間違いも含めて。

信頼性
エンジニアリング
リリース