This version restores XScreenSaver support. Many Bothans died to bring you these frame buffers.
So here's how XScreenSaver support should work: when invoked with --root or --window-id, just render the GTK widget hierarchy onto an external X11 window, and let it run normally. The following should do that:
GtkWindow *win = ...self...;
GdkDisplay *gdpy = gdk_display_get_default();
GdkWindow *gw = gdk_x11_window_foreign_new_for_display (gdpy, xwin);
gtk_widget_set_has_window (win, TRUE);
gdk_window_set_user_data (gw, win);
g_signal_connect (win, "realize", G_CALLBACK (foreign_realize), gw);
// And in foreign_realize():
gtk_widget_set_window (widget, GDK_WINDOW (user_data));
Spoiler alert, that doesn't work. I can find no evidence that creating a GtkWindow and GtkWidget hierarchy atop an existing X11 Window works at all. See the sample program in this comment for our best attempt.
So instead how it works is this:
- Create a new EGL or GLX context on the existing X11 Window, that hopefully is close enough to the one that the GtkGLArea would have made;
- Create, but do not ever realize, the GtkGLArea widget;
- Manually run that widget's "render" method, and have it bind to our context instead of the context that the GtkGLArea would have created, had we allowed it to be born.
It's nasty, and it's a lot more code (because EGL is ridiculously verbose), but it works?
It's possible that GLX would work on all extant systems, avoiding the need for that EGL nonsense, but I'm not sure.
Also: I would love to see an example of any GTK program that has convinced the compositor to respect the window's alpha channel (meaning different parts of the window have different opacity, as opposed to giving the entire window a single alpha value.) Someone claimed it was possible but I have my doubts.
Previously.