目录

使用WindowManager管理多模输入事件 (C/C++)

场景介绍

WindowManager提供应用窗口的管理能力,可以用于管理多模输入事件。

当前支持使用WindowManager进行多模输入事件的过滤,还可以将多模触摸事件注入目标窗口,具体开发步骤可见下文。

过滤多模输入事件

使用WindowManager模块提供的能力去拦截按键事件,让按键事件不往应用内部组件分发。

[h2]在CMake脚本中链接动态库

target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so)

[h2]接口使用说明

接口名 描述
OH_NativeWindowManager_RegisterKeyEventFilter(int32_t windowId, OH_NativeWindowManager_KeyEventFilter keyEventFilter) 为指定的窗口注册过滤回调函数keyEventFilter。
OH_NativeWindowManager_UnregisterKeyEventFilter(int32_t windowId) 取消指定窗口上的过滤回调函数。

[h2]示例代码

以下示例代码中介绍了如何注册过滤函数和取消过滤函数,以过滤ESC退出按键和数字按键为例。

#include "napi/native_api.h"
#include "window_manager/oh_window_comm.h"
#include "window_manager/oh_window_event_filter.h"
#include "multimodalinput/oh_input_manager.h"
#include "multimodalinput/oh_key_code.h"

// 设置过滤函数
static bool filterFunc(Input_KeyEvent *event)
{
    auto keyCode = OH_Input_GetKeyEventKeyCode(event);
    auto action = OH_Input_GetKeyEventAction(event);
    
    // 过滤escape和数字键的按下
    return (keyCode >= Input_KeyCode::KEYCODE_0 && keyCode <= Input_KeyCode::KEYCODE_9
         && action == Input_KeyEventAction::KEY_ACTION_DOWN) || (keyCode == Input_KeyCode::KEYCODE_ESCAPE);
}

static napi_value registerFilter(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);
    
    // 向windowId对应的窗口注册filterFunc的过滤函数
    auto res = OH_NativeWindowManager_RegisterKeyEventFilter(windowId, filterFunc);
    
    napi_value errCode;
    napi_create_int32(env, res, &errCode);
    return errCode;
}

static napi_value clearFilter(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);

    auto res = OH_NativeWindowManager_UnregisterKeyEventFilter(windowId);
    napi_value errCode;
    napi_create_int32(env, res, &errCode);
    return errCode;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        {"registerFilter", nullptr, registerFilter, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"clearFilter", nullptr, clearFilter, nullptr, nullptr, nullptr, napi_default, nullptr}};
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

将多模触摸事件注入给目标窗口

使用WindowManager模块提供的能力为指定窗口注入触摸事件,仅支持同进程窗口。此操作不会触发窗口焦点、层级变化或拖拽,事件会直接发送给ArkUI。

[h2]在CMake脚本中链接动态库

target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so)

[h2]接口使用说明

接口名 描述
OH_WindowManager_InjectTouchEvent(int32_t windowId, Input_TouchEvent* touchEvent, int32_t windowX, int32_t windowY) 为指定的窗口注入触摸事件。

[h2]示例代码

以下示例代码介绍了如何将多模触摸事件注入目标窗口,以单次事件注入为例。

#include "napi/native_api.h"
#include "window_manager/oh_window.h"
#include "multimodalinput/oh_input_manager.h"

const int32_t ARGS_TWO = 2;
const int32_t ARGS_THREE = 3;
const int32_t ARGS_FOUR = 4;
const int32_t ARGS_FIVE = 5;
const int32_t ARGS_SIX = 6;
const int32_t ARGS_SEVEN = 7;
const int32_t ARGS_EIGHT = 8;
const int32_t ARGS_NINE = 9;
const int32_t ARGS_TEN = 10;

static napi_value injectEvent(napi_env env, napi_callback_info info)
{
    size_t argc = ARGS_TEN;
    napi_value args[ARGS_TEN] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    int32_t windowId;
    napi_get_value_int32(env, args[0], &windowId);

    int32_t displayId;
    napi_get_value_int32(env, args[1], &displayId);

    int32_t windowX;
    napi_get_value_int32(env, args[ARGS_TWO], &windowX);

    int32_t windowY;
    napi_get_value_int32(env, args[ARGS_THREE], &windowY);

    int32_t action;
    napi_get_value_int32(env, args[ARGS_FOUR], &action);

    int32_t fingerId;
    napi_get_value_int32(env, args[ARGS_FIVE], &fingerId);

    int32_t displayX;
    napi_get_value_int32(env, args[ARGS_SIX], &displayX);

    int32_t displayY;
    napi_get_value_int32(env, args[ARGS_SEVEN], &displayY);

    int32_t actionTime;
    napi_get_value_int32(env, args[ARGS_EIGHT], &actionTime);

    int32_t TE_WindowId;
    napi_get_value_int32(env, args[ARGS_NINE], &TE_WindowId);
    
    // 构造多模事件touchEvent
    Input_TouchEvent* touchEvent = OH_Input_CreateTouchEvent();
    OH_Input_SetTouchEventAction(touchEvent, action);
    OH_Input_SetTouchEventFingerId(touchEvent, fingerId);
    OH_Input_SetTouchEventDisplayX(touchEvent, displayX);
    OH_Input_SetTouchEventDisplayY(touchEvent, displayY);
    OH_Input_SetTouchEventActionTime(touchEvent, actionTime);
    OH_Input_SetTouchEventWindowId(touchEvent, TE_WindowId);
    OH_Input_SetTouchEventDisplayId(touchEvent, displayId);

    // 向windowId对应的窗口注入多模触摸事件
    auto res = OH_WindowManager_InjectTouchEvent(windowId, touchEvent, windowX, windowY);

    // 使用完touchEvent后销毁对象
    OH_Input_DestroyTouchEvent(&touchEvent);
    
    napi_value errCode;
    napi_create_int32(env, res, &errCode);
    return errCode;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        {"injectEvent", nullptr, injectEvent, nullptr, nullptr, nullptr, napi_default, nullptr}};
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END