Remy
Remy

Reputation: 521

How can I make a window transparent in Windows, Mac OS X, and Linux using FLTK?

I'm writing an application in C++ using FLTK 1.3.2. This is the code I use to make the main window transparent on Windows 7 or 8:

// Given:
// Fl_Window *my_fltk_window;
// bool is_transparent;

HWND hwnd = fl_xid(my_fltk_window);
LONG_PTR exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
if (!(exstyle & WS_EX_LAYERED)) {
    SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyle | WS_EX_LAYERED);
}
SetLayeredWindowAttributes(hwnd, 0, is_transparent ? 192 : 255, LWA_ALPHA);

It works just fine: I put that code in a callback function, assign it to a button or menu item, and clicking it toggles window transparency. However, I'd like for this to be cross-platform, but don't have experience with the OS X or Linux APIs. What should I do to match the effect of the Windows code?


Edit: I got it to work in OS X. The main file calls this function:

#include "my-cocoa-wrappers.h"

setWindowTransparency(my_fltk_window, is_transparent ? 0.75 : 1.0);

Then I created my-cocoa-wrappers.h:

#ifndef MY_COCOA_WRAPPERS_H
#define MY_COCOA_WRAPPERS_H

#include <FL/x.H>
#include <FL/Fl_Window.H>

void setWindowTransparency(Fl_Window *w, double alpha);

#endif

And my-cocoa-wrappers.mm:

#import <Cocoa/Cocoa.h>

#include "my-cocoa-wrappers.h"

void setWindowTransparency(Fl_Window *w, double alpha) {
    [fl_xid(w) setAlphaValue:alpha];
}

The Makefile already took care of compiling my-cocoa-wrappers.mm as Objective-C instead of C++.


Edit 2: And here is a solution for Linux by Sanel Zukan which only depends on X11, not GTK+ as I expected it would need:

Atom atom = XInternAtom(fl_display, "_NET_WM_WINDOW_OPACITY", False);
uint32_t opacity = is_transparent ? 0xC0000000 : 0xFFFFFFFF;
XChangeProperty(fl_display, fl_xid(my_fltk_window), atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1);

Upvotes: 3

Views: 1813

Answers (1)

Remy
Remy

Reputation: 521

Here is a solution for Mac OS X. The main file calls this function:

#include "my-cocoa-wrappers.h"

setWindowTransparency(my_fltk_window, is_transparent ? 0.75 : 1.0);

Then I created my-cocoa-wrappers.h:

#ifndef MY_COCOA_WRAPPERS_H
#define MY_COCOA_WRAPPERS_H

#include <FL/x.H>
#include <FL/Fl_Window.H>

void setWindowTransparency(Fl_Window *w, double alpha);

#endif

And my-cocoa-wrappers.mm:

#import <Cocoa/Cocoa.h>

#include "my-cocoa-wrappers.h"

void setWindowTransparency(Fl_Window *w, double alpha) {
    [fl_xid(w) setAlphaValue:alpha];
}

The Makefile already took care of compiling my-cocoa-wrappers.mm as Objective-C instead of C++.


And here is a solution for Linux by Sanel Zukan which only depends on X11, not GTK+ as I expected it would need:

Atom atom = XInternAtom(fl_display, "_NET_WM_WINDOW_OPACITY", False);
uint32_t opacity = is_transparent ? 0xC0000000 : 0xFFFFFFFF;
XChangeProperty(fl_display, fl_xid(my_fltk_window), atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1);

Upvotes: 2

Related Questions