Skip to content

NEW: Correctly expose Media keys through keyboard #2212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Aug 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ however, it has to be formatted properly to pass verification tests.

## [Unreleased] - yyyy-mm-dd

### Added
- Exposed MediaPlayPause, MediaRewind, MediaForward keys on Keyboard.

## [1.14.2] - 2025-08-05

Expand Down
47 changes: 46 additions & 1 deletion Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ public unsafe struct KeyboardState : IInputStateTypeInfo
[InputControl(name = "f22", displayName = "F22", layout = "Key", bit = (int)Key.F22)]
[InputControl(name = "f23", displayName = "F23", layout = "Key", bit = (int)Key.F23)]
[InputControl(name = "f24", displayName = "F24", layout = "Key", bit = (int)Key.F24)]
[InputControl(name = "mediaPlayPause", displayName = "MediaPlayPause", layout = "Key", bit = (int)Key.MediaPlayPause)]
[InputControl(name = "mediaRewind", displayName = "MediaRewind", layout = "Key", bit = (int)Key.MediaRewind)]
[InputControl(name = "mediaForward", displayName = "MediaForward", layout = "Key", bit = (int)Key.MediaForward)]
[InputControl(name = "IMESelected", layout = "Button", bit = (int)KeyEx.RemappedIMESelected, synthetic = true)] // Use the last bit to hold IME selected state.
public fixed byte keys[kSizeInBytes];

Expand Down Expand Up @@ -969,6 +972,21 @@ public enum Key
/// </summary>
F24,

/// <summary>
/// The <see cref="Keyboard.mediaPlayPause"/>.
/// </summary>
MediaPlayPause,

/// <summary>
/// The <see cref="Keyboard.mediaRewind"/>.
/// </summary>
MediaRewind,

/// <summary>
/// The <see cref="Keyboard.mediaForward"/>.
/// </summary>
MediaForward,

/// <summary>
/// Don't use this. This is a dummy key that is only used internally to represent the IME selected state.
/// Will be removed in the future.
Expand Down Expand Up @@ -1048,7 +1066,7 @@ public class Keyboard : InputDevice, ITextInputReceiver, IEventPreProcessor
/// </summary>
/// <value>Total number of key controls.</value>
public const int KeyCount = (int)Key.OEM5; // Not updated to Key.F24 for not breaking the API
internal const int ExtendedKeyCount = (int)Key.F24;
internal const int ExtendedKeyCount = (int)Key.MediaForward;

/// <summary>
/// Event that is fired for every single character entered on the keyboard.
Expand Down Expand Up @@ -2270,6 +2288,30 @@ public string keyboardLayout
/// </remarks>
public KeyControl f24Key => this[Key.F24];

/// <summary>
/// The Media Play/Pause key on the keyboard or TV remote.
/// </summary>
/// <remarks><see cref="KeyControl"/> representing <see cref="Key.MediaPlayPause"/>.
/// Supported on Windows and Android.
/// </remarks>
public KeyControl mediaPlayPause => this[Key.MediaPlayPause];

/// <summary>
/// The Media Rewind key on the keyboard or TV remote.
/// </summary>
/// <remarks><see cref="KeyControl"/> representing <see cref="Key.MediaRewind"/>.
/// Supported on Android.
/// </remarks>
public KeyControl mediaRewind => this[Key.MediaRewind];

/// <summary>
/// The Media Forward key on the keyboard or TV remote.
/// </summary>
/// <remarks><see cref="KeyControl"/> representing <see cref="Key.MediaForward"/>.
/// Supported on Android.
/// </remarks>
public KeyControl mediaForward => this[Key.MediaForward];

/// <summary>
/// An artificial combination of <see cref="leftShiftKey"/> and <see cref="rightShiftKey"/> into one control.
/// </summary>
Expand Down Expand Up @@ -2531,6 +2573,9 @@ protected override void FinishSetup()
"f22",
"f23",
"f24",
nameof(mediaPlayPause),
nameof(mediaRewind),
nameof(mediaForward),
};
m_Keys = new KeyControl[keyStrings.Length];
for (var i = 0; i < keyStrings.Length; ++i)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ internal partial class FastKeyboard : UnityEngine.InputSystem.Keyboard
public const string metadata = ";AnyKey;Button;Axis;Key;DiscreteButton;Keyboard";
public FastKeyboard()
{
var builder = this.Setup(127, 15, 7)
var builder = this.Setup(130, 15, 7)
.WithName("Keyboard")
.WithDisplayName("Keyboard")
.WithChildren(0, 127)
.WithChildren(0, 130)
.WithLayout(new InternedString("Keyboard"))
.WithStateBlock(new InputStateBlock { format = new FourCC(1262836051), sizeInBits = 128 });

Expand Down Expand Up @@ -414,6 +414,15 @@ public FastKeyboard()
// /Keyboard/f24
var ctrlKeyboardf24 = Initialize_ctrlKeyboardf24(kKeyLayout, this);

// /Keyboard/mediaPlayPause
var ctrlKeyboardmediaPlayPause = Initialize_ctrlKeyboardmediaPlayPause(kKeyLayout, this);

// /Keyboard/mediaRewind
var ctrlKeyboardmediaRewind = Initialize_ctrlKeyboardmediaRewind(kKeyLayout, this);

// /Keyboard/mediaForward
var ctrlKeyboardmediaForward = Initialize_ctrlKeyboardmediaForward(kKeyLayout, this);

// /Keyboard/IMESelected
var ctrlKeyboardIMESelected = Initialize_ctrlKeyboardIMESelected(kButtonLayout, this);

Expand Down Expand Up @@ -444,7 +453,7 @@ public FastKeyboard()
builder.WithControlAlias(6, new InternedString("RightCommand"));

// Control getters/arrays.
this.keys = new UnityEngine.InputSystem.Controls.KeyControl[123];
this.keys = new UnityEngine.InputSystem.Controls.KeyControl[126];
this.keys[0] = ctrlKeyboardspace;
this.keys[1] = ctrlKeyboardenter;
this.keys[2] = ctrlKeyboardtab;
Expand Down Expand Up @@ -567,6 +576,9 @@ public FastKeyboard()
this.keys[120] = ctrlKeyboardf22;
this.keys[121] = ctrlKeyboardf23;
this.keys[122] = ctrlKeyboardf24;
this.keys[123] = ctrlKeyboardmediaPlayPause;
this.keys[124] = ctrlKeyboardmediaRewind;
this.keys[125] = ctrlKeyboardmediaForward;
this.anyKey = ctrlKeyboardanyKey;
this.shiftKey = ctrlKeyboardshift;
this.ctrlKey = ctrlKeyboardctrl;
Expand All @@ -576,7 +588,7 @@ public FastKeyboard()
// State offset to control index map.
builder.WithStateOffsetToControlIndexMap(new uint[]
{
525314u, 650240u, 1049603u, 1573892u, 2098181u, 2622470u, 3146759u, 3671048u, 4195337u, 4719626u
525314u, 653312u, 1049603u, 1573892u, 2098181u, 2622470u, 3146759u, 3671048u, 4195337u, 4719626u
, 5243915u, 5768204u, 6292493u, 6816782u, 7341071u, 7865364u, 8389653u, 8913942u, 9438231u, 9962520u
, 10486809u, 11011098u, 11535387u, 12059676u, 12583965u, 13108254u, 13632543u, 14156832u, 14681121u, 15205410u
, 15729699u, 16253988u, 16778277u, 17302566u, 17826855u, 18351144u, 18875433u, 19399722u, 19924011u, 20448300u
Expand All @@ -588,7 +600,7 @@ public FastKeyboard()
, 45614169u, 46138458u, 46662747u, 47187036u, 47711325u, 48235614u, 48759903u, 49284193u, 49808482u, 50332771u
, 50857060u, 51381349u, 51905638u, 52429927u, 52954216u, 53478505u, 54002794u, 54527083u, 55051372u, 55575661u
, 56099950u, 56624239u, 57148528u, 57672817u, 58721394u, 59245683u, 59769972u, 60294261u, 60818550u, 61342839u
, 61867128u, 62391417u, 62915706u, 63439995u, 63964284u, 64488573u, 66585726u
, 61867128u, 62391417u, 62915706u, 63439995u, 63964284u, 64488573u, 65012862u, 65537151u, 66061440u, 66585729u
});

builder.WithControlTree(new byte[]
Expand Down Expand Up @@ -652,8 +664,8 @@ public FastKeyboard()
, 0, 1, 117, 0, 255, 255, 122, 0, 1, 118, 0, 255, 255, 123, 0, 1, 119, 0, 255, 255, 124, 0, 1, 123, 0, 241, 0, 0, 0, 0
, 127, 0, 247, 0, 0, 0, 0, 121, 0, 243, 0, 0, 0, 0, 123, 0, 245, 0, 0, 0, 0, 120, 0, 255, 255, 125, 0, 1, 121, 0
, 255, 255, 126, 0, 1, 122, 0, 255, 255, 127, 0, 1, 123, 0, 255, 255, 128, 0, 1, 125, 0, 249, 0, 0, 0, 0, 127, 0, 251, 0
, 0, 0, 0, 124, 0, 255, 255, 129, 0, 1, 125, 0, 255, 255, 0, 0, 0, 126, 0, 255, 255, 0, 0, 0, 127, 0, 253, 0, 0, 0
, 0, 127, 0, 255, 255, 0, 0, 0, 127, 0, 255, 0, 0, 0, 0, 128, 0, 255, 255, 130, 0, 1, 127, 0, 255, 255, 0, 0, 0
, 0, 0, 0, 124, 0, 255, 255, 129, 0, 1, 125, 0, 255, 255, 130, 0, 1, 126, 0, 255, 255, 131, 0, 1, 127, 0, 253, 0, 132, 0
, 1, 127, 0, 255, 255, 0, 0, 0, 127, 0, 255, 0, 0, 0, 0, 128, 0, 255, 255, 133, 0, 1, 127, 0, 255, 255, 0, 0, 0
}, new ushort[]
{
// Control tree node indicies
Expand All @@ -662,7 +674,7 @@ public FastKeyboard()
, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58
, 58, 59, 60, 61, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85
, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115
, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126
, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129
});

builder.Finish();
Expand All @@ -684,7 +696,7 @@ private UnityEngine.InputSystem.Controls.AnyKeyControl Initialize_ctrlKeyboardan
format = new FourCC(1112101920),
byteOffset = 0,
bitOffset = 1,
sizeInBits = 123
sizeInBits = 126
})
.WithMinAndMax(0, 1)
.Finish();
Expand Down Expand Up @@ -2075,7 +2087,7 @@ private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardright
})
.WithMinAndMax(0, 1)
.Finish();
ctrlKeyboardrightAlt.keyCode = UnityEngine.InputSystem.Key.RightAlt;
ctrlKeyboardrightAlt.keyCode = UnityEngine.InputSystem.Key.AltGr;
return ctrlKeyboardrightAlt;
}

Expand Down Expand Up @@ -2196,7 +2208,7 @@ private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardleftM
})
.WithMinAndMax(0, 1)
.Finish();
ctrlKeyboardleftMeta.keyCode = UnityEngine.InputSystem.Key.LeftWindows;
ctrlKeyboardleftMeta.keyCode = UnityEngine.InputSystem.Key.LeftCommand;
return ctrlKeyboardleftMeta;
}

Expand Down Expand Up @@ -3583,11 +3595,80 @@ private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardf24(I
return ctrlKeyboardf24;
}

private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardmediaPlayPause(InternedString kKeyLayout, InputControl parent)
{
var ctrlKeyboardmediaPlayPause = new UnityEngine.InputSystem.Controls.KeyControl();
ctrlKeyboardmediaPlayPause.Setup()
.At(this, 126)
.WithParent(parent)
.WithName("mediaPlayPause")
.WithDisplayName("MediaPlayPause")
.WithLayout(kKeyLayout)
.IsButton(true)
.WithStateBlock(new InputStateBlock
{
format = new FourCC(1112101920),
byteOffset = 0,
bitOffset = 124,
sizeInBits = 1
})
.WithMinAndMax(0, 1)
.Finish();
ctrlKeyboardmediaPlayPause.keyCode = UnityEngine.InputSystem.Key.MediaPlayPause;
return ctrlKeyboardmediaPlayPause;
}

private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardmediaRewind(InternedString kKeyLayout, InputControl parent)
{
var ctrlKeyboardmediaRewind = new UnityEngine.InputSystem.Controls.KeyControl();
ctrlKeyboardmediaRewind.Setup()
.At(this, 127)
.WithParent(parent)
.WithName("mediaRewind")
.WithDisplayName("MediaRewind")
.WithLayout(kKeyLayout)
.IsButton(true)
.WithStateBlock(new InputStateBlock
{
format = new FourCC(1112101920),
byteOffset = 0,
bitOffset = 125,
sizeInBits = 1
})
.WithMinAndMax(0, 1)
.Finish();
ctrlKeyboardmediaRewind.keyCode = UnityEngine.InputSystem.Key.MediaRewind;
return ctrlKeyboardmediaRewind;
}

private UnityEngine.InputSystem.Controls.KeyControl Initialize_ctrlKeyboardmediaForward(InternedString kKeyLayout, InputControl parent)
{
var ctrlKeyboardmediaForward = new UnityEngine.InputSystem.Controls.KeyControl();
ctrlKeyboardmediaForward.Setup()
.At(this, 128)
.WithParent(parent)
.WithName("mediaForward")
.WithDisplayName("MediaForward")
.WithLayout(kKeyLayout)
.IsButton(true)
.WithStateBlock(new InputStateBlock
{
format = new FourCC(1112101920),
byteOffset = 0,
bitOffset = 126,
sizeInBits = 1
})
.WithMinAndMax(0, 1)
.Finish();
ctrlKeyboardmediaForward.keyCode = UnityEngine.InputSystem.Key.MediaForward;
return ctrlKeyboardmediaForward;
}

private UnityEngine.InputSystem.Controls.ButtonControl Initialize_ctrlKeyboardIMESelected(InternedString kButtonLayout, InputControl parent)
{
var ctrlKeyboardIMESelected = new UnityEngine.InputSystem.Controls.ButtonControl();
ctrlKeyboardIMESelected.Setup()
.At(this, 126)
.At(this, 129)
.WithParent(parent)
.WithName("IMESelected")
.WithDisplayName("IMESelected")
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/InputExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ public static bool IsTextInputKey(this Key key)
case Key.OEM3:
case Key.OEM4:
case Key.OEM5:
case Key.MediaPlayPause:
case Key.MediaForward:
case Key.MediaRewind:
case KeyEx.IMESelected:
return false;
}
Expand Down