I was trying to make a transparent window with pass-through click events but:
GetWindow().MousePassthrough = true
only works for same application windows (I wanted to be for any other application/desktop), and:
GetWindow().MousePassthroughPolygon = null;
///
GetWindow().MousePassthroughPolygon = new []{new Vector2(), new Vector2(), new Vector2()};
is not really available either (the “clickable/unclickable” behavior is correct, but when in pass-through the window gets cut as well)
Intention: I was trying to render 3D meshes on a Transparent background (and transparent window as well ofc) and I already managed to detect the pixel under the cursor (if it’s alpha > .5f it should be clickable, else it should passthrough)
Is it even possible? Or if I have to deal with it at lower level / editing the engine, where should I even begin with?
It looks like currently (on windows) you will need to set your polygon to cover exactly what you want to see/click on. if you want to be able to click through things you can also see you’ll need to deal with the windows API directly, not sure how to do it but it seems possible
At last I resolved, using calls to the Windows API in C#
I am not 100% sure of what the things do and why, but it seems to be working
tl;dr if anyone wants to implement something like this
// [... inside a Node inherited class]
// GetActiveWindow() retrieves the handle of the currently active window on the desktop.
[DllImport("user32.dll")]
public static extern IntPtr GetActiveWindow();
// SetWindowLong() modifies a specific flag value associated with a window.
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
private const int GwlExStyle = -20;
// "Properties" of the window to be set, Layered is to have transparent pixels, Transparent is to make the window click-through
private const uint WsExLayered = 0x00080000;
private const uint WsExTransparent = 0x00000020;
// index reference of the window
private IntPtr _hWnd;
public override void _Ready()
{
// Get the reference of the game window
_hWnd = GetActiveWindow();
// setting the flags of becoming a layered and transparent window
SetWindowLong(_hWnd, GwlExStyle, WsExLayered | WsExTransparent);
}
// Call this method via your preferred detection algorythm (personally I check the
// pixel under cursor to have alpha < 0.5f but you do you)
public void SetClickThrough(bool clickthrough)
{
if (clickthrough)
{
SetWindowLong(_hWnd, GwlExStyle, WsExLayered | WsExTransparent);
}
else
{
SetWindowLong(_hWnd, GwlExStyle, WsExLayered);
}
}