QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3500|回复: 7

Gtk通用窗口透明函数!

[复制链接]
发表于 2005-4-12 03:06:47 | 显示全部楼层 |阅读模式
经过几天的摸索,终于解决了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
发表于 2005-4-13 00:43:40 | 显示全部楼层
AFAICT, you must first map a window before the opacity setting can be applied
回复

使用道具 举报

 楼主| 发表于 2005-4-13 13:09:03 | 显示全部楼层
其实gtk_widget_show就是做这个用的,我这里规定必须show之后才能调用这个函数啊,但是加上哪个XMapWindow也是可以的,但是就是好象多此一举似的,我再改改,至于有的时候不能透明,哪个问题就是因为window还没有画出来(sleep几秒钟等画出来再调用就没事了),所以即是属性设置也没有用,还有一个奇怪的现象,终端下运行没问题,execlp就出问题了,可能是这个比较耗时吧,
liuspider有没有什么函数可以看是否一个窗口已经画完了?
我想这个应该还和窗口管理器有关,kde-3.4自己不是可以管理透明了吗?应该比现在这个xcompmgr好吧!
回复

使用道具 举报

发表于 2005-4-13 20:36:50 | 显示全部楼层
in Qt, you can call isVisible of a widget to see whether it is shown

I am sure there is such a function under gtk as well

BTW: mis-spell other's name is not a good practice...
回复

使用道具 举报

 楼主| 发表于 2005-4-13 21:40:02 | 显示全部楼层
哈哈,我已经改过来了,不好意思!对了,你说的那个visible也只是来设置这个用户是否对用户可见,并不能说明这个window是否实际显示了出来,Xlib有
[code:1]
        XWindowAttributes window_attributes;
        XGetWindowAttributes(display, window, &window_attributes);
        window_attributes.map_state == IsViewable)
[/code:1]
不过似乎不起作用!
回复

使用道具 举报

发表于 2005-4-14 00:40:13 | 显示全部楼层
isVisible 在Qt 中,只有 show() (会调用 xmap 的) 了之后,才会 return true 的

你可以看到,在 skim 的代码中,使用的是 xmap 的
回复

使用道具 举报

 楼主| 发表于 2005-4-14 11:55:08 | 显示全部楼层
XMapWindow(qt_xdisplay(), w->winId());
这个函数和调用show效果是一样的吧!
哈哈,应该kde-3.4的WM更好些吧,我现在Gentoo还没有升级到3.4,等到时候再测试吧,
应该不会出现上述问题了!
回复

使用道具 举报

发表于 2005-4-14 12:30:01 | 显示全部楼层
看看代码你就可以发现: kompmgr is only a ugly fork of xcompmgr, sucks as well...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-6 07:08 , Processed in 0.076813 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表