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; }
/* * 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; }
/* * 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; }
/** * 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; }