From d87f743a2bd2fac761b94de77ed7255d7a983f03 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:49:35 +0100 Subject: [PATCH 01/72] Add flat white icons This is mainly for dark mode users, as I think that the regular colour of the flat icons do not look good with dark mode. --- launcher/resources/flat_white/flat_white.qrc | 46 ++++++++ launcher/resources/flat_white/index.theme | 11 ++ .../resources/flat_white/scalable/about.svg | 3 + .../flat_white/scalable/accounts.svg | 3 + .../resources/flat_white/scalable/bug.svg | 3 + .../resources/flat_white/scalable/cat.svg | 3 + .../flat_white/scalable/centralmods.svg | 3 + .../flat_white/scalable/checkupdate.svg | 3 + .../resources/flat_white/scalable/copy.svg | 3 + .../flat_white/scalable/coremods.svg | 3 + .../flat_white/scalable/custom-commands.svg | 86 +++++++++++++++ .../resources/flat_white/scalable/discord.svg | 4 + .../flat_white/scalable/externaltools.svg | 3 + .../resources/flat_white/scalable/help.svg | 17 +++ .../flat_white/scalable/instance-settings.svg | 3 + .../resources/flat_white/scalable/jarmods.svg | 3 + .../resources/flat_white/scalable/java.svg | 3 + .../flat_white/scalable/language.svg | 103 ++++++++++++++++++ .../flat_white/scalable/launcher.svg | 2 + .../flat_white/scalable/loadermods.svg | 3 + .../resources/flat_white/scalable/log.svg | 3 + .../flat_white/scalable/minecraft.svg | 3 + .../resources/flat_white/scalable/multimc.svg | 3 + .../resources/flat_white/scalable/new.svg | 3 + .../resources/flat_white/scalable/news.svg | 3 + .../resources/flat_white/scalable/notes.svg | 3 + .../flat_white/scalable/packages.svg | 3 + .../resources/flat_white/scalable/patreon.svg | 3 + .../resources/flat_white/scalable/proxy.svg | 3 + .../flat_white/scalable/quickmods.svg | 3 + .../flat_white/scalable/reddit-alien.svg | 3 + .../resources/flat_white/scalable/refresh.svg | 3 + .../flat_white/scalable/resourcepacks.svg | 3 + .../scalable/screenshot-placeholder.svg | 3 + .../flat_white/scalable/screenshots.svg | 3 + .../flat_white/scalable/settings.svg | 3 + .../flat_white/scalable/shaderpacks.svg | 56 ++++++++++ .../resources/flat_white/scalable/star.svg | 3 + .../flat_white/scalable/status-bad.svg | 3 + .../flat_white/scalable/status-good.svg | 3 + .../flat_white/scalable/status-running.svg | 3 + .../flat_white/scalable/status-yellow.svg | 3 + .../flat_white/scalable/viewfolder.svg | 3 + .../resources/flat_white/scalable/worlds.svg | 3 + 44 files changed, 433 insertions(+) create mode 100644 launcher/resources/flat_white/flat_white.qrc create mode 100644 launcher/resources/flat_white/index.theme create mode 100644 launcher/resources/flat_white/scalable/about.svg create mode 100644 launcher/resources/flat_white/scalable/accounts.svg create mode 100644 launcher/resources/flat_white/scalable/bug.svg create mode 100644 launcher/resources/flat_white/scalable/cat.svg create mode 100644 launcher/resources/flat_white/scalable/centralmods.svg create mode 100644 launcher/resources/flat_white/scalable/checkupdate.svg create mode 100644 launcher/resources/flat_white/scalable/copy.svg create mode 100644 launcher/resources/flat_white/scalable/coremods.svg create mode 100644 launcher/resources/flat_white/scalable/custom-commands.svg create mode 100644 launcher/resources/flat_white/scalable/discord.svg create mode 100644 launcher/resources/flat_white/scalable/externaltools.svg create mode 100644 launcher/resources/flat_white/scalable/help.svg create mode 100644 launcher/resources/flat_white/scalable/instance-settings.svg create mode 100644 launcher/resources/flat_white/scalable/jarmods.svg create mode 100644 launcher/resources/flat_white/scalable/java.svg create mode 100644 launcher/resources/flat_white/scalable/language.svg create mode 100644 launcher/resources/flat_white/scalable/launcher.svg create mode 100644 launcher/resources/flat_white/scalable/loadermods.svg create mode 100644 launcher/resources/flat_white/scalable/log.svg create mode 100644 launcher/resources/flat_white/scalable/minecraft.svg create mode 100644 launcher/resources/flat_white/scalable/multimc.svg create mode 100644 launcher/resources/flat_white/scalable/new.svg create mode 100644 launcher/resources/flat_white/scalable/news.svg create mode 100644 launcher/resources/flat_white/scalable/notes.svg create mode 100644 launcher/resources/flat_white/scalable/packages.svg create mode 100644 launcher/resources/flat_white/scalable/patreon.svg create mode 100644 launcher/resources/flat_white/scalable/proxy.svg create mode 100644 launcher/resources/flat_white/scalable/quickmods.svg create mode 100644 launcher/resources/flat_white/scalable/reddit-alien.svg create mode 100644 launcher/resources/flat_white/scalable/refresh.svg create mode 100644 launcher/resources/flat_white/scalable/resourcepacks.svg create mode 100644 launcher/resources/flat_white/scalable/screenshot-placeholder.svg create mode 100644 launcher/resources/flat_white/scalable/screenshots.svg create mode 100644 launcher/resources/flat_white/scalable/settings.svg create mode 100644 launcher/resources/flat_white/scalable/shaderpacks.svg create mode 100644 launcher/resources/flat_white/scalable/star.svg create mode 100644 launcher/resources/flat_white/scalable/status-bad.svg create mode 100644 launcher/resources/flat_white/scalable/status-good.svg create mode 100644 launcher/resources/flat_white/scalable/status-running.svg create mode 100644 launcher/resources/flat_white/scalable/status-yellow.svg create mode 100644 launcher/resources/flat_white/scalable/viewfolder.svg create mode 100644 launcher/resources/flat_white/scalable/worlds.svg diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc new file mode 100644 index 00000000..d2b752b1 --- /dev/null +++ b/launcher/resources/flat_white/flat_white.qrc @@ -0,0 +1,46 @@ + + + + index.theme + scalable/about.svg + scalable/accounts.svg + scalable/bug.svg + scalable/cat.svg + scalable/centralmods.svg + scalable/checkupdate.svg + scalable/copy.svg + scalable/coremods.svg + scalable/custom-commands.svg + scalable/discord.svg + scalable/externaltools.svg + scalable/help.svg + scalable/instance-settings.svg + scalable/jarmods.svg + scalable/java.svg + scalable/language.svg + scalable/launcher.svg + scalable/loadermods.svg + scalable/log.svg + scalable/minecraft.svg + scalable/new.svg + scalable/news.svg + scalable/notes.svg + scalable/packages.svg + scalable/proxy.svg + scalable/quickmods.svg + scalable/reddit-alien.svg + scalable/refresh.svg + scalable/resourcepacks.svg + scalable/shaderpacks.svg + scalable/screenshot-placeholder.svg + scalable/screenshots.svg + scalable/settings.svg + scalable/star.svg + scalable/status-bad.svg + scalable/status-good.svg + scalable/status-running.svg + scalable/status-yellow.svg + scalable/viewfolder.svg + scalable/worlds.svg + + diff --git a/launcher/resources/flat_white/index.theme b/launcher/resources/flat_white/index.theme new file mode 100644 index 00000000..a0b3ba6f --- /dev/null +++ b/launcher/resources/flat_white/index.theme @@ -0,0 +1,11 @@ +[Icon Theme] +Name=White Flat +Comment=White version of the flat icons (for dark mode) +Inherits=multimc +Directories=scalable + +[scalable] +Size=48 +Type=Scalable +MinSize=16 +MaxSize=256 diff --git a/launcher/resources/flat_white/scalable/about.svg b/launcher/resources/flat_white/scalable/about.svg new file mode 100644 index 00000000..e42ca948 --- /dev/null +++ b/launcher/resources/flat_white/scalable/about.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/accounts.svg b/launcher/resources/flat_white/scalable/accounts.svg new file mode 100644 index 00000000..e714bde1 --- /dev/null +++ b/launcher/resources/flat_white/scalable/accounts.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/bug.svg b/launcher/resources/flat_white/scalable/bug.svg new file mode 100644 index 00000000..3122702e --- /dev/null +++ b/launcher/resources/flat_white/scalable/bug.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/cat.svg b/launcher/resources/flat_white/scalable/cat.svg new file mode 100644 index 00000000..18da097a --- /dev/null +++ b/launcher/resources/flat_white/scalable/cat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/centralmods.svg b/launcher/resources/flat_white/scalable/centralmods.svg new file mode 100644 index 00000000..d8d10f2f --- /dev/null +++ b/launcher/resources/flat_white/scalable/centralmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/checkupdate.svg b/launcher/resources/flat_white/scalable/checkupdate.svg new file mode 100644 index 00000000..0fa66fc2 --- /dev/null +++ b/launcher/resources/flat_white/scalable/checkupdate.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/copy.svg b/launcher/resources/flat_white/scalable/copy.svg new file mode 100644 index 00000000..1aaed97b --- /dev/null +++ b/launcher/resources/flat_white/scalable/copy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/coremods.svg b/launcher/resources/flat_white/scalable/coremods.svg new file mode 100644 index 00000000..32c34383 --- /dev/null +++ b/launcher/resources/flat_white/scalable/coremods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/custom-commands.svg b/launcher/resources/flat_white/scalable/custom-commands.svg new file mode 100644 index 00000000..3d67d8f1 --- /dev/null +++ b/launcher/resources/flat_white/scalable/custom-commands.svg @@ -0,0 +1,86 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/discord.svg b/launcher/resources/flat_white/scalable/discord.svg new file mode 100644 index 00000000..ee07ed25 --- /dev/null +++ b/launcher/resources/flat_white/scalable/discord.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/externaltools.svg b/launcher/resources/flat_white/scalable/externaltools.svg new file mode 100644 index 00000000..e7c0930c --- /dev/null +++ b/launcher/resources/flat_white/scalable/externaltools.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/help.svg b/launcher/resources/flat_white/scalable/help.svg new file mode 100644 index 00000000..82b413fe --- /dev/null +++ b/launcher/resources/flat_white/scalable/help.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/flat_white/scalable/instance-settings.svg b/launcher/resources/flat_white/scalable/instance-settings.svg new file mode 100644 index 00000000..7dac7b14 --- /dev/null +++ b/launcher/resources/flat_white/scalable/instance-settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/jarmods.svg b/launcher/resources/flat_white/scalable/jarmods.svg new file mode 100644 index 00000000..f0f298f3 --- /dev/null +++ b/launcher/resources/flat_white/scalable/jarmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/java.svg b/launcher/resources/flat_white/scalable/java.svg new file mode 100644 index 00000000..56bb481f --- /dev/null +++ b/launcher/resources/flat_white/scalable/java.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/language.svg b/launcher/resources/flat_white/scalable/language.svg new file mode 100644 index 00000000..18c22efb --- /dev/null +++ b/launcher/resources/flat_white/scalable/language.svg @@ -0,0 +1,103 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg new file mode 100644 index 00000000..d7ad0dd3 --- /dev/null +++ b/launcher/resources/flat_white/scalable/launcher.svg @@ -0,0 +1,2 @@ + + diff --git a/launcher/resources/flat_white/scalable/loadermods.svg b/launcher/resources/flat_white/scalable/loadermods.svg new file mode 100644 index 00000000..100f7a93 --- /dev/null +++ b/launcher/resources/flat_white/scalable/loadermods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/log.svg b/launcher/resources/flat_white/scalable/log.svg new file mode 100644 index 00000000..69b7c1dc --- /dev/null +++ b/launcher/resources/flat_white/scalable/log.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/minecraft.svg b/launcher/resources/flat_white/scalable/minecraft.svg new file mode 100644 index 00000000..a0348e79 --- /dev/null +++ b/launcher/resources/flat_white/scalable/minecraft.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/multimc.svg b/launcher/resources/flat_white/scalable/multimc.svg new file mode 100644 index 00000000..3dce2699 --- /dev/null +++ b/launcher/resources/flat_white/scalable/multimc.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/new.svg b/launcher/resources/flat_white/scalable/new.svg new file mode 100644 index 00000000..46dc3361 --- /dev/null +++ b/launcher/resources/flat_white/scalable/new.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/news.svg b/launcher/resources/flat_white/scalable/news.svg new file mode 100644 index 00000000..414e5454 --- /dev/null +++ b/launcher/resources/flat_white/scalable/news.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/notes.svg b/launcher/resources/flat_white/scalable/notes.svg new file mode 100644 index 00000000..4ce5f6f1 --- /dev/null +++ b/launcher/resources/flat_white/scalable/notes.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/packages.svg b/launcher/resources/flat_white/scalable/packages.svg new file mode 100644 index 00000000..909ad0b2 --- /dev/null +++ b/launcher/resources/flat_white/scalable/packages.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/patreon.svg b/launcher/resources/flat_white/scalable/patreon.svg new file mode 100644 index 00000000..b745765b --- /dev/null +++ b/launcher/resources/flat_white/scalable/patreon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/proxy.svg b/launcher/resources/flat_white/scalable/proxy.svg new file mode 100644 index 00000000..a86703f4 --- /dev/null +++ b/launcher/resources/flat_white/scalable/proxy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/quickmods.svg b/launcher/resources/flat_white/scalable/quickmods.svg new file mode 100644 index 00000000..9e0045b2 --- /dev/null +++ b/launcher/resources/flat_white/scalable/quickmods.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/reddit-alien.svg b/launcher/resources/flat_white/scalable/reddit-alien.svg new file mode 100644 index 00000000..be22148c --- /dev/null +++ b/launcher/resources/flat_white/scalable/reddit-alien.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/refresh.svg b/launcher/resources/flat_white/scalable/refresh.svg new file mode 100644 index 00000000..08c63bdf --- /dev/null +++ b/launcher/resources/flat_white/scalable/refresh.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/resourcepacks.svg b/launcher/resources/flat_white/scalable/resourcepacks.svg new file mode 100644 index 00000000..9dd73c3a --- /dev/null +++ b/launcher/resources/flat_white/scalable/resourcepacks.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/screenshot-placeholder.svg b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg new file mode 100644 index 00000000..41eb6fcf --- /dev/null +++ b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/screenshots.svg b/launcher/resources/flat_white/scalable/screenshots.svg new file mode 100644 index 00000000..68cf8969 --- /dev/null +++ b/launcher/resources/flat_white/scalable/screenshots.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/settings.svg b/launcher/resources/flat_white/scalable/settings.svg new file mode 100644 index 00000000..7dac7b14 --- /dev/null +++ b/launcher/resources/flat_white/scalable/settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/shaderpacks.svg b/launcher/resources/flat_white/scalable/shaderpacks.svg new file mode 100644 index 00000000..ccae221c --- /dev/null +++ b/launcher/resources/flat_white/scalable/shaderpacks.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + diff --git a/launcher/resources/flat_white/scalable/star.svg b/launcher/resources/flat_white/scalable/star.svg new file mode 100644 index 00000000..116f952e --- /dev/null +++ b/launcher/resources/flat_white/scalable/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-bad.svg b/launcher/resources/flat_white/scalable/status-bad.svg new file mode 100644 index 00000000..5a121c09 --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-bad.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-good.svg b/launcher/resources/flat_white/scalable/status-good.svg new file mode 100644 index 00000000..ccb732ab --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-good.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-running.svg b/launcher/resources/flat_white/scalable/status-running.svg new file mode 100644 index 00000000..aa2d5fbf --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-running.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/status-yellow.svg b/launcher/resources/flat_white/scalable/status-yellow.svg new file mode 100644 index 00000000..772699d3 --- /dev/null +++ b/launcher/resources/flat_white/scalable/status-yellow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/viewfolder.svg b/launcher/resources/flat_white/scalable/viewfolder.svg new file mode 100644 index 00000000..145f8624 --- /dev/null +++ b/launcher/resources/flat_white/scalable/viewfolder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/worlds.svg b/launcher/resources/flat_white/scalable/worlds.svg new file mode 100644 index 00000000..cea30cf8 --- /dev/null +++ b/launcher/resources/flat_white/scalable/worlds.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 92dfd659f1a3e11accdbf0ebbdc7cb91f74d9a21 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:54:26 +0100 Subject: [PATCH 02/72] Fix .QRC file for flat white icons --- launcher/resources/flat_white/flat_white.qrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index d2b752b1..feda4762 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -1,6 +1,6 @@ - + index.theme scalable/about.svg scalable/accounts.svg From 0a7383a4e1c36b0dbbdc615433a30665d1777f64 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 20 Oct 2022 16:54:39 -0300 Subject: [PATCH 03/72] fix: hide ProgressDialog when failing/succeeding tasks WHY IS QT LIKE THAT AAAAAAAA Signed-off-by: flow --- launcher/ui/dialogs/ProgressDialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index 68dd4d17..05269f62 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -136,11 +136,13 @@ void ProgressDialog::onTaskStarted() {} void ProgressDialog::onTaskFailed(QString failure) { reject(); + hide(); } void ProgressDialog::onTaskSucceeded() { accept(); + hide(); } void ProgressDialog::changeStatus(const QString& status) From 01b90809e8be2bef02644ba91feceb21b6f7cb8f Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 20 Oct 2022 16:55:22 -0300 Subject: [PATCH 04/72] fix: memory leak when finishing blocked mods job Signed-off-by: flow --- launcher/modplatform/flame/FileResolvingTask.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 1e7f5559..0b2431f7 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -66,7 +66,11 @@ void Flame::FileResolvingTask::netJobFinished() } index++; } - connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); + connect(job, &NetJob::finished, this, + [this, &job] { + modrinthCheckFinished(); + job->deleteLater(); + }); job->start(); } From 919f8c54d74f81e7144d8a18a1ef068e3538f458 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 21 Oct 2022 17:42:18 +0200 Subject: [PATCH 05/72] fix: don't build renovate branches They will be built using the pull_requests event anyway. Signed-off-by: Sefa Eyeoglu --- .github/workflows/trigger_builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger_builds.yml b/.github/workflows/trigger_builds.yml index 55b4fdd4..8adaa5e5 100644 --- a/.github/workflows/trigger_builds.yml +++ b/.github/workflows/trigger_builds.yml @@ -3,7 +3,7 @@ name: Build Application on: push: branches-ignore: - - 'stable' + - 'renovate/**' paths-ignore: - '**.md' - '**/LICENSE' From 7eecf454e83314cd6f8029f54678dea568d41843 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 21 Oct 2022 14:07:43 -0300 Subject: [PATCH 06/72] fix: remove max height logic for mod update changelogs It's not worth it to keep this, it's just a heuristic that fails from time to time. Signed-off-by: flow --- launcher/ui/dialogs/ModUpdateDialog.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 4171586e..cedd4a96 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -366,33 +366,28 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info) auto changelog = new QTreeWidgetItem(changelog_item); auto changelog_area = new QTextBrowser(); + QString text = info.changelog; switch (info.provider) { case ModPlatform::Provider::MODRINTH: { HoeDown h; // HoeDown bug?: \n aren't converted to
- auto text = h.process(info.changelog.toUtf8()); + text = h.process(info.changelog.toUtf8()); // Don't convert if there's an HTML tag right after (Qt rendering weirdness) text.remove(QRegularExpression("(\n+)(?=<)")); text.replace('\n', "
"); - changelog_area->setHtml(text); break; } - case ModPlatform::Provider::FLAME: { - changelog_area->setHtml(info.changelog); + default: break; - } } + changelog_area->setHtml(text); changelog_area->setOpenExternalLinks(true); - changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap); + changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::WidgetWidth); changelog_area->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - // HACK: Is there a better way of achieving this? - auto font_height = QFontMetrics(changelog_area->font()).height(); - changelog_area->setMaximumHeight((changelog_area->toPlainText().count(QRegularExpression("\n|
")) + 2) * font_height); - ui->modTreeWidget->setItemWidget(changelog, 0, changelog_area); ui->modTreeWidget->addTopLevelItem(item_top); From 1288b926153c86b7966727e60de4af8e7dcb4031 Mon Sep 17 00:00:00 2001 From: Hibi <69405847+Hibiii@users.noreply.github.com> Date: Fri, 21 Oct 2022 15:40:28 -0300 Subject: [PATCH 07/72] Add argument to show instance window --- launcher/Application.cpp | 14 +++++++++++++- launcher/Application.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 6ffec1ae..ace06c2c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -245,7 +245,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"}, {{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"}, {"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"}, - {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"} + {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}, + {"show", "Opens the window for the specified instance (by instance ID)", "show"} }); parser.addHelpOption(); parser.addVersionOption(); @@ -257,6 +258,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_profileToUse = parser.value("profile"); m_liveCheck = parser.isSet("alive"); m_zipToImport = parser.value("import"); + m_instanceIdToShowWindowOf = parser.value("show"); // error if --launch is missing with --server or --profile if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) @@ -986,6 +988,16 @@ void Application::performMainStartupAction() return; } } + if(!m_instanceIdToShowWindowOf.isEmpty()) + { + auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf); + if(inst) + { + qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf; + showInstanceWindow(inst); + return; + } + } if(!m_mainWindow) { // normal main window diff --git a/launcher/Application.h b/launcher/Application.h index 34ad8c15..c453cc28 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -301,6 +301,7 @@ public: QString m_profileToUse; bool m_liveCheck = false; QUrl m_zipToImport; + QString m_instanceIdToShowWindowOf; std::unique_ptr logFile; }; From 5b75869c0ba60e00147d723d5633c9f6a5d6304e Mon Sep 17 00:00:00 2001 From: Hibi <69405847+Hibiii@users.noreply.github.com> Date: Fri, 21 Oct 2022 16:10:03 -0300 Subject: [PATCH 08/72] Add --show to manual page --- program_info/prismlauncher.6.scd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/program_info/prismlauncher.6.scd b/program_info/prismlauncher.6.scd index e3c7de86..f979e457 100644 --- a/program_info/prismlauncher.6.scd +++ b/program_info/prismlauncher.6.scd @@ -26,6 +26,9 @@ Here are the current features of Prism Launcher. *-l, --launch*=INSTANCE_ID Launch the instance specified by INSTANCE_ID. +*--show*=INSTANCE_ID + Show the configuration window of the instance specified by INSTANCE_ID. + *--alive* Write a small 'live.check' file after Prism Launcher starts. From 82d1dbf1736bb234938db7fdb8aecbc954023989 Mon Sep 17 00:00:00 2001 From: Hibi <69405847+Hibiii@users.noreply.github.com> Date: Fri, 21 Oct 2022 17:59:35 -0300 Subject: [PATCH 09/72] DCO Remediation Commit for Hibi <69405847+Hibiii@users.noreply.github.com> I, Hibi <69405847+Hibiii@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 1288b926153c86b7966727e60de4af8e7dcb4031 I, Hibi <69405847+Hibiii@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 5b75869c0ba60e00147d723d5633c9f6a5d6304e Signed-off-by: Hibi <69405847+Hibiii@users.noreply.github.com> From 9b17cde01929e58819c353868734f81faf811958 Mon Sep 17 00:00:00 2001 From: forkiesassds Date: Sat, 22 Oct 2022 01:19:51 +0300 Subject: [PATCH 10/72] CurseForge modpack page improvements Signed-off-by: forkiesassds --- .../ui/pages/modplatform/flame/FlameModel.cpp | 52 +++++++++++-------- .../ui/pages/modplatform/flame/FlamePage.cpp | 10 ++++ .../ui/pages/modplatform/flame/FlamePage.ui | 9 +++- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index b9804681..9f8605eb 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -1,6 +1,7 @@ #include "FlameModel.h" #include #include "Application.h" +#include "ui/widgets/ProjectItem.h" #include #include @@ -31,29 +32,38 @@ QVariant ListModel::data(const QModelIndex& index, int role) const } IndexedPack pack = modpacks.at(pos); - if (role == Qt::DisplayRole) { - return pack.name; - } else if (role == Qt::ToolTipRole) { - if (pack.description.length() > 100) { - // some magic to prevent to long tooltips and replace html linebreaks - QString edit = pack.description.left(97); - edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); - return edit; + switch (role) { + case Qt::ToolTipRole: { + if (pack.description.length() > 100) { + // some magic to prevent to long tooltips and replace html linebreaks + QString edit = pack.description.left(97); + edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); + return edit; + } + return pack.description; + } case Qt::DecorationRole: { + if (m_logoMap.contains(pack.logoName)) { + return (m_logoMap.value(pack.logoName)); + } + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); + ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); + return icon; + } case Qt::UserRole: { + QVariant v; + v.setValue(pack); + return v; } - return pack.description; - } else if (role == Qt::DecorationRole) { - if (m_logoMap.contains(pack.logoName)) { - return (m_logoMap.value(pack.logoName)); - } - QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); - return icon; - } else if (role == Qt::UserRole) { - QVariant v; - v.setValue(pack); - return v; + case Qt::SizeHintRole: + return QSize(0, 58); + case UserDataTypes::TITLE: + return pack.name; + case UserDataTypes::DESCRIPTION: + return pack.description; + case UserDataTypes::SELECTED: + return false; + default: + break; } - return QVariant(); } diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 7d2ba2e2..a65b6585 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -43,6 +43,10 @@ #include "InstanceImportTask.h" #include "Json.h" #include "ui/dialogs/NewInstanceDialog.h" +#include "ui/widgets/ProjectItem.h" +#include "modplatform/flame/FlameAPI.h" + +static FlameAPI api; FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) { @@ -66,6 +70,9 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(paren connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged); connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlamePage::onVersionSelectionChanged); + + ui->packView->setItemDelegate(new ProjectItemDelegate(this)); + ui->packDescription->setMetaEntry("FlamePacks"); } FlamePage::~FlamePage() @@ -250,7 +257,10 @@ void FlamePage::updateUi() text += "- " + tr("Source code: %1").arg(current.extra.sourceUrl) + "
"; } + text += "
"; + text += api.getModDescription(current.addonId).toUtf8(); ui->packDescription->setHtml(text + current.description); + ui->packDescription->flush(); } diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui index 1a3d0225..71d19513 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.ui +++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui @@ -66,7 +66,7 @@ - + true @@ -99,6 +99,13 @@ + + + ProjectDescriptionPage + QTextBrowser +
ui/widgets/ProjectDescriptionPage.h
+
+
packView packDescription From ba4af1a890f3d2990d86a36a2fbbb16ad2c774cf Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 21 Oct 2022 19:54:10 -0400 Subject: [PATCH 11/72] fix: make jars path specific to prism Signed-off-by: seth --- CMakeLists.txt | 2 +- launcher/Application.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 131d3e53..97bad31b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,7 +249,7 @@ if(UNIX AND APPLE) elseif(UNIX) set(BINARY_DEST_DIR "bin") set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") - set(JARS_DEST_DIR "share/jars") + set(JARS_DEST_DIR "share/${Launcher_APP_BINARY_NAME}") set(LAUNCHER_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory") set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory") set(LAUNCHER_ICON_DEST_DIR "share/icons/hicolor/scalable/apps" CACHE STRING "Path to the scalable icon directory") diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 6ffec1ae..babf824a 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1571,7 +1571,7 @@ QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - FS::PathCombine(m_rootPath, "share/jars"), + FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_NAME), #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars") From 4a2b25e841224441c0dcaa81bcbd0f716d64201e Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 21 Oct 2022 21:29:28 -0400 Subject: [PATCH 12/72] fix: use correct variable for jars path Signed-off-by: seth --- buildconfig/BuildConfig.cpp.in | 1 + buildconfig/BuildConfig.h | 1 + launcher/Application.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index 50e5e8a4..fc68326c 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -42,6 +42,7 @@ Config::Config() { // Name and copyright LAUNCHER_NAME = "@Launcher_Name@"; + LAUNCHER_APP_BINARY_NAME = "@Launcher_APP_BINARY_NAME@"' LAUNCHER_DISPLAYNAME = "@Launcher_DisplayName@"; LAUNCHER_COPYRIGHT = "@Launcher_Copyright@"; LAUNCHER_DOMAIN = "@Launcher_Domain@"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index ef384ed2..13ccdaa1 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -44,6 +44,7 @@ class Config { public: Config(); QString LAUNCHER_NAME; + QString LAUNCHER_APP_BINARY_NAME; QString LAUNCHER_DISPLAYNAME; QString LAUNCHER_COPYRIGHT; QString LAUNCHER_DOMAIN; diff --git a/launcher/Application.cpp b/launcher/Application.cpp index babf824a..97f757f7 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1571,7 +1571,7 @@ QString Application::getJarPath(QString jarFile) { QStringList potentialPaths = { #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) - FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_NAME), + FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME), #endif FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars") From 2592c690213506c3cdfbc441c20f13ef7cf3eb23 Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 21 Oct 2022 21:37:31 -0400 Subject: [PATCH 13/72] semicolon fail i was off by one key :( Signed-off-by: seth --- buildconfig/BuildConfig.cpp.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index fc68326c..b8fa5133 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -42,7 +42,7 @@ Config::Config() { // Name and copyright LAUNCHER_NAME = "@Launcher_Name@"; - LAUNCHER_APP_BINARY_NAME = "@Launcher_APP_BINARY_NAME@"' + LAUNCHER_APP_BINARY_NAME = "@Launcher_APP_BINARY_NAME@"; LAUNCHER_DISPLAYNAME = "@Launcher_DisplayName@"; LAUNCHER_COPYRIGHT = "@Launcher_Copyright@"; LAUNCHER_DOMAIN = "@Launcher_Domain@"; From 56ae4e5b6ad984d4c9569cb024d807bd695555a6 Mon Sep 17 00:00:00 2001 From: Bensuperpc Date: Sat, 22 Oct 2022 13:04:48 +0200 Subject: [PATCH 14/72] Change old style cast to C++ cast Change old style cast to C++ cast Signed-off-by: Bensuperpc --- launcher/GZip.cpp | 4 ++-- launcher/HoeDown.h | 2 +- launcher/tasks/Task.cpp | 2 +- libraries/LocalPeer/src/LocalPeer.cpp | 2 +- libraries/katabasis/src/DeviceFlow.cpp | 2 +- libraries/murmur2/src/MurmurHash2.cpp | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp index 067104cf..e36dc8a4 100644 --- a/launcher/GZip.cpp +++ b/launcher/GZip.cpp @@ -72,7 +72,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte uncompLength *= 2; } - strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out); + strm.next_out = reinterpret_cast((uncompressedBytes.data() + strm.total_out)); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. @@ -129,7 +129,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) { compressedBytes.resize(compressedBytes.size() * 2); } - zs.next_out = (Bytef *) (compressedBytes.data() + offset); + zs.next_out = reinterpret_cast((compressedBytes.data() + offset)); temp = zs.avail_out = compressedBytes.size() - offset; ret = deflate(&zs, Z_FINISH); offset += temp - zs.avail_out; diff --git a/launcher/HoeDown.h b/launcher/HoeDown.h index b9e06ffb..cb62de6c 100644 --- a/launcher/HoeDown.h +++ b/launcher/HoeDown.h @@ -42,7 +42,7 @@ public: } void put(QByteArray input) { - hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size()); + hoedown_buffer_put(buf, reinterpret_cast(input.data()), input.size()); } const uint8_t * data() const { diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp index b4babdd4..9ea1bb26 100644 --- a/launcher/tasks/Task.cpp +++ b/launcher/tasks/Task.cpp @@ -153,7 +153,7 @@ QString Task::describe() auto name = objectName(); if(name.isEmpty()) { - out << QString("0x%1").arg((quintptr)this, 0, 16); + out << QString("0x%1").arg(reinterpret_cast(this), 0, 16); } else { diff --git a/libraries/LocalPeer/src/LocalPeer.cpp b/libraries/LocalPeer/src/LocalPeer.cpp index 3c3d8b4c..b7149c40 100644 --- a/libraries/LocalPeer/src/LocalPeer.cpp +++ b/libraries/LocalPeer/src/LocalPeer.cpp @@ -210,7 +210,7 @@ void LocalPeer::receiveConnection() return; } - while (socket->bytesAvailable() < (int)sizeof(quint32)) + while (socket->bytesAvailable() < static_cast(sizeof(quint32))) { socket->waitForReadyRead(); } diff --git a/libraries/katabasis/src/DeviceFlow.cpp b/libraries/katabasis/src/DeviceFlow.cpp index ba1d121d..f78fd620 100644 --- a/libraries/katabasis/src/DeviceFlow.cpp +++ b/libraries/katabasis/src/DeviceFlow.cpp @@ -445,7 +445,7 @@ void DeviceFlow::onRefreshError(QNetworkReply::NetworkError error, QNetworkReply if(refreshReply) { refreshReply->deleteLater(); } - qDebug() << "DeviceFlow::onRefreshFinished: Error" << (int)error << " - " << errorString; + qDebug() << "DeviceFlow::onRefreshFinished: Error" << static_cast(error) << " - " << errorString; } } diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index b625efb1..c13608f0 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -55,12 +55,12 @@ uint32_t MurmurHash2(std::ifstream&& file_stream, std::size_t buffer_size, std:: // Mix 4 bytes at a time into the hash if (index == 0) - FourBytes_MurmurHash2((unsigned char*)&data, info); + FourBytes_MurmurHash2(reinterpret_cast(&data), info); } } while (!file_stream.eof()); // Do one last bit shuffle in the hash - FourBytes_MurmurHash2((unsigned char*)&data, info); + FourBytes_MurmurHash2(reinterpret_cast(&data), info); delete[] buffer; @@ -72,7 +72,7 @@ void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev) { if (prev.len >= 4) { // Not the final mix - uint32_t k = *(uint32_t*)data; + uint32_t k = *reinterpret_cast(data); k *= m; k ^= k >> r; From a6b13487f0e27c8bea1917720a0c5c1eb1eb206c Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Thu, 20 Oct 2022 18:30:32 +0100 Subject: [PATCH 15/72] ATLauncher: Abort install if optional mods dialog is closed This matches the behaviour of ATLauncher. --- launcher/modplatform/atlauncher/ATLPackInstallTask.cpp | 7 ++++++- launcher/modplatform/atlauncher/ATLPackInstallTask.h | 2 +- .../atlauncher/AtlUserInteractionSupportImpl.cpp | 7 +++++-- .../modplatform/atlauncher/AtlUserInteractionSupportImpl.h | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index a553eafd..68d75943 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -736,7 +736,12 @@ void PackInstallTask::downloadMods() QVector selectedMods; if (!optionalMods.isEmpty()) { setStatus(tr("Selecting optional mods...")); - selectedMods = m_support->chooseOptionalMods(m_version, optionalMods); + auto mods = m_support->chooseOptionalMods(m_version, optionalMods); + if (!mods.has_value()) { + emitAborted(); + return; + } + selectedMods = mods.value(); } setStatus(tr("Downloading mods...")); diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h index ed4436f0..78cd87fb 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h @@ -62,7 +62,7 @@ public: /** * Requests a user interaction to select which optional mods should be installed. */ - virtual QVector chooseOptionalMods(PackVersion version, QVector mods) = 0; + virtual std::optional> chooseOptionalMods(PackVersion version, QVector mods) = 0; /** * Requests a user interaction to select a component version from a given version list diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp index 03196685..c68e40ba 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -43,10 +43,13 @@ AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget *parent) : { } -QVector AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) +std::optional> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) { AtlOptionalModDialog optionalModDialog(m_parent, version, mods); - optionalModDialog.exec(); + auto result = optionalModDialog.exec(); + if (result == QDialog::Rejected) { + return {}; + } return optionalModDialog.getResult(); } diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h index aa22fc73..3b37c9be 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h @@ -47,7 +47,7 @@ public: private: QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; - QVector chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) override; + std::optional> chooseOptionalMods(ATLauncher::PackVersion version, QVector mods) override; void displayMessage(QString message) override; private: From a4f4f2891c8127c86365b1f36cf2982e1cfafa2c Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sat, 22 Oct 2022 12:56:40 +0100 Subject: [PATCH 16/72] DCO Remediation Commit for a6b13487 I, Jamie Mansfield , hereby add my Signed-off-by to this commit: a6b13487f0e27c8bea1917720a0c5c1eb1eb206c Signed-off-by: Jamie Mansfield From 970e4b020ea14a1fbd5abe65517a3e26399280cb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 22 Oct 2022 14:11:51 +0200 Subject: [PATCH 17/72] fix: fix segfault when resolving Flame resources Signed-off-by: Sefa Eyeoglu --- launcher/modplatform/flame/FileResolvingTask.cpp | 14 ++++++-------- launcher/modplatform/flame/FileResolvingTask.h | 3 ++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 0b2431f7..c50abb8f 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -12,6 +12,8 @@ bool Flame::FileResolvingTask::abort() bool aborted = true; if (m_dljob) aborted &= m_dljob->abort(); + if (m_checkJob) + aborted &= m_checkJob->abort(); return aborted ? Task::abort() : false; } @@ -40,7 +42,7 @@ void Flame::FileResolvingTask::netJobFinished() setProgress(1, 3); int index = 0; // job to check modrinth for blocked projects - auto job = new NetJob("Modrinth check", m_network); + m_checkJob = new NetJob("Modrinth check", m_network); blockedProjects = QMap(); auto doc = Json::requireDocument(*result); auto array = Json::requireArray(doc.object()["data"]); @@ -60,19 +62,15 @@ void Flame::FileResolvingTask::netJobFinished() out.resolved = true; }); - job->addNetAction(dl); + m_checkJob->addNetAction(dl); blockedProjects.insert(&out, output); } } index++; } - connect(job, &NetJob::finished, this, - [this, &job] { - modrinthCheckFinished(); - job->deleteLater(); - }); + connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); - job->start(); + m_checkJob->start(); } void Flame::FileResolvingTask::modrinthCheckFinished() { diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h index f71b87ce..8fc17ea9 100644 --- a/launcher/modplatform/flame/FileResolvingTask.h +++ b/launcher/modplatform/flame/FileResolvingTask.h @@ -30,8 +30,9 @@ protected slots: private: /* data */ shared_qobject_ptr m_network; Flame::Manifest m_toProcess; - std::shared_ptr result; + std::shared_ptr result; NetJob::Ptr m_dljob; + NetJob::Ptr m_checkJob; void modrinthCheckFinished(); From 8b3093e7580c01e43d80803b8b931445f9438bc8 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 22 Oct 2022 14:57:03 +0200 Subject: [PATCH 18/72] chore: add PR template Signed-off-by: Sefa Eyeoglu --- .github/pull_request_template.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..41f0604e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ + From 1dad35ca760662b9fc7c22cc0799403f75780bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=B6ritz?= Date: Sat, 22 Oct 2022 15:00:52 +0200 Subject: [PATCH 19/72] update macos plist contents (fixes #132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Möritz --- CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 131d3e53..09f62bb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,19 +211,19 @@ if(NOT (UNIX AND APPLE)) endif() if(UNIX AND APPLE) - set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") - set(LIBRARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") - set(PLUGIN_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") - set(FRAMEWORK_DEST_DIR "${Launcher_Name}.app/Contents/Frameworks") - set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources") - set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars") + set(BINARY_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") + set(LIBRARY_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") + set(PLUGIN_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") + set(FRAMEWORK_DEST_DIR "${Launcher_DisplayName}.app/Contents/Frameworks") + set(RESOURCES_DEST_DIR "${Launcher_DisplayName}.app/Contents/Resources") + set(JARS_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS/jars") # Apps to bundle - set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") + set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_DisplayName}.app") # Mac bundle settings - set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") - set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") + set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_DisplayName}") + set(MACOSX_BUNDLE_INFO_STRING "${Launcher_DisplayName}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.prismlauncher.${Launcher_Name}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") From 500a7eceabd292a7ddef5a5e2cec0fd26d66cef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=B6ritz?= Date: Sat, 22 Oct 2022 15:10:32 +0200 Subject: [PATCH 20/72] update macOS build process to work with new .app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tobias Möritz --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6400791..f67ba4c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -249,8 +249,8 @@ jobs: cmake --install ${{ env.BUILD_DIR }} cd ${{ env.INSTALL_DIR }} - chmod +x "PrismLauncher.app/Contents/MacOS/prismlauncher" - sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PrismLauncher.app/Contents/MacOS/prismlauncher" + chmod +x "Prism Launcher.app/Contents/MacOS/prismlauncher" + sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "Prism Launcher.app/Contents/MacOS/prismlauncher" tar -czf ../PrismLauncher.tar.gz * - name: Make Sparkle signature (macOS) From 0e17eee0960edd67a60f86c704a4c23237463caf Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sat, 22 Oct 2022 15:22:30 +0100 Subject: [PATCH 21/72] ATLauncher: Fix pack installation always aborting I made a mistake during when cherry picking a previous commit, this applies the change - and fixes installing ATLauncher packs. --- .../ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp index 004fdc57..9138dcbb 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp @@ -331,7 +331,7 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVers connect(ui->clearAllButton, &QPushButton::clicked, listModel, &AtlOptionalModListModel::clearAll); connect(ui->installButton, &QPushButton::clicked, - this, &QDialog::close); + this, &QDialog::accept); } AtlOptionalModDialog::~AtlOptionalModDialog() { From 1471eddc7e9a5383218daf0fb271987d81e7096b Mon Sep 17 00:00:00 2001 From: AliceDTRH <57547425+AliceDTRH@users.noreply.github.com> Date: Sat, 22 Oct 2022 16:40:31 +0200 Subject: [PATCH 22/72] Deduplicates java installs before passing it on Signed-off-by: AliceDTRH <57547425+AliceDTRH@users.noreply.github.com> --- launcher/java/JavaUtils.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 040fe821..81b3a0b2 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -379,7 +379,9 @@ QList JavaUtils::FindJavaPaths() } } - return addJavasFromEnv(candidates); + javas = addJavasFromEnv(javas); + javas.removeDuplicates(); + return javas; } #elif defined(Q_OS_MAC) @@ -402,7 +404,9 @@ QList JavaUtils::FindJavaPaths() javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java"); javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java"); } - return addJavasFromEnv(javas); + javas = addJavasFromEnv(javas); + javas.removeDuplicates(); + return javas; } #elif defined(Q_OS_LINUX) @@ -448,7 +452,9 @@ QList JavaUtils::FindJavaPaths() scanJavaDir("/opt/jdks"); // flatpak scanJavaDir("/app/jdk"); - return addJavasFromEnv(javas); + javas = addJavasFromEnv(javas); + javas.removeDuplicates(); + return javas; } #else QList JavaUtils::FindJavaPaths() From a6e65dfc7a7e8080297b59ecf322b788d1c9bad2 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Sat, 22 Oct 2022 15:40:39 +0100 Subject: [PATCH 23/72] Add new flat white icons --- launcher/resources/flat_white/scalable/delete.svg | 5 +++++ launcher/resources/flat_white/scalable/export.svg | 5 +++++ launcher/resources/flat_white/scalable/rename.svg | 4 ++++ launcher/resources/flat_white/scalable/tag.svg | 4 ++++ 4 files changed, 18 insertions(+) create mode 100644 launcher/resources/flat_white/scalable/delete.svg create mode 100644 launcher/resources/flat_white/scalable/export.svg create mode 100644 launcher/resources/flat_white/scalable/rename.svg create mode 100644 launcher/resources/flat_white/scalable/tag.svg diff --git a/launcher/resources/flat_white/scalable/delete.svg b/launcher/resources/flat_white/scalable/delete.svg new file mode 100644 index 00000000..4cf7206e --- /dev/null +++ b/launcher/resources/flat_white/scalable/delete.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/export.svg b/launcher/resources/flat_white/scalable/export.svg new file mode 100644 index 00000000..a28bb254 --- /dev/null +++ b/launcher/resources/flat_white/scalable/export.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/rename.svg b/launcher/resources/flat_white/scalable/rename.svg new file mode 100644 index 00000000..f2067c16 --- /dev/null +++ b/launcher/resources/flat_white/scalable/rename.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/tag.svg b/launcher/resources/flat_white/scalable/tag.svg new file mode 100644 index 00000000..2473126f --- /dev/null +++ b/launcher/resources/flat_white/scalable/tag.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 99e1c13e80d12764f57a993661656d9ed7de27bb Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Sat, 22 Oct 2022 15:50:06 +0100 Subject: [PATCH 24/72] fix: add flat_white to code --- launcher/CMakeLists.txt | 1 + launcher/main.cpp | 1 + launcher/resources/flat_white/index.theme | 2 +- launcher/ui/pages/global/LauncherPage.cpp | 13 ++++++++++--- launcher/ui/pages/global/LauncherPage.ui | 5 +++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 79ac49c7..0dae47df 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -602,6 +602,7 @@ SET(LAUNCHER_SOURCES resources/OSX/OSX.qrc resources/iOS/iOS.qrc resources/flat/flat.qrc + resources/flat_white/flat_white.qrc resources/documents/documents.qrc ../${Launcher_Branding_LogoQRC} diff --git a/launcher/main.cpp b/launcher/main.cpp index c6a7614c..e2116f38 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -84,6 +84,7 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(OSX); Q_INIT_RESOURCE(iOS); Q_INIT_RESOURCE(flat); + Q_INIT_RESOURCE(flat_white); return app.exec(); } case Application::Failed: diff --git a/launcher/resources/flat_white/index.theme b/launcher/resources/flat_white/index.theme index a0b3ba6f..0292509f 100644 --- a/launcher/resources/flat_white/index.theme +++ b/launcher/resources/flat_white/index.theme @@ -1,5 +1,5 @@ [Icon Theme] -Name=White Flat +Name=Flat (White) Comment=White version of the flat icons (for dark mode) Inherits=multimc Directories=scalable diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index b8431e8c..536ab22e 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -310,9 +310,12 @@ void LauncherPage::applySettings() s->set("IconTheme", "flat"); break; case 7: - s->set("IconTheme", "multimc"); + s->set("IconTheme", "flat_white"); break; case 8: + s->set("IconTheme", "multimc"); + break; + case 9: s->set("IconTheme", "custom"); break; } @@ -408,14 +411,18 @@ void LauncherPage::loadSettings() { ui->themeComboBox->setCurrentIndex(6); } - else if (theme == "multimc") + else if (theme == "flat_white") { ui->themeComboBox->setCurrentIndex(7); } - else if (theme == "custom") + else if (theme == "multimc") { ui->themeComboBox->setCurrentIndex(8); } + else if (theme == "custom") + { + ui->themeComboBox->setCurrentIndex(9); + } { auto currentTheme = s->get("ApplicationTheme").toString(); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 0d14f147..76a25f2e 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -300,6 +300,11 @@ Flat + + + Flat (White) + + Legacy From 46fe7e77b3285a77ee71df5f055b927b777ca112 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Sat, 22 Oct 2022 16:14:50 +0100 Subject: [PATCH 25/72] DCO Remediation Commit for he3als <65787561+he3als@users.noreply.github.com> I, he3als <65787561+he3als@users.noreply.github.com>, hereby add my Signed-off-by to this commit: d87f743a2bd2fac761b94de77ed7255d7a983f03 I, he3als <65787561+he3als@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 92dfd659f1a3e11accdbf0ebbdc7cb91f74d9a21 I, he3als <65787561+he3als@users.noreply.github.com>, hereby add my Signed-off-by to this commit: a6e65dfc7a7e8080297b59ecf322b788d1c9bad2 I, he3als <65787561+he3als@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 99e1c13e80d12764f57a993661656d9ed7de27bb Signed-off-by: he3als <65787561+he3als@users.noreply.github.com> --- launcher/resources/flat_white/index.theme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/resources/flat_white/index.theme b/launcher/resources/flat_white/index.theme index 0292509f..54dd0e10 100644 --- a/launcher/resources/flat_white/index.theme +++ b/launcher/resources/flat_white/index.theme @@ -1,6 +1,6 @@ [Icon Theme] Name=Flat (White) -Comment=White version of the flat icons (for dark mode) +Comment=White version of the flat icons (dark mode) Inherits=multimc Directories=scalable From b2789fef0fd91b6088bc8ec5ea17ea3b59810c96 Mon Sep 17 00:00:00 2001 From: AliceDTRH <57547425+AliceDTRH@users.noreply.github.com> Date: Sat, 22 Oct 2022 17:19:34 +0200 Subject: [PATCH 26/72] Use correct variable for Windows Signed-off-by: AliceDTRH <57547425+AliceDTRH@users.noreply.github.com> --- launcher/java/JavaUtils.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 81b3a0b2..6c0c60cd 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -379,9 +379,9 @@ QList JavaUtils::FindJavaPaths() } } - javas = addJavasFromEnv(javas); - javas.removeDuplicates(); - return javas; + candidates = addJavasFromEnv(candidates); + candidates.removeDuplicates(); + return candidates; } #elif defined(Q_OS_MAC) From 01db80d19a82ada1f6e37e3fb3ef45143156302b Mon Sep 17 00:00:00 2001 From: jn64 <23169302+jn64@users.noreply.github.com> Date: Sun, 23 Oct 2022 03:35:23 +0800 Subject: [PATCH 27/72] Fix version labels width Make labels fit to the contents, so Ibeam cursor doesn't appear over empty space. Should have been done with 90025ed. Signed-off-by: jn64 <23169302+jn64@users.noreply.github.com> --- launcher/ui/dialogs/AboutDialog.ui | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui index e0429321..4a9eef08 100644 --- a/launcher/ui/dialogs/AboutDialog.ui +++ b/launcher/ui/dialogs/AboutDialog.ui @@ -87,14 +87,11 @@ - + IBeamCursor - - Qt::AlignCenter - Qt::TextSelectableByMouse @@ -167,7 +164,7 @@ - + IBeamCursor @@ -183,7 +180,7 @@ - + IBeamCursor @@ -199,7 +196,7 @@ - + IBeamCursor @@ -215,7 +212,7 @@ - + IBeamCursor From 4777a4572267a604dc4fa8e1cd1f4bf2fc068929 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Sun, 23 Oct 2022 14:32:35 +0100 Subject: [PATCH 28/72] Fix new flat white icons Signed-off-by: he3als <65787561+he3als@users.noreply.github.com> --- launcher/resources/flat_white/flat_white.qrc | 6 +++++- launcher/resources/flat_white/scalable/delete.svg | 2 +- launcher/resources/flat_white/scalable/tag.svg | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index feda4762..4243760b 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -41,6 +41,10 @@ scalable/status-running.svg scalable/status-yellow.svg scalable/viewfolder.svg - scalable/worlds.svg + scalable/worlds.svg + scalable/delete.svg + scalable/export.svg + scalable/rename.svg + scalable/tag.svg
diff --git a/launcher/resources/flat_white/scalable/delete.svg b/launcher/resources/flat_white/scalable/delete.svg index 4cf7206e..3365a96f 100644 --- a/launcher/resources/flat_white/scalable/delete.svg +++ b/launcher/resources/flat_white/scalable/delete.svg @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/launcher/resources/flat_white/scalable/tag.svg b/launcher/resources/flat_white/scalable/tag.svg index 2473126f..f91fb0b4 100644 --- a/launcher/resources/flat_white/scalable/tag.svg +++ b/launcher/resources/flat_white/scalable/tag.svg @@ -1,4 +1,4 @@ - + \ No newline at end of file From 0aac85dda145603434e64bf04f39823f44509605 Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Sun, 23 Oct 2022 14:35:33 +0100 Subject: [PATCH 29/72] Replace tab with spaces in flat_white.qrc Signed-off-by: he3als <65787561+he3als@users.noreply.github.com> --- launcher/resources/flat_white/flat_white.qrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index 4243760b..9df69060 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -42,7 +42,7 @@ scalable/status-yellow.svg scalable/viewfolder.svg scalable/worlds.svg - scalable/delete.svg + scalable/delete.svg scalable/export.svg scalable/rename.svg scalable/tag.svg From d5109f024b7bde5862a60b7359d815dc3d138663 Mon Sep 17 00:00:00 2001 From: Trisave <42098407+Protrikk@users.noreply.github.com> Date: Sun, 23 Oct 2022 20:32:04 +0200 Subject: [PATCH 30/72] Better dark theme selection contrast Tweak background of the selection background in order to make text more readable Signed-off-by: Trisave <42098407+Protrikk@users.noreply.github.com> --- launcher/ui/themes/DarkTheme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp index 07a2efd2..48231b53 100644 --- a/launcher/ui/themes/DarkTheme.cpp +++ b/launcher/ui/themes/DarkTheme.cpp @@ -31,7 +31,7 @@ QPalette DarkTheme::colorScheme() darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); darkPalette.setColor(QPalette::Link, QColor(47,163,198)); - darkPalette.setColor(QPalette::Highlight, QColor(145,205,92)); + darkPalette.setColor(QPalette::Highlight, QColor(150,219,89)); darkPalette.setColor(QPalette::HighlightedText, Qt::black); darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray); return fadeInactive(darkPalette, fadeAmount(), fadeColor()); From 43bf601f120c9b1eac1c73feb31c67df54955b6d Mon Sep 17 00:00:00 2001 From: leo78913 Date: Sun, 23 Oct 2022 11:34:49 -0300 Subject: [PATCH 31/72] add icons to the instance toolbar Signed-off-by: leo78913 --- launcher/resources/OSX/OSX.qrc | 1 + launcher/resources/OSX/scalable/launch.svg | 33 +++++++++++++++++++ launcher/resources/flat/flat.qrc | 1 + launcher/resources/flat/scalable/launch.svg | 16 +++++++++ launcher/resources/iOS/iOS.qrc | 1 + launcher/resources/iOS/scalable/launch.svg | 17 ++++++++++ launcher/resources/pe_blue/pe_blue.qrc | 1 + .../resources/pe_blue/scalable/launch.svg | 20 +++++++++++ launcher/resources/pe_colored/pe_colored.qrc | 1 + .../resources/pe_colored/scalable/launch.svg | 23 +++++++++++++ launcher/resources/pe_dark/pe_dark.qrc | 1 + .../resources/pe_dark/scalable/launch.svg | 17 ++++++++++ launcher/resources/pe_light/pe_light.qrc | 1 + .../resources/pe_light/scalable/launch.svg | 17 ++++++++++ launcher/ui/MainWindow.cpp | 17 ++++++++-- 15 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 launcher/resources/OSX/scalable/launch.svg create mode 100644 launcher/resources/flat/scalable/launch.svg create mode 100644 launcher/resources/iOS/scalable/launch.svg create mode 100644 launcher/resources/pe_blue/scalable/launch.svg create mode 100644 launcher/resources/pe_colored/scalable/launch.svg create mode 100644 launcher/resources/pe_dark/scalable/launch.svg create mode 100644 launcher/resources/pe_light/scalable/launch.svg diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc index 55be28b5..19fe312b 100644 --- a/launcher/resources/OSX/OSX.qrc +++ b/launcher/resources/OSX/OSX.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/OSX/scalable/launch.svg b/launcher/resources/OSX/scalable/launch.svg new file mode 100644 index 00000000..fb189162 --- /dev/null +++ b/launcher/resources/OSX/scalable/launch.svg @@ -0,0 +1,33 @@ + + + + diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc index 7f59da7b..508e0a9f 100644 --- a/launcher/resources/flat/flat.qrc +++ b/launcher/resources/flat/flat.qrc @@ -46,5 +46,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/flat/scalable/launch.svg b/launcher/resources/flat/scalable/launch.svg new file mode 100644 index 00000000..b462f2e4 --- /dev/null +++ b/launcher/resources/flat/scalable/launch.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc index 1d752042..aa08d811 100644 --- a/launcher/resources/iOS/iOS.qrc +++ b/launcher/resources/iOS/iOS.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/iOS/scalable/launch.svg b/launcher/resources/iOS/scalable/launch.svg new file mode 100644 index 00000000..c16d5c37 --- /dev/null +++ b/launcher/resources/iOS/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc index 3d385713..3121ffe6 100644 --- a/launcher/resources/pe_blue/pe_blue.qrc +++ b/launcher/resources/pe_blue/pe_blue.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_blue/scalable/launch.svg b/launcher/resources/pe_blue/scalable/launch.svg new file mode 100644 index 00000000..b3bd124f --- /dev/null +++ b/launcher/resources/pe_blue/scalable/launch.svg @@ -0,0 +1,20 @@ + + + + diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc index fa6cd9cd..ce5ad8e2 100644 --- a/launcher/resources/pe_colored/pe_colored.qrc +++ b/launcher/resources/pe_colored/pe_colored.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_colored/scalable/launch.svg b/launcher/resources/pe_colored/scalable/launch.svg new file mode 100644 index 00000000..76713387 --- /dev/null +++ b/launcher/resources/pe_colored/scalable/launch.svg @@ -0,0 +1,23 @@ + + + + diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc index 6b9c7cb6..156d8f8b 100644 --- a/launcher/resources/pe_dark/pe_dark.qrc +++ b/launcher/resources/pe_dark/pe_dark.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_dark/scalable/launch.svg b/launcher/resources/pe_dark/scalable/launch.svg new file mode 100644 index 00000000..3746e2dd --- /dev/null +++ b/launcher/resources/pe_dark/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc index 963bfcde..d8e4a1bd 100644 --- a/launcher/resources/pe_light/pe_light.qrc +++ b/launcher/resources/pe_light/pe_light.qrc @@ -38,5 +38,6 @@ scalable/tag.svg scalable/export.svg scalable/rename.svg + scalable/launch.svg diff --git a/launcher/resources/pe_light/scalable/launch.svg b/launcher/resources/pe_light/scalable/launch.svg new file mode 100644 index 00000000..6c27b7e0 --- /dev/null +++ b/launcher/resources/pe_light/scalable/launch.svg @@ -0,0 +1,17 @@ + + + + diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 97152a48..559ebc31 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -656,6 +656,7 @@ public: actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance")); actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Launch")); actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance.")); + actionLaunchInstance->setIcon(APPLICATION->getThemedIcon("launch")); all_actions.append(&actionLaunchInstance); actionLaunchInstanceOffline = TranslatedAction(MainWindow); @@ -741,7 +742,9 @@ public: // See https://github.com/PolyMC/PolyMC/issues/493 connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); - instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly); + instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + instanceToolBar->setIconSize(QSize(16, 16)); + instanceToolBar->setFloatable(false); instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar")); @@ -761,8 +764,18 @@ public: instanceToolBar->addAction(actionViewSelectedInstFolder); instanceToolBar->addAction(actionExportInstance); - instanceToolBar->addAction(actionDeleteInstance); instanceToolBar->addAction(actionCopyInstance); + instanceToolBar->addAction(actionDeleteInstance); + + QLayout * lay = instanceToolBar->layout(); + for(int i = 0; i < lay->count(); i++) + { + QLayoutItem * item = lay->itemAt(i); + if (item->widget()->metaObject()->className() == QString("QToolButton")) + { + item->setAlignment(Qt::AlignLeft); + } + } all_toolbars.append(&instanceToolBar); MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar); From 6a474a01258d375228a0883b0b5c792049ef74ef Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 20 Oct 2022 14:00:11 +0200 Subject: [PATCH 32/72] fix: update icon generate script Signed-off-by: Sefa Eyeoglu --- launcher/resources/OSX/scalable/launcher.svg | 14 ++- launcher/resources/flat/scalable/launcher.svg | 14 ++- launcher/resources/iOS/scalable/launcher.svg | 14 ++- .../resources/multimc/scalable/launcher.svg | 14 ++- .../resources/pe_blue/scalable/launcher.svg | 14 ++- .../pe_colored/scalable/launcher.svg | 14 ++- .../resources/pe_dark/scalable/launcher.svg | 14 ++- .../resources/pe_light/scalable/launcher.svg | 14 ++- program_info/genicons.sh | 86 ++++++++++++------ program_info/prismlauncher.ico | Bin 102134 -> 372526 bytes 10 files changed, 132 insertions(+), 66 deletions(-) diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/OSX/scalable/launcher.svg +++ b/launcher/resources/OSX/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/flat/scalable/launcher.svg +++ b/launcher/resources/flat/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/iOS/scalable/launcher.svg +++ b/launcher/resources/iOS/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/multimc/scalable/launcher.svg b/launcher/resources/multimc/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/multimc/scalable/launcher.svg +++ b/launcher/resources/multimc/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/pe_blue/scalable/launcher.svg +++ b/launcher/resources/pe_blue/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/pe_colored/scalable/launcher.svg +++ b/launcher/resources/pe_colored/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/pe_dark/scalable/launcher.svg +++ b/launcher/resources/pe_dark/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg index 69dd84b1..aeee8433 100644 --- a/launcher/resources/pe_light/scalable/launcher.svg +++ b/launcher/resources/pe_light/scalable/launcher.svg @@ -37,17 +37,21 @@ https://github.com/PrismLauncher/PrismLauncher - - - CC BY-SA 4.0 - - Prism Launcher + + + + + + + + + diff --git a/program_info/genicons.sh b/program_info/genicons.sh index bfe756d8..42592c4e 100755 --- a/program_info/genicons.sh +++ b/program_info/genicons.sh @@ -1,39 +1,73 @@ -#/bin/bash +#!/bin/bash -# ICO +svg2png() { + input_file="$1" + output_file="$2" + width="$3" + height="$4" -inkscape -w 16 -h 16 -o prismlauncher_16.png org.prismlauncher.PrismLauncher.svg -inkscape -w 24 -h 24 -o prismlauncher_24.png org.prismlauncher.PrismLauncher.svg -inkscape -w 32 -h 32 -o prismlauncher_32.png org.prismlauncher.PrismLauncher.svg -inkscape -w 48 -h 48 -o prismlauncher_48.png org.prismlauncher.PrismLauncher.svg -inkscape -w 64 -h 64 -o prismlauncher_64.png org.prismlauncher.PrismLauncher.svg -inkscape -w 128 -h 128 -o prismlauncher_128.png org.prismlauncher.PrismLauncher.svg + inkscape -w "$width" -h "$height" -o "$output_file" "$input_file" +} -convert prismlauncher_128.png prismlauncher_64.png prismlauncher_48.png prismlauncher_32.png prismlauncher_24.png prismlauncher_16.png prismlauncher.ico +sipsresize() { + input_file="$1" + output_file="$2" + width="$3" + height="$4" -rm -f prismlauncher_*.png + sips -z "$width" "$height" "$input_file" --out "$output_file" +} -inkscape -w 1024 -h 1024 -o prismlauncher_1024.png org.prismlauncher.PrismLauncher.bigsur.svg +if command -v "inkscape" && command -v "icotool"; then + # Windows ICO + d=$(mktemp -d) -mkdir prismlauncher.iconset + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_16.png" 16 16 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_24.png" 24 24 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_32.png" 32 32 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_48.png" 48 48 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_64.png" 64 64 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_128.png" 128 128 + svg2png org.prismlauncher.PrismLauncher.svg "$d/prismlauncher_256.png" 256 256 -sips -z 16 16 prismlauncher_1024.png --out prismlauncher.iconset/icon_16x16.png -sips -z 32 32 prismlauncher_1024.png --out prismlauncher.iconset/icon_16x16@2x.png -sips -z 32 32 prismlauncher_1024.png --out prismlauncher.iconset/icon_32x32.png -sips -z 64 64 prismlauncher_1024.png --out prismlauncher.iconset/icon_32x32@2x.png -sips -z 128 128 prismlauncher_1024.png --out prismlauncher.iconset/icon_128x128.png -sips -z 256 256 prismlauncher_1024.png --out prismlauncher.iconset/icon_128x128@2x.png -sips -z 256 256 prismlauncher_1024.png --out prismlauncher.iconset/icon_256x256.png -sips -z 512 512 prismlauncher_1024.png --out prismlauncher.iconset/icon_256x256@2x.png -sips -z 512 512 prismlauncher_1024.png --out prismlauncher.iconset/icon_512x512.png -cp prismlauncher_1024.png prismlauncher.iconset/icon_512x512@2x.png + rm prismlauncher.ico && icotool -o prismlauncher.ico -c \ + "$d/prismlauncher_256.png" \ + "$d/prismlauncher_128.png" \ + "$d/prismlauncher_64.png" \ + "$d/prismlauncher_48.png" \ + "$d/prismlauncher_32.png" \ + "$d/prismlauncher_24.png" \ + "$d/prismlauncher_16.png" +else + echo "ERROR: Windows icons were NOT generated!" >&2 + echo "ERROR: requires inkscape and icotool in PATH" +fi -iconutil -c icns prismlauncher.iconset +if command -v "inkscape" && command -v "sips" && command -v "iconutil"; then + # macOS ICNS + d=$(mktemp -d) -rm -f prismlauncher_*.png -rm -rf prismlauncher.iconset + d="$d/prismlauncher.iconset" + mkdir -p "$d" + + svg2png org.prismlauncher.PrismLauncher.bigsur.svg "$d/icon_512x512@2x.png" 1024 1024 + sipsresize "$d/icon_512x512@2.png" "$d/icon_16x16.png" 16 16 + sipsresize "$d/icon_512x512@2.png" "$d/icon_16x16@2.png" 32 32 + sipsresize "$d/icon_512x512@2.png" "$d/icon_32x32.png" 32 32 + sipsresize "$d/icon_512x512@2.png" "$d/icon_32x32@2.png" 64 64 + sipsresize "$d/icon_512x512@2.png" "$d/icon_128x128.png" 128 128 + sipsresize "$d/icon_512x512@2.png" "$d/icon_128x128@2.png" 256 256 + sipsresize "$d/icon_512x512@2.png" "$d/icon_256x256.png" 256 256 + sipsresize "$d/icon_512x512@2.png" "$d/icon_256x256@2.png" 512 512 + iconutil -c icns "$d" +else + echo "ERROR: macOS icons were NOT generated!" >&2 + echo "ERROR: requires inkscape, sips and iconutil in PATH" +fi + +# replace icon in themes for dir in ../launcher/resources/*/scalable do - cp -v org.prismlauncher.PrismLauncher.svg $dir/launcher.svg + cp -v org.prismlauncher.PrismLauncher.svg "$dir/launcher.svg" done diff --git a/program_info/prismlauncher.ico b/program_info/prismlauncher.ico index e4529f93807cd8f40c25820338e2821dc35105cf..2f0fa67ff6be7681f76aa8ccbdfedabcef766b72 100644 GIT binary patch literal 372526 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

ol&v!0pbHjkGtsBcQlsT;+OpWK_) z{js~=4ZB`tY*(=Te=_Qy#HBZc*ovEZhU@D54##lUGP2>G+3}O>q-j-TEi}SMZhRWp zwa-i%9FX(i#kA`iv2%if8)ya zhiBIQ1IC{ieRvg)O;!}*nlcH7n42P$@2*f|`3+`jFSv!r6u>dC$vFPi7RR`L;Z^DN zidVkZOM(s(mV86LC2^3rjB#Szq#j0whhD?OTn}?nqFuZ9e;vm_{)kaH^?UQ};Qzz< z!dtPdY{GJ#99!q~N_OZIhI?rJ8pjA$;&;Ze7*f`n>ji$v^*N*aF5hnm`n4@$+WQ8F zWBB{z8}`9`zxu-nrd+{0Hsd4YjC4bb7BJWGq<;I~Q++j6S1aM@lgB zJ#3%W_tB~^k_Iqw5MRhHxLz=`S7KEBSo7R6Qtn+odj^gyOMzX6-mrdoOmn%Kqo2Wi zkG{BznKCXk$#NeZcDcE3Cwt$U)CJ7<=!?9P`TnESg%)Ka`}+;(56kq~&fhj=gT3!< zm3wnaADH{#u&i6oe9xwTNXmSuu(7|z-G`51`sF9)@6lG9=_m3d<(A*H8SvqO#gJaQ z10J({D<4-i!on@s2ekytlV;!BCiKxZ%kTa1Q$hysU1+fuA@Obe{OTdt^7#Xp5Puco z(q6RK^wo7uaR+M#G4zu&+VDZP{CpU@G-|BbkMKckMngFJTjn~laMk}qd$S4;^Ll{H z_h{1^<7YknEM_j)%)d+=*)P!|Key3Ez&q_ hz~1A>IL2Q2ikDaZOI}`vHntD)j)Wm$$v5QN{|~PZ9Vq|+ literal 102134 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 H688T9&?`5g From 74b98af8e5573da4ca5a311fd13cb3f455bc1b9c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Mon, 24 Oct 2022 11:23:02 +0200 Subject: [PATCH 33/72] fix: use display name in NSIS Signed-off-by: Sefa Eyeoglu --- program_info/win_install.nsi.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 1c1f29da..0cd7ea11 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -4,7 +4,7 @@ Unicode true -Name "@Launcher_CommonName@" +Name "@Launcher_DisplayName@" InstallDir "$LOCALAPPDATA\Programs\@Launcher_CommonName@" InstallDirRegKey HKCU "Software\@Launcher_CommonName@" "InstallDir" RequestExecutionLevel user @@ -113,7 +113,7 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@ ;-------------------------------- ; The stuff to install -Section "@Launcher_CommonName@" +Section "@Launcher_DisplayName@" SectionIn RO From b638a6ae950e472c6e6139cfdbaa2950e848efb0 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 24 Oct 2022 09:07:41 -0300 Subject: [PATCH 34/72] fix: retry mod search job after aborting it This way, we don't get stuck with an aborted job in our way! :o Signed-off-by: flow --- .../modplatform/helpers/NetworkModAPI.cpp | 1 + launcher/ui/pages/modplatform/ModModel.cpp | 25 ++++++++++++------- launcher/ui/pages/modplatform/ModModel.h | 1 + 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp index 866e7540..7633030e 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.cpp +++ b/launcher/modplatform/helpers/NetworkModAPI.cpp @@ -15,6 +15,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); }); QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); + QObject::connect(netJob, &NetJob::aborted, caller, &CallerType::searchRequestAborted); QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 49766fa6..ed58eb32 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -267,18 +267,25 @@ void ListModel::searchRequestFailed(QString reason) .arg(m_parent->displayName()) .arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME))); } + + jobPtr.reset(); + searchState = Finished; +} + +void ListModel::searchRequestAborted() +{ + if (searchState != ResetRequested) + qCritical() << "Search task in ModModel aborted by an unknown reason!"; + + // Retry fetching jobPtr.reset(); - if (searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); + beginResetModel(); + modpacks.clear(); + endResetModel(); - nextSearchOffset = 0; - performPaginatedSearch(); - } else { - searchState = Finished; - } + nextSearchOffset = 0; + performPaginatedSearch(); } void ListModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index) diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index a58c7c55..d2636d87 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -51,6 +51,7 @@ class ListModel : public QAbstractListModel { public slots: void searchRequestFinished(QJsonDocument& doc); void searchRequestFailed(QString reason); + void searchRequestAborted(); void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index); From d9463620e601aa62342cafc3fb2fbeae5f56511c Mon Sep 17 00:00:00 2001 From: tobimori Date: Tue, 25 Oct 2022 09:34:07 +0200 Subject: [PATCH 35/72] move .app rename to packaging process, update mac copyright string Signed-off-by: tobimori --- .github/workflows/build.yml | 5 +++-- CMakeLists.txt | 16 ++++++++-------- program_info/CMakeLists.txt | 1 + 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f67ba4c7..ac701c1e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -249,8 +249,9 @@ jobs: cmake --install ${{ env.BUILD_DIR }} cd ${{ env.INSTALL_DIR }} - chmod +x "Prism Launcher.app/Contents/MacOS/prismlauncher" - sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "Prism Launcher.app/Contents/MacOS/prismlauncher" + chmod +x "PrismLauncher.app/Contents/MacOS/prismlauncher" + sudo codesign --sign - --deep --force --entitlements "../program_info/App.entitlements" --options runtime "PrismLauncher.app/Contents/MacOS/prismlauncher" + mv "PrismLauncher.app" "Prism Launcher.app" tar -czf ../PrismLauncher.tar.gz * - name: Make Sparkle signature (macOS) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09f62bb3..611ca1de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,15 +211,15 @@ if(NOT (UNIX AND APPLE)) endif() if(UNIX AND APPLE) - set(BINARY_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") - set(LIBRARY_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") - set(PLUGIN_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS") - set(FRAMEWORK_DEST_DIR "${Launcher_DisplayName}.app/Contents/Frameworks") - set(RESOURCES_DEST_DIR "${Launcher_DisplayName}.app/Contents/Resources") - set(JARS_DEST_DIR "${Launcher_DisplayName}.app/Contents/MacOS/jars") + set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(LIBRARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(PLUGIN_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") + set(FRAMEWORK_DEST_DIR "${Launcher_Name}.app/Contents/Frameworks") + set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources") + set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars") # Apps to bundle - set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_DisplayName}.app") + set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") # Mac bundle settings set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_DisplayName}") @@ -229,7 +229,7 @@ if(UNIX AND APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) - set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}") + set(MACOSX_BUNDLE_COPYRIGHT "© 2021-2022 ${Launcher_Copyright_Mac}") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index f6e2ea84..61949e13 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -15,6 +15,7 @@ set(Launcher_Name "${Launcher_CommonName}" PARENT_SCOPE) set(Launcher_DisplayName "${Launcher_DisplayName}" PARENT_SCOPE) set(Launcher_Copyright "Prism Launcher Contributors\\n© 2021-2022 PolyMC Contributors \\n© 2012-2021 MultiMC Contributors") +set(Launcher_Copyright_Mac "Prism Launcher Contributors, © 2021-2022 PolyMC Contributors and © 2012-2021 MultiMC Contributors" PARENT_SCOPE) set(Launcher_Copyright "${Launcher_Copyright}" PARENT_SCOPE) set(Launcher_Domain "prismlauncher.org" PARENT_SCOPE) set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_SCOPE) From 482d3a1d76e1c66e351b400c40d772be624cd9b9 Mon Sep 17 00:00:00 2001 From: tobimori Date: Tue, 25 Oct 2022 15:24:41 +0200 Subject: [PATCH 36/72] update macos copyright year Signed-off-by: tobimori --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 611ca1de..d2111fe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,7 +229,7 @@ if(UNIX AND APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) - set(MACOSX_BUNDLE_COPYRIGHT "© 2021-2022 ${Launcher_Copyright_Mac}") + set(MACOSX_BUNDLE_COPYRIGHT "© 2022 ${Launcher_Copyright_Mac}") set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "v55ZWWD6QlPoXGV6VLzOTZxZUggWeE51X8cRQyQh6vA=") set(MACOSX_SPARKLE_UPDATE_FEED_URL "https://prismlauncher.org/feed/appcast.xml") From 610b9711178d164a41f76106968c3fb511570fd8 Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Wed, 26 Oct 2022 02:09:45 +0200 Subject: [PATCH 37/72] Improve a bit README.md (#305) Add Open Collective and fix some stuff. --- README.md | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index d7df8e26..dc6cdbc7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ -

+

Prism Launcher logo Prism Launcher logo

+ Prism Launcher is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once. This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. + ## Installation - All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/). @@ -16,25 +18,24 @@ This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. -Portable builds are provided for on Linux, Windows, and macOS. +Portable builds are provided for Linux, Windows, and macOS. + +For Arch, Debian and Gentoo, respectively, you can use these packages to get compiled development versions: + +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=appveyor)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=appveyor)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=appveyor)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=appveyor)](https://packages.gentoo.org/packages/games-action/prismlauncher) -For Debian and Arch, you can use these packages for the latest development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue)](https://aur.archlinux.org/packages/prismlauncher-git/) -[![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange)](https://mpr.makedeb.org/packages/prismlauncher-git) ## Help & Support -Feel free to create an issue if you need help. However, you might find it easier to ask in the Discord server. +Feel free to create an issue if you need help. +#### Join our Discord server: [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher) -We will also soon be opening up our Matrix channels. -You can already join our Matrix space: +#### Join our Matrix space: +[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&logo=appveyor)](https://matrix.to/#/#prismlauncher:matrix.org) -[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?label=PrismLauncher%20space)](https://matrix.to/#/#prismlauncher:matrix.org) - -We also have a subreddit you can post your issues and suggestions on: - -[r/PrismLauncher](https://www.reddit.com/r/PrismLauncher/) +#### Join our SubReddit: +[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge&logo=appveyor)](https://www.reddit.com/r/PrismLauncher/) ## Building @@ -60,13 +61,11 @@ Be aware that if you build this software without removing the provided API keys If you do not agree with these terms and conditions, then remove the associated API keys from the [CMakeLists.txt](CMakeLists.txt) file by setting them to an empty string (`""`). -## License +## Sponsors & Partners -All launcher code is available under the GPL-3.0-only license. - -The logo and related assets are under the CC BY-SA 4.0 license. +We thank all the wonderful backers over at Open Collective! Support Prism Launcher by [becoming a backer](https://opencollective.com/prismlauncher). -## Sponsors +[![OpenCollective Backers](https://opencollective.com/prismlauncher/backers.svg?width=890&limit=1000)](https://opencollective.com/prismlauncher#backers) Thanks to JetBrains for providing us a few licenses for all their products, as part of their [Open Source program](https://www.jetbrains.com/opensource/). @@ -85,3 +84,12 @@ Thanks to Netlify for providing us their excellent web services, as part of thei Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), for providing M1-Macs for development purposes! Powered by MacStadium + + +## License + +All launcher code is available under the GPL-3.0-only license. + +![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?style=for-the-badge) + +The logo and related assets are under the CC BY-SA 4.0 license. From 990cfb7b3378aa5c4f0482c1f6ef4bfa8b073e81 Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Thu, 27 Oct 2022 18:08:56 +0200 Subject: [PATCH 38/72] Remove appveyor I forgor :skull: But seriously I forgor to remove the &logo=appveyor thing AAAAAH!!! Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dc6cdbc7..db0e2c62 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Portable builds are provided for Linux, Windows, and macOS. For Arch, Debian and Gentoo, respectively, you can use these packages to get compiled development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=appveyor)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=appveyor)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=appveyor)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=appveyor)](https://packages.gentoo.org/packages/games-action/prismlauncher) +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher) ## Help & Support @@ -32,10 +32,10 @@ Feel free to create an issue if you need help. [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher) #### Join our Matrix space: -[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&logo=appveyor)](https://matrix.to/#/#prismlauncher:matrix.org) +[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge)](https://matrix.to/#/#prismlauncher:matrix.org) #### Join our SubReddit: -[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge&logo=appveyor)](https://www.reddit.com/r/PrismLauncher/) +[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge)](https://www.reddit.com/r/PrismLauncher/) ## Building From b18466da8430ba782e59f50812f3724defa1f2a9 Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Thu, 27 Oct 2022 12:29:41 +0100 Subject: [PATCH 39/72] Fix: Don't specify x86 in manifest Signed-off-by: TheLastRar --- program_info/prismlauncher.manifest.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program_info/prismlauncher.manifest.in b/program_info/prismlauncher.manifest.in index 1d764445..6f4467c7 100644 --- a/program_info/prismlauncher.manifest.in +++ b/program_info/prismlauncher.manifest.in @@ -10,7 +10,7 @@ - + Custom Minecraft launcher for managing multiple installs. From d35c985d2ebca44903bedba87c99efb8db0f158d Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Sun, 23 Oct 2022 12:57:29 +0200 Subject: [PATCH 40/72] feat(actions): use clang32 for building on windows *way* faster Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6400791..a7dd31d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,12 +30,12 @@ jobs: - os: windows-2022 name: "Windows-Legacy" - msystem: mingw32 + msystem: clang32 qt_ver: 5 - os: windows-2022 name: "Windows" - msystem: mingw32 + msystem: clang32 qt_ver: 6 - os: macos-12 @@ -89,6 +89,7 @@ jobs: update: true install: >- git + mingw-w64-x86_64-binutils pacboy: >- toolchain:p cmake:p @@ -99,7 +100,6 @@ jobs: qt${{ matrix.qt_ver }}-imageformats:p quazip-qt${{ matrix.qt_ver }}:p ccache:p - nsis:p ${{ matrix.qt_ver == 6 && 'qt6-5compat:p' || '' }} - name: Setup ccache @@ -194,7 +194,7 @@ jobs: if: runner.os == 'Windows' shell: msys2 {0} run: | - cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -G Ninja + cmake -S . -B ${{ env.BUILD_DIR }} -DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }} -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DENABLE_LTO=ON -DLauncher_BUILD_PLATFORM=${{ matrix.name }} -DCMAKE_C_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ env.CCACHE_VAR }} -DLauncher_QT_VERSION_MAJOR=${{ matrix.qt_ver }} -DCMAKE_OBJDUMP=/mingw64/bin/objdump.exe -G Ninja - name: Configure CMake (Linux) if: runner.os == 'Linux' @@ -280,7 +280,7 @@ jobs: cd ${{ env.INSTALL_DIR }} if [ "${{ matrix.qt_ver }}" == "5" ]; then - cp /mingw32/bin/libcrypto-1_1.dll /mingw32/bin/libssl-1_1.dll ./ + cp /clang32/bin/libcrypto-1_1.dll /clang32/bin/libssl-1_1.dll ./ fi - name: Package (Windows, portable) @@ -292,7 +292,6 @@ jobs: - name: Package (Windows, installer) if: runner.os == 'Windows' - shell: msys2 {0} run: | cd ${{ env.INSTALL_DIR }} makensis -NOCD "${{ github.workspace }}/${{ env.BUILD_DIR }}/program_info/win_install.nsi" From 2ba3de79d8df31d196f0cd249b1606e7233cf840 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 27 Oct 2022 21:14:30 +0200 Subject: [PATCH 41/72] chore: add comment about copy bug Signed-off-by: Sefa Eyeoglu --- launcher/FileSystem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 39e68c20..76cfccb0 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -401,6 +401,7 @@ bool overrideFolder(QString overwritten_path, QString override_path) std::error_code err; fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing; + // FIXME: hello traveller! Apparently std::copy does NOT overwrite existing files on GNU libstdc++ on Windows? fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err); if (err) { From 93894f62ffcb8c33caf36e8801e163738cc2873d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 28 Oct 2022 00:05:11 +0200 Subject: [PATCH 42/72] fix: avoid segfault for unexpected API reponse Signed-off-by: Sefa Eyeoglu --- .../modrinth/ModrinthPackIndex.cpp | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 3e53becb..ae45e096 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-only /* -* PolyMC - Minecraft Launcher -* Copyright (c) 2022 flowln -* -* 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, version 3. -* -* 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 . -*/ + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 flowln + * + * 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, version 3. + * + * 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 . + */ #include "ModrinthPackIndex.h" #include "ModrinthAPI.h" @@ -35,7 +35,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) pack.provider = ModPlatform::Provider::MODRINTH; pack.name = Json::requireString(obj, "title"); - + pack.slug = Json::ensureString(obj, "slug", ""); if (!pack.slug.isEmpty()) pack.websiteUrl = "https://modrinth.com/mod/" + pack.slug; @@ -59,23 +59,23 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj) { pack.extraData.issuesUrl = Json::ensureString(obj, "issues_url"); - if(pack.extraData.issuesUrl.endsWith('/')) + if (pack.extraData.issuesUrl.endsWith('/')) pack.extraData.issuesUrl.chop(1); pack.extraData.sourceUrl = Json::ensureString(obj, "source_url"); - if(pack.extraData.sourceUrl.endsWith('/')) + if (pack.extraData.sourceUrl.endsWith('/')) pack.extraData.sourceUrl.chop(1); pack.extraData.wikiUrl = Json::ensureString(obj, "wiki_url"); - if(pack.extraData.wikiUrl.endsWith('/')) + if (pack.extraData.wikiUrl.endsWith('/')) pack.extraData.wikiUrl.chop(1); pack.extraData.discordUrl = Json::ensureString(obj, "discord_url"); - if(pack.extraData.discordUrl.endsWith('/')) + if (pack.extraData.discordUrl.endsWith('/')) pack.extraData.discordUrl.chop(1); auto donate_arr = Json::ensureArray(obj, "donation_urls"); - for(auto d : donate_arr){ + for (auto d : donate_arr) { auto d_obj = Json::requireObject(d); ModPlatform::DonationData donate; @@ -104,7 +104,7 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj); - if(file.fileId.isValid()) // Heuristic to check if the returned value is valid + if (file.fileId.isValid()) // Heuristic to check if the returned value is valid unsortedVersions.append(file); } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { @@ -116,7 +116,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, pack.versionsLoaded = true; } -auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_type, QString preferred_file_name) -> ModPlatform::IndexedVersion +auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name) + -> ModPlatform::IndexedVersion { ModPlatform::IndexedVersion file; @@ -141,6 +142,12 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t auto files = Json::requireArray(obj, "files"); int i = 0; + if (files.empty()) { + // This should not happen normally, but check just in case + qWarning() << "Modrinth returned an unexpected empty list of files:" << obj; + return {}; + } + // Find correct file (needed in cases where one version may have multiple files) // Will default to the last one if there's no primary (though I think Modrinth requires that // at least one file is primary, idk) @@ -167,7 +174,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t file.fileName = Json::requireString(parent, "filename"); file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1); auto hash_list = Json::requireObject(parent, "hashes"); - + if (hash_list.contains(preferred_hash_type)) { file.hash = Json::requireString(hash_list, preferred_hash_type); file.hash_type = preferred_hash_type; From a5be974f1a53a8e56527d639beb4c16f3a7e18c6 Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Thu, 27 Oct 2022 21:05:32 +0200 Subject: [PATCH 43/72] feat: use clang64 on qt6 builds Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca82d3d8..dd2c0599 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: - os: windows-2022 name: "Windows" - msystem: clang32 + msystem: clang64 qt_ver: 6 - os: macos-12 From e6e92f2b0e9ef16bdbae371ccb284339a70cff02 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 28 Oct 2022 13:31:21 -0300 Subject: [PATCH 44/72] fix: only allow workarounds for blocked mods from MR when 100% safe If a version on Modrinth has more than a single mod loader associated, it means that it's possible we might get the wrong file for download, since individual files don't really have this kind of metadata in the API response. So, in such cases, it's best to let the user take care of it instead. Signed-off-by: flow --- .../modplatform/flame/FileResolvingTask.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index c50abb8f..25b56fbd 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -3,6 +3,8 @@ #include "Json.h" #include "net/Upload.h" +#include "modplatform/modrinth/ModrinthPackIndex.h" + Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr& network, Flame::Manifest& toProcess) : m_network(network), m_toProcess(toProcess) {} @@ -84,18 +86,21 @@ void Flame::FileResolvingTask::modrinthCheckFinished() { delete bytes; continue; } + QJsonDocument doc = QJsonDocument::fromJson(*bytes); auto obj = doc.object(); - auto array = Json::requireArray(obj,"files"); - for (auto file: array) { - auto fileObj = Json::requireObject(file); - auto primary = Json::requireBoolean(fileObj,"primary"); - if (primary) { - out->url = Json::requireUrl(fileObj,"url"); - qDebug() << "Found alternative on modrinth " << out->fileName; - break; - } + auto file = Modrinth::loadIndexedPackVersion(obj); + + // If there's more than one mod loader for this version, we can't know for sure + // which file is relative to each loader, so it's best to not use any one and + // let the user download it manually. + if (file.loaders.size() <= 1) { + out->url = file.downloadUrl; + qDebug() << "Found alternative on modrinth " << out->fileName; + } else { + out->resolved = false; } + delete bytes; } //copy to an output list and filter out projects found on modrinth From 76146e0f17dc56a68128edb13a73f4852af86e84 Mon Sep 17 00:00:00 2001 From: leo78913 Date: Fri, 28 Oct 2022 15:51:20 -0300 Subject: [PATCH 45/72] add a flat white version of the launch icon Signed-off-by: leo78913 --- launcher/resources/flat_white/flat_white.qrc | 1 + .../resources/flat_white/scalable/launch.svg | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 launcher/resources/flat_white/scalable/launch.svg diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc index 9df69060..e11d6316 100644 --- a/launcher/resources/flat_white/flat_white.qrc +++ b/launcher/resources/flat_white/flat_white.qrc @@ -46,5 +46,6 @@ scalable/export.svg scalable/rename.svg scalable/tag.svg + scalable/launch.svg diff --git a/launcher/resources/flat_white/scalable/launch.svg b/launcher/resources/flat_white/scalable/launch.svg new file mode 100644 index 00000000..9e759431 --- /dev/null +++ b/launcher/resources/flat_white/scalable/launch.svg @@ -0,0 +1,16 @@ + + + + + From be3c9abcfeb68ad76914848e7135b2595490beda Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 28 Oct 2022 20:11:46 -0300 Subject: [PATCH 46/72] fix: copy single files too in FS::copy eek Signed-off-by: flow --- launcher/FileSystem.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 76cfccb0..9bca847e 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -182,6 +182,21 @@ bool copy::operator()(const QString& offset) if (!m_followSymlinks) opt |= copy_opts::copy_symlinks; + // Function that'll do the actual copying + auto copy_file = [&](QString src_path, QString relative_dst_path) { + if (m_blacklist && m_blacklist->matches(relative_dst_path)) + return; + + auto dst_path = PathCombine(dst, relative_dst_path); + ensureFilePathExists(dst_path); + + fs::copy(toStdString(src_path), toStdString(dst_path), opt, err); + if (err) { + qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); + qDebug() << "Source file:" << src_path; + qDebug() << "Destination file:" << dst_path; + } + }; // We can't use copy_opts::recursive because we need to take into account the // blacklisted paths, so we iterate over the source directory, and if there's no blacklist @@ -193,20 +208,13 @@ bool copy::operator()(const QString& offset) auto src_path = source_it.next(); auto relative_path = src_dir.relativeFilePath(src_path); - if (m_blacklist && m_blacklist->matches(relative_path)) - continue; - - auto dst_path = PathCombine(dst, relative_path); - ensureFilePathExists(dst_path); - - fs::copy(toStdString(src_path), toStdString(dst_path), opt, err); - if (err) { - qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); - qDebug() << "Source file:" << src_path; - qDebug() << "Destination file:" << dst_path; - } + copy_file(src_path, relative_path); } + // If the root src is not a directory, the previous iterator won't run. + if (!fs::is_directory(toStdString(src))) + copy_file(src, ""); + return err.value() == 0; } From 81333515e0ecfa0ad0880032808a220a3f463e30 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 28 Oct 2022 20:55:25 -0300 Subject: [PATCH 47/72] feat(tests): add test for FS::copy with files Signed-off-by: flow --- tests/FileSystem_test.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp index 47a963b0..21270f6f 100644 --- a/tests/FileSystem_test.cpp +++ b/tests/FileSystem_test.cpp @@ -183,6 +183,32 @@ slots: f(); } + void test_copy_single_file() + { + QTemporaryDir tempDir; + tempDir.setAutoRemove(true); + + { + QString file = QFINDTESTDATA("testdata/FileSystem/test_folder/pack.mcmeta"); + + qDebug() << "From:" << file << "To:" << tempDir.path(); + + QDir target_dir(FS::PathCombine(tempDir.path(), "pack.mcmeta")); + qDebug() << tempDir.path(); + qDebug() << target_dir.path(); + FS::copy c(file, target_dir.filePath("pack.mcmeta")); + c(); + + auto filter = QDir::Filter::Files; + + for (auto entry: target_dir.entryList(filter)) { + qDebug() << entry; + } + + QVERIFY(target_dir.entryList(filter).contains("pack.mcmeta")); + } + } + void test_getDesktop() { QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); From 5ed7eb9d537558da603683d517f5537f0e4537a1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 29 Oct 2022 13:12:51 +0200 Subject: [PATCH 48/72] chore: update credits Signed-off-by: Sefa Eyeoglu --- launcher/ui/dialogs/AboutDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index cecda1df..52d6baef 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -97,7 +97,7 @@ QString getCreditsHtml() stream << "
\n"; stream << "

" << QObject::tr("With thanks to", "About Credits") << "

\n"; - stream << QString("

Boba %1

\n") .arg(getWebsite("https://cmdplusv.neocities.org/")); + stream << QString("

Boba %1

\n") .arg(getWebsite("https://bobaonline.neocities.org/")); stream << QString("

Davi Rafael %1

\n") .arg(getWebsite("https://auti.one/")); stream << QString("

Fulmine %1

\n") .arg(getWebsite("https://www.fulmine.xyz/")); stream << QString("

ely %1

\n") .arg(getGitHub("elyrodso")); From 7f991ed897d0f344166511daddde4aa4994a67b0 Mon Sep 17 00:00:00 2001 From: txtsd Date: Sat, 29 Oct 2022 19:24:12 +0530 Subject: [PATCH 49/72] feat: Add Repology badge to README Signed-off-by: txtsd --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index db0e2c62..57f1e30a 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,10 @@ This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. ## Installation + + Packaging status + + - All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/). - Last build status can be found [here](https://github.com/PrismLauncher/PrismLauncher/actions). From b142a6da5b2ae433ce8164c7be0a3c3870131414 Mon Sep 17 00:00:00 2001 From: fn2006 Date: Sat, 29 Oct 2022 16:10:18 +0100 Subject: [PATCH 50/72] fix hardcoded svg Signed-off-by: fn2006 --- buildconfig/BuildConfig.cpp.in | 1 + buildconfig/BuildConfig.h | 1 + launcher/Application.cpp | 2 +- program_info/CMakeLists.txt | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index b8fa5133..1262ce8e 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -49,6 +49,7 @@ Config::Config() LAUNCHER_CONFIGFILE = "@Launcher_ConfigFile@"; LAUNCHER_GIT = "@Launcher_Git@"; LAUNCHER_DESKTOPFILENAME = "@Launcher_DesktopFileName@"; + LAUNCHER_SVGFILENAME = "@Launcher_SVGFileName@"; USER_AGENT = "@Launcher_UserAgent@"; USER_AGENT_UNCACHED = USER_AGENT + " (Uncached)"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 13ccdaa1..4a309073 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -51,6 +51,7 @@ class Config { QString LAUNCHER_CONFIGFILE; QString LAUNCHER_GIT; QString LAUNCHER_DESKTOPFILENAME; + QString LAUNCHER_SVGFILENAME; /// The major version number. int VERSION_MAJOR; diff --git a/launcher/Application.cpp b/launcher/Application.cpp index f6b41850..c6814abf 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1177,7 +1177,7 @@ void Application::setIconTheme(const QString& name) QIcon Application::getThemedIcon(const QString& name) { if(name == "logo") { - return QIcon(":/org.prismlauncher.PrismLauncher.svg"); // FIXME: Make this a BuildConfig variable + return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME); } return QIcon::fromTheme(name); } diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index 61949e13..b0507816 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -22,6 +22,7 @@ set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_ set(Launcher_ConfigFile "prismlauncher.cfg" PARENT_SCOPE) set(Launcher_Git "https://github.com/PrismLauncher/PrismLauncher" PARENT_SCOPE) set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) +set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) set(Launcher_Desktop "program_info/org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) set(Launcher_MetaInfo "program_info/org.prismlauncher.PrismLauncher.metainfo.xml" PARENT_SCOPE) From 98891a036dcd96dc7d9bf6b8f11c2a5f2ddd054e Mon Sep 17 00:00:00 2001 From: fn2006 Date: Sat, 29 Oct 2022 17:35:37 +0100 Subject: [PATCH 51/72] use existing variables Signed-off-by: fn2006 --- program_info/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index b0507816..f064e098 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -21,12 +21,12 @@ set(Launcher_Domain "prismlauncher.org" PARENT_SCOPE) set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_SCOPE) set(Launcher_ConfigFile "prismlauncher.cfg" PARENT_SCOPE) set(Launcher_Git "https://github.com/PrismLauncher/PrismLauncher" PARENT_SCOPE) -set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) -set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) +set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop") +set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg") -set(Launcher_Desktop "program_info/org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) +set(Launcher_Desktop "program_info/${Launcher_DesktopFileName}" PARENT_SCOPE) set(Launcher_MetaInfo "program_info/org.prismlauncher.PrismLauncher.metainfo.xml" PARENT_SCOPE) -set(Launcher_SVG "program_info/org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) +set(Launcher_SVG "program_info/${Launcher_SVGFileName}" PARENT_SCOPE) set(Launcher_Branding_ICNS "program_info/prismlauncher.icns" PARENT_SCOPE) set(Launcher_Branding_ICO "program_info/prismlauncher.ico") set(Launcher_Branding_ICO "${Launcher_Branding_ICO}" PARENT_SCOPE) From 19a8d51bf3567950db77d6bc05b16373fd1a0a1d Mon Sep 17 00:00:00 2001 From: Ryan Cao <70191398+ryanccn@users.noreply.github.com> Date: Sun, 30 Oct 2022 11:52:16 +0800 Subject: [PATCH 52/72] fix: more user friendly Java warning text Signed-off-by: Ryan Cao <70191398+ryanccn@users.noreply.github.com> --- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 99809f82..43f118f4 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -71,5 +71,7 @@ void VerifyJavaInstall::executeTask() { { emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } + emit logLine(tr("If you are sure your version will work, go to instance settings and check \"Skip Java compatibility checks\"."), MessageLevel::Error); + emitFailed(QString("Incompatible Java major version")); } From b4be28b9bb29609212b398a5f46ee4dbc400cf2d Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 30 Oct 2022 18:37:03 +0100 Subject: [PATCH 53/72] fix: fix disabled trash undo action Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 559ebc31..55f3e4f8 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1134,11 +1134,6 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos) connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(deleteGroup())); actions.append(actionDeleteGroup); } - - QAction *actionUndoTrashInstance = new QAction("Undo last trash instance", this); - connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), SLOT(undoTrashInstance())); - actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); - actions.append(actionUndoTrashInstance); } QMenu myMenu; myMenu.addActions(actions); @@ -1834,6 +1829,7 @@ void MainWindow::deleteGroup() void MainWindow::undoTrashInstance() { APPLICATION->instances()->undoTrashInstance(); + ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); } void MainWindow::on_actionViewInstanceFolder_triggered() @@ -1940,6 +1936,7 @@ void MainWindow::on_actionDeleteInstance_triggered() auto id = m_selectedInstance->id(); if (APPLICATION->instances()->trashInstance(id)) { + ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); return; } From fd099166c6a69bf77491cef8aa42cbdf06c78e35 Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sun, 30 Oct 2022 20:27:37 +0000 Subject: [PATCH 54/72] Fix: Check if Windows 10 before calling setDarkWinTitlebar() Signed-off-by: TheLastRar --- launcher/Application.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c6814abf..38613280 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -62,6 +62,7 @@ #ifdef Q_OS_WIN #include "ui/WinDarkmode.h" +#include #endif #include "ui/setupwizard/SetupWizard.h" @@ -1154,7 +1155,7 @@ void Application::setApplicationTheme(const QString& name, bool initial) auto & theme = (*themeIter).second; theme->apply(initial); #ifdef Q_OS_WIN - if (m_mainWindow) { + if (m_mainWindow && IsWindows10OrGreater()) { if (QString::compare(theme->id(), "dark") == 0) { WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); } else { @@ -1395,10 +1396,13 @@ MainWindow* Application::showMainWindow(bool minimized) m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); #ifdef Q_OS_WIN - if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); - } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + if (IsWindows10OrGreater()) + { + if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + } else { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + } } #endif if(minimized) From b7d5fee9956a2fe7801f009eb7905eeae4f09c34 Mon Sep 17 00:00:00 2001 From: Fayne Aldan Date: Sun, 30 Oct 2022 15:55:15 -0600 Subject: [PATCH 55/72] Change Profiles to Accounts for consistency Signed-off-by: Fayne Aldan --- launcher/ui/MainWindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 559ebc31..84a78941 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -527,7 +527,7 @@ public: menuBar->addMenu(foldersMenu); - profileMenu = menuBar->addMenu(tr("&Profiles")); + profileMenu = menuBar->addMenu(tr("&Accounts")); profileMenu->setSeparatorsCollapsible(false); profileMenu->addAction(actionManageAccounts); @@ -1052,7 +1052,7 @@ void MainWindow::retranslateUi() accountMenuButton->setText(profileLabel); } else { - accountMenuButton->setText(tr("Profiles")); + accountMenuButton->setText(tr("Accounts")); } if (m_selectedInstance) { @@ -1395,7 +1395,7 @@ void MainWindow::defaultAccountChanged() // Set the icon to the "no account" icon. accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount")); - accountMenuButton->setText(tr("Profiles")); + accountMenuButton->setText(tr("Accounts")); } bool MainWindow::eventFilter(QObject *obj, QEvent *ev) From 42350e689d9dba0c9385f15e7d4c4da0a71f200c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 30 Oct 2022 23:50:56 +0100 Subject: [PATCH 56/72] chore: improve display names of certain languages Signed-off-by: Sefa Eyeoglu --- launcher/translations/TranslationsModel.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index 2f57de3a..20aa6d04 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -83,6 +83,12 @@ struct Language else if(key == "es_UY") { result = u8"español de Latinoamérica"; } + else if(key == "en@pirate") { + result = u8"Tongue of the High Seas"; + } + else if(key == "en@uwu") { + result = u8"Cute Engwish"; + } else { result = locale.nativeLanguageName(); } From 27dfe30fe61055de5591d60c43351c7b2ca22668 Mon Sep 17 00:00:00 2001 From: Ryan Cao <70191398+ryanccn@users.noreply.github.com> Date: Mon, 31 Oct 2022 14:44:11 +0800 Subject: [PATCH 57/72] Update VerifyJavaInstall.cpp Signed-off-by: Ryan Cao <70191398+ryanccn@users.noreply.github.com> --- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 43f118f4..89ece6e5 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -71,7 +71,7 @@ void VerifyJavaInstall::executeTask() { { emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } - emit logLine(tr("If you are sure your version will work, go to instance settings and check \"Skip Java compatibility checks\"."), MessageLevel::Error); + emit logLine(tr(""Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error); emitFailed(QString("Incompatible Java major version")); } From 8467daa0ec71544b86fadae5bbaca9818f21254e Mon Sep 17 00:00:00 2001 From: Ryan Cao <70191398+ryanccn@users.noreply.github.com> Date: Mon, 31 Oct 2022 14:58:38 +0800 Subject: [PATCH 58/72] oop Signed-off-by: Ryan Cao <70191398+ryanccn@users.noreply.github.com> --- launcher/minecraft/launch/VerifyJavaInstall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp index 89ece6e5..6ae666b4 100644 --- a/launcher/minecraft/launch/VerifyJavaInstall.cpp +++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp @@ -71,7 +71,7 @@ void VerifyJavaInstall::executeTask() { { emit logLine(tr("Java version %1").arg(major), MessageLevel::Error); } - emit logLine(tr(""Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error); + emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error); emitFailed(QString("Incompatible Java major version")); } From 29d362a6e08f28ac48e737510a17ae7b3b717850 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 30 Oct 2022 18:54:52 +0100 Subject: [PATCH 59/72] fix: do not trash instances in Flatpak Signed-off-by: Sefa Eyeoglu --- launcher/Application.cpp | 9 --------- launcher/Application.h | 2 -- launcher/DesktopServices.cpp | 19 ++++++++++++++----- launcher/DesktopServices.h | 2 ++ launcher/FileSystem.cpp | 4 ++++ launcher/ui/pages/global/LauncherPage.cpp | 3 ++- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c6814abf..0c370b42 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1136,15 +1136,6 @@ std::vector Application::getValidApplicationThemes() return ret; } -bool Application::isFlatpak() -{ - #ifdef Q_OS_LINUX - return QFile::exists("/.flatpak-info"); - #else - return false; - #endif -} - void Application::setApplicationTheme(const QString& name, bool initial) { auto systemPalette = qApp->palette(); diff --git a/launcher/Application.h b/launcher/Application.h index c453cc28..8fa0ab10 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -116,8 +116,6 @@ public: QIcon getThemedIcon(const QString& name); - bool isFlatpak(); - void setIconTheme(const QString& name); std::vector getValidApplicationThemes(); diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index c29cbe7d..302eaf96 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -119,7 +119,7 @@ bool openDirectory(const QString &path, bool ensureExists) return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -140,7 +140,7 @@ bool openFile(const QString &path) return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -158,7 +158,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo qDebug() << "Opening file" << path << "using" << application; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen([&]() { @@ -178,7 +178,7 @@ bool run(const QString &application, const QStringList &args, const QString &wor { qDebug() << "Running" << application << "with args" << args.join(' '); #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave return IndirectOpen([&]() @@ -203,7 +203,7 @@ bool openUrl(const QUrl &url) return QDesktopServices::openUrl(url); }; #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - if(!APPLICATION->isFlatpak()) + if(!isFlatpak()) { return IndirectOpen(f); } @@ -216,4 +216,13 @@ bool openUrl(const QUrl &url) #endif } +bool isFlatpak() +{ +#ifdef Q_OS_LINUX + return QFile::exists("/.flatpak-info"); +#else + return false; +#endif +} + } diff --git a/launcher/DesktopServices.h b/launcher/DesktopServices.h index 1c081da4..21c9cae0 100644 --- a/launcher/DesktopServices.h +++ b/launcher/DesktopServices.h @@ -33,4 +33,6 @@ namespace DesktopServices * Open the URL, most likely in a browser. Maybe. */ bool openUrl(const QUrl &url); + + bool isFlatpak(); } diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 76cfccb0..aaa75e6f 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -44,6 +44,7 @@ #include #include #include +#include "DesktopServices.h" #if defined Q_OS_WIN32 #include @@ -228,6 +229,9 @@ bool trash(QString path, QString *pathInTrash = nullptr) #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) return false; #else + // FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal + if (DesktopServices::isFlatpak()) + return false; return QFile::moveToTrash(path, pathInTrash); #endif } diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 536ab22e..4ae7509c 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -49,6 +49,7 @@ #include #include "Application.h" #include "BuildConfig.h" +#include "DesktopServices.h" #include "ui/themes/ITheme.h" #include @@ -143,7 +144,7 @@ void LauncherPage::on_instDirBrowseBtn_clicked() ui->instDirTextBox->setText(cooked_dir); } } - else if(APPLICATION->isFlatpak() && raw_dir.startsWith("/run/user")) + else if(DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user")) { QMessageBox warning; warning.setText(tr("You're trying to specify an instance folder " From f2d445d27b1052a038cd94a5c514cee807abd894 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 30 Oct 2022 19:08:02 +0100 Subject: [PATCH 60/72] fix: fix undo key sequence Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 55f3e4f8..3b1779b7 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -335,11 +335,10 @@ public: all_actions.append(&actionSettings); actionUndoTrashInstance = TranslatedAction(MainWindow); - connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), MainWindow, SLOT(undoTrashInstance())); actionUndoTrashInstance->setObjectName(QStringLiteral("actionUndoTrashInstance")); actionUndoTrashInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Undo Last Instance Deletion")); actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); - actionUndoTrashInstance->setShortcut(QKeySequence("Ctrl+Z")); + actionUndoTrashInstance->setShortcut(QKeySequence::Undo); all_actions.append(&actionUndoTrashInstance); actionClearMetadata = TranslatedAction(MainWindow); @@ -1023,6 +1022,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow } } + connect(ui->actionUndoTrashInstance.operator->(), &QAction::triggered, this, &MainWindow::undoTrashInstance); + setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); // removing this looks stupid From dfdf739282792ca646bb284b3d83b2d2265a9d55 Mon Sep 17 00:00:00 2001 From: Chrono Date: Mon, 31 Oct 2022 19:44:55 -0400 Subject: [PATCH 61/72] remove one space Signed-off-by: Chrono --- launcher/ui/pages/global/APIPage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 1ae788c7..d56a9ef6 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -179,7 +179,7 @@ - Enter a custom client ID for Microsoft Authentication here. + Enter a custom client ID for Microsoft Authentication here. Qt::RichText From b142e2a7a75171da4c5bad9be17aa1bc52676b67 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 1 Nov 2022 13:59:11 +0100 Subject: [PATCH 62/72] fix: fix logo name Signed-off-by: Sefa Eyeoglu --- program_info/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index f064e098..b0507816 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -21,12 +21,12 @@ set(Launcher_Domain "prismlauncher.org" PARENT_SCOPE) set(Launcher_UserAgent "${Launcher_CommonName}/${Launcher_VERSION_NAME}" PARENT_SCOPE) set(Launcher_ConfigFile "prismlauncher.cfg" PARENT_SCOPE) set(Launcher_Git "https://github.com/PrismLauncher/PrismLauncher" PARENT_SCOPE) -set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop") -set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg") +set(Launcher_DesktopFileName "org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) +set(Launcher_SVGFileName "org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) -set(Launcher_Desktop "program_info/${Launcher_DesktopFileName}" PARENT_SCOPE) +set(Launcher_Desktop "program_info/org.prismlauncher.PrismLauncher.desktop" PARENT_SCOPE) set(Launcher_MetaInfo "program_info/org.prismlauncher.PrismLauncher.metainfo.xml" PARENT_SCOPE) -set(Launcher_SVG "program_info/${Launcher_SVGFileName}" PARENT_SCOPE) +set(Launcher_SVG "program_info/org.prismlauncher.PrismLauncher.svg" PARENT_SCOPE) set(Launcher_Branding_ICNS "program_info/prismlauncher.icns" PARENT_SCOPE) set(Launcher_Branding_ICO "program_info/prismlauncher.ico") set(Launcher_Branding_ICO "${Launcher_Branding_ICO}" PARENT_SCOPE) From 718a9a35599a109578bbf36925548f60e9a0167d Mon Sep 17 00:00:00 2001 From: txtsd Date: Wed, 2 Nov 2022 01:20:58 +0530 Subject: [PATCH 63/72] change: Update credits Replaces txtsd's GitHub link with their website Moves DioEgizio and flowln from contributors to dev team Signed-off-by: txtsd --- launcher/ui/dialogs/AboutDialog.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 52d6baef..a36e4a3d 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -73,17 +73,12 @@ QString getCreditsHtml() stream << "

" << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

\n"; stream << QString("

Sefa Eyeoglu (Scrumplex) %1

\n") .arg(getWebsite("https://scrumplex.net")); stream << QString("

dada513 %1

\n") .arg(getGitHub("dada513")); - stream << QString("

txtsd %1

\n") .arg(getGitHub("txtsd")); + stream << QString("

txtsd %1

\n") .arg(getWebsite("https://ihavea.quest")); stream << QString("

timoreo %1

\n") .arg(getGitHub("timoreo22")); stream << QString("

Ezekiel Smith (ZekeSmith) %1

\n") .arg(getGitHub("ZekeSmith")); stream << QString("

cozyGalvinism %1

\n") .arg(getGitHub("cozyGalvinism")); - stream << "
\n"; - - //: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Contributors" - stream << "

" << QObject::tr("%1 Contributors", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "

\n"; stream << QString("

DioEgizio %1

\n") .arg(getGitHub("DioEgizio")); stream << QString("

flowln %1

\n") .arg(getGitHub("flowln")); - stream << QString("

swirl %1

\n") .arg(getWebsite("https://swurl.xyz/")); stream << "
\n"; // TODO: possibly retrieve from git history at build time? From 0a0ce74105b1c01bb312175a823e715d6abb310c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20C=C3=A9zar?= Date: Tue, 1 Nov 2022 19:06:27 -0300 Subject: [PATCH 64/72] add rory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Santiago Cézar Co-authored-by: Ashtaka <66513643+AshtakaOOf@users.noreply.github.com> --- launcher/Application.cpp | 1 + .../resources/backgrounds/backgrounds.qrc | 9 +++-- launcher/resources/backgrounds/generic.jpg | Bin 0 -> 335269 bytes .../{cattiversary.png => kitteh-bday.png} | Bin .../{catmas.png => kitteh-xmas.png} | Bin .../backgrounds/{catbgrnd2.png => kitteh.png} | Bin launcher/resources/backgrounds/rory-bday.png | Bin 0 -> 89472 bytes launcher/resources/backgrounds/rory-xmas.png | Bin 0 -> 90158 bytes launcher/resources/backgrounds/rory.png | Bin 0 -> 90624 bytes launcher/ui/MainWindow.cpp | 17 ++++----- launcher/ui/pages/global/LauncherPage.cpp | 16 +++++++++ launcher/ui/pages/global/LauncherPage.ui | 33 ++++++++++++++++++ 12 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 launcher/resources/backgrounds/generic.jpg rename launcher/resources/backgrounds/{cattiversary.png => kitteh-bday.png} (100%) rename launcher/resources/backgrounds/{catmas.png => kitteh-xmas.png} (100%) rename launcher/resources/backgrounds/{catbgrnd2.png => kitteh.png} (100%) create mode 100644 launcher/resources/backgrounds/rory-bday.png create mode 100644 launcher/resources/backgrounds/rory-xmas.png create mode 100644 launcher/resources/backgrounds/rory.png diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 2da8ac56..5772d7ca 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -501,6 +501,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Theming m_settings->registerSetting("IconTheme", QString("pe_colored")); m_settings->registerSetting("ApplicationTheme", QString("system")); + m_settings->registerSetting("BackgroundCat", QString("kitteh")); // Remembered state m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc index 52921512..db48af8b 100644 --- a/launcher/resources/backgrounds/backgrounds.qrc +++ b/launcher/resources/backgrounds/backgrounds.qrc @@ -1,8 +1,11 @@ - catbgrnd2.png - catmas.png - cattiversary.png + kitteh.png + kitteh-xmas.png + kitteh-bday.png + rory.png + rory-xmas.png + rory-bday.png diff --git a/launcher/resources/backgrounds/generic.jpg b/launcher/resources/backgrounds/generic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c4832b0a9a2d8f83f899e811376077ab7c7dffc9 GIT binary patch literal 335269 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

d?1i*GrNZ4 z_)o?*2w0u?=|lYg06Jotm?DW3qY(E%Wp+O0-lxjCVm>>5I16ewzM+|gD$y6*cFV*< z#Uz){Ko5Mjxj%kO&`J~+q2m*0RE)-^=3~I@gXiZt-rkITM>e71O{7u%aBD2XQxt;F ztQx+*i&fllc&RH4DEkIjWGofO^8n`33(=*t4lGtWr zey1&rC`n9#l%17lBKJ)oRn`*q<%vckh!88uWYkCp=^Fw29e6I zJYu4mkErELj776?+KvoNBP0%azA&bPBuYY$t_kFMPSxY&^vH-b=G%n_r@kD=J8?nPHih+zP9!!V-B&d*^SyU(JoH)B*X!EK$h~4j11O8b)Di=V<5{VMLUE z?2ve@U71w{kx%%$lDZqp4d+~A|5&U!9^dOc_(N%#9CAm`t6A8eJ}tLdASw`xyEDCNx%*GoME=A z@sMX#Tiw$J$`dSHH(V;rYJsA9OC2Q=6Mj`b}-kr+IjVrmGB7$HUA z+7Bbt3EB;n?Swjr6Tg;3S z6#H|P5lRl{TCQ_Ki!kRd!DxazVRp|+h}~waReNL!109R)WSk`WVPU{MZL7Wz7}h$C zcqYieS&~h+yLEIIgh?%VuAM$`>Z(Q8PPnweJj1kddthH;$h1c|vN;xw)MWXLfr5g5 zm@8*u{{V@=DMD11{IOJBl9C0CIhdHpJbPfGJEST<6NNUjjhqW&Xk;W)?<@tD!$Acb z01uPb86YB>Jp17ZTU9Wt=sobGOzZ`P1HK$FyPq4t9Oo4}|t`&7^s;U7kf=FIx+*MJ3GIGv^ zBq|hf(BKoz4#AiZ0qI?Gvg+hMlnRIIXBT#sy<`FGG7PGK@NemXJ7q1nxF_c%7AKya z@}6e#&!lAev9ADgg(=?`ij zI0ZCMsjumfP0&zD%SRDzTbyBI+ARK936Sevp1C$^g7SUwy1)pTwLNR;foP)%>SM_m zVK5v6XD95*{6wFOJaI+^D)EFYcgStN?ha4g9-JI{R0^Kl;)JZc5x_VPx@@TwaolCn zLc@cW47@2IgNn+J3lf}zfqhX%j>+{5RkY2tNg3QLk(V*aD5J&XpqEZ|vf7^G8d+>B zCiOH$1DA~fOl6}JwGotU9I*?G?j38sXHCqZcGLNHdBaT1EOU6lmvR(gM0PpQF+)e8 z>6zVZp^cN8HH_%Nebi_UxJg|qk39Ct(J%`2-mfgI=jm|r#JfPTlc#OP%MNUeI-qVr zqwRo_7Dn?U1RmgXdAB5LG^+ljJ6q!bWRaut-i3F@)=Q51^cUP%VR4<`o(paHa=J+jFIRmp}itMyUsbMmc1fFqBOZ*9u#nPA@PfWwrE?+XCoipYHMoNYcs<jI}Z2>eAXZlx9Tye7`v;g@D1H#2`DNJU}ZSj_Xm6H zf^A892dbRcl*Uw<6ndg@Y*%ZK{)Z(s#eVSw9`%6Kzy=S{fzQ(r@PI}=4YNKkX z0|8y~IT6SLwR2~-G?1x4r9mBe=Oxe>==MB(Wh0b>w~HNp@H$u!0k8#e(`Xg=;_WlB z^7d2xags@H2TTM}mzqY7PI%