how to change root window background

来源:互联网 发布:access数据库同步工具 编辑:程序博客网 时间:2024/06/06 01:23

how to change root window background

/*root_back.c*/

#include <gtk/gtk.h>
#include <gdk/gdkx.h>

static void
set_real_root_window_pixmap(GdkScreen *gscreen,
      GdkPixmap *pmap)
{
        Window xid;
        GdkWindow *groot;

        xid = GDK_DRAWABLE_XID(pmap);
        groot = gdk_screen_get_root_window(gscreen);

        gdk_error_trap_push();

        /* set root property for transparent Eterms */
        gdk_property_change(groot,
                        gdk_atom_intern("_XROOTPMAP_ID", FALSE),
                        gdk_atom_intern("PIXMAP", FALSE), 32,
                        GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
        /* set this other property because someone might need it sometime. */
        gdk_property_change(groot,
                        gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
                        gdk_atom_intern("PIXMAP", FALSE), 32,
                        GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
        /* and set the root window's BG pixmap, because aterm is somewhat lame. */
        gdk_window_set_back_pixmap(groot, pmap, FALSE);
        /* there really should be a standard for this crap... */

        gdk_error_trap_pop();
}


int main(int argc, char ** argv)
{

        gtk_init (&argc, &argv);
        if(argc != 2){
                fprintf(stderr,"Usage: %s filename_of_picture/n", argv[0]);
                return 1;
        }
        gchar *pic_filename = argv[1];

        GtkWidget *invisible;
        GdkWindow *root;
        GdkScreen *screen;
        GdkPixmap *pixmap;
        GdkPixbuf *pixbuf;
        int width, height;
        invisible = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        screen = gtk_window_get_screen(GTK_WINDOW(invisible));

        width = gdk_screen_get_width(screen);
        height = gdk_screen_get_height(screen);
        gtk_widget_set_size_request(invisible, width, height);
        if((pixbuf = gdk_pixbuf_new_from_file_at_scale(pic_filename,width, height, FALSE, NULL)) == NULL){
                fprintf(stderr,"invalid name for background picture :%s/n", pic_filename);
                return 1;
        }
        gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 0);
        set_real_root_window_pixmap(screen, pixmap);
        gtk_widget_show(invisible);
        gtk_widget_add_events( invisible, GDK_EXPOSURE_MASK);

        return 0;
}

最开始使用GtkInvisible控件, 但始终桌面背景需要使用xrefresh命令刷新一下。于是改用gtkwindow控件,通过gtk_widget_show这个window产生expose 事件刷出root window背景。

 

值得一提的是, 此程序最后不需要调用gtk_main()函数, 原因为:

一、root window背景设置一次就可以,不需反复设置

二、一旦调用gtk_main(), 我们用gtk_widget_show(invisible) show出来的window就会真的被show出来,而不是我们的用意:仅仅用于产生expose event

 

编译上述程序使用:

gcc -o root_back root_back.c `pkg-config --cflags --libs gtk+-2.0`