support for transparent background for widgets in GTK

1,975 views
Skip to first unread message

Armel

unread,
Dec 18, 2011, 8:52:03 AM12/18/11
to wx-dev
Hi,

i am trying to find a way to achieve transparency for widgets on GTK.

my findings is that it should be possible. at leat when a compositing
window manager is there (problem: my main Linux box is all new but in
virtual machine, and i am not sure yet if it does compositing. EDIT:
sure it was not, I had to follow these instructions:
http://epx.com.br/logbook/archive/2009/06/composite-mode-in-linux-under-vmware.html)

we might be able to do something with:
- gdk_screen_is_composited (screen) to know if native transparency is
possible
- gdk_screen_get_rgba_colormap (screen) to get the RGBA colormap from
the screen
- gtk_widget_set_colormap (widget, rgba_colormap) to be sure the 'A'
part is well in place

(see this message on stackoverflow on how to make a WebKit browser
transparent: http://stackoverflow.com/questions/324923/is-it-possible-to-render-web-content-over-a-clear-background-using-webkit

see also that sample (it worked after enabling compositing, without
enabling i got a big black widget):
http://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent

I need to continue now by tweaking in wxGTK, but my guess is that it
is definitely possible

Best regards
Armel

Vadim Zeitlin

unread,
Dec 20, 2011, 7:29:00 AM12/20/11
to wx-...@googlegroups.com
On Sun, 18 Dec 2011 05:52:03 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> i am trying to find a way to achieve transparency for widgets on GTK.

Notice that "widget" != "window". It seems to me that all of the links you
posted were about the windows, i.e. top-level windows in wx terminology.
This is something we already can do with wxTLW::SetShape() and
SetTransparent() methods. But we can't do this for the child widgets.

Regards,
VZ

Armel

unread,
Dec 20, 2011, 8:27:07 AM12/20/11
to wx-dev

On 20 déc, 13:29, Vadim Zeitlin <va...@wxwidgets.org> wrote:


> On Sun, 18 Dec 2011 05:52:03 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> i am trying to find a way to achieve transparency for widgets on GTK.
>
>  Notice that "widget" != "window". It seems to me that all of the links you
> posted were about the windows, i.e. top-level windows in wx terminology.
> This is something we already can do with wxTLW::SetShape() and
> SetTransparent() methods. But we can't do this for the child widgets.

these properties deal indeed with top level window, but the RGBA
colormap let us manipulate a given transparency -per pixel- (some kind
of visual super-shape, while it may not provide same feature for mouse
events).

up to now I could make a sample with transparency achieved for
children widgets, BUT that transparency does not seem to be composed
with the hierarchy (i.e. if child C of top level parent P is
transparent at X,Y, then desktop is shown at X,Y rather than P
content...). From a totally external point of view it could be
logical: "inside an application deal with transparency your way, with
top level window have the window manager do it for you", i'll have to
see what is right...

I need to dig to see if it is possible to get that composition, I
believe it is because in the wx version I patched I get a black
background for the 'should-be-transparent' widget, and that black
color must come from somewhere (and sure it's not the desktop). the
RGBA code is the same in both cases.

Regards
Armel

Armel

unread,
Dec 21, 2011, 8:08:05 AM12/21/11
to wx-dev
I finally found the right documentation, it was not so badly placed
but as usual, one knows where something is documented once he knows
the feature... so the method is to use (in addition to the RGBA
colormap) gdk_window_set_composited (it works since gtk 2.12 see
http://developer.gnome.org/gdk/stable/gdk-Windows.html#composited-window-example).

basically the logic is like this:
- transparency-ability is achieved by calling
gdk_window_set_composited() on a -child- window
- the expose-event of the child is handled normally (in double-buffer
though)
- a special expose-event handler must be added to the parent window,
this handler puts the image of each child on top of its own rendering
when necessary

it requires us to:
- know that at least one child is transparent to avoid the event if
not useful, built in the set-parent logic
- have a "background transparent" flag (wxBG_STYLE_TRANSPARENT seems
appropriate)
- the colormap MUST be set BEFORE realization, thus unless we un-
realize and re-realize (I don't know yet how to do that) when calling
SetBackgroundStyle() it would seem appropriate to have a "window flag"
for that (it seems definitely something which is not variable), or
check if caling SetBackgrounStyle() can be called before Create() [if
it's easy to un-realize/realize again, together with children if any,
please tell]
- update wxDC stuff to make it RGBA aware (wxGetPoolGC, seems quite
easy, adding a _ALPHA variant), probably other things...

I am going to test all of that to be sure it really works before
proposing too much alterations...

Regards
Armel

Vadim Zeitlin

unread,
Dec 21, 2011, 12:11:25 PM12/21/11
to wx-...@googlegroups.com
On Wed, 21 Dec 2011 05:08:05 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> I finally found the right documentation, it was not so badly placed
A> but as usual, one knows where something is documented once he knows
A> the feature... so the method is to use (in addition to the RGBA
A> colormap) gdk_window_set_composited (it works since gtk 2.12 see
A> http://developer.gnome.org/gdk/stable/gdk-Windows.html#composited-window-example).

Ah, yes, indeed this looks like what we want.

A> basically the logic is like this:
A> - transparency-ability is achieved by calling
A> gdk_window_set_composited() on a -child- window
A> - the expose-event of the child is handled normally (in double-buffer
A> though)
A> - a special expose-event handler must be added to the parent window,
A> this handler puts the image of each child on top of its own rendering
A> when necessary

This is the ugly part. It would make much more sense to handle this
entirely in the child but apparently we'll have to emulate this ourselves.

A> it requires us to:
A> - know that at least one child is transparent to avoid the event if
A> not useful, built in the set-parent logic
A> - have a "background transparent" flag (wxBG_STYLE_TRANSPARENT seems
A> appropriate)

Yes, wxBG_STYLE_TRANSPARENT looks good for this. I wonder what should be
done under MSW if it's _not_ specified as everything works there even
without any special flags currently.

A> - the colormap MUST be set BEFORE realization, thus unless we un-
A> realize and re-realize (I don't know yet how to do that) when calling
A> SetBackgroundStyle() it would seem appropriate to have a "window flag"
A> for that (it seems definitely something which is not variable), or
A> check if caling SetBackgrounStyle() can be called before Create() [if
A> it's easy to un-realize/realize again, together with children if any,
A> please tell]

We can call SetBackgrounStyle() before calling Create(). I'm not sure if
we can re-realize the window neither, it would need to be tested.

A> - update wxDC stuff to make it RGBA aware (wxGetPoolGC, seems quite
A> easy, adding a _ALPHA variant), probably other things...

I don't think we want to do this, we need to use wxGraphicsContext for
anything alpha-aware.

Good luck!
VZ

Armel

unread,
Dec 22, 2011, 5:57:55 AM12/22/11
to wx-dev


On 21 déc, 18:11, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Wed, 21 Dec 2011 05:08:05 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> I finally found the right documentation, it was not so badly placed
> A> but as usual, one knows where something is documented once he knows
> A> the feature... so the method is to use (in addition to the RGBA
> A> colormap) gdk_window_set_composited (it works since gtk 2.12 see
> A>http://developer.gnome.org/gdk/stable/gdk-Windows.html#composited-win...).
>
>  Ah, yes, indeed this looks like what we want.
>
> A> basically the logic is like this:
> A> - transparency-ability is achieved by calling
> A> gdk_window_set_composited() on a -child- window
> A> - the expose-event of the child is handled normally (in double-buffer
> A> though)
> A> - a special expose-event handler must be added to the parent window,
> A> this handler puts the image of each child on top of its own rendering
> A> when necessary
>
>  This is the ugly part. It would make much more sense to handle this
> entirely in the child but apparently we'll have to emulate this ourselves.

TADAAAA! it works :)
I have added a m_compositedChildren to the native GTK wxWindowGTK and
added code to:
- clean the background of window with transparent background
- added code near the end of GtkSendPaintEvents which overlays
composited children

I added a fallback to wxBG_STYLE_ERASE mode if transparency cannot be
achieved in a particular screen (no composite window manager)
the code requires wxUSE_GRAPHICS_CONTEXT

> A> it requires us to:
> A> - know that at least one child is transparent to avoid the event if
> A> not useful, built in the set-parent logic
> A> - have a "background transparent" flag (wxBG_STYLE_TRANSPARENT seems
> A> appropriate)
>
>  Yes, wxBG_STYLE_TRANSPARENT looks good for this. I wonder what should be
> done under MSW if it's _not_ specified as everything works there even
> without any special flags currently.
>
> A> - the colormap MUST be set BEFORE realization, thus unless we un-
> A> realize and re-realize (I don't know yet how to do that) when calling
> A> SetBackgroundStyle() it would seem appropriate to have a "window flag"
> A> for that (it seems definitely something which is not variable), or
> A> check if caling SetBackgrounStyle() can be called before Create() [if
> A> it's easy to un-realize/realize again, together with children if any,
> A> please tell]
>
>  We can call SetBackgrounStyle() before calling Create(). I'm not sure if
> we can re-realize the window neither, it would need to be tested.
>
> A> - update wxDC stuff to make it RGBA aware (wxGetPoolGC, seems quite
> A> easy, adding a _ALPHA variant), probably other things...
>
>  I don't think we want to do this, we need to use wxGraphicsContext for
> anything alpha-aware.
oh, i did it and it works nice (my code was not yet GC aware)

how can I submit a "proof of concept" patch? in the tracking system?

Regards
Armel

Armel

unread,
Dec 22, 2011, 7:13:09 AM12/22/11
to wx-dev
tried to do it on review.bakefile.org but i lost my password and the
password recovery system just makes an error 500 (for a valid email/
account only). there is no contact form to report a problem :( (only
bugs but it is about bugs on the review board soft itself).

Armel

Vadim Zeitlin

unread,
Dec 22, 2011, 7:39:20 AM12/22/11
to wx-...@googlegroups.com
On Thu, 22 Dec 2011 02:57:55 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> TADAAAA! it works :)

Wow, great!

A> I have added a m_compositedChildren to the native GTK wxWindowGTK and
A> added code to:
A> - clean the background of window with transparent background
A> - added code near the end of GtkSendPaintEvents which overlays
A> composited children

How is this m_compositedChildren handled? Do children add themselves to it
when wxBG_STYLE_TRANSPARENT is used?

A> how can I submit a "proof of concept" patch? in the tracking system?

I don't really think you need to submit proof of concept via Trac or RB, I
don't think anybody would have any special comments on it. But it would be
great if you could submit the final patch to RB. Please contact Vaclav for
your password recovery.

Thanks,
VZ

Armel

unread,
Dec 22, 2011, 8:14:59 AM12/22/11
to wx-dev


On 22 déc, 13:39, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 22 Dec 2011 02:57:55 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> TADAAAA! it works :)
>
>  Wow, great!
>
> A> I have added a m_compositedChildren to the native GTK wxWindowGTK and
> A> added code to:
> A> - clean the background of window with transparent background
> A> - added code near the end of GtkSendPaintEvents which overlays
> A> composited children
>
>  How is this m_compositedChildren handled? Do children add themselves to it
> when wxBG_STYLE_TRANSPARENT is used?
currently it's handled in two places, 1) when a transition between
wxBG_STYLE_TRANSPARENT to/from something else happens and m_parent
exists and 2) when AddChild/RemoveChild functions are called and the
current style is transparent. I think I'll add a GtkIsComposite() to
avoid these tests on wxBG_STYLE_TRANSPARENT and make two functions
GtkAdd/RemoveCompositeChild() called from AddChild/RemoveChild and
SetBackgroundMode, to make it easier to verify things happens
normally.
NB: I am not really sure how scrolled window will behave (because
there are two GTK widgets), but it seems acceptable for the scrolled
windows not to work (yet) with transparent background.

> A> how can I submit a "proof of concept" patch? in the tracking system?
>
>  I don't really think you need to submit proof of concept via Trac or RB, I
> don't think anybody would have any special comments on it. But it would be
> great if you could submit the final patch to RB. Please contact Vaclav for
> your password recovery.
OK

Regards
Armel

Armel

unread,
Jan 12, 2012, 8:37:21 AM1/12/12
to wx-dev
added a patch review here: http://review.bakefile.org/r/376/

Regards
Armel

Vadim Zeitlin

unread,
Jan 12, 2012, 9:27:38 AM1/12/12
to wx-...@googlegroups.com
On Thu, 12 Jan 2012 05:37:21 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> added a patch review here: http://review.bakefile.org/r/376/

Thanks but after a very quick look at it I wonder how is this supposed to
work exactly, i.e. do we need to do anything else than setting
wxBG_STYLE_TRANSPARENT? How did you test this exactly, can the new
behaviour be seen in the "erase" sample?

TIA,
VZ

Armel

unread,
Jan 12, 2012, 10:31:23 AM1/12/12
to wx-dev


On 12 jan, 15:27, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 12 Jan 2012 05:37:21 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> added a patch review here:http://review.bakefile.org/r/376/
>
>  Thanks but after a very quick look at it I wonder how is this supposed to
> work exactly, i.e. do we need to do anything else than setting
> wxBG_STYLE_TRANSPARENT?
just have to set the background style to wxBG_STYLE_TRANSPARENT before
calling Create() [i'd advocate for a window creation style which would
be easier to use but there is no such flags yet]

> How did you test this exactly, can the new
> behaviour be seen in the "erase" sample?

yes I altered the erase sample, forgot it.

Armel

unread,
Jan 12, 2012, 11:02:46 AM1/12/12
to wx-dev
I am trying to make the updates that you propose but I cannot compile
the head, it complains about wxCOMPILE_TIME_ASSERT being unknown in
include/wx/defs.h

I configure with: ../wx-head/configure --srcdir=/home/armel/wx-head --
enable-debug --enable-debug_gdb --with-gtk --disable-stc --enable-
unicode --with-libpng=builtin --with-zlib=builtin --with-
libjpeg=builtin --with-regex=builtin --with-expat=builtin --disable-
shared --disable-fswatcher

Vadim Zeitlin

unread,
Jan 12, 2012, 11:49:08 AM1/12/12
to wx-...@googlegroups.com
On Thu, 12 Jan 2012 08:02:46 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> I am trying to make the updates that you propose but I cannot compile
A> the head, it complains about wxCOMPILE_TIME_ASSERT being unknown in
A> include/wx/defs.h

This must be some local problem because it builds fine for me and on the
buildbot. And there have been no changes here. Please remove the build
directory, reconfigure again (there is nothing wrong with the configure
options you use but several of them are unneeded) and hopefully the problem
will go away.

Regards,
VZ

Armel

unread,
Jan 12, 2012, 1:00:26 PM1/12/12
to wx-dev


On 12 jan, 17:49, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 12 Jan 2012 08:02:46 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> I am trying to make the updates that you propose but I cannot compile
> A> the head, it complains about wxCOMPILE_TIME_ASSERT being unknown in
> A> include/wx/defs.h
>
>  This must be some local problem because it builds fine for me and on the
> buildbot. And there have been no changes here. Please remove the build
> directory, reconfigure again (there is nothing wrong with the configure
> options you use but several of them are unneeded) and hopefully the problem
> will go away.
unfortunetaly no, this is again the same old CRLF/LF problem, my main
development is made on Windows so my checkout is there and shared on
Linux, but nothing works then :( (many .in files are with CRLF and so
on, ....)
patience, patience...
when I work on snapshots (such as 2.9.3) I always Unix tree (tar.gz)
else I get into these problems :( but for SVN head cannot do that
unfortunately

Vadim Zeitlin

unread,
Jan 12, 2012, 1:02:35 PM1/12/12
to wx-...@googlegroups.com
On Thu, 12 Jan 2012 10:00:26 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> when I work on snapshots (such as 2.9.3) I always Unix tree (tar.gz)
A> else I get into these problems :( but for SVN head cannot do that
A> unfortunately

Just use git. You can then keep multiple clones locally with minimal
effort.

Regards,
VZ

Armel

unread,
Jan 12, 2012, 2:48:55 PM1/12/12
to wx-dev


On 12 jan, 19:02, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 12 Jan 2012 10:00:26 -0800 (PST) Armel <armel.asse...@elliecomputing.com> wrote:
>
> A> when I work on snapshots (such as 2.9.3) I always Unix tree (tar.gz)
> A> else I get into these problems :( but for SVN head cannot do that
> A> unfortunately
>
>  Just use git. You can then keep multiple clones locally with minimal
> effort.
I am playing with git currently, but it seems rather cumbersome on
windows... (it is able to consider as modified files that I just
checked out and did not touch... after searching the internet I
managed to find that the default EOL settings are seomwhat bad, but
this is definitely counter intuitive). and git over HTTPS is a plea on
Windows (trying to get data from github), the other way over SSH is
not really better.
i need to find a good distribution/integration of it...

Regards
Armel

Vadim Zeitlin

unread,
Jan 12, 2012, 4:06:17 PM1/12/12
to wx-...@googlegroups.com
On Thu, 12 Jan 2012 11:48:55 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:

A> I am playing with git currently, but it seems rather cumbersome on
A> windows...

I use Cygwin git and it works very well provided you set core.filemode to
false, otherwise you're going to have all sorts of problems with files
being wrongly detected as modified and it's also going to be even slower.

Because the only problem I have with git under MSW is that it's much, much
slower than under Linux. This is to be expected, of course, and it's still
pretty much unnoticeable on reasonably sized projects and even with wx it's
mostly fine but with projects using a lot of (huge) binary files this does
become a problem. Unfortunately I don't know what can be done about it,
MinGW implementation is not that much faster. I'd kill (or at least pay
good money) for a git as fast as its Unix equivalent under Windows...

Regards,
VZ

Marian 'VooDooMan' Meravy

unread,
Jan 12, 2012, 4:34:21 PM1/12/12
to wx-...@googlegroups.com
scroll bellow...

On 12. 1. 2012 22:06, Vadim Zeitlin wrote:
> On Thu, 12 Jan 2012 11:48:55 -0800 (PST) Armel <armel....@elliecomputing.com> wrote:
>
> A> I am playing with git currently, but it seems rather cumbersome on
> A> windows...
>
> I use Cygwin git and it works very well provided you set core.filemode to
> false, otherwise you're going to have all sorts of problems with files
> being wrongly detected as modified and it's also going to be even slower.
>
> Because the only problem I have with git under MSW is that it's much, much
> slower than under Linux. This is to be expected, of course, and it's still

yes, msysgit, or any UNIX SW ported to cygwin suffers from problem that
Windows have not native "fork()" system call. Cygwin uses workaround, it
spawns new process suspended, and it mmap()'s (==linux speech/copy data)
data segment of that process (witch from my experience
sometimes/occasanously fail) into same address, and then mark in data
segment's variable the IP pointer address that forked child should jump
into. That is fork() UNIX/POSIX syscall emulation.

This fork() emulation under Widows is extremely slow, that is why I have
git-clone'd wxWidgets SVN repo inside Linux box, and then transferred it
into my desktop Vista x64. Git heavily uses perl as sub-processes
(spawning a sup-process under Windows is really rather slow, compared to
Linux), and often it makes fork() syscall, that is emulated by spawning
a child process, as I have explained that in previous paragraph.

Cygwin is really cool, though it is extremely slow compared to native
UNIX-like system.

best,
vdm
.

signature.asc
Reply all
Reply to author
Forward
0 new messages