TEST_F(InputEventBuilder, makes_valid_pointer_event) { MirPointerAction action = mir_pointer_action_enter; auto depressed_buttons = mir_pointer_button_back | mir_pointer_button_tertiary; float x_axis_value = 3.9, y_axis_value = 7.4, hscroll_value = .9, vscroll_value = .3; auto const relative_x_value = 0.0; auto const relative_y_value = 0.0; auto ev = mev::make_event(device_id, timestamp, mac, modifiers, action, depressed_buttons, x_axis_value, y_axis_value, hscroll_value, vscroll_value, relative_x_value, relative_y_value); 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_pointer, mir_input_event_get_type(ie)); auto pev = mir_input_event_get_pointer_event(ie); EXPECT_EQ(modifiers, mir_pointer_event_modifiers(pev)); EXPECT_EQ(action, mir_pointer_event_action(pev)); EXPECT_EQ(mac, mir_pointer_event_get_cookie(pev).mac); EXPECT_EQ(timestamp.count(), mir_pointer_event_get_cookie(pev).timestamp); EXPECT_TRUE(mir_pointer_event_button_state(pev, mir_pointer_button_back)); EXPECT_TRUE(mir_pointer_event_button_state(pev, mir_pointer_button_tertiary)); EXPECT_FALSE(mir_pointer_event_button_state(pev, mir_pointer_button_primary)); EXPECT_FALSE(mir_pointer_event_button_state(pev, mir_pointer_button_secondary)); EXPECT_FALSE(mir_pointer_event_button_state(pev, mir_pointer_button_forward)); EXPECT_EQ(x_axis_value, mir_pointer_event_axis_value(pev, mir_pointer_axis_x)); EXPECT_EQ(y_axis_value, mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); EXPECT_EQ(hscroll_value, mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll)); EXPECT_EQ(vscroll_value, mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll)); }
void _gdk_mir_print_motion_event (const MirInputEvent *event) { const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event); if (!pointer_event) return; g_printerr ("MOTION\n"); g_printerr (" Device %lld\n", (long long int) mir_input_event_get_device_id (event)); g_printerr (" Action "); switch (mir_pointer_event_action (pointer_event)) { case mir_pointer_action_button_down: g_printerr ("down"); break; case mir_pointer_action_button_up: g_printerr ("up"); break; case mir_pointer_action_enter: g_printerr ("enter"); break; case mir_pointer_action_leave: g_printerr ("leave"); break; case mir_pointer_action_motion: g_printerr ("motion"); break; default: g_printerr ("%u", mir_pointer_event_action (pointer_event)); } g_printerr ("\n"); _gdk_mir_print_modifiers (mir_pointer_event_modifiers (pointer_event)); g_printerr (" Button State"); if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_primary)) g_printerr (" primary"); if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_secondary)) g_printerr (" secondary"); if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_tertiary)) g_printerr (" tertiary"); if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_back)) g_printerr (" back"); if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_forward)) g_printerr (" forward"); g_printerr ("\n"); g_printerr (" Offset (%f, %f)\n", mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x), mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y)); g_printerr (" Event Time %lli\n", (long long int) mir_input_event_get_event_time (event)); }
static void handlePointerMotion(_GLFWwindow* window, const MirPointerEvent* pointer_event) { int current_x = window->cursorPosX; int current_y = window->cursorPosY; int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x); int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y); int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll); int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); if (current_x != x || current_y != y) _glfwInputCursorMotion(window, x, y); if (dx != 0 || dy != 0) _glfwInputScroll(window, dx, dy); }
void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev) { const auto window = platformWindow->window(); const auto timestamp = mir_input_event_get_event_time(ev) / 1000000; const auto pev = mir_input_event_get_pointer_event(ev); const auto action = mir_pointer_event_action(pev); const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev)); const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x), mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); mLastInputWindow = platformWindow; switch (action) { case mir_pointer_action_button_up: case mir_pointer_action_button_down: case mir_pointer_action_motion: { const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll); const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll); if (hDelta != 0 || vDelta != 0) { // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid const QPoint angleDelta(120 * hDelta, 120 * vDelta); QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint, QPoint(), angleDelta, modifiers, Qt::ScrollUpdate); } auto buttons = extract_buttons(pev); QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, window->position() + localPoint /* Should we omit global point instead? */, buttons, modifiers); break; } case mir_pointer_action_enter: QWindowSystemInterface::handleEnterEvent(window, localPoint, window->position() + localPoint); break; case mir_pointer_action_leave: QWindowSystemInterface::handleLeaveEvent(window); break; default: Q_UNREACHABLE(); } }
static void handlePointerMotion(_GLFWwindow* window, const MirPointerEvent* pointer_event) { const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll); const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.mir.disabledCursorWindow != window) return; const int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_x); const int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_y); const int current_x = window->virtualCursorPosX; const int current_y = window->virtualCursorPosY; _glfwInputCursorPos(window, dx + current_x, dy + current_y); } else { const int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x); const int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y); _glfwInputCursorPos(window, x, y); } if (hscroll != 0 || vscroll != 0) _glfwInputScroll(window, hscroll, vscroll); }
bool me::WindowManager::handle_pointer_event(MirPointerEvent const* pev) { bool handled = false; geometry::Point cursor{mir_pointer_event_axis_value(pev, mir_pointer_axis_x), mir_pointer_event_axis_value(pev, mir_pointer_axis_y)}; auto action = mir_pointer_event_action(pev); auto modifiers = mir_pointer_event_modifiers(pev); auto vscroll = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll); auto primary_button_pressed = mir_pointer_event_button_state(pev, mir_pointer_button_primary); auto tertiary_button_pressed = mir_pointer_event_button_state(pev, mir_pointer_button_tertiary); float new_zoom_mag = 0.0f; // zero means unchanged if (modifiers & mir_input_event_modifier_meta && action == mir_pointer_action_motion) { zoom_exponent += vscroll; // Negative exponents do work too, but disable them until // there's a clear edge to the desktop. if (zoom_exponent < 0) zoom_exponent = 0; new_zoom_mag = powf(1.2f, zoom_exponent); handled = true; } me::DemoCompositor::for_each( [new_zoom_mag,&cursor](me::DemoCompositor& c) { if (new_zoom_mag > 0.0f) c.zoom(new_zoom_mag); c.on_cursor_movement(cursor); }); if (zoom_exponent || new_zoom_mag) force_redraw(); auto const surf = focus_controller->focused_surface(); if (surf && (modifiers & mir_input_event_modifier_alt) && (primary_button_pressed || tertiary_button_pressed)) { // Start of a gesture: When the latest finger/button goes down if (action == mir_pointer_action_button_down) { click = cursor; save_edges(*surf, click); handled = true; } else if (action == mir_pointer_action_motion) { geometry::Displacement drag = cursor - old_cursor; if (tertiary_button_pressed) { // Resize by mouse middle button resize(*surf, cursor); } else { surf->move_to(old_pos + drag); } handled = true; } old_pos = surf->top_left(); old_size = surf->size(); } if (surf && (modifiers & mir_input_event_modifier_alt) && action == mir_pointer_action_motion && vscroll) { float alpha = surf->alpha(); alpha += 0.1f * vscroll; if (alpha < 0.0f) alpha = 0.0f; else if (alpha > 1.0f) alpha = 1.0f; surf->set_alpha(alpha); handled = true; } old_cursor = cursor; return handled; }
static void handle_motion_event (GdkWindow *window, const MirInputEvent *event) { const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event); GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl); gdouble x, y; gboolean cursor_inside; guint button_state; guint modifier_state; guint32 event_time; GdkEventType event_type; guint changed_button_state; if (!pointer_event) return; _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state); modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), mir_pointer_event_get_button_state (pointer_event)); event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event)); /* TODO: Remove once we have proper transient window support. */ if (mir_pointer_event_action (pointer_event) == mir_pointer_action_leave) { LeaveInfo info; info.x = x; info.y = y; info.time = event_time; info.except = window; /* Leave all transient children from leaf to root, except the root since we do it later. */ _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info); } else { LeaveInfo info; info.x = x; info.y = y; info.time = event_time; info.except = _gdk_mir_window_get_visible_transient_child (window, x, y, &x, &y); /* Leave all transient children from leaf to root, except the pointer window since we enter it. */ _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info); window = info.except; if (window) { /* Enter the pointer window. */ gboolean cursor_inside_pointer_window; impl = GDK_MIR_WINDOW_IMPL (window->impl); _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, &cursor_inside_pointer_window, NULL); if (!cursor_inside_pointer_window) { generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time); _gdk_mir_window_impl_set_cursor_state (impl, x, y, TRUE, mir_pointer_event_get_button_state (pointer_event)); } } } if (window) { gdouble new_x; gdouble new_y; gdouble hscroll; gdouble vscroll; /* Update which window has focus */ _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state); switch (mir_pointer_event_action (pointer_event)) { case mir_pointer_action_button_up: case mir_pointer_action_button_down: event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE; changed_button_state = button_state ^ mir_pointer_event_get_button_state (pointer_event); if (changed_button_state == 0 || (changed_button_state & mir_pointer_button_primary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time); if ((changed_button_state & mir_pointer_button_secondary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time); if ((changed_button_state & mir_pointer_button_tertiary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time); button_state = mir_pointer_event_get_button_state (pointer_event); break; case mir_pointer_action_motion: new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x); new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y); hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll); vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll); if (hscroll > 0.5 || vscroll > 0.5) generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time); if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5) generate_motion_event (window, new_x, new_y, modifier_state, event_time); break; case mir_pointer_action_leave: if (cursor_inside) { cursor_inside = FALSE; generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time); } break; default: break; } _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state); } }
static void handle_motion_event (GdkWindow *window, const MirInputEvent *event) { const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event); GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl); gdouble x, y; gboolean cursor_inside; guint button_state; guint new_button_state; guint modifier_state; guint32 event_time; GdkEventType event_type; guint changed_button_state; if (!pointer_event) return; _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state); new_button_state = get_button_state (pointer_event); modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), new_button_state); event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event)); if (window) { gdouble new_x; gdouble new_y; gdouble hscroll; gdouble vscroll; /* Update which window has focus */ _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state); switch (mir_pointer_event_action (pointer_event)) { case mir_pointer_action_button_up: case mir_pointer_action_button_down: event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE; changed_button_state = button_state ^ new_button_state; if (changed_button_state == 0 || (changed_button_state & GDK_BUTTON1_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time); if ((changed_button_state & GDK_BUTTON2_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time); if ((changed_button_state & GDK_BUTTON3_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time); button_state = new_button_state; break; case mir_pointer_action_motion: new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x); new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y); hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll); vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll); if (hscroll != 0.0 || vscroll != 0.0) generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time); if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5) { generate_motion_event (window, new_x, new_y, modifier_state, event_time); x = new_x; y = new_y; } break; case mir_pointer_action_enter: if (!cursor_inside) { cursor_inside = TRUE; generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time); } break; case mir_pointer_action_leave: if (cursor_inside) { cursor_inside = FALSE; generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time); } break; default: break; } _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state); } }