How to create a transparent window in GDK 3 that passes mouse events?

We need to create a transparent window and when user clicks inside this window then mouse event to be passed to a window that is behind. For example, if there is a text editor behind the window then mouse event should be passed to that editor window. By other words we need the window to be transparent for mouse events.

This is the code. It creates a transparent window but it doesn’t pass mouse events to windows that are behind it

#include <gtk/gtk.h>
#include <cairo.h>

static void on_destroy(GtkWidget *widget, gpointer data) {
    gtk_main_quit();
}

static void on_realize(GtkWidget *widget, gpointer data) {
    GdkWindow *gdk_window;
    gdk_window = gtk_widget_get_window(widget);
    if (gdk_window) {
        cairo_rectangle_int_t rect = { 0, 0, 400, 300 };
        cairo_region_t *region = cairo_region_create_rectangle(&rect);
        gdk_window_input_shape_combine_region(gdk_window, region, 0, 0);
        cairo_region_destroy(region);
    }
}

int main(int argc, char *argv[]) {
    GtkWidget *window;

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), NULL);
    g_signal_connect(window, "realize", G_CALLBACK(on_realize), NULL);

    GdkScreen *screen = gtk_widget_get_screen(window);
    GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
    if (visual != NULL) {
        gtk_widget_set_visual(window, visual);
    }
    gtk_widget_set_app_paintable(window, TRUE);

    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

Could anyone say how to create a transparent window that passes mouse events using C?

Have you tried setting gdk_window_set_pass_through?

Thank you for your help. I tried gdk_window_set_pass_through but it didn’t help.

Hi @PavelTurk, I know it’s late but I hope this helps anyway

The problem is that GTK overwrites your input shape right after realizing the GtkWindow. If you set a breakpoint on gdk_window_input_shape_combine_region, you’ll see that it’s called two times: first within your callback, then by gtk_widget_update_input_shape.

To integrate your regions with GTK you can use gtk_widget_input_shape_combine_region

Beside that, consider that gdk_window_input_shape_combine_region sets the region where input will be accepted. In your case, the app will receive input in the upper-left 400x300 rectangle and pass-through anything outside. To exclude pointer input for the entire window, pass an empty region.