I was able to do this job on Windows using JNA.
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.Color;
import com.mygdx.game.CharlatanoOverlay;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import static com.sun.jna.platform.win32.WinUser.*;
public class DesktopLauncher {
public static final WinDef.DWORD DWM_BB_ENABLE = new WinDef.DWORD(0x00000001);
public static final WinDef.DWORD DWM_BB_BLURREGION = new WinDef.DWORD(0x00000002);
public static final WinDef.DWORD DWM_BB_TRANSITIONONMAXIMIZED = new WinDef.DWORD(0x00000004);
public static final WinDef.HWND HWND_TOPPOS = new WinDef.HWND(new Pointer(-1));
private static final int SWP_NOSIZE = 0x0001;
private static final int SWP_NOMOVE = 0x0002;
private static final int WS_EX_TOOLWINDOW = 0x00000080;
private static final int WS_EX_APPWINDOW = 0x00040000;
public static void main(String[] arg) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
System.setProperty("org.lwjgl.opengl.Window.undecorated", "true");
cfg.width = LwjglApplicationConfiguration.getDesktopDisplayMode().width-1;
cfg.height = LwjglApplicationConfiguration.getDesktopDisplayMode().height-1;
cfg.resizable = false;
cfg.fullscreen = false;
cfg.initialBackgroundColor = new Color(0, 0, 0, 0);
new LwjglApplication(new CharlatanoOverlay(), cfg);
WinDef.HWND hwnd;
while ((hwnd = User32.INSTANCE.FindWindow(null, "CharlatanoOverlay")) == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(hwnd);
System.out.println(transparentWindow(hwnd));
}
public static boolean transparentWindow(WinDef.HWND hwnd) {
DWM_BLURBEHIND bb = new DWM_BLURBEHIND();
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.hRgnBlur = null;
DWM.DwmEnableBlurBehindWindow(hwnd, bb);
int wl = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT;
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
wl &= ~(WS_VISIBLE);
wl |= WS_EX_TOOLWINDOW;
wl &= ~(WS_EX_APPWINDOW);
User32.INSTANCE.ShowWindow(hwnd, SW_HIDE);
User32.INSTANCE.SetWindowLong(hwnd, GWL_STYLE, wl);
User32.INSTANCE.ShowWindow(hwnd, SW_SHOW);
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
return User32.INSTANCE.SetWindowPos(hwnd, HWND_TOPPOS, 0, 0, 2560, 1440, SWP_NOMOVE | SWP_NOSIZE);
}
}
DWM:
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
public class DWM {
static {
Native.register("Dwmapi");
}
public static native WinNT.HRESULT DwmEnableBlurBehindWindow(WinDef.HWND hWnd, DWM_BLURBEHIND pBlurBehind);
}
DWM_BLURBEHIND:
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import java.util.Arrays;
import java.util.List;
public class DWM_BLURBEHIND extends Structure {
public WinDef.DWORD dwFlags;
public boolean fEnable;
public WinDef.HRGN hRgnBlur;
public boolean fTransitionOnMaximized;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("dwFlags", "fEnable", "hRgnBlur", "fTransitionOnMaximized");
}
}