admin管理员组文章数量:1122846
I need a transparent X11 window that passes all mouse events. For example, it must let select a text in the window behind.
This is my code that makes the right half of the window transparent:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/Xfixes.h>
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
Bool MakeAlwaysOnTop(Display* display, Window mywin) {
int screen = DefaultScreen(display);
Window root = RootWindow(display, screen);
Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
if( wmStateAbove != None ) {
printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
return False;
}
Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
if( wmNetWmState != None ) {
printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE !\n" );
return False;
}
if( wmStateAbove != None ) {
XClientMessageEvent xclient;
memset( &xclient, 0, sizeof (xclient) );
xclient.type = ClientMessage;
xclient.window = mywin;
xclient.message_type = wmNetWmState;
xclient.format = 32;
xclient.data.l[0] = _NET_WM_STATE_ADD;
xclient.data.l[1] = wmStateAbove;
xclient.data.l[2] = 0;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent( display,
root,
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient );
XFlush(display);
return True;
}
return False;
}
const int width = 400;
const int height = 300;
int main() {
Display *dpy;
Window win;
GC gc;
XEvent event;
int screen;
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
fprintf(stderr, "Cannot open display\n");
return 1;
}
screen = DefaultScreen(dpy);
win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 10, 10, width, height, 1, BlackPixel(dpy, screen), WhitePixel(dpy, screen));
Pixmap shape = XCreatePixmap(dpy, win, width, height, 1);
GC gc2 = XCreateGC(dpy, shape, 0, NULL);
XSetFillStyle(dpy, gc2, FillSolid);
XSetForeground(dpy, gc2, 0);
XFillRectangle(dpy, shape, gc2, 0, 0, width, height);
XSetForeground(dpy, gc2, 1);
XFillRectangle(dpy, shape, gc2, 0, 0, width / 2, height);
XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shape, ShapeSet);
XMapWindow(dpy, win);
set_no_decoration(dpy, win);
MakeAlwaysOnTop(dpy, win);
// make_window_transparent(dpy, win);
while (1) {
XNextEvent(dpy, &event);
if (event.type == KeyPress) {
break;
}
}
XFreeGC(dpy, gc);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
return 0;
}
void make_window_transparent(Display* display, Window window) {
XRectangle rect;
XserverRegion region = XFixesCreateRegion(display, &rect, 1);
XFixesSetWindowShapeRegion(display, window, ShapeInput, 0, 0, region);
XFixesDestroyRegion(display, region);
}
struct mwm_hints{
int flags;
int functions;
int decorations;
int input_mode;
int status;
};
#define MWM_HINTS_DEC (1 << 1)
#define MWM_DECOR_NONE 0
void set_no_decoration(Display* dpy, Window win) {
Atom wm_hints;
if((wm_hints = XInternAtom(dpy, "_MOTIF_WM_HINTS", True)) != None) {
struct mwm_hints hints = {MWM_HINTS_DEC, 0, MWM_DECOR_NONE, 0, 0};
XChangeProperty(dpy, win, wm_hints, wm_hints, 32, PropModeReplace, (unsigned char*)&hints, 4);
}
}
And this is the result:
As you see, in the right (transparent) part I can select a text, so mouse events pass. The problem is that it works only if I call set_no_decoration
function that removes title bar and borders.
But I need both title bar and borders. If I don't call set_no_decoration
then I have title bar and borders, but mouse events don't pass through transparent part of the window - for example, it is not possible to select a text.
Could anyone say how to make a transparent window with title bar and border that passes mouse events?
本文标签: cHow to make a transparent window with title bar and border pass mouse eventsStack Overflow
版权声明:本文标题:c - How to make a transparent window with title bar and border pass mouse events? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736309212a1933934.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论