Merge pull request #174 from kra-mo/desktop-file-importer

Desktop file importer
This commit is contained in:
kramo
2023-08-25 21:53:26 +02:00
committed by GitHub
13 changed files with 574 additions and 218 deletions

View File

@@ -2,153 +2,159 @@ using Gtk 4.0;
using Adw 1;
template $DetailsWindow : Adw.Window {
default-width: 480; // Same as Nautilus' properties window
default-height: -1;
modal: true;
default-width: 480; // Same as Nautilus' properties window
default-height: -1;
modal: true;
ShortcutController {
Shortcut {
trigger: "Escape";
action: "action(window.close)";
}
ShortcutController {
Shortcut {
trigger: "Escape";
action: "action(window.close)";
}
}
Box {
orientation: vertical;
Adw.HeaderBar HeaderBar {
show-start-title-buttons: false;
show-end-title-buttons: false;
[start]
Button cancel_button {
label: _("Cancel");
action-name: "window.close";
}
[end]
Button apply_button {
styles [
"suggested-action",
]
}
}
Box {
orientation: vertical;
Adw.PreferencesPage {
vexpand: true;
Adw.HeaderBar HeaderBar {
show-start-title-buttons: false;
show-end-title-buttons: false;
Adw.PreferencesGroup cover_group {
Adw.Clamp cover_clamp {
maximum-size: 200;
[start]
Button cancel_button {
label: _("Cancel");
action-name: "window.close";
Overlay {
[overlay]
Spinner spinner {
margin-start: 72;
margin-end: 72;
}
[end]
Button apply_button {
Overlay cover_overlay {
halign: center;
valign: center;
[overlay]
Button cover_button_edit {
icon-name: "document-edit-symbolic";
tooltip-text: _("New Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"suggested-action"
"circular",
"osd",
]
}
[overlay]
Revealer cover_button_delete_revealer {
transition-type: crossfade;
margin-end: 40;
Button cover_button_delete {
icon-name: "user-trash-symbolic";
tooltip-text: _("Delete Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular",
"osd",
]
}
}
Picture cover {
width-request: 200;
height-request: 300;
styles [
"card",
]
}
}
}
}
}
Adw.PreferencesGroup {
Adw.EntryRow name {
title: _("Title");
}
Adw.PreferencesPage {
vexpand: true;
Adw.PreferencesGroup cover_group {
Adw.Clamp cover_clamp {
maximum-size: 200;
Overlay {
[overlay]
Spinner spinner {
margin-start: 72;
margin-end: 72;
}
Overlay cover_overlay {
halign: center;
valign: center;
[overlay]
Button cover_button_edit {
icon-name: "document-edit-symbolic";
tooltip-text: _("New Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular", "osd"
]
}
[overlay]
Revealer cover_button_delete_revealer {
transition-type: crossfade;
margin-end: 40;
Button cover_button_delete {
icon-name: "user-trash-symbolic";
tooltip-text: _("Delete Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular", "osd"
]
}
}
Picture cover {
width-request: 200;
height-request: 300;
styles [
"card"
]
}
}
}
}
}
Adw.PreferencesGroup {
Adw.EntryRow name {
title: _("Title");
}
Adw.EntryRow developer {
title: _("Developer (optional)");
}
}
Adw.PreferencesGroup {
Adw.EntryRow executable {
title: _("Executable");
[suffix]
Gtk.Button file_chooser_button {
valign: center;
icon-name: "document-open-symbolic";
tooltip-text: _("Select File");
styles [
"flat"
]
}
[suffix]
Gtk.MenuButton exec_info_button {
valign: center;
icon-name: "help-about-symbolic";
tooltip-text: _("More Info");
popover: Popover exec_info_popover {
focusable: true;
Label exec_info_label {
use-markup: true;
wrap: true;
max-width-chars: 50;
halign: center;
valign: center;
margin-top: 6;
margin-bottom: 6;
margin-start: 6;
margin-end: 6;
}
};
styles [
"flat"
]
}
}
}
Adw.EntryRow developer {
title: _("Developer (optional)");
}
}
Adw.PreferencesGroup {
Adw.EntryRow executable {
title: _("Executable");
[suffix]
Button file_chooser_button {
valign: center;
icon-name: "document-open-symbolic";
tooltip-text: _("Select File");
styles [
"flat",
]
}
[suffix]
MenuButton exec_info_button {
valign: center;
icon-name: "help-about-symbolic";
tooltip-text: _("More Info");
popover:
Popover exec_info_popover {
focusable: true;
Label exec_info_label {
use-markup: true;
wrap: true;
max-width-chars: 50;
halign: center;
valign: center;
margin-top: 6;
margin-bottom: 6;
margin-start: 6;
margin-end: 6;
}
}
;
styles [
"flat",
]
}
}
}
}
}
}
}

View File

@@ -76,7 +76,6 @@ template $PreferencesWindow : Adw.PreferencesWindow {
]
}
}
}
}
@@ -311,6 +310,35 @@ template $PreferencesWindow : Adw.PreferencesWindow {
}
}
}
Adw.ExpanderRow desktop_expander_row {
title: _("Desktop Entries");
show-enable-switch: true;
Adw.ComboRow desktop_terminal_exec_row {
title: _("Terminal");
subtitle: _("Used only by games that require one to run");
model: StringList {
strings [
_("Custom"),
"xdg-terminal-exec",
"GNOME Console",
"GNOME Terminal",
"Konsole",
"XTerm"
]
};
[suffix]
Revealer desktop_tereminal_custom_exec_revealer {
transition-type: slide_right;
Entry desktop_tereminal_custom_exec {
valign: center;
placeholder-text: _("Executable");
}
}
}
}
}
}

View File

@@ -194,13 +194,19 @@ template $CartridgesWindow : Adw.ApplicationWindow {
action-name: "app.edit_game";
tooltip-text: _("Edit");
styles ["raised", "circular"]
styles [
"raised",
"circular",
]
}
Button details_view_hide_button {
action-name: "app.hide_game";
styles ["raised", "circular"]
styles [
"raised",
"circular",
]
}
Button {
@@ -208,7 +214,10 @@ template $CartridgesWindow : Adw.ApplicationWindow {
action-name: "app.remove_game";
tooltip-text: _("Remove");
styles ["raised", "circular"]
styles [
"raised",
"circular",
]
}
MenuButton {
@@ -216,7 +225,10 @@ template $CartridgesWindow : Adw.ApplicationWindow {
menu-model: search;
tooltip-text: _("Search");
styles ["raised", "circular"]
styles [
"raised",
"circular",
]
}
styles [

View File

@@ -1,5 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="cartridges">
<enum id="@APP_ID@.terminals">
<value nick="custom" value="0"/>
<value nick="xdg-terminal-exec" value="1"/>
<value nick="kgx" value="2"/>
<value nick="gnome-terminal" value="3"/>
<value nick="konsole" value="4"/>
<value nick="xterm" value="5"/>
</enum>
<schema id="@APP_ID@" path="@PREFIX@/">
<key name="exit-after-launch" type="b">
<default>false</default>
@@ -76,6 +86,15 @@
<key name="retroarch-location" type="s">
<default>"~/.var/app/org.libretro.RetroArch/config/retroarch/"</default>
</key>
<key name="desktop" type="b">
<default>true</default>
</key>
<key name="desktop-terminal" enum="@APP_ID@.terminals">
<default>"xdg-terminal-exec"</default>
</key>
<key name="desktop-terminal-custom-exec" type="s">
<default>""</default>
</key>
<key name="flatpak" type="b">
<default>true</default>
</key>
@@ -98,6 +117,7 @@
<default>false</default>
</key>
</schema>
<schema id="@APP_ID@.State" path="@PREFIX@/State/">
<key name="width" type="i">
<default>1110</default>
@@ -121,5 +141,8 @@
<key name="steam-limiter-tokens-history" type="s">
<default>"[]"</default>
</key>
<key name="terminal-check-done" type="b">
<default>false</default>
</key>
</schema>
</schemalist>

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Cartridges\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-19 12:45+0200\n"
"POT-Creation-Date: 2023-08-21 16:18+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,7 +19,7 @@ msgstr ""
#: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:173
#: src/main.py:174
msgid "Cartridges"
msgstr ""
@@ -58,7 +58,7 @@ msgstr ""
msgid "Game Details"
msgstr ""
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:263 src/importer/importer.py:301
#: src/importer/importer.py:352
msgid "Preferences"
@@ -68,31 +68,31 @@ msgstr ""
msgid "Cancel"
msgstr ""
#: data/gtk/details-window.blp:57
#: data/gtk/details-window.blp:58
msgid "New Cover"
msgstr ""
#: data/gtk/details-window.blp:75
#: data/gtk/details-window.blp:77
msgid "Delete Cover"
msgstr ""
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80
#: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title"
msgstr ""
#: data/gtk/details-window.blp:105
#: data/gtk/details-window.blp:109
msgid "Developer (optional)"
msgstr ""
#: data/gtk/details-window.blp:110
#: data/gtk/details-window.blp:115 data/gtk/preferences.blp:310
msgid "Executable"
msgstr ""
#: data/gtk/details-window.blp:116
#: data/gtk/details-window.blp:121
msgid "Select File"
msgstr ""
#: data/gtk/details-window.blp:127
#: data/gtk/details-window.blp:132
msgid "More Info"
msgstr ""
@@ -105,7 +105,7 @@ msgid "Hide"
msgstr ""
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209
#: data/gtk/window.blp:215
msgid "Remove"
msgstr ""
@@ -121,8 +121,8 @@ msgstr ""
msgid "Quit"
msgstr ""
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257
#: data/gtk/window.blp:324
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:336
msgid "Search"
msgstr ""
@@ -134,7 +134,7 @@ msgstr ""
msgid "Shortcuts"
msgstr ""
#: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:122
#: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:128
#: src/importer/importer.py:376
msgid "Undo"
msgstr ""
@@ -163,8 +163,8 @@ msgstr ""
msgid "Remove game"
msgstr ""
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89
#: data/gtk/preferences.blp:304
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:332
msgid "Behavior"
msgstr ""
@@ -200,114 +200,130 @@ msgstr ""
msgid "Remove All Games"
msgstr ""
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444
#: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import"
msgstr ""
#: data/gtk/preferences.blp:92
#: data/gtk/preferences.blp:91
msgid "Remove Uninstalled Games"
msgstr ""
#: data/gtk/preferences.blp:102
#: data/gtk/preferences.blp:101
msgid "Sources"
msgstr ""
#: data/gtk/preferences.blp:105
#: data/gtk/preferences.blp:104
msgid "Steam"
msgstr ""
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270
#: data/gtk/preferences.blp:108 data/gtk/preferences.blp:122
#: data/gtk/preferences.blp:163 data/gtk/preferences.blp:213
#: data/gtk/preferences.blp:227 data/gtk/preferences.blp:241
#: data/gtk/preferences.blp:255 data/gtk/preferences.blp:269
msgid "Install Location"
msgstr ""
#: data/gtk/preferences.blp:119
#: data/gtk/preferences.blp:118
msgid "Lutris"
msgstr ""
#: data/gtk/preferences.blp:132
#: data/gtk/preferences.blp:131
msgid "Cache Location"
msgstr ""
#: data/gtk/preferences.blp:141
#: data/gtk/preferences.blp:140
msgid "Import Steam Games"
msgstr ""
#: data/gtk/preferences.blp:150
#: data/gtk/preferences.blp:149
msgid "Import Flatpak Games"
msgstr ""
#: data/gtk/preferences.blp:160
#: data/gtk/preferences.blp:159
msgid "Heroic"
msgstr ""
#: data/gtk/preferences.blp:173
#: data/gtk/preferences.blp:172
msgid "Import Epic Games"
msgstr ""
#: data/gtk/preferences.blp:182
#: data/gtk/preferences.blp:181
msgid "Import GOG Games"
msgstr ""
#: data/gtk/preferences.blp:191
#: data/gtk/preferences.blp:190
msgid "Import Amazon Games"
msgstr ""
#: data/gtk/preferences.blp:200
#: data/gtk/preferences.blp:199
msgid "Import Sideloaded Games"
msgstr ""
#: data/gtk/preferences.blp:210
#: data/gtk/preferences.blp:209
msgid "Bottles"
msgstr ""
#: data/gtk/preferences.blp:224
#: data/gtk/preferences.blp:223
msgid "itch"
msgstr ""
#: data/gtk/preferences.blp:238
#: data/gtk/preferences.blp:237
msgid "Legendary"
msgstr ""
#: data/gtk/preferences.blp:252
#: data/gtk/preferences.blp:251
msgid "RetroArch"
msgstr ""
#: data/gtk/preferences.blp:266
#: data/gtk/preferences.blp:265
msgid "Flatpak"
msgstr ""
#: data/gtk/preferences.blp:279
#: data/gtk/preferences.blp:278
msgid "Import Game Launchers"
msgstr ""
#: data/gtk/preferences.blp:288
msgid "Desktop Entries"
msgstr ""
#: data/gtk/preferences.blp:292
msgid "SteamGridDB"
msgid "Terminal"
msgstr ""
#: data/gtk/preferences.blp:293
msgid "Used only by games that require one to run"
msgstr ""
#: data/gtk/preferences.blp:296
msgid "Custom"
msgstr ""
#: data/gtk/preferences.blp:320
msgid "SteamGridDB"
msgstr ""
#: data/gtk/preferences.blp:324
msgid "Authentication"
msgstr ""
#: data/gtk/preferences.blp:299
#: data/gtk/preferences.blp:327
msgid "API Key"
msgstr ""
#: data/gtk/preferences.blp:307
#: data/gtk/preferences.blp:335
msgid "Use SteamGridDB"
msgstr ""
#: data/gtk/preferences.blp:308
#: data/gtk/preferences.blp:336
msgid "Download images when adding or importing games"
msgstr ""
#: data/gtk/preferences.blp:317
#: data/gtk/preferences.blp:345
msgid "Prefer Over Official Images"
msgstr ""
#: data/gtk/preferences.blp:326
#: data/gtk/preferences.blp:354
msgid "Prefer Animated Images"
msgstr ""
@@ -335,7 +351,7 @@ msgstr ""
msgid "Games you hide will appear here."
msgstr ""
#: data/gtk/window.blp:64 data/gtk/window.blp:305
#: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back"
msgstr ""
@@ -347,64 +363,64 @@ msgstr ""
msgid "Play"
msgstr ""
#: data/gtk/window.blp:243 data/gtk/window.blp:437
#: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game"
msgstr ""
#: data/gtk/window.blp:250 data/gtk/window.blp:317
#: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu"
msgstr ""
#: data/gtk/window.blp:272
#: data/gtk/window.blp:284
msgid "Search games"
msgstr ""
#: data/gtk/window.blp:312
#: data/gtk/window.blp:324
msgid "Hidden Games"
msgstr ""
#: data/gtk/window.blp:339
#: data/gtk/window.blp:351
msgid "Search hidden games"
msgstr ""
#: data/gtk/window.blp:376
#: data/gtk/window.blp:388
msgid "Sort"
msgstr ""
#: data/gtk/window.blp:379
#: data/gtk/window.blp:391
msgid "A-Z"
msgstr ""
#: data/gtk/window.blp:385
#: data/gtk/window.blp:397
msgid "Z-A"
msgstr ""
#: data/gtk/window.blp:391
#: data/gtk/window.blp:403
msgid "Newest"
msgstr ""
#: data/gtk/window.blp:397
#: data/gtk/window.blp:409
msgid "Oldest"
msgstr ""
#: data/gtk/window.blp:403
#: data/gtk/window.blp:415
msgid "Last Played"
msgstr ""
#: data/gtk/window.blp:410
#: data/gtk/window.blp:422
msgid "Show Hidden"
msgstr ""
#: data/gtk/window.blp:423
#: data/gtk/window.blp:435
msgid "Keyboard Shortcuts"
msgstr ""
#: data/gtk/window.blp:428
#: data/gtk/window.blp:440
msgid "About Cartridges"
msgstr ""
#. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:192
#: src/main.py:193
msgid "translator_credits"
msgstr ""
@@ -434,8 +450,7 @@ msgstr ""
msgid "Add"
msgstr ""
#. Gdk.Texture supports .svg but PIL doesn't
#: src/details_window.py:88
#: src/details_window.py:91
msgid "Executables"
msgstr ""
@@ -508,28 +523,28 @@ msgstr ""
msgid "{} removed"
msgstr ""
#: src/preferences.py:121
#: src/preferences.py:127
msgid "All games removed"
msgstr ""
#: src/preferences.py:170
#: src/preferences.py:207
msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr ""
#: src/preferences.py:298
#: src/preferences.py:335
msgid "Installation Not Found"
msgstr ""
#: src/preferences.py:300
#: src/preferences.py:337
msgid "Select a valid directory."
msgstr ""
#: src/preferences.py:356
#: src/preferences.py:393
msgid "Invalid Directory"
msgstr ""
#: src/preferences.py:362
#: src/preferences.py:399
msgid "Set Location"
msgstr ""
@@ -537,7 +552,7 @@ msgstr ""
msgid "Dismiss"
msgstr ""
#: src/importer/importer.py:135
#: src/importer/importer.py:137
msgid "Importing Games…"
msgstr ""

View File

@@ -73,7 +73,6 @@ class BottlesSourceIterable(SourceIterable):
image_path = bottles_location / bottle_path / "grids" / image_name
additional_data = {"local_image_path": image_path}
# Produce game
yield (game, additional_data)

View File

@@ -0,0 +1,214 @@
# desktop_source.py
#
# Copyright 2023 kramo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
import shlex
from hashlib import sha3_256
from pathlib import Path
from time import time
from typing import NamedTuple
from gi.repository import GLib, Gtk
from src import shared
from src.game import Game
from src.importer.sources.source import Source, SourceIterable
class DesktopSourceIterable(SourceIterable):
source: "DesktopSource"
def __iter__(self):
"""Generator method producing games"""
added_time = int(time())
icon_theme = Gtk.IconTheme.new()
search_paths = [
shared.home / ".local" / "share",
"/run/host/usr/local/share",
"/run/host/usr/share",
"/run/host/usr/share/pixmaps",
"/usr/share/pixmaps",
] + GLib.get_system_data_dirs()
for search_path in search_paths:
path = Path(search_path)
if not str(search_path).endswith("/pixmaps"):
path = path / "icons"
if not path.is_dir():
continue
if str(path).startswith("/app/"):
continue
icon_theme.add_search_path(str(path))
terminal_exec = self.get_terminal_exec()
for path in search_paths:
if str(path).startswith("/app/"):
continue
path = Path(path) / "applications"
if not path.is_dir():
continue
for entry in path.iterdir():
if entry.suffix != ".desktop":
continue
# Skip Lutris games
if str(entry.name).startswith("net.lutris."):
continue
keyfile = GLib.KeyFile.new()
try:
keyfile.load_from_file(str(entry), 0)
if "Game" not in keyfile.get_string_list(
"Desktop Entry", "Categories"
):
continue
name = keyfile.get_string("Desktop Entry", "Name")
executable = keyfile.get_string("Desktop Entry", "Exec").split(
" %"
)[0]
except GLib.GError:
continue
# Skip Steam games
if "steam://rungameid/" in executable:
continue
# Skip Heroic games
if "heroic://launch/" in executable:
continue
# Skip Bottles games
if "bottles-cli " in executable:
continue
try:
if keyfile.get_boolean("Desktop Entry", "NoDisplay"):
continue
except GLib.GError:
pass
try:
terminal = keyfile.get_boolean("Desktop Entry", "Terminal")
except GLib.GError:
terminal = False
try:
cd_path = (
"cd " + keyfile.get_string("Desktop Entry", "Path") + " && "
)
except GLib.GError:
cd_path = ""
values = {
"source": self.source.source_id,
"added": added_time,
"name": name,
"game_id": "desktop_"
+ sha3_256(
str(entry).encode("utf-8"), usedforsecurity=False
).hexdigest(),
"executable": cd_path
+ (
(terminal_exec + shlex.quote(executable))
if terminal
else executable
),
}
game = Game(values)
additional_data = {}
try:
icon_str = keyfile.get_string("Desktop Entry", "Icon")
except GLib.GError:
print("AAAAAAAAAAAAAAAAAAAAAAA")
yield game
continue
else:
if "/" in icon_str:
additional_data = {"local_icon_path": Path(icon_str)}
yield (game, additional_data)
continue
try:
if (
icon_path := icon_theme.lookup_icon(
icon_str,
None,
512,
1,
shared.win.get_direction(),
0,
)
.get_file()
.get_path()
):
additional_data = {"local_icon_path": Path(icon_path)}
except GLib.GError:
pass
yield (game, additional_data)
def get_terminal_exec(self) -> str:
match shared.schema.get_enum("desktop-terminal"):
case 0:
terminal_exec = shared.schema.get_string("desktop-terminal-custom-exec")
case 1:
terminal_exec = "xdg-terminal-exec"
case 2:
terminal_exec = "kgx -e"
case 3:
terminal_exec = "gnome-terminal --"
case 4:
terminal_exec = "konsole -e"
case 5:
terminal_exec = "xterm -e"
return terminal_exec + " "
class DesktopLocations(NamedTuple):
pass
class DesktopSource(Source):
"""Generic Flatpak source"""
source_id = "desktop"
name = _("Desktop")
iterable_class = DesktopSourceIterable
available_on = {"linux"}
locations: DesktopLocations
def __init__(self) -> None:
super().__init__()
self.locations = DesktopLocations()

View File

@@ -109,7 +109,6 @@ class FlatpakSourceIterable(SourceIterable):
except GLib.GError:
pass
# Produce game
yield (game, additional_data)

View File

@@ -77,7 +77,6 @@ class LutrisSourceIterable(SourceIterable):
image_path = self.source.locations.cache["coverart"] / f"{row[2]}.jpg"
additional_data = {"local_image_path": image_path}
# Produce game
yield (game, additional_data)
# Cleanup

View File

@@ -78,7 +78,6 @@ class Source(Iterable):
def is_available(self) -> bool:
return sys.platform in self.available_on
@abstractmethod
def make_executable(self, *args, **kwargs) -> str:
"""
Create a game executable command.

View File

@@ -105,7 +105,6 @@ class SteamSourceIterable(SourceIterable):
)
additional_data = {"local_image_path": image_path, "steam_appid": appid}
# Produce game
yield (game, additional_data)

View File

@@ -20,6 +20,8 @@
import json
import lzma
import os
import shlex
import subprocess
import sys
from typing import Any, Optional
@@ -36,6 +38,7 @@ from src.details_window import DetailsWindow
from src.game import Game
from src.importer.importer import Importer
from src.importer.sources.bottles_source import BottlesSource
from src.importer.sources.desktop_source import DesktopSource
from src.importer.sources.flatpak_source import FlatpakSource
from src.importer.sources.heroic_source import HeroicSource
from src.importer.sources.itch_source import ItchSource
@@ -72,6 +75,10 @@ class CartridgesApplication(Adw.Application):
if os.name == "nt":
migrate_files_v1_to_v2()
else:
if not shared.state_schema.get_boolean("terminal-check-done"):
self.check_desktop_terminals()
shared.state_schema.set_boolean("terminal-check-done", True)
# Set fallback icon-name
Gtk.Window.set_default_icon_name(shared.APP_ID)
@@ -142,6 +149,22 @@ class CartridgesApplication(Adw.Application):
self.win.present()
def check_desktop_terminals(self) -> None:
"""Look for an installed terminal for desktop entries and set the relevant gsetting"""
terminals = ("xdg-terminal-exec", "kgx", "gnome-terminal", "konsole", "xterm")
for index, command in enumerate(terminals):
command = f"type {command} &> /dev/null"
if os.getenv("FLATPAK_ID") == shared.APP_ID:
command = "flatpak-spawn --host /bin/sh -c " + shlex.quote(command)
try:
subprocess.run(command, shell=True, check=True)
shared.schema.set_enum("desktop-terminal", index + 1)
return
except subprocess.CalledProcessError:
pass
def load_games_from_disk(self) -> None:
if shared.games_dir.is_dir():
for game_file in shared.games_dir.iterdir():
@@ -155,9 +178,9 @@ class CartridgesApplication(Adw.Application):
def on_about_action(self, *_args: Any) -> None:
# Get the debug info from the log files
debug_str = ""
for i, path in enumerate(shared.log_files):
for index, path in enumerate(shared.log_files):
# Add a horizontal line between runs
if i > 0:
if index > 0:
debug_str += "" * 37 + "\n"
# Add the run's logs
log_file = (
@@ -241,6 +264,9 @@ class CartridgesApplication(Adw.Application):
if shared.schema.get_boolean("flatpak"):
shared.importer.add_source(FlatpakSource())
if shared.schema.get_boolean("desktop"):
shared.importer.add_source(DesktopSource())
if shared.schema.get_boolean("itch"):
shared.importer.add_source(ItchSource())

View File

@@ -28,6 +28,7 @@ from gi.repository import Adw, Gio, GLib, Gtk
from src import shared
from src.game import Game
from src.importer.sources.bottles_source import BottlesSource
from src.importer.sources.desktop_source import DesktopSource
from src.importer.sources.flatpak_source import FlatpakSource
from src.importer.sources.heroic_source import HeroicSource
from src.importer.sources.itch_source import ItchSource
@@ -97,6 +98,11 @@ class PreferencesWindow(Adw.PreferencesWindow):
flatpak_data_file_chooser_button = Gtk.Template.Child()
flatpak_import_launchers_switch = Gtk.Template.Child()
desktop_expander_row = Gtk.Template.Child()
desktop_terminal_exec_row = Gtk.Template.Child()
desktop_tereminal_custom_exec_revealer = Gtk.Template.Child()
desktop_tereminal_custom_exec = Gtk.Template.Child()
sgdb_key_group = Gtk.Template.Child()
sgdb_key_entry_row = Gtk.Template.Child()
sgdb_switch = Gtk.Template.Child()
@@ -144,6 +150,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
for source_class in (
BottlesSource,
FlatpakSource,
DesktopSource,
HeroicSource,
ItchSource,
LegendarySource,
@@ -158,6 +165,36 @@ class PreferencesWindow(Adw.PreferencesWindow):
else:
self.init_source_row(source)
# Desktop Terminal Executable
def set_terminal_exec(widget: Adw.ComboRow, _param: Any) -> None:
shared.schema.set_enum("desktop-terminal", widget.get_selected())
self.desktop_tereminal_custom_exec_revealer.set_reveal_child(
widget.get_selected() == 0
)
self.desktop_terminal_exec_row.connect("notify::selected", set_terminal_exec)
self.desktop_terminal_exec_row.set_selected(
terminal_value := shared.schema.get_enum("desktop-terminal")
)
if not terminal_value:
set_terminal_exec(
self.desktop_terminal_exec_row, None
) # The default value is supposed to be 4294967295, but it's 0 and I can't change it
self.desktop_tereminal_custom_exec.set_text(
shared.schema.get_string("desktop-terminal-custom-exec")
)
def desktop_custom_exec_changed(*_args: Any) -> None:
shared.schema.set_string(
"desktop-terminal-custom-exec",
self.desktop_tereminal_custom_exec.get_text(),
)
self.desktop_tereminal_custom_exec.connect(
"changed", desktop_custom_exec_changed
)
# SteamGridDB
def sgdb_key_changed(*_args: Any) -> None:
shared.schema.set_string("sgdb-key", self.sgdb_key_entry_row.get_text())