/** * shell_global_create_root_pixmap_actor: * @global: a #ShellGlobal * * Creates an actor showing the root window pixmap. * * Return value: (transfer none): a #ClutterActor with the root window pixmap. * The actor is floating, hence (transfer none). */ ClutterActor * shell_global_create_root_pixmap_actor (ShellGlobal *global) { GdkWindow *window; ClutterActor *stage; ClutterColor stage_color; /* The actor created is actually a ClutterClone of global->root_pixmap. */ if (global->root_pixmap == NULL) { global->root_pixmap = clutter_glx_texture_pixmap_new (); clutter_texture_set_repeat (CLUTTER_TEXTURE (global->root_pixmap), TRUE, TRUE); /* The low and medium quality filters give nearest-neighbor resizing. */ clutter_texture_set_filter_quality (CLUTTER_TEXTURE (global->root_pixmap), CLUTTER_TEXTURE_QUALITY_HIGH); /* Initialize to the stage color, since that's what will be seen * in the main view if there's no actual background window. */ stage = mutter_plugin_get_stage (global->plugin); clutter_stage_get_color (CLUTTER_STAGE (stage), &stage_color); clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (global->root_pixmap), /* ClutterColor has the same layout * as one pixel of RGB(A) data. */ (const guchar *)&stage_color, FALSE, /* w, h, rowstride, bpp, flags */ 1, 1, 3, 3, 0, NULL); /* We can only clone an actor within a stage, so we hide the source * texture then add it to the stage */ clutter_actor_hide (global->root_pixmap); clutter_container_add_actor (CLUTTER_CONTAINER (stage), global->root_pixmap); /* This really should never happen; but just in case... */ g_signal_connect (global->root_pixmap, "destroy", G_CALLBACK (root_pixmap_destroy), global); /* Metacity handles changes to some root window properties in its global * event filter, though not _XROOTPMAP_ID. For all root window property * changes, the global filter returns GDK_FILTER_CONTINUE, so our * window specific filter will be called after the global one. * * Because Metacity is already handling root window property updates, * we don't have to worry about adding the PropertyChange mask to the * root window to get PropertyNotify events. */ window = gdk_get_default_root_window (); gdk_window_add_filter (window, root_window_filter, global); update_root_window_pixmap (global); } return clutter_clone_new (global->root_pixmap); }
/* * Called when the X server emits a root window change event. If the event is * about a new pixmap, update the global->root_pixmap actor. */ static GdkFilterReturn root_window_filter (GdkXEvent *native, GdkEvent *event, gpointer data) { XEvent *xevent = (XEvent *)native; if ((xevent->type == PropertyNotify) && (xevent->xproperty.window == gdk_x11_get_default_root_xwindow ()) && (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"))) update_root_window_pixmap (SHELL_GLOBAL (data)); return GDK_FILTER_CONTINUE; }
/** * shell_global_create_root_pixmap_actor: * @global: a #ShellGlobal * * Creates an actor showing the root window pixmap. * * Return value: (transfer none): a #ClutterActor with the root window pixmap. * The actor is floating, hence (transfer none). */ ClutterActor * shell_global_create_root_pixmap_actor (ShellGlobal *global) { GdkWindow *window; ClutterActor *stage; /* The actor created is actually a ClutterClone of global->root_pixmap. */ if (global->root_pixmap == NULL) { global->root_pixmap = clutter_glx_texture_pixmap_new (); /* The low and medium quality filters give nearest-neighbor resizing. */ clutter_texture_set_filter_quality (CLUTTER_TEXTURE (global->root_pixmap), CLUTTER_TEXTURE_QUALITY_HIGH); /* We can only clone an actor within a stage, so we hide the source * texture then add it to the stage */ clutter_actor_hide (global->root_pixmap); stage = mutter_plugin_get_stage (global->plugin); clutter_container_add_actor (CLUTTER_CONTAINER (stage), global->root_pixmap); g_signal_connect (global->root_pixmap, "paint", G_CALLBACK (root_pixmap_paint), NULL); /* This really should never happen; but just in case... */ g_signal_connect (global->root_pixmap, "destroy", G_CALLBACK (root_pixmap_destroy), global); /* Metacity handles changes to some root window properties in its global * event filter, though not _XROOTPMAP_ID. For all root window property * changes, the global filter returns GDK_FILTER_CONTINUE, so our * window specific filter will be called after the global one. * * Because Metacity is already handling root window property updates, * we don't have to worry about adding the PropertyChange mask to the * root window to get PropertyNotify events. */ window = gdk_get_default_root_window (); gdk_window_add_filter (window, root_window_filter, global); update_root_window_pixmap (global); } return clutter_clone_new (global->root_pixmap); }