private XkbKeyPressData TrackKey(uint keyCode, uint state) { // Determine the keysym for this before any event as it may impact if we read it afterwards KeyboardKey key = XkbStateKeySym(_stateHandle, keyCode); if (state == 0) { _keyboardState.KeyRemove(key, keyCode); } else { _keyboardState.KeyAdd(key, keyCode); } // Update our current tracking state uint stateModsEffective = (1 << 3); uint newState = XkbStateUpdateKey(_stateHandle, keyCode, state); if ((newState & stateModsEffective) != 0) { List <KeyboardModifier> modifiers = new List <KeyboardModifier>(); if (XkbStateModNameIsActive(_stateHandle, "Shift", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.Shift); } if (XkbStateModNameIsActive(_stateHandle, "Lock", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.CapsLock); } if (XkbStateModNameIsActive(_stateHandle, "Control", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.Control); } if (XkbStateModNameIsActive(_stateHandle, "Mod1", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.Alt); } if (XkbStateModNameIsActive(_stateHandle, "Mod2", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.NumLock); } if (XkbStateModNameIsActive(_stateHandle, "Mod4", stateModsEffective) == 1) { modifiers.Add(KeyboardModifier.Logo); } _keyboardState.ModifiersUpdate(modifiers); // Update any key codes that have changed - i.e. A to a when shift is depressed uint[] keyCodes = _keyboardState.KeyCodes; KeyboardKey[] keys = _keyboardState.Keys; foreach (uint thisKeyCode in keyCodes) { KeyboardKey thisKey = XkbStateKeySym(_stateHandle, thisKeyCode); if (!keys.Contains(thisKey)) { _keyboardState.KeyAdd(thisKey, thisKeyCode); } } } // Return press data return(GetPressData(key, keyCode)); }