static void handle_key_event (GdkWindow *window, const MirInputEvent *event) { const MirKeyboardEvent *keyboard_event = mir_input_event_get_keyboard_event (event); GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl); GdkKeymap *keymap; guint modifier_state; guint button_state; if (!keyboard_event) return; switch (mir_keyboard_event_action (keyboard_event)) { case mir_keyboard_action_up: case mir_keyboard_action_down: // FIXME: Convert keycode _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state); modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state); keymap = gdk_keymap_get_for_display (gdk_window_get_display (window)); generate_key_event (window, mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_down ? GDK_KEY_PRESS : GDK_KEY_RELEASE, modifier_state, mir_keyboard_event_key_code (keyboard_event), mir_keyboard_event_scan_code (keyboard_event), _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)), NANO_TO_MILLI (mir_input_event_get_event_time (event))); break; default: //case mir_key_action_multiple: // FIXME break; } }
void _gdk_mir_print_key_event (const MirInputEvent *event) { const MirKeyboardEvent *keyboard_event = mir_input_event_get_keyboard_event (event); if (!keyboard_event) return; g_printerr ("KEY\n"); g_printerr (" Device %lld\n", (long long int) mir_input_event_get_device_id (event)); g_printerr (" Action "); switch (mir_keyboard_event_action (keyboard_event)) { case mir_keyboard_action_down: g_printerr ("down"); break; case mir_keyboard_action_up: g_printerr ("up"); break; case mir_keyboard_action_repeat: g_printerr ("repeat"); break; default: g_printerr ("%u", mir_keyboard_event_action (keyboard_event)); break; } g_printerr ("\n"); _gdk_mir_print_modifiers (mir_keyboard_event_modifiers (keyboard_event)); g_printerr (" Key Code %i\n", mir_keyboard_event_key_code (keyboard_event)); g_printerr (" Scan Code %i\n", mir_keyboard_event_scan_code (keyboard_event)); g_printerr (" Event Time %lli\n", (long long int) mir_input_event_get_event_time (event)); }
static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* window) { const int action = mir_keyboard_event_action (key_event); const int scan_code = mir_keyboard_event_scan_code(key_event); const int key_code = mir_keyboard_event_key_code (key_event); const int modifiers = mir_keyboard_event_modifiers(key_event); const int pressed = action == mir_keyboard_action_up ? GLFW_RELEASE : GLFW_PRESS; const int mods = mirModToGLFWMod(modifiers); const long text = _glfwKeySym2Unicode(key_code); const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); _glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods); if (text != -1) _glfwInputChar(window, text, mods, plain); }
void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event) { const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event); ulong timestamp = mir_input_event_get_event_time(event) / 1000000; xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event); quint32 scan_code = mir_keyboard_event_scan_code(key_event); quint32 native_modifiers = mir_keyboard_event_modifiers(key_event); // Key modifier and unicode index mapping. auto modifiers = qt_modifiers_from_mir(native_modifiers); MirKeyboardAction action = mir_keyboard_event_action(key_event); QEvent::Type keyType = action == mir_keyboard_action_up ? QEvent::KeyRelease : QEvent::KeyPress; if (action == mir_keyboard_action_down) mLastInputWindow = window; QString text; QVarLengthArray<char, 32> chars(32); { int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size()); if (result > 0) { text = QString::fromUtf8(chars.constData()); } } int sym = translateKeysym(xk_sym, text); bool is_auto_rep = action == mir_keyboard_action_repeat; QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); if (context) { QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); qKeyEvent.setTimestamp(timestamp); if (context->filterEvent(&qKeyEvent)) { qCDebug(mirclient, "key event filtered out by input context"); return; } } QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); }
TEST_F(InputEventBuilder, makes_valid_key_event) { MirKeyboardAction const action = mir_keyboard_action_down; xkb_keysym_t const key_code = 34; int const scan_code = 17; auto ev = mev::make_event(device_id, timestamp, mac, action, key_code, scan_code, modifiers); auto e = ev.get(); EXPECT_EQ(mir_event_type_input, mir_event_get_type(e)); auto ie = mir_event_get_input_event(e); EXPECT_EQ(mir_input_event_type_key, mir_input_event_get_type(ie)); auto kev = mir_input_event_get_keyboard_event(ie); EXPECT_EQ(action, mir_keyboard_event_action(kev)); EXPECT_EQ(key_code, mir_keyboard_event_key_code(kev)); EXPECT_EQ(scan_code, mir_keyboard_event_scan_code(kev)); EXPECT_EQ(modifiers, mir_keyboard_event_modifiers(kev)); EXPECT_EQ(mac, mir_keyboard_event_get_cookie(kev).mac); EXPECT_EQ(timestamp.count(), mir_keyboard_event_get_cookie(kev).timestamp); }
bool me::WindowManager::handle_key_event(MirKeyboardEvent const* kev) { // TODO: Fix android configuration and remove static hack ~racarr static bool display_off = false; if (mir_keyboard_event_action(kev) != mir_keyboard_action_down) return false; auto modifiers = mir_keyboard_event_modifiers(kev); auto scan_code = mir_keyboard_event_scan_code(kev); if (modifiers & mir_input_event_modifier_alt && scan_code == KEY_TAB) // TODO: Use keycode once we support keymapping on the server side { focus_controller->focus_next_session(); if (auto const surface = focus_controller->focused_surface()) focus_controller->raise({surface}); return true; } else if (modifiers & mir_input_event_modifier_alt && scan_code == KEY_GRAVE) { if (auto const prev = focus_controller->focused_surface()) { auto const app = focus_controller->focused_session(); auto const next = app->surface_after(prev); focus_controller->set_focus_to(app, next); focus_controller->raise({next}); } return true; } else if (modifiers & mir_input_event_modifier_alt && scan_code == KEY_F4) { auto const surf = focus_controller->focused_surface(); if (surf) surf->request_client_surface_close(); return true; } else if ((modifiers & mir_input_event_modifier_alt && scan_code == KEY_P) || (scan_code == KEY_POWER)) { compositor->stop(); auto conf = display->configuration(); MirPowerMode new_power_mode = display_off ? mir_power_mode_on : mir_power_mode_off; conf->for_each_output( [&](mg::UserDisplayConfigurationOutput& output) -> void { output.power_mode = new_power_mode; }); display_off = !display_off; display->configure(*conf.get()); if (!display_off) compositor->start(); return true; } else if ((modifiers & mir_input_event_modifier_alt) && (modifiers & mir_input_event_modifier_ctrl) && (scan_code == KEY_ESC)) { std::abort(); return true; } else if ((modifiers & mir_input_event_modifier_alt) && (modifiers & mir_input_event_modifier_ctrl) && (scan_code == KEY_L) && focus_controller) { auto const app = focus_controller->focused_session(); if (app) { app->set_lifecycle_state(mir_lifecycle_state_will_suspend); } } else if ((modifiers & mir_input_event_modifier_alt) && (modifiers & mir_input_event_modifier_ctrl)) { MirOrientation orientation = mir_orientation_normal; bool rotating = true; int mode_change = 0; bool preferred_mode = false; switch (scan_code) { case KEY_UP: orientation = mir_orientation_normal; break; case KEY_DOWN: orientation = mir_orientation_inverted; break; case KEY_LEFT: orientation = mir_orientation_left; break; case KEY_RIGHT: orientation = mir_orientation_right; break; default: rotating = false; break; } switch (scan_code) { case KEY_MINUS: mode_change = -1; break; case KEY_EQUAL: mode_change = +1; break; case KEY_0: preferred_mode = true; break; default: break; } if (rotating || mode_change || preferred_mode) { compositor->stop(); auto conf = display->configuration(); conf->for_each_output( [&](mg::UserDisplayConfigurationOutput& output) -> void { // Only apply changes to the monitor the cursor is on if (!output.extents().contains(old_cursor)) return; if (rotating) output.orientation = orientation; if (preferred_mode) { output.current_mode_index = output.preferred_mode_index; } else if (mode_change) { size_t nmodes = output.modes.size(); if (nmodes) output.current_mode_index = (output.current_mode_index + nmodes + mode_change) % nmodes; } }); display->configure(*conf); compositor->start(); return true; } } else if ((scan_code == KEY_VOLUMEDOWN || scan_code == KEY_VOLUMEUP) && max_fingers == 1) { int delta = (scan_code == KEY_VOLUMEDOWN) ? -1 : +1; static const MirOrientation order[4] = { mir_orientation_normal, mir_orientation_right, mir_orientation_inverted, mir_orientation_left }; compositor->stop(); auto conf = display->configuration(); conf->for_each_output( [&](mg::UserDisplayConfigurationOutput& output) { int i = 0; for (; i < 4; ++i) { if (output.orientation == order[i]) break; } output.orientation = order[(i+4+delta) % 4]; }); display->configure(*conf.get()); compositor->start(); return true; } else if (modifiers & mir_input_event_modifier_meta && scan_code == KEY_N) { toggle(inverse); return true; } else if (modifiers & mir_input_event_modifier_meta && scan_code == KEY_C) { toggle(contrast); return true; } return false; }