经过几天的摸索,终于解决了Xorg>=6.8.0版本的gtk程序的alpha透明的实现,写成了一个通用的函数方便大家啊,下面是函数代码和测试程序代码,其实只需要有一个GtkWidget构件调用这个函数就足够了!
[code:1]
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW
#define OPAQUE 0xffffffff
/* set the widget's transparency to opacity
* opacity is guint 0x00000000-0xffffffff
*/
int
gtk_widget_set_transparency(GtkWidget *widget, guint opacity)
{
Display *display;
Window window;
Window parent_win;
Window root_win;
Window* child_windows;
int num_child_windows;
if(!GTK_IS_WIDGET(widget)){
printf("gtk_widget_set_transparency: not a widget!\n");
return -1;
}
if(widget->window == NULL){
printf("gtk_widget_set_transparency: please init widget before set transparency!\n");
return -1;
}
/* Set the Display and Screen */
display = (Display*)gdk_x11_get_default_xdisplay();
/* sync, so the window manager can know the new widget */
XSync(display, False);
window = GDK_WINDOW_XWINDOW(widget->window);
/* Get the cureent window's top-level window */
while(1){
XQueryTree(display, window,
&root_win,
&parent_win,
&child_windows, &num_child_windows);
XFree(child_windows);
/* found the top-level window */
if(root_win == parent_win) break;
window = parent_win;
}
if(opacity == OPAQUE){
XDeleteProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False));
}else{
XChangeProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False),
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &opacity, 1L);
}
XSync(display, False);
return 0;
}
/* test code */
int main(int argc, char **argv)
{
unsigned int opacity = 0x99999998;
GtkWidget *widget;
gtk_init(&argc, &argv);
widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(widget);
gtk_widget_set_transparency(widget, opacity);
gtk_main();
return 0;
}
[/code:1]
几点说明:
这个测试函数可能在xcompmgr -cf模式下不能正常工作,原因好象是因为那个时候窗口还没有实际的draw出来,如果你的程序需要在显示窗口的条件下动态调整,这个就应该没有什么问题
enjoy yourself |