Saltar al contenido principal

Migrar ShortcutActivator y ShortcutManager al sistema KeyEvent

El subsistema de eventos de teclado en crudo (raw key event) ha sido reemplazado por el subsistema de eventos de teclado, y las APIs que usan RawKeyEvent y RawKeyboard se convierten a KeyEvent y HardwareKeyboard.

Resumen

#

Desde hace algún tiempo (años), Flutter ha tenido dos sistemas de eventos de teclado implementados. El nuevo sistema alcanzó la paridad con el antiguo sistema de eventos de teclas nativas (raw key events) de cada plataforma, y el sistema antiguo (raw) será eliminado. Para prepararse para eso, se están modificando las APIs de Flutter que usan el sistema antiguo, y para unas pocas de ellas hemos decidido realizar cambios disruptivos (breaking changes) en la API para preservar la calidad de la misma.

Contexto

#

En el subsistema de eventos de teclado original, manejar las particularidades de cada plataforma en el framework y en las aplicaciones clientes generaba un código excesivamente complejo, y el sistema antiguo no representaba correctamente el estado real de los eventos de teclado en el sistema.

Por lo tanto, nació el nuevo sistema basado en KeyEvent, y para minimizar los cambios disruptivos, se implementó en paralelo con el sistema antiguo con la intención de eventualmente deprecar el sistema raw. Ese momento está llegando rápidamente, y para prepararse, hemos realizado algunos cambios disruptivos mínimos requeridos para preservar la calidad de la API.

Descripción del cambio

#

Resumen de las APIs que se han visto afectadas:

  • ShortcutActivator.accepts ahora recibe un KeyEvent y un HardwareKeyboard.
  • ShortcutActivator.isActivatedBy ahora está deprecado. Simplemente llama a accepts en su lugar.
  • ShortcutActivator.triggers ahora es opcional y devuelve null si no está implementado.
  • ShortcutManager.handleKeypress ahora recibe un KeyEvent.

El cambio modifica el método ShortcutActivator.accepts para recibir un KeyEvent y un HardwareKeyboard en lugar del anterior RawKeyEvent y RawKeyboard.

El significado de ShortcutActivator.accepts ha cambiado ligeramente. Antes del cambio, se asumía que accepts solo se llamaba si ShortcutActivator.triggers devolvía null, o si el evento de teclado enviado a accepts tenía una tecla lógica que estaba en la lista de triggers. Ahora siempre se llama, y puede usar la lista de triggers como una mejora de rendimiento, pero no es obligatorio hacerlo. Las subclases de Flutter como SingleActivator y CharacterActivator ya hacen esto.

El cambio también modifica el método ShortcutManager.handleKeypress para recibir un KeyEvent en lugar de RawKeyEvent.

Guía de migración

#

Las APIs proporcionadas por el framework de Flutter ya han sido migradas. La migración es necesaria solo si estás utilizando alguno de los métodos enumerados en la sección anterior.

Migración de tus APIs que usan ShortcutActivator o sus subclases.

#

Pasa un KeyEvent en lugar de un RawKeyEvent a ShortcutActivator.accepts. Esto puede significar cambiar el lugar de donde obtienes tus eventos de teclado. Dependiendo de dónde los obtengas, esto puede significar cambiar al uso de Focus.onKeyEvent en su lugar de Focus.onKey, o un cambio similar si utilizas FocusScope, FocusNode o FocusScopeNode.

Si estás utilizando un RawKeyboardListener, cambia a usar un KeyboardListener en su lugar. Si estás accediendo a RawKeyboard directamente, usa HardwareKeyboard en su lugar. Encontrarás que existen equivalentes no-raw para todas las fuentes de eventos de teclado.

Migración de tus APIs que extienden ShortcutActivator

#

El método ShortcutActivator.accepts fue modificado para recibir un KeyEvent y un HardwareKeyboard en lugar de un RawKeyEvent y RawKeyboard.

Antes:

dart
class MyActivator extends ShortcutActivator {
  @override
  bool accepts(RawKeyEvent event, RawKeyboard state) {
    // ... (your implementation here)
    returns false;
  }
  // ...
}

Después:

dart
class MyActivator extends ShortcutActivator {
  @override
  bool accepts(KeyEvent event, HardwareKeyboard state) {
    // ... (your implementation here)
    returns false;
  }
  // ...
}

Migración de tus APIs que extienden ShortcutManager

#

La clase ShortcutManager fue modificada para recibir KeyEvents en handleKeypress en lugar de RawKeyEvents. Una diferencia en las dos APIs es que las teclas repetidas se determinan de manera diferente. En el caso de RawKeyEvent, el miembro repeat indicaba una repetición, pero en el código de RawKeyEvent, el evento es de un tipo diferente (KeyRepeatEvent).

Antes:

dart
class _MyShortcutManager extends ShortcutManager {
  @override
  KeyEventResult handleKeypress(BuildContext context, RawKeyEvent event) {
    if (event is! RawKeyDownEvent) {
      return KeyEventResult.ignored;
    }
    if (event.repeat) {
      // (Do something with repeated keys.)
    }
    // ... (your implementation here)
    return KeyEventResult.handled;
  }
}

Después:

dart
class _MyShortcutManager extends ShortcutManager {
  @override
  KeyEventResult handleKeypress(BuildContext context, KeyEvent event) {
    if (event is! KeyDownEvent && event is! KeyRepeatEvent) {
      return KeyEventResult.ignored;
    }
    if (event is KeyRepeatEvent) {
      // (Do something with repeated keys.)
    }
    // ... (your implementation here)
    return KeyEventResult.handled;
  }
}

Timeline

#

Llegó en la versión: 3.17.0-5.0.pre
En la versión estable: 3.19.0

Referencias

#

Documentación de la API:

Issues relevantes:

PRs relevantes: