
Чому запис екрана захоплює не той монітор (і як ми це виправили)
На конфігурації з двома моніторами GeekBye записував і робив скриншоти з основного дисплея незалежно від того, на якому екрані ви працювали. Фікс умістився в одну невелику функцію — але перша її версія була хибною, і код-рев’ю впіймало чому.
Ось баг, який існує, лише якщо у вас два монітори, — тому він якийсь час і жив тихо. Ви працюєте на бічному дисплеї, запускаєте запис GeekBye, а він записує ваш основний монітор. Той, що з меню-баром. Той, на який ви не дивилися.
Той самий дефект, тихіший і гірший, ударив по скриншотах, які GeekBye надсилає ШІ для контексту: тиснете гарячу клавішу скриншота на другому моніторі, а ШІ отримує картинку першого. Жодної візуальної ознаки — асистент просто відповідає про не той екран, а ви дивуєтеся, чому він спантеличений. GeekBye v2.0.10 виправив обидва.
Два конвеєри, один лінивий дефолт
Захоплення екрана на десктопі — це два окремі шляхи коду, і обидва незалежно обрали основний дисплей:
- Запис відео перелічувала доступні джерела екрана і брала перше —
sources[0]. На macOS це фактично завжди основний дисплей. Ні вибору, ні логіки про те, де ви насправді були. Коментар у нашому власному коді буквально казав «auto-select first screen source» (автовибір першого джерела екрана). - Скриншоти використовували macOS-команду
screencaptureз флагом-m. У цього флага рівно одне значення: лише основний дисплей. Зашито намертво.
Жоден зі шляхів жодного разу не поставив питання, яке має значення: на якому екрані користувач?
Одне, що ніколи не було зламаним, і це варто прояснити, бо люди думають інакше: перемикання між просторами (Spaces) macOS на тому самому моніторі завжди працювало. Захоплення відбувається на рівні дисплея — воно бере той простір, що видно на обраному дисплеї. Баг ніколи не був про простори. Він завжди був про вибір не того фізичного дисплея.
Фікс, який виглядав очевидним — і був хибним
Правильний сигнал здається простим: захопи дисплей, на якому користувач. Наша перша реалізація прив’язалася до вікна оверлея GeekBye — захоплюй той дисплей, на якому живе оверлей.
Код-рев’ю справедливо його зарубало. Оверлей GeekBye створюється як вікно на всю робочу область на основному дисплеї, у позиції (0,0). Він переміщується на інший монітор, лише якщо ви фізично перетягнете туди його «пігулку» — а гарячі клавіші, що його підсовують, затиснуті розмірами основного дисплея, тож вони не можуть перенести його на другий монітор узагалі. Прив’язка захоплення до оверлея означала: для кожного користувача, який не перетягнув оверлей на свій робочий екран, «фікс» розв’язувався назад в основний дисплей. Він не виправив би майже нікого — а під час швидкого тесту на одномоніторній машині розробника виглядав би як робочий.
Правильна точка прив’язки — курсор. Хоч би де була ваша миша, це і є дисплей, на якому ви працюєте, — і це вірно для будь-якого способу почати захоплення: гаряча клавіша спрацьовує там, куди ви вказуєте, а клік по кнопці «Запис» за визначенням поміщає ваш курсор на цей дисплей. Підсумковий фікс — дворядкова функція: дисплей, найближчий до курсора. Відео зіставляє своє джерело захоплення з id цього дисплея; скриншоти передають межі цього дисплея в screencapture -R (конкретний прямокутник) замість флага -m (лише основний дисплей).
Ми навмисне обрали -R (явний прямокутник у глобальних координатах екрана) замість -D (індекс дисплея): індекс дисплея в ОС не має гарантованої відповідності порядку дисплеїв у фреймворку, тож індекс був би другою грою в вгадайку. Прямокутник із реальних меж дисплея однозначний — а поведінку флага ми перевірили, включно з від’ємними координатами для дисплеїв ліворуч від основного, на справжній багатомоніторній збірці перед випуском.
Чому це добрий навчальний баг
- «Захопи екран» приховує рішення. На одному дисплеї рішення немає, тому рішення ніколи не проєктується — воно призначається за замовчуванням. Кілька моніторів — це місце, де випливає кожен неявний дефолт.
- Тихо-хибно гірше, ніж видимо-хибно. Баг із відео дратував людей. Баг зі скриншотом вводив в оману ШІ, незримо. Коли ви будуєте функції, що живлять модель контекстом, хибний вхід дає впевнено хибний вихід без жодної помилки будь-де. Саме такі відмови варто вистежувати найзапекліше.
- Фікс, що проходить на вашій машині, може провалитися на будь-якій чужій. Версія, прив’язана до оверлея, працювала в одномоніторному тесті. Весь сенс бага — кілька моніторів, — а рев’юер розважив про реальне положення вікна, замість того щоб довіряти зеленому тесту. Рев’ю — не штамп на робочому коді; це друга модель того, чому код працює.
GeekBye v2.0.10 випускає оснований на курсорі фікс і для запису, і для скриншотів. Якщо у вас кілька дисплеїв, захоплення тепер іде за вами.
Сусідні релізи цієї серії дивіться в чому ваш ШІ-нотатник зупиняє запис посеред зустрічі (v2.0.9) і чому ШІ-транскрипція перекручує технічні терміни (v2.0.11). Про те, як оверлей поводиться під час дзвінків, читайте в як лишатися невидимим під час демонстрації екрана.