Question: I'd like to make the background of a Gtk+ window transparent so that only the widgets in the window are visible. I found a few tutorials:

<http://mikehearn.wordpress.com/2006/03/26/gtk-windows-with-alpha-channels/>

<http://macslow.thepimp.net/?p=26>

But they both appear to listen to the "expose" event, and then delegate to Cairo to do the rendering. This means that other widgets added to the window are not rendered (for example, I've tried adding a button to the window as well).

I see that there's a method modify-bg on GtkWidget: <http://library.gnome.org/devel/gtk/stable/GtkWidget.html#gtk-widget-modify-bg>

However, GdkColor does not appear to accept a parameter for transparency: <http://library.gnome.org/devel/gdk/stable/gdk-Colormaps-and-Colors.html>

I've tried the GtkWindow.set\_opacity method as well, but this sets the opacity for the window contents as well, which is not what I want.

I'd appreciate any guidance anyone can provide in this.

Answer: 
Thanks for the answer. I rewrite the code in python + GTK3:

```
#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
import cairo

supports_alpha = False

def screen_changed(widget, old_screen, userdata=None):
    global supports_alpha

    screen = widget.get_screen()
    visual = screen.get_rgba_visual()

    if visual is None:
        print("Your screen does not support alpha channels!")
        visual = screen.get_system_visual()
        supports_alpha = False
    else:
        print("Your screen supports alpha channels!")
        supports_alpha = True

    widget.set_visual(visual)

def expose_draw(widget, event, userdata=None):
    global supports_alpha

    cr = Gdk.cairo_create(widget.get_window())

    if supports_alpha:
        print("setting transparent window")
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.0) 
    else:
        print("setting opaque window")
        cr.set_source_rgb(1.0, 1.0, 1.0)

    cr.set_operator(cairo.OPERATOR_SOURCE)
    cr.paint()

    return False

def clicked(window, event, userdata=None):
    # toggle window manager frames
    window.set_decorated(not window.get_decorated())

if __name__ == "__main__":
    window = Gtk.Window()
    window.set_position(Gtk.WindowPosition.CENTER)
    window.set_default_size(400, 400)
    window.set_title("Alpha Demo")
    window.connect("delete-event", Gtk.main_quit)

    window.set_app_paintable(True)

    window.connect("draw", expose_draw)
    window.connect("screen-changed", screen_changed)

    window.set_decorated(False)
    window.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
    window.connect("button-press-event", clicked)

    fixed_container = Gtk.Fixed()
    window.add(fixed_container)
    button = Gtk.Button.new_with_label("button1")
    button.set_size_request(100, 100)
    fixed_container.add(button)

    screen_changed(window, None, None)

    window.show_all()
    Gtk.main()

```
With Gtk 3, you can just set the background color, see docs for [override\_background\_color](https://docs.gtk.org/gtk3/method.Widget.override_background_color.html) (deprecated)

```py
window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,0))
window.set_visual(window.get_screen().get_rgba_visual())

```

or more properly, by using CSS and setting `background-color: rgba(...)` to the main window. Here's a code example for the latter strategy, copied from [here](https://discourse.gnome.org/t/top-level-window-transparency-in-newer-versions-of-gtk/2210):

```py
import gi

gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0")

from gi.repository import Gdk
from gi.repository import Gtk

CSS = b"""
#toplevel {
    background-color: rgba(0, 0, 0, 0);
}
"""

style_provider = Gtk.CssProvider()
style_provider.load_from_data(CSS)

Gtk.StyleContext.add_provider_for_screen(
    Gdk.Screen.get_default(),
    style_provider,
    Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)

button1 = Gtk.Button(label="Hello, world!")
box = Gtk.Box(spacing=50)
box.pack_start(button1, True, True, 50)

window = Gtk.Window(title="Hello World", name="toplevel")
window.set_visual(window.get_screen().get_rgba_visual())
window.add(box)
window.show_all()
window.connect("destroy", Gtk.main_quit)

Gtk.main()

```