Transparent window

263 views
Skip to first unread message

holm.h...@gmail.com

unread,
Jun 12, 2022, 3:37:09 AM6/12/22
to fltk.general

Hello,

I add the following lines to a fltk-program (testing on examples/browser-simple) and expect to see a transparent window. That do however not happen.

  Display* display;
  char* connection_string = NULL;
  display = XOpenDisplay (connection_string);
  Atom atom = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False);
  uint opacity = 0x80000000; /* 0x0 .. 0xffffffff */
  XChangeProperty(display, fl_xid(win), atom, XA_CARDINAL, 32,
            PropModeReplace, (unsigned char*)&opacity, 1L);

I run under linux/X11. How to get a transparent window ?

Best regards
Håvard

Manolo

unread,
Jun 12, 2022, 4:41:34 AM6/12/22
to fltk.general
At this point, FLTK does not support transparent colors. Thus, any background drawing FLTK does, especially window background, uses opaque colors. You need to make sure FLTK draws no background. FL_NO_BOX should help.

If the transparent areas you'd like to obtain have a fixed position, Fl_Window::shape(Fl_Image*) could be a solution.

Ian MacArthur

unread,
Jun 12, 2022, 2:17:51 PM6/12/22
to Fltk General
Apologies if this appears twice - I thought I posted before, but my response doesn’t seem to be here... Odd...
As Manolo has said, fltk doesn’t really support transparent colours in a window, so a shaped window might be the best we can do using fltk options (there are examples in the docs and in the test folder of using shaped window.)

The other thing you can do is to alter the translucency of the entire window (not just a region of it, though).
I have code (attached below) that illustrates this, which worked on X11, OSX and Win32 as of 2015’ish... so probably still OK!

TBH, I thought I had a nice worked example of this, but actually all I can find now is this rather feeble OSK demo, that uses the technique to make the pop-up keyboard widget semi-transparent.

So, not great - but once you have the translucent window created, you can vary its alpha dynamically at runtime, which is quite cool, if not actually all that useful!

Might be informative for your use-case, so the code is here...

transp-kbd.zip

Manolo

unread,
Jun 13, 2022, 3:26:41 AM6/13/22
to fltk.general
But, transparency is easily achieved now under Linux using the Wayland platform, new in FLTK 1.4 :

//
// Hello, World! program for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2021 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file.  If this
// file is missing or damaged, see the license at:
//
//     https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
//     https://www.fltk.org/bugs.php
//

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <FL/platform.H>
#if FLTK_USE_WAYLAND
#include <cairo/cairo.h>
#endif

class transparent_window : public Fl_Window {
public:
  transparent_window(int w, int h) : Fl_Window(w,h) {}
  void draw() {
#if FLTK_USE_WAYLAND
    cairo_set_source_rgba(fl_wl_cairo(), 0, 0, 0, 0); // fully transparent color
#else
    fl_color(FL_RED);
#endif
    fl_rectf(0, 0, w(), h());
    Fl_Window::draw();
  }
};

int main(int argc, char **argv) {
  transparent_window *window = new transparent_window(340, 180);
  window->box(FL_NO_BOX);
  Fl_Box *box = new Fl_Box(20, 40, 300, 100, "Hello, World!");
  box->box(FL_UP_BOX);
  box->labelfont(FL_BOLD + FL_ITALIC);
  box->labelsize(36);
  box->labeltype(FL_SHADOW_LABEL);
  window->end();
  window->show(argc, argv);
  return Fl::run();
}

Ian MacArthur

unread,
Jun 13, 2022, 9:01:29 AM6/13/22
to fltk.general
On Monday, 13 June 2022 at 08:26:41 UTC+1 Manolo wrote:
But, transparency is easily achieved now under Linux using the Wayland platform, new in FLTK 1.4 :

That's quite neat.
But, you know, Wayland... 

In the meantime, here's a simplified, cleaned up version of the sample I posted, before...
This *should* work OK on Win32, recent X11 and macOS. (But NOT Wayland, as it happens!)
Well, works for me at any rate.




fade_win.zip

holm.h...@gmail.com

unread,
Jun 14, 2022, 2:25:59 AM6/14/22
to fltk.general

Hi,
I have noticed in test/cube.cxx there is a fl_button with the following color:
Fl::set_color(FL_FREE_COLOR, 255, 255, 0, 75);
That gives a transparent color and works for both fl_button and fl_group (probably many more) as long as they are children of fl_gl_window.

Are there any chance the same would work for fl_window ?

It would open for a more modern look.

Best regards
Håvard

Ian MacArthur

unread,
Jun 14, 2022, 4:25:55 AM6/14/22
to fltk.general
On Tuesday, 14 June 2022 at 07:25:59 UTC+1  Håvard  wrote:

I have noticed in test/cube.cxx there is a fl_button with the following color:
Fl::set_color(FL_FREE_COLOR, 255, 255, 0, 75);
That gives a transparent color and works for both fl_button and fl_group (probably many more) as long as they are children of fl_gl_window.

Are there any chance the same would work for fl_window ?

Not really - the key is that the GL render context can support alpha, whereas the stock 2D rendering APIs we use for windows do not. As a result, the button drawn in the GL scene can be translucent, but "the same" button drawn to a standard window will not.

Typically, to get translucent windows you need to have some form of compositing of the desktop as a whole, for example to deal with the background changing underneath your window, even if your window is not being redrawn, that sort of thing.
That was not available in "legacy" window manager systems, but it is fairly common now. (Though still far from universal, and not always cheap to do at runtime either!)

However, how it is used (and the runtime cost of doing so) varies a fair bit between systems, so it is not something that fltk has, at least not yet.
You can get some of that functionality if you are happy to add some platform specific code to your window.
There are tricky issues to this though - as my example shows, it is pretty easy to make a translucent window (where the window *and all its widgets* are translucent); but with the current system it is tricky to have fully-opaque widgets on an otherwise transparent window, or widgets with differing alpha, and that is not an easy thing to work around in the current schemes.


holm.h...@gmail.com

unread,
Jun 19, 2022, 9:30:05 AM6/19/22
to fltk.general

Sorry for re-posting. I do not know if the other post is shown as it is done as a follow-up on an old thread.

Based on the nice work by Matthias, I make a FL_Group in my Fl_Gl_Window. This do support transparent colors, as can be seen in the attached image.

This looks just like I wanted. However there are a few issues:
1) The event handling is not always ok. I suspect that my Fl_Gl_Window captrues it. This may be my mistake.
2) Clicking on the buttons causes a redraw, and that may lead to the Fl_Group is "blinking". Is the problem that my Fl_Gl_Window/draw() uses too much time ?

Best regards
Håvard
Screenshot from 2022-06-18 21-43-52.png

Ian MacArthur

unread,
Jun 20, 2022, 3:49:50 AM6/20/22
to fltk.general
On Sunday, 19 June 2022 at 14:30:05 UTC+1  Håvard  wrote:

Sorry for re-posting. I do not know if the other post is shown as it is done as a follow-up on an old thread.

For the record - yes, the post (on the other thread) did indeed appear OK.
 

Based on the nice work by Matthias, I make a FL_Group in my Fl_Gl_Window. This do support transparent colors, as can be seen in the attached image.

Looks pretty good, doo.

 
This looks just like I wanted. However there are a few issues:
1) The event handling is not always ok. I suspect that my Fl_Gl_Window captrues it. This may be my mistake.

It could be - I've had weird issues with event handling in GL windows in the past, so it may well be tricky!
That said, I have no real grasp of how Matt handles propagation of events to fltk widgets within the GL window context, so...
I don't suppose you have a minimal compileable example that shows how you did your GL context?

 
2) Clicking on the buttons causes a redraw, and that may lead to the Fl_Group is "blinking". Is the problem that my Fl_Gl_Window/draw() uses too much time ?

I'd speculate that the redraw of the GL scene is what triggers the flickering...

That said, if you are happy with a floating window that is translucent (including all its enclosed widgets) you can get that effect from the 2D API if you use the platform code I showed, so it may be possible to float a "translucent Fl_Double_Window" over your GL scene and have that redraw without flicker, I think.
Possibly.

 

Matthias Melcher

unread,
Jun 20, 2022, 5:52:29 AM6/20/22
to fltk.general
holm.h...@gmail.com schrieb am Sonntag, 19. Juni 2022 um 15:30:05 UTC+2:

Based on the nice work by Matthias, I make a FL_Group in my Fl_Gl_Window. This do support transparent colors, as can be seen in the attached image.

Oh, wow, thanks for the screenshot. This looks really great!
 
This looks just like I wanted. However there are a few issues:
1) The event handling is not always ok. I suspect that my Fl_Gl_Window captrues it. This may be my mistake.

You need to override Fl_Gl_Window::handle() and make sure that your new function still calls the original handle() function. If that returns 1, the even was handled by the children or the GL window. Only if it was not handled (returning 0), you should add your own action (and then return 1 yourself if you handled the event, and 0 if not).

It is entirely possible though that I messed something up in the event handler. If you can get me more details, I'll be happy to dive in and find out, where the events are mishandled.
 
2) Clicking on the buttons causes a redraw, and that may lead to the Fl_Group is "blinking". Is the problem that my Fl_Gl_Window/draw() uses too much time ?

Redrawing a UI within a GL window is different to a regular window. A GL window must always be redrawn in its entirety (*including* the 3D scene in the background), whereas system windows use clipping and other tricks to redraw only what's needed. Again, I'll be happy to look into that, but I will need more detail, and probably some sample source code that shows the unexpected behaviour. The overridden Fl_Gl_Window::draw() function should redraw the entire 3D scene first, and then call the original draw() function.

Hope that helps,

 Matthias
 

Ian MacArthur

unread,
Jun 20, 2022, 6:23:36 AM6/20/22
to fltk.general
On Monday, 20 June 2022 at 10:52:29 UTC+1 Matthias Melcher wrote:
 
2) Clicking on the buttons causes a redraw, and that may lead to the Fl_Group is "blinking". Is the problem that my Fl_Gl_Window/draw() uses too much time ?

Redrawing a UI within a GL window is different to a regular window. A GL window must always be redrawn in its entirety (*including* the 3D scene in the background), whereas system windows use clipping and other tricks to redraw only what's needed. Again, I'll be happy to look into that, but I will need more detail, and probably some sample source code that shows the unexpected behaviour. The overridden Fl_Gl_Window::draw() function should redraw the entire 3D scene first, and then call the original draw() function.

As a rider to what Matt said, it turns out you can draw a translucent 2D dialog over the GL scene and that appears to be flicker-free (since it is in a separate window and not drawn as part of the GL scene.)

Code example attached...



transp_dialog.zip
Reply all
Reply to author
Forward
0 new messages