Steven
Steven4 мин четене

Защо записът на екрана хваща грешния монитор (и как го поправихме)

При настройка с два монитора GeekBye записваше и правеше екранни снимки на основния дисплей, независимо на кой екран работиш. Фиксът беше една малка функция — но първата ѝ версия беше грешна и code review хвана защо.

Запис на екран
Multi-Display
Инженерство
GeekBye издания
Защо записът на екрана хваща грешния монитор (и как го поправихме)

Ето един бъг, който съществува само ако притежаваш два монитора — затова и живя тихо известно време. Работиш на страничния си дисплей, стартираш запис в GeekBye, а той записва основния ти монитор. Този с лентата с менюта. Този, който не гледаше.

Същият дефект, по-тих и по-лош, удряше екранните снимки, които GeekBye изпраща на AI-я за контекст: натискаш клавишната комбинация за снимка на втория си монитор, а AI-ят получава картина на първия. Няма визуален знак — асистентът просто отговаря за грешния екран, а ти оставаш да се чудиш защо е объркан. GeekBye v2.0.10 поправи и двете.

Два pipeline-а, един мързелив default

Захващането на екрана на десктопа са два отделни кодови пътя и двата независимо бяха избрали основния дисплей:

  • Видео записът изброяваше наличните screen sources и вземаше първия — sources[0]. На macOS това на практика винаги е основният дисплей. Без picker, без логика за това къде всъщност беше. Коментарът в собствения ни код буквално казваше "auto-select first screen source."
  • Екранните снимки използваха macOS командата screencapture с флага -m. Този флаг има точно едно значение: само основен дисплей. Хардкоднато.

Нито един път никога не задаваше въпроса, който има значение: на кой екран е потребителят?

Едно нещо, което никога не е било счупено, струва си да се изясни, защото хората предполагат, че е било: превключването между macOS Spaces на същия монитор винаги работеше. Захващането става на ниво дисплей — то грабва каквото Space е видимо на избрания дисплей. Бъгът никога не беше за Spaces. Винаги беше за избирането на грешния физически дисплей.

Фиксът, който изглеждаше очевиден — и беше грешен

Правилният сигнал изглежда лесен: захвани дисплея, на който е потребителят. Първата ни имплементация се закачи за overlay прозореца на GeekBye — захвани дисплея, на който живее overlay-ят.

Code review го уби, и то правилно. Overlay-ят на GeekBye се създава като full-workarea прозорец на основния дисплей, на позиция (0,0). Мести се на друг монитор само ако физически издърпаш неговата „хапче" там — а клавишните комбинации, които го побутват наоколо, се ограничават до размерите на основния дисплей, така че не могат изобщо да го преместят на втори монитор. Закачането на захващането за overlay-я означаваше: за всеки потребител, който не се е случило да издърпа overlay-я на работния си екран, „фиксът" се разрешаваше право обратно към основния дисплей. Той нямаше да поправи почти никого — докато изглеждаше, при бърз тест на dev машина с един монитор, сякаш работи.

Правилната котва е курсорът. Където и да е мишката ти, това е дисплеят, на който работиш — и е правилно за всеки начин, по който започва захващане: клавишна комбинация се задейства там, където сочиш, а натискането на бутона Record поставя курсора ти на този дисплей по дефиниция. Финалният фикс е функция от два реда: дисплеят, най-близък до курсора. Видеото съпоставя своя capture source с id-то на този дисплей; снимките подават границите на този дисплей към screencapture -R (конкретен правоъгълник) вместо флага -m за основен дисплей.

Избрахме -R (изричен правоъгълник в глобални екранни координати) вместо -D (индекс на дисплей) съзнателно: индексът на дисплея от операционната система няма гарантирано съответствие с подредбата на дисплеите на framework-а, така че индексът би бил втора игра на познаване. Правоъгълник от реалните граници на дисплея е недвусмислен — и проверихме поведението на флага, включително отрицателни координати за дисплеи, разположени вляво от основния, на реален multi-monitor стенд преди пускането.

Защо този е добър обучаващ бъг

  1. „Захвани екрана" крие решение. При един дисплей няма решение, така че решението никога не се проектира — то се остава по подразбиране. Multi-monitor е мястото, където всеки имплицитен default излиза наяве.
  2. Тихо-грешно е по-лошо от видимо-грешно. Видео бъгът дразнеше хората. Бъгът със снимката подвеждаше AI-я, невидимо. Когато строиш функции, които захранват контекст в модел, грешен вход произвежда уверено грешен изход без грешка никъде. Това са провалите, които си струва да ловуваш най-упорито.
  3. Фикс, който минава на твоята машина, може да се провали на тази на всички останали. Версията, закачена за overlay-я, работеше в тест с един монитор. Целият смисъл на бъга са няколкото монитора — а ревюиращият разсъждаваше за реалната позиция на прозореца, вместо да се довери на зеления тест. Review не е гумен печат върху работещ код; то е втори модел на това защо кодът работи.

GeekBye v2.0.10 пуска базирания на курсора фикс и за записа, и за снимките. Ако ползваш няколко дисплея, захващането вече те следва.

За съседните издания в тази серия виж защо твоят AI notetaker спира записа по средата на срещата (v2.0.9) и защо AI транскрипцията греши техническите термини (v2.0.11). За това как се държи overlay-ят по време на разговори виж как да останеш невидим по време на споделяне на екран.

Свързани статии

Една CSS променлива, пет кръга ревю и един Swift toolchain, който излъга
Steven
Steven7 мин четене

Една CSS променлива, пет кръга ревю и един Swift toolchain, който излъга

GeekBye v2.0.7 направи целия overlay регулируемо полупрозрачен — което звучи като едноредова CSS промяна и абсолютно не беше. Истинската история е какво улови ревюто: две повърхности, които отказваха да избледнеят, лента за запис, която изглеждаше грешно при същата непрозрачност, и компилиран бинарен файл, който се разлюля с 672 байта, защото собствената ни документация каза на един ревюиращ грешната версия на Swift.

Инженерство
Дизайн
Компилация
Бъгът със слушалките: когато другият човек изчезна от нашата транскрипция
Steven
Steven6 мин четене

Бъгът със слушалките: когато другият човек изчезна от нашата транскрипция

Двуканалната транскрипция работеше безупречно на високоговорителите на лаптопа и на слушалките тип over-ear. После някой включи слушалки тип „тапи" и човекът, с когото говореше, просто изчезна от транскрипцията — защото Chromium безшумно заглуши звука ни в мига, в който той проговори. Единайсет поправки се провалиха. Дванайсетата промени цялата архитектура.

Инженерство
Аудио
Транскрипция
Транскрипция на живо, когато защитната стена блокира WebSocket-ите
Steven
Steven5 мин четене

Транскрипция на живо, когато защитната стена блокира WebSocket-ите

Корпоративните мрежи обожават да разрешават HTTPS и тихо да убиват WebSocket upgrade-ите. Това счупва безшумно транскрипцията в реално време. GeekBye v2.0.8 автоматично преминава към чист HTTPS транспорт — а пускането му разкри бъг, който щеше да направи цялата функция безполезна.

Транскрипция
Мрежи
Инженерство