Do you only need it for linux? I hacked some code together that seems to work (for both the case where only the background has to be transparent and the case where the entire contents has to be transparent).
The downside is that it required a modification in SFML:
diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp
index da697505..abbdd00e 100644
--- a/src/SFML/Window/Unix/WindowImplX11.cpp
+++ b/src/SFML/Window/Unix/WindowImplX11.cpp
@@ -573,13 +573,17 @@ m_lastInputTime (0)
int height = mode.height;
// Choose the visual according to the context settings
- XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings);
+ //XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings);
+
+ XVisualInfo visualInfo;
+ XMatchVisualInfo(m_display, m_screen, 32, TrueColor, &visualInfo);
// Define the window attributes
XSetWindowAttributes attributes;
attributes.colormap = XCreateColormap(m_display, DefaultRootWindow(m_display), visualInfo.visual, AllocNone);
attributes.event_mask = eventMask;
attributes.override_redirect = (m_fullscreen && !ewmhSupported()) ? True : False;
+ attributes.border_pixel = 0;
m_window = XCreateWindow(m_display,
DefaultRootWindow(m_display),
@@ -589,7 +593,7 @@ m_lastInputTime (0)
visualInfo.depth,
InputOutput,
visualInfo.visual,
- CWEventMask | CWOverrideRedirect | CWColormap,
+ CWEventMask | CWOverrideRedirect | CWColormap | CWBorderPixel,
&attributes);
if (!m_window)
After that the following code should give the result shown in the images above:
#include <SFML/Graphics.hpp>
// Comment this define to only make the background transparent and keep all other things drawn to the window opaque
#define TRANSPARENT_DRAWING
const unsigned char backgroundOpacity = 150;
int main(int argc, char* argv[])
{
sf::Image backgroundImage;
backgroundImage.loadFromFile("image.png");
sf::RenderWindow window(sf::VideoMode(backgroundImage.getSize().x, backgroundImage.getSize().y, 32), "Transparent Window");
window.setPosition(sf::Vector2i((sf::VideoMode::getDesktopMode().width - backgroundImage.getSize().x) / 2,
(sf::VideoMode::getDesktopMode().height - backgroundImage.getSize().y) / 2));
sf::Texture backgroundTexture;
sf::Sprite backgroundSprite;
backgroundTexture.loadFromImage(backgroundImage);
backgroundSprite.setTexture(backgroundTexture);
#ifdef TRANSPARENT_DRAWING
sf::RenderTexture renderTexture;
renderTexture.create(backgroundImage.getSize().x, backgroundImage.getSize().y, 32);
#endif
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape))
window.close();
}
#ifdef TRANSPARENT_DRAWING
renderTexture.clear(sf::Color::Transparent);
renderTexture.draw(backgroundSprite);
renderTexture.display();
sf::Sprite renderTextureSprite(renderTexture.getTexture());
renderTextureSprite.setColor({255, 255, 255, backgroundOpacity});
window.clear({0, 0, 0, backgroundOpacity});
window.draw(renderTextureSprite);
window.display();
#else
window.clear({0, 0, 0, backgroundOpacity});
window.draw(backgroundSprite);
window.display();
#endif
}
return 0;
}