Naturally, the suggested combine input shape with empty rect did not work and gtk_widget_input_combine_region() did not help How to create a transparent window in GDK 3 that passes mouse events? . Same with gdk_window_set_pass_through() though gtk_overlay_set_overlay_pass_through is uhh not completely certain how adding an overlay would help with pass through (though as a newbie I cant be completely sure) https://stackoverflow.com/questions/79204687/how-to-create-a-transparent-window-in-gdk-3-that-passes-mouse-events-using-c
notably gdk_window_set_pass_through is not called twice gtk_widget_update_input_shape (GtkWidget *widget) doesnt seem like it should be able to do that anyways? (per gtk/gtkwidget.c · 3.24.43 · GNOME / gtk · GitLab) still not passing through tho
forgot to mention but tested on xfce (so it should exist on x11)
Hi,
the following code works for me (tested on X11 / Compiz, but should work generally). Note:
- In my experience, directly calling `
gdk_window_set_pass_through()`is not necessary. - With `
gtk_widget_update_input_shape()`you should set the region that want input. So to get a “hole” (as in the case of my example), you have to subtract it from the whole window area.
#include <gtk/gtk.h>
#include <gdk/gdk.h>
static cairo_surface_t *surface = NULL;
static void _on_button_press(G_GNUC_UNUSED GtkWidget* pWidget, G_GNUC_UNUSED GdkEventButton* event, G_GNUC_UNUSED gpointer data) {
fprintf(stderr,"button event\n");
}
static void _on_enter(G_GNUC_UNUSED GtkWidget* pWidget, G_GNUC_UNUSED GdkEvent* event, G_GNUC_UNUSED gpointer data) {
fprintf(stderr,"enter event\n");
}
static void _on_leave(G_GNUC_UNUSED GtkWidget* pWidget, G_GNUC_UNUSED GdkEvent* event, G_GNUC_UNUSED gpointer data) {
fprintf(stderr,"leave event\n");
}
static void _draw_realize(GtkWidget* pWidget, G_GNUC_UNUSED gpointer unused) {
if(surface) cairo_surface_destroy(surface);
surface = gdk_window_create_similar_surface(gtk_widget_get_window(pWidget),
CAIRO_CONTENT_COLOR_ALPHA, gtk_widget_get_allocated_width(pWidget), gtk_widget_get_allocated_height(pWidget));
cairo_t* cr = cairo_create(surface);
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
cairo_move_to(cr, 100, 100);
cairo_line_to(cr, 300, 100);
cairo_line_to(cr, 300, 300);
cairo_line_to(cr, 100, 300);
cairo_close_path(cr);
cairo_set_source_rgba(cr, 1, 1, 1, 0);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_fill(cr);
cairo_destroy(cr);
}
static void _on_realize(GtkWidget* pWidget, G_GNUC_UNUSED gpointer unused) {
GdkWindow* win = gtk_widget_get_window(pWidget);
GdkEventMask events = gdk_window_get_events(win);
gdk_window_set_events(win, events | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
_draw_realize(pWidget, NULL);
}
static gboolean _draw(G_GNUC_UNUSED GtkWidget* pWidget, cairo_t* cr, G_GNUC_UNUSED gpointer unused) {
if(surface) {
cairo_set_source_surface(cr, surface, 0, 0);
cairo_paint(cr);
}
return TRUE;
}
int main(int argc, char **argv) {
const int w = 500;
const int h = 400;
gtk_init(&argc, &argv);
GtkWindow* win = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(win, "GDK input shape test");
gtk_window_set_default_size(win, w, h);
gtk_widget_set_size_request(GTK_WIDGET(win), w, h);
g_signal_connect(win, "delete-event", gtk_main_quit, NULL);
g_signal_connect(win, "realize", G_CALLBACK(_on_realize), NULL);
g_signal_connect(win, "button-press-event", G_CALLBACK(_on_button_press), NULL);
g_signal_connect(win, "button-release-event", G_CALLBACK(_on_button_press), NULL);
g_signal_connect(win, "enter-notify-event", G_CALLBACK(_on_enter), NULL);
g_signal_connect(win, "leave-notify-event", G_CALLBACK(_on_leave), NULL);
g_signal_connect(win, "draw", G_CALLBACK(_draw), NULL);
GdkScreen* screen = gtk_window_get_screen(win);
GdkVisual* visual = gdk_screen_get_rgba_visual(screen);
if(visual) gtk_widget_set_visual(GTK_WIDGET(win), visual);
gtk_widget_set_app_paintable(GTK_WIDGET(win), TRUE);
cairo_rectangle_int_t rect1 = { .x = 0, .y = 0, .width = w, .height = h };
cairo_rectangle_int_t rect2 = { .x = 100, .y = 100, .width = 200, .height = 200 };
cairo_region_t* r = cairo_region_create_rectangle(&rect1);
cairo_region_subtract_rectangle(r, &rect2);
gtk_widget_input_shape_combine_region(GTK_WIDGET(win), r);
cairo_region_destroy(r);
gtk_widget_show_all(GTK_WIDGET(win));
gtk_main();
return 0;
}
huh, maybe a xfwm4 gdk/gtk thing then
oclock works somehow though so would this go in like…a bug report?