diff --git a/.gitignore b/.gitignore
index ca2c45072..031d9ad29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,27 @@ _codeql_detected_source_root
/build*/
!/build_tools/
!/build_tools/**
+
+# macOS noise
+.DS_Store
+/bin
+/CMakeLists.txt.user
+/.qtcreator
+/.kdev4
+/strawberry.kdev4
+/.vscode
+/.code-workspace
+/.sublime-workspace
+/.idea
+/.vs
+/out
+/CMakeSettings.json
+/dist/scripts/maketarball.sh
+/debian/changelog
+_codeql_detected_source_root
+
+# Build output (keep build tooling scripts in /build_tools/ tracked)
+/cmake-build*/
+/build*/
+!/build_tools/
+!/build_tools/**
diff --git a/Changelog b/Changelog
index dd2c1ed1b..68ada1d2f 100644
--- a/Changelog
+++ b/Changelog
@@ -343,7 +343,7 @@ Version 1.1.0 (2024.07.14):
* Only use playbin3 with GStreamer 1.24 and higher, not with GStreamer 1.22 or lower.
* (macOS/Windows) Fixed dash and hls streaming, plugins were missing.
* (Windows) Fixed incorrect colors in smart playlist wizard with Fusion in dark mode (#1399).
- * (Windows) Fixed update window blocking sponsor window on startup.
+ * (Windows) Fixed update window blocking startup window on launch.
Enhancements:
* Improve error messages when connecting and copying to devices.
diff --git a/README.md b/README.md
index 20cbec3dc..50fd092bc 100644
--- a/README.md
+++ b/README.md
@@ -1,60 +1,49 @@
-# :strawberry: Strawberry Music Player [](https://github.com/strawberrymusicplayer/strawberry/actions)
-[](https://github.com/sponsors/jonaski)
-[](https://patreon.com/jonaskvinge)
-[](https://paypal.me/jonaskvinge)
+# Strawberry (macOS-focused fork)
-Strawberry is a **music player and music collection organizer**, originally forked from *Clementine* in 2018.
-It’s written in **C++ using the Qt framework**, designed for **audiophiles and music collectors**.
+This repository is a **macOS-focused fork** of the upstream Strawberry Music Player project originally created and maintained by **Jonas Kvinge** (itself originally forked from Clementine).
-
+The goal of this fork is to make Strawberry **build cleanly and repeatably on macOS**, with:
----
+- Homebrew dependency installation via `Brewfile`
+- local Homebrew formulas (tap) for missing dependencies
+- build / deploy / signing / notarization helper scripts under `build_tools/`
+- Sparkle feed configuration knobs so you can publish your own updates
-## :globe_with_meridians: Resources
+## Upstream vs this fork (macOS distribution)
-- **Website:** https://www.strawberrymusicplayer.org
-- **Wiki:** https://wiki.strawberrymusicplayer.org
-- **Forum:** https://forum.strawberrymusicplayer.org
-- **GitHub:** https://github.com/strawberrymusicplayer/strawberry
-- **Latest builds:** https://builds.strawberrymusicplayer.org
-- **openSUSE Build Service:**
- - Stable: https://build.opensuse.org/package/show/home:jonaski:strawberry/strawberry
- - Unstable: https://build.opensuse.org/package/show/home:jonaski:strawberry-dev/strawberry
-- **Ubuntu PPAs:**
- - Stable: https://launchpad.net/~jonaski/+archive/ubuntu/strawberry
- - Unstable: https://launchpad.net/~jonaski/+archive/ubuntu/strawberry-unstable
-- **Translations:** https://crowdin.com/project/strawberrymusicplayer
+Upstream Strawberry is free/open-source, but upstream’s **macOS binaries** may be distributed via a **paid-access channel** depending on the release period and policy.
----
+This fork is intended for people who want to:
-## :warning: Opening an Issue
+- **build from source on macOS** without guesswork
+- **produce signed + notarized binaries** themselves (and optionally distribute them)
-Before creating a new GitHub issue:
+General safety note: whether you use upstream builds, your own builds, or someone else’s, only install software from sources you trust and prefer **signed + notarized** releases.
-1. **Read the [FAQ](https://wiki.strawberrymusicplayer.org/wiki/FAQ)**.
-2. **Search existing issues** to avoid duplicates. If one already exists, comment there with any additional information.
-3. **Use the [forum](https://forum.strawberrymusicplayer.org/)** for technical problems, discussions or feature suggestions — it’s better suited for back-and-forth conversation.
-4. **Feature requests are not accepted on GitHub.** Issues created for feature requests will be closed. You can still discuss ideas on the forum.
-5. **Flatpak users:** We do **not** maintain the Flatpak package. Report Flatpak-specific issues via [Flatpak support](https://flatpak.org/about/).
+## Quick start (macOS)
----
+Install Homebrew dependencies:
-## :moneybag: Sponsoring
+```bash
+./build_tools/macos/install_brew_deps.sh
+```
-Strawberry is **free software released under the GPL**.
-If you enjoy using it, please consider **supporting development** through sponsorship or donation.
+Build:
-**Sponsorship options:**
-1. [Patreon](https://www.patreon.com/jonaskvinge)
-2. [GitHub](https://github.com/sponsors/jonaski)
-3. [Ko-fi](https://ko-fi.com/jonaskvinge)
-4. [PayPal](https://paypal.me/jonaskvinge)
+```bash
+./build_tools/macos/build_app.sh --release --clean
+open ./cmake-build-macos-release/strawberry.app
+```
-Supporting open-source developers helps ensure continued maintenance and improvements.
+Build + deploy + sign + notarize (+ DMG):
----
+```bash
+./build_tools/macos/build_sign_notarize.sh --run --release --clean --deploy --dmg \
+ --identity "Developer ID Application: Your Name (TEAMID)" \
+ --notary-profile ""
+```
-## :white_check_mark: Features
+## Features
- Play and organize your music collection
- Supports formats: WAV, FLAC, WavPack, Ogg Vorbis, Opus, MPC, TrueAudio, AIFF, MP4, MP3, ASF, and Monkey’s Audio
@@ -78,11 +67,6 @@ Supporting open-source developers helps ensure continued maintenance and improve
:white_check_mark: Tested on **Linux**, **OpenBSD**, **FreeBSD**, **macOS**, and **Windows**.
-> **Note:** macOS and Windows releases are currently **available to sponsors only**.
-> A monthly sponsorship via [Patreon](https://www.patreon.com/jonaskvinge) grants direct access to new releases.
-
----
-
## :gear: Requirements
To build Strawberry from source, you’ll need:
diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp
index 455d114d3..c06c0c56b 100644
--- a/src/core/mainwindow.cpp
+++ b/src/core/mainwindow.cpp
@@ -1142,18 +1142,7 @@ MainWindow::MainWindow(Application *app,
asked_permission = s.value("asked_permission", false).toBool();
s.endGroup();
#endif
- if (asked_permission) {
- s.beginGroup(MainWindowSettings::kSettingsGroup);
- const bool do_not_show_sponsor_message = s.value(MainWindowSettings::kDoNotShowSponsorMessage, false).toBool();
- s.endGroup();
- if (!do_not_show_sponsor_message) {
- MessageDialog *sponsor_message = new MessageDialog(this);
- sponsor_message->set_settings_group(QLatin1String(MainWindowSettings::kSettingsGroup));
- sponsor_message->set_do_not_show_message_again(QLatin1String(MainWindowSettings::kDoNotShowSponsorMessage));
- sponsor_message->setAttribute(Qt::WA_DeleteOnClose);
- sponsor_message->ShowMessage(tr("Sponsoring Strawberry"), tr("Strawberry is free and open source software. If you like Strawberry, please consider sponsoring the project. For more information about sponsorship see our website %1").arg(u"www.strawberrymusicplayer.org"_s), IconLoader::Load(u"dialog-information"_s));
- }
- }
+ Q_UNUSED(asked_permission)
}
qLog(Debug) << "Started" << QThread::currentThread();
diff --git a/src/dialogs/about.cpp b/src/dialogs/about.cpp
index 419f18041..143624a31 100644
--- a/src/dialogs/about.cpp
+++ b/src/dialogs/about.cpp
@@ -124,17 +124,6 @@ QString About::MainHtml() const {
ret += tr("You should have received a copy of the GNU General Public License along with this program. If not, see %1").arg(QStringLiteral("http://www.gnu.org/licenses/").arg(palette().text().color().name()));
ret += "
"_L1;
- ret += ""_L1;
- ret += tr("If you like Strawberry and can make use of it, consider sponsoring or donating.");
- ret += "
"_L1;
- ret += tr("You can sponsor the author on %1 or %2. You can also make a one-time payment through %3.").arg(
- QStringLiteral("Patreon").arg(palette().text().color().name()),
- QStringLiteral("GitHub").arg(palette().text().color().name()),
- QStringLiteral("paypal.me/jonaskvinge").arg(palette().text().color().name())
- );
-
- ret += "
"_L1;
-
return ret;
}
diff --git a/src/radios/radiomodel.cpp b/src/radios/radiomodel.cpp
index 4d7ce9371..ca64c0cfa 100644
--- a/src/radios/radiomodel.cpp
+++ b/src/radios/radiomodel.cpp
@@ -113,11 +113,6 @@ QVariant RadioModel::data(const RadioItem *item, int role) const {
if (service) return service->Homepage();
break;
}
- case Role_Donate:{
- RadioService *service = radio_services_->ServiceBySource(item->source);
- if (service) return service->Donate();
- break;
- }
default:
return QVariant();
}
diff --git a/src/radios/radiomodel.h b/src/radios/radiomodel.h
index 68b4ec52f..d1c623991 100644
--- a/src/radios/radiomodel.h
+++ b/src/radios/radiomodel.h
@@ -56,7 +56,6 @@ class RadioModel : public SimpleTreeModel {
Role_Source,
Role_Url,
Role_Homepage,
- Role_Donate,
RoleCount
};
diff --git a/src/radios/radioparadiseservice.cpp b/src/radios/radioparadiseservice.cpp
index 8ba558a1b..bc5783b14 100644
--- a/src/radios/radioparadiseservice.cpp
+++ b/src/radios/radioparadiseservice.cpp
@@ -41,7 +41,6 @@ RadioParadiseService::RadioParadiseService(const SharedPtr task_man
: RadioService(Song::Source::RadioParadise, u"Radio Paradise"_s, IconLoader::Load(u"radioparadise"_s), task_manager, network, parent) {}
QUrl RadioParadiseService::Homepage() { return QUrl(u"https://radioparadise.com/"_s); }
-QUrl RadioParadiseService::Donate() { return QUrl(u"https://payments.radioparadise.com/rp2s-content.php?name=Support&file=support"_s); }
void RadioParadiseService::Abort() {
diff --git a/src/radios/radioparadiseservice.h b/src/radios/radioparadiseservice.h
index b411011a8..d55490296 100644
--- a/src/radios/radioparadiseservice.h
+++ b/src/radios/radioparadiseservice.h
@@ -37,7 +37,6 @@ class RadioParadiseService : public RadioService {
explicit RadioParadiseService(const SharedPtr task_manager, const SharedPtr network, QObject *parent = nullptr);
QUrl Homepage() override;
- QUrl Donate() override;
void Abort();
diff --git a/src/radios/radioservice.h b/src/radios/radioservice.h
index 34eba9d85..6b2f81546 100644
--- a/src/radios/radioservice.h
+++ b/src/radios/radioservice.h
@@ -56,7 +56,6 @@ class RadioService : public QObject {
virtual void ReloadSettings() {}
virtual QUrl Homepage() = 0;
- virtual QUrl Donate() = 0;
Q_SIGNALS:
void NewChannels(const RadioChannelList &channels = RadioChannelList());
diff --git a/src/radios/radioview.cpp b/src/radios/radioview.cpp
index aaa0285ec..e94c9300e 100644
--- a/src/radios/radioview.cpp
+++ b/src/radios/radioview.cpp
@@ -44,7 +44,6 @@ RadioView::RadioView(QWidget *parent)
action_playlist_replace_(nullptr),
action_playlist_new_(nullptr),
action_homepage_(nullptr),
- action_donate_(nullptr),
initialized_(false) {
setItemDelegate(new CollectionItemDelegate(this));
@@ -88,10 +87,6 @@ void RadioView::contextMenuEvent(QContextMenuEvent *e) {
QObject::connect(action_homepage_, &QAction::triggered, this, &RadioView::Homepage);
menu_->addAction(action_homepage_);
- action_donate_ = new QAction(IconLoader::Load(u"download"_s), tr("Donate"), this);
- QObject::connect(action_donate_, &QAction::triggered, this, &RadioView::Donate);
- menu_->addAction(action_donate_);
-
menu_->addAction(IconLoader::Load(u"view-refresh"_s), tr("Refresh channels"), this, &RadioView::GetChannels);
}
@@ -101,7 +96,6 @@ void RadioView::contextMenuEvent(QContextMenuEvent *e) {
action_playlist_replace_->setVisible(channels_selected);
action_playlist_new_->setVisible(channels_selected);
action_homepage_->setVisible(channels_selected);
- action_donate_->setVisible(channels_selected);
menu_->popup(e->globalPos());
@@ -165,22 +159,3 @@ void RadioView::Homepage() {
}
}
-
-void RadioView::Donate() {
-
- const QModelIndexList selected_indexes = selectedIndexes();
- if (selected_indexes.isEmpty()) return;
-
- QList urls;
- for (const QModelIndex &idx : selected_indexes) {
- QUrl url = idx.data(RadioModel::Role_Donate).toUrl();
- if (!urls.contains(url)) {
- urls << url; // clazy:exclude=reserve-candidates
- }
- }
-
- for (const QUrl &url : std::as_const(urls)) {
- QDesktopServices::openUrl(url);
- }
-
-}
diff --git a/src/radios/radioview.h b/src/radios/radioview.h
index 6e8b9513a..18efa9ce7 100644
--- a/src/radios/radioview.h
+++ b/src/radios/radioview.h
@@ -50,7 +50,6 @@ class RadioView : public AutoExpandingTreeView {
void ReplacePlaylist();
void OpenInNewPlaylist();
void Homepage();
- void Donate();
private:
QMenu *menu_;
@@ -58,7 +57,6 @@ class RadioView : public AutoExpandingTreeView {
QAction *action_playlist_replace_;
QAction *action_playlist_new_;
QAction *action_homepage_;
- QAction *action_donate_;
bool initialized_;
};
diff --git a/src/radios/somafmservice.cpp b/src/radios/somafmservice.cpp
index 8c63081ee..0c7bf86ba 100644
--- a/src/radios/somafmservice.cpp
+++ b/src/radios/somafmservice.cpp
@@ -49,7 +49,6 @@ SomaFMService::~SomaFMService() {
}
QUrl SomaFMService::Homepage() { return QUrl(u"https://somafm.com/"_s); }
-QUrl SomaFMService::Donate() { return QUrl(u"https://somafm.com/support/"_s); }
void SomaFMService::Abort() {
diff --git a/src/radios/somafmservice.h b/src/radios/somafmservice.h
index 585155d6a..eed41008f 100644
--- a/src/radios/somafmservice.h
+++ b/src/radios/somafmservice.h
@@ -40,7 +40,6 @@ class SomaFMService : public RadioService {
~SomaFMService();
QUrl Homepage() override;
- QUrl Donate() override;
void Abort();