X11 - Draw on Overlay Window

Asked
Active3 hr before
Viewed126 times

6 Answers

overlay
90%

Mouse works fine outside the overlay window; what I experience is that mouse clicks in the region of the window do not get passed on to the window behind the transparent window. On re-reading, I'm not sure this was actually a design goal of this program. – David Zhao Akeley Jul 9 '20 at 23:48 , 1 This is not a correct use of the overlay window. Why don't you just create your own override-redirect window that is only as large as you need it and call XRaiseWindow on it 100 times per second? (This would still be insane, but slightly less insane than the existing solution here) – Uli Schlachter Jan 7 '19 at 20:12 , Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers ,I want to draw simple primitives at specific pixels on the screen (similar to this question). In order to do that I draw on top of all windows using the Overlay Window of the Window Manager. I can see the shape I am drawing and mouse events pass through but I don't see for example Window movements that are below the Overlay Window (unless I kill my application). I am new to Xlib programming, sry for asking a maybe simple question.

May I suggest a simpler, pure X11 solution that does not have the flickering problem I experienced and also mentioned here. It uses the override_redirect functionality in Xlib:

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

#include <cairo.h>
#include <cairo-xlib.h>

#include <chrono>
#include <thread>

void draw(cairo_t *cr) {
    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.5);
    cairo_rectangle(cr, 0, 0, 200, 200);
    cairo_fill(cr);
}

int main() {
    Display *d = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(d);
    int default_screen = XDefaultScreen(d);

    // these two lines are really all you need
    XSetWindowAttributes attrs;
    attrs.override_redirect = true;

    XVisualInfo vinfo;
    if (!XMatchVisualInfo(d, DefaultScreen(d), 32, TrueColor, &vinfo)) {
        printf("No visual found supporting 32 bit color, terminating\n");
        exit(EXIT_FAILURE);
    }
    // these next three lines add 32 bit depth, remove if you dont need and change the flags below
    attrs.colormap = XCreateColormap(d, root, vinfo.visual, AllocNone);
    attrs.background_pixel = 0;
    attrs.border_pixel = 0;

    // Window XCreateWindow(
    //     Display *display, Window parent,
    //     int x, int y, unsigned int width, unsigned int height, unsigned int border_width,
    //     int depth, unsigned int class, 
    //     Visual *visual,
    //     unsigned long valuemask, XSetWindowAttributes *attributes
    // );
    Window overlay = XCreateWindow(
        d, root,
        0, 0, 200, 200, 0,
        vinfo.depth, InputOutput, 
        vinfo.visual,
        CWOverrideRedirect | CWColormap | CWBackPixel | CWBorderPixel, &attrs
    );

    XMapWindow(d, overlay);

    cairo_surface_t* surf = cairo_xlib_surface_create(d, overlay,
                                  vinfo.visual,
                                  200, 200);
    cairo_t* cr = cairo_create(surf);

    draw(cr);
    XFlush(d);

    std::this_thread::sleep_for(std::chrono::milliseconds(10000));

    cairo_destroy(cr);
    cairo_surface_destroy(surf);

    XUnmapWindow(d, overlay);
    XCloseDisplay(d);
    return 0;
}
load more v
88%

To actually draw on top of all windows you need to create simple composite manager or if there is already CM running use it's overlay window.,CompositeGetOverlayWindow returns the XID of the Composite Overlay Window. If the window has not yet been mapped, it is mapped by this request. When all clients who have called this request have terminated their X11 connections the window is unmapped.,Another approach would be to create transparent window, make it topmost and draw on it's surface. You'll need to propagate mouse events to underlying windows manually.,But nothing appears on the screen (however, the root window is assigned: grabbing keyboard after it works). How to do this correctly?

I want to draw some primitives on top of all windows on the screen. I've found some code in C and tried to port it to use python's xlib:

from Xlib.display
import Display
from Xlib
import X
from Xlib
import protocol

display = Display(':0')
root = display.screen().root
gc = root.create_gc()
root.fill_rectangle(gc, 100, 100, 500, 500)
72%

A transparent overlay window is a special class of an X InputOutput window into which pixels can be rendered transparently. Handles to transparent overlay windows have the X window type Window. Just like standard X windows, overlay windows are drawables, and an overlay window handle can be passed to any Xlib drawing routine that takes a Drawable. ,In most respects, a transparent overlay window is just like a standard X InputOutput window. Specifically, a transparent overlay window has these characteristics:,The border of overlay windows is opaque. It is always drawn with opaque paint. Just like standard X InputOutput windows, the border width can be controlled with XSetWindowBorderWidth.,When both the source and destination drawables are non-overlay, the XCopyArea and XCopyPlane routines work as defined in the X11 specification. However, note the following for the cases in which either the source or the destination drawable is an overlay window.

typedef

enum {
   XSolarisOvlPaintTransparent,
   XSolarisOvlPaintOpaque,
}

XSolarisOvlPaintType;
load more v
65%

This is a very basic library for drawing over other windows using a transparent overlay window. It supports Linux distributions using X11. Wayland is not supported directly, but this should work with XWayland. This has been tested on Ubuntu 17.10 only.,Allow for drawing over a given window, automatically updating position and dimensions, Basic overlay library for X11. , Basic overlay library for X11.

sudo apt - get update;
sudo apt - get install - y libcairo2 libcairo2 - dev libcairo2 - doc libx11 - 6 libx11 - dev libx11 - doc libxfixes3 libxfixes - dev libxcomposite1 libxcomposite - dev
load more v
75%

I adopted the code for overlay window from here: X11 - Draw on Overlay Window,I wanted to know if the Overlay window was a child of the Root Window or not. That's because when I use XGetImage() for the root window, I see that the Overlay window also appears in the saved image (I save it through OpenCV 3.4.1). So, is there a method to get the image of only the root window (excluding the overlay window.),I tried many ways, like changing the focus of input, using only XCompositeRedirectWindow (which resulted in BadMatch error), etc, but unable to get only root window image.,If you add any files,it will delete all existing files related to this answer-(only this answer)

Overlays can be tricky. You can use XQueryTree() to find parent and children windows from a given window.

XQueryTree()
40%

X11 - Draw on Overlay Window

1.2.#include <assert.h>3.#include <stdio.h>4.#include <X11/Xlib.h>5.#include <X11/X.h>6.#include <X11/Xutil.h>7.8.#include <cairo.h>9.#include <cairo-xlib.h>10.11.#include <chrono>12.#include <thread>13.14.void draw(cairo_t *cr) {15.    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.5);16.    cairo_rectangle(cr, 0, 0, 200, 200);17.    cairo_fill(cr);18.}19.20.int main() {21.    Display *d = XOpenDisplay(NULL);22.    Window root = DefaultRootWindow(d);23.    int default_screen = XDefaultScreen(d);24.25.    // these two lines are really all you need26.    XSetWindowAttributes attrs;27.    attrs.override_redirect = true;28.29.    XVisualInfo vinfo;30.    if (!XMatchVisualInfo(d, DefaultScreen(d), 32, TrueColor, &vinfo)) {31.        printf("No visual found supporting 32 bit color, terminating\n");32.        exit(EXIT_FAILURE);33.    }34.    // these next three lines add 32 bit depth, remove if you dont need and change the flags below35.    attrs.colormap = XCreateColormap(d, root, vinfo.visual, AllocNone);36.    attrs.background_pixel = 0;37.    attrs.border_pixel = 0;38.39.    // Window XCreateWindow(40.    //     Display *display, Window parent,41.    //     int x, int y, unsigned int width, unsigned int height, unsigned int border_width,42.    //     int depth, unsigned int class, 43.    //     Visual *visual,44.    //     unsigned long valuemask, XSetWindowAttributes *attributes45.    // );46.    Window overlay = XCreateWindow(47.        d, root,48.        0, 0, 200, 200, 0,49.        vinfo.depth, InputOutput, 50.        vinfo.visual,51.        CWOverrideRedirect | CWColormap | CWBackPixel | CWBorderPixel, &attrs52.    );53.54.    XMapWindow(d, overlay);55.56.    cairo_surface_t* surf = cairo_xlib_surface_create(d, overlay,57.                                  vinfo.visual,58.                                  200, 200);59.    cairo_t* cr = cairo_create(surf);60.61.    draw(cr);62.    XFlush(d);63.64.    std::this_thread::sleep_for(std::chrono::milliseconds(10000));65.66.    cairo_destroy(cr);67.    cairo_surface_destroy(surf);68.69.    XUnmapWindow(d, overlay);70.    XCloseDisplay(d);71.    return 0;72.}73.

Other "overlay-undefined" queries related to "X11 - Draw on Overlay Window"