示例#1
0
/**
 * meta_compositor_process_event: (skip)
 * @compositor:
 * @event:
 * @window:
 *
 */
gboolean
meta_compositor_process_event (MetaCompositor *compositor,
                               XEvent         *event,
                               MetaWindow     *window)
{
  if (!meta_is_wayland_compositor () &&
      event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
    {
      /* Core code doesn't handle damage events, so we need to extract the MetaWindow
       * ourselves
       */
      if (window == NULL)
        {
          Window xwin = ((XDamageNotifyEvent *) event)->drawable;
          window = meta_display_lookup_x_window (compositor->display, xwin);
        }

      if (window)
        process_damage (compositor, (XDamageNotifyEvent *) event, window);
    }

  if (compositor->have_x11_sync_object)
    meta_sync_ring_handle_event (event);

  /* Clutter needs to know about MapNotify events otherwise it will
     think the stage is invisible */
  if (!meta_is_wayland_compositor () && event->type == MapNotify)
    clutter_x11_handle_event (event);

  /* The above handling is basically just "observing" the events, so we return
   * FALSE to indicate that the event should not be filtered out; if we have
   * GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
   */
  return FALSE;
}
示例#2
0
static void
handle_host_xevent (MetaBackend *backend,
                    XEvent      *event)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  gboolean bypass_clutter = FALSE;

  XGetEventData (priv->xdisplay, &event->xcookie);

  {
    MetaDisplay *display = meta_get_display ();

    if (display)
      {
        MetaCompositor *compositor = display->compositor;
        if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
          bypass_clutter = TRUE;
      }
  }

  if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
    handle_alarm_notify (backend, event);

  if (event->type == priv->xkb_event_base)
    {
      XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;

      if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
        {
          switch (xkb_ev->xkb_type)
            {
            case XkbNewKeyboardNotify:
            case XkbMapNotify:
              keymap_changed (backend);
            default:
              break;
            }
        }
    }

  {
    MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
    if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
        meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
      bypass_clutter = TRUE;
  }

  if (!bypass_clutter)
    {
      handle_input_event (x11, event);
      clutter_x11_handle_event (event);
    }

  XFreeEventData (priv->xdisplay, &event->xcookie);
}
示例#3
0
gboolean
_meta_plugin_xevent_filter (MetaPlugin *plugin,
                            XEvent     *xev)
{
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);

  if (klass->xevent_filter && klass->xevent_filter (plugin, xev))
    return TRUE;
  else
    return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}
示例#4
0
static GdkFilterReturn
event_filter (GdkXEvent *xevent,
              GdkEvent  *event,
              gpointer   data)
{
  XEvent *xev = (XEvent *)xevent;

  if (clutter_x11_handle_event (xev) == CLUTTER_X11_FILTER_CONTINUE)
    return GDK_FILTER_CONTINUE;
  else
    return GDK_FILTER_REMOVE;
}
static GdkFilterReturn
gdk_to_clutter_event_pump__ (GdkXEvent *xevent,
                             GdkEvent  *event,
                             gpointer   data)
{
  GdkDisplay *display = gdk_display_get_default ();
  GdkWindow *gdk_win;

  XEvent *xev = (XEvent*) xevent;
  guint32 timestamp = 0;

  gdk_win = gdk_x11_window_foreign_new_for_display (display, xev->xany.window);

  if (!gdk_win)
    gdk_win = gdk_x11_window_foreign_new_for_display (display,
                                                      GPOINTER_TO_INT (data));

  /*
   * Ensure we update the user time on this window if the event
   * implies user action.
   */
  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
    case GDK_2BUTTON_PRESS:
      case GDK_3BUTTON_PRESS:
    case GDK_BUTTON_RELEASE:
      timestamp = event->button.time;
      break;
    case GDK_MOTION_NOTIFY:
      timestamp = event->motion.time;
      break;
    case GDK_KEY_PRESS:
    case GDK_KEY_RELEASE:
      timestamp = event->key.time;
      break;
    default: ;
    }

  if (timestamp && gdk_win)
    gdk_x11_window_set_user_time (gdk_win, timestamp);

  switch (clutter_x11_handle_event (xev))
    {
    default:
    case CLUTTER_X11_FILTER_CONTINUE:
      return GDK_FILTER_CONTINUE;
    case CLUTTER_X11_FILTER_TRANSLATE:
      return GDK_FILTER_TRANSLATE;
    case CLUTTER_X11_FILTER_REMOVE:
      return GDK_FILTER_REMOVE;
    }
};
示例#6
0
/*
 * The public method that the compositor hooks into for desktop switching.
 *
 * Returns TRUE if at least one of the plugins handled the event type (i.e.,
 * if the return value is FALSE, there will be no subsequent call to the
 * manager completed() callback, and the compositor must ensure that any
 * appropriate post-effect cleanup is carried out.
 */
gboolean
meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
                                   XEvent            *xev)
{
  GList *l;
  gboolean have_plugin_xevent_func;

  if (!plugin_mgr)
    return FALSE;

  l = plugin_mgr->plugins;

  /* We need to make sure that clutter gets certain events, like
   * ConfigureNotify on the stage window. If there is a plugin that
   * provides an xevent_filter function, then it's the responsibility
   * of that plugin to pass events to Clutter. Otherwise, we send the
   * event directly to Clutter ourselves.
   *
   * What happens if there are two plugins with xevent_filter functions
   * is undefined; in general, multiple competing plugins are something
   * we don't support well or care much about.
   *
   * FIXME: Really, we should just always handle sending the event to
   *  clutter if a plugin doesn't report the event as handled by
   *  returning TRUE, but it doesn't seem worth breaking compatibility
   *  of the plugin interface right now to achieve this; the way it is
   *  now works fine in practice.
   */
  have_plugin_xevent_func = FALSE;

  while (l)
    {
      MetaPlugin      *plugin = l->data;
      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);

      if (klass->xevent_filter)
        {
          have_plugin_xevent_func = TRUE;
          if (klass->xevent_filter (plugin, xev) == TRUE)
            return TRUE;
        }

      l = l->next;
    }

  if (!have_plugin_xevent_func)
    return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;

  return FALSE;
}
示例#7
0
/*
 * The public method that the compositor hooks into for desktop switching.
 *
 * Returns TRUE if the plugin handled the event type (i.e.,
 * if the return value is FALSE, there will be no subsequent call to the
 * manager completed() callback, and the compositor must ensure that any
 * appropriate post-effect cleanup is carried out.
 */
gboolean
meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
                                   XEvent            *xev)
{
  MetaPlugin *plugin = plugin_mgr->plugin;
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);

  /* We need to make sure that clutter gets certain events, like
   * ConfigureNotify on the stage window. If there is a plugin that
   * provides an xevent_filter function, then it's the responsibility
   * of that plugin to pass events to Clutter. Otherwise, we send the
   * event directly to Clutter ourselves.
   */
  if (klass->xevent_filter)
    return klass->xevent_filter (plugin, xev);
  else
    return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}
示例#8
0
static void
handle_host_xevent (MetaBackend *backend,
                    XEvent      *event)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  gboolean bypass_clutter = FALSE;

  XGetEventData (priv->xdisplay, &event->xcookie);

  {
    MetaDisplay *display = meta_get_display ();

    if (display)
      {
        MetaCompositor *compositor = display->compositor;
        if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
          bypass_clutter = TRUE;
      }
  }

  if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
    {
#ifdef HAVE_WAYLAND
      Window xwin = meta_backend_x11_get_xwindow(x11);
      XEvent xev;

      if (event->xfocus.window == xwin)
        {
          /* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
           * by a KeymapNotify event */
          XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
          MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
          meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
        }
#else
      g_assert_not_reached ();
#endif
    }

  if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
    handle_alarm_notify (backend, event);

  if (event->type == priv->xkb_event_base)
    {
      XkbEvent *xkb_ev = (XkbEvent *) event;

      if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
        {
          switch (xkb_ev->any.xkb_type)
            {
            case XkbNewKeyboardNotify:
            case XkbMapNotify:
              keymap_changed (backend);
              break;
            case XkbStateNotify:
              if (xkb_ev->state.changed & XkbGroupLockMask)
                {
                  if (priv->locked_group != xkb_ev->state.locked_group)
                    XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group);
                }
              break;
            default:
              break;
            }
        }
    }

  {
    MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
    if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
        meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
      bypass_clutter = TRUE;
  }

  if (!bypass_clutter)
    {
      handle_input_event (x11, event);
      clutter_x11_handle_event (event);
    }

  XFreeEventData (priv->xdisplay, &event->xcookie);
}
示例#9
0
文件: compositor.c 项目: nkoep/muffin
/**
 * meta_compositor_process_event: (skip)
 *
 */
gboolean
meta_compositor_process_event (MetaCompositor *compositor,
                               XEvent         *event,
                               MetaWindow     *window)
{
    if (compositor->modal_plugin && is_grabbed_event (event))
    {
        MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin);

        if (klass->xevent_filter)
            klass->xevent_filter (compositor->modal_plugin, event);

        /* We always consume events even if the plugin says it didn't handle them;
         * exclusive is exclusive */
        return TRUE;
    }

    if (window)
    {
        MetaCompScreen *info;
        MetaScreen     *screen;

        screen = meta_window_get_screen (window);
        info = meta_screen_get_compositor_data (screen);

        if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
        {
            DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
            return TRUE;
        }
    }
    else
    {
        GSList *l;

        l = meta_display_get_screens (compositor->display);

        while (l)
        {
            MetaScreen     *screen = l->data;
            MetaCompScreen *info;

            info = meta_screen_get_compositor_data (screen);

            if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
            {
                DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
                return TRUE;
            }

            l = l->next;
        }
    }

    switch (event->type)
    {
    case PropertyNotify:
        process_property_notify (compositor, (XPropertyEvent *) event, window);
        break;

    default:
        if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
        {
            /* Core code doesn't handle damage events, so we need to extract the MetaWindow
             * ourselves
             */
            if (window == NULL)
            {
                Window xwin = ((XDamageNotifyEvent *) event)->drawable;
                window = meta_display_lookup_x_window (compositor->display, xwin);
            }

            DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
            process_damage (compositor, (XDamageNotifyEvent *) event, window);
        }
        break;
    }

    /* Clutter needs to know about MapNotify events otherwise it will
       think the stage is invisible */
    if (event->type == MapNotify)
        clutter_x11_handle_event (event);

    /* The above handling is basically just "observing" the events, so we return
     * FALSE to indicate that the event should not be filtered out; if we have
     * GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
     */
    return FALSE;
}