/** * clutter_input_device_update_from_event: * @device: a #ClutterInputDevice * @event: a #ClutterEvent * @update_stage: whether to update the #ClutterStage of the @device * using the stage of the event * * Forcibly updates the state of the @device using a #ClutterEvent * * This function should never be used by applications: it is meant * for integration with embedding toolkits, like clutter-gtk * * Embedding toolkits that disable the event collection inside Clutter * need to use this function to update the state of input devices depending * on a #ClutterEvent that they are going to submit to the event handling code * in Clutter though clutter_do_event(). Since the input devices hold the state * that is going to be used to fill in fields like the #ClutterButtonEvent * click count, or to emit synthesized events like %CLUTTER_ENTER and * %CLUTTER_LEAVE, it is necessary for embedding toolkits to also be * responsible of updating the input device state. * * For instance, this might be the code to translate an embedding toolkit * native motion notification into a Clutter #ClutterMotionEvent and ask * Clutter to process it: * * |[ * ClutterEvent c_event; * * translate_native_event_to_clutter (native_event, &c_event); * * clutter_do_event (&c_event); * ]| * * Before letting clutter_do_event() process the event, it is necessary to call * clutter_input_device_update_from_event(): * * |[ * ClutterEvent c_event; * ClutterDeviceManager *manager; * ClutterInputDevice *device; * * translate_native_event_to_clutter (native_event, &c_event); * * /* get the device manager */ * manager = clutter_device_manager_get_default (); * * /* use the default Core Pointer that Clutter * * backends register by default * */ * device = clutter_device_manager_get_core_device (manager, %CLUTTER_POINTER_DEVICE); * * /* update the state of the input device */ * clutter_input_device_update_from_event (device, &c_event, FALSE); * * clutter_do_event (&c_event); * ]| * * The @update_stage boolean argument should be used when the input device * enters and leaves a #ClutterStage; it will use the #ClutterStage field * of the passed @event to update the stage associated to the input device. * * Since: 1.2 */ void clutter_input_device_update_from_event (ClutterInputDevice *device, ClutterEvent *event, gboolean update_stage) { ClutterModifierType event_state; ClutterStage *event_stage; gfloat event_x, event_y; guint32 event_time; g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); g_return_if_fail (event != NULL); event_state = clutter_event_get_state (event); event_time = clutter_event_get_time (event); event_stage = clutter_event_get_stage (event); clutter_event_get_coords (event, &event_x, &event_y); _clutter_input_device_set_coords (device, event_x, event_y); _clutter_input_device_set_state (device, event_state); _clutter_input_device_set_time (device, event_time); if (update_stage) _clutter_input_device_set_stage (device, event_stage); }
/** * xfdashboard_create_app_context: * @inWorkspace: The workspace where to place application windows on or %NULL * * Returns a #GAppLaunchContext suitable for launching applications on the * given display and workspace by GIO. * * If @inWorkspace is specified it sets workspace on which applications will * be launched when using this context when running under a window manager * that supports multiple workspaces. * * When the workspace is not specified it is up to the window manager to pick * one, typically it will be the current workspace. * * Return value: (transfer full): the newly created #GAppLaunchContext or %NULL * in case of an error. Use g_object_unref() to free return value. */ GAppLaunchContext* xfdashboard_create_app_context(XfdashboardWindowTrackerWorkspace *inWorkspace) { GdkAppLaunchContext *context; const ClutterEvent *event; XfdashboardWindowTracker *tracker; g_return_val_if_fail(inWorkspace==NULL || XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE(inWorkspace), NULL); /* Get last event for timestamp */ event=clutter_get_current_event(); /* Get active workspace if not specified */ if(!inWorkspace) { tracker=xfdashboard_window_tracker_get_default(); inWorkspace=xfdashboard_window_tracker_get_active_workspace(tracker); g_object_unref(tracker); } /* Create and set up application context to use either the workspace specified * or otherwise current active workspace. We will even set the current active * explicitly to launch the application on current workspace even if user changes * workspace in the time between launching application and showing first window. */ context=gdk_display_get_app_launch_context(gdk_display_get_default()); if(event) gdk_app_launch_context_set_timestamp(context, clutter_event_get_time(event)); gdk_app_launch_context_set_desktop(context, xfdashboard_window_tracker_workspace_get_number(inWorkspace)); /* Return application context */ return(G_APP_LAUNCH_CONTEXT(context)); }
static GesturePoint * gesture_register_point (ClutterGestureAction *action, ClutterEvent *event) { ClutterGestureActionPrivate *priv = action->priv; GesturePoint *point = NULL; if (priv->points->len >= MAX_GESTURE_POINTS) return NULL; g_array_set_size (priv->points, priv->points->len + 1); point = &g_array_index (priv->points, GesturePoint, priv->points->len - 1); point->last_event = clutter_event_copy (event); point->device = clutter_event_get_device (event); clutter_event_get_coords (event, &point->press_x, &point->press_y); point->last_motion_x = point->press_x; point->last_motion_y = point->press_y; point->last_motion_time = clutter_event_get_time (event); point->last_delta_x = point->last_delta_y = 0; point->last_delta_time = 0; if (clutter_event_type (event) != CLUTTER_BUTTON_PRESS) point->sequence = clutter_event_get_event_sequence (event); else point->sequence = NULL; return point; }
static void notify_motion (ClaylandSeat *seat, const ClutterEvent *event) { ClaylandPointer *pointer = &seat->pointer; float x, y; clutter_event_get_coords (event, &x, &y); pointer->x = wl_fixed_from_double (x); pointer->y = wl_fixed_from_double (y); clayland_seat_repick (seat, clutter_event_get_time (event), clutter_event_get_source (event)); pointer->grab->interface->motion (pointer->grab, clutter_event_get_time (event), pointer->grab->x, pointer->grab->y); }
static void gesture_update_release_point (GesturePoint *point, ClutterEvent *event) { gint64 _time; clutter_event_get_coords (event, &point->release_x, &point->release_y); clutter_event_free (point->last_event); point->last_event = clutter_event_copy (event); /* Treat the release event as the continuation of the last motion, * in case the user keeps the pointer still for a while before * releasing it. */ _time = clutter_event_get_time (event); point->last_delta_time += _time - point->last_motion_time; }
void meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, const ClutterEvent *event) { struct wl_resource *resource; struct wl_list *l; l = &pointer->focus_resource_list; wl_resource_for_each(resource, l) { wl_fixed_t sx, sy; meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy); wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy); }
static void drag_grab_motion (MetaWaylandPointerGrab *grab, const ClutterEvent *event) { MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; wl_fixed_t sx, sy; if (drag_grab->drag_focus_data_device) { meta_wayland_pointer_get_relative_coordinates (grab->pointer, drag_grab->drag_focus, &sx, &sy); wl_data_device_send_motion (drag_grab->drag_focus_data_device, clutter_event_get_time (event), sx, sy); } if (drag_grab->drag_surface) meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), event); }
static void gesture_update_motion_point (GesturePoint *point, ClutterEvent *event) { gfloat motion_x, motion_y; gint64 _time; clutter_event_get_coords (event, &motion_x, &motion_y); clutter_event_free (point->last_event); point->last_event = clutter_event_copy (event); point->last_delta_x = motion_x - point->last_motion_x; point->last_delta_y = motion_y - point->last_motion_y; point->last_motion_x = motion_x; point->last_motion_y = motion_y; _time = clutter_event_get_time (event); point->last_delta_time = _time - point->last_motion_time; point->last_motion_time = _time; }
IO_METHOD(IoClutterEvent, getTime) { return IoDate_newWithTime_(IOSTATE, clutter_event_get_time(IOCEVENT(self))); }
/** * shell_tray_icon_click: * @icon: a #ShellTrayIcon * @event: the #ClutterEvent triggering the fake click * * Fakes a press and release on @icon. @event must be a * %CLUTTER_BUTTON_RELEASE, %CLUTTER_KEY_PRESS or %CLUTTER_KEY_RELEASE event. * Its relevant details will be passed on to the icon, but its * coordinates will be ignored; the click is * always made on the center of @icon. */ void shell_tray_icon_click (ShellTrayIcon *icon, ClutterEvent *event) { XKeyEvent xkevent; XButtonEvent xbevent; XCrossingEvent xcevent; GdkWindow *remote_window; GdkScreen *screen; int x_root, y_root; Display *xdisplay; Window xwindow, xrootwindow; ClutterEventType event_type = clutter_event_type (event); g_return_if_fail (event_type == CLUTTER_BUTTON_RELEASE || event_type == CLUTTER_KEY_PRESS || event_type == CLUTTER_KEY_RELEASE); gdk_error_trap_push (); remote_window = gtk_socket_get_plug_window (GTK_SOCKET (icon->priv->socket)); xwindow = GDK_WINDOW_XID (remote_window); xdisplay = GDK_WINDOW_XDISPLAY (remote_window); screen = gdk_window_get_screen (remote_window); xrootwindow = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); gdk_window_get_origin (remote_window, &x_root, &y_root); /* First make the icon believe the pointer is inside it */ xcevent.type = EnterNotify; xcevent.window = xwindow; xcevent.root = xrootwindow; xcevent.subwindow = None; xcevent.time = clutter_event_get_time (event); xcevent.x = gdk_window_get_width (remote_window) / 2; xcevent.y = gdk_window_get_height (remote_window) / 2; xcevent.x_root = x_root + xcevent.x; xcevent.y_root = y_root + xcevent.y; xcevent.mode = NotifyNormal; xcevent.detail = NotifyNonlinear; xcevent.same_screen = True; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xcevent); /* Now do the click */ if (event_type == CLUTTER_BUTTON_RELEASE) { xbevent.window = xwindow; xbevent.root = xrootwindow; xbevent.subwindow = None; xbevent.time = xcevent.time; xbevent.x = xcevent.x; xbevent.y = xcevent.y; xbevent.x_root = xcevent.x_root; xbevent.y_root = xcevent.y_root; xbevent.state = clutter_event_get_state (event); xbevent.same_screen = True; xbevent.type = ButtonPress; xbevent.button = clutter_event_get_button (event); XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent); xbevent.type = ButtonRelease; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent); } else { xkevent.window = xwindow; xkevent.root = xrootwindow; xkevent.subwindow = None; xkevent.time = xcevent.time; xkevent.x = xcevent.x; xkevent.y = xcevent.y; xkevent.x_root = xcevent.x_root; xkevent.y_root = xcevent.y_root; xkevent.state = clutter_event_get_state (event); xkevent.same_screen = True; xkevent.keycode = clutter_event_get_key_code (event); xkevent.type = KeyPress; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xkevent); if (event_type == CLUTTER_KEY_RELEASE) { /* If the application takes a grab on KeyPress, we don't * want to send it a KeyRelease. There's no good way of * knowing whether a tray icon will take a grab, so just * assume it does, and don't send the KeyRelease. That might * make the tracking for key events messed up if it doesn't take * a grab, but the tray icon won't get key focus in normal cases, * so let's hope this isn't too damaging... */ xkevent.type = KeyRelease; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xkevent); } } /* And move the pointer back out */ xcevent.type = LeaveNotify; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xcevent); gdk_error_trap_pop_ignored (); }
/** * cinnamon_tray_icon_click: * @icon: a #CinnamonTrayIcon * @event: the #ClutterEvent triggering the fake click * * Fakes a press and release on @icon. @event must be a * %CLUTTER_BUTTON_RELEASE event. Its relevant details will be passed * on to the icon, but its coordinates will be ignored; the click is * always made on the center of @icon. */ void cinnamon_tray_icon_click (CinnamonTrayIcon *icon, ClutterEvent *event) { XButtonEvent xbevent; XCrossingEvent xcevent; GdkWindow *remote_window; GdkScreen *screen; int x_root, y_root; Display *xdisplay; Window xwindow, xrootwindow; g_return_if_fail (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE); gdk_error_trap_push (); remote_window = gtk_socket_get_plug_window (GTK_SOCKET (icon->priv->socket)); if (remote_window == NULL) { g_warning ("cinnamon tray: plug window is gone"); gdk_error_trap_pop_ignored (); return; } xwindow = GDK_WINDOW_XID (remote_window); xdisplay = GDK_WINDOW_XDISPLAY (remote_window); screen = gdk_window_get_screen (remote_window); xrootwindow = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); gdk_window_get_origin (remote_window, &x_root, &y_root); /* First make the icon believe the pointer is inside it */ xcevent.type = EnterNotify; xcevent.window = xwindow; xcevent.root = xrootwindow; xcevent.subwindow = None; xcevent.time = clutter_event_get_time (event); xcevent.x = gdk_window_get_width (remote_window) / 2; xcevent.y = gdk_window_get_height (remote_window) / 2; xcevent.x_root = x_root + xcevent.x; xcevent.y_root = y_root + xcevent.y; xcevent.mode = NotifyNormal; xcevent.detail = NotifyNonlinear; xcevent.same_screen = True; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xcevent); /* Now do the click */ xbevent.type = ButtonPress; xbevent.window = xwindow; xbevent.root = xrootwindow; xbevent.subwindow = None; xbevent.time = xcevent.time; xbevent.x = xcevent.x; xbevent.y = xcevent.y; xbevent.x_root = xcevent.x_root; xbevent.y_root = xcevent.y_root; xbevent.state = clutter_event_get_state (event); xbevent.button = clutter_event_get_button (event); xbevent.same_screen = True; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent); xbevent.type = ButtonRelease; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent); /* And move the pointer back out */ xcevent.type = LeaveNotify; XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xcevent); gdk_error_trap_pop_ignored (); }