mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-17 17:33:21 +08:00
[feat] add HarmonyOS desktop and mobile clients,issue #117
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#include "keyboard_hook.h"
|
||||
#include "keyboard_hook_mock.h"
|
||||
#include "keyboard_state.h"
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
using namespace crossdesk;
|
||||
using namespace crossdesk::harmony::desktop;
|
||||
std::vector<KeyboardInput> delivered;
|
||||
void Sink(int key, bool down, uint32_t scan, bool extended, void* context) {
|
||||
assert(context == &delivered); delivered.push_back({key, down, scan, extended});
|
||||
}
|
||||
void Event(int code, int action) {
|
||||
static int id = 0;
|
||||
const Input_KeyEvent event{code, action, ++id};
|
||||
assert(hook_callback); hook_callback(&event);
|
||||
}
|
||||
int main() {
|
||||
KeyboardHook hook;
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_APP_NOT_FOCUSED);
|
||||
SetKeyboardFocus(2, true);
|
||||
hook_add_result = INPUT_PERMISSION_DENIED;
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_PERMISSION_DENIED);
|
||||
assert(!hook.Active() && hook.Stop() == INPUT_SUCCESS);
|
||||
hook_add_result = INPUT_SUCCESS;
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_SUCCESS && hook.Active());
|
||||
const int installed_count = hook_adds;
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_SUCCESS && hook_adds == installed_count);
|
||||
KeyboardHook other;
|
||||
assert(other.Start(Sink, &delivered) == INPUT_REPEAT_INTERCEPTOR);
|
||||
assert(other.Stop() == INPUT_SUCCESS && hook.Active());
|
||||
// Alt+Tab and Meta+L reach the same shared input queue as ordinary keys.
|
||||
for (auto [modifier, key] : {std::pair{2045, 2049}, std::pair{2076, 2028}}) {
|
||||
Event(modifier, KEY_ACTION_DOWN); Event(key, KEY_ACTION_DOWN);
|
||||
Event(key, KEY_ACTION_UP); Event(modifier, KEY_ACTION_UP);
|
||||
}
|
||||
assert(delivered.size() == 8 && forwarded_events.empty());
|
||||
assert(delivered[0].key_code == 0xA4 && delivered[1].key_code == 0x09);
|
||||
assert(delivered[4].key_code == 0x5B && delivered[4].extended && delivered[5].key_code == 'L');
|
||||
Event(2073, KEY_ACTION_DOWN); Event(2119, KEY_ACTION_DOWN); Event(2119, KEY_ACTION_DOWN);
|
||||
assert(delivered.back().key_code == 0x0D && delivered.back().scan_code == 0x1C && delivered.back().extended);
|
||||
Event(2119, KEY_ACTION_CANCEL);
|
||||
assert(!delivered.back().is_down && delivered.back().key_code == 0xA3);
|
||||
assert(delivered[delivered.size()-2].key_code == 0x0D);
|
||||
const auto count = delivered.size();
|
||||
Event(9999, KEY_ACTION_DOWN); Event(2017, KEY_ACTION_UP);
|
||||
assert(delivered.size() == count && forwarded_events.size() == 2);
|
||||
Event(2072, KEY_ACTION_DOWN);
|
||||
SetKeyboardFocus(2, false);
|
||||
assert(!hook.Active() && !delivered.back().is_down);
|
||||
Event(2017, KEY_ACTION_DOWN);
|
||||
assert(forwarded_events.size() == 3);
|
||||
SetKeyboardFocus(1, true); Event(2017, KEY_ACTION_DOWN);
|
||||
assert(!hook.Active() && forwarded_events.size() == 4);
|
||||
hook.Stop(); SetKeyboardFocus(2, true);
|
||||
hook.Start(Sink, &delivered); Event(2076, KEY_ACTION_DOWN);
|
||||
SetKeyboardHookPermission(false);
|
||||
assert(!hook.Active() && !delivered.back().is_down);
|
||||
Event(2017, KEY_ACTION_DOWN); assert(forwarded_events.size() == 5);
|
||||
// Failed unregistration must leave a pass-through callback, never a dangling sink.
|
||||
hook_remove_result = INPUT_SERVICE_EXCEPTION;
|
||||
assert(hook.Stop() == INPUT_SERVICE_EXCEPTION);
|
||||
const auto after_stop = delivered.size();
|
||||
Event(2017, KEY_ACTION_DOWN); assert(delivered.size() == after_stop);
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_SERVICE_EXCEPTION);
|
||||
hook_remove_result = INPUT_SUCCESS;
|
||||
assert(hook.Start(Sink, &delivered) == INPUT_SUCCESS && hook.Active());
|
||||
hook.Stop();
|
||||
// A focus change inside the OS registration call cannot bind the hook to
|
||||
// a local dialog that replaced the control window during installation.
|
||||
focus_during_add = 1;
|
||||
hook.Start(Sink, &delivered); assert(!hook.Active());
|
||||
Event(2017, KEY_ACTION_DOWN); assert(delivered.size() == after_stop);
|
||||
hook.Stop();
|
||||
focus_during_add = 0;
|
||||
{
|
||||
auto transient = std::make_unique<KeyboardHook>();
|
||||
transient->Start(Sink, &delivered);
|
||||
hook_remove_result = INPUT_SERVICE_EXCEPTION;
|
||||
}
|
||||
Event(2017, KEY_ACTION_DOWN); assert(delivered.size() == after_stop);
|
||||
hook_remove_result = INPUT_SUCCESS; hook.Stop();
|
||||
}
|
||||
Reference in New Issue
Block a user