diff --git a/src/OpenMaui.AppImage/Program.cs b/src/OpenMaui.AppImage/Program.cs
index b1b90e4..56041b5 100644
--- a/src/OpenMaui.AppImage/Program.cs
+++ b/src/OpenMaui.AppImage/Program.cs
@@ -341,6 +341,8 @@ do_install() {{
fi
# Create .desktop file
+ # WM_CLASS is app name without spaces or underscores
+ WM_CLASS=$(echo ""$APPIMAGE_NAME"" | tr -d ' _')
cat > ""$APPS_DIR/${{SANITIZED}}.desktop"" << DESKTOP
[Desktop Entry]
Type=Application
@@ -350,6 +352,7 @@ Exec=$BIN_DIR/$APPIMAGE_BASENAME
Icon=$SANITIZED
Categories=$APPIMAGE_CATEGORY;
Terminal=false
+StartupWMClass=$WM_CLASS
X-AppImage-Version=$APPIMAGE_VERSION
DESKTOP
@@ -363,22 +366,26 @@ DESKTOP
return 0
}}
-# Check for first run - show zenity dialog
+# Check for first run or if already installed - show zenity dialog
+# Skip dialog entirely if running from installed location (~/.local/bin)
if [ -n ""$APPIMAGE"" ]; then
APPIMAGE_BASENAME=$(basename ""$APPIMAGE"")
- if [ ! -f ""$INSTALLED_MARKER/$APPIMAGE_BASENAME"" ] || [ ""$SHOW_INSTALLER"" = ""1"" ]; then
+ APPIMAGE_DIR=$(dirname ""$APPIMAGE"")
+ SANITIZED=$(echo ""$APPIMAGE_NAME"" | tr ' ' '_')
+
+ # If running from installed location, just run the app (no dialog)
+ if [ ""$APPIMAGE_DIR"" = ""$BIN_DIR"" ]; then
+ : # Skip to running the app
+ elif [ ""$SHOW_INSTALLER"" = ""1"" ]; then
+ # Forced install dialog
if command -v zenity &> /dev/null; then
- # Find app icon
- SANITIZED=$(echo ""$APPIMAGE_NAME"" | tr ' ' '_')
ICON_PATH=""""
for ext in svg png ico; do
[ -f ""$HERE/${{SANITIZED}}.${{ext}}"" ] && ICON_PATH=""$HERE/${{SANITIZED}}.${{ext}}"" && break
done
-
ICON_OPT=""""
[ -n ""$ICON_PATH"" ] && ICON_OPT=""--window-icon=$ICON_PATH""
- # Run zenity and capture exit code properly
zenity --question --title=""$APPIMAGE_NAME"" \
--text=""$APPIMAGE_NAME\nVersion $APPIMAGE_VERSION\n\n$APPIMAGE_COMMENT\n\nWould you like to install this application?"" \
--ok-label=""Install"" --cancel-label=""Run Only"" \
@@ -386,18 +393,85 @@ if [ -n ""$APPIMAGE"" ]; then
ZENITY_EXIT=$?
if [ $ZENITY_EXIT -eq 0 ]; then
- # Install clicked
do_install
- if [ $? -eq 0 ]; then
- zenity --info --title=""Installation Complete"" \
- --text=""$APPIMAGE_NAME has been installed.\n\nYou can find it in your application menu."" \
+ zenity --info --title=""Installation Complete"" \
+ --text=""$APPIMAGE_NAME has been installed.\n\nYou can find it in your application menu."" \
+ --width=300 $ICON_OPT 2>/dev/null
+ elif [ $ZENITY_EXIT -ne 1 ]; then
+ exit 0
+ fi
+ fi
+ elif [ -f ""$APPS_DIR/${{SANITIZED}}.desktop"" ]; then
+ # Already installed and running from different location - show options
+ if command -v zenity &> /dev/null; then
+ ICON_PATH=""""
+ for ext in svg png ico; do
+ [ -f ""$HERE/${{SANITIZED}}.${{ext}}"" ] && ICON_PATH=""$HERE/${{SANITIZED}}.${{ext}}"" && break
+ done
+ ICON_OPT=""""
+ [ -n ""$ICON_PATH"" ] && ICON_OPT=""--window-icon=$ICON_PATH""
+
+ CHOICE=$(zenity --list --title=""$APPIMAGE_NAME"" \
+ --text=""$APPIMAGE_NAME is already installed.\n\nWhat would you like to do?"" \
+ --radiolist --column="" "" --column=""Action"" \
+ TRUE ""Run the application"" \
+ FALSE ""Reinstall (update)"" \
+ FALSE ""Uninstall"" \
+ --width=400 --height=280 $ICON_OPT 2>/dev/null)
+ ZENITY_EXIT=$?
+
+ if [ $ZENITY_EXIT -ne 0 ]; then
+ exit 0
+ fi
+
+ case ""$CHOICE"" in
+ ""Run the application"")
+ :
+ ;;
+ ""Reinstall (update)"")
+ do_install
+ zenity --info --title=""Update Complete"" \
+ --text=""$APPIMAGE_NAME has been updated."" \
--width=300 $ICON_OPT 2>/dev/null
- fi
- elif [ $ZENITY_EXIT -eq 1 ]; then
- # Run Only clicked - continue to run the app
- :
- else
- # Dialog closed or error
+ ;;
+ ""Uninstall"")
+ rm -f ""$BIN_DIR/$APPIMAGE_BASENAME""
+ rm -f ""$APPS_DIR/${{SANITIZED}}.desktop""
+ rm -f ""$ICONS_DIR_SCALABLE/${{SANITIZED}}.svg""
+ rm -f ""$ICONS_DIR_256/${{SANITIZED}}.png""
+ rm -f ""$ICONS_DIR_256/${{SANITIZED}}.ico""
+ rm -f ""$INSTALLED_MARKER/$APPIMAGE_BASENAME""
+ command -v update-desktop-database &> /dev/null && update-desktop-database ""$APPS_DIR"" 2>/dev/null
+ command -v gtk-update-icon-cache &> /dev/null && gtk-update-icon-cache -f -t ""$HOME/.local/share/icons/hicolor"" 2>/dev/null
+ zenity --info --title=""Uninstall Complete"" \
+ --text=""$APPIMAGE_NAME has been removed."" \
+ --width=300 $ICON_OPT 2>/dev/null
+ exit 0
+ ;;
+ esac
+ fi
+ else
+ # Not installed - show install dialog
+ if command -v zenity &> /dev/null; then
+ ICON_PATH=""""
+ for ext in svg png ico; do
+ [ -f ""$HERE/${{SANITIZED}}.${{ext}}"" ] && ICON_PATH=""$HERE/${{SANITIZED}}.${{ext}}"" && break
+ done
+ ICON_OPT=""""
+ [ -n ""$ICON_PATH"" ] && ICON_OPT=""--window-icon=$ICON_PATH""
+
+ zenity --question --title=""$APPIMAGE_NAME"" \
+ --text=""$APPIMAGE_NAME\nVersion $APPIMAGE_VERSION\n\n$APPIMAGE_COMMENT\n\nWould you like to install this application?"" \
+ --ok-label=""Install"" --cancel-label=""Run Only"" \
+ --width=350 $ICON_OPT 2>/dev/null
+ ZENITY_EXIT=$?
+
+ if [ $ZENITY_EXIT -eq 0 ]; then
+ do_install
+ zenity --info --title=""Installation Complete"" \
+ --text=""$APPIMAGE_NAME has been installed.\n\nYou can find it in your application menu."" \
+ --width=300 $ICON_OPT 2>/dev/null
+ elif [ $ZENITY_EXIT -ne 1 ]; then
exit 0
fi
fi
@@ -426,6 +500,8 @@ fi
private async Task CreateDesktopFile(string path, PackageOptions options)
{
+ // WM_CLASS is app name without spaces or underscores (matches X11Window.cs)
+ var wmClass = options.AppName.Replace(" ", "").Replace("_", "");
var desktop = $@"[Desktop Entry]
Type=Application
Name={options.AppName}
@@ -434,6 +510,7 @@ Exec={SanitizeFileName(options.AppName)}
Icon={SanitizeFileName(options.AppName)}
Categories={options.Category};
Terminal=false
+StartupWMClass={wmClass}
X-AppImage-Version={options.Version}
";
await File.WriteAllTextAsync(path, desktop);