changeset 232:ff0061e75f0f

theme: add OS detection with glib
author Paper <mrpapersonic@gmail.com>
date Sat, 13 Jan 2024 11:06:16 -0500
parents 69f4768a820c
children 0a5b6a088886
files CMakeLists.txt dep/animia/src/strategist.cc include/gui/dialog/settings.h include/sys/glib/dark_theme.h src/gui/dialog/settings/application.cc src/gui/dialog/settings/library.cc src/gui/dialog/settings/recognition.cc src/gui/dialog/settings/services.cc src/gui/dialog/settings/torrents.cc src/gui/pages/anime_list.cc src/gui/theme.cc src/gui/widgets/poster.cc src/gui/window.cc src/sys/glib/dark_theme.cc
diffstat 14 files changed, 121 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Jan 13 09:43:41 2024 -0500
+++ b/CMakeLists.txt	Sat Jan 13 11:06:16 2024 -0500
@@ -125,6 +125,8 @@
 	rc/locale/es.ts
 )
 
+set(DEFINES)
+
 set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/rc/locale")
 
 if(UPDATE_TRANSLATIONS)
@@ -165,6 +167,7 @@
 		src/sys/osx/filesystem.cc
 		${app_icon_osx}
 	)
+	list(APPEND DEFINES MACOSX)
 elseif(WIN32) # Windows
 	configure_file(
 		${CMAKE_CURRENT_SOURCE_DIR}/rc/win32/version.rc.in
@@ -176,17 +179,31 @@
 		rc/win32/resource.rc
 		${CMAKE_CURRENT_BINARY_DIR}/rc/version.rc
 	)
-elseif(LINUX)
-	configure_file(
-		${CMAKE_CURRENT_SOURCE_DIR}/rc/linux/Minori.desktop.in
-		${CMAKE_CURRENT_BINARY_DIR}/rc/Minori.desktop
-		@ONLY
-	)
-	configure_file(
-		${CMAKE_CURRENT_SOURCE_DIR}/rc/favicon256.png
-		${CMAKE_CURRENT_BINARY_DIR}/rc/Minori.png
-		COPYONLY
-	)
+	list(APPEND DEFINES WIN32)
+else()
+	if(LINUX)
+		configure_file(
+			${CMAKE_CURRENT_SOURCE_DIR}/rc/linux/Minori.desktop.in
+			${CMAKE_CURRENT_BINARY_DIR}/rc/Minori.desktop
+			@ONLY
+		)
+		configure_file(
+			${CMAKE_CURRENT_SOURCE_DIR}/rc/favicon256.png
+			${CMAKE_CURRENT_BINARY_DIR}/rc/Minori.png
+			COPYONLY
+		)
+	endif()
+
+	find_package(PkgConfig)
+	if (PKG_CONFIG_FOUND)
+		pkg_check_modules(GLIB gio-2.0 glib-2.0)
+		if (GLIB_FOUND)
+			list(APPEND SRC_FILES src/sys/glib/dark_theme.cc)
+			list(APPEND INCLUDE ${GLIB_INCLUDE_DIRS})
+			list(APPEND LIBRARIES ${GLIB_LINK_LIBRARIES})
+			list(APPEND DEFINES GLIB)
+		endif()
+	endif()
 endif()
 
 add_executable(minori WIN32 MACOSX_BUNDLE ${SRC_FILES})
@@ -194,16 +211,13 @@
 set_property(TARGET minori PROPERTY AUTOMOC ON)
 set_property(TARGET minori PROPERTY AUTORCC ON)
 
-target_include_directories(minori PUBLIC ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PRIVATE ${INCLUDE})
+target_include_directories(minori PRIVATE ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PUBLIC ${INCLUDE})
+target_link_libraries(minori PRIVATE ${LIBRARIES})
 target_compile_options(minori PRIVATE -Wall -Wpedantic -Wextra -Wsuggest-override -Wold-style-cast)
+target_compile_definitions(minori PRIVATE ${DEFINES})
+
 if(APPLE)
-	target_compile_definitions(minori PUBLIC MACOSX)
 	set_target_properties(minori PROPERTIES MACOSX_BUNDLE TRUE)
 elseif(WIN32)
-	target_compile_definitions(minori PUBLIC WIN32)
-endif()
-target_link_libraries(minori ${LIBRARIES})
-
-if(WIN32)
 	install(FILES $<TARGET_RUNTIME_DLLS:minori> TYPE BIN)
 endif()
--- a/dep/animia/src/strategist.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/dep/animia/src/strategist.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -28,6 +28,7 @@
 	switch (result_.type) {
 		case ResultType::Process: success |= ApplyOpenFilesStrategy(); break;
 		case ResultType::Window: success |= ApplyWindowTitleStrategy(); break;
+		default: break;
 	}
 
 	return success;
--- a/include/gui/dialog/settings.h	Sat Jan 13 09:43:41 2024 -0500
+++ b/include/gui/dialog/settings.h	Sat Jan 13 11:06:16 2024 -0500
@@ -37,8 +37,8 @@
 	private:
 		QWidget* CreateMainPage();
 		QWidget* CreateAniListPage();
-		QString username;
-		Anime::Services service;
+
+		decltype(session.config.service) service;
 };
 
 class SettingsPageApplication final : public SettingsPage {
@@ -51,14 +51,16 @@
 	private:
 		QWidget* CreateAnimeListWidget();
 		QWidget* CreateGeneralWidget();
-		decltype(session.config.anime_list.score_format) format;
+
 		Themes theme;
 		QLocale locale;
-		Anime::TitleLanguage language;
-		bool display_aired_episodes;
-		bool display_available_episodes;
-		bool highlight_anime_if_available;
-		bool highlighted_anime_above_others;
+
+		decltype(session.config.anime_list.score_format) format;
+		decltype(session.config.anime_list.language) language;
+		decltype(session.config.anime_list.display_aired_episodes) display_aired_episodes;
+		decltype(session.config.anime_list.display_available_episodes) display_available_episodes;
+		decltype(session.config.anime_list.highlight_anime_if_available) highlight_anime_if_available;
+		decltype(session.config.anime_list.highlighted_anime_above_others) highlighted_anime_above_others;
 };
 
 class SettingsPageTorrents final : public SettingsPage {
@@ -70,6 +72,7 @@
 
 	private:
 		QWidget* CreateGeneralWidget();
+
 		decltype(session.config.torrents.feed_link) feed_link;
 };
 
@@ -82,6 +85,7 @@
 
 	private:
 		QWidget* CreatePlayersWidget();
+
 		decltype(session.config.recognition.detect_media_players) detect_media_players;
 		decltype(session.config.recognition.players) players;
 };
@@ -95,6 +99,7 @@
 
 	private:
 		QWidget* CreateFoldersWidget();
+
 		decltype(session.config.library.paths) paths;
 		decltype(session.config.library.real_time_monitor) real_time_monitor;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/sys/glib/dark_theme.h	Sat Jan 13 11:06:16 2024 -0500
@@ -0,0 +1,10 @@
+#ifndef __sys__glib__dark_theme_h
+#define __sys__glib__dark_theme_h
+
+namespace glib {
+
+bool IsInDarkTheme();
+
+}
+
+#endif // __sys__glib__dark_theme_h
\ No newline at end of file
--- a/src/gui/dialog/settings/application.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/dialog/settings/application.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -18,7 +18,6 @@
 
 QWidget* SettingsPageApplication::CreateAnimeListWidget() {
 	QWidget* result = new QWidget(this);
-	result->setAutoFillBackground(true);
 	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
 
 	QVBoxLayout* full_layout = new QVBoxLayout(result);
@@ -173,7 +172,6 @@
 
 QWidget* SettingsPageApplication::CreateGeneralWidget() {
 	QWidget* result = new QWidget(this);
-	result->setAutoFillBackground(true);
 	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
 
 	QVBoxLayout* full_layout = new QVBoxLayout(result);
--- a/src/gui/dialog/settings/library.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/dialog/settings/library.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -75,7 +75,6 @@
 
 QWidget* SettingsPageLibrary::CreateFoldersWidget() {
 	QWidget* result = new QWidget(this);
-	result->setAutoFillBackground(true);
 	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
 
 	QVBoxLayout* full_layout = new QVBoxLayout(result);
--- a/src/gui/dialog/settings/recognition.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/dialog/settings/recognition.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -14,7 +14,6 @@
 
 QWidget* SettingsPageRecognition::CreatePlayersWidget() {
 	QWidget* result = new QWidget(this);
-	result->setAutoFillBackground(true);
 	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
 
 	QVBoxLayout* full_layout = new QVBoxLayout(result);
--- a/src/gui/dialog/settings/services.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/dialog/settings/services.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -66,25 +66,11 @@
 		QVBoxLayout* layout = new QVBoxLayout(group_box);
 
 		{
-			QLabel* username_entry_label = new QLabel(tr("Username: (not your email address)"), group_box);
-			layout->addWidget(username_entry_label);
-		}
-
-		{
 			/* Authorization */
 			QWidget* auth_widget = new QWidget(group_box);
 			QHBoxLayout* auth_layout = new QHBoxLayout(auth_widget);
 
 			{
-				/* Username: this literally never gets used btw */
-				QLineEdit* username_entry = new QLineEdit(username, auth_widget);
-				connect(username_entry, &QLineEdit::editingFinished, this,
-				        [this, username_entry] { username = username_entry->text(); });
-				auth_layout->addWidget(username_entry);
-			}
-
-			{
-				/* The actual auth button */
 				QPushButton* auth_button = new QPushButton(auth_widget);
 				connect(auth_button, &QPushButton::clicked, this, [] { Services::AniList::AuthorizeUser(); });
 				auth_button->setText(session.config.auth.anilist.auth_token.empty() ? tr("Authorize...") : tr("Re-authorize..."));
@@ -113,12 +99,10 @@
 
 void SettingsPageServices::SaveInfo() {
 	// see services/anilist.cc for why this is commented out
-	// session.config.anilist.username = Strings::ToUtf8String(username);
 	session.config.service = service;
 }
 
 SettingsPageServices::SettingsPageServices(QWidget* parent) : SettingsPage(parent, tr("Services")) {
-	// username = QString::fromUtf8(session.config.anilist.username.c_str());
 	service = session.config.service;
 	AddTab(CreateMainPage(), tr("Main"));
 	AddTab(CreateAniListPage(), tr("AniList"));
--- a/src/gui/dialog/settings/torrents.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/dialog/settings/torrents.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -10,7 +10,6 @@
 
 QWidget* SettingsPageTorrents::CreateGeneralWidget() {
 	QWidget* result = new QWidget(this);
-	result->setAutoFillBackground(true);
 	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
 
 	QVBoxLayout* full_layout = new QVBoxLayout(result);
--- a/src/gui/pages/anime_list.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/pages/anime_list.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -218,12 +218,12 @@
 }
 
 void AnimeListPage::UpdateAnime(int id) {
-	QThread* thread = QThread::create([id] {
+	QThread* thread = QThread::create([this, id] {
 		Services::UpdateAnimeEntry(id);
 	});
 
 	connect(thread, &QThread::finished, this, &AnimeListPage::Refresh);
-	connect(thread, &QThread::finished, this, &QThread::deleteLater);
+	connect(thread, &QThread::finished, thread, &QThread::deleteLater);
 
 	thread->start();
 }
--- a/src/gui/theme.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/theme.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -9,6 +9,10 @@
 #	include "sys/osx/dark_theme.h"
 #elif WIN32
 #	include "sys/win32/dark_theme.h"
+#else
+#	ifdef GLIB
+#		include "sys/glib/dark_theme.h"
+#	endif
 #endif
 
 /* Weird quirks of this implementation:
@@ -37,6 +41,10 @@
 #elif defined(WIN32)
 	if (win32::DarkThemeAvailable())
 		return win32::IsInDarkTheme();
+#else
+#	ifdef GLIB
+	return glib::IsInDarkTheme();
+#	endif
 #endif
 	return (theme == Themes::DARK);
 }
@@ -68,13 +76,8 @@
 }
 
 Themes Theme::GetCurrentOSTheme() const {
-#ifdef MACOSX
-	if (osx::DarkThemeAvailable())
-		return osx::IsInDarkTheme() ? Themes::DARK : Themes::LIGHT;
-#elif defined(WIN32)
-	if (win32::DarkThemeAvailable())
-		return win32::IsInDarkTheme() ? Themes::DARK : Themes::LIGHT;
-#endif
+	return IsInDarkTheme() ? Themes::DARK : Themes::LIGHT;
+
 	/* Currently OS detection only supports Windows and macOS.
 	   Please don't be shy if you're willing to port it to other OSes
 	   (or desktop environments, or window managers) */
--- a/src/gui/widgets/poster.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/widgets/poster.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -36,14 +36,15 @@
 
 void Poster::SetAnime(const Anime::Anime& anime) {
 	{
-		QByteArray ba;
+		QByteArray* ba = new QByteArray;
 
-		QThread* thread = QThread::create([&] {
-			ba = HTTP::Get(anime.GetPosterUrl(), {});
+		QThread* thread = QThread::create([ba, anime] {
+			*ba = HTTP::Get(anime.GetPosterUrl(), {});
 		});
 
-		connect(thread, &QThread::finished, this, [&] {
-			ImageDownloadFinished(ba);
+		connect(thread, &QThread::finished, this, [this, ba] {
+			ImageDownloadFinished(*ba);
+			delete ba;
 		});
 
 		thread->start();
--- a/src/gui/window.cc	Sat Jan 13 09:43:41 2024 -0500
+++ b/src/gui/window.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -87,27 +87,28 @@
 	*/
 	thread.reset(new PlayingThread(this));
 
+	connect(thread.get(), &PlayingThread::Done, this, [page](const std::vector<std::string>& files) {
+		for (const auto& file : files) {
+			anitomy::Anitomy anitomy;
+			anitomy.Parse(Strings::ToWstring(file));
+
+			const auto& elements = anitomy.elements();
+
+			int id = Anime::db.GetAnimeFromTitle(Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)));
+			if (id <= 0)
+				continue;
+
+			page->SetPlaying(Anime::db.items[id], elements);
+			break;
+		}
+	});
+
 	QTimer* timer = new QTimer(this);
 
 	connect(timer, &QTimer::timeout, this, [this, page] {
 		if (!thread.get() || thread->isRunning())
 			return;
 
-		connect(thread.get(), &PlayingThread::Done, this, [page](const std::vector<std::string>& files) {
-			for (const auto& file : files) {
-				anitomy::Anitomy anitomy;
-				anitomy.Parse(Strings::ToWstring(file));
-
-				const auto& elements = anitomy.elements();
-
-				int id = Anime::db.GetAnimeFromTitle(Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)));
-				if (id <= 0)
-					continue;
-
-				page->SetPlaying(Anime::db.items[id], elements);
-				break;
-			}
-		});
 		thread->start();
 	});
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sys/glib/dark_theme.cc	Sat Jan 13 11:06:16 2024 -0500
@@ -0,0 +1,31 @@
+#include <gio/gio.h>
+#include <cstring>
+
+#include <iostream>
+
+namespace glib {
+
+bool IsInDarkTheme() {
+	GSettings* settings = g_settings_new("org.gnome.desktop.interface");
+	if (!settings)
+		return false;
+
+	GVariant* val = g_settings_get_value(settings, "color-scheme");
+	if (!val)
+		return false;
+
+	const gchar* str;
+	g_variant_get(val, "&s", &str); /* should not be freed */
+	if (!str) /* how */
+		return false;
+
+	bool success = !std::strcmp(str, "prefer-dark");
+
+	/* unref these */
+	g_variant_unref(val);
+	g_object_unref(settings);
+
+	return success;
+}
+
+}