File: 10-copilot-key-override.lua

package info (click to toggle)
libinput 1.30.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,404 kB
  • sloc: ansic: 104,881; python: 3,570; sh: 183; makefile: 37; cpp: 7
file content (71 lines) | stat: -rw-r--r-- 2,737 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
59
60
61
62
63
64
65
66
67
68
69
70
71
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin detects the Copilot key on the keyboard with
-- the given VID/PID and replaces it with a different key (sequence).

-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})

-- Replace this with your keyboard's VID/PID
KEYBOARD_VID = 0x046d
KEYBOARD_PID = 0x4088

meta_is_down = false
shift_is_down = false

-- shift-A, because you can never have enough screaming
replacement_sequence = { evdev.KEY_LEFTSHIFT, evdev.KEY_A }

function frame(device, frame, _)
    for _, v in ipairs(frame) do
        if v.value ~= 2 then -- ignore key repeats
            if v.usage == evdev.KEY_LEFTMETA then
                meta_is_down = v.value == 1
            elseif v.usage == evdev.KEY_LEFTSHIFT then
                shift_is_down = v.value == 1
            elseif v.usage == evdev.KEY_F23 and meta_is_down and shift_is_down then
                -- We know from the MS requirements that F23 for copilot is
                -- either last key (on press) or the first key (on release)
                -- of the three-key sequence, and no other keys are
                -- within this frame.
                if v.value == 1 then
                    -- Release our modifiers first
                    device:prepend_frame({
                        { usage = evdev.KEY_LEFTSHIFT, value = 0 },
                        { usage = evdev.KEY_LEFTMETA, value = 0 },
                    })
                    -- Insert our replacement press sequence
                    local replacement_frame = {}
                    for _, rv in ipairs(replacement_sequence) do
                        table.insert(replacement_frame, { usage = rv, value = 1 })
                    end
                    device:append_frame(replacement_frame)
                else
                    -- Insert our replacement release sequence
                    local replacement_frame = {}
                    for idx = #replacement_sequence, 1, -1 do
                        table.insert(replacement_frame, { usage = replacement_sequence[idx], value = 0 })
                    end
                    device:append_frame(replacement_frame)

                    -- we don't care about re-pressing shift/meta because the
                    -- rest of the stack will filter the release for an
                    -- unpressed key anyway.
                end

                return {} -- discard this frame
            end
        end
    end
end

function device_new(device)
    local info = device:info()
    if  info.vid == KEYBOARD_VID and info.pid == KEYBOARD_PID then
        device:connect("evdev-frame", frame)
    end
end

libinput:connect("new-evdev-device", device_new)