Пример #1
0
static void
window_grab_broken_cb (GSWindow           *window,
                       GdkEventGrabBroken *event,
                       GSManager          *manager)
{
	GdkDisplay *display;
	GdkSeat    *seat;
	GdkDevice  *device;

	display = gdk_window_get_display (gs_window_get_gdk_window (window));
	seat = gdk_display_get_default_seat (display);

	if (event->keyboard)
	{
		gs_debug ("KEYBOARD GRAB BROKEN!");
		device = gdk_seat_get_pointer (seat);
		if (!gdk_display_device_is_grabbed (display, device))
			gs_grab_reset (manager->priv->grab);
	}
	else
	{
		gs_debug ("POINTER GRAB BROKEN!");
		device = gdk_seat_get_keyboard (seat);
		if (!gdk_display_device_is_grabbed (display, device))
			gs_grab_reset (manager->priv->grab);
	}
}
Пример #2
0
static gboolean
maybe_redirect_mouse_event (XEvent *xevent)
{
  GdkDisplay *gdisplay;
  MetaUI *ui;
#if GTK_CHECK_VERSION (3, 0, 0)
  GdkDeviceManager *gmanager;
  GdkDevice *gdevice;
  GdkEvent *gevent;
#else
  GdkEvent gevent;
#endif
  GdkWindow *gdk_window;
  Window window;

  switch (xevent->type)
    {
    case ButtonPress:
    case ButtonRelease:
      window = xevent->xbutton.window;
      break;
    case MotionNotify:
      window = xevent->xmotion.window;
      break;
    case EnterNotify:
    case LeaveNotify:
      window = xevent->xcrossing.window;
      break;
    default:
      return FALSE;
    }

  gdisplay = gdk_x11_lookup_xdisplay (xevent->xany.display);
  ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
  if (!ui)
    return FALSE;

#if GTK_CHECK_VERSION (3, 0, 0)
  gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
#else
  gdk_window = gdk_window_lookup_for_display (gdisplay, window);
#endif
  if (gdk_window == NULL)
    return FALSE;

#if GTK_CHECK_VERSION (3, 0, 0)
  gmanager = gdk_display_get_device_manager (gdisplay);
  gdevice = gdk_device_manager_get_client_pointer (gmanager);
#endif

  /* If GDK already thinks it has a grab, we better let it see events; this
   * is the menu-navigation case and events need to get sent to the appropriate
   * (client-side) subwindow for individual menu items.
   */
#if GTK_CHECK_VERSION (3, 0, 0)
  if (gdk_display_device_is_grabbed (gdisplay, gdevice))
#else
  if (gdk_display_pointer_is_grabbed (gdisplay))
#endif
    return FALSE;

#if !GTK_CHECK_VERSION (3, 0, 0)
  memset (&gevent, 0, sizeof (gevent));
#endif

  switch (xevent->type)
    {
    case ButtonPress:
    case ButtonRelease:
      if (xevent->type == ButtonPress)
        {
          GtkSettings *settings = gtk_settings_get_default ();
          int double_click_time;
          int double_click_distance;

          g_object_get (settings,
                        "gtk-double-click-time", &double_click_time,
                        "gtk-double-click-distance", &double_click_distance,
                        NULL);

          if (xevent->xbutton.button == ui->button_click_number &&
              xevent->xbutton.window == ui->button_click_window &&
              xevent->xbutton.time < ui->button_click_time + double_click_time &&
              ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance &&
              ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance)
            {
#if GTK_CHECK_VERSION (3, 0, 0)
              gevent = gdk_event_new (GDK_2BUTTON_PRESS);
#else
              gevent.button.type = GDK_2BUTTON_PRESS;
#endif

              ui->button_click_number = 0;
            }
          else
            {
#if GTK_CHECK_VERSION (3, 0, 0)
              gevent = gdk_event_new (GDK_BUTTON_PRESS);
#else
              gevent.button.type = GDK_BUTTON_PRESS;
#endif
              ui->button_click_number = xevent->xbutton.button;
              ui->button_click_window = xevent->xbutton.window;
              ui->button_click_time = xevent->xbutton.time;
              ui->button_click_x = xevent->xbutton.x;
              ui->button_click_y = xevent->xbutton.y;
            }
        }
      else
        {
#if GTK_CHECK_VERSION (3, 0, 0)
          gevent = gdk_event_new (GDK_BUTTON_RELEASE);
#else
          gevent.button.type = GDK_BUTTON_RELEASE;
#endif
        }

#if GTK_CHECK_VERSION (3, 0, 0)
      gevent->button.window = g_object_ref (gdk_window);
      gevent->button.button = xevent->xbutton.button;
      gevent->button.time = xevent->xbutton.time;
      gevent->button.x = xevent->xbutton.x;
      gevent->button.y = xevent->xbutton.y;
      gevent->button.x_root = xevent->xbutton.x_root;
      gevent->button.y_root = xevent->xbutton.y_root;
#else
      gevent.button.window = gdk_window;
      gevent.button.button = xevent->xbutton.button;
      gevent.button.time = xevent->xbutton.time;
      gevent.button.x = xevent->xbutton.x;
      gevent.button.y = xevent->xbutton.y;
      gevent.button.x_root = xevent->xbutton.x_root;
      gevent.button.y_root = xevent->xbutton.y_root;
#endif

      break;
    case MotionNotify:
#if GTK_CHECK_VERSION (3, 0, 0)
      gevent = gdk_event_new (GDK_MOTION_NOTIFY);
      gevent->motion.type = GDK_MOTION_NOTIFY;
      gevent->motion.window = g_object_ref (gdk_window);
#else
      gevent.motion.type = GDK_MOTION_NOTIFY;
      gevent.motion.window = gdk_window;
#endif
      break;
    case EnterNotify:
    case LeaveNotify:
#if GTK_CHECK_VERSION (3, 0, 0)
      gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
      gevent->crossing.window = g_object_ref (gdk_window);
      gevent->crossing.x = xevent->xcrossing.x;
      gevent->crossing.y = xevent->xcrossing.y;
#else
      gevent.crossing.type = xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
      gevent.crossing.window = gdk_window;
      gevent.crossing.x = xevent->xcrossing.x;
      gevent.crossing.y = xevent->xcrossing.y;
#endif
      break;
    default:
      g_assert_not_reached ();
      break;
    }

  /* If we've gotten here, we've filled in the gdk_event and should send it on */
#if GTK_CHECK_VERSION (3, 0, 0)
  gdk_event_set_device (gevent, gdevice);
  gtk_main_do_event (gevent);
  gdk_event_free (gevent);
#else
  gtk_main_do_event (&gevent);
#endif

  return TRUE;
}
Пример #3
0
Файл: ui.c Проект: darkxst/mtest
static gboolean
maybe_redirect_mouse_event (XEvent *xevent)
{
  GdkDisplay *gdisplay;
  GdkDeviceManager *gmanager;
  GdkDevice *gdevice;
  MetaUI *ui;
  GdkEvent *gevent;
  GdkWindow *gdk_window;
  Window window;
  XIEvent *xev;
  XIDeviceEvent *xev_d = NULL;
  XIEnterEvent *xev_e = NULL;

  if (!is_input_event (xevent))
    return FALSE;

  xev = (XIEvent *) xevent->xcookie.data;

  switch (xev->evtype)
    {
    case XI_TouchBegin:
    case XI_ButtonPress:
    case XI_ButtonRelease:
    case XI_Motion:
      xev_d = (XIDeviceEvent *) xev;
      window = xev_d->event;
      break;
    case XI_Enter:
    case XI_Leave:
      xev_e = (XIEnterEvent *) xev;
      window = xev_e->event;
      break;
    default:
      return FALSE;
    }

  gdisplay = gdk_x11_lookup_xdisplay (xev->display);
  ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
  if (!ui)
    return FALSE;

  gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
  if (gdk_window == NULL)
    return FALSE;

  gmanager = gdk_display_get_device_manager (gdisplay);
  gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);

  /* If GDK already thinks it has a grab, we better let it see events; this
   * is the menu-navigation case and events need to get sent to the appropriate
   * (client-side) subwindow for individual menu items.
   */
  if (gdk_display_device_is_grabbed (gdisplay, gdevice))
    return FALSE;

  switch (xev->evtype)
    {
    case XI_TouchBegin:
    case XI_ButtonPress:
    case XI_ButtonRelease:
      if (xev_d->evtype == XI_ButtonPress || xev_d->evtype == XI_TouchBegin)
        {
          GtkSettings *settings = gtk_settings_get_default ();
          int double_click_time;
          int double_click_distance;
          int button;

          g_object_get (settings,
                        "gtk-double-click-time", &double_click_time,
                        "gtk-double-click-distance", &double_click_distance,
                        NULL);

          if (xev->evtype == XI_TouchBegin)
            button = 1;
          else
            button = xev_d->detail;

          if (button == ui->button_click_number &&
              xev_d->event == ui->button_click_window &&
              xev_d->time < ui->button_click_time + double_click_time &&
              ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance &&
              ABS (xev_d->event_y - ui->button_click_y) <= double_click_distance)
            {
              gevent = gdk_event_new (GDK_2BUTTON_PRESS);

              ui->button_click_number = 0;
            }
          else
            {
              gevent = gdk_event_new (GDK_BUTTON_PRESS);
              ui->button_click_number = button;
              ui->button_click_window = xev_d->event;
              ui->button_click_time = xev_d->time;
              ui->button_click_x = xev_d->event_x;
              ui->button_click_y = xev_d->event_y;
            }

          gevent->button.button = button;
        }
      else
        {
          gevent = gdk_event_new (GDK_BUTTON_RELEASE);
          gevent->button.button = xev_d->detail;
        }

      gevent->button.window = g_object_ref (gdk_window);
      gevent->button.time = xev_d->time;
      gevent->button.x = xev_d->event_x;
      gevent->button.y = xev_d->event_y;
      gevent->button.x_root = xev_d->root_x;
      gevent->button.y_root = xev_d->root_y;

      break;
    case XI_Motion:
      gevent = gdk_event_new (GDK_MOTION_NOTIFY);
      gevent->motion.type = GDK_MOTION_NOTIFY;
      gevent->motion.window = g_object_ref (gdk_window);
      break;
    case XI_Enter:
    case XI_Leave:
      gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
      gevent->crossing.window = g_object_ref (gdk_window);
      gevent->crossing.x = xev_e->event_x;
      gevent->crossing.y = xev_e->event_y;
      break;
    default:
      g_assert_not_reached ();
      break;
    }

  /* If we've gotten here, we've created the gdk_event and should send it on */
  gdk_event_set_device (gevent, gdevice);
  gtk_main_do_event (gevent);
  gdk_event_free (gevent);

  return TRUE;
}