1# Using WindowManager to Manage Multimodal Input Events (C/C++) 2<!--Kit: ArkUI--> 3<!--Subsystem: Window--> 4<!--Owner: @waterwin--> 5<!--Designer: @stupidb--> 6<!--Tester: @qinliwen0417--> 7<!--Adviser: @ge-yafang--> 8 9## When to Use 10 11[WindowManager](../reference/apis-arkui/capi-windowmanager.md) provides the capability to manage application windows and can be used to handle multimodal input events. 12 13Currently, WindowManager supports filtering multimodal input events and injecting multimodal touch events into target windows. The specific development steps are detailed below. 14 15## Filtering Multimodal Input Events 16 17You can use the capability provided by the WindowManager module to intercept key events so that they are not distributed to internal components of your application. 18 19### Linking the Dynamic Library in the CMake Script 20``` 21target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so) 22``` 23 24### Adding Header Files 25```c++ 26#include "multimodalinput/oh_input_manager.h" 27#include "multimodalinput/oh_key_code.h" 28#include "window_manager/oh_window_comm.h" 29#include "window_manager/oh_window_event_filter.h" 30``` 31 32### Available APIs 33 34| API | Description | 35| ------------------------------------------------------------ | -------------------------------------------- | 36| OH_NativeWindowManager_RegisterKeyEventFilter (int32_t windowId, OH_NativeWindowManager_KeyEventFilter keyEventFilter) | Registers a key event filter for a window.| 37| OH_NativeWindowManager_UnregisterKeyEventFilter(int32_t windowId) | Unregisters the key event filter of a window. | 38 39- After an application window is created, bind a key event filter using the window ID. 40- The key event filter is triggered only when the application window receives a key event. 41- If the callback function returns **true**, the event is intercepted; if it returns **false**, the event is not intercepted. 42- Only one key event filter can be registered for the same window ID. The last registered key event filter overwrites the previously registered one. To filter a multi-key event, you are advised to process the multi-key combination in a filter. 43 44### Example 45 46The following sample code describes how to register and unregister a key event filter. The following uses the Esc key and number keys as an example. 47```c++ 48#include "napi/native_api.h" 49#include "window_manager/oh_window_comm.h" 50#include "window_manager/oh_window_event_filter.h" 51#include "multimodalinput/oh_input_manager.h" 52#include "multimodalinput/oh_key_code.h" 53 54// Set a filter. 55static bool filterFunc(Input_KeyEvent *event) { 56 auto keyCode = OH_Input_GetKeyEventKeyCode(event); 57 auto action = OH_Input_GetKeyEventAction(event); 58 // Case1: Implement the event filter for the Esc key. 59 // return keyCode == Input_KeyCode::KEYCODE_ESCAPE; 60 61 // Case 2: Implement the event filter for the number keys only when they are pressed. 62 // return keyCode >= Input_KeyCode::KEYCODE_0 && keyCode <= Input_KeyCode::KEYCODE_9 63 // && action == Input_KeyEventAction::KEY_ACTION_DOWN; 64 65 // Implement the event filter for the combination of the Esc key and a pressed-down number key. (Case1 || Case2). 66 return (keyCode >= Input_KeyCode::KEYCODE_0 && keyCode <= Input_KeyCode::KEYCODE_9 67 && action == Input_KeyEventAction::KEY_ACTION_DOWN) || (keyCode == Input_KeyCode::KEYCODE_ESCAPE); 68} 69 70static napi_value registerFilter(napi_env env, napi_callback_info info) { 71 size_t argc = 1; 72 napi_value args[1] = {nullptr}; 73 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 74 75 int32_t windowId; 76 napi_get_value_int32(env, args[0], &windowId); 77 78 // Register the filter for the window specified by the window ID. 79 auto res = OH_NativeWindowManager_RegisterKeyEventFilter(windowId, filterFunc); 80 81 napi_value errCode; 82 napi_create_int32(env, res, &errCode); 83 return errCode; 84} 85 86static napi_value clearFilter(napi_env env, napi_callback_info info) { 87 size_t argc = 1; 88 napi_value args[1] = {nullptr}; 89 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 90 91 int32_t windowId; 92 napi_get_value_int32(env, args[0], &windowId); 93 94 auto res = OH_NativeWindowManager_UnregisterKeyEventFilter(windowId); 95 napi_value errCode; 96 napi_create_int32(env, res, &errCode); 97 return errCode; 98 99} 100 101EXTERN_C_START 102static napi_value Init(napi_env env, napi_value exports) { 103 napi_property_descriptor desc[] = { 104 {"registerFilter", nullptr, registerFilter, nullptr, nullptr, nullptr, napi_default, nullptr}, 105 {"clearFilter", nullptr, clearFilter, nullptr, nullptr, nullptr, napi_default, nullptr}}; 106 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 107 return exports; 108} 109EXTERN_C_END 110``` 111 112## Injecting Multimodal Touch Events 113 114You can use the capability provided by the WindowManager module to inject touch events into a specified window. This operation is supported only for windows within the same process. It does not trigger changes in window focus, z-order, or dragging. Instead, the events are directly sent to ArkUI. 115 116 117### Linking the Dynamic Library in the CMake Script 118 119``` 120target_link_libraries(entry PUBLIC libnative_window_manager.so libohinput.so) 121``` 122 123### Adding Header Files 124 125```c++ 126#include "multimodalinput/oh_input_manager.h" 127#include "window_manager/oh_window.h" 128#include "napi/native_api.h" 129``` 130 131### Available APIs 132 133| API | Description | 134| ------------------------------------------------------------ | -------------------------- | 135| OH_WindowManager_InjectTouchEvent(int32_t windowId, Input_TouchEvent* touchEvent, int32_t windowX, int32_t windowY) | Injects a touch event into the specified window.| 136 137- Construct event parameters and inject the event to the window with the specified window ID. 138 139- Only windows within the same process are supported. Injection does not trigger changes in window focus, z-order, or dragging. Events are directly sent to ArkUI. 140 141- The API must be called after the specified window has completed its UI loading. 142 143- Check the window and multimodal touch event to ensure the event parameters are correct before sending the event to ArkUI. The specific parameter descriptions are as follows: 144 145 | Name | Description | 146 | ---------- | ------------------------------------------------------------ | 147 | windowId | ID of the target window. Only windows within the same process are supported. Otherwise, error code 1300002 is returned. The window must have completed UI loading. Otherwise, error code 1300003 is returned.| 148 | touchEvent | Pointer to the multimodal touch event. For details, see [Input_TouchEvent](../reference/apis-input-kit/capi-input-input-touchevent.md). The event is defined in **oh_input_manager.h**. Call [OH_Input_CreateTouchEvent](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_createtouchevent) to create a touchEvent object, and call [OH_Input_DestroyTouchEvent](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_destroytouchevent) to destroy the object after use. For specific parameter details, see the table below.| 149 | windowX | X coordinate of the event relative to the target window. The parameter must be a non-negative integer; otherwise, error code 1300003 is returned.| 150 | windowY | Y coordinate of the event relative to the target window. The parameter must be a non-negative integer; otherwise, error code 1300003 is returned.| 151 152 The following table describes the parameters of the **touchEvent** event. 153 154 | Name | API | Description | 155 | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | 156 | action | [OH_Input_SetTouchEventAction](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventaction) | Event action. The default value is **0**.<br>Only the following actions are supported:<br>- **0**: cancel, indicating a cancel event.<br>- **1**: down, indicating a press-down event.<br>- **2**: move, indicating a move event.<br>- **3**: up, indicating a lift event.<br>- For other actions, error code 1300003 is returned.| 157 | id | [OH_Input_SetTouchEventFingerId](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventfingerid) | Finger ID. The default value is **0**.<br>The parameter must be a non-negative integer; otherwise, error code 1300003 is returned.| 158 | displayX | [OH_Input_SetTouchEventDisplayX](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventdisplayx) | X coordinate of the event relative to the screen. The default value is **0**.<br>The parameter must be a non-negative integer; otherwise, error code 1300003 is returned. It is recommended that the value of this parameter be the same as that of **windowX**, although inconsistency will not return an error code. Only the input parameter's range is verified. You are advised to use [getWindowProperties()](../reference/apis-arkui/arkts-apis-window-Window.md#getwindowproperties9) to obtain the **windowRect** property and calculate the corresponding **windowX** by subtracting the horizontal coordinate of the window's upper-left corner in **windowRect** from **displayX**.| 159 | displayY | [OH_Input_SetTouchEventDisplayY](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventdisplayy) | Y coordinate of the event relative to the screen. The default value is **0**.<br>The parameter must be a non-negative integer; otherwise, error code 1300003 is returned. It is recommended that the value of this parameter be the same as that of **windowY**, although inconsistency will not return an error code. Only the input parameter's range is verified. You are advised to use [getWindowProperties()](../reference/apis-arkui/arkts-apis-window-Window.md#getwindowproperties9) to obtain the **windowRect** property and calculate the corresponding **windowY** by subtracting the horizontal coordinate of the window's upper-left corner in **windowRect** from **displayY**.| 160 | actionTime | [OH_Input_SetTouchEventActionTime](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventactiontime) | Timestamp. The default value is **-1**. The parameter must be a non-negative integer; otherwise, error code 1300003 is returned.| 161 | windowId | [OH_Input_SetTouchEventWindowId](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventwindowid) | Window ID for event injection. The default value is **-1**. If the parameter is not the default value and does not match **windowId** in [OH_WindowManager_InjectTouchEvent](../reference/apis-arkui/capi-oh-window-h.md#oh_windowmanager_injecttouchevent), the input parameter is considered invalid.| 162 | displayId | [OH_Input_SetTouchEventDisplayId](../reference/apis-input-kit/capi-oh-input-manager-h.md#oh_input_settoucheventdisplayid) | Display ID for event injection. The default value is **-1**. There are no restrictions, but you are advised to ensure that the display ID matches the window ID in [OH_WindowManager_InjectTouchEvent](../reference/apis-arkui/capi-oh-window-h.md#oh_windowmanager_injecttouchevent). You are advised to call [getWindowProperties()](../reference/apis-arkui/arkts-apis-window-Window.md#getwindowproperties9) to obtain the **displayId** property.| 163 164### Example 165 166The following sample code describes how to inject a multimodal touch event into the target window, using a single event injection as an example. 167 168```c++ 169#include "window_manager/oh_window.h" 170#include "multimodalinput/oh_input_manager.h" 171#include "napi/native_api.h" 172 173static napi_value injectEvent(napi_env env, napi_callback_info info) { 174 size_t argc = 1; 175 napi_value args[10] = {nullptr}; 176 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 177 178 int32_t windowId; 179 napi_get_value_int32(env, args[0], &windowId); 180 181 int32_t displayId; 182 napi_get_value_int32(env, args[1], &displayId); 183 184 int32_t windowX; 185 napi_get_value_int32(env, args[2], &windowX); 186 187 int32_t windowY; 188 napi_get_value_int32(env, args[3], &windowY); 189 190 int32_t action; 191 napi_get_value_int32(env, args[4], &action); 192 193 int32_t fingerId; 194 napi_get_value_int32(env, args[5], &fingerId); 195 196 int32_t displayX; 197 napi_get_value_int32(env, args[6], &displayX); 198 199 int32_t displayY; 200 napi_get_value_int32(env, args[7], &displayY); 201 202 int32_t actionTime; 203 napi_get_value_int32(env, args[8], &actionTime); 204 205 int32_t TE_WindowId; 206 napi_get_value_int32(env, args[9], &TE_WindowId); 207 208 // Construct a multimodal touch event. 209 Input_TouchEvent* touchEvent = OH_Input_CreateTouchEvent(); 210 OH_Input_SetTouchEventAction(touchEvent, action); 211 OH_Input_SetTouchEventFingerId(touchEvent, fingerId); 212 OH_Input_SetTouchEventDisplayX(touchEvent, displayX); 213 OH_Input_SetTouchEventDisplayY(touchEvent, displayY); 214 OH_Input_SetTouchEventActionTime(touchEvent, actionTime); 215 OH_Input_SetTouchEventWindowId(touchEvent, TE_WindowId); 216 OH_Input_SetTouchEventDisplayId(touchEvent, displayId); 217 218 // Inject the multimodal touch event to the window with the specified windowId. 219 auto res = OH_WindowManager_InjectTouchEvent(windowId, touchEvent, windowX, windowY); 220 221 // Destroy the touchEvent object after using it. 222 OH_Input_DestroyTouchEvent(&touchEvent); 223 224 napi_value errCode; 225 napi_create_int32(env, res, &errCode); 226 return errCode; 227} 228 229EXTERN_C_START 230static napi_value Init(napi_env env, napi_value exports) { 231 napi_property_descriptor desc[] = { 232 {"injectEvent", nullptr, injectEvent, nullptr, nullptr, nullptr, napi_default, nullptr}}; 233 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 234 return exports; 235} 236EXTERN_C_END 237``` 238