2016-10-06 6 views
2

Я хотел бы создать полупрозрачное белое окно в XLib, но окно не полупрозрачное, оно остается полностью непрозрачным. Я использую Комптон наборщик и есть прозрачные окна в системе, так что проблема в коде:Как создать полупрозрачное белое окно в XLib

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

int main(int argc, char* argv[]) 
{ 
    Display* display = XOpenDisplay(NULL); 

    XVisualInfo vinfo; 

    XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo); 

    XSetWindowAttributes attr; 
    attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone); 
    attr.border_pixel = 0; 
    attr.background_pixel = 0x80ffffff; 

    Window win = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 200, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr); 
    XSelectInput(display, win, StructureNotifyMask); 
    GC gc = XCreateGC(display, win, 0, 0); 

    Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0); 
    XSetWMProtocols(display, win, &wm_delete_window, 1); 

    XMapWindow(display, win); 

    int keep_running = 1; 
    XEvent event; 

    while (keep_running) { 
     XNextEvent(display, &event); 

     switch(event.type) { 
      case ClientMessage: 
       if (event.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", 1) && (Atom)event.xclient.data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", 1)) 
        keep_running = 0; 

       break; 

      default: 
       break; 
     } 
    } 

    XDestroyWindow(display, win); 
    XCloseDisplay(display); 
    return 0; 
} 

ответ

4

Х11 ожидает, предварительно перемножаются цвета, то есть в режиме реального непрозрачные цвета должны быть умножены на величину альфа (и масштабируется соответствующим образом, то есть делится на 256, когда канал ширина - 8 бит). С этим форматом проще работать, когда вам нужно объединить множество уровней. См. Формулы here. Там меньше вычислений, когда все предварительно умножается.

Таким образом, вы должны умножить каждый из ваших R, G и B каналов на величину альфа (0x80) и разделить на 256.

Установка фона для 0x80808080 дает желаемый результат:

Обратите внимание, что результат отличается от того, что предлагает @patthoyts: здесь только окно является полупрозрачным, украшение WM остается непрозрачным; там как собственно окно, так и украшение сделаны прозрачными WM (и WM делает необходимое смешение цветов).

+0

Нет, это не так. Проверьте это изображение: http://oscomp.hu/depot/white_transparency_qt5_vs_xlib.png Цвет фона эквивалентен в обоих окнах: 0x80ffffff; Qt5 нравится, как мне это нужно, и XLib нет. Это должно быть что-то в коде, я делаю неправильно, но что? – jsr

+0

@jsr Вы пытались это сделать? Посмотрите на изображение. Как вы думаете, я отредактировал его в gimp или что? –

+0

Qt не XLib. Это портативный инструментарий, который работает с X11, Windows GDI, необработанными фреймбуферами Linux, а что нет. Я понятия не имею, что Qt делает внутри, чтобы угодить пользователю и поддерживать совместимый API. X11 делает именно то, что вы можете видеть на изображении, которое я разместил. –

2

Вам нужно установить _NET_WM_WINDOW_OPACITY. Вот фрагмент кода, чтобы добавить перед тем, как отобразить окно:

double alpha = 0.8; 
unsigned long opacity = (unsigned long)(0xFFFFFFFFul * alpha); 
Atom XA_NET_WM_WINDOW_OPACITY = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False); 
XChangeProperty(display, win, XA_NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, 
       PropModeReplace, (unsigned char *)&opacity, 1L); 

Примечание Вы должны добавить #include <X11/Xatom.h> получить декларацию XA_CARDINAL.

Я не совсем уверен, насколько стабилен этот интерфейс. Это, по-видимому, является предлагаемым расширением спецификации Extended Window Manager Hints, но не внесло изменений в окончательную версию из того, что я вижу. Я знаю, что это так Tk implements transparency support на unix.

Результат выглядит следующим образом:

transparent X11 window over editor

+0

К сожалению, это не сработало. Я попробовал его в Xfce, TDE и MotifWM с помощью compton, и он все еще полностью белый во всех средах. У меня есть код Qt5, который может установить его прозрачность фона, просто установив верхний 8 бит цвета фона. Единственное, что он делает раньше, это настройка атрибута WA_TranslucentBackground. Я все еще пытаюсь понять, что он делает, глядя на источники Qt5, но не повезло. – jsr

+0

@jsr работает с недавним KDE. Думаю, вы можете изменить оконный менеджер в Xfce и TDE на то, что поддерживает этот атом. –

+0

Мне нужно универсальное решение, а не зависящее от WM. Кроме Qt5 может сделать полупрозрачное белое окно: http://oscomp.hu/depot/white_transparency_qt5_vs_xlib.png Цвет фона эквивалент в двух программах: 0x80ffffff и еще чистый XLib один показывает полностью непрозрачное окно , – jsr

Смежные вопросы