eventtap: setProperty choose CGEventField setter based on value type#3859
eventtap: setProperty choose CGEventField setter based on value type#3859mogenson wants to merge 1 commit intoHammerspoon:masterfrom
Conversation
eventtap event's setProperty() method uses CGEventSetDoubleValueField for a defined list of CGEventField properties, and CGEventSetIntegerValueField for all others. Keep the list of double type CGEventField properties, but make a change to check the type of the value parameter for the all others case. If the value is a Lua integer, use CGEventSetIntegerValueField. If the value is a Lua number (aka double), use the CGEventSetDoubleValueField. The motivation for this change is to use setProperty() to set private / hidden event fields. These event field constants are not defined in any public headers from Apple so it doesn't make sense to add a mapping from string to constant value in the hs.eventtap.event.types table. However, a spoon or Hammerspoon config can set these event fields with setProperty(property, value) by passing an integer for the property and integer or number for the value. Also add a doc note clarifying which CGEvent API is used depending on the Lua value type passed.
|
Some people have discovered a very cool way to switch spaces without the animation by posting a swipe gesture with a very fast velocity: https://github.com/joshuarli/iss It would be great if we could use this technique in Hammerspoon. However, it requires setting some undocumented / hidden CGEventFields. I'm not sure about the best way to go about this. The fast swipe gesture only works on spaces on the same screen, so it's not a suitable replacement for With this change we can create a fast swipe gesture to switch spaces without an animation by doing the following: local FLT_TRUE_MIN = 2 ^ -149
local kCGEventGestureHIDType = 110
local kCGEventGesturePhase = 132
local kCGEventGestureScrollY = 119
local kCGEventGestureSwipeMotion = 123
local kCGEventGestureSwipeProgress = 124
local kCGEventGestureSwipeVelocityX = 129
local kCGEventGestureSwipeVelocityY = 130
local kCGEventGestureZoomDeltaX = 139
local kCGEventScrollGestureFlagBits = 135
local kCGGestureMotionHorizontal = 1
local kCGSEventDockControl = 30
local kCGSEventGesture = 29
local kCGSEventTypeField = 55
local kCGSGesturePhaseBegan = 1
local kCGSGesturePhaseEnded = 4
local kIOHIDEventTypeDockSwipe = 23
function fast_switch_space(direction_right)
-- begin gesture
local ev = hs.eventtap.event.newEvent()
ev:setProperty(kCGSEventTypeField, kCGSEventDockControl)
ev:setProperty(kCGEventGestureHIDType, kIOHIDEventTypeDockSwipe)
ev:setProperty(kCGEventGesturePhase, kCGSGesturePhaseBegan)
ev:setProperty(kCGEventScrollGestureFlagBits, direction_right and 1 or 0)
ev:setProperty(kCGEventGestureSwipeMotion, kCGGestureMotionHorizontal)
ev:setProperty(kCGEventGestureScrollY, 0.0) -- must be a double value
ev:setProperty(kCGEventGestureZoomDeltaX, FLT_TRUE_MIN) -- must be a double value
ev:post()
hs.eventtap.event.newEvent():setProperty(kCGSEventTypeField, kCGSEventGesture):post()
-- end gesture
ev = hs.eventtap.event.newEvent()
ev:setProperty(kCGSEventTypeField, kCGSEventDockControl)
ev:setProperty(kCGEventGestureHIDType, kIOHIDEventTypeDockSwipe)
ev:setProperty(kCGEventGesturePhase, kCGSGesturePhaseEnded)
ev:setProperty(kCGEventGestureSwipeProgress, direction_right and 2.0 or -2.0) -- double value
ev:setProperty(kCGEventScrollGestureFlagBits, direction_right and 1 or 0)
ev:setProperty(kCGEventGestureSwipeMotion, kCGGestureMotionHorizontal)
ev:setProperty(kCGEventGestureScrollY, 0.0) -- must be a double value
ev:setProperty(kCGEventGestureSwipeVelocityX, direction_right and 400.0 or -400.0) -- must be a double value
ev:setProperty(kCGEventGestureSwipeVelocityY, 0.0) -- must be a double value
ev:setProperty(kCGEventGestureZoomDeltaX, FLT_TRUE_MIN) -- must be a double value
ev:post()
hs.eventtap.event.newEvent():setProperty(kCGSEventTypeField, kCGSEventGesture):post()
endAs far as I know, this change preserves previous behavior because all the existing "(N)" CGEventField properties still explicitly call However, let me know if all CGEventField types should be defined in |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #3859 +/- ##
==========================================
- Coverage 27.39% 27.37% -0.03%
==========================================
Files 191 191
Lines 51537 51542 +5
==========================================
- Hits 14119 14108 -11
- Misses 37418 37434 +16 🚀 New features to boost your workflow:
|
|
Generally yes, even private properties are added to the appropriate tables (in this case, in |
eventtap event's setProperty() method uses CGEventSetDoubleValueField for a defined list of CGEventField properties, and CGEventSetIntegerValueField for all others.
Keep the list of double type CGEventField properties, but make a change to check the type of the value parameter for the all others case.
If the value is a Lua integer, use CGEventSetIntegerValueField. If the value is a Lua number (aka double), use the CGEventSetDoubleValueField.
The motivation for this change is to use setProperty() to set private / hidden event fields. These event field constants are not defined in any public headers from Apple so it doesn't make sense to add a mapping from string to constant value in the hs.eventtap.event.types table. However, a spoon or Hammerspoon config can set these event fields with setProperty(property, value) by passing an integer for the property and integer or number for the value.
Also add a doc note clarifying which CGEvent API is used depending on the Lua value type passed.