@@ -171,6 +171,22 @@ class PhysicalKeyData {
171171        // Skip key that is not actually generated by any keyboard. 
172172        continue ;
173173      }
174+       final  PhysicalKeyEntry ?  existing =  entries[usbHidCode];
175+       // Allow duplicate entries for Fn, which overwrites. 
176+       if  (existing !=  null  &&  existing.name !=  'Fn' ) {
177+         // If it's an existing entry, the only thing we currently support is 
178+         // to insert an extra DOMKey. The other entries must be empty. 
179+         assert (evdevCode ==  0 
180+             &&  xKbScanCode ==  0 
181+             &&  windowsScanCode ==  0 
182+             &&  macScanCode ==  0xffff 
183+             &&  chromiumCode !=  null 
184+             &&  chromiumCode.isNotEmpty,
185+             'Duplicate usbHidCode ${existing .usbHidCode } of key ${existing .name } ' 
186+             'conflicts with existing ${entries [existing .usbHidCode ]!.name }.' );
187+         existing.otherWebCodes.add (chromiumCode! );
188+         continue ;
189+       }
174190      final  PhysicalKeyEntry  newEntry =  PhysicalKeyEntry (
175191        usbHidCode:  usbHidCode,
176192        androidScanCodes:  nameToAndroidScanCodes[name] ??  < int > [],
@@ -182,15 +198,6 @@ class PhysicalKeyData {
182198        name:  name,
183199        chromiumCode:  chromiumCode,
184200      );
185-       // Remove duplicates: last one wins, so that supplemental codes 
186-       // override. 
187-       if  (entries.containsKey (newEntry.usbHidCode)) {
188-         // This is expected for Fn. Warn for other keys. 
189-         if  (newEntry.name !=  'Fn' ) {
190-           print ('Duplicate usbHidCode ${newEntry .usbHidCode } of key ${newEntry .name } ' 
191-             'conflicts with existing ${entries [newEntry .usbHidCode ]!.name }. Keeping the new one.' );
192-         }
193-       }
194201      entries[newEntry.usbHidCode] =  newEntry;
195202    }
196203    return  entries.map ((int  code, PhysicalKeyEntry  entry) => 
@@ -216,7 +223,8 @@ class PhysicalKeyEntry {
216223    required  this .macOSScanCode,
217224    required  this .iOSScanCode,
218225    required  this .chromiumCode,
219-   });
226+     List <String >?  otherWebCodes,
227+   }) :  otherWebCodes =  otherWebCodes ??  < String > [];
220228
221229  /// Populates the key from a JSON map. 
222230factory  PhysicalKeyEntry .fromJsonMapEntry (Map <String , dynamic > map) {
@@ -232,6 +240,7 @@ class PhysicalKeyEntry {
232240      windowsScanCode:  scanCodes['windows' ] as  int ? ,
233241      macOSScanCode:  scanCodes['macos' ] as  int ? ,
234242      iOSScanCode:  scanCodes['ios' ] as  int ? ,
243+       otherWebCodes:  (map['otherWebCodes' ] as  List <dynamic >? )? .cast <String >(),
235244    );
236245  }
237246
@@ -258,11 +267,14 @@ class PhysicalKeyEntry {
258267final  String  name;
259268  /// The Chromium event code for the key. 
260269final  String ?  chromiumCode;
270+   /// Other codes used by Web besides chromiumCode. 
271+ final  List <String > otherWebCodes;
261272
262273  Iterable <String > webCodes () sync *  {
263274    if  (chromiumCode !=  null ) {
264275      yield  chromiumCode! ;
265276    }
277+     yield *  otherWebCodes;
266278  }
267279
268280  /// Creates a JSON map from the key data. 
@@ -272,6 +284,7 @@ class PhysicalKeyEntry {
272284        'name' :  name,
273285        'chromium' :  chromiumCode,
274286      },
287+       'otherWebCodes' :  otherWebCodes,
275288      'scanCodes' :  < String , dynamic > {
276289        'android' :  androidScanCodes,
277290        'usb' :  usbHidCode,
@@ -323,11 +336,14 @@ class PhysicalKeyEntry {
323336
324337  @override 
325338  String  toString () {
339+     final  String  otherWebStr =  otherWebCodes.isEmpty
340+         ?  '' 
341+         :  ', otherWebCodes: [${otherWebCodes .join (', ' )}]' ;
326342    return  """'$constantName ': (name: "$name ", usbHidCode: ${toHex (usbHidCode )}, """ 
327343        'linuxScanCode: ${toHex (evdevCode )}, xKbScanCode: ${toHex (xKbScanCode )}, ' 
328344        'windowsKeyCode: ${toHex (windowsScanCode )}, macOSScanCode: ${toHex (macOSScanCode )}, ' 
329345        'windowsScanCode: ${toHex (windowsScanCode )}, chromiumSymbolName: $chromiumCode  ' 
330-         'iOSScanCode: ${toHex (iOSScanCode )})' ;
346+         'iOSScanCode: ${toHex (iOSScanCode )})$ otherWebStr ' ;
331347  }
332348
333349  static  int  compareByUsbHidCode (PhysicalKeyEntry  a, PhysicalKeyEntry  b) => 
0 commit comments