简体   繁体   English

使用 xlib 绘制边框(框架)

[英]Draw border (frame) using xlib

Is it possible to draw transparent window without title bar, close button, responses on mouse buttons using xlib.是否可以使用 xlib 绘制没有标题栏、关闭按钮、鼠标按钮响应的透明窗口。 So just border with specific color and width?所以只是用特定的颜色和宽度边框? Something like就像是在此处输入图片说明

this orange rectangle is what I need to create.这个橙色矩形是我需要创建的。 Also I'd like to have possibility to move, resize, close and make it flicking (change border's color on timer) programatically.此外,我希望有可能以编程方式移动、调整大小、关闭并使其闪烁(更改计时器的边框颜色)。

I managed to create transparent window without titlebar and draw rectangles on each side of the window to make border-effect:我设法创建没有标题栏的透明窗口,并在窗口的每一侧绘制矩形以制作边框效果:

#define W_WIDTH 640
#define W_HEIGHT 480

#define X_POS 100
#define Y_POS 120
#define BORDER_WIDTH 2

Display *dpy;
Window w;

XRectangle rectangles[4] =
    {
    { X_POS, Y_POS, W_WIDTH, BORDER_WIDTH },
    { X_POS, Y_POS, BORDER_WIDTH, W_HEIGHT },
    { X_POS, W_HEIGHT - BORDER_WIDTH, W_WIDTH, BORDER_WIDTH },
    { W_WIDTH - BORDER_WIDTH, Y_POS, BORDER_WIDTH, W_HEIGHT }
    };

int main(int argc, char *argv[])
{
    GC gc;
    XGCValues gcv;
    int run = 1;

    dpy = XOpenDisplay(NULL);

    XVisualInfo vinfo;
    XMatchVisualInfo(dpy, DefaultScreen(dpy), 32, TrueColor, &vinfo);
    XSetWindowAttributes attr;
    attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone);

    w = XCreateWindow(dpy, DefaultRootWindow(dpy), X_POS, Y_POS,
                      W_WIDTH, W_HEIGHT, BORDER_WIDTH, vinfo.depth,
                      InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr);
    XColor color;
    Colormap colormap;
    char orangeDark[] = "#FF8000";
    colormap = DefaultColormap(dpy, 0);
    XParseColor(dpy, colormap, orangeDark, &color);
    XAllocColor(dpy, colormap, &color);

    gcv.line_width = BORDER_WIDTH;
    gc = XCreateGC(dpy, w, GCLineWidth, &gcv);

    XSelectInput(dpy, w, ExposureMask);
    Atom window_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
    long value = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
    XChangeProperty(dpy, w, window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
    XMapWindow(dpy, w);
    XSync(dpy, False);

    while(run)
    {
        XEvent xe;
        XNextEvent(dpy, &xe);
        switch (xe.type)
        {
            case Expose:
                XSetForeground(dpy, gc, color.pixel);
                XDrawRectangles(dpy, w, gc, rectangles, 4);
                XFillRectangles(dpy, w, gc, rectangles, 4);
                XSync(dpy, False);
                break;
            default:
                break;
        }
    }

    XDestroyWindow(dpy, w);
    XCloseDisplay(dpy);

    return 0;
}

This code works almost fine except the thing, that my orange border is semitransparent and is almost invisible on light windows:这段代码几乎可以正常工作,除了我的橙色边框是半透明的并且在光窗上几乎不可见: 在此处输入图片说明 Could you please tell how I need change my code to draw solid orange rectangles?你能告诉我如何改变我的代码来绘制纯橙色矩形吗? Another variant I have is to draw transparent rectangle inside of orange window.我的另一个变体是在橙色窗口内绘制透明矩形。 But I didn't find any info in the Internet about how to do that.但我没有在互联网上找到任何关于如何做到这一点的信息。

Two main mistakes.两个主要错误。

  1. Not initializing attr and gcv to 0未将attrgcv初始化为 0
  2. Not using attr.colormap for color allocation不使用attr.colormap进行颜色分配

That should help:这应该有帮助:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

#define W_WIDTH 640
#define W_HEIGHT 480

#define X_POS 100
#define Y_POS 120
#define BORDER_WIDTH 2

int main(int argc, char *argv[]) {
    XRectangle rectangles[4] = {
        { X_POS, Y_POS, W_WIDTH, BORDER_WIDTH },
        { X_POS, Y_POS, BORDER_WIDTH, W_HEIGHT },
        { X_POS, W_HEIGHT - BORDER_WIDTH, W_WIDTH, BORDER_WIDTH },
        { W_WIDTH - BORDER_WIDTH, Y_POS, BORDER_WIDTH, W_HEIGHT }
    };
    Display *dpy = XOpenDisplay(NULL);
    XSetWindowAttributes attr = {0};
    XGCValues gcv = {0};
    XVisualInfo vinfo;
    GC gc;

    Window w;

    int run = 1;

    XMatchVisualInfo(dpy, DefaultScreen(dpy), 32, TrueColor, &vinfo);
    attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone);

    XColor color;
    char orangeDark[] = "#FF8000";
    XParseColor(dpy, attr.colormap, orangeDark, &color);
    XAllocColor(dpy, attr.colormap, &color);

    w = XCreateWindow(dpy, DefaultRootWindow(dpy), X_POS, Y_POS,
                      W_WIDTH, W_HEIGHT, BORDER_WIDTH, vinfo.depth,
                      InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr);

    gcv.line_width = BORDER_WIDTH;
    gc = XCreateGC(dpy, w, GCLineWidth, &gcv);

    XSelectInput(dpy, w, ExposureMask);
    long value = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
    XChangeProperty(dpy, w, XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False),
                    XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
    XMapWindow(dpy, w);
    XSync(dpy, False);

    while(run) {
        XEvent xe;
        XNextEvent(dpy, &xe);
        switch (xe.type) {
            case Expose:
                XSetForeground(dpy, gc, color.pixel);
                XDrawRectangles(dpy, w, gc, rectangles, 4);
                XFillRectangles(dpy, w, gc, rectangles, 4);
                XSync(dpy, False);
                break;

            default:
                break;
        }
    }

    XDestroyWindow(dpy, w);
    XCloseDisplay(dpy);

    return 0;
}

Result:结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM