From e4d996f4a6f588d234ac1ae83dcf62ac4e896209 Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Tue, 16 Jun 2026 17:53:18 +0200 Subject: [PATCH 1/9] feat: add scripts for gui launcher windows, linux, macos --- .gitattributes | 4 + gui/scripts/linux/create-shortcuts.sh | 113 +++++++++++++++++++++++ gui/scripts/linux/launch-gui.sh | 35 +++++++ gui/scripts/macos/create-shortcuts.sh | 113 +++++++++++++++++++++++ gui/scripts/macos/launch-gui.command | 37 ++++++++ gui/scripts/windows/create-shortcuts.ps1 | 80 ++++++++++++++++ gui/scripts/windows/launch-gui.bat | 36 ++++++++ 7 files changed, 418 insertions(+) create mode 100644 gui/scripts/linux/create-shortcuts.sh create mode 100644 gui/scripts/linux/launch-gui.sh create mode 100644 gui/scripts/macos/create-shortcuts.sh create mode 100644 gui/scripts/macos/launch-gui.command create mode 100644 gui/scripts/windows/create-shortcuts.ps1 create mode 100644 gui/scripts/windows/launch-gui.bat diff --git a/.gitattributes b/.gitattributes index 7e7a79ac69..6d1dc4b290 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,9 @@ * eol=lf *.bat eol=crlf +*.ps1 eol=crlf +*.ps2 eol=crlf +*.sh eol=lf +*.command eol=lf *.png binary *.zip binary *.tgz binary diff --git a/gui/scripts/linux/create-shortcuts.sh b/gui/scripts/linux/create-shortcuts.sh new file mode 100644 index 0000000000..e59ff6bf42 --- /dev/null +++ b/gui/scripts/linux/create-shortcuts.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# IDEasy GUI Shortcut Creator for Linux +# Creates .desktop files for easy GUI launching from the Application Menu and Desktop +# Supports: GNOME, KDE, XFCE, and other freedesktop-compatible environments + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +LAUNCHER_SCRIPT="$SCRIPT_DIR/launch-gui.sh" + +# Set error handling - exit on error but allow catching specific errors +set -o pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +function print_error() { + echo -e "${RED}Error: $1${NC}" >&2 +} + +function print_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +function print_info() { + echo -e "${YELLOW}ℹ $1${NC}" +} + +# Verify launcher script exists and is executable +if [ ! -f "$LAUNCHER_SCRIPT" ]; then + print_error "Launcher script not found: $LAUNCHER_SCRIPT" + exit 1 +fi + +chmod +x "$LAUNCHER_SCRIPT" + +# Create Desktop Entry (.desktop file) +function create_desktop_entry() { + local target_dir="$1" + local desktop_file="$target_dir/ideasy-gui.desktop" + + if [ ! -f "$LAUNCHER_SCRIPT" ]; then + print_error "Launcher script not found: $LAUNCHER_SCRIPT" + return 1 + fi + + if ! mkdir -p "$target_dir" 2>/dev/null; then + print_error "Failed to create directory: $target_dir" + return 1 + fi + + # Use absolute path to ensure it works from anywhere + local absolute_launcher="$(cd "$(dirname "$LAUNCHER_SCRIPT")"; pwd)/$(basename "$LAUNCHER_SCRIPT")" + + if ! cat > "$desktop_file" </dev/null; then + print_error "Failed to make executable: $desktop_file" + return 1 + fi + + print_success "Created: $desktop_file" + return 0 +} + +# Create application menu entry +APPLICATIONS_DIR="$HOME/.local/share/applications" +if ! create_desktop_entry "$APPLICATIONS_DIR"; then + print_info "Note: Could not create application menu entry (may require additional permissions)" +else + print_info "Launch from: Application Menu or Launcher" +fi + +# Create Desktop entry +DESKTOP_DIR="$HOME/Desktop" +if [ -d "$DESKTOP_DIR" ]; then + if ! create_desktop_entry "$DESKTOP_DIR"; then + print_info "Note: Desktop entry creation requires write permissions" + else + print_info "Launch from: Desktop" + fi +else + print_info "Desktop directory not found (Desktop feature may not be available)" +fi + +echo "" +print_success "IDEasy GUI shortcuts ready!" +echo "" +echo "Usage:" +echo " • Open your Application Menu and search for 'IDEasy GUI'" +echo " • Or double-click the shortcut on your Desktop" +echo " • First launch may take longer as Maven downloads dependencies" +echo "" + diff --git a/gui/scripts/linux/launch-gui.sh b/gui/scripts/linux/launch-gui.sh new file mode 100644 index 0000000000..137fb7c468 --- /dev/null +++ b/gui/scripts/linux/launch-gui.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# IDEasy GUI Launcher for Linux +# This script launches the IDEasy GUI using the native 'ide gui' command +# The GUI runs in the background, the script exits immediately + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +if [ ! -f "$PROJECT_ROOT/pom.xml" ]; then + echo "Error: IDEasy project root not found at $PROJECT_ROOT" + echo "Please ensure this script is located in: IDEasy/gui/scripts/linux/" + exit 1 +fi + +if ! command -v ide &> /dev/null; then + echo "" + echo "Error: IDEasy is not installed" + echo "" + echo "Please install IDEasy first:" + echo "https://github.com/devonfw/IDEasy#setup" + echo "" + exit 1 +fi + +cd "$PROJECT_ROOT" + +# Launch IDE GUI in background and exit immediately +# Redirect output to suppress any console messages +ide gui > /dev/null 2>&1 & + +# Give the process a moment to start (may need time for Maven dependencies on first run) +sleep 3 + +exit 0 diff --git a/gui/scripts/macos/create-shortcuts.sh b/gui/scripts/macos/create-shortcuts.sh new file mode 100644 index 0000000000..a7e8431c5c --- /dev/null +++ b/gui/scripts/macos/create-shortcuts.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# IDEasy GUI Shortcut Creator for macOS +# Creates shortcuts for easy GUI launching from Finder +# Supports creating: Applications folder alias and Desktop alias + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +LAUNCHER_SCRIPT="$SCRIPT_DIR/launch-gui.command" + +# Set error handling - exit on error but allow catching specific errors +set -o pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +function print_error() { + echo -e "${RED}Error: $1${NC}" >&2 +} + +function print_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +function print_info() { + echo -e "${YELLOW}ℹ $1${NC}" +} + +# Verify launcher script exists and is executable +if [ ! -f "$LAUNCHER_SCRIPT" ]; then + print_error "Launcher script not found: $LAUNCHER_SCRIPT" + exit 1 +fi + +chmod +x "$LAUNCHER_SCRIPT" + +# Create an alias/shortcut using osascript (AppleScript) +function create_alias() { + local source="$1" + local target_dir="$2" + local target_name="$3" + + if [ ! -f "$source" ]; then + print_error "Source file not found: $source" + return 1 + fi + + if ! mkdir -p "$target_dir" 2>/dev/null; then + print_error "Failed to create directory: $target_dir" + return 1 + fi + + # Properly escape paths for AppleScript + local escaped_source="$(printf '%s\n' "$source" | sed 's/\\/\\\\/g; s/"/\\"/g')" + local escaped_target_dir="$(printf '%s\n' "$target_dir" | sed 's/\\/\\\\/g; s/"/\\"/g')" + local escaped_target_name="$(printf '%s\n' "$target_name" | sed 's/\\/\\\\/g; s/"/\\"/g')" + + local output + output=$(osascript 2>&1 < IDEasy GUI" +fi + +# Create Desktop alias +DESKTOP_DIR="$HOME/Desktop" +if create_alias "$LAUNCHER_SCRIPT" "$DESKTOP_DIR" "IDEasy GUI"; then + print_info "Launch from: Desktop" +else + print_info "Note: Desktop shortcut creation requires manual steps" + print_info "You can manually create a shortcut by:" + print_info "1. Open Finder" + print_info "2. Go to $SCRIPT_DIR" + print_info "3. Right-click 'launch-gui.command' → Make Alias" + print_info "4. Drag alias to Desktop or Applications" +fi + +echo "" +print_success "IDEasy GUI shortcuts ready!" +echo "" +echo "Usage:" +echo " • Open Finder and go to Applications" +echo " • Double-click 'IDEasy GUI' to launch" +echo " • Or double-click the Desktop shortcut" +echo "" diff --git a/gui/scripts/macos/launch-gui.command b/gui/scripts/macos/launch-gui.command new file mode 100644 index 0000000000..d7538fd7a3 --- /dev/null +++ b/gui/scripts/macos/launch-gui.command @@ -0,0 +1,37 @@ +#!/bin/bash + +# IDEasy GUI Launcher for macOS +# This script launches the IDEasy GUI using the native 'ide gui' command +# The GUI runs in the background, the script exits immediately + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +if [ ! -f "$PROJECT_ROOT/pom.xml" ]; then + echo "Error: IDEasy project root not found at $PROJECT_ROOT" + echo "Please ensure this script is located in: IDEasy/gui/scripts/macos/" + read -p "Press Enter to close..." + exit 1 +fi + +if ! command -v ide &> /dev/null; then + echo "" + echo "Error: IDEasy is not installed" + echo "" + echo "Please install IDEasy first:" + echo "https://github.com/devonfw/IDEasy#setup" + echo "" + read -p "Press Enter to close..." + exit 1 +fi + +cd "$PROJECT_ROOT" + +# Launch IDE GUI in background and exit immediately +ide gui > /dev/null 2>&1 & + +# Give the process a moment to start (may need time for Maven dependencies on first run) +sleep 3 + +# Close this terminal window after the GUI is launched +exit 0 diff --git a/gui/scripts/windows/create-shortcuts.ps1 b/gui/scripts/windows/create-shortcuts.ps1 new file mode 100644 index 0000000000..c42c146a85 --- /dev/null +++ b/gui/scripts/windows/create-shortcuts.ps1 @@ -0,0 +1,80 @@ +#Requires -Version 5.0 + +# IDEasy GUI Launcher - Create Windows Start Menu Shortcut and Desktop Link +# This script creates shortcuts to launch the IDEasy GUI from Windows Start Menu and Desktop + +param ( + [switch]$SkipDesktop, + [switch]$SkipStartMenu +) + +$ErrorActionPreference = 'Stop' + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$guiDir = Split-Path -Parent (Split-Path -Parent $scriptDir) +$projectRoot = Split-Path -Parent $guiDir + +$launcherBat = Join-Path $scriptDir "launch-gui.bat" +$pomFile = Join-Path $projectRoot "pom.xml" + +if (-not (Test-Path $launcherBat)) { + Write-Host "Error: launch-gui.bat not found" -ForegroundColor Red + exit 1 +} + +if (-not (Test-Path $pomFile)) { + Write-Host "Error: pom.xml not found" -ForegroundColor Red + exit 1 +} + +Write-Host "IDEasy GUI Launcher Setup" -ForegroundColor Cyan +Write-Host "Project: $projectRoot" -ForegroundColor Cyan +Write-Host "" + +function Create-Shortcut { + param( + [string]$Path, + [string]$Target, + [string]$Description + ) + + $wshShell = New-Object -ComObject WScript.Shell + + try { + Write-Host "Creating shortcut: $Path" + + $shortcut = $wshShell.CreateShortcut($Path) + $shortcut.TargetPath = $Target + $shortcut.WorkingDirectory = $projectRoot + $shortcut.Description = $Description + + $iconPath = Join-Path $scriptDir "icon.ico" + if (Test-Path $iconPath) { + $shortcut.IconLocation = "$iconPath,0" + } else { + $shortcut.IconLocation = "$env:SystemRoot\system32\shell32.dll,1" + } + + $shortcut.Save() + Write-Host "Created: $Path" -ForegroundColor Green + } + catch { + Write-Host "Error creating shortcut: $($_.Exception.Message)" -ForegroundColor Red + } + finally { + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wshShell) | Out-Null + } +} + +if (-not $SkipDesktop) { + $desktopShortcut = Join-Path "$env:USERPROFILE\Desktop" "IDEasy GUI.lnk" + Create-Shortcut -Path $desktopShortcut -Target $launcherBat -Description "Launch IDEasy GUI" +} + +if (-not $SkipStartMenu) { + $startMenuShortcut = Join-Path "$env:APPDATA\Microsoft\Windows\Start Menu\Programs" "IDEasy GUI.lnk" + Create-Shortcut -Path $startMenuShortcut -Target $launcherBat -Description "Launch IDEasy GUI" +} + +Write-Host "" +Write-Host "Setup complete!" -ForegroundColor Green diff --git a/gui/scripts/windows/launch-gui.bat b/gui/scripts/windows/launch-gui.bat new file mode 100644 index 0000000000..2d612be744 --- /dev/null +++ b/gui/scripts/windows/launch-gui.bat @@ -0,0 +1,36 @@ +@echo off +setlocal + +REM IDEasy GUI Launcher for Windows + +set "SCRIPT_DIR=%~dp0" + +REM Check if ide command exists +where ide >nul 2>&1 || ( + echo. + echo Error: IDEasy is not installed or not in PATH + echo https://github.com/devonfw/IDEasy#setup + echo. + pause + exit /b 1 +) + +REM Determine project root safely +pushd "%SCRIPT_DIR%..\..\.." +set "PROJECT_ROOT=%CD%" +popd + +REM Check project structure +if not exist "%PROJECT_ROOT%\pom.xml" ( + echo Error: IDEasy project root not found at %PROJECT_ROOT% + echo. + pause + exit /b 1 +) + +REM Launch GUI +cd /d "%PROJECT_ROOT%" +echo Starting IDEasy GUI... +START "" ide gui + +exit /b 0 \ No newline at end of file From e7c5854380a53fe23deece82e2834f0afac2357b Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Wed, 17 Jun 2026 12:13:56 +0200 Subject: [PATCH 2/9] feat: update scripts and using correct icon --- .gitignore | 3 + gui/scripts/linux/create-shortcuts.sh | 36 ++++++----- gui/scripts/linux/launch-gui.sh | 7 +- gui/scripts/macos/create-shortcuts.sh | 28 +++++--- gui/scripts/macos/launch-gui.command | 7 +- gui/scripts/windows/create-shortcuts.ps1 | 82 ++++++++++++++++++++---- gui/scripts/windows/launch-gui.bat | 4 +- 7 files changed, 117 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index 4cfa743f86..5f8dc176d2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ eclipse-target/ generated/ node_modules +# Generated GUI assets (created at runtime, not to be committed) +gui/scripts/windows/ideasy-gui.ico + # Package Files # *.jar *.war diff --git a/gui/scripts/linux/create-shortcuts.sh b/gui/scripts/linux/create-shortcuts.sh index e59ff6bf42..16d28b694e 100644 --- a/gui/scripts/linux/create-shortcuts.sh +++ b/gui/scripts/linux/create-shortcuts.sh @@ -5,8 +5,8 @@ # Supports: GNOME, KDE, XFCE, and other freedesktop-compatible environments SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" LAUNCHER_SCRIPT="$SCRIPT_DIR/launch-gui.sh" +ICON_PATH="$SCRIPT_DIR/../../src/main/resources/com/devonfw/ide/gui/assets/devonfw.png" # Set error handling - exit on error but allow catching specific errors set -o pipefail @@ -37,32 +37,31 @@ fi chmod +x "$LAUNCHER_SCRIPT" +# Resolve icon: use bundled devonfw.png if available, otherwise fall back to system theme +if [ -f "$ICON_PATH" ]; then + ICON="$(cd "$(dirname "$ICON_PATH")" && pwd)/$(basename "$ICON_PATH")" +else + ICON="application-x-executable" +fi + # Create Desktop Entry (.desktop file) function create_desktop_entry() { local target_dir="$1" local desktop_file="$target_dir/ideasy-gui.desktop" - - if [ ! -f "$LAUNCHER_SCRIPT" ]; then - print_error "Launcher script not found: $LAUNCHER_SCRIPT" - return 1 - fi - + if ! mkdir -p "$target_dir" 2>/dev/null; then print_error "Failed to create directory: $target_dir" return 1 fi - - # Use absolute path to ensure it works from anywhere - local absolute_launcher="$(cd "$(dirname "$LAUNCHER_SCRIPT")"; pwd)/$(basename "$LAUNCHER_SCRIPT")" - + if ! cat > "$desktop_file" </dev/null || true print_info "Launch from: Application Menu or Launcher" fi -# Create Desktop entry -DESKTOP_DIR="$HOME/Desktop" +# Determine desktop directory via XDG standard (respects custom Desktop locations) +DESKTOP_DIR=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop") if [ -d "$DESKTOP_DIR" ]; then if ! create_desktop_entry "$DESKTOP_DIR"; then print_info "Note: Desktop entry creation requires write permissions" else + # GNOME 3.28+: mark desktop file as trusted so it can be launched by double-click + gio set "$DESKTOP_DIR/ideasy-gui.desktop" "metadata::trusted" true 2>/dev/null || true print_info "Launch from: Desktop" fi else @@ -110,4 +113,3 @@ echo " • Open your Application Menu and search for 'IDEasy GUI'" echo " • Or double-click the shortcut on your Desktop" echo " • First launch may take longer as Maven downloads dependencies" echo "" - diff --git a/gui/scripts/linux/launch-gui.sh b/gui/scripts/linux/launch-gui.sh index 137fb7c468..1a87233c60 100644 --- a/gui/scripts/linux/launch-gui.sh +++ b/gui/scripts/linux/launch-gui.sh @@ -26,10 +26,7 @@ fi cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately -# Redirect output to suppress any console messages -ide gui > /dev/null 2>&1 & - -# Give the process a moment to start (may need time for Maven dependencies on first run) -sleep 3 +LOG_FILE="$HOME/.ideasy-gui.log" +ide gui >> "$LOG_FILE" 2>&1 & exit 0 diff --git a/gui/scripts/macos/create-shortcuts.sh b/gui/scripts/macos/create-shortcuts.sh index a7e8431c5c..4e262b948b 100644 --- a/gui/scripts/macos/create-shortcuts.sh +++ b/gui/scripts/macos/create-shortcuts.sh @@ -5,7 +5,6 @@ # Supports creating: Applications folder alias and Desktop alias SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" LAUNCHER_SCRIPT="$SCRIPT_DIR/launch-gui.command" # Set error handling - exit on error but allow catching specific errors @@ -38,26 +37,27 @@ fi chmod +x "$LAUNCHER_SCRIPT" # Create an alias/shortcut using osascript (AppleScript) +# Falls back to a symlink if Finder is not running or AppleScript fails function create_alias() { local source="$1" local target_dir="$2" local target_name="$3" - + if [ ! -f "$source" ]; then print_error "Source file not found: $source" return 1 fi - + if ! mkdir -p "$target_dir" 2>/dev/null; then print_error "Failed to create directory: $target_dir" return 1 fi - + # Properly escape paths for AppleScript local escaped_source="$(printf '%s\n' "$source" | sed 's/\\/\\\\/g; s/"/\\"/g')" local escaped_target_dir="$(printf '%s\n' "$target_dir" | sed 's/\\/\\\\/g; s/"/\\"/g')" local escaped_target_name="$(printf '%s\n' "$target_name" | sed 's/\\/\\\\/g; s/"/\\"/g')" - + local output output=$(osascript 2>&1 </dev/null; then + print_success "Created symlink: $target_dir/$target_name.command" + return 0 + fi + + print_error "Failed to create shortcut: $target_dir/$target_name" + [ -n "$output" ] && print_error "Reason: $output" + return 1 } # Create Applications alias diff --git a/gui/scripts/macos/launch-gui.command b/gui/scripts/macos/launch-gui.command index d7538fd7a3..91618250f3 100644 --- a/gui/scripts/macos/launch-gui.command +++ b/gui/scripts/macos/launch-gui.command @@ -28,10 +28,7 @@ fi cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately -ide gui > /dev/null 2>&1 & +LOG_FILE="$HOME/.ideasy-gui.log" +ide gui >> "$LOG_FILE" 2>&1 & -# Give the process a moment to start (may need time for Maven dependencies on first run) -sleep 3 - -# Close this terminal window after the GUI is launched exit 0 diff --git a/gui/scripts/windows/create-shortcuts.ps1 b/gui/scripts/windows/create-shortcuts.ps1 index c42c146a85..f1c1226899 100644 --- a/gui/scripts/windows/create-shortcuts.ps1 +++ b/gui/scripts/windows/create-shortcuts.ps1 @@ -31,29 +31,86 @@ Write-Host "IDEasy GUI Launcher Setup" -ForegroundColor Cyan Write-Host "Project: $projectRoot" -ForegroundColor Cyan Write-Host "" +# Wrap the PNG bytes directly into an ICO container (Windows Vista+ supports PNG frames in ICO). +# This preserves full color depth and alpha transparency without any image processing. +# The ICO is written next to the scripts so the shortcut has a stable reference path. +# Returns $true on success, $false on failure. +function Convert-PngToIco { + param([string]$PngPath, [string]$IcoPath) + try { + $pngBytes = [System.IO.File]::ReadAllBytes($PngPath) + + # PNG dimensions are stored big-endian in the IHDR chunk at bytes 16-23 + $width = ($pngBytes[16] -shl 24) -bor ($pngBytes[17] -shl 16) -bor ($pngBytes[18] -shl 8) -bor $pngBytes[19] + $height = ($pngBytes[20] -shl 24) -bor ($pngBytes[21] -shl 16) -bor ($pngBytes[22] -shl 8) -bor $pngBytes[23] + + # ICO directory encodes 256 as 0 + $icoW = if ($width -ge 256) { [byte]0 } else { [byte]$width } + $icoH = if ($height -ge 256) { [byte]0 } else { [byte]$height } + + $sizeBytes = [System.BitConverter]::GetBytes([int32]$pngBytes.Length) + $offsetBytes = [System.BitConverter]::GetBytes([int32](6 + 16)) # header(6) + one dir entry(16) + + # ICO header (6 bytes) + single directory entry (16 bytes) + $icoHeader = [byte[]]( + 0x00, 0x00, # reserved + 0x01, 0x00, # type: icon + 0x01, 0x00, # image count: 1 + $icoW, $icoH, 0x00, 0x00, # w, h, colorCount, reserved + 0x01, 0x00, # color planes + 0x20, 0x00, # bits per pixel (32) + $sizeBytes[0], $sizeBytes[1], $sizeBytes[2], $sizeBytes[3], # image data size + $offsetBytes[0], $offsetBytes[1], $offsetBytes[2], $offsetBytes[3] # image data offset + ) + + $stream = [System.IO.FileStream]::new($IcoPath, [System.IO.FileMode]::Create) + $stream.Write($icoHeader, 0, $icoHeader.Length) + $stream.Write($pngBytes, 0, $pngBytes.Length) + $stream.Close() + return $true + } + catch { + return $false + } +} + +# Resolve icon location: prefer devonfw.png converted to ICO, fall back to shell32 +$pngSource = Join-Path $guiDir "src\main\resources\com\devonfw\ide\gui\assets\devonfw.png" +$generatedIco = Join-Path $scriptDir "ideasy-gui.ico" +$iconLocation = "$env:SystemRoot\system32\shell32.dll,1" + +if (Test-Path $pngSource) { + if (-not (Test-Path $generatedIco)) { + if (Convert-PngToIco -PngPath $pngSource -IcoPath $generatedIco) { + Write-Host "Icon generated from devonfw.png" -ForegroundColor Cyan + } else { + Write-Host "Note: Icon conversion failed, using default icon" -ForegroundColor Yellow + } + } + if (Test-Path $generatedIco) { + $iconLocation = "$generatedIco,0" + } +} elseif (Test-Path (Join-Path $scriptDir "icon.ico")) { + $iconLocation = "$(Join-Path $scriptDir 'icon.ico'),0" +} + function Create-Shortcut { param( [string]$Path, [string]$Target, [string]$Description ) - - $wshShell = New-Object -ComObject WScript.Shell + $wshShell = $null try { Write-Host "Creating shortcut: $Path" + $wshShell = New-Object -ComObject WScript.Shell $shortcut = $wshShell.CreateShortcut($Path) $shortcut.TargetPath = $Target $shortcut.WorkingDirectory = $projectRoot $shortcut.Description = $Description - - $iconPath = Join-Path $scriptDir "icon.ico" - if (Test-Path $iconPath) { - $shortcut.IconLocation = "$iconPath,0" - } else { - $shortcut.IconLocation = "$env:SystemRoot\system32\shell32.dll,1" - } + $shortcut.IconLocation = $iconLocation $shortcut.Save() Write-Host "Created: $Path" -ForegroundColor Green @@ -62,12 +119,15 @@ function Create-Shortcut { Write-Host "Error creating shortcut: $($_.Exception.Message)" -ForegroundColor Red } finally { - [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wshShell) | Out-Null + if ($wshShell) { + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wshShell) | Out-Null + } } } if (-not $SkipDesktop) { - $desktopShortcut = Join-Path "$env:USERPROFILE\Desktop" "IDEasy GUI.lnk" + # Use Shell32 to resolve the Desktop folder — works correctly with OneDrive-redirected Desktops + $desktopShortcut = Join-Path ([Environment]::GetFolderPath('Desktop')) "IDEasy GUI.lnk" Create-Shortcut -Path $desktopShortcut -Target $launcherBat -Description "Launch IDEasy GUI" } diff --git a/gui/scripts/windows/launch-gui.bat b/gui/scripts/windows/launch-gui.bat index 2d612be744..7bbe8dc26f 100644 --- a/gui/scripts/windows/launch-gui.bat +++ b/gui/scripts/windows/launch-gui.bat @@ -31,6 +31,6 @@ if not exist "%PROJECT_ROOT%\pom.xml" ( REM Launch GUI cd /d "%PROJECT_ROOT%" echo Starting IDEasy GUI... -START "" ide gui +START "" /B ide gui >> "%USERPROFILE%\.ideasy-gui.log" 2>&1 -exit /b 0 \ No newline at end of file +exit /b 0 From 2a7d8720f135866dc383b1fe95b7b294a14e66ae Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Thu, 18 Jun 2026 11:12:32 +0200 Subject: [PATCH 3/9] fix: minor directory bug for linux --- gui/scripts/linux/create-shortcuts.sh | 11 +++++++++-- gui/scripts/linux/launch-gui.sh | 24 ++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/gui/scripts/linux/create-shortcuts.sh b/gui/scripts/linux/create-shortcuts.sh index 16d28b694e..b7775ce6a7 100644 --- a/gui/scripts/linux/create-shortcuts.sh +++ b/gui/scripts/linux/create-shortcuts.sh @@ -60,7 +60,7 @@ Version=1.0 Type=Application Name=IDEasy GUI Comment=Launch IDEasy Integrated Development Environment GUI -Exec="$LAUNCHER_SCRIPT" +Exec=$LAUNCHER_SCRIPT Icon=$ICON Terminal=false Categories=Development;IDE; @@ -91,8 +91,15 @@ else print_info "Launch from: Application Menu or Launcher" fi -# Determine desktop directory via XDG standard (respects custom Desktop locations) +# Determine desktop directory via XDG standard (respects custom Desktop locations). +# On systems where xdg-user-dirs was never configured (e.g. minimal WM setups), +# xdg-user-dir falls back to printing $HOME itself — guard against that so we +# don't drop a loose .desktop file directly into the user's home directory. DESKTOP_DIR=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop") +DESKTOP_DIR="${DESKTOP_DIR%/}" +if [ -z "$DESKTOP_DIR" ] || [ "$DESKTOP_DIR" = "$HOME" ]; then + DESKTOP_DIR="$HOME/Desktop" +fi if [ -d "$DESKTOP_DIR" ]; then if ! create_desktop_entry "$DESKTOP_DIR"; then print_info "Note: Desktop entry creation requires write permissions" diff --git a/gui/scripts/linux/launch-gui.sh b/gui/scripts/linux/launch-gui.sh index 1a87233c60..f0763b2780 100644 --- a/gui/scripts/linux/launch-gui.sh +++ b/gui/scripts/linux/launch-gui.sh @@ -6,27 +6,35 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +LOG_FILE="$HOME/.ideasy-gui.log" + +# When launched from an application menu (Terminal=false), there is no console to +# show errors on. Redirect everything to a log file from the start so failures +# (e.g. 'ide' missing from the launcher's PATH) are diagnosable after the fact +exec >> "$LOG_FILE" 2>&1 +echo "---- $(date) ----" + +function notify_error() { + command -v notify-send &> /dev/null && notify-send -i dialog-error "IDEasy GUI" "$1" +} if [ ! -f "$PROJECT_ROOT/pom.xml" ]; then echo "Error: IDEasy project root not found at $PROJECT_ROOT" echo "Please ensure this script is located in: IDEasy/gui/scripts/linux/" + notify_error "Project root not found at $PROJECT_ROOT" exit 1 fi if ! command -v ide &> /dev/null; then - echo "" - echo "Error: IDEasy is not installed" - echo "" - echo "Please install IDEasy first:" - echo "https://github.com/devonfw/IDEasy#setup" - echo "" + echo "Error: IDEasy is not installed or not in PATH" + echo "Please install IDEasy first: https://github.com/devonfw/IDEasy#setup" + notify_error "'ide' command not found in PATH (see $LOG_FILE)" exit 1 fi cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately -LOG_FILE="$HOME/.ideasy-gui.log" -ide gui >> "$LOG_FILE" 2>&1 & +ide gui & exit 0 From 470006ec3faaea35653f7aed4774b160d3199c6a Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Fri, 19 Jun 2026 10:36:28 +0200 Subject: [PATCH 4/9] feat: update linux script --- gui/scripts/linux/launch-gui.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gui/scripts/linux/launch-gui.sh b/gui/scripts/linux/launch-gui.sh index f0763b2780..84bf508947 100644 --- a/gui/scripts/linux/launch-gui.sh +++ b/gui/scripts/linux/launch-gui.sh @@ -25,16 +25,21 @@ if [ ! -f "$PROJECT_ROOT/pom.xml" ]; then exit 1 fi -if ! command -v ide &> /dev/null; then +# 'ide' is a shell function defined in $IDE_ROOT/_ide/installation/functions and +# sourced by ~/.bashrc / ~/.zshrc — those only get sourced in interactive shells. +# Application launchers (Terminal=false) start a plain, non-interactive shell, so +# 'ide' is invisible there even though it works fine from a terminal. Route through +# an interactive bash so the function gets sourced regardless of launch context. +if ! bash -ic "command -v ide" &> /dev/null; then echo "Error: IDEasy is not installed or not in PATH" echo "Please install IDEasy first: https://github.com/devonfw/IDEasy#setup" - notify_error "'ide' command not found in PATH (see $LOG_FILE)" + notify_error "'ide' command not found (see $LOG_FILE)" exit 1 fi cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately -ide gui & +bash -ic "ide gui" & exit 0 From 1c7a1cca23b707761290721276c14eb41728f900 Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Tue, 23 Jun 2026 15:04:55 +0200 Subject: [PATCH 5/9] fix: not updated root environment --- gui/scripts/windows/launch-gui.bat | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gui/scripts/windows/launch-gui.bat b/gui/scripts/windows/launch-gui.bat index 7bbe8dc26f..753ed321a1 100644 --- a/gui/scripts/windows/launch-gui.bat +++ b/gui/scripts/windows/launch-gui.bat @@ -5,10 +5,24 @@ REM IDEasy GUI Launcher for Windows set "SCRIPT_DIR=%~dp0" +REM Desktop/Start-Menu shortcuts are spawned by explorer.exe, which caches its +REM environment from login and does not pick up registry PATH/IDE_ROOT changes +REM made by the IDEasy installer until the user logs off or restarts explorer. +REM Re-read IDE_ROOT directly from the registry and extend PATH with it here, +REM so the shortcut works even with explorer's stale inherited environment. +if not defined IDE_ROOT ( + for /f "tokens=2,*" %%A in ('reg query "HKCU\Environment" /v IDE_ROOT 2^>nul') do set "IDE_ROOT=%%B" +) +if defined IDE_ROOT ( + set "PATH=%IDE_ROOT%\_ide\installation\bin;%PATH%" +) + REM Check if ide command exists where ide >nul 2>&1 || ( echo. echo Error: IDEasy is not installed or not in PATH + echo If you just installed IDEasy, log off/on once or restart Explorer so + echo the desktop shortcut picks up the updated environment. echo https://github.com/devonfw/IDEasy#setup echo. pause From 87c0e2491fdbca17fd797916d5324c2d2828ad3e Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Tue, 23 Jun 2026 15:13:32 +0200 Subject: [PATCH 6/9] fix: reset gitignore and attributes --- .gitattributes | 4 ---- .gitignore | 3 --- 2 files changed, 7 deletions(-) diff --git a/.gitattributes b/.gitattributes index 6d1dc4b290..7e7a79ac69 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,5 @@ * eol=lf *.bat eol=crlf -*.ps1 eol=crlf -*.ps2 eol=crlf -*.sh eol=lf -*.command eol=lf *.png binary *.zip binary *.tgz binary diff --git a/.gitignore b/.gitignore index 5f8dc176d2..4cfa743f86 100644 --- a/.gitignore +++ b/.gitignore @@ -19,9 +19,6 @@ eclipse-target/ generated/ node_modules -# Generated GUI assets (created at runtime, not to be committed) -gui/scripts/windows/ideasy-gui.ico - # Package Files # *.jar *.war From 79e973ce934c7b5bca90737432376576c08e2086 Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Wed, 24 Jun 2026 09:39:54 +0200 Subject: [PATCH 7/9] doc: add issue to changelog --- CHANGELOG.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b95c6b8a9f..1441b5ec0b 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,6 +6,8 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE Release with new features and bugfixes: +* https://github.com/devonfw/IDEasy/issues/1917[#1917]: Allow creation of a shortcut for Windows, macOs and Linux + The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/46?closed=1[milestone 2026.07.001]. From 690be00cc448b96b71914a3a786866250be8190d Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Wed, 24 Jun 2026 10:13:17 +0200 Subject: [PATCH 8/9] feat: update window script to not open a new terminal --- gui/scripts/windows/create-shortcuts.ps1 | 17 +++++++++++++++-- gui/scripts/windows/launch-gui-silent.vbs | 11 +++++++++++ gui/scripts/windows/launch-gui.bat | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 gui/scripts/windows/launch-gui-silent.vbs diff --git a/gui/scripts/windows/create-shortcuts.ps1 b/gui/scripts/windows/create-shortcuts.ps1 index f1c1226899..24e3aeaba7 100644 --- a/gui/scripts/windows/create-shortcuts.ps1 +++ b/gui/scripts/windows/create-shortcuts.ps1 @@ -15,6 +15,7 @@ $guiDir = Split-Path -Parent (Split-Path -Parent $scriptDir) $projectRoot = Split-Path -Parent $guiDir $launcherBat = Join-Path $scriptDir "launch-gui.bat" +$launcherVbs = Join-Path $scriptDir "launch-gui-silent.vbs" $pomFile = Join-Path $projectRoot "pom.xml" if (-not (Test-Path $launcherBat)) { @@ -22,6 +23,11 @@ if (-not (Test-Path $launcherBat)) { exit 1 } +if (-not (Test-Path $launcherVbs)) { + Write-Host "Error: launch-gui-silent.vbs not found" -ForegroundColor Red + exit 1 +} + if (-not (Test-Path $pomFile)) { Write-Host "Error: pom.xml not found" -ForegroundColor Red exit 1 @@ -98,6 +104,7 @@ function Create-Shortcut { param( [string]$Path, [string]$Target, + [string]$Arguments, [string]$Description ) @@ -108,6 +115,7 @@ function Create-Shortcut { $wshShell = New-Object -ComObject WScript.Shell $shortcut = $wshShell.CreateShortcut($Path) $shortcut.TargetPath = $Target + $shortcut.Arguments = $Arguments $shortcut.WorkingDirectory = $projectRoot $shortcut.Description = $Description $shortcut.IconLocation = $iconLocation @@ -125,15 +133,20 @@ function Create-Shortcut { } } +# Target wscript.exe running the silent VBS wrapper instead of launch-gui.bat directly, +# so no console window ever appears - independent of the user's terminal "close on exit" setting. +$wscriptPath = Join-Path "$env:SystemRoot\System32" "wscript.exe" +$launcherArgs = "`"$launcherVbs`"" + if (-not $SkipDesktop) { # Use Shell32 to resolve the Desktop folder — works correctly with OneDrive-redirected Desktops $desktopShortcut = Join-Path ([Environment]::GetFolderPath('Desktop')) "IDEasy GUI.lnk" - Create-Shortcut -Path $desktopShortcut -Target $launcherBat -Description "Launch IDEasy GUI" + Create-Shortcut -Path $desktopShortcut -Target $wscriptPath -Arguments $launcherArgs -Description "Launch IDEasy GUI" } if (-not $SkipStartMenu) { $startMenuShortcut = Join-Path "$env:APPDATA\Microsoft\Windows\Start Menu\Programs" "IDEasy GUI.lnk" - Create-Shortcut -Path $startMenuShortcut -Target $launcherBat -Description "Launch IDEasy GUI" + Create-Shortcut -Path $startMenuShortcut -Target $wscriptPath -Arguments $launcherArgs -Description "Launch IDEasy GUI" } Write-Host "" diff --git a/gui/scripts/windows/launch-gui-silent.vbs b/gui/scripts/windows/launch-gui-silent.vbs new file mode 100644 index 0000000000..f5432adebb --- /dev/null +++ b/gui/scripts/windows/launch-gui-silent.vbs @@ -0,0 +1,11 @@ +' Runs launch-gui.bat completely hidden (no console window), regardless of the +' user's terminal "close on exit" settings. The shortcut targets this file via +' wscript.exe instead of launch-gui.bat directly so no window ever appears. +Dim shell, fso, scriptDir, batPath + +Set shell = CreateObject("WScript.Shell") +Set fso = CreateObject("Scripting.FileSystemObject") +scriptDir = fso.GetParentFolderName(WScript.ScriptFullName) +batPath = fso.BuildPath(scriptDir, "launch-gui.bat") + +shell.Run """" & batPath & """", 0, False diff --git a/gui/scripts/windows/launch-gui.bat b/gui/scripts/windows/launch-gui.bat index 753ed321a1..0f96d1cbc3 100644 --- a/gui/scripts/windows/launch-gui.bat +++ b/gui/scripts/windows/launch-gui.bat @@ -45,6 +45,6 @@ if not exist "%PROJECT_ROOT%\pom.xml" ( REM Launch GUI cd /d "%PROJECT_ROOT%" echo Starting IDEasy GUI... -START "" /B ide gui >> "%USERPROFILE%\.ideasy-gui.log" 2>&1 +START "" /B cmd /c ide gui >> "%USERPROFILE%\.ideasy-gui.log" 2>&1 exit /b 0 From 824a9a559e3ee2b1ac334e78f4ac9c83d40141d3 Mon Sep 17 00:00:00 2001 From: Hieu Do Date: Wed, 24 Jun 2026 10:29:11 +0200 Subject: [PATCH 9/9] feat: add fix for macOs and Linux script --- gui/scripts/linux/launch-gui.sh | 8 +++++++- gui/scripts/macos/launch-gui.command | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gui/scripts/linux/launch-gui.sh b/gui/scripts/linux/launch-gui.sh index 84bf508947..0258583743 100644 --- a/gui/scripts/linux/launch-gui.sh +++ b/gui/scripts/linux/launch-gui.sh @@ -8,6 +8,11 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" LOG_FILE="$HOME/.ideasy-gui.log" +# Ignore SIGHUP so this script (and what it launches) survives even if the +# process that handed off execution (desktop session bus, gio launch, etc.) +# disconnects before we are done. +trap '' HUP + # When launched from an application menu (Terminal=false), there is no console to # show errors on. Redirect everything to a log file from the start so failures # (e.g. 'ide' missing from the launcher's PATH) are diagnosable after the fact @@ -40,6 +45,7 @@ fi cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately -bash -ic "ide gui" & +bash -ic "ide gui" /dev/null; then +# 'ide' is a shell function defined in $IDE_ROOT/_ide/installation/functions and +# sourced by ~/.bashrc / ~/.zshrc — those only get sourced in interactive shells. +# Double-clicking a .command file runs it via its #!/bin/bash shebang directly, +# which is a non-interactive shell, so 'ide' is invisible there even though it +# works fine from a regular Terminal window. Route through an interactive bash +# so the function gets sourced regardless of how this script was launched. +if ! bash -ic "command -v ide" &> /dev/null; then echo "" echo "Error: IDEasy is not installed" echo "" @@ -29,6 +35,7 @@ cd "$PROJECT_ROOT" # Launch IDE GUI in background and exit immediately LOG_FILE="$HOME/.ideasy-gui.log" -ide gui >> "$LOG_FILE" 2>&1 & +bash -ic "ide gui" >> "$LOG_FILE" 2>&1 & +disown exit 0