Fixed command modifier on macOS
parent
cdf312c83d
commit
7e1088167a
|
@ -177,209 +177,49 @@
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
/* This is a helper function for HandleModifierSide. This
|
|
||||||
* function reverts back to behavior before the distinction between
|
|
||||||
* sides was made.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
HandleNonDeviceModifier(unsigned int device_independent_mask,
|
|
||||||
unsigned int oldMods,
|
|
||||||
unsigned int newMods,
|
|
||||||
SDL_Scancode scancode)
|
|
||||||
{
|
|
||||||
unsigned int oldMask, newMask;
|
|
||||||
|
|
||||||
/* Isolate just the bits we care about in the depedent bits so we can
|
|
||||||
* figure out what changed
|
|
||||||
*/
|
|
||||||
oldMask = oldMods & device_independent_mask;
|
|
||||||
newMask = newMods & device_independent_mask;
|
|
||||||
|
|
||||||
if (oldMask && oldMask != newMask) {
|
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
|
||||||
} else if (newMask && oldMask != newMask) {
|
|
||||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a helper function for HandleModifierSide.
|
|
||||||
* This function sets the actual SDL_PrivateKeyboard event.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
|
|
||||||
SDL_Scancode scancode,
|
|
||||||
unsigned int sided_device_dependent_mask)
|
|
||||||
{
|
|
||||||
unsigned int old_dep_mask, new_dep_mask;
|
|
||||||
|
|
||||||
/* Isolate just the bits we care about in the depedent bits so we can
|
|
||||||
* figure out what changed
|
|
||||||
*/
|
|
||||||
old_dep_mask = oldMods & sided_device_dependent_mask;
|
|
||||||
new_dep_mask = newMods & sided_device_dependent_mask;
|
|
||||||
|
|
||||||
/* We now know that this side bit flipped. But we don't know if
|
|
||||||
* it went pressed to released or released to pressed, so we must
|
|
||||||
* find out which it is.
|
|
||||||
*/
|
|
||||||
if (new_dep_mask && old_dep_mask != new_dep_mask) {
|
|
||||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
|
||||||
} else {
|
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a helper function for DoSidedModifiers.
|
|
||||||
* This function will figure out if the modifier key is the left or right side,
|
|
||||||
* e.g. left-shift vs right-shift.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
HandleModifierSide(int device_independent_mask,
|
|
||||||
unsigned int oldMods, unsigned int newMods,
|
|
||||||
SDL_Scancode left_scancode,
|
|
||||||
SDL_Scancode right_scancode,
|
|
||||||
unsigned int left_device_dependent_mask,
|
|
||||||
unsigned int right_device_dependent_mask)
|
|
||||||
{
|
|
||||||
unsigned int device_dependent_mask = (left_device_dependent_mask |
|
|
||||||
right_device_dependent_mask);
|
|
||||||
unsigned int diff_mod;
|
|
||||||
|
|
||||||
/* On the basis that the device independent mask is set, but there are
|
|
||||||
* no device dependent flags set, we'll assume that we can't detect this
|
|
||||||
* keyboard and revert to the unsided behavior.
|
|
||||||
*/
|
|
||||||
if ((device_dependent_mask & newMods) == 0) {
|
|
||||||
/* Revert to the old behavior */
|
|
||||||
HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XOR the previous state against the new state to see if there's a change */
|
|
||||||
diff_mod = (device_dependent_mask & oldMods) ^
|
|
||||||
(device_dependent_mask & newMods);
|
|
||||||
if (diff_mod) {
|
|
||||||
/* A change in state was found. Isolate the left and right bits
|
|
||||||
* to handle them separately just in case the values can simulataneously
|
|
||||||
* change or if the bits don't both exist.
|
|
||||||
*/
|
|
||||||
if (left_device_dependent_mask & diff_mod) {
|
|
||||||
HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
|
|
||||||
}
|
|
||||||
if (right_device_dependent_mask & diff_mod) {
|
|
||||||
HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a helper function for DoSidedModifiers.
|
|
||||||
* This function will release a key press in the case that
|
|
||||||
* it is clear that the modifier has been released (i.e. one side
|
|
||||||
* can't still be down).
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ReleaseModifierSide(unsigned int device_independent_mask,
|
|
||||||
unsigned int oldMods, unsigned int newMods,
|
|
||||||
SDL_Scancode left_scancode,
|
|
||||||
SDL_Scancode right_scancode,
|
|
||||||
unsigned int left_device_dependent_mask,
|
|
||||||
unsigned int right_device_dependent_mask)
|
|
||||||
{
|
|
||||||
unsigned int device_dependent_mask = (left_device_dependent_mask |
|
|
||||||
right_device_dependent_mask);
|
|
||||||
|
|
||||||
/* On the basis that the device independent mask is set, but there are
|
|
||||||
* no device dependent flags set, we'll assume that we can't detect this
|
|
||||||
* keyboard and revert to the unsided behavior.
|
|
||||||
*/
|
|
||||||
if ((device_dependent_mask & oldMods) == 0) {
|
|
||||||
/* In this case, we can't detect the keyboard, so use the left side
|
|
||||||
* to represent both, and release it.
|
|
||||||
*/
|
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This could have been done in an if-else case because at this point,
|
|
||||||
* we know that all keys have been released when calling this function.
|
|
||||||
* But I'm being paranoid so I want to handle each separately,
|
|
||||||
* so I hope this doesn't cause other problems.
|
|
||||||
*/
|
|
||||||
if ( left_device_dependent_mask & oldMods ) {
|
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
|
|
||||||
}
|
|
||||||
if ( right_device_dependent_mask & oldMods ) {
|
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function will handle the modifier keys and also determine the
|
|
||||||
* correct side of the key.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
DoSidedModifiers(unsigned short scancode,
|
|
||||||
unsigned int oldMods, unsigned int newMods)
|
|
||||||
{
|
|
||||||
/* Set up arrays for the key syms for the left and right side. */
|
|
||||||
const SDL_Scancode left_mapping[] = {
|
|
||||||
SDL_SCANCODE_LSHIFT,
|
|
||||||
SDL_SCANCODE_LCTRL,
|
|
||||||
SDL_SCANCODE_LALT,
|
|
||||||
SDL_SCANCODE_LGUI
|
|
||||||
};
|
|
||||||
const SDL_Scancode right_mapping[] = {
|
|
||||||
SDL_SCANCODE_RSHIFT,
|
|
||||||
SDL_SCANCODE_RCTRL,
|
|
||||||
SDL_SCANCODE_RALT,
|
|
||||||
SDL_SCANCODE_RGUI
|
|
||||||
};
|
|
||||||
/* Set up arrays for the device dependent masks with indices that
|
|
||||||
* correspond to the _mapping arrays
|
|
||||||
*/
|
|
||||||
const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
|
|
||||||
const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
|
|
||||||
|
|
||||||
unsigned int i, bit;
|
|
||||||
|
|
||||||
/* Iterate through the bits, testing each against the old modifiers */
|
|
||||||
for (i = 0, bit = NSEventModifierFlagShift; bit <= NSEventModifierFlagCommand; bit <<= 1, ++i) {
|
|
||||||
unsigned int oldMask, newMask;
|
|
||||||
|
|
||||||
oldMask = oldMods & bit;
|
|
||||||
newMask = newMods & bit;
|
|
||||||
|
|
||||||
/* If the bit is set, we must always examine it because the left
|
|
||||||
* and right side keys may alternate or both may be pressed.
|
|
||||||
*/
|
|
||||||
if (newMask) {
|
|
||||||
HandleModifierSide(bit, oldMods, newMods,
|
|
||||||
left_mapping[i], right_mapping[i],
|
|
||||||
left_device_mapping[i], right_device_mapping[i]);
|
|
||||||
}
|
|
||||||
/* If the state changed from pressed to unpressed, we must examine
|
|
||||||
* the device dependent bits to release the correct keys.
|
|
||||||
*/
|
|
||||||
else if (oldMask && oldMask != newMask) {
|
|
||||||
ReleaseModifierSide(bit, oldMods, newMods,
|
|
||||||
left_mapping[i], right_mapping[i],
|
|
||||||
left_device_mapping[i], right_device_mapping[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
|
HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
|
||||||
{
|
{
|
||||||
SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
|
SDL_Scancode code = darwin_scancode_table[scancode];
|
||||||
|
|
||||||
if (modifierFlags == data.modifierFlags) {
|
const SDL_Scancode codes[] = {
|
||||||
return;
|
SDL_SCANCODE_LSHIFT,
|
||||||
|
SDL_SCANCODE_LCTRL,
|
||||||
|
SDL_SCANCODE_LALT,
|
||||||
|
SDL_SCANCODE_LGUI,
|
||||||
|
SDL_SCANCODE_RSHIFT,
|
||||||
|
SDL_SCANCODE_RCTRL,
|
||||||
|
SDL_SCANCODE_RALT,
|
||||||
|
SDL_SCANCODE_RGUI,
|
||||||
|
SDL_SCANCODE_LSHIFT,
|
||||||
|
SDL_SCANCODE_LCTRL,
|
||||||
|
SDL_SCANCODE_LALT,
|
||||||
|
SDL_SCANCODE_LGUI, };
|
||||||
|
|
||||||
|
const unsigned int modifiers[] = {
|
||||||
|
NX_DEVICELSHIFTKEYMASK,
|
||||||
|
NX_DEVICELCTLKEYMASK,
|
||||||
|
NX_DEVICELALTKEYMASK,
|
||||||
|
NX_DEVICELCMDKEYMASK,
|
||||||
|
NX_DEVICERSHIFTKEYMASK,
|
||||||
|
NX_DEVICERCTLKEYMASK,
|
||||||
|
NX_DEVICERALTKEYMASK,
|
||||||
|
NX_DEVICERCMDKEYMASK,
|
||||||
|
NX_SHIFTMASK,
|
||||||
|
NX_CONTROLMASK,
|
||||||
|
NX_ALTERNATEMASK,
|
||||||
|
NX_COMMANDMASK };
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if (code == codes[i])
|
||||||
|
{
|
||||||
|
if (modifierFlags & modifiers[i])
|
||||||
|
SDL_SendKeyboardKey(SDL_PRESSED, code);
|
||||||
|
else
|
||||||
|
SDL_SendKeyboardKey(SDL_RELEASED, code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DoSidedModifiers(scancode, data.modifierFlags, modifierFlags);
|
|
||||||
data.modifierFlags = modifierFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -579,8 +419,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, code);
|
SDL_SendKeyboardKey(SDL_RELEASED, code);
|
||||||
break;
|
break;
|
||||||
case NSEventTypeFlagsChanged:
|
case NSEventTypeFlagsChanged:
|
||||||
/* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
|
HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);
|
||||||
HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);
|
|
||||||
break;
|
break;
|
||||||
default: /* just to avoid compiler warnings */
|
default: /* just to avoid compiler warnings */
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue