• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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