diff --git a/data/GameHub.css b/data/GameHub.css index 32d5afd1..2d04d53b 100755 --- a/data/GameHub.css +++ b/data/GameHub.css @@ -196,46 +196,44 @@ list:not(:backdrop) row:selected:focus label.category-label color: alpha(#ffffff, 0.8); } -GtkListBox.installers-list, -list.installers-list +.installers-list { background: transparent; } -GtkListBox.installers-list .list-row, -list.installers-list row +.installers-list .list-row, +.installers-list row { border-radius: 2px; } -GtkListBox.downloads-list .list-row, -list.downloads-list row +.downloads-list .list-row, +.downloads-list row { background: transparent; border-bottom: 1px alpha(#333, 0.3) solid; outline: none; } -GtkListBox.downloads-list .list-row:last-child, -list.downloads-list row:last-child +.downloads-list .list-row:last-child, +.downloads-list row:last-child { border-bottom: none; } -GtkListBox.downloads-list .list-row:selected, -list.downloads-list row:selected +.downloads-list .list-row:selected, +.downloads-list row:selected { background: transparent; outline: none; } -GtkListBox.downloads-list .list-row:focus, -list.downloads-list row:focus +.downloads-list .list-row:focus, +.downloads-list row:focus { background: transparent; outline: none; } -GtkLabel.games-list-header, -label.games-list-header +.games-list-header { background: alpha(#333, 0.1); margin-top: -1px; diff --git a/po/com.github.tkashkin.gamehub.pot b/po/com.github.tkashkin.gamehub.pot index 75631094..5f7cd6f4 100644 --- a/po/com.github.tkashkin.gamehub.pot +++ b/po/com.github.tkashkin.gamehub.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-28 12:05+0300\n" +"POT-Creation-Date: 2018-12-06 14:52+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,75 +18,87 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 +#: src/app.vala:134 +msgid "Run game" +msgstr "" + +#: src/app.vala:135 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:136 +msgid "Show main window" +msgstr "" + +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:226 #: src/ui/dialogs/GamePropertiesDialog.vala:220 msgid "Select executable" msgstr "" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:140 src/ui/views/GamesView/GamesView.vala:352 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:144 src/ui/views/GamesView/GamesView.vala:352 #: src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Select" msgstr "" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:139 src/ui/widgets/FileChooserEntry.vala:53 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:143 src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Cancel" msgstr "" -#: src/data/Runnable.vala:125 src/ui/widgets/FileChooserEntry.vala:47 +#: src/data/Runnable.vala:129 src/ui/widgets/FileChooserEntry.vala:47 msgid "Select directory" msgstr "" -#: src/data/Runnable.vala:354 +#: src/data/Runnable.vala:359 #, c-format msgid "Part %u of %u: " msgstr "" -#: src/data/Game.vala:424 +#: src/data/Game.vala:465 msgctxt "status" msgid "Running" msgstr "" -#: src/data/Game.vala:427 +#: src/data/Game.vala:468 msgctxt "status" msgid "Installed" msgstr "" -#: src/data/Game.vala:428 +#: src/data/Game.vala:469 msgctxt "status" msgid "Installing" msgstr "" -#: src/data/Game.vala:429 +#: src/data/Game.vala:470 msgctxt "status" msgid "Download started" msgstr "" -#: src/data/Game.vala:431 +#: src/data/Game.vala:472 msgctxt "status" msgid "Not installed" msgstr "" -#: src/data/Game.vala:441 +#: src/data/Game.vala:482 msgctxt "status_header" msgid "Installed" msgstr "" -#: src/data/Game.vala:442 +#: src/data/Game.vala:483 msgctxt "status_header" msgid "Installing" msgstr "" -#: src/data/Game.vala:443 +#: src/data/Game.vala:484 msgctxt "status_header" msgid "Downloading" msgstr "" -#: src/data/Game.vala:445 +#: src/data/Game.vala:486 msgctxt "status_header" msgid "Not installed" msgstr "" @@ -138,7 +150,7 @@ msgstr "" msgid "Edit custom script" msgstr "" -#: src/data/compat/WineWrap.vala:57 +#: src/data/compat/WineWrap.vala:59 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:206 #: src/ui/dialogs/CompatRunDialog.vala:100 #: src/ui/views/GamesView/GameContextMenu.vala:42 @@ -146,11 +158,11 @@ msgstr "" msgid "Run" msgstr "" -#: src/data/compat/WineWrap.vala:60 +#: src/data/compat/WineWrap.vala:62 msgid "Show WineWrap menu" msgstr "" -#: src/data/compat/WineWrap.vala:63 src/data/compat/Proton.vala:80 +#: src/data/compat/WineWrap.vala:65 src/data/compat/Proton.vala:80 #: src/data/compat/Wine.vala:80 msgid "Kill apps in prefix" msgstr "" @@ -497,6 +509,14 @@ msgstr "" msgid "Compatibility" msgstr "" +#: src/ui/dialogs/GamePropertiesDialog.vala:273 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:284 +msgid "Copy to clipboard" +msgstr "" + #: src/ui/dialogs/GameFSOverlaysDialog.vala:52 #, c-format msgid "%s: Overlays" diff --git a/po/de.po b/po/de.po index 38f59a06..7dbbd841 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-28 12:05+0300\n" +"POT-Creation-Date: 2018-12-06 14:52+0300\n" "PO-Revision-Date: 2018-11-30 04:58+0000\n" "Last-Translator: Ettore Atalan \n" "Language-Team: German \n" "Language-Team: Indonesian \n" "Language-Team: Norwegian Bokmål \n" "Language-Team: Dutch 1);\n" "X-Generator: Poedit 2.0.6\n" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 +#: src/app.vala:134 +#, fuzzy +msgid "Run game" +msgstr "%u jogo" + +#: src/app.vala:135 +#, fuzzy +msgid "Show compatibility options dialog" +msgstr "Forçar o modo de compatibilidade" + +#: src/app.vala:136 +msgid "Show main window" +msgstr "" + +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:226 #: src/ui/dialogs/GamePropertiesDialog.vala:220 msgid "Select executable" msgstr "Selecione o executável" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:140 src/ui/views/GamesView/GamesView.vala:352 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:144 src/ui/views/GamesView/GamesView.vala:352 #: src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Select" msgstr "Selecione" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:139 src/ui/widgets/FileChooserEntry.vala:53 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:143 src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Cancel" msgstr "Cancelar" -#: src/data/Runnable.vala:125 src/ui/widgets/FileChooserEntry.vala:47 +#: src/data/Runnable.vala:129 src/ui/widgets/FileChooserEntry.vala:47 msgid "Select directory" msgstr "Selecione o diretório" -#: src/data/Runnable.vala:354 +#: src/data/Runnable.vala:359 #, c-format msgid "Part %u of %u: " msgstr "Parte %u de %u: " -#: src/data/Game.vala:424 +#: src/data/Game.vala:465 msgctxt "status" msgid "Running" msgstr "Correndo" -#: src/data/Game.vala:427 +#: src/data/Game.vala:468 msgctxt "status" msgid "Installed" msgstr "Instalado" -#: src/data/Game.vala:428 +#: src/data/Game.vala:469 msgctxt "status" msgid "Installing" msgstr "Instalando" -#: src/data/Game.vala:429 +#: src/data/Game.vala:470 msgctxt "status" msgid "Download started" msgstr "Download iniciado" -#: src/data/Game.vala:431 +#: src/data/Game.vala:472 msgctxt "status" msgid "Not installed" msgstr "Não instalado" -#: src/data/Game.vala:441 +#: src/data/Game.vala:482 msgctxt "status_header" msgid "Installed" msgstr "Instalado" -#: src/data/Game.vala:442 +#: src/data/Game.vala:483 msgctxt "status_header" msgid "Installing" msgstr "Instalando" -#: src/data/Game.vala:443 +#: src/data/Game.vala:484 msgctxt "status_header" msgid "Downloading" msgstr "Baixar" -#: src/data/Game.vala:445 +#: src/data/Game.vala:486 msgctxt "status_header" msgid "Not installed" msgstr "Não instalado" @@ -140,7 +154,7 @@ msgstr "Editar script" msgid "Edit custom script" msgstr "Editar script personalizado" -#: src/data/compat/WineWrap.vala:57 +#: src/data/compat/WineWrap.vala:59 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:206 #: src/ui/dialogs/CompatRunDialog.vala:100 #: src/ui/views/GamesView/GameContextMenu.vala:42 @@ -148,11 +162,11 @@ msgstr "Editar script personalizado" msgid "Run" msgstr "Jogar" -#: src/data/compat/WineWrap.vala:60 +#: src/data/compat/WineWrap.vala:62 msgid "Show WineWrap menu" msgstr "" -#: src/data/compat/WineWrap.vala:63 src/data/compat/Proton.vala:80 +#: src/data/compat/WineWrap.vala:65 src/data/compat/Proton.vala:80 #: src/data/compat/Wine.vala:80 msgid "Kill apps in prefix" msgstr "Mate aplicativos no prefixo" @@ -502,6 +516,14 @@ msgstr "Pesquisar imagens:" msgid "Compatibility" msgstr "Compatibilidade" +#: src/ui/dialogs/GamePropertiesDialog.vala:273 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:284 +msgid "Copy to clipboard" +msgstr "" + #: src/ui/dialogs/GameFSOverlaysDialog.vala:52 #, c-format msgid "%s: Overlays" diff --git a/po/ru.po b/po/ru.po index da9e5069..42f2fbb9 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-28 12:05+0300\n" +"POT-Creation-Date: 2018-12-06 14:52+0300\n" "PO-Revision-Date: 2018-11-30 01:08+0000\n" "Last-Translator: Anatoliy Kashkin \n" "Language-Team: Russian =2 && n%10<=" -"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 3.3-dev\n" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 +#: src/app.vala:134 +msgid "Run game" +msgstr "Запустить игру" + +#: src/app.vala:135 +msgid "Show compatibility options dialog" +msgstr "Показать диалог опций совместимости" + +#: src/app.vala:136 +msgid "Show main window" +msgstr "Показать главное окно" + +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:226 #: src/ui/dialogs/GamePropertiesDialog.vala:220 msgid "Select executable" msgstr "Выберите исполняемый файл" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:140 src/ui/views/GamesView/GamesView.vala:352 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:144 src/ui/views/GamesView/GamesView.vala:352 #: src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Select" msgstr "Выбрать" -#: src/data/Runnable.vala:69 src/data/Runnable.vala:71 -#: src/data/Runnable.vala:139 src/ui/widgets/FileChooserEntry.vala:53 +#: src/data/Runnable.vala:73 src/data/Runnable.vala:75 +#: src/data/Runnable.vala:143 src/ui/widgets/FileChooserEntry.vala:53 #: src/ui/widgets/FileChooserEntry.vala:55 msgid "Cancel" msgstr "Отмена" -#: src/data/Runnable.vala:125 src/ui/widgets/FileChooserEntry.vala:47 +#: src/data/Runnable.vala:129 src/ui/widgets/FileChooserEntry.vala:47 msgid "Select directory" msgstr "Выберите папку" -#: src/data/Runnable.vala:354 +#: src/data/Runnable.vala:359 #, c-format msgid "Part %u of %u: " msgstr "Часть %u из %u: " -#: src/data/Game.vala:424 +#: src/data/Game.vala:465 msgctxt "status" msgid "Running" msgstr "Запущена" -#: src/data/Game.vala:427 +#: src/data/Game.vala:468 msgctxt "status" msgid "Installed" msgstr "Установлена" -#: src/data/Game.vala:428 +#: src/data/Game.vala:469 msgctxt "status" msgid "Installing" msgstr "Установка" -#: src/data/Game.vala:429 +#: src/data/Game.vala:470 msgctxt "status" msgid "Download started" msgstr "Загрузка начата" -#: src/data/Game.vala:431 +#: src/data/Game.vala:472 msgctxt "status" msgid "Not installed" msgstr "Не установлена" -#: src/data/Game.vala:441 +#: src/data/Game.vala:482 msgctxt "status_header" msgid "Installed" msgstr "Установленные" -#: src/data/Game.vala:442 +#: src/data/Game.vala:483 msgctxt "status_header" msgid "Installing" msgstr "Установка" -#: src/data/Game.vala:443 +#: src/data/Game.vala:484 msgctxt "status_header" msgid "Downloading" msgstr "Загрузка" -#: src/data/Game.vala:445 +#: src/data/Game.vala:486 msgctxt "status_header" msgid "Not installed" msgstr "Не установленные" @@ -142,7 +154,7 @@ msgstr "Редактировать скрипт" msgid "Edit custom script" msgstr "Редактировать пользовательский скрипт" -#: src/data/compat/WineWrap.vala:57 +#: src/data/compat/WineWrap.vala:59 #: src/ui/dialogs/SettingsDialog/tabs/Emulators.vala:206 #: src/ui/dialogs/CompatRunDialog.vala:100 #: src/ui/views/GamesView/GameContextMenu.vala:42 @@ -150,11 +162,11 @@ msgstr "Редактировать пользовательский скрипт msgid "Run" msgstr "Запустить" -#: src/data/compat/WineWrap.vala:60 +#: src/data/compat/WineWrap.vala:62 msgid "Show WineWrap menu" msgstr "Показать меню WineWrap" -#: src/data/compat/WineWrap.vala:63 src/data/compat/Proton.vala:80 +#: src/data/compat/WineWrap.vala:65 src/data/compat/Proton.vala:80 #: src/data/compat/Wine.vala:80 msgid "Kill apps in prefix" msgstr "Завершить приложения в префиксе" @@ -503,6 +515,14 @@ msgstr "Поиск изображений:" msgid "Compatibility" msgstr "Совместимость" +#: src/ui/dialogs/GamePropertiesDialog.vala:273 +msgid "Launch from terminal" +msgstr "Запустить из терминала" + +#: src/ui/dialogs/GamePropertiesDialog.vala:284 +msgid "Copy to clipboard" +msgstr "Копировать в буфер обмена" + #: src/ui/dialogs/GameFSOverlaysDialog.vala:52 #, c-format msgid "%s: Overlays" diff --git a/src/app.vala b/src/app.vala index 4b3c87c9..f14ce5f3 100644 --- a/src/app.vala +++ b/src/app.vala @@ -32,17 +32,22 @@ namespace GameHub { public class Application: Granite.Application { + public static Application instance; + + private GameHub.UI.Windows.MainWindow? main_window; + construct { application_id = ProjectConfig.PROJECT_NAME; - flags = ApplicationFlags.FLAGS_NONE; + flags = ApplicationFlags.HANDLES_COMMAND_LINE; program_name = "GameHub"; build_version = ProjectConfig.VERSION; + instance = this; } - protected override void activate() + private void init() { - info("Distro: %s", Utils.get_distro()); + if(Platforms != null && GameSources != null && CompatTools != null) return; FSUtils.make_dirs(); @@ -79,12 +84,23 @@ namespace GameHub var provider = new CssProvider(); provider.load_from_resource("/com/github/tkashkin/gamehub/GameHub.css"); StyleContext.add_provider_for_screen(Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } - #if MANETTE - GameHub.Utils.Gamepad.init(); - #endif + protected override void activate() + { + info("Distro: %s", Utils.get_distro()); + + if(main_window == null) + { + init(); - new GameHub.UI.Windows.MainWindow(this).show_all(); + #if MANETTE + GameHub.Utils.Gamepad.init(); + #endif + + main_window = new GameHub.UI.Windows.MainWindow(this); + main_window.show_all(); + } } public static int main(string[] args) @@ -102,5 +118,101 @@ namespace GameHub return app.run(args); } + + public override int command_line(ApplicationCommandLine cmd) + { + init(); + + string[] oargs = cmd.get_arguments(); + unowned string[] args = oargs; + + string? opt_run = null; + bool opt_show_compat = false; + bool opt_show = false; + + OptionEntry[] options = new OptionEntry[4]; + options[0] = { "run", 'r', 0, OptionArg.STRING, out opt_run, _("Run game"), null }; + options[1] = { "show-compat", 'c', 0, OptionArg.NONE, out opt_show_compat, _("Show compatibility options dialog"), null }; + options[2] = { "show", 's', 0, OptionArg.NONE, out opt_show, _("Show main window"), null }; + options[3] = { null }; + + var ctx = new OptionContext(); + ctx.add_main_entries(options, null); + try + { + ctx.parse(ref args); + } + catch(Error e) + { + warning(e.message); + } + + Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.INFO; + set_options(); + + if(opt_show || opt_run == null) + { + activate(); + main_window.present(); + } + + if(opt_run != null) + { + opt_run = opt_run.strip(); + if(opt_run.length > 0 && ":" in opt_run) + { + var id_parts = opt_run.split(":"); + var game = GameHub.Data.DB.Tables.Games.get(id_parts[0], id_parts[1]); + if(game != null) + { + info("Starting `%s`", game.name); + + var loop = new MainLoop(); + game.update_game_info.begin((obj, res) => { + game.update_game_info.end(res); + // wait for winewrap index update + Timeout.add(game.use_compat ? 2000 : 0, () => { + run_game.begin(game, opt_show_compat, (obj, res) => { + run_game.end(res); + info("`%s` finished", game.name); + loop.quit(); + }); + return Source.REMOVE; + }); + }); + loop.run(); + } + else + { + error("Game with id `%s` from source `%s` is not found", id_parts[1], id_parts[0]); + } + } + else + { + error("`%s` is not a fully-qualified game id", opt_run); + } + } + + return 0; + } + + private async void run_game(Game game, bool show_compat) + { + if(game.status.state == Game.State.INSTALLED) + { + if(game.use_compat) + { + yield game.run_with_compat(show_compat); + } + else + { + yield game.run(); + } + } + else if(game.status.state == Game.State.UNINSTALLED) + { + yield game.install(); + } + } } } diff --git a/src/data/Runnable.vala b/src/data/Runnable.vala index e56c3203..b2cf136a 100644 --- a/src/data/Runnable.vala +++ b/src/data/Runnable.vala @@ -59,7 +59,11 @@ namespace GameHub.Data { if(!RunnableIsLaunched) { - new UI.Dialogs.CompatRunDialog(this, is_opened_from_menu); + var dlg = new UI.Dialogs.CompatRunDialog(this, is_opened_from_menu); + dlg.destroy.connect(() => { + Idle.add(run_with_compat.callback); + }); + yield; } } diff --git a/src/data/compat/WineWrap.vala b/src/data/compat/WineWrap.vala index bf314eb1..e79fc4ed 100644 --- a/src/data/compat/WineWrap.vala +++ b/src/data/compat/WineWrap.vala @@ -40,6 +40,8 @@ namespace GameHub.Data.Compat private async void update_index() { + debug("[WineWrap] updating index"); + var root_node = yield Parser.parse_remote_json_file_async(WRAPPERS_INDEX_URL); if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) return; var root = root_node.get_object(); @@ -65,6 +67,8 @@ namespace GameHub.Data.Compat }) }; } + + debug("[WineWrap] index updated"); } public override bool can_install(Runnable runnable) diff --git a/src/ui/dialogs/CompatRunDialog.vala b/src/ui/dialogs/CompatRunDialog.vala index 5a67fdf7..871aa7a1 100644 --- a/src/ui/dialogs/CompatRunDialog.vala +++ b/src/ui/dialogs/CompatRunDialog.vala @@ -92,7 +92,7 @@ namespace GameHub.UI.Dialogs { case ResponseType.ACCEPT: run_with_compat(); - destroy(); + hide(); break; } }); @@ -110,7 +110,7 @@ namespace GameHub.UI.Dialogs { Idle.add(() => { run_with_compat(); - destroy(); + hide(); return Source.REMOVE; }); return; @@ -133,6 +133,7 @@ namespace GameHub.UI.Dialogs compat_tool_picker.selected.run_emulator.end(res); RunnableIsLaunched = game.is_running = emulated_game.is_running = false; emulated_game.update_status(); + destroy(); }); } else @@ -146,6 +147,7 @@ namespace GameHub.UI.Dialogs game.update_status(); (game as Game).playtime_tracked += ((get_real_time() / 1000000) - (game as Game).last_launch) / 60; game.save(); + destroy(); }); } diff --git a/src/ui/dialogs/GamePropertiesDialog.vala b/src/ui/dialogs/GamePropertiesDialog.vala index 43a83ee6..b78a1d21 100644 --- a/src/ui/dialogs/GamePropertiesDialog.vala +++ b/src/ui/dialogs/GamePropertiesDialog.vala @@ -270,6 +270,29 @@ namespace GameHub.UI.Dialogs game.notify_property("use-compat"); } + var gh_run_args_header = new HeaderLabel(_("Launch from terminal")); + gh_run_args_header.xpad = 8; + properties_box.add(gh_run_args_header); + + var gh_run_args_entry = new Entry(); + gh_run_args_entry.text = ProjectConfig.PROJECT_NAME + " --run " + game.full_id; + gh_run_args_entry.editable = false; + gh_run_args_entry.primary_icon_name = "utilities-terminal-symbolic"; + gh_run_args_entry.primary_icon_activatable = false; + gh_run_args_entry.secondary_icon_name = "edit-copy-symbolic"; + gh_run_args_entry.secondary_icon_activatable = true; + gh_run_args_entry.secondary_icon_tooltip_text = _("Copy to clipboard"); + gh_run_args_entry.margin_start = gh_run_args_entry.margin_end = 4; + properties_box.add(gh_run_args_entry); + + gh_run_args_entry.icon_press.connect((icon, event) => { + if(icon == EntryIconPosition.SECONDARY && ((EventButton) event).button == 1) + { + gh_run_args_entry.select_region(0, -1); + gh_run_args_entry.copy_clipboard(); + } + }); + content.add(tags_box); content.add(new Separator(Orientation.VERTICAL)); content.add(properties_box);