Skip to content

Commit e6254ab

Browse files
FIX: Xbox Controllers on macOS don't detect up-left DPAD presses (ISXB-810) (#2140)
1 parent 36a93fe commit e6254ab

File tree

3 files changed

+33
-25
lines changed

3 files changed

+33
-25
lines changed

Assets/Tests/InputSystem/Plugins/XInputTests.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using UnityEngine.InputSystem.Layouts;
66
using UnityEngine.InputSystem.Utilities;
77
using System.Runtime.InteropServices;
8+
using UnityEngine.InputSystem.Controls;
89
using UnityEngine.InputSystem.HID;
910
using UnityEngine.InputSystem.Processors;
1011

@@ -207,8 +208,6 @@ public void Devices_SupportWirelessXboxOneAndSeriesControllerOnOSX(int vendorId,
207208
Assert.That(gamepad.startButton.isPressed);
208209
}
209210

210-
// Disable tests in standalone builds from 2022.1+ see UUM-19622
211-
#if !UNITY_STANDALONE_OSX || !TEMP_DISABLE_STANDALONE_OSX_XINPUT_TEST
212211
[Test]
213212
[Category("Devices")]
214213
public void Devices_SupportXboxWirelessControllerOnOSX()
@@ -242,6 +241,8 @@ public void Devices_SupportXboxWirelessControllerOnOSX()
242241

243242
InputSystem.Update();
244243

244+
Assert.That(gamepad.leftStick.x.IsActuated());
245+
245246
Assert.That(gamepad.leftStick.x.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
246247
Assert.That(gamepad.leftStick.y.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
247248
Assert.That(gamepad.leftStick.up.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
@@ -268,10 +269,17 @@ public void Devices_SupportXboxWirelessControllerOnOSX()
268269
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithButton(XInputControllerWirelessOSXState.Button.Y), gamepad.yButton);
269270
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithButton(XInputControllerWirelessOSXState.Button.Y), gamepad.buttonNorth);
270271

271-
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(5), gamepad.dpad.down);
272272
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(1), gamepad.dpad.up);
273-
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(7), gamepad.dpad.left);
273+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(2), gamepad.dpad.up, gamepad.dpad.right);
274274
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(3), gamepad.dpad.right);
275+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(4), gamepad.dpad.down, gamepad.dpad.right);
276+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(5), gamepad.dpad.down);
277+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(6), gamepad.dpad.down, gamepad.dpad.left);
278+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(7), gamepad.dpad.left);
279+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(8), gamepad.dpad.up, gamepad.dpad.left);
280+
// No Dpad button pressed when the value is 0
281+
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithDpad(0));
282+
275283

276284
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithButton(XInputControllerWirelessOSXState.Button.LeftThumbstickPress), gamepad.leftStickButton);
277285
AssertButtonPress(gamepad, XInputControllerWirelessOSXState.defaultState.WithButton(XInputControllerWirelessOSXState.Button.RightThumbstickPress), gamepad.rightStickButton);
@@ -306,9 +314,6 @@ public void Devices_SupportXboxWirelessControllerOnOSX()
306314

307315
#endif // TEMP_DISABLE_STANDALONE_OSX_XINPUT_TEST
308316

309-
#endif
310-
311-
312317
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN || UNITY_WSA
313318
[Test]
314319
[Category("Devices")]

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ however, it has to be formatted properly to pass verification tests.
1414
- Fixed an analytics event being invoked twice when the Save button in the Actions view was pressed. [ISXB-1378](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1378)
1515
- Fixed an issue causing a number of errors to be displayed when using `InputTestFixture` in playmode tests with domain reloading disabled on playmode entry. [ISXB-1446](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1446)
1616
- Fixed issue where user was not prompted to save changes when loading a second input actions asset into an already opened editor. [ISXB-1343](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1343)
17+
- Fixed an issue on macOS which didn't detect up-left DPAD presses for Xbox controllers. [ISXB-810](https://issuetracker.unity3d.com/issues/macos-d-pad-upper-left-corner-is-not-logged-with-the-xbox-controller)
1718

1819
## [1.14.0] - 2025-03-20
1920

Packages/com.unity.inputsystem/InputSystem/Plugins/XInput/XboxGamepadMacOS.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public XInputControllerOSXState WithButton(Button button)
106106
[StructLayout(LayoutKind.Explicit)]
107107
internal struct XInputControllerWirelessOSXState : IInputStateTypeInfo
108108
{
109+
const ushort k_StickZeroValue = 32767;
109110
public static FourCC kFormat => new FourCC('H', 'I', 'D');
110111

111112
public enum Button
@@ -125,20 +126,20 @@ public enum Button
125126
private byte padding;
126127

127128
[InputControl(name = "leftStick", layout = "Stick", format = "VC2S")]
128-
[InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
129+
[InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
129130
[InputControl(name = "leftStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
130131
[InputControl(name = "leftStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
131-
[InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
132+
[InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
132133
[InputControl(name = "leftStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
133134
[InputControl(name = "leftStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
134135
[FieldOffset(1)] public ushort leftStickX;
135136
[FieldOffset(3)] public ushort leftStickY;
136137

137138
[InputControl(name = "rightStick", layout = "Stick", format = "VC2S")]
138-
[InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
139+
[InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
139140
[InputControl(name = "rightStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
140141
[InputControl(name = "rightStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
141-
[InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
142+
[InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
142143
[InputControl(name = "rightStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
143144
[InputControl(name = "rightStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
144145
[FieldOffset(5)] public ushort rightStickX;
@@ -149,7 +150,7 @@ public enum Button
149150
[InputControl(name = "rightTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
150151
[FieldOffset(11)] public ushort rightTrigger;
151152

152-
[InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4, defaultState = 8)]
153+
[InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4)]
153154
[InputControl(name = "dpad/up", format = "BIT", layout = "DiscreteButton", parameters = "minValue=8,maxValue=2,nullValue=0,wrapAtValue=9", bit = 0, sizeInBits = 4)]
154155
[InputControl(name = "dpad/right", format = "BIT", layout = "DiscreteButton", parameters = "minValue=2,maxValue=4", bit = 0, sizeInBits = 4)]
155156
[InputControl(name = "dpad/down", format = "BIT", layout = "DiscreteButton", parameters = "minValue=4,maxValue=6", bit = 0, sizeInBits = 4)]
@@ -188,16 +189,17 @@ public XInputControllerWirelessOSXState WithDpad(byte value)
188189

189190
public static XInputControllerWirelessOSXState defaultState => new XInputControllerWirelessOSXState
190191
{
191-
rightStickX = 32767,
192-
rightStickY = 32767,
193-
leftStickX = 32767,
194-
leftStickY = 32767
192+
rightStickX = k_StickZeroValue,
193+
rightStickY = k_StickZeroValue,
194+
leftStickX = k_StickZeroValue,
195+
leftStickY = k_StickZeroValue
195196
};
196197
}
197198

198199
[StructLayout(LayoutKind.Explicit)]
199200
internal struct XInputControllerWirelessOSXStateV2 : IInputStateTypeInfo
200201
{
202+
const ushort k_StickZeroValue = 32767;
201203
public static FourCC kFormat => new FourCC('H', 'I', 'D');
202204

203205
public enum Button
@@ -217,20 +219,20 @@ public enum Button
217219
private byte padding;
218220

219221
[InputControl(name = "leftStick", layout = "Stick", format = "VC2S")]
220-
[InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
222+
[InputControl(name = "leftStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
221223
[InputControl(name = "leftStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
222224
[InputControl(name = "leftStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
223-
[InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
225+
[InputControl(name = "leftStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
224226
[InputControl(name = "leftStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
225227
[InputControl(name = "leftStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
226228
[FieldOffset(1)] public ushort leftStickX;
227229
[FieldOffset(3)] public ushort leftStickY;
228230

229231
[InputControl(name = "rightStick", layout = "Stick", format = "VC2S")]
230-
[InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
232+
[InputControl(name = "rightStick/x", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
231233
[InputControl(name = "rightStick/left", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
232234
[InputControl(name = "rightStick/right", offset = 0, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1")]
233-
[InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5")]
235+
[InputControl(name = "rightStick/y", offset = 2, format = "USHT", parameters = "invert,normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5", defaultState = k_StickZeroValue)]
234236
[InputControl(name = "rightStick/up", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0,clampMax=0.5,invert")]
235237
[InputControl(name = "rightStick/down", offset = 2, format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=1,normalizeZero=0.5,clamp=1,clampMin=0.5,clampMax=1,invert=false")]
236238
[FieldOffset(5)] public ushort rightStickX;
@@ -241,7 +243,7 @@ public enum Button
241243
[InputControl(name = "rightTrigger", format = "USHT", parameters = "normalize,normalizeMin=0,normalizeMax=0.01560998")]
242244
[FieldOffset(11)] public ushort rightTrigger;
243245

244-
[InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4, defaultState = 8)]
246+
[InputControl(name = "dpad", format = "BIT", layout = "Dpad", sizeInBits = 4)]
245247
[InputControl(name = "dpad/up", format = "BIT", layout = "DiscreteButton", parameters = "minValue=8,maxValue=2,nullValue=0,wrapAtValue=9", bit = 0, sizeInBits = 4)]
246248
[InputControl(name = "dpad/right", format = "BIT", layout = "DiscreteButton", parameters = "minValue=2,maxValue=4", bit = 0, sizeInBits = 4)]
247249
[InputControl(name = "dpad/down", format = "BIT", layout = "DiscreteButton", parameters = "minValue=4,maxValue=6", bit = 0, sizeInBits = 4)]
@@ -280,10 +282,10 @@ public XInputControllerWirelessOSXStateV2 WithDpad(byte value)
280282

281283
public static XInputControllerWirelessOSXStateV2 defaultState => new XInputControllerWirelessOSXStateV2
282284
{
283-
rightStickX = 32767,
284-
rightStickY = 32767,
285-
leftStickX = 32767,
286-
leftStickY = 32767
285+
rightStickX = k_StickZeroValue,
286+
rightStickY = k_StickZeroValue,
287+
leftStickX = k_StickZeroValue,
288+
leftStickY = k_StickZeroValue
287289
};
288290
}
289291
}

0 commit comments

Comments
 (0)