Handle bare modifier flags on macOS (#45438)
This fixes an unreported bug in the macOS key handling where for some remote access situations, the modifier mask is set to the "any modifier" mask without any side specified (e.g. modifierShift bit is specified and not modifierLeftShift bit).
This commit is contained in:
@@ -127,15 +127,21 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
if (modifiers & anyMask == 0) {
|
||||
return false;
|
||||
}
|
||||
// If only the "anyMask" bit is set, then we respond true for requests of
|
||||
// whether either left or right is pressed.
|
||||
// Handles the case where macOS supplies just the "either" modifier flag,
|
||||
// but not the left/right flag. (e.g. modifierShift but not
|
||||
// modifierLeftShift).
|
||||
final bool anyOnly = modifiers & (leftMask | rightMask | anyMask) == anyMask;
|
||||
switch (side) {
|
||||
case KeyboardSide.any:
|
||||
return true;
|
||||
case KeyboardSide.all:
|
||||
return modifiers & leftMask != 0 && modifiers & rightMask != 0;
|
||||
return modifiers & leftMask != 0 && modifiers & rightMask != 0 || anyOnly;
|
||||
case KeyboardSide.left:
|
||||
return modifiers & leftMask != 0;
|
||||
return modifiers & leftMask != 0 || anyOnly;
|
||||
case KeyboardSide.right:
|
||||
return modifiers & rightMask != 0;
|
||||
return modifiers & rightMask != 0 || anyOnly;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -143,17 +149,23 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
@override
|
||||
bool isModifierPressed(ModifierKey key, {KeyboardSide side = KeyboardSide.any}) {
|
||||
final int independentModifier = modifiers & deviceIndependentMask;
|
||||
bool result;
|
||||
switch (key) {
|
||||
case ModifierKey.controlModifier:
|
||||
return _isLeftRightModifierPressed(side, independentModifier & modifierControl, modifierLeftControl, modifierRightControl);
|
||||
result = _isLeftRightModifierPressed(side, independentModifier & modifierControl, modifierLeftControl, modifierRightControl);
|
||||
break;
|
||||
case ModifierKey.shiftModifier:
|
||||
return _isLeftRightModifierPressed(side, independentModifier & modifierShift, modifierLeftShift, modifierRightShift);
|
||||
result = _isLeftRightModifierPressed(side, independentModifier & modifierShift, modifierLeftShift, modifierRightShift);
|
||||
break;
|
||||
case ModifierKey.altModifier:
|
||||
return _isLeftRightModifierPressed(side, independentModifier & modifierOption, modifierLeftOption, modifierRightOption);
|
||||
result = _isLeftRightModifierPressed(side, independentModifier & modifierOption, modifierLeftOption, modifierRightOption);
|
||||
break;
|
||||
case ModifierKey.metaModifier:
|
||||
return _isLeftRightModifierPressed(side, independentModifier & modifierCommand, modifierLeftCommand, modifierRightCommand);
|
||||
result = _isLeftRightModifierPressed(side, independentModifier & modifierCommand, modifierLeftCommand, modifierRightCommand);
|
||||
break;
|
||||
case ModifierKey.capsLockModifier:
|
||||
return independentModifier & modifierCapsLock != 0;
|
||||
result = independentModifier & modifierCapsLock != 0;
|
||||
break;
|
||||
// On macOS, the function modifier bit is set for any function key, like F1,
|
||||
// F2, etc., but the meaning of ModifierKey.modifierFunction in Flutter is
|
||||
// that of the Fn modifier key, so there's no good way to emulate that on
|
||||
@@ -163,21 +175,26 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
case ModifierKey.symbolModifier:
|
||||
case ModifierKey.scrollLockModifier:
|
||||
// These modifier masks are not used in macOS keyboards.
|
||||
return false;
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
assert(!result || getModifierSide(key) != null, "$runtimeType thinks that a modifier is pressed, but can't figure out what side it's on.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
KeyboardSide getModifierSide(ModifierKey key) {
|
||||
KeyboardSide findSide(int leftMask, int rightMask) {
|
||||
KeyboardSide findSide(int leftMask, int rightMask, int anyMask) {
|
||||
final int combinedMask = leftMask | rightMask;
|
||||
final int combined = modifiers & combinedMask;
|
||||
if (combined == leftMask) {
|
||||
return KeyboardSide.left;
|
||||
} else if (combined == rightMask) {
|
||||
return KeyboardSide.right;
|
||||
} else if (combined == combinedMask) {
|
||||
} else if (combined == combinedMask || modifiers & (combinedMask | anyMask) == anyMask) {
|
||||
// Handles the case where macOS supplies just the "either" modifier
|
||||
// flag, but not the left/right flag. (e.g. modifierShift but not
|
||||
// modifierLeftShift).
|
||||
return KeyboardSide.all;
|
||||
}
|
||||
return null;
|
||||
@@ -185,13 +202,13 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
|
||||
switch (key) {
|
||||
case ModifierKey.controlModifier:
|
||||
return findSide(modifierLeftControl, modifierRightControl);
|
||||
return findSide(modifierLeftControl, modifierRightControl, modifierControl);
|
||||
case ModifierKey.shiftModifier:
|
||||
return findSide(modifierLeftShift, modifierRightShift);
|
||||
return findSide(modifierLeftShift, modifierRightShift, modifierShift);
|
||||
case ModifierKey.altModifier:
|
||||
return findSide(modifierLeftOption, modifierRightOption);
|
||||
return findSide(modifierLeftOption, modifierRightOption, modifierOption);
|
||||
case ModifierKey.metaModifier:
|
||||
return findSide(modifierLeftCommand, modifierRightCommand);
|
||||
return findSide(modifierLeftCommand, modifierRightCommand, modifierCommand);
|
||||
case ModifierKey.capsLockModifier:
|
||||
case ModifierKey.numLockModifier:
|
||||
case ModifierKey.scrollLockModifier:
|
||||
|
||||
@@ -563,6 +563,10 @@ void main() {
|
||||
RawKeyEventDataMacOs.modifierControl | RawKeyEventDataMacOs.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
|
||||
RawKeyEventDataMacOs.modifierCommand | RawKeyEventDataMacOs.modifierLeftCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
|
||||
RawKeyEventDataMacOs.modifierCommand | RawKeyEventDataMacOs.modifierRightCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
|
||||
RawKeyEventDataMacOs.modifierOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
|
||||
RawKeyEventDataMacOs.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
|
||||
RawKeyEventDataMacOs.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
|
||||
RawKeyEventDataMacOs.modifierCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.all),
|
||||
RawKeyEventDataMacOs.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user