Modifying low level mouse events

Hi, I’m trying to write a program to fix mouse scroll wheel drift. The aim of the program should be to modify invalid scroll wheel events and correct them with valid ones before they get sent to the system (for instance, if you’re scrolling down and then an up event occurs, that should be modified to a down one). As a consequence, I wrote an hook to listen for mouse events and modify that if the event is of the correct type. However, whenever I send the modified event the system starts lagging and nothing really happens. I’ve tried several methods and all of them trigger the same thing. Why is that the case?

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "unsafe"

    "github.com/gonutz/w32"
)

const CUSTOM_DATA = 0x1234567

// Define the MSLLHOOKSTRUCT structure
type MSLLHOOKSTRUCT struct {
    Pt          w32.POINT
    MouseData   uint32
    Flags       uint32
    Time        uint32
    DwExtraInfo uintptr
}

var hook w32.HHOOK

// MouseProc is the hook procedure for mouse events
func MouseProc(code int, wparam w32.WPARAM, lparam w32.LPARAM) w32.LRESULT {
    if code >= 0 {
        msllhookstruct := (*MSLLHOOKSTRUCT)(unsafe.Pointer(lparam))

        if wparam == w32.WM_MOUSEWHEEL && msllhookstruct.DwExtraInfo != CUSTOM_DATA {
            // Modify the scroll delta here, for example, halving it to reduce scroll speed
            scrollAmount := int32(msllhookstruct.MouseData >> 16)
            scrollAmount /= 2 // Adjust this factor as necessary
            msllhookstruct.MouseData = uint32(scrollAmount << 16)
            msllhookstruct.DwExtraInfo = CUSTOM_DATA
            fmt.Println("Scroll event modified")
        }

        // Ensure the modified event is passed to the next hook
        return w32.CallNextHookEx(hook, code, wparam, lparam)
    }
    return w32.CallNextHookEx(hook, code, wparam, lparam)
}

func main() {
    hook = w32.SetWindowsHookEx(w32.WH_MOUSE_LL, MouseProc, 0, 0)
    if hook == 0 {
        fmt.Println("Failed to set hook")
        return
    }
    defer w32.UnhookWindowsHookEx(hook)

    // Keep the program running to listen to mouse events
    sig := make(chan os.Signal, 1)
    signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
    <-sig
}