diff --git a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs index 0972379dc0..11259f1ff3 100644 --- a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs +++ b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs @@ -124,6 +124,15 @@ namespace OpenRA.Platforms.Default [DllImport("user32.dll")] static extern bool SetProcessDPIAware(); + [DllImport("libX11")] + static extern IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists); + + [DllImport("libX11", CharSet=CharSet.Ansi)] + static extern int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, IntPtr mode, string data, int elements); + + [DllImport("libX11")] + static extern IntPtr XFlush(IntPtr display); + public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay, GLProfile requestProfile, bool enableLegacyGL) { @@ -218,10 +227,10 @@ namespace OpenRA.Platforms.Default window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay), SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay), windowSize.Width, windowSize.Height, windowFlags); - // Work around an issue in macOS's GL backend where the window remains permanently black - // (if dark mode is enabled) unless we drain the event queue before initializing GL if (Platform.CurrentPlatform == PlatformType.OSX) { + // Work around an issue in macOS's GL backend where the window remains permanently black + // (if dark mode is enabled) unless we drain the event queue before initializing GL while (SDL.SDL_PollEvent(out var e) != 0) { // We can safely ignore all mouse/keyboard events and window size changes @@ -241,6 +250,35 @@ namespace OpenRA.Platforms.Default } } } + else if (Platform.CurrentPlatform == PlatformType.Linux) + { + // The KDE task switcher limits itself to the 128px icon unless we + // set an X11 _KDE_NET_WM_DESKTOP_FILE property on the window + var currentDesktop = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP"); + var desktopFilename = Environment.GetEnvironmentVariable("OPENRA_DESKTOP_FILENAME"); + if (desktopFilename != null && currentDesktop == "KDE") + { + try + { + var info = default(SDL.SDL_SysWMinfo); + SDL.SDL_VERSION(out info.version); + SDL.SDL_GetWindowWMInfo(Window, ref info); + + var d = info.info.x11.display; + var w = info.info.x11.window; + var property = XInternAtom(d, "_KDE_NET_WM_DESKTOP_FILE", false); + var type = XInternAtom(d, "UTF8_STRING", false); + + XChangeProperty(d, w, property, type, 8, IntPtr.Zero, desktopFilename, desktopFilename.Length + 1); + XFlush(d); + } + catch + { + Log.Write("debug", "Failed to set _KDE_NET_WM_DESKTOP_FILE"); + Console.WriteLine("Failed to set _KDE_NET_WM_DESKTOP_FILE"); + } + } + } // Enable high resolution rendering for Retina displays if (Platform.CurrentPlatform == PlatformType.OSX) diff --git a/packaging/linux/openra.appimage.in b/packaging/linux/openra.appimage.in index 727545f5c2..45cac44b4f 100755 --- a/packaging/linux/openra.appimage.in +++ b/packaging/linux/openra.appimage.in @@ -8,19 +8,27 @@ cd "${HERE}/../lib/openra" || exit 1 if [ -n "${APPIMAGE}" ]; then LAUNCHER=${APPIMAGE} - # appimaged doesn't update the mime or icon caches when registering AppImages. - # Run update-desktop-database and gtk-update-icon-cache ourselves if we detect - # that the desktop file has been installed but the handler is not cached - if command -v update-desktop-database > /dev/null; then - APPIMAGEID=$(printf "file://%s" "${APPIMAGE}" | md5sum | cut -d' ' -f1) - LAUNCHER_NAME="appimagekit_${APPIMAGEID}-openra-{MODID}.desktop" - LAUNCHER_PATH="${HOME}/.local/share/applications/${LAUNCHER_NAME}" - MIMECACHE_PATH="${HOME}/.local/share/applications/mimeinfo.cache" - SCHEME="x-scheme-handler/openra-{MODID}-{TAG}" - if [ -f "${LAUNCHER_PATH}" ] && ! grep -qs "${SCHEME}=" "${MIMECACHE_PATH}"; then - update-desktop-database "${HOME}/.local/share/applications" - if command -v gtk-update-icon-cache > /dev/null; then - gtk-update-icon-cache ~/.local/share/icons/hicolor/ -t + APPIMAGEID=$(printf "file://%s" "${APPIMAGE}" | md5sum | cut -d' ' -f1) + LAUNCHER_NAME="appimagekit_${APPIMAGEID}-openra-{MODID}.desktop" + LAUNCHER_PATH="${HOME}/.local/share/applications/${LAUNCHER_NAME}" + export SDL_VIDEO_X11_WMCLASS="openra-{MODID}-{TAG}" + + if [ -f "${LAUNCHER_PATH}" ]; then + # The KDE task switcher limits itself to the 128px icon unless we + # set an X11 _KDE_NET_WM_DESKTOP_FILE property on the window + export OPENRA_DESKTOP_FILENAME="${LAUNCHER_NAME}" + + # appimaged doesn't update the mime or icon caches when registering AppImages. + # Run update-desktop-database and gtk-update-icon-cache ourselves if we detect + # that the desktop file has been installed but the handler is not cached + if command -v update-desktop-database > /dev/null; then + MIMECACHE_PATH="${HOME}/.local/share/applications/mimeinfo.cache" + SCHEME="x-scheme-handler/openra-{MODID}-{TAG}" + if ! grep -qs "${SCHEME}=" "${MIMECACHE_PATH}"; then + update-desktop-database "${HOME}/.local/share/applications" + if command -v gtk-update-icon-cache > /dev/null; then + gtk-update-icon-cache ~/.local/share/icons/hicolor/ -t + fi fi fi fi