Jump to content

[Guide] Map screenshot/mission control/other function keys to keyboard hotkeys without SysPref


stevezheng
 Share

1 post in this topic

Recommended Posts

Pre-read:

  [Beginner's Guide] Fix Keyboard Hot keys / Functional Keys

  [Guide] Patching DSDT/SSDT for LAPTOP backlight control

 

Abstract:

  At first, thanks to Rehabman's amazing VoodooPS2Keyboard and the guide. This instruction is for mapping function keys like screenshot, mission control, or video mirror without the need for SysPref. Since the adb codes of these function keys are unknown, we can't directly map the function we want to the hotkey. The basic idea is to map the combination of keys to the hotkey so that the hotkey can trigger the desired function. For example, we can map Shift+Command+4 to screenshot hotkey, and Shift+Up Arrow to the mission control hotkey.

 

1. Find the EC Queries or GPE methods that control the hotkey event

  The instructions listed in Pre-read part have already shown the instruction step by step. Generally, you need to apply "Add DSDT Debug Methods" and "Instrument EC Queries" Patch (EC Queries scenario) or manually patch your GPE method (GPE scenario) to find the corresponding methods that control the target hotkey. Take my laptop as an example, when I press down the hotkey, the device will call _L16 method, then ECLV() -> LEVN() -> LGPA(). And then in LGPA method I got multiple cases, so I patched them all to find the corresponding case.

Case (0x10)
{
	// Screenshot   
	If ((^^WMIX.EV02 != Zero))
	{
		Notify (WMIX, 0x86) // Device-Specific
	}
	If ((^^WMIE.EVTB != Zero))
	{
		Notify (WMIE, 0x8B) // Device-Specific
	}
}

 

2. Patch to send combination deadkey PS2 codes

  In order for future mapping, we need to patch these methods to send PS2 keys so that VoodooPS2Keyboard can recognize them. According to Rehabman's words at Remapping keyboard with VoodooPS2

0x01xx: standard PS2 codes... make/break separate
0x02xx: extended PS2 codes (e0)... make/break separate
0x03xx: standard PS2 codes... make/break combined (eg. make and break are sent with only a single notify)
0x04xx: extended PS2 codes (e0)... make/break combined

In this way, if we want a method to call two keys (key A and key B), we can let it first send 0x02xx of key A, and then send 0x02xx of key B, which means first make A key and then B key. Then we call 0x02xx of B key and 0x02xx of A key to break these keys. By doing this, the method can send the combination of two keys (key A & key B). In my case, I want my screenshot hotkey map to Shift+Command+4, so I prepare 3 deadkeys for this method. The patched code is like this:

Case (0x10)
{
	// Screenshot
	If (_OSI ("Darwin"))
	{
		Notify (PS2K, 0x0223) // Press Down e023
		Notify (PS2K, 0x0225) // Press Down e025
		Notify (PS2K, 0x0226) // Press Down e026
		Notify (PS2K, 0x02A6) // Press Up e026
		Notify (PS2K, 0x02A5) // Press Up e025
		Notify (PS2K, 0x02A3) // Press Up e023
	}
	If ((^^WMIX.EV02 != Zero))
	{
		Notify (WMIX, 0x86) // Device-Specific
	}

	If ((^^WMIE.EVTB != Zero))
	{
		Notify (WMIE, 0x8B) // Device-Specific
	}
}

NOTE 1: the break code should add 8 on the third digit of the make code. For example, the make code of e023 is 0x0223, then the break code of 0x0223 is 0x02(2+8)3=0x02A3.

NOTE 2: ApplePS2ToADBMap.h is a great place to check PS2 extended deadkey like e023.

 

3. Map the deadkey PS2 key to adb code in VoodooPS2Keyboard

  The final step is to map the extended PS2 code to the adb code of the function shortcut. This can be done in a Name(RMCF) in SSDT or in info.plist of VoodooPS2Keyboard.kext. I prefer the SSDT way.

Scope (_SB.PCI0.LPCB.PS2K)
{
	If (_OSI ("Darwin"))
	{
		Name (RMCF, Package (0x02)
		{
			"Keyboard", 
			Package (0x02)
			{
				"Custom ADB Map", 
				Package (0x04)
				{
					Package (0x00){},
					"e023=38", // e023=Shift
					"e025=37", // e025=Command
					"e026=15" // e026=4
				}
			}
		})
	}
}

NOTE: In my case, the adb code is different from what Rehabman provides in his repository. I find reliable ADB code map in /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h

A quick glance of Events.h:

  kVK_Return                    = 0x24,
  kVK_Tab                       = 0x30,
  kVK_Space                     = 0x31,
  kVK_Delete                    = 0x33,
  kVK_Escape                    = 0x35,
  kVK_Command                   = 0x37,
  kVK_Shift                     = 0x38,
  kVK_CapsLock                  = 0x39,
  kVK_Option                    = 0x3A,
  kVK_Control                   = 0x3B,
  kVK_RightCommand              = 0x36,
  kVK_RightShift                = 0x3C,
  kVK_RightOption               = 0x3D,
  kVK_RightControl              = 0x3E,
  kVK_Function                  = 0x3F,

By using the same method, we can map the video mirror key to Command+F1, mission control key to Control+Up Arrow...

 

Limitation

  The limitation of this method is that we can't change keys in SysPref - Modifier Keys. macOS would change the adb code of the key according to the settings in SysPref - Modifier Keys. A workaround is that we can change the key by patching Name(RMCF) or info.plist in VoodooPS2Keyboard like Step 3. An example is SSDT-Swap-LeftControlCapsLock.dsl.

  • Like 2
Link to comment
Share on other sites

 Share

×
×
  • Create New...