feat: added add to desktop and menu to egs context menu
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
@ -142,6 +142,32 @@ class ContextMenuManager:
|
||||
open_folder_action.triggered.connect(
|
||||
lambda: self.open_egs_game_folder(game_card.appid)
|
||||
)
|
||||
# Add desktop shortcut actions for EGS games
|
||||
desktop_dir = subprocess.check_output(['xdg-user-dir', 'DESKTOP']).decode('utf-8').strip()
|
||||
desktop_path = os.path.join(desktop_dir, f"{game_card.name}.desktop")
|
||||
if os.path.exists(desktop_path):
|
||||
remove_desktop_action = menu.addAction(_("Remove from Desktop"))
|
||||
remove_desktop_action.triggered.connect(
|
||||
lambda: self.remove_egs_from_desktop(game_card.name)
|
||||
)
|
||||
else:
|
||||
add_desktop_action = menu.addAction(_("Add to Desktop"))
|
||||
add_desktop_action.triggered.connect(
|
||||
lambda: self.add_egs_to_desktop(game_card.name, game_card.appid)
|
||||
)
|
||||
# Add menu shortcut actions for EGS games
|
||||
applications_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "applications")
|
||||
menu_path = os.path.join(applications_dir, f"{game_card.name}.desktop")
|
||||
if os.path.exists(menu_path):
|
||||
remove_menu_action = menu.addAction(_("Remove from Menu"))
|
||||
remove_menu_action.triggered.connect(
|
||||
lambda: self.remove_egs_from_menu(game_card.name)
|
||||
)
|
||||
else:
|
||||
add_menu_action = menu.addAction(_("Add to Menu"))
|
||||
add_menu_action.triggered.connect(
|
||||
lambda: self.add_egs_to_menu(game_card.name, game_card.appid)
|
||||
)
|
||||
|
||||
if game_card.game_source not in ("steam", "epic"):
|
||||
desktop_dir = subprocess.check_output(['xdg-user-dir', 'DESKTOP']).decode('utf-8').strip()
|
||||
@ -428,6 +454,185 @@ class ContextMenuManager:
|
||||
desktop_path = os.path.join(self.portproton_location, f"{sanitized_name}.desktop")
|
||||
return desktop_path
|
||||
|
||||
def _get_egs_desktop_path(self, game_name):
|
||||
"""Construct the .desktop file path for EGS games."""
|
||||
desktop_path = os.path.join(self.portproton_location, "egs_desktops", f"{game_name}.desktop")
|
||||
return desktop_path
|
||||
|
||||
def _create_egs_desktop_file(self, game_name: str, app_name: str) -> bool:
|
||||
"""
|
||||
Creates a .desktop file for an EGS game in the PortProton egs_desktops directory.
|
||||
|
||||
Args:
|
||||
game_name: The display name of the game.
|
||||
app_name: The Legendary app_name (unique identifier for the game).
|
||||
|
||||
Returns:
|
||||
bool: True if the .desktop file was created successfully, False otherwise.
|
||||
"""
|
||||
if not self._check_portproton():
|
||||
return False
|
||||
|
||||
if not os.path.exists(self.legendary_path):
|
||||
self._show_warning_dialog(
|
||||
_("Error"),
|
||||
_("Legendary executable not found at {0}").format(self.legendary_path)
|
||||
)
|
||||
return False
|
||||
|
||||
# Determine wrapper
|
||||
wrapper = "flatpak run ru.linux_gaming.PortProton"
|
||||
start_sh_path = os.path.join(self.portproton_location, "data", "scripts", "start.sh")
|
||||
if self.portproton_location and ".var" not in self.portproton_location:
|
||||
wrapper = start_sh_path
|
||||
if not os.path.exists(start_sh_path):
|
||||
self._show_warning_dialog(
|
||||
_("Error"),
|
||||
_("start.sh not found at {0}").format(start_sh_path)
|
||||
)
|
||||
return False
|
||||
|
||||
# Get cover image path
|
||||
image_folder = os.path.join(
|
||||
os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache")),
|
||||
"PortProtonQt", "images"
|
||||
)
|
||||
cover_path = os.path.join(image_folder, f"{app_name}.jpg")
|
||||
icon_path = cover_path if os.path.exists(cover_path) else ""
|
||||
|
||||
# Create egs_desktops directory
|
||||
egs_desktop_dir = os.path.join(self.portproton_location, "egs_desktops")
|
||||
os.makedirs(egs_desktop_dir, exist_ok=True)
|
||||
|
||||
# Create .desktop file with direct Exec line
|
||||
desktop_path = self._get_egs_desktop_path(game_name)
|
||||
desktop_entry = f"""[Desktop Entry]
|
||||
Type=Application
|
||||
Name={game_name}
|
||||
Exec="{self.legendary_path}" launch {app_name} --no-wine --wrapper "env START_FROM_STEAM=1 {wrapper}" "$@"
|
||||
Icon={icon_path}
|
||||
Terminal=false
|
||||
Categories=Game;
|
||||
"""
|
||||
try:
|
||||
with open(desktop_path, "w", encoding="utf-8") as f:
|
||||
f.write(desktop_entry)
|
||||
os.chmod(desktop_path, 0o755)
|
||||
logger.info(f"Created .desktop file for EGS game: {desktop_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
self._show_warning_dialog(
|
||||
_("Error"),
|
||||
_("Failed to create .desktop file: {0}").format(str(e))
|
||||
)
|
||||
return False
|
||||
|
||||
def add_egs_to_desktop(self, game_name: str, app_name: str):
|
||||
"""
|
||||
Copies the .desktop file for an EGS game to the Desktop folder.
|
||||
|
||||
Args:
|
||||
game_name: The display name of the game.
|
||||
app_name: The Legendary app_name (unique identifier for the game).
|
||||
"""
|
||||
if not self._check_portproton():
|
||||
return
|
||||
|
||||
desktop_path = self._get_egs_desktop_path(game_name)
|
||||
if not os.path.exists(desktop_path):
|
||||
# Create the .desktop file if it doesn't exist
|
||||
if not self._create_egs_desktop_file(game_name, app_name):
|
||||
return
|
||||
|
||||
desktop_dir = subprocess.check_output(['xdg-user-dir', 'DESKTOP']).decode('utf-8').strip()
|
||||
os.makedirs(desktop_dir, exist_ok=True)
|
||||
dest_path = os.path.join(desktop_dir, f"{game_name}.desktop")
|
||||
|
||||
try:
|
||||
shutil.copyfile(desktop_path, dest_path)
|
||||
os.chmod(dest_path, 0o755)
|
||||
if self.parent.statusBar():
|
||||
self.parent.statusBar().showMessage(
|
||||
_("Game '{0}' added to desktop").format(game_name), 3000
|
||||
)
|
||||
logger.debug("Direct status message: Game '%s' added to desktop", game_name)
|
||||
else:
|
||||
logger.warning("Status bar not available when adding '%s' to desktop", game_name)
|
||||
except OSError as e:
|
||||
self._show_warning_dialog(
|
||||
_("Error"),
|
||||
_("Failed to add game to desktop: {0}").format(str(e))
|
||||
)
|
||||
|
||||
def remove_egs_from_desktop(self, game_name: str):
|
||||
"""
|
||||
Removes the .desktop file for an EGS game from the Desktop folder.
|
||||
|
||||
Args:
|
||||
game_name: The display name of the game.
|
||||
"""
|
||||
desktop_dir = subprocess.check_output(['xdg-user-dir', 'DESKTOP']).decode('utf-8').strip()
|
||||
desktop_path = os.path.join(desktop_dir, f"{game_name}.desktop")
|
||||
self._remove_file(
|
||||
desktop_path,
|
||||
_("Failed to remove game from Desktop: {0}"),
|
||||
_("Game '{0}' removed from Desktop"),
|
||||
game_name
|
||||
)
|
||||
|
||||
def add_egs_to_menu(self, game_name: str, app_name: str):
|
||||
"""
|
||||
Copies the .desktop file for an EGS game to ~/.local/share/applications.
|
||||
|
||||
Args:
|
||||
game_name: The display name of the game.
|
||||
app_name: The Legendary app_name (unique identifier for the game).
|
||||
"""
|
||||
if not self._check_portproton():
|
||||
return
|
||||
|
||||
desktop_path = self._get_egs_desktop_path(game_name)
|
||||
if not os.path.exists(desktop_path):
|
||||
# Create the .desktop file if it doesn't exist
|
||||
if not self._create_egs_desktop_file(game_name, app_name):
|
||||
return
|
||||
|
||||
applications_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "applications")
|
||||
os.makedirs(applications_dir, exist_ok=True)
|
||||
dest_path = os.path.join(applications_dir, f"{game_name}.desktop")
|
||||
|
||||
try:
|
||||
shutil.copyfile(desktop_path, dest_path)
|
||||
os.chmod(dest_path, 0o755)
|
||||
if self.parent.statusBar():
|
||||
self.parent.statusBar().showMessage(
|
||||
_("Game '{0}' added to menu").format(game_name), 3000
|
||||
)
|
||||
logger.debug("Direct status message: Game '%s' added to menu", game_name)
|
||||
else:
|
||||
logger.warning("Status bar not available when adding '%s' to menu", game_name)
|
||||
except OSError as e:
|
||||
self._show_warning_dialog(
|
||||
_("Error"),
|
||||
_("Failed to add game to menu: {0}").format(str(e))
|
||||
)
|
||||
|
||||
def remove_egs_from_menu(self, game_name: str):
|
||||
"""
|
||||
Removes the .desktop file for an EGS game from ~/.local/share/applications.
|
||||
|
||||
Args:
|
||||
game_name: The display name of the game.
|
||||
"""
|
||||
applications_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "applications")
|
||||
desktop_path = os.path.join(applications_dir, f"{game_name}.desktop")
|
||||
self._remove_file(
|
||||
desktop_path,
|
||||
_("Failed to remove game from menu: {0}"),
|
||||
_("Game '{0}' removed from menu"),
|
||||
game_name
|
||||
)
|
||||
|
||||
def _get_exec_line(self, game_name, exec_line):
|
||||
"""Retrieve and validate exec_line from .desktop file if necessary."""
|
||||
if exec_line and exec_line.strip() != "full":
|
||||
|
Reference in New Issue
Block a user