Ejemplo n.º 1
0
static gboolean
actor_manipulator_motion (ClutterActor *stage,
                          ClutterEvent *event,
                          gpointer      data)
{
  if (manipulated_actor)
    {
      gfloat x;
      gfloat y;
      gfloat dx;
      gfloat dy;

      x =  (event->button.x);
      y =  (event->button.y);

      clutter_actor_transform_stage_point (
        clutter_actor_get_parent (manipulated_actor),
        x, y,
        &x, &y);

      dx = x - start_x;
      dy = y - start_y;

      switch (mode)
        {
#ifdef BOX2D_MANIPULATION
          case Box2D:
          {
            ClutterVertex target = { x, y };
            clutter_box2d_mouse_joint_update_target (mouse_joint, &target);
            break;
          }
#endif

          case Direct:
            if (clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK)
              {
                x = orig_x + dx;
                y = orig_y + dy;

                clutter_actor_set_position (manipulated_actor, x, y);
              }
            else if (clutter_event_get_state (event) & CLUTTER_BUTTON2_MASK)
              {
                clutter_actor_set_rotation (manipulated_actor, CLUTTER_Z_AXIS,
                                             orig_rotation + dx, 0, 0, 0);
              }
            break;

          case None:
            g_print ("we shouldn't be doing %s in None mode\n", G_STRLOC);
            return FALSE;
        }
    }
  return FALSE;
}
Ejemplo n.º 2
0
/**
 * 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);
}
Ejemplo n.º 3
0
static void
emit_drag_end (ClutterDragAction *action,
               ClutterActor      *actor,
               ClutterEvent      *event)
{
  ClutterDragActionPrivate *priv = action->priv;

  clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);

  /* we might not have emitted ::drag-begin yet */
  if (!priv->emit_delayed_press)
    g_signal_emit (action, drag_signals[DRAG_END], 0,
                   actor,
                   priv->last_motion_x, priv->last_motion_y,
                   clutter_event_get_state (event));

  /* disconnect the capture */
  if (priv->capture_id != 0)
    {
      g_signal_handler_disconnect (priv->stage, priv->capture_id);
      priv->capture_id = 0;
    }

  _clutter_stage_set_motion_events_enabled (priv->stage,
                                            priv->motion_events_enabled);

  priv->in_drag = FALSE;
}
Ejemplo n.º 4
0
Archivo: main.c Proyecto: aalex/jasm
gboolean key_press_event(ClutterActor *stage, ClutterEvent *event, gpointer user_data)
{
    UNUSED(user_data);
    guint keyval = clutter_event_get_key_symbol(event);
    ClutterModifierType state = clutter_event_get_state(event);
    gboolean ctrl_pressed = (state & CLUTTER_CONTROL_MASK ? TRUE : FALSE);
    if (keyval == CLUTTER_KEY_Escape)
    {
        if (clutter_stage_get_fullscreen(CLUTTER_STAGE(stage)))
            clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), FALSE);
        else
            clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), TRUE);
    }
    else if (keyval == CLUTTER_KEY_q)
    {
        // Quit application on ctrl-q, this quits the main loop
        // (if there is one)
        if (ctrl_pressed)
        {
            if (option_verbose)
                g_print("ctrl-q pressed. quitting.\n");
            clutter_main_quit();
        }
    }
    return TRUE;
}
Ejemplo n.º 5
0
static void key_event_cb(ClutterActor *actor, ClutterKeyEvent *event, gpointer user_data)
{
    TempiClutterStageNode *self = (TempiClutterStageNode *) user_data;
    (void) self; // TODO: remove this
    ClutterModifierType state = clutter_event_get_state((ClutterEvent*) event);
    bool ctrl_pressed = (state & CLUTTER_CONTROL_MASK ? true : false);
    switch (event->keyval)
    {
        case CLUTTER_KEY_q:
            if (ctrl_pressed)
                clutter_main_quit();
            break;
    }
}
Ejemplo n.º 6
0
static gboolean
key_release_cb (ClutterActor *actor,
                ClutterEvent *event,
                gpointer user_data)
{
  guint keysym = clutter_event_get_key_symbol (event);
  ClutterModifierType mods = clutter_event_get_state (event);

  if (keysym == CLUTTER_KEY_q ||
      ((mods & CLUTTER_SHIFT_MASK) && keysym == CLUTTER_KEY_q))
    clutter_main_quit ();

  return CLUTTER_EVENT_STOP;
}
Ejemplo n.º 7
0
static gboolean
on_captured_event (ClutterActor      *stage,
                   ClutterEvent      *event,
                   ClutterDragAction *action)
{
  ClutterDragActionPrivate *priv = action->priv;
  ClutterActor *actor;
  
  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));

  if (!priv->in_drag)
    return FALSE;

  switch (clutter_event_type (event))
    {
    case CLUTTER_MOTION:
      {
        ClutterModifierType mods = clutter_event_get_state (event);

        /* we might miss a button-release event in case of grabs,
         * so we need to check whether the button is still down
         * during a motion event
         */
        if (mods & CLUTTER_BUTTON1_MASK)
          emit_drag_motion (action, actor, event);
        else
          emit_drag_end (action, actor, event);
      }
      break;

    case CLUTTER_BUTTON_RELEASE:
      if (priv->in_drag)
        emit_drag_end (action, actor, event);
      break;

    case CLUTTER_ENTER:
    case CLUTTER_LEAVE:
      if (priv->in_drag)
        return TRUE;
      break;

    default:
      break;
    }

  return FALSE;
}
Ejemplo n.º 8
0
static gboolean on_key_release(ClutterActor *actor, ClutterEvent *event, MosesOverview* self)
{
    MosesOverviewPrivate* priv = self->priv;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    MetaDisplay* display = meta_screen_get_display(screen);
    ClutterModifierType state = clutter_event_get_state(event);
    g_debug("%s", __func__);

    if (priv->ready) {
        guint action = meta_display_get_keybinding_action(display, clutter_event_get_key_code(event), state);
        if (action == elsa_wm_get_action(ELSA_WM_PLUGIN(priv->plugin), "expose-windows")) {
            overview_animated_destroy(self, MOSES_OV_REASON_NORMAL, FALSE);
            return TRUE;
        }
    }

    return FALSE;
}
Ejemplo n.º 9
0
static gboolean
button_event_cb (ClutterActor *actor,
                 ClutterEvent *event,
                 gpointer      user_data)
{
  gfloat x, y;
  gchar *event_type;
  guint button_pressed;
  ClutterModifierType state;
  gchar *ctrl_pressed;
  guint32 click_count;

  /* where the pointer was when the button event occurred */
  clutter_event_get_coords (event, &x, &y);

  /* check whether it was a press or release event */
  event_type = "released";
  if (clutter_event_type (event) == CLUTTER_BUTTON_PRESS)
    event_type = "pressed";

  /* which button triggered the event */
  button_pressed = clutter_event_get_button (event);

  /* keys down when the button was pressed */
  state = clutter_event_get_state (event);

  ctrl_pressed = "ctrl not pressed";
  if (state & CLUTTER_CONTROL_MASK)
    ctrl_pressed = "ctrl pressed";

  /* click count */
  click_count = clutter_event_get_click_count (event);

  g_debug ("button %d %s at %.0f,%.0f; %s; click count %d",
           button_pressed,
           event_type,
           x,
           y,
           ctrl_pressed,
           click_count);

  return TRUE;
}
Ejemplo n.º 10
0
static gboolean
on_button_press (ClutterActor      *actor,
                 ClutterEvent      *event,
                 ClutterDragAction *action)
{
  ClutterDragActionPrivate *priv = action->priv;

  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
    return FALSE;

  if (clutter_event_get_button (event) != 1)
    return FALSE;

  if (priv->stage == NULL)
    priv->stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));

  clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
  priv->press_state = clutter_event_get_state (event);

  priv->last_motion_x = priv->press_x;
  priv->last_motion_y = priv->press_y;

  priv->transformed_press_x = priv->press_x;
  priv->transformed_press_y = priv->press_y;
  clutter_actor_transform_stage_point (actor, priv->press_x, priv->press_y,
                                       &priv->transformed_press_x,
                                       &priv->transformed_press_y);

  priv->motion_events_enabled =
    _clutter_stage_get_motion_events_enabled (priv->stage);

  if (priv->x_drag_threshold == 0 || priv->y_drag_threshold == 0)
    emit_drag_begin (action, actor, event);
  else
    priv->emit_delayed_press = TRUE;

  priv->in_drag = TRUE;
  priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
                                             G_CALLBACK (on_captured_event),
                                             action);

  return FALSE;
}
Ejemplo n.º 11
0
//FIXME: actually key_release is activated even when key press (WTF). does it because I'm hold alt/super?
static gboolean on_key_release(ClutterActor *actor, ClutterEvent *event, MetaSwitcher* self)
{
    MetaSwitcherPrivate* priv = self->priv;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    MetaDisplay* display = meta_screen_get_display(screen);

    ClutterModifierType state = clutter_event_get_state(event);
    guint keysym = clutter_event_get_key_symbol(event);
    guint action = meta_display_get_keybinding_action(display, clutter_event_get_key_code(event), state);

    int id = priv->selected_id;
    if (action == META_KEYBINDING_ACTION_SWITCH_WINDOWS) {
        id = (id + 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD) {
        id = (priv->apps->len + id - 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS) {
        id = (id + 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD) {
        id = (priv->apps->len + id - 1) % priv->apps->len;
    }
    _set_highlight(self, priv->selected_id, FALSE);
    _set_highlight(self, id, TRUE);
    g_debug("%s, key: 0x%x, action: %d, previd: %d, now: %d", __func__, keysym, action,
            priv->selected_id, id);
    priv->selected_id = id;

    switch(keysym) {
        //FIXME: do not hardcode keysyms, use action instead
        case CLUTTER_KEY_Super_L:
        case CLUTTER_KEY_Super_R:
        case CLUTTER_KEY_Alt_L:
        case CLUTTER_KEY_Alt_R:
        {
            if (priv->selected_id >= 0) {
                meta_window_activate(g_ptr_array_index(priv->apps, priv->selected_id), clutter_get_current_event_time());
            }
            g_object_unref(self);
        }
        default: break;
    }

    return FALSE;
}
Ejemplo n.º 12
0
/* An event was captured */
static gboolean _xfdashboard_click_action_on_captured_event(XfdashboardClickAction *self,
        ClutterEvent *inEvent,
        gpointer inUserData)
{
    XfdashboardClickActionPrivate	*priv;
    ClutterActor					*stage G_GNUC_UNUSED;
    ClutterActor					*actor;
    ClutterModifierType				modifierState;
    gboolean						hasButton;

    g_return_val_if_fail(XFDASHBOARD_IS_CLICK_ACTION(self), CLUTTER_EVENT_PROPAGATE);
    g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE);

    priv=self->priv;
    stage=CLUTTER_ACTOR(inUserData);
    hasButton=TRUE;

    /* Handle captured event */
    actor=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self));
    switch(clutter_event_type(inEvent))
    {
    case CLUTTER_TOUCH_END:
        hasButton=FALSE;

    case CLUTTER_BUTTON_RELEASE:
        if(!priv->isHeld) return(CLUTTER_EVENT_STOP);

        if((hasButton && clutter_event_get_button(inEvent)!=priv->pressButton) ||
                (hasButton && clutter_event_get_click_count(inEvent)!=1) ||
                clutter_event_get_device_id(inEvent)!=priv->pressDeviceID ||
                clutter_event_get_event_sequence(inEvent)!=priv->pressSequence)
        {
            return(CLUTTER_EVENT_PROPAGATE);
        }

        _xfdashboard_click_action_set_held(self, FALSE);
        _xfdashboard_click_action_cancel_long_press(self);

        /* Disconnect the capture */
        if(priv->captureID!=0)
        {
            g_signal_handler_disconnect(priv->stage, priv->captureID);
            priv->captureID = 0;
        }

        if(priv->longPressID!=0)
        {
            g_source_remove(priv->longPressID);
            priv->longPressID=0;
        }

        if(!clutter_actor_contains(actor, clutter_event_get_source(inEvent)))
        {
            return(CLUTTER_EVENT_PROPAGATE);
        }

        /* Exclude any button-mask so that we can compare
         * the press and release states properly
         */
        modifierState=clutter_event_get_state(inEvent) &
                      ~(CLUTTER_BUTTON1_MASK |
                        CLUTTER_BUTTON2_MASK |
                        CLUTTER_BUTTON3_MASK |
                        CLUTTER_BUTTON4_MASK |
                        CLUTTER_BUTTON5_MASK);

        /* If press and release states don't match we simply ignore
         * modifier keys. i.e. modifier keys are expected to be pressed
         * throughout the whole click
         */
        if(modifierState!=priv->modifierState) priv->modifierState=0;

        _xfdashboard_click_action_set_pressed(self, FALSE);
        g_signal_emit(self, XfdashboardClickActionSignals[SIGNAL_CLICKED], 0, actor);
        break;

    case CLUTTER_MOTION:
    case CLUTTER_TOUCH_UPDATE:
    {
        gfloat				motionX, motionY;
        gfloat				deltaX, deltaY;

        if(!priv->isHeld) return(CLUTTER_EVENT_PROPAGATE);

        clutter_event_get_coords (inEvent, &motionX, &motionY);

        deltaX=ABS(motionX-priv->pressX);
        deltaY=ABS(motionY-priv->pressY);

        if(deltaX>priv->dragThreshold || deltaY>priv->dragThreshold)
        {
            _xfdashboard_click_action_cancel_long_press(self);
        }
    }
    break;

    default:
        break;
    }

    /* This is line changed in returning CLUTTER_EVENT_PROPAGATE
     * instead of CLUTTER_EVENT_STOP
     */
    return(CLUTTER_EVENT_PROPAGATE);
}
Ejemplo n.º 13
0
static gboolean
on_captured_event (ClutterActor       *stage,
                   ClutterEvent       *event,
                   ClutterClickAction *action)
{
  ClutterClickActionPrivate *priv = action->priv;
  ClutterActor *actor;
  ClutterModifierType modifier_state;
  gboolean has_button = TRUE;

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));

  switch (clutter_event_type (event))
    {
    case CLUTTER_TOUCH_END:
      has_button = FALSE;
    case CLUTTER_BUTTON_RELEASE:
      if (!priv->is_held)
        return CLUTTER_EVENT_STOP;

      if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
          (has_button && clutter_event_get_click_count (event) != 1) ||
          clutter_event_get_device_id (event) != priv->press_device_id ||
          clutter_event_get_event_sequence (event) != priv->press_sequence)
        return CLUTTER_EVENT_PROPAGATE;

      click_action_set_held (action, FALSE);
      click_action_cancel_long_press (action);

      /* disconnect the capture */
      if (priv->capture_id != 0)
        {
          g_signal_handler_disconnect (priv->stage, priv->capture_id);
          priv->capture_id = 0;
        }

      if (priv->long_press_id != 0)
        {
          g_source_remove (priv->long_press_id);
          priv->long_press_id = 0;
        }

      if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
        return CLUTTER_EVENT_PROPAGATE;

      /* exclude any button-mask so that we can compare
       * the press and release states properly */
      modifier_state = clutter_event_get_state (event) &
                       ~(CLUTTER_BUTTON1_MASK |
                         CLUTTER_BUTTON2_MASK |
                         CLUTTER_BUTTON3_MASK |
                         CLUTTER_BUTTON4_MASK |
                         CLUTTER_BUTTON5_MASK);

      /* if press and release states don't match we
       * simply ignore modifier keys. i.e. modifier keys
       * are expected to be pressed throughout the whole
       * click */
      if (modifier_state != priv->modifier_state)
        priv->modifier_state = 0;

      click_action_set_pressed (action, FALSE);
      g_signal_emit (action, click_signals[CLICKED], 0, actor);
      break;

    case CLUTTER_MOTION:
    case CLUTTER_TOUCH_UPDATE:
      {
        gfloat motion_x, motion_y;
        gfloat delta_x, delta_y;

        if (!priv->is_held)
          return CLUTTER_EVENT_PROPAGATE;

        clutter_event_get_coords (event, &motion_x, &motion_y);

        delta_x = ABS (motion_x - priv->press_x);
        delta_y = ABS (motion_y - priv->press_y);

        if (delta_x > priv->drag_threshold ||
            delta_y > priv->drag_threshold)
          click_action_cancel_long_press (action);
      }
      break;

    default:
      break;
    }

  return CLUTTER_EVENT_STOP;
}
Ejemplo n.º 14
0
static gboolean
on_event (ClutterActor       *actor,
          ClutterEvent       *event,
          ClutterClickAction *action)
{
  ClutterClickActionPrivate *priv = action->priv;
  gboolean has_button = TRUE;

  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
    return CLUTTER_EVENT_PROPAGATE;

  switch (clutter_event_type (event))
    {
    case CLUTTER_TOUCH_BEGIN:
      has_button = FALSE;
    case CLUTTER_BUTTON_PRESS:
      if (has_button && clutter_event_get_click_count (event) != 1)
        return CLUTTER_EVENT_PROPAGATE;

      if (priv->is_held)
        return CLUTTER_EVENT_STOP;

      if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
        return CLUTTER_EVENT_PROPAGATE;

      priv->press_button = has_button ? clutter_event_get_button (event) : 0;
      priv->press_device_id = clutter_event_get_device_id (event);
      priv->press_sequence = clutter_event_get_event_sequence (event);
      priv->modifier_state = clutter_event_get_state (event);
      clutter_event_get_coords (event, &priv->press_x, &priv->press_y);

      if (priv->long_press_threshold < 0)
        {
          ClutterSettings *settings = clutter_settings_get_default ();

          g_object_get (settings,
                        "dnd-drag-threshold", &priv->drag_threshold,
                        NULL);
        }
      else
        priv->drag_threshold = priv->long_press_threshold;

      if (priv->stage == NULL)
        priv->stage = clutter_actor_get_stage (actor);

      priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
                                                 G_CALLBACK (on_captured_event),
                                                 action);

      click_action_set_pressed (action, TRUE);
      click_action_set_held (action, TRUE);
      click_action_query_long_press (action);
      break;

    case CLUTTER_ENTER:
      click_action_set_pressed (action, priv->is_held);
      break;

    case CLUTTER_LEAVE:
      click_action_set_pressed (action, priv->is_held);
      click_action_cancel_long_press (action);
      break;

    default:
      break;
    }

  return CLUTTER_EVENT_PROPAGATE;
}
Ejemplo n.º 15
0
/**
 * 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 ();
}
Ejemplo n.º 16
0
/**
 * cinnamon_get_event_state:
 * @event: a #ClutterEvent
 *
 * Gets the current state of the event (the set of modifier keys that
 * are pressed down). Thhis is a wrapper around
 * clutter_event_get_state() that strips out any un-declared modifier
 * flags, to make gjs happy; see
 * https://bugzilla.gnome.org/show_bug.cgi?id=597292.
 *
 * Return value: the state from the event
 */
ClutterModifierType
cinnamon_get_event_state (ClutterEvent *event)
{
  ClutterModifierType state = clutter_event_get_state (event);
  return state & CLUTTER_MODIFIER_MASK;
}
Ejemplo n.º 17
0
/**
 * clutter_event_has_control_modifier:
 * @event: a #ClutterEvent
 *
 * Checks whether @event has the Control modifier mask set.
 *
 * Return value: %TRUE if the event has the Control modifier mask set
 *
 * Since: 1.12
 */
gboolean
clutter_event_has_control_modifier (const ClutterEvent *event)
{
  return (clutter_event_get_state (event) & CLUTTER_CONTROL_MASK) != FALSE;
}
Ejemplo n.º 18
0
/**
 * clutter_event_has_shift_modifier:
 * @event: a #ClutterEvent
 *
 * Checks whether @event has the Shift modifier mask set.
 *
 * Return value: %TRUE if the event has the Shift modifier mask set
 *
 * Since: 1.12
 */
gboolean
clutter_event_has_shift_modifier (const ClutterEvent *event)
{
  return (clutter_event_get_state (event) & CLUTTER_SHIFT_MASK) != FALSE;
}
Ejemplo n.º 19
0
static gboolean
stage_captured_event_cb (ClutterActor         *stage,
                         ClutterEvent         *event,
                         ClutterGestureAction *action)
{
  ClutterGestureActionPrivate *priv = action->priv;
  ClutterActor *actor;
  gint position;
  float threshold_x, threshold_y;
  gboolean return_value;
  GesturePoint *point;
  ClutterEventType event_type;

  event_type = clutter_event_type (event);
  if (event_type != CLUTTER_TOUCH_CANCEL &&
      event_type != CLUTTER_TOUCH_UPDATE &&
      event_type != CLUTTER_TOUCH_END &&
      event_type != CLUTTER_MOTION &&
      event_type != CLUTTER_BUTTON_RELEASE)
    return CLUTTER_EVENT_PROPAGATE;

  if ((point = gesture_find_point (action, event, &position)) == NULL)
    return CLUTTER_EVENT_PROPAGATE;

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));

  switch (clutter_event_type (event))
    {
    case CLUTTER_MOTION:
      {
        ClutterModifierType mods = clutter_event_get_state (event);

        /* we might miss a button-release event in case of grabs,
         * so we need to check whether the button is still down
         * during a motion event
         */
        if (!(mods & CLUTTER_BUTTON1_MASK))
          {
            cancel_gesture (action);
            return CLUTTER_EVENT_PROPAGATE;
          }
      }
      /* Follow same code path as a touch event update */

    case CLUTTER_TOUCH_UPDATE:
      if (!priv->in_gesture)
        {
          if (priv->points->len < priv->requested_nb_points)
            {
              gesture_update_motion_point (point, event);
              return CLUTTER_EVENT_PROPAGATE;
            }

          /* Wait until the drag threshold has been exceeded
           * before starting _TRIGGER_EDGE_AFTER gestures. */
          if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER &&
              gesture_point_pass_threshold (action, point, event))
            {
              gesture_update_motion_point (point, event);
              return CLUTTER_EVENT_PROPAGATE;
            }

          if (!begin_gesture (action, actor))
            {
              if ((point = gesture_find_point (action, event, &position)) != NULL)
                gesture_update_motion_point (point, event);
              return CLUTTER_EVENT_PROPAGATE;
            }

          if ((point = gesture_find_point (action, event, &position)) == NULL)
            return CLUTTER_EVENT_PROPAGATE;
        }

      gesture_update_motion_point (point, event);

      g_signal_emit (action, gesture_signals[GESTURE_PROGRESS], 0, actor,
                     &return_value);
      if (!return_value)
        {
          cancel_gesture (action);
          return CLUTTER_EVENT_PROPAGATE;
        }

      /* Check if a _TRIGGER_EDGE_BEFORE gesture needs to be cancelled because
       * the drag threshold has been exceeded. */
      clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
      if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE &&
          ((fabsf (point->press_y - point->last_motion_y) > threshold_y) ||
           (fabsf (point->press_x - point->last_motion_x) > threshold_x)))
        {
          cancel_gesture (action);
          return CLUTTER_EVENT_PROPAGATE;
        }
      break;

    case CLUTTER_BUTTON_RELEASE:
    case CLUTTER_TOUCH_END:
      {
        gesture_update_release_point (point, event);

        if (priv->in_gesture &&
            ((priv->points->len - 1) < priv->requested_nb_points))
          {
            priv->in_gesture = FALSE;
            g_signal_emit (action, gesture_signals[GESTURE_END], 0, actor);
          }

        gesture_unregister_point (action, position);
      }
      break;

    case CLUTTER_TOUCH_CANCEL:
      {
        gesture_update_release_point (point, event);

        if (priv->in_gesture)
          {
            priv->in_gesture = FALSE;
            cancel_gesture (action);
          }

        gesture_unregister_point (action, position);
      }
      break;

    default:
      break;
    }

  if (priv->points->len == 0 && priv->stage_capture_id)
    {
      g_signal_handler_disconnect (priv->stage, priv->stage_capture_id);
      priv->stage_capture_id = 0;
    }

  return CLUTTER_EVENT_PROPAGATE;
}
Ejemplo n.º 20
0
/**
 * 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 ();
}
Ejemplo n.º 21
0
IO_METHOD(IoClutterEvent, getState) {
  return IONUMBER(clutter_event_get_state(IOCEVENT(self)));
}
Ejemplo n.º 22
0
/* An event was received */
static gboolean _xfdashboard_click_action_on_event(XfdashboardClickAction *self, ClutterEvent *inEvent, gpointer inUserData)
{
    XfdashboardClickActionPrivate	*priv;
    gboolean						hasButton;
    ClutterActor					*actor;

    g_return_val_if_fail(XFDASHBOARD_IS_CLICK_ACTION(self), CLUTTER_EVENT_PROPAGATE);
    g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE);

    priv=self->priv;
    hasButton=TRUE;
    actor=CLUTTER_ACTOR(inUserData);

    /* Check if actor is enabled to handle events */
    if(!clutter_actor_meta_get_enabled(CLUTTER_ACTOR_META(self))) return(CLUTTER_EVENT_PROPAGATE);

    /* Handle event */
    switch(clutter_event_type(inEvent))
    {
    case CLUTTER_TOUCH_BEGIN:
        hasButton=FALSE;

    case CLUTTER_BUTTON_PRESS:
        /* We only handle single clicks if it is pointer device */
        if(hasButton && clutter_event_get_click_count(inEvent)!=1)
        {
            return(CLUTTER_EVENT_PROPAGATE);
        }

        /* Do we already held the press? */
        if(priv->isHeld) return(CLUTTER_EVENT_STOP);

        /* Is the source of event a child of this actor. If not do
         * not handle this event but any other.
         */
        if(!clutter_actor_contains(actor, clutter_event_get_source(inEvent)))
        {
            return(CLUTTER_EVENT_PROPAGATE);
        }

        /* Remember event data */
        priv->pressButton=hasButton ? clutter_event_get_button(inEvent) : 0;
        priv->pressDeviceID=clutter_event_get_device_id(inEvent);
        priv->pressSequence=clutter_event_get_event_sequence(inEvent);
        priv->modifierState=clutter_event_get_state(inEvent);
        clutter_event_get_coords(inEvent, &priv->pressX, &priv->pressY);

        if(priv->longPressThreshold<0)
        {
            ClutterSettings		*settings=clutter_settings_get_default();

            g_object_get(settings, "dnd-drag-threshold", &priv->dragThreshold, NULL);
        }
        else priv->dragThreshold=priv->longPressThreshold;

        if(priv->stage==NULL) priv->stage=clutter_actor_get_stage(actor);

        /* Connect signals */
        priv->captureID=g_signal_connect_object(priv->stage,
                                                "captured-event",
                                                G_CALLBACK(_xfdashboard_click_action_on_captured_event),
                                                self,
                                                G_CONNECT_AFTER | G_CONNECT_SWAPPED);

        /* Set state of this action */
        _xfdashboard_click_action_set_pressed(self, TRUE);
        _xfdashboard_click_action_set_held(self, TRUE);
        _xfdashboard_click_action_query_long_press(self);
        break;

    case CLUTTER_ENTER:
        _xfdashboard_click_action_set_pressed(self, priv->isHeld);
        break;

    case CLUTTER_LEAVE:
        _xfdashboard_click_action_set_pressed(self, priv->isHeld);
        _xfdashboard_click_action_cancel_long_press(self);
        break;

    default:
        break;
    }

    return(CLUTTER_EVENT_PROPAGATE);
}