• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/common/ime/text_input_client.h"
17 
18 #include "core/pipeline_ng/pipeline_context.h"
19 
20 namespace OHOS::Ace {
21 namespace {
22 using tic = TextInputClient; // give it a shorter name to maintain a good code layout
23 }
24 
25 // Here declares function keys which can be handled by TextInputClient.
26 std::map<KeyComb, std::function<bool(TextInputClient*)>> TextInputClient::functionKeys_ = {
27     { KeyComb(KeyCode::KEY_ESCAPE), &tic::HandleOnEscape },
__anon6297b4360202() 28     { KeyComb(KeyCode::KEY_TAB), [](tic* c) -> bool { return c->HandleOnTab(false); } },
__anon6297b4360302() 29     { KeyComb(KeyCode::KEY_TAB, KEY_SHIFT), [](tic* c) -> bool { return c->HandleOnTab(true); } },
30 };
31 
32 // Here declares keyboard shortcuts which should be handled and consumed by TextInputClient.
33 std::map<KeyComb, std::function<void(TextInputClient*)>> TextInputClient::keyboardShortCuts_ = {
34 // actions
35 #if defined(MAC_PLATFORM)
36     { KeyComb(KeyCode::KEY_A, KEY_META), &tic::HandleOnSelectAll },
__anon6297b4360402() 37     { KeyComb(KeyCode::KEY_C, KEY_META), [](tic* c) -> void { c->HandleOnCopy(true); }  },
__anon6297b4360502() 38     { KeyComb(KeyCode::KEY_D, KEY_META), [](tic* c) -> void { c->HandleOnDelete(true); } },
39     { KeyComb(KeyCode::KEY_V, KEY_META), &tic::HandleOnPaste },
40     { KeyComb(KeyCode::KEY_X, KEY_META), &tic::HandleOnCut },
41     { KeyComb(KeyCode::KEY_Y, KEY_META), &tic::HandleOnRedoAction },
42     { KeyComb(KeyCode::KEY_Z, KEY_META), &tic::HandleOnUndoAction },
43     { KeyComb(KeyCode::KEY_Z, KEY_META | KEY_SHIFT), &tic::HandleOnRedoAction },
44 #else
45     { KeyComb(KeyCode::KEY_A, KEY_CTRL), &tic::HandleOnSelectAll },
46     { KeyComb(KeyCode::KEY_C, KEY_CTRL), [](tic* c) -> void { c->HandleOnCopy(true); } },
47     { KeyComb(KeyCode::KEY_D, KEY_CTRL), [](tic* c) -> void { c->HandleOnDelete(true); } },
48     { KeyComb(KeyCode::KEY_V, KEY_CTRL), &tic::HandleOnPaste },
49     { KeyComb(KeyCode::KEY_X, KEY_CTRL), &tic::HandleOnCut },
50     { KeyComb(KeyCode::KEY_Y, KEY_CTRL), &tic::HandleOnRedoAction },
51     { KeyComb(KeyCode::KEY_Z, KEY_CTRL), &tic::HandleOnUndoAction },
52     { KeyComb(KeyCode::KEY_Z, KEY_CTRL | KEY_SHIFT), &tic::HandleOnRedoAction },
53 #endif
__anon6297b4360602() 54     { KeyComb(KeyCode::KEY_DEL), [](tic* c) -> void { c->HandleOnDelete(true); } },
__anon6297b4360702() 55     { KeyComb(KeyCode::KEY_FORWARD_DEL), [](tic* c) -> void { c->HandleOnDelete(false); } },
__anon6297b4360802() 56     { KeyComb(KeyCode::KEY_DEL, KEY_CTRL), [](tic* c) -> void { c->HandleOnDeleteComb(true); } },
__anon6297b4360902() 57     { KeyComb(KeyCode::KEY_FORWARD_DEL, KEY_CTRL), [](tic* c) -> void { c->HandleOnDeleteComb(false); } },
__anon6297b4360a02() 58     { KeyComb(KeyCode::KEY_INSERT, KEY_CTRL), [](tic* c) -> void { c->HandleOnCopy(true); } },
59     { KeyComb(KeyCode::KEY_INSERT, KEY_SHIFT), &tic::HandleOnPaste },
60     { KeyComb(KeyCode::KEY_PASTE), &tic::HandleOnPaste },
61     { KeyComb(KeyCode::KEY_F10, KEY_SHIFT), &tic::HandleOnShowMenu },
62     { KeyComb(KeyCode::KEY_MENU), &tic::HandleOnShowMenu },
63     { KeyComb(KeyCode::KEY_ENTER), &tic::HandleOnEnter },
64     { KeyComb(KeyCode::KEY_NUMPAD_ENTER), &tic::HandleOnEnter },
65     { KeyComb(KeyCode::KEY_DPAD_CENTER), &tic::HandleOnEnter },
66     { KeyComb(KeyCode::KEY_ENTER, KEY_CTRL), &tic::HandleOnEnter },
67     { KeyComb(KeyCode::KEY_NUMPAD_ENTER, KEY_CTRL), &tic::HandleOnEnter },
68     { KeyComb(KeyCode::KEY_DPAD_CENTER, KEY_CTRL), &tic::HandleOnEnter },
69     { KeyComb(KeyCode::KEY_PAGE_UP), &tic::HandleOnPageUp },
70     { KeyComb(KeyCode::KEY_PAGE_DOWN), &tic::HandleOnPageDown },
71     // caret move keys
__anon6297b4360b02() 72     { KeyComb(KeyCode::KEY_DPAD_LEFT), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Left); } },
__anon6297b4360c02() 73     { KeyComb(KeyCode::KEY_DPAD_RIGHT), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Right); } },
__anon6297b4360d02() 74     { KeyComb(KeyCode::KEY_DPAD_UP), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Up); } },
__anon6297b4360e02() 75     { KeyComb(KeyCode::KEY_DPAD_DOWN), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Down); } },
__anon6297b4360f02() 76     { KeyComb(KeyCode::KEY_MOVE_HOME), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LineBegin); } },
__anon6297b4361002() 77     { KeyComb(KeyCode::KEY_MOVE_END), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LineEnd); } },
__anon6297b4361102() 78     { KeyComb(KeyCode::KEY_DPAD_LEFT, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LeftWord); } },
__anon6297b4361202() 79     { KeyComb(KeyCode::KEY_DPAD_RIGHT, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::RightWord); } },
__anon6297b4361302() 80     { KeyComb(KeyCode::KEY_DPAD_UP, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghBegin); } },
__anon6297b4361402() 81     { KeyComb(KeyCode::KEY_DPAD_DOWN, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghEnd); } },
__anon6297b4361502() 82     { KeyComb(KeyCode::KEY_MOVE_HOME, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Home); } },
__anon6297b4361602() 83     { KeyComb(KeyCode::KEY_MOVE_END, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::End); } },
84     // select key combinations
__anon6297b4361702() 85     { KeyComb(KeyCode::KEY_DPAD_LEFT, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Left); } },
__anon6297b4361802() 86     { KeyComb(KeyCode::KEY_DPAD_RIGHT, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Right); } },
__anon6297b4361902() 87     { KeyComb(KeyCode::KEY_DPAD_UP, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Up); } },
__anon6297b4361a02() 88     { KeyComb(KeyCode::KEY_DPAD_DOWN, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Down); } },
__anon6297b4361b02() 89     { KeyComb(KeyCode::KEY_MOVE_HOME, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LineBegin); } },
__anon6297b4361c02() 90     { KeyComb(KeyCode::KEY_MOVE_END, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LineEnd); } },
91     { KeyComb(KeyCode::KEY_DPAD_LEFT, KEY_CTRL | KEY_SHIFT),
__anon6297b4361d02() 92         [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LeftWord); } },
93     { KeyComb(KeyCode::KEY_DPAD_RIGHT, KEY_CTRL | KEY_SHIFT),
__anon6297b4361e02() 94         [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::RightWord); } },
95     { KeyComb(KeyCode::KEY_DPAD_UP, KEY_CTRL | KEY_SHIFT),
__anon6297b4361f02() 96         [](tic* c) -> void { c->HandleSelectExtend(CaretMoveIntent::ParagraghBegin); } },
97     { KeyComb(KeyCode::KEY_DPAD_DOWN, KEY_CTRL | KEY_SHIFT),
__anon6297b4362002() 98         [](tic* c) -> void { c->HandleSelectExtend(CaretMoveIntent::ParagraghEnd); } },
99     { KeyComb(KeyCode::KEY_MOVE_HOME, KEY_CTRL | KEY_SHIFT),
__anon6297b4362102() 100         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Home); } },
101     { KeyComb(KeyCode::KEY_MOVE_END, KEY_CTRL | KEY_SHIFT),
__anon6297b4362202() 102         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::End); } },
__anon6297b4362302() 103     { KeyComb(KeyCode::KEY_B, KEY_CTRL), [](tic* c) -> void { c->HandleSelectFontStyle(KeyCode::KEY_B); } },
__anon6297b4362402() 104     { KeyComb(KeyCode::KEY_I, KEY_CTRL), [](tic* c) -> void { c->HandleSelectFontStyle(KeyCode::KEY_I); } },
__anon6297b4362502() 105     { KeyComb(KeyCode::KEY_U, KEY_CTRL), [](tic* c) -> void { c->HandleSelectFontStyle(KeyCode::KEY_U); } },
106     // when numLock off, KEY_NUMPAD_0 perform as KEY_INSERT
__anon6297b4362602() 107     { KeyComb(KeyCode::KEY_NUMPAD_0, KEY_CTRL), [](tic* c) -> void { c->HandleOnCopy(true); } },
108     { KeyComb(KeyCode::KEY_NUMPAD_0, KEY_SHIFT), &tic::HandleOnPaste },
109     // when numLock off, KEY_NUMPAD_1 perform as KEY_MOVE_END
__anon6297b4362702() 110     { KeyComb(KeyCode::KEY_NUMPAD_1), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LineEnd); } },
__anon6297b4362802() 111     { KeyComb(KeyCode::KEY_NUMPAD_1, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::End); } },
__anon6297b4362902() 112     { KeyComb(KeyCode::KEY_NUMPAD_1, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LineEnd); } },
113     { KeyComb(KeyCode::KEY_NUMPAD_1, KEY_CTRL | KEY_SHIFT),
__anon6297b4362a02() 114         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::End); } },
115     // when numLock off, KEY_NUMPAD_2 perform as KEY_DPAD_DOWN
__anon6297b4362b02() 116     { KeyComb(KeyCode::KEY_NUMPAD_2), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Down); } },
__anon6297b4362c02() 117     { KeyComb(KeyCode::KEY_NUMPAD_2, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghEnd); } },
__anon6297b4362d02() 118     { KeyComb(KeyCode::KEY_NUMPAD_2, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Down); } },
119     { KeyComb(KeyCode::KEY_NUMPAD_2, KEY_CTRL | KEY_SHIFT),
__anon6297b4362e02() 120         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghEnd); } },
121     // when numLock off, KEY_NUMPAD_3 perform as KEY_PAGE_DOWN
122     { KeyComb(KeyCode::KEY_NUMPAD_3), &tic::HandleOnPageDown },
123     // when numLock off, KEY_NUMPAD_4 perform as KEY_DPAD_LEFT
__anon6297b4362f02() 124     { KeyComb(KeyCode::KEY_NUMPAD_4), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Left); } },
__anon6297b4363002() 125     { KeyComb(KeyCode::KEY_NUMPAD_4, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LeftWord); } },
__anon6297b4363102() 126     { KeyComb(KeyCode::KEY_NUMPAD_4, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Left); } },
127     { KeyComb(KeyCode::KEY_NUMPAD_4, KEY_CTRL | KEY_SHIFT),
__anon6297b4363202() 128         [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LeftWord); } },
129     // when numLock off, KEY_NUMPAD_5 perform as none
130     // when numLock off, KEY_NUMPAD_6 perform as KEY_DPAD_RIGHT
__anon6297b4363302() 131     { KeyComb(KeyCode::KEY_NUMPAD_6), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Right); } },
__anon6297b4363402() 132     { KeyComb(KeyCode::KEY_NUMPAD_6, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::RightWord); } },
__anon6297b4363502() 133     { KeyComb(KeyCode::KEY_NUMPAD_6, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Right); } },
134     { KeyComb(KeyCode::KEY_NUMPAD_6, KEY_CTRL | KEY_SHIFT),
__anon6297b4363602() 135         [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::RightWord); } },
136     // when numLock off, KEY_NUMPAD_7 perform as KEY_MOVE_HOME
__anon6297b4363702() 137     { KeyComb(KeyCode::KEY_NUMPAD_7), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::LineBegin); } },
__anon6297b4363802() 138     { KeyComb(KeyCode::KEY_NUMPAD_7, KEY_CTRL), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Home); } },
__anon6297b4363902() 139     { KeyComb(KeyCode::KEY_NUMPAD_7, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::LineBegin); } },
140     { KeyComb(KeyCode::KEY_NUMPAD_7, KEY_CTRL | KEY_SHIFT),
__anon6297b4363a02() 141         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Home); } },
142     // when numLock off, KEY_NUMPAD_8 perform as KEY_DPAD_UP
__anon6297b4363b02() 143     { KeyComb(KeyCode::KEY_NUMPAD_8), [](tic* c) -> void { c->CursorMove(CaretMoveIntent::Up); } },
144     { KeyComb(KeyCode::KEY_NUMPAD_8, KEY_CTRL),
__anon6297b4363c02() 145         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghBegin); } },
__anon6297b4363d02() 146     { KeyComb(KeyCode::KEY_NUMPAD_8, KEY_SHIFT), [](tic* c) -> void { c->HandleSelect(CaretMoveIntent::Up); } },
147     { KeyComb(KeyCode::KEY_NUMPAD_8, KEY_CTRL | KEY_SHIFT),
__anon6297b4363e02() 148         [](tic* c) -> void { c->CursorMove(CaretMoveIntent::ParagraghBegin); } },
149     // when numLock off, KEY_NUMPAD_9 perform as KEY_PAGE_UP
150     { KeyComb(KeyCode::KEY_NUMPAD_9), &tic::HandleOnPageUp },
151     // when numLock off, KEY_NUMPAD_DOT perform as KEY_FORWARD_DEL
__anon6297b4363f02() 152     { KeyComb(KeyCode::KEY_NUMPAD_DOT), [](tic* c) -> void { c->HandleOnDelete(false); } },
__anon6297b4364002() 153     { KeyComb(KeyCode::KEY_NUMPAD_DOT, KEY_CTRL), [](tic* c) -> void { c->HandleOnDeleteComb(false); } },
154     { KeyComb(KeyCode::KEY_DEL, KEY_ALT), &tic::HandleOnExtendUndoAction },
155 };
156 
NotifyKeyboardHeight(uint32_t height)157 void TextInputClient::NotifyKeyboardHeight(uint32_t height)
158 {
159     auto pipeline = NG::PipelineContext::GetCurrentContext();
160     CHECK_NULL_VOID(pipeline);
161     auto manager = pipeline->GetSafeAreaManager();
162     CHECK_NULL_VOID(manager);
163     manager->SetkeyboardHeightConsideringUIExtension(height);
164 }
165 
HandleKeyEvent(const KeyEvent & keyEvent)166 bool TextInputClient::HandleKeyEvent(const KeyEvent& keyEvent)
167 {
168     UpdateShiftFlag(keyEvent);
169     if (keyEvent.action != KeyAction::DOWN) {
170         return false;
171     }
172     uint32_t ctrlFlag =
173         (keyEvent.HasKey(KeyCode::KEY_CTRL_LEFT) || keyEvent.HasKey(KeyCode::KEY_CTRL_RIGHT) ? KEY_CTRL : KEY_NULL);
174     bool vFlag = keyEvent.HasKey(KeyCode::KEY_V);
175     if (!keyEvent.msg.empty() && ctrlFlag == KEY_CTRL && vFlag) {
176         InsertValue(keyEvent.msg);
177         return true;
178     }
179     uint32_t modKeyFlags =
180         (keyEvent.HasKey(KeyCode::KEY_ALT_LEFT) || keyEvent.HasKey(KeyCode::KEY_ALT_RIGHT) ? KEY_ALT : KEY_NULL) |
181         (keyEvent.HasKey(KeyCode::KEY_SHIFT_LEFT) || keyEvent.HasKey(KeyCode::KEY_SHIFT_RIGHT) ? KEY_SHIFT : KEY_NULL) |
182         (keyEvent.HasKey(KeyCode::KEY_CTRL_LEFT) || keyEvent.HasKey(KeyCode::KEY_CTRL_RIGHT) ? KEY_CTRL : KEY_NULL) |
183         (keyEvent.HasKey(KeyCode::KEY_META_LEFT) || keyEvent.HasKey(KeyCode::KEY_META_RIGHT) ? KEY_META : KEY_NULL);
184     if (modKeyFlags == KEY_NULL || modKeyFlags == KEY_SHIFT) {
185         auto value = keyEvent.ConvertCodeToString();
186         if (value != "") {
187             InsertValue(value, true);
188             return true;
189         }
190     }
191     auto iterFunctionKeys = functionKeys_.find(KeyComb(keyEvent.code, modKeyFlags));
192     if (iterFunctionKeys != functionKeys_.end()) {
193         this->ResetOriginCaretPosition();
194         return iterFunctionKeys->second(this);
195     }
196     auto iterKeyboardShortCuts = keyboardShortCuts_.find(KeyComb(keyEvent.code, modKeyFlags));
197     if (iterKeyboardShortCuts != keyboardShortCuts_.end()) {
198         auto isShortCutBlocked = IsShortCutBlocked();
199         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "find a keyboard shortcut, key code: %{public}d, modKeyFlags: %{public}d, "
200             "isBlocked: %{public}d", static_cast<int32_t>(keyEvent.code), modKeyFlags, isShortCutBlocked);
201         CHECK_EQUAL_RETURN(isShortCutBlocked, true, true);
202         if (KeyComb(keyEvent.code, modKeyFlags) == KeyComb(KeyCode::KEY_DPAD_UP, KEY_SHIFT) ||
203             KeyComb(keyEvent.code, modKeyFlags) == KeyComb(KeyCode::KEY_DPAD_DOWN, KEY_SHIFT)) {
204             this->RecordOriginCaretPosition();
205         } else {
206             this->ResetOriginCaretPosition();
207         }
208         iterKeyboardShortCuts->second(this);
209         return true;
210     }
211     return false;
212 }
213 } // namespace OHOS::Ace
214