Steven
Steven5 min de lectura

Por qué la grabación de pantalla captura el monitor equivocado (y cómo lo arreglamos)

En una configuración de dos monitores, GeekBye grababa y capturaba la pantalla principal sin importar en qué monitor estuvieras trabajando. El arreglo fue una pequeña función — pero la primera versión estaba mal, y la code review descubrió por qué.

Grabación de Pantalla
Multipantalla
Ingeniería
Lanzamientos de GeekBye
Por qué la grabación de pantalla captura el monitor equivocado (y cómo lo arreglamos)

Este es un bug que solo existe si tienes dos monitores — por eso vivió tranquilo durante un tiempo. Trabajas en tu pantalla lateral, inicias una grabación de GeekBye y graba tu monitor principal. El de la barra de menús. El que no estabas mirando.

El mismo defecto, más silencioso y peor, golpeaba las capturas de pantalla que GeekBye envía a la IA para dar contexto: pulsas el atajo de captura en tu segundo monitor y la IA recibe una imagen del primero. No hay ninguna señal visual — el asistente simplemente responde sobre la pantalla equivocada y te quedas preguntándote por qué está confundido. GeekBye v2.0.10 corrigió ambos.

Dos pipelines, un mismo valor por defecto perezoso

La captura de pantalla en el escritorio son dos rutas de código separadas, y ambas habían elegido por su cuenta la pantalla principal:

  • La grabación de vídeo enumeraba las fuentes de pantalla disponibles y tomaba la primera — sources[0]. En macOS eso es, en la práctica, siempre la pantalla principal. Sin selector, sin lógica alguna sobre dónde estabas realmente. El comentario en nuestro propio código decía literalmente "auto-select first screen source."
  • Las capturas de pantalla usaban el comando screencapture de macOS con el flag -m. Ese flag tiene exactamente un significado: solo pantalla principal. Fijo en el código.

Ninguna de las dos rutas hacía jamás la pregunta que importa: ¿en qué pantalla está el usuario?

Una cosa que nunca estuvo rota, y vale la pena aclararla porque la gente asume que sí: cambiar entre Spaces de macOS en el mismo monitor siempre funcionó. La captura ocurre a nivel de pantalla — agarra el Space que esté visible en la pantalla elegida. El bug nunca fue sobre los Spaces. Siempre fue sobre elegir la pantalla física equivocada.

El arreglo que parecía obvio — y estaba mal

La señal correcta parece fácil: capturar la pantalla en la que está el usuario. Nuestra primera implementación se ancló en la ventana del overlay de GeekBye — capturar la pantalla en la que viva el overlay.

La code review lo mató, y con razón. El overlay de GeekBye se crea como una ventana a área de trabajo completa en la pantalla principal, en la posición (0,0). Solo se mueve a otro monitor si arrastras físicamente su pastilla hasta allí — y los atajos de teclado que lo empujan se limitan a las dimensiones de la pantalla principal, así que no pueden moverlo a un segundo monitor en absoluto. Anclar la captura en el overlay significaba: para cada usuario que no arrastrara por casualidad el overlay hasta su pantalla de trabajo, el "arreglo" resolvía de vuelta a la pantalla principal. No habría arreglado casi a nadie — mientras parecía, en una prueba rápida en una máquina de desarrollo de un solo monitor, que funcionaba.

El ancla correcta es el cursor. Donde esté tu ratón, esa es la pantalla en la que estás trabajando — y es correcta para cada forma en que arranca una captura: un atajo de teclado se dispara donde estás apuntando, y hacer clic en el botón Grabar pone tu cursor en esa pantalla por definición. El arreglo final es una función de dos líneas: la pantalla más cercana al cursor. El vídeo hace coincidir su fuente de captura con el id de esa pantalla; las capturas pasan los límites de esa pantalla a screencapture -R (un rectángulo concreto) en lugar del flag -m de pantalla principal.

Elegimos -R (un rectángulo explícito en coordenadas globales de pantalla) sobre -D (un índice de pantalla) de forma deliberada: el índice de pantalla del sistema operativo no tiene correspondencia garantizada con el orden de pantallas del framework, así que un índice sería un segundo juego de adivinanzas. Un rectángulo a partir de los límites reales de la pantalla es inequívoco — y verificamos el comportamiento del flag, incluidas las coordenadas negativas para pantallas colocadas a la izquierda de la principal, en un equipo multimonitor real antes de publicar.

Por qué este es un buen bug para aprender

  1. "Capturar la pantalla" esconde una decisión. En una sola pantalla no hay decisión, así que la decisión nunca se diseña — se toma por defecto. El multimonitor es donde aflora cada valor por defecto implícito.
  2. Equivocarse en silencio es peor que equivocarse a la vista. El bug del vídeo molestaba a la gente. El bug de las capturas engañaba a la IA, de forma invisible. Cuando construyes funciones que alimentan contexto a un modelo, una entrada equivocada produce una salida equivocada con total seguridad y sin ningún error por ninguna parte. Esos son los fallos que más merece la pena cazar.
  3. Un arreglo que pasa en tu máquina puede fallar en la de todos los demás. La versión anclada en el overlay funcionaba en una prueba de un solo monitor. Todo el sentido del bug son los múltiples monitores — y el revisor razonó sobre la posición real de la ventana en lugar de fiarse del test en verde. La revisión no es un sello de goma sobre código que funciona; es un segundo modelo de por qué funciona el código.

GeekBye v2.0.10 lleva el arreglo basado en el cursor tanto para la grabación como para las capturas. Si usas varias pantallas, la captura ahora te sigue.

Para los lanzamientos vecinos de esta serie, mira por qué tu notetaker con IA deja de grabar en mitad de la reunión (v2.0.9) y por qué la transcripción con IA malinterpreta los términos técnicos (v2.0.11). Sobre cómo se comporta el overlay durante las llamadas, mira cómo mantenerte invisible al compartir pantalla.

Artículos Relacionados

El silencio era estructural
Steven
Steven8 min de lectura

El silencio era estructural

Las dos últimas releases de GeekBye v1 giran en torno a la misma verdad incómoda: la transcripción en tiempo real sobre una red real no es sin pérdidas, y lo honesto es dejar de fingir que lo es. La v1.8.20 guardaba en disco una copia de cada chunk de audio antes de descartarlo durante una reconexión, y empezó a marcar en voz alta los huecos en la transcripción. La v1.9.0 dejó de enviar silencio para ahorrar ancho de banda — y descubrió que el silencio era justo la señal que el transcriptor usaba para saber que una frase había terminado. Dos releases sobre el coste de tirar cosas.

Ingeniería
Audio
Fiabilidad
Los tres verbos que mantienen vivo el Web Audio
Steven
Steven10 min de lectura

Los tres verbos que mantienen vivo el Web Audio

Dos releases puntuales de GeekBye, con dos meses de diferencia y en dos archivos distintos, le enseñaron a nuestro código de audio la misma lección desde extremos opuestos: dejar de tratar el AudioContext del navegador como desechable. Una release aprendió a hacer resume() de un contexto que macOS había suspendido silenciosamente a mitad de grabación; la otra aprendió a hacer suspend() en vez de close() para que las sesiones consecutivas dejen de estrellarse contra el techo de aproximadamente seis contextos de Chromium. Resume, suspend, close — ese es todo el argumento.

Ingeniería
Audio
Desktop
Distinguir una llamada de una app abierta
Steven
Steven10 min de lectura

Distinguir una llamada de una app abierta

GeekBye puede notar que te has unido a una reunión por video y ofrecerte grabarla. La detección resulta ser la mitad fácil — un binario Swift que lee títulos de ventana cada diez segundos. La mitad difícil es la precisión: no dispararse cuando Zoom está meramente abierto, no ofrecerte grabar una reunión que ya estás grabando, y no silenciar el micrófono en la llamada en la que realmente estás. Tres releases, y cada una es una salvaguarda que tuvo que aprender a no derrotarse a sí misma.

Ingeniería
macOS
Desktop