changeset 249:6b2441c776dd

*: merge
author Paper <mrpapersonic@gmail.com>
date Wed, 24 Jan 2024 20:18:59 -0500
parents cf47a8f687c0 (current diff) f475e168fac8 (diff)
children c130f47f6f48
files Makefile.am configure.ac
diffstat 42 files changed, 970 insertions(+), 940 deletions(-) [+]
line wrap: on
line diff
--- a/.builds/linux.yml	Wed Jan 24 20:18:14 2024 -0500
+++ b/.builds/linux.yml	Wed Jan 24 20:18:59 2024 -0500
@@ -2,7 +2,9 @@
 packages:
   - qtbase5-dev
   - qttools5-dev
-  - cmake
+  - automake
+  - autoconf
+  - libtool
   - clang
   - libcurl4-openssl-dev
   - wget
@@ -11,32 +13,32 @@
   - xorg-dev # shouldn't install Xorg!
   - libwayland-dev
   - pkg-config
+  - libglib2.0-dev
 sources:
   - https://hg.sr.ht/~mrpapersonic/minori
-environment:
-  BUILD_SUBMITTER: hg.sr.ht
 tasks:
   - build: |
+      # build
       cd minori
       autoreconf -i
-      cd dep/animia
-      autoreconf -i
-      cd ../anitomy
-      autoreconf -i
-      cd ../pugixml
-      autoreconf -i
-      cd ../..
       mkdir build
       cd build
       ../configure
       make
+      sudo make install
 
+      # resources
+      mkdir -p rc
+      cp ../rc/linux/Minori.desktop rc/Minori.desktop
+      cp ../rc/linux/Minori.png rc/Minori.png
+
+      # use linuxdeploy to make an appimage
       wget -O linuxdeploy "https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20231026-1/linuxdeploy-x86_64.AppImage"
       chmod +x linuxdeploy
-      ./linuxdeploy --appdir Minori --executable minori -d rc/Minori.desktop -i rc/Minori.png --output appimage
+      LD_LIBRARY_PATH=/usr/local/lib ./linuxdeploy --appdir Minori --executable $(which minori) -d rc/Minori.desktop -i rc/Minori.png --output appimage
 artifacts:
   - minori/build/Minori-x86_64.AppImage
 triggers:
   - action: email
     condition: failure
-    to: Paper <mrpapersonic@gmail.com>
+    to: Paper <paper@paper.us.eu.org>
--- a/.builds/windows.yml	Wed Jan 24 20:18:14 2024 -0500
+++ b/.builds/windows.yml	Wed Jan 24 20:18:59 2024 -0500
@@ -1,47 +1,35 @@
 image: debian/bookworm
 packages:
-  - wget
-  - tar
-  - zstd
-  - gpg
-  - clang
-  - lld
-  - xz-utils
-  - wine
-  - cmake
-  - ncurses-bin
-  - qtbase5-dev
-  - qttools5-dev
+  - automake
+  - autoconf
+  - libtool
 sources:
   - https://hg.sr.ht/~mrpapersonic/minori
-environment:
-  BUILD_SUBMITTER: hg.sr.ht
 tasks:
-  - build-win64: |
-      export WINEARCH=win64
-      git clone https://github.com/holyblackcat/quasi-msys2 quasi-msys2-win64
-      cd quasi-msys2-win64
-      echo MINGW64 >msystem.txt
-      make install _gcc _qt5-base _qt5-tools _curl _autotools
-      cd ../minori
-      sudo bash -c 'echo -n 1 >/proc/sys/fs/binfmt_misc/status'
-      bash -c 'source ../../quasi-msys2-win64/env/all.src && autoreconf -i && cd dep/animia && autoreconf -i && cd ../anitomy && autoreconf -i && cd ../pugixml && autoreconf -i && ../.. && mkdir build64 && cd build64 && ../configure && make'
-  - get-wine32: |
-      sudo dpkg --add-architecture i386
-      sudo apt-get update
-      sudo apt-get -y install wine32:i386
-  - build-win32: |
-      export WINEARCH=win32
-      export WINEPREFIX="$HOME/.wine32"
-      git clone https://github.com/holyblackcat/quasi-msys2 quasi-msys2-win32
-      cd quasi-msys2-win32
-      echo MINGW32 >msystem.txt
-      make install _gcc _qt5-base _qt5-tools _curl
-      cd ../minori
-      mkdir build32
-      cd build32
-      sudo bash -c 'echo -n 1 >/proc/sys/fs/binfmt_misc/status'
-      bash -c 'source ../../quasi-msys2-win32/env/all.src && autoreconf -i && cd dep/animia && autoreconf -i && cd ../anitomy && autoreconf -i && cd ../pugixml && autoreconf -i && ../.. && mkdir build32 && cd build32 && ../configure && make'
+  - install-docker: |
+      # Add Docker's official GPG key:
+      sudo apt update
+      sudo apt install ca-certificates curl gnupg
+      sudo install -m 0755 -d /etc/apt/keyrings
+      curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+      sudo chmod a+r /etc/apt/keyrings/docker.gpg
+
+      # Add the repository to Apt sources:
+      echo \
+        "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
+        $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
+        sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+      sudo apt update
+
+      sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
+  - build: |
+      export ARCH="x86_64"
+      cd minori
+      autoreconf -i
+
+      mkdir build
+      sudo docker run -e MSYSTEM=MINGW64 -w "$PWD/build" amitie10g/msys2 "/bin/bash -c 'pacman -S --noconfirm mingw-w64-$ARCH-qt5-base mingw-w64-$ARCH-qt5-translations mingw-w64-$ARCH-qt5-tools mingw-w64-$ARCH-toolchain mingw-w64-$ARCH-curl mingw-w64-$ARCH-make; ../configure; make; ../scripts/win32/deploy_build.sh'"
+
 triggers:
   - action: email
     condition: failure
--- a/.hgignore	Wed Jan 24 20:18:14 2024 -0500
+++ b/.hgignore	Wed Jan 24 20:18:59 2024 -0500
@@ -1,5 +1,14 @@
 syntax: glob
 
+m4/libtool.m4
+m4/lt*.m4
+build-aux
+aclocal.m4
+Makefile.in
+configure
+*~
+autom4te.cache
+
 # stupid OS X things
 .DS_Store
 ._*
@@ -35,7 +44,6 @@
 # Executables
 *.exe
 *.out
-*.app
 
 syntax: regexp
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,26 @@
+This is just like any typical autotools-based project.
+
+To install, it's as simple as:
+	0). autoreconf -i
+			This step is only necessary if you're cloning from the repository.
+			Tarballs will have this step done already.
+	1). ./configure
+			Configures the build, finds Qt and the necessary runtime libraries.
+
+			NOTE: If you don't have Qt binaries on your PATH (e.g. MacPorts),
+			you can temporarily add it by prepending `PATH=qt_path:$PATH"
+			before configuring.
+	2). make
+			Builds the package.
+	3). make install
+			Installs the package. Use a suitable permission escalator like sudo
+			or doas.
+
+In some cases, the configure script will fail to find Qt. To solve this, put the
+path containing qmake into your PATH or configure pkg-config with the correct
+paths for Qt[5/6]Widgets.
+
+On OS X/macOS, you'll probably want an app bundle. To create this, simply call
+`scripts/osx/deploy_build.sh` from the build directory.
+	NOTE: This script relies on `macdeployqt` being in your PATH for it to work
+	      properly.
--- a/LICENSE	Wed Jan 24 20:18:14 2024 -0500
+++ b/LICENSE	Wed Jan 24 20:18:59 2024 -0500
@@ -1,6 +1,6 @@
 BSD 3-Clause License
 
-Copyright (c) 2023, Paper
+Copyright (c) 2023-2024, Paper
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
--- a/Makefile.am	Wed Jan 24 20:18:14 2024 -0500
+++ b/Makefile.am	Wed Jan 24 20:18:59 2024 -0500
@@ -1,9 +1,33 @@
 bin_PROGRAMS = minori
 
+minori_locale_ts = \
+	rc/locale/en_GB.ts \
+	rc/locale/es.ts
+
+.ts.qm:
+	@MKDIR_P@ `dirname $@`; \
+	@QT_LRELEASE@ $< -qm $@
+
+minori_locale_qm = $(minori_locale_ts:.ts=.qm)
+
+# this has to be in the root build folder
+translations.qrc: $(minori_locale_qm)
+	printf "<!DOCTYPE rcc><RCC version=\"1.0\">\n\t<qresource prefix=\"locale/\">\n" > $@; \
+	for q in $(minori_locale_qm); do \
+		printf "\t\t<file alias=\"%s\">%s</file>\n" "`basename $$q`" "$$q" >> $@; \
+	done; \
+	printf "\t</qresource>\n</RCC>\n" >> $@;
+
 minori_qtrc = \
-	$(top_srcdir)/rc/dark.qrc	\
-	$(top_srcdir)/rc/icons.qrc	\
-	$(top_srcdir)/rc/player_data.qrc
+	$(top_srcdir)/rc/icons/icons.qrc	\
+	$(top_srcdir)/rc/player_data.qrc	\
+	translations.qrc
+
+if BUILD_WIN
+
+minori_qtrc += $(top_srcdir)/rc/win32/dark/dark.qrc
+
+endif
 
 rc/final_qrc.cc: $(minori_qtrc)
 	@QT_RCC@ -o $@ $(minori_qtrc)
@@ -66,21 +90,25 @@
 
 if BUILD_WIN
 files_win = src/sys/win32/dark_theme.cc
+libs_win = -lole32 -luuid
+ldflags_win = -mwindows
 
 if BUILD_WINDRES
-# Untested...
-wrcflags_version = -DWRC_VERSION=0,`echo '$(PACKAGE_VERSION)' | @SED@ 's/(\d+)\.(\d+)\.(\d+)/\1,\2,\3/'`
 
-WRCFLAGS = --use-temp-file -I. -I$(srcdir) $(wrcflags_version)
+wrcflags_version = -DWRC_VERSION=0,`echo $(PACKAGE_VERSION) | @SED@ 's/\([0-9]\{1,\}\)\.\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/\1,\2,\3/'`
+
+WRCFLAGS = --use-temp-file -I. -I$(srcdir) $(wrcflags_version) $(CPPFLAGS)
 .rc.$(OBJEXT):
 	$(WINDRES) $(WRCFLAGS) -i $< -o $@
-files_windres=rc/win32/version.rc
+files_windres=rc/win32/version.rc rc/win32/resource.rc
 endif
 endif
 
 if BUILD_OSX
-files_osx = src/sys/osx/dark_theme.cc src/sys/osx/filesystem.cc
-libs_osx = Foundation AppKit
+files_osx = src/sys/osx/dark_theme.cc src/sys/osx/filesystem.cc src/sys/osx/permissions.cc
+cflags_osx = -mmacosx-version-min=10.15
+libs_osx = -lobjc
+ldflags_osx = -framework Foundation -framework AppKit
 endif
 
 minori_SOURCES = \
@@ -139,19 +167,17 @@
 	-I$(top_srcdir)/dep/anitomy \
 	-I$(top_srcdir)/dep
 
-minori_CPPFLAGS = $(minori_includes) @QT_CXXFLAGS@ @LIBCURL_CPPFLAGS@
-minori_CXXFLAGS = $(cflags_glib) $(cflags_win) $(cflags_osx)
+minori_CPPFLAGS = @LIBCURL_CPPFLAGS@ $(minori_includes)
+minori_CXXFLAGS = @QT_CXXFLAGS@ $(cflags_osx) $(cflags_glib) $(cflags_win) -std=c++17
+minori_LDFLAGS = $(ldflags_osx) $(ldflags_win)
 
 minori_DEPENDENCIES = dep/pugixml/libpugixml.la dep/animia/libanimia.la dep/anitomy/libanitomy.la
-minori_LDADD = $(libs_glib) $(libs_osx) @LIBCURL@ @QT_LIBS@ dep/pugixml/libpugixml.la dep/animia/libanimia.la dep/anitomy/libanitomy.la
-
-.qrc_qrc.cc:
-	
+minori_LDADD = $(libs_glib) $(libs_osx) $(libs_win) @LIBCURL@ @QT_LIBS@ dep/pugixml/libpugixml.la dep/animia/libanimia.la dep/anitomy/libanitomy.la
 
 .h_moc.cc:
 	@MKDIR_P@ -- `dirname $@`
 	@QT_MOC@ -o $@ $(minori_includes) $<
 
-SUFFIXES = .h _moc.cc .qrc _qrc.cc
+SUFFIXES = .h _moc.cc .ts .qm
 SUBDIRS = $(subdirs)
 ACLOCAL_AMFLAGS = -I m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,4 @@
+Minori is a cross-platform Taiga clone built with Qt.
+
+For instructions on installing, view INSTALL. For documentation,
+view the docs/ directory.
\ No newline at end of file
--- a/README.md	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Minori
-A cross-platform Taiga clone.
--- a/configure.ac	Wed Jan 24 20:18:14 2024 -0500
+++ b/configure.ac	Wed Jan 24 20:18:59 2024 -0500
@@ -2,6 +2,7 @@
 
 AC_CANONICAL_HOST
 
+AC_CONFIG_SUBDIRS([dep/pugixml dep/animia dep/anitomy])
 AC_CONFIG_SRCDIR([src/main.cc])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIRS([m4])
@@ -9,9 +10,11 @@
 AM_INIT_AUTOMAKE([-Wall -Wportability foreign subdir-objects])
 
 # Do we have a C++17 compiler
+: ${CXXFLAGS=""}
 AC_PROG_CXX
-AX_CXX_COMPILE_STDCXX(17, noext, mandatory)
+AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
 
+# Init libtool
 AM_PROG_AR
 LT_INIT
 
@@ -26,7 +29,7 @@
 AC_PROG_MKDIR_P
 
 # libcurl?
-LIBCURL_CHECK_CONFIG(yes, 7.7.2, [have_libcurl=yes], [have_libcurl=no])
+LIBCURL_CHECK_CONFIG([yes], [7.7.2], [have_libcurl=yes], [have_libcurl=no])
 
 if test "x$have_libcurl" = "xno"; then
 	AC_MSG_ERROR([*** libcurl not found.])
@@ -58,7 +61,7 @@
 		# Everything else
 		AC_SUBST([GIO_CFLAGS])
 		AC_SUBST([GIO_LIBS])
-		PKG_CHECK_MODULES(GIO, gio-2.0, [build_glib=yes], [])
+		PKG_CHECK_MODULES([GIO], [gio-2.0], [build_glib=yes], [])
 		;;
 esac
 
@@ -67,7 +70,5 @@
 AM_CONDITIONAL([BUILD_GLIB], [test "x$build_glib" = "xyes"])
 AM_CONDITIONAL([BUILD_WINDRES], [test "x$WINDRES" != "x"])
 
-AC_CONFIG_SUBDIRS([dep/pugixml dep/animia dep/anitomy])
-
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
--- a/dep/animia/Makefile.am	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/animia/Makefile.am	Wed Jan 24 20:18:59 2024 -0500
@@ -7,8 +7,8 @@
 
 if BUILD_OSX
 files_osx = src/fd/xnu.cc src/win/quartz.cc src/util/osx.cc
-cflags_osx =
-libs_osx = Foundation CoreGraphics AppKit objc
+libs_osx = -lobjc
+ldflags_osx = -framework Foundation -framework CoreGraphics -framework ApplicationServices
 endif
 
 if BUILD_LINUX
@@ -57,9 +57,8 @@
 
 libanimia_la_CPPFLAGS = -I$(top_srcdir)/include @DEFS@
 
-libanimia_la_LDFLAGS = -version-info 0:0:0
-
-libanimia_la_CXXFLAGS = $(cflags_osx) $(cflags_x11) $(cflags_wayland)
+libanimia_la_CXXFLAGS = -std=c++17 $(cflags_osx) $(cflags_x11) $(cflags_wayland)
+libanimia_la_LDFLAGS = -version-info 0:0:0 $(ldflags_osx)
 
 libanimia_la_LIBADD = $(libs_wayland) $(libs_x11) $(libs_osx) $(libs_libutil) $(libs_libkvm)
 
--- a/dep/animia/include/animia/util/osx.h	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/animia/include/animia/util/osx.h	Wed Jan 24 20:18:59 2024 -0500
@@ -5,14 +5,10 @@
 #include <string>
 #include <cstdint>
 
-#ifdef HAVE_COREFOUNDATION
 #include <CoreFoundation/CoreFoundation.h>
-#endif
 
 namespace animia::internal::osx::util {
 
-#ifdef HAVE_COREFOUNDATION
-
 template<typename T>
 bool GetCFNumber(CFNumberRef num, T& result) {
 	if (!num)
@@ -28,8 +24,6 @@
 
 bool StringFromCFString(CFStringRef string, std::string& result);
 
-#endif // HAVE_COREFOUNDATION
-
 bool GetProcessName(pid_t pid, std::string& result);
 
 }
--- a/dep/animia/src/fd/proc.cc	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/animia/src/fd/proc.cc	Wed Jan 24 20:18:59 2024 -0500
@@ -7,8 +7,6 @@
 #include <sstream>
 #include <string>
 
-#include <iostream>
-
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
--- a/dep/animia/src/util/osx.cc	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/animia/src/util/osx.cc	Wed Jan 24 20:18:59 2024 -0500
@@ -8,7 +8,6 @@
 
 namespace animia::internal::osx::util {
 
-#ifdef HAVE_COREFOUNDATION
 /* all of these LaunchServices things use *internal functions* that are subject
  * to change. Granted, it's not very likely that these will change very much
  * because I'm fairly sure Apple uses them lots in their own internal code.
@@ -104,7 +103,6 @@
 
 	return true;
 }
-#endif // HAVE_COREFOUNDATION
 
 static bool GetProcessArgs(pid_t pid, std::string& args) {
 	/* sysctl shouldn't touch these, so we define them as const */
--- a/dep/animia/src/win/quartz.cc	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/animia/src/win/quartz.cc	Wed Jan 24 20:18:59 2024 -0500
@@ -2,8 +2,7 @@
  * win/quartz.cc: support for macOS (the Quartz Compositor)
  *
  * This file does not require an Objective-C++ compiler,
- * but it *does* require an Objective-C runtime and linking
- * with AppKit in order to receive proper window titles.
+ * but it *does* require an Objective-C runtime.
 */
 #include "animia/win/quartz.h"
 #include "animia/util/osx.h"
@@ -14,51 +13,50 @@
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreGraphics/CoreGraphics.h>
+#include <ApplicationServices/ApplicationServices.h>
 
 namespace animia::internal::quartz {
 
+/* all of these LaunchServices things use *internal functions* that are subject
+ * to change. Granted, it's not very likely that these will change very much
+ * because I'm fairly sure Apple uses them lots in their own internal code.
+*/
+#if __LP64__
+typedef long NSInteger;
+#else
+typedef int NSInteger;
+#endif
+typedef int CGSConnection;
+
+typedef CGSConnection (*CGSDefaultConnectionForThreadSpec)(void);
+typedef CGError (*CGSCopyWindowPropertySpec)(const CGSConnection, NSInteger, CFStringRef, CFStringRef*);
+
+static CGSDefaultConnectionForThreadSpec CGSDefaultConnectionForThread = nullptr;
+static CGSCopyWindowPropertySpec CGSCopyWindowProperty = nullptr;
+
+static const CFStringRef kCoreGraphicsBundleID = CFSTR("com.apple.CoreGraphics");
+
+/* Objective-C */
 typedef id (*object_message_send)(id, SEL, ...);
 typedef id (*class_message_send)(Class, SEL, ...);
 
 static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend);
 static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend);
 
-static bool GetWindowTitle(unsigned int wid, std::string& result) {
-	// NSApplication* app = [NSApplication sharedApplication];
-	const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
-
-	// NSWindow* window = [app windowWithWindowNumber: wid];
-	const id window = obj_send(app, sel_getUid("windowWithWindowNumber:"), wid);
-	if (!window)
-		return false;
-
-	// NSString* title = [window title];
-	const CFStringRef title = reinterpret_cast<CFStringRef>(obj_send(window, sel_getUid("title")));
-	if (!title)
+static bool GetCoreGraphicsPrivateSymbols() {
+	CFBundleRef core_graphics_bundle = CFBundleGetBundleWithIdentifier(kCoreGraphicsBundleID);
+	if (!core_graphics_bundle)
 		return false;
 
-	// return [title UTF8String];
-	return osx::util::StringFromCFString(title, result);
-}
-
-static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {
-	/* The Bundle ID is essentially OS X's solution to Windows'
-	 * "class name"; theoretically, it should be different for
-	 * each program, although it requires an app bundle.
-	*/
-
-	// NSRunningApplication* app = [NSRunningApplication runningApplicationWithProcessIdentifier: pid];
-	const id app = cls_send(objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid);
-	if (!app)
+	CGSDefaultConnectionForThread = (CGSDefaultConnectionForThreadSpec)CFBundleGetFunctionPointerForName(core_graphics_bundle, CFSTR("CGSDefaultConnectionForThread"));
+	if (!CGSDefaultConnectionForThread)
 		return false;
 
-	// NSString* bundle_id = [app bundleIdentifier];
-	const CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier")));
-	if (!bundle_id)
+	CGSCopyWindowProperty = (CGSCopyWindowPropertySpec)CFBundleGetFunctionPointerForName(core_graphics_bundle, CFSTR("CGSCopyWindowProperty"));
+	if (!CGSCopyWindowProperty)
 		return false;
 
-	// return [bundle_id UTF8String];
-	return osx::util::StringFromCFString(bundle_id, result);
+	return true;
 }
 
 template<typename T>
@@ -77,11 +75,110 @@
 	return true;
 }
 
+static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) {
+	CGRect bounds = {0};
+	{
+		const CGWindowID wids[1] = {wid};
+		CFArrayRef arr = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)wids, 1, NULL);
+
+		CFArrayRef dicts = CGWindowListCreateDescriptionFromArray(arr);
+
+		CFRelease(arr);
+
+		if (!dicts || CFArrayGetCount(dicts) < 1)
+			return false;
+
+		CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(dicts, 0);
+		if (!dict) {
+			CFRelease(dicts);
+			return false;
+		}
+
+		CFDictionaryRef bounds_dict = nullptr;
+		if (!CFDictionaryGetValueIfPresent(dict, kCGWindowBounds, reinterpret_cast<CFTypeRef*>(&bounds_dict)) || !bounds_dict) {
+			CFRelease(dicts);
+			return false;
+		}
+
+		if (!CGRectMakeWithDictionaryRepresentation(bounds_dict, &bounds)) {
+			CFRelease(dicts);
+			return false;
+		}
+
+		CFRelease(dicts);
+	}
+
+	/* now we can actually do stuff */
+	AXUIElementRef axapp = AXUIElementCreateApplication(pid);
+	CFArrayRef windows;
+	if ((AXUIElementCopyAttributeValue(axapp, kAXWindowsAttribute, (CFTypeRef*)&windows) != kAXErrorSuccess) || !windows)
+		return false;
+
+	const CFIndex count = CFArrayGetCount(windows);
+	for (CFIndex i = 0; i < count; i++) {
+		const AXUIElementRef window = (AXUIElementRef)CFArrayGetValueAtIndex(windows, i);
+
+		AXValueRef val;
+		if (AXUIElementCopyAttributeValue(window, kAXPositionAttribute, (CFTypeRef*)&val) == kAXErrorSuccess) {
+			CGPoint point;
+			if (!AXValueGetValue(val, kAXValueTypeCGPoint, (void*)&point) || (point.x != bounds.origin.x || point.y != bounds.origin.y))
+				continue;
+		} else continue;
+
+		if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, (CFTypeRef*)&val) == kAXErrorSuccess) {
+			CGSize size;
+			if (!AXValueGetValue(val, kAXValueTypeCGSize, (void*)&size) || (size.width != bounds.size.width || size.height != bounds.size.height))
+				continue;
+		} else continue;
+
+		CFStringRef title;
+		if (AXUIElementCopyAttributeValue(window, kAXTitleAttribute, (CFTypeRef*)&title) == kAXErrorSuccess) {
+			CFRelease(windows);
+			return osx::util::StringFromCFString(title, result);
+		}
+	}
+
+	CFRelease(windows);
+
+	return false;
+}
+
+static bool GetWindowTitle(unsigned int wid, pid_t pid, std::string& result) {
+	/* private internal OS X functions */
+	if ((CGSDefaultConnectionForThread && CGSCopyWindowProperty) || GetCoreGraphicsPrivateSymbols()) {
+		CFStringRef title = nullptr;
+
+		CGSCopyWindowProperty(CGSDefaultConnectionForThread(), wid, CFSTR("kCGSWindowTitle"), &title);
+		if (title && CFStringGetLength(title) && osx::util::StringFromCFString(title, result))
+			return true;
+	}
+
+	/* don't attempt to use accessibility if we aren't trusted */
+	return AXIsProcessTrusted() ? GetWindowTitleAccessibility(wid, pid, result) : false;
+}
+
+static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {
+	/* The Bundle ID is essentially OS X's solution to Windows'
+	 * "class name"; theoretically, it should be different for
+	 * each program, although it requires an app bundle.
+	*/
+	const id app = cls_send(objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid);
+	if (!app)
+		return false;
+
+	CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier")));
+	if (!bundle_id)
+		return false;
+
+	result = osx::util::StringFromCFString(bundle_id, result);
+	return true;
+}
+
 bool EnumerateWindows(window_proc_t window_proc) {
 	if (!window_proc)
 		return false;
 
-	const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
+	const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
 	if (!windows)
 		return false;
 
@@ -102,13 +199,12 @@
 		{
 			CFDictionaryGetValue(window, CFSTR("kCGWindowNumber"), win.id);
 
-			if (!GetProcessBundleIdentifier(proc.pid, win.class_name)) {
+			if (!GetProcessBundleIdentifier(proc.pid, win.class_name))
 				// Fallback to the Quartz window name, which is unlikely to be filled, but it
 				// *could* be.
 				CFDictionaryGetValue(window, CFSTR("kCGWindowName"), win.class_name);
-			}
 
-			GetWindowTitle(win.id, win.text);
+			GetWindowTitle(win.id, proc.pid, win.text);
 		}
 
 		if (!window_proc(proc, win)) {
--- a/dep/anitomy/Makefile.am	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/anitomy/Makefile.am	Wed Jan 24 20:18:59 2024 -0500
@@ -19,4 +19,5 @@
 	anitomy/token.h	\
 	anitomy/tokenizer.h
 
+libanitomy_la_CXXFLAGS = -std=c++17
 ACLOCAL_AMFLAGS = -I m4
\ No newline at end of file
--- a/dep/pugixml/Makefile.am	Wed Jan 24 20:18:14 2024 -0500
+++ b/dep/pugixml/Makefile.am	Wed Jan 24 20:18:59 2024 -0500
@@ -2,4 +2,5 @@
 libpugixml_la_SOURCES = src/pugixml.cpp
 include_HEADERS = src/pugixml.hpp
 
+libpugixml_la_CXXFLAGS = -std=c++11
 ACLOCAL_AMFLAGS = -I m4
--- a/include/sys/osx/dark_theme.h	Wed Jan 24 20:18:14 2024 -0500
+++ b/include/sys/osx/dark_theme.h	Wed Jan 24 20:18:59 2024 -0500
@@ -11,4 +11,4 @@
 
 } // namespace osx
 
-#endif // __sys__osx__dark_theme_h
\ No newline at end of file
+#endif // __sys__osx__dark_theme_h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/sys/osx/permissions.h	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,10 @@
+#ifndef __sys__osx__permissions_h
+#define __sys__osx__permissions_h
+
+namespace osx {
+
+bool AskForPermissions();
+
+} // namespace osx
+
+#endif // __sys__osx__permissions_h
--- a/m4/libcurl.m4	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-#***************************************************************************
-#                                  _   _ ____  _
-#  Project                     ___| | | |  _ \| |
-#                             / __| | | | |_) | |
-#                            | (__| |_| |  _ <| |___
-#                             \___|\___/|_| \_\_____|
-#
-# Copyright (C) David Shaw <dshaw@jabberwocky.com>
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-# SPDX-License-Identifier: curl
-#
-###########################################################################
-# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
-#                       [ACTION-IF-YES], [ACTION-IF-NO])
-# ----------------------------------------------------------
-#      David Shaw <dshaw@jabberwocky.com>   May-09-2006
-#
-# Checks for libcurl.  DEFAULT-ACTION is the string yes or no to
-# specify whether to default to --with-libcurl or --without-libcurl.
-# If not supplied, DEFAULT-ACTION is yes.  MINIMUM-VERSION is the
-# minimum version of libcurl to accept.  Pass the version as a regular
-# version number like 7.10.1. If not supplied, any version is
-# accepted.  ACTION-IF-YES is a list of shell commands to run if
-# libcurl was successfully found and passed the various tests.
-# ACTION-IF-NO is a list of shell commands that are run otherwise.
-# Note that using --without-libcurl does run ACTION-IF-NO.
-#
-# This macro #defines HAVE_LIBCURL if a working libcurl setup is
-# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
-# values.  Other useful defines are LIBCURL_FEATURE_xxx where xxx are
-# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
-# where yyy are the various protocols supported by libcurl.  Both xxx
-# and yyy are capitalized.  See the list of AH_TEMPLATEs at the top of
-# the macro for the complete list of possible defines.  Shell
-# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
-# defined to 'yes' for those features and protocols that were found.
-# Note that xxx and yyy keep the same capitalization as in the
-# curl-config list (e.g. it's "HTTP" and not "http").
-#
-# Users may override the detected values by doing something like:
-# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
-#
-# For the sake of sanity, this macro assumes that any libcurl that is found is
-# after version 7.7.2, the first version that included the curl-config script.
-# Note that it is important for people packaging binary versions of libcurl to
-# include this script!  Without curl-config, we can only guess what protocols
-# are available, or use curl_version_info to figure it out at runtime.
-
-AC_DEFUN([LIBCURL_CHECK_CONFIG],
-[
-  AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
-  AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
-  AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
-  AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
-  AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
-  AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
-  AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
-  AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
-
-  AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP])
-  AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP])
-
-  AC_ARG_WITH(libcurl,
-     AS_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
-     [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
-
-  if test "$_libcurl_with" != "no" ; then
-
-     AC_PROG_AWK
-
-     _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
-
-     _libcurl_try_link=yes
-
-     if test -d "$_libcurl_with" ; then
-        LIBCURL_CPPFLAGS="-I$withval/include"
-        _libcurl_ldflags="-L$withval/lib"
-        AC_PATH_PROG([_libcurl_config],[curl-config],[],
-                     ["$withval/bin"])
-     else
-        AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH])
-     fi
-
-     if test x$_libcurl_config != "x" ; then
-        AC_CACHE_CHECK([for the version of libcurl],
-           [libcurl_cv_lib_curl_version],
-           [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
-
-        _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
-        _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
-
-        if test $_libcurl_wanted -gt 0 ; then
-           AC_CACHE_CHECK([for libcurl >= version $2],
-              [libcurl_cv_lib_version_ok],
-              [
-              if test $_libcurl_version -ge $_libcurl_wanted ; then
-                 libcurl_cv_lib_version_ok=yes
-              else
-                 libcurl_cv_lib_version_ok=no
-              fi
-              ])
-        fi
-
-        if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
-           if test x"$LIBCURL_CPPFLAGS" = "x" ; then
-              LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
-           fi
-           if test x"$LIBCURL" = "x" ; then
-              LIBCURL=`$_libcurl_config --libs`
-
-              # This is so silly, but Apple actually has a bug in their
-              # curl-config script.  Fixed in Tiger, but there are still
-              # lots of Panther installs around.
-              case "${host}" in
-                 powerpc-apple-darwin7*)
-                    LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
-                 ;;
-              esac
-           fi
-
-           # All curl-config scripts support --feature
-           _libcurl_features=`$_libcurl_config --feature`
-
-           # Is it modern enough to have --protocols? (7.12.4)
-           if test $_libcurl_version -ge 461828 ; then
-              _libcurl_protocols=`$_libcurl_config --protocols`
-           fi
-        else
-           _libcurl_try_link=no
-        fi
-
-        unset _libcurl_wanted
-     fi
-
-     if test $_libcurl_try_link = yes ; then
-
-        # we did not find curl-config, so let's see if the user-supplied
-        # link line (or failing that, "-lcurl") is enough.
-        LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
-
-        AC_CACHE_CHECK([whether libcurl is usable],
-           [libcurl_cv_lib_curl_usable],
-           [
-           _libcurl_save_cppflags=$CPPFLAGS
-           CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
-           _libcurl_save_libs=$LIBS
-           LIBS="$LIBCURL $LIBS"
-
-           AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[
-/* Try and use a few common options to force a failure if we are
-   missing symbols or cannot link. */
-int x;
-curl_easy_setopt(NULL,CURLOPT_URL,NULL);
-x=CURL_ERROR_SIZE;
-x=CURLOPT_WRITEFUNCTION;
-x=CURLOPT_WRITEDATA;
-x=CURLOPT_ERRORBUFFER;
-x=CURLOPT_STDERR;
-x=CURLOPT_VERBOSE;
-if (x) {;}
-]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
-
-           CPPFLAGS=$_libcurl_save_cppflags
-           LIBS=$_libcurl_save_libs
-           unset _libcurl_save_cppflags
-           unset _libcurl_save_libs
-           ])
-
-        if test $libcurl_cv_lib_curl_usable = yes ; then
-
-           # Does curl_free() exist in this version of libcurl?
-           # If not, fake it with free()
-
-           _libcurl_save_cppflags=$CPPFLAGS
-           CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
-           _libcurl_save_libs=$LIBS
-           LIBS="$LIBS $LIBCURL"
-
-           AC_CHECK_DECL([curl_free],[],
-              [AC_DEFINE([curl_free],[free],
-                [Define curl_free() as free() if our version of curl lacks curl_free.])],
-              [[#include <curl/curl.h>]])
-
-           CPPFLAGS=$_libcurl_save_cppflags
-           LIBS=$_libcurl_save_libs
-           unset _libcurl_save_cppflags
-           unset _libcurl_save_libs
-
-           AC_DEFINE(HAVE_LIBCURL,1,
-             [Define to 1 if you have a functional curl library.])
-           AC_SUBST(LIBCURL_CPPFLAGS)
-           AC_SUBST(LIBCURL)
-
-           for _libcurl_feature in $_libcurl_features ; do
-              AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
-              eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
-           done
-
-           if test "x$_libcurl_protocols" = "x" ; then
-
-              # We do not have --protocols, so just assume that all
-              # protocols are available
-              _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP"
-
-              if test x$libcurl_feature_SSL = xyes ; then
-                 _libcurl_protocols="$_libcurl_protocols HTTPS"
-
-                 # FTPS was not standards-compliant until version
-                 # 7.11.0 (0x070b00 == 461568)
-                 if test $_libcurl_version -ge 461568; then
-                    _libcurl_protocols="$_libcurl_protocols FTPS"
-                 fi
-              fi
-
-              # RTSP, IMAP, POP3 and SMTP were added in
-              # 7.20.0 (0x071400 == 463872)
-              if test $_libcurl_version -ge 463872; then
-                 _libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP"
-              fi
-           fi
-
-           for _libcurl_protocol in $_libcurl_protocols ; do
-              AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
-              eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
-           done
-        else
-           unset LIBCURL
-           unset LIBCURL_CPPFLAGS
-        fi
-     fi
-
-     unset _libcurl_try_link
-     unset _libcurl_version_parse
-     unset _libcurl_config
-     unset _libcurl_feature
-     unset _libcurl_features
-     unset _libcurl_protocol
-     unset _libcurl_protocols
-     unset _libcurl_version
-     unset _libcurl_ldflags
-  fi
-
-  if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
-     # This is the IF-NO path
-     ifelse([$4],,:,[$4])
-  else
-     # This is the IF-YES path
-     ifelse([$3],,:,[$3])
-  fi
-
-  unset _libcurl_with
-])
--- a/m4/m4_ax_have_qt.m4	Wed Jan 24 20:18:14 2024 -0500
+++ b/m4/m4_ax_have_qt.m4	Wed Jan 24 20:18:59 2024 -0500
@@ -49,6 +49,7 @@
 #
 #   Copyright (c) 2008 Bastiaan Veelo <Bastiaan@Veelo.net>
 #   Copyright (c) 2014 Alex Henrie <alexhenrie24@gmail.com>
+#   Copyright (c) 2024 Paper <mrpapersonic@gmail.com>
 #
 #   Copying and distribution of this file, with or without modification, are
 #   permitted in any medium without royalty provided the copyright notice
@@ -60,187 +61,208 @@
 AU_ALIAS([BNV_HAVE_QT], [AX_HAVE_QT])
 AC_DEFUN([AX_HAVE_QT],
 [
-  AC_REQUIRE([AC_PROG_CXX])
-  AC_REQUIRE([AC_PATH_X])
-  AC_REQUIRE([AC_PATH_XTRA])
-  # openSUSE leap 15.3 installs qmake-qt5, not qmake, for example.
-  # Store the full name (like qmake-qt5) into QMAKE
-  # and the specifier (like -qt5 or empty) into am_have_qt_qmexe_suff.
-  AC_ARG_VAR([QMAKE],"Qt make tool")
-  AC_CHECK_TOOLS([QMAKE],[qmake qmake-qt6 qmake-qt5],[false])
+	AC_REQUIRE([AC_PROG_CXX])
+	AC_REQUIRE([AC_PATH_X])
+	AC_REQUIRE([AC_PATH_XTRA])
+	# openSUSE leap 15.3 installs qmake-qt5, not qmake, for example.
+	# Store the full name (like qmake-qt5) into QMAKE
+	# and the specifier (like -qt5 or empty) into am_have_qt_qmexe_suff.
+	AC_ARG_VAR([QMAKE],"Qt make tool")
+	AC_CHECK_TOOLS([QMAKE],[qmake qmake-qt6 qmake-qt5],[false])
 
-  AC_MSG_CHECKING(for Qt)
-  am_have_qt_qmexe_suff=`echo $QMAKE | sed 's,^.*qmake,,'`
-  # If we have Qt5 or later in the path, we're golden
-  ver=`$QMAKE --version | grep -o "Qt version ."`
+	AC_MSG_CHECKING(for Qt)
+	am_have_qt_qmexe_suff=`echo $QMAKE | sed 's,^.*qmake,,'`
+	# If we have Qt5 or later in the path, we're golden
+	ver=`$QMAKE --version | grep -o "Qt version ."`
 
-  if test "$ver" ">" "Qt version 4"; then
-    have_qt=yes
-    # This pro file dumps qmake's variables, but it only works on Qt 5 or later
-    am_have_qt_dir=`mktemp -d`
-    am_have_qt_pro="$am_have_qt_dir/test.pro"
-    am_have_qt_stash="$am_have_qt_dir/.qmake.stash"
-    am_have_qt_makefile="$am_have_qt_dir/Makefile"
-    # http://qt-project.org/doc/qt-5/qmake-variable-reference.html#qt
-    cat > $am_have_qt_pro << EOF
+	if test "$ver" ">" "Qt version 4"; then
+		have_qt=yes
+		# This pro file dumps qmake's variables, but it only works on Qt 5 or later
+		am_have_qt_dir=`mktemp -d`
+		am_have_qt_pro="$am_have_qt_dir/test.pro"
+		am_have_qt_stash="$am_have_qt_dir/.qmake.stash"
+		am_have_qt_makefile="$am_have_qt_dir/Makefile"
+		# http://qt-project.org/doc/qt-5/qmake-variable-reference.html#qt
+		cat > $am_have_qt_pro << EOF
 win32 {
-    CONFIG -= debug_and_release
-    CONFIG += release
+		CONFIG -= debug_and_release
+		CONFIG += release
 }
-qtHaveModule(axcontainer):       QT += axcontainer
-qtHaveModule(axserver):          QT += axserver
-qtHaveModule(concurrent):        QT += concurrent
+
+CONFIG += sdk_no_version_check
+
+# use absolute paths, useful on windows
+# where qmake really loves giving relative paths
+QMAKE_PROJECT_DEPTH = 0
+
+# commented out all the modules we don't use
+#qtHaveModule(axcontainer):       QT += axcontainer
+#qtHaveModule(axserver):          QT += axserver
+#qtHaveModule(concurrent):        QT += concurrent
 qtHaveModule(core):              QT += core
-qtHaveModule(dbus):              QT += dbus
-qtHaveModule(declarative):       QT += declarative
-qtHaveModule(designer):          QT += designer
+#qtHaveModule(dbus):              QT += dbus
+#qtHaveModule(declarative):       QT += declarative
+#qtHaveModule(designer):          QT += designer
 qtHaveModule(gui):               QT += gui
-qtHaveModule(help):              QT += help
-qtHaveModule(multimedia):        QT += multimedia
-qtHaveModule(multimediawidgets): QT += multimediawidgets
-qtHaveModule(network):           QT += network
-qtHaveModule(opengl):            QT += opengl
-qtHaveModule(printsupport):      QT += printsupport
-qtHaveModule(qml):               QT += qml
-qtHaveModule(qmltest):           QT += qmltest
-qtHaveModule(x11extras):         QT += x11extras
-qtHaveModule(script):            QT += script
-qtHaveModule(scripttools):       QT += scripttools
-qtHaveModule(sensors):           QT += sensors
-qtHaveModule(serialport):        QT += serialport
-qtHaveModule(sql):               QT += sql
-qtHaveModule(svg):               QT += svg
-qtHaveModule(testlib):           QT += testlib
-qtHaveModule(uitools):           QT += uitools
-qtHaveModule(webkit):            QT += webkit
-qtHaveModule(webkitwidgets):     QT += webkitwidgets
-qtHaveModule(xml):               QT += xml
-qtHaveModule(xmlpatterns):       QT += xmlpatterns
+#qtHaveModule(help):              QT += help
+#qtHaveModule(multimedia):        QT += multimedia
+#qtHaveModule(multimediawidgets): QT += multimediawidgets
+#qtHaveModule(network):           QT += network
+#qtHaveModule(opengl):            QT += opengl
+#qtHaveModule(printsupport):      QT += printsupport
+#qtHaveModule(qml):               QT += qml
+#qtHaveModule(qmltest):           QT += qmltest
+#qtHaveModule(x11extras):         QT += x11extras
+#qtHaveModule(script):            QT += script
+#qtHaveModule(scripttools):       QT += scripttools
+#qtHaveModule(sensors):           QT += sensors
+#qtHaveModule(serialport):        QT += serialport
+#qtHaveModule(sql):               QT += sql
+#qtHaveModule(svg):               QT += svg
+#qtHaveModule(testlib):           QT += testlib
+#qtHaveModule(uitools):           QT += uitools
+#qtHaveModule(webkit):            QT += webkit
+#qtHaveModule(webkitwidgets):     QT += webkitwidgets
+#qtHaveModule(xml):               QT += xml
+#qtHaveModule(xmlpatterns):       QT += xmlpatterns
+qtHaveModule(widgets):           QT += widgets
 percent.target = %
 percent.commands = @echo -n "\$(\$(@))\ "
 QMAKE_EXTRA_TARGETS += percent
 EOF
-    $QMAKE $am_have_qt_pro -o $am_have_qt_makefile
-    QT_CXXFLAGS=`cd $am_have_qt_dir; make -s -f $am_have_qt_makefile CXXFLAGS INCPATH`
-    QT_LIBS=`cd $am_have_qt_dir; make -s -f $am_have_qt_makefile LIBS`
-    rm $am_have_qt_pro $am_have_qt_stash $am_have_qt_makefile
-    rmdir $am_have_qt_dir
+		am_have_qt_makefile_cxxflags=`cat << EOF
+include $am_have_qt_makefile
+
+VAR:
+	@echo \\$(CXXFLAGS) \\$(INCPATH)
+EOF`
+		am_have_qt_makefile_libs=`cat << EOF
+include $am_have_qt_makefile
 
-    # Look for specific tools in $PATH
-    QT_MOC=`which moc$am_have_qt_qmexe_suff`
-    QT_UIC=`which uic$am_have_qt_qmexe_suff`
-    QT_RCC=`which rcc$am_have_qt_qmexe_suff`
-    QT_LRELEASE=`which lrelease$am_have_qt_qmexe_suff`
-    QT_LUPDATE=`which lupdate$am_have_qt_qmexe_suff`
+VAR:
+	@echo \\$(LIBS)
+EOF`
+		$QMAKE "$am_have_qt_pro" -o "$am_have_qt_makefile"
+		QT_CXXFLAGS=`cd $am_have_qt_dir; echo "\$am_have_qt_makefile_cxxflags" | make -s -f - VAR`
+		QT_LIBS=`cd $am_have_qt_dir; echo "\$am_have_qt_makefile_libs" | make -s -f - VAR`
+		rm $am_have_qt_pro $am_have_qt_stash $am_have_qt_makefile
+		rmdir $am_have_qt_dir
 
-    # Get Qt version from qmake
-    QT_DIR=`$QMAKE --version | grep -o -E /.+`
+		# Look for specific tools in $PATH
+		QT_MOC=`which moc$am_have_qt_qmexe_suff`
+		QT_UIC=`which uic$am_have_qt_qmexe_suff`
+		QT_RCC=`which rcc$am_have_qt_qmexe_suff`
+		QT_LRELEASE=`which lrelease$am_have_qt_qmexe_suff`
+		QT_LUPDATE=`which lupdate$am_have_qt_qmexe_suff`
+
+		# Get Qt version from qmake
+		QT_DIR=`$QMAKE --version | grep -o -E /.+`
 
-    # All variables are defined, report the result
-    AC_MSG_RESULT([$have_qt:
-    QT_CXXFLAGS=$QT_CXXFLAGS
-    QT_DIR=$QT_DIR
-    QT_LIBS=$QT_LIBS
-    QT_UIC=$QT_UIC
-    QT_MOC=$QT_MOC
-    QT_RCC=$QT_RCC
-    QT_LRELEASE=$QT_LRELEASE
-    QT_LUPDATE=$QT_LUPDATE])
-  else
-    # Qt was not found
-    have_qt=no
-    QT_CXXFLAGS=
-    QT_DIR=
-    QT_LIBS=
-    QT_UIC=
-    QT_MOC=
-    QT_RCC=
-    QT_LRELEASE=
-    QT_LUPDATE=
-    AC_MSG_RESULT($have_qt)
-  fi
-  AC_SUBST(QT_CXXFLAGS)
-  AC_SUBST(QT_DIR)
-  AC_SUBST(QT_LIBS)
-  AC_SUBST(QT_UIC)
-  AC_SUBST(QT_MOC)
-  AC_SUBST(QT_RCC)
-  AC_SUBST(QT_LRELEASE)
-  AC_SUBST(QT_LUPDATE)
-  AC_SUBST(QMAKE)
+		# All variables are defined, report the result
+		AC_MSG_RESULT([$have_qt:
+		QT_CXXFLAGS=$QT_CXXFLAGS
+		QT_DIR=$QT_DIR
+		QT_LIBS=$QT_LIBS
+		QT_UIC=$QT_UIC
+		QT_MOC=$QT_MOC
+		QT_RCC=$QT_RCC
+		QT_LRELEASE=$QT_LRELEASE
+		QT_LUPDATE=$QT_LUPDATE])
+	else
+		# Qt was not found
+		have_qt=no
+		QT_CXXFLAGS=
+		QT_DIR=
+		QT_LIBS=
+		QT_UIC=
+		QT_MOC=
+		QT_RCC=
+		QT_LRELEASE=
+		QT_LUPDATE=
+		AC_MSG_RESULT($have_qt)
+	fi
+	AC_SUBST(QT_CXXFLAGS)
+	AC_SUBST(QT_DIR)
+	AC_SUBST(QT_LIBS)
+	AC_SUBST(QT_UIC)
+	AC_SUBST(QT_MOC)
+	AC_SUBST(QT_RCC)
+	AC_SUBST(QT_LRELEASE)
+	AC_SUBST(QT_LUPDATE)
+	AC_SUBST(QMAKE)
 
-  #### Being paranoid:
-  if test x"$have_qt" = xyes; then
-    AC_MSG_CHECKING(correct functioning of Qt installation)
-    AC_CACHE_VAL(ax_cv_qt_test_result,
-    [
-      cat > ax_qt_test.h << EOF
+	#### Being paranoid:
+	if test x"$have_qt" = xyes; then
+		AC_MSG_CHECKING(correct functioning of Qt installation)
+		AC_CACHE_VAL(ax_cv_qt_test_result,
+		[
+			cat > ax_qt_test.h << EOF
 #include <qobject.h>
 class Test : public QObject
 {
 Q_OBJECT
 public:
-  Test() {}
-  ~Test() {}
+	Test() {}
+	~Test() {}
 public slots:
-  void receive() {}
+	void receive() {}
 signals:
-  void send();
+	void send();
 };
 EOF
 
-      cat > ax_qt_main.$ac_ext << EOF
+			cat > ax_qt_main.$ac_ext << EOF
 #include "ax_qt_test.h"
 #include <qapplication.h>
 int main( int argc, char **argv )
 {
-  QApplication app( argc, argv );
-  Test t;
-  QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) );
+	QApplication app( argc, argv );
+	Test t;
+	QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) );
 }
 EOF
 
-      ax_cv_qt_test_result="failure"
-      ax_try_1="$QT_MOC ax_qt_test.h -o moc_ax_qt_test.$ac_ext >/dev/null 2>/dev/null"
-      AC_TRY_EVAL(ax_try_1)
-      if test x"$ac_status" != x0; then
-        echo "$ax_err_1" >&AS_MESSAGE_LOG_FD
-        echo "configure: could not run $QT_MOC on:" >&AS_MESSAGE_LOG_FD
-        cat ax_qt_test.h >&AS_MESSAGE_LOG_FD
-      else
-        ax_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_ax_qt_test.o moc_ax_qt_test.$ac_ext >/dev/null 2>/dev/null"
-        AC_TRY_EVAL(ax_try_2)
-        if test x"$ac_status" != x0; then
-          echo "$ax_err_2" >&AS_MESSAGE_LOG_FD
-          echo "configure: could not compile:" >&AS_MESSAGE_LOG_FD
-          cat moc_ax_qt_test.$ac_ext >&AS_MESSAGE_LOG_FD
-        else
-          ax_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o ax_qt_main.o ax_qt_main.$ac_ext >/dev/null 2>/dev/null"
-          AC_TRY_EVAL(ax_try_3)
-          if test x"$ac_status" != x0; then
-            echo "$ax_err_3" >&AS_MESSAGE_LOG_FD
-            echo "configure: could not compile:" >&AS_MESSAGE_LOG_FD
-            cat ax_qt_main.$ac_ext >&AS_MESSAGE_LOG_FD
-          else
-            ax_try_4="$CXX -o ax_qt_main ax_qt_main.o moc_ax_qt_test.o $QT_LIBS $LIBS >/dev/null 2>/dev/null"
-            AC_TRY_EVAL(ax_try_4)
-            if test x"$ac_status" != x0; then
-              echo "$ax_err_4" >&AS_MESSAGE_LOG_FD
-            else
-              ax_cv_qt_test_result="success"
-            fi
-          fi
-        fi
-      fi
-    ])dnl AC_CACHE_VAL ax_cv_qt_test_result
-    AC_MSG_RESULT([$ax_cv_qt_test_result])
-    if test x"$ax_cv_qt_test_result" = "xfailure"; then
-      AC_MSG_ERROR([Failed to find matching components of a complete
-                  Qt installation. Try using more options,
-                  see ./configure --help.])
-    fi
+			ax_cv_qt_test_result="failure"
+			ax_try_1="$QT_MOC ax_qt_test.h -o moc_ax_qt_test.$ac_ext >/dev/null 2>/dev/null"
+			AC_TRY_EVAL(ax_try_1)
+			if test x"$ac_status" != x0; then
+				echo "$ax_err_1" >&AS_MESSAGE_LOG_FD
+				echo "configure: could not run $QT_MOC on:" >&AS_MESSAGE_LOG_FD
+				cat ax_qt_test.h >&AS_MESSAGE_LOG_FD
+			else
+				ax_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_ax_qt_test.o moc_ax_qt_test.$ac_ext >/dev/null 2>/dev/null"
+				AC_TRY_EVAL(ax_try_2)
+				if test x"$ac_status" != x0; then
+					echo "$ax_err_2" >&AS_MESSAGE_LOG_FD
+					echo "configure: could not compile:" >&AS_MESSAGE_LOG_FD
+					cat moc_ax_qt_test.$ac_ext >&AS_MESSAGE_LOG_FD
+				else
+					ax_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o ax_qt_main.o ax_qt_main.$ac_ext >/dev/null 2>/dev/null"
+					AC_TRY_EVAL(ax_try_3)
+					if test x"$ac_status" != x0; then
+						echo "$ax_err_3" >&AS_MESSAGE_LOG_FD
+						echo "configure: could not compile:" >&AS_MESSAGE_LOG_FD
+						cat ax_qt_main.$ac_ext >&AS_MESSAGE_LOG_FD
+					else
+						ax_try_4="$CXX -o ax_qt_main ax_qt_main.o moc_ax_qt_test.o $QT_LIBS $LIBS >/dev/null 2>/dev/null"
+						AC_TRY_EVAL(ax_try_4)
+						if test x"$ac_status" != x0; then
+							echo "$ax_err_4" >&AS_MESSAGE_LOG_FD
+						else
+							ax_cv_qt_test_result="success"
+						fi
+					fi
+				fi
+			fi
+		])dnl AC_CACHE_VAL ax_cv_qt_test_result
+		AC_MSG_RESULT([$ax_cv_qt_test_result])
+		if test x"$ax_cv_qt_test_result" = "xfailure"; then
+			AC_MSG_ERROR([Failed to find matching components of a complete
+						  Qt installation. Try using more options,
+						  see ./configure --help.])
+		fi
 
-    rm -f ax_qt_test.h moc_ax_qt_test.$ac_ext moc_ax_qt_test.o \
-          ax_qt_main.$ac_ext ax_qt_main.o ax_qt_main
-  fi
+		rm -f ax_qt_test.h moc_ax_qt_test.$ac_ext moc_ax_qt_test.o \
+					ax_qt_main.$ac_ext ax_qt_main.o ax_qt_main
+	fi
 ])
--- a/rc/dark.qrc	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<!DOCTYPE rcc><RCC version="1.0">
-	<qresource>
-		<file>dark.qss</file>
-	</qresource>
-</RCC>
--- a/rc/dark.qss	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,294 +0,0 @@
-/*
-Much of this is taken from the Breeze Style Sheets,
-which is under the MIT license:
-
-Copyright © `<2013-2014>` `<Colin Duquesnoy>`
-Copyright © `<2015-2016>` `<Alex Huszagh>`
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the “Software”), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-/* Colors should be the same as the QPalette in gui/theme.cc, i.e.:
-	window == darkgray == #353535;
-	??? == gray == #808080;
-	base == black == #191919;
-	highlighted == blue = #2A82DA;
-   We could include a preprocessor like sass to make these constants,
-   but that's really lame :(
-*/
-
-AnimeListPage::pane {
-	margin: 0.04em;
-	border: 0.04em solid #808080;
-	top: -0.04em;
-	left: -0.04em;
-}
-
-QTabWidget::pane:top {
-	border: 0.04em solid #808080;
-	top: -0.04em;
-}
-
-QTabWidget::pane:bottom {
-	border: 0.04em solid #808080;
-	bottom: -0.04em;
-}
-
-QTabWidget::pane:left {
-	border: 0.04em solid #808080;
-	left: -0.04em;
-}
-
-QTabWidget::pane:right {
-	border: 0.04em solid #808080;
-	right: -0.04em;
-}
-
-QTabBar {
-	qproperty-drawBase: 0;
-	left: 0.23em;
-	border-radius: 0.13em;
-	selection-color: transparent;
-}
-
-QTabBar:focus {
-	border: 0em transparent black;
-}
-
-QTabBar::tab:top,
-QTabBar::tab:top:last,
-QTabBar::tab:top:only-one {
-	color: white;
-	border: 0.04em transparent black;
-	border-left: 0.04em solid #808080;
-	border-right: 0.04em solid #808080;
-	border-top: 0.04em solid #808080;
-	background-color: #353535;
-	min-width: 50px;
-	padding-top: 0.23em;
-	padding-bottom: 0.23em;
-	padding-left: 0.78em;
-	padding-right: 0.78em;
-	border-radius: 0.09em;
-	border-bottom-left-radius: 0em;
-	border-bottom-right-radius: 0em;
-}
-
-QTabBar::tab:top:!selected {
-	color: white;
-	background-color: #353535;
-	border: 0.04em solid #808080;
-	border-radius: 0.09em;
-	border-bottom-left-radius: 0em;
-	border-bottom-right-radius: 0em;
-	margin-top: 0.13em;
-}
-
-QTabBar::tab:top:next-selected {
-	border-right: 0.04em transparent #353535;
-	border-bottom-left-radius: 0em;
-	border-bottom-right-radius: 0em;
-}
-
-QTabBar::tab:top:previous-selected {
-	border-left: 0.04em transparent #353535;
-	border-bottom-left-radius: 0em;
-	border-bottom-right-radius: 0em;
-}
-
-QTabBar::tab:top:!selected:hover {
-	background-color: rgba(42, 130, 218, 0.1);
-	border-radius: 0.09em;
-	border-bottom-left-radius: 0em;
-	border-bottom-right-radius: 0em;
-}
-
-QTabBar::tab:top:!selected:first:hover {
-	background-color: rgba(42, 130, 218, 0.1);
-}
-
-QGroupBox::title {
-	color: white;
-}
-
-QComboBox,
-QPushButton,
-QDateEdit,
-QSpinBox {
-	background-color: #353535;
-	color: white;
-}
-
-QComboBox,
-QDateEdit,
-QSpinBox {
-	border: 0.04em solid #808080;
-}
-
-QComboBox:disabled,
-QPushButton:disabled,
-QDateEdit:disabled,
-QSpinBox:disabled {
-	color: #808080;
-}
-
-QPushButton:hover {
-	background-color: #39424B;
-}
-
-/*
- * QLineEdit
- */
-
-QLineEdit {
-	background: transparent;
-	color: white;
-}
-
-QLineEdit:!read-only {
-	background-color: #191919;
-	padding: 0.23em;
-	border-style: solid;
-	border: 0.04em solid #808080;
-	border-radius: 0.09em;
-}
-
-/* QMenuBar */
-
-QMenuBar {
-	background-color: #353535;
-	color: white;
-}
-
-QMenuBar::item:selected {
-	background-color: #414141;
-}
-
-QMenuBar::item:disabled {
-	color: #808080;
-}
-
-QMenuBar::item:pressed {
-	background-color: #414141;
-	margin-bottom: -0.09em;
-	padding-bottom: 0.09em;
-}
-
-/* QMenu */
-
-QMenu {
-	color: white;
-	background-color: #353535;
-	padding: 0.18em 0.18em;
-	border: 0.09em solid #A0A0A0;
-}
-
-QMenu::icon {
-	margin: 0.23em;
-}
-
-QMenu::item {
-	/* Add extra padding on the right for the QMenu arrow */
-	padding: 0.23em 1.5em 0.23em 1.3em;
-	border: 0.09em solid transparent;
-	background: transparent;
-}
-
-QMenu::item:selected {
-	color: white;
-	background-color: #414141;
-}
-
-QMenu::item:selected:disabled {
-	background-color: #353535;
-}
-
-QMenu::item:disabled {
-	color: #808080;
-}
-
-QMenu::indicator {
-	width: 0.8em;
-	height: 0.8em;
-	/* To align with QMenu::icon, which has a 0.23em margin. */
-	margin-left: 0.3em;
-	subcontrol-position: center left;
-}
-
-/*
- * QHeaderView:
- * Need this for the anime list, on Windows it gets screwed up.
-*/
-
-QHeaderView {
-	background-color: #353535;
-	border: 0.04em transparent;
-	border-radius: 0em;
-	margin: 0em;
-	padding: 0em;
-}
-
-QHeaderView::section {
-	background-color: #353535;
-	border: 0.04em solid #808080;
-	color: #eff0f1;
-	border-radius: 0em;
-	padding: 0em 0.23em 0em 0.23em;
-	text-align: center;
-}
-
-QHeaderView::section::vertical::first,
-QHeaderView::section::vertical::only-one {
-	border-top: 0.04em solid #808080;
-}
-
-QHeaderView::section::vertical {
-	border-top: transparent;
-}
-
-QHeaderView::section::horizontal::first,
-QHeaderView::section::horizontal::only-one {
-	border-left: 0.04em solid #808080;
-}
-
-QHeaderView::section::horizontal {
-	border-left: transparent;
-}
-
-QHeaderView[showSortIndicator="true"]::section::horizontal {
-	/* Same as the width of the arrow subcontrols below. */
-	padding-right: 0.8em;
-}
-
-QHeaderView::section:checked {
-	color: white;
-	background-color: #808080;
-}
-
-/* Note that this doesn't work for QTreeView unless the header is clickable */
-QHeaderView::section:hover,
-QHeaderView::section::horizontal::first:hover,
-QHeaderView::section::horizontal::only-one:hover,
-QHeaderView::section::vertical::first:hover,
-QHeaderView::section::vertical::only-one:hover {
-	background-color: #353535;
-}
Binary file rc/favicon.png has changed
Binary file rc/favicon256.png has changed
--- a/rc/icons.qrc	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-<!DOCTYPE rcc><RCC version="1.0">
-	<qresource>
-		<file>favicon.png</file>
-		<file>icons/16x16/arrow-circle-315.png</file>
-		<file>icons/16x16/calendar.png</file>
-		<file>icons/16x16/chart.png</file>
-		<file>icons/16x16/clock-history-frame.png</file>
-		<file>icons/16x16/cross-button.png</file>
-		<file>icons/16x16/document-list.png</file>
-		<file>icons/16x16/feed.png</file>
-		<file>icons/16x16/film.png</file>
-		<file>icons/16x16/gear.png</file>
-		<file>icons/16x16/magnifier.png</file>
-		<file>icons/16x16/navigation-270-button.png</file>
-		<file>icons/16x16/plus-button.png</file>
-		<file>icons/24x24/application-export.png</file>
-		<file>icons/24x24/application-sidebar-list.png</file>
-		<file>icons/24x24/arrow-circle-double-135.png</file>
-		<file>icons/24x24/feed.png</file>
-		<file>icons/24x24/folder-open.png</file>
-		<file>icons/24x24/gear.png</file>
-		<file>icons/24x24/globe.png</file>
-		<file>icons/24x24/inbox-film.png</file>
-		<file>icons/24x24/megaphone.png</file>
-		<file>icons/24x24/question.png</file>
-	</qresource>
-</RCC>
Binary file rc/icons/favicon.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/icons/icons.qrc	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,27 @@
+<!DOCTYPE rcc><RCC version="1.0">
+	<qresource prefix="icons/">
+		<file>favicon.png</file>
+		<file>16x16/arrow-circle-315.png</file>
+		<file>16x16/calendar.png</file>
+		<file>16x16/chart.png</file>
+		<file>16x16/clock-history-frame.png</file>
+		<file>16x16/cross-button.png</file>
+		<file>16x16/document-list.png</file>
+		<file>16x16/feed.png</file>
+		<file>16x16/film.png</file>
+		<file>16x16/gear.png</file>
+		<file>16x16/magnifier.png</file>
+		<file>16x16/navigation-270-button.png</file>
+		<file>16x16/plus-button.png</file>
+		<file>24x24/application-export.png</file>
+		<file>24x24/application-sidebar-list.png</file>
+		<file>24x24/arrow-circle-double-135.png</file>
+		<file>24x24/feed.png</file>
+		<file>24x24/folder-open.png</file>
+		<file>24x24/gear.png</file>
+		<file>24x24/globe.png</file>
+		<file>24x24/inbox-film.png</file>
+		<file>24x24/megaphone.png</file>
+		<file>24x24/question.png</file>
+	</qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/linux/Minori.desktop	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,24 @@
+[Desktop Entry]
+
+# The type as listed above
+Type=Application
+
+# The version of the desktop entry specification to which this file complies
+Version=1.4
+
+# The name of the application
+Name=Minori
+
+# A comment which can/will be used as a tooltip
+Comment=A lightweight anime tracker built with Qt.
+
+# Executable name
+Exec=minori
+
+# Favicon
+Icon=Minori
+
+# Describes whether this application needs to be run in a terminal or not
+Terminal=false
+
+Categories=Utility;Qt;
\ No newline at end of file
--- a/rc/linux/Minori.desktop.in	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-[Desktop Entry]
-
-# The type as listed above
-Type=Application
-
-# The version of the desktop entry specification to which this file complies
-Version=1.4
-
-# The name of the application
-Name=Minori
-
-# A comment which can/will be used as a tooltip
-Comment=@RC_INFO_STRING@
-
-# Executable name
-Exec=minori
-
-# Favicon
-Icon=Minori
-
-# Describes whether this application needs to be run in a terminal or not
-Terminal=false
-
-Categories=Utility;Qt;
\ No newline at end of file
Binary file rc/linux/Minori.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/osx/Minori.app/Contents/Info.plist	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>minori</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Copyright</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright</string>
+	<key>CFBundleIconFile</key>
+	<string>Minori.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.eu.us.paper.Minori</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Minori</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>0.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>Schm</string>
+	<key>CFBundleVersion</key>
+	<string>0.0.0</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+	<key>CGDisableCoalescedUpdates</key>
+	<true/>
+	<key>NSHighResolutionCapable</key>
+	<true/>
+</dict>
+</plist>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/osx/Minori.app/Contents/PkgInfo	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,1 @@
+APPLSchm
\ No newline at end of file
Binary file rc/osx/Minori.app/Contents/Resources/Minori.icns has changed
Binary file rc/osx/favicon.icns has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/win32/dark/dark.qrc	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,5 @@
+<!DOCTYPE rcc><RCC version="1.0">
+	<qresource>
+		<file>dark.qss</file>
+	</qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/win32/dark/dark.qss	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,294 @@
+/*
+Much of this is taken from the Breeze Style Sheets,
+which is under the MIT license:
+
+Copyright © `<2013-2014>` `<Colin Duquesnoy>`
+Copyright © `<2015-2016>` `<Alex Huszagh>`
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the “Software”), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/* Colors should be the same as the QPalette in gui/theme.cc, i.e.:
+	window == darkgray == #353535;
+	??? == gray == #808080;
+	base == black == #191919;
+	highlighted == blue = #2A82DA;
+   We could include a preprocessor like sass to make these constants,
+   but that's really lame :(
+*/
+
+AnimeListPage::pane {
+	margin: 0.04em;
+	border: 0.04em solid #808080;
+	top: -0.04em;
+	left: -0.04em;
+}
+
+QTabWidget::pane:top {
+	border: 0.04em solid #808080;
+	top: -0.04em;
+}
+
+QTabWidget::pane:bottom {
+	border: 0.04em solid #808080;
+	bottom: -0.04em;
+}
+
+QTabWidget::pane:left {
+	border: 0.04em solid #808080;
+	left: -0.04em;
+}
+
+QTabWidget::pane:right {
+	border: 0.04em solid #808080;
+	right: -0.04em;
+}
+
+QTabBar {
+	qproperty-drawBase: 0;
+	left: 0.23em;
+	border-radius: 0.13em;
+	selection-color: transparent;
+}
+
+QTabBar:focus {
+	border: 0em transparent black;
+}
+
+QTabBar::tab:top,
+QTabBar::tab:top:last,
+QTabBar::tab:top:only-one {
+	color: white;
+	border: 0.04em transparent black;
+	border-left: 0.04em solid #808080;
+	border-right: 0.04em solid #808080;
+	border-top: 0.04em solid #808080;
+	background-color: #353535;
+	min-width: 50px;
+	padding-top: 0.23em;
+	padding-bottom: 0.23em;
+	padding-left: 0.78em;
+	padding-right: 0.78em;
+	border-radius: 0.09em;
+	border-bottom-left-radius: 0em;
+	border-bottom-right-radius: 0em;
+}
+
+QTabBar::tab:top:!selected {
+	color: white;
+	background-color: #353535;
+	border: 0.04em solid #808080;
+	border-radius: 0.09em;
+	border-bottom-left-radius: 0em;
+	border-bottom-right-radius: 0em;
+	margin-top: 0.13em;
+}
+
+QTabBar::tab:top:next-selected {
+	border-right: 0.04em transparent #353535;
+	border-bottom-left-radius: 0em;
+	border-bottom-right-radius: 0em;
+}
+
+QTabBar::tab:top:previous-selected {
+	border-left: 0.04em transparent #353535;
+	border-bottom-left-radius: 0em;
+	border-bottom-right-radius: 0em;
+}
+
+QTabBar::tab:top:!selected:hover {
+	background-color: rgba(42, 130, 218, 0.1);
+	border-radius: 0.09em;
+	border-bottom-left-radius: 0em;
+	border-bottom-right-radius: 0em;
+}
+
+QTabBar::tab:top:!selected:first:hover {
+	background-color: rgba(42, 130, 218, 0.1);
+}
+
+QGroupBox::title {
+	color: white;
+}
+
+QComboBox,
+QPushButton,
+QDateEdit,
+QSpinBox {
+	background-color: #353535;
+	color: white;
+}
+
+QComboBox,
+QDateEdit,
+QSpinBox {
+	border: 0.04em solid #808080;
+}
+
+QComboBox:disabled,
+QPushButton:disabled,
+QDateEdit:disabled,
+QSpinBox:disabled {
+	color: #808080;
+}
+
+QPushButton:hover {
+	background-color: #39424B;
+}
+
+/*
+ * QLineEdit
+ */
+
+QLineEdit {
+	background: transparent;
+	color: white;
+}
+
+QLineEdit:!read-only {
+	background-color: #191919;
+	padding: 0.23em;
+	border-style: solid;
+	border: 0.04em solid #808080;
+	border-radius: 0.09em;
+}
+
+/* QMenuBar */
+
+QMenuBar {
+	background-color: #353535;
+	color: white;
+}
+
+QMenuBar::item:selected {
+	background-color: #414141;
+}
+
+QMenuBar::item:disabled {
+	color: #808080;
+}
+
+QMenuBar::item:pressed {
+	background-color: #414141;
+	margin-bottom: -0.09em;
+	padding-bottom: 0.09em;
+}
+
+/* QMenu */
+
+QMenu {
+	color: white;
+	background-color: #353535;
+	padding: 0.18em 0.18em;
+	border: 0.09em solid #A0A0A0;
+}
+
+QMenu::icon {
+	margin: 0.23em;
+}
+
+QMenu::item {
+	/* Add extra padding on the right for the QMenu arrow */
+	padding: 0.23em 1.5em 0.23em 1.3em;
+	border: 0.09em solid transparent;
+	background: transparent;
+}
+
+QMenu::item:selected {
+	color: white;
+	background-color: #414141;
+}
+
+QMenu::item:selected:disabled {
+	background-color: #353535;
+}
+
+QMenu::item:disabled {
+	color: #808080;
+}
+
+QMenu::indicator {
+	width: 0.8em;
+	height: 0.8em;
+	/* To align with QMenu::icon, which has a 0.23em margin. */
+	margin-left: 0.3em;
+	subcontrol-position: center left;
+}
+
+/*
+ * QHeaderView:
+ * Need this for the anime list, on Windows it gets screwed up.
+*/
+
+QHeaderView {
+	background-color: #353535;
+	border: 0.04em transparent;
+	border-radius: 0em;
+	margin: 0em;
+	padding: 0em;
+}
+
+QHeaderView::section {
+	background-color: #353535;
+	border: 0.04em solid #808080;
+	color: #eff0f1;
+	border-radius: 0em;
+	padding: 0em 0.23em 0em 0.23em;
+	text-align: center;
+}
+
+QHeaderView::section::vertical::first,
+QHeaderView::section::vertical::only-one {
+	border-top: 0.04em solid #808080;
+}
+
+QHeaderView::section::vertical {
+	border-top: transparent;
+}
+
+QHeaderView::section::horizontal::first,
+QHeaderView::section::horizontal::only-one {
+	border-left: 0.04em solid #808080;
+}
+
+QHeaderView::section::horizontal {
+	border-left: transparent;
+}
+
+QHeaderView[showSortIndicator="true"]::section::horizontal {
+	/* Same as the width of the arrow subcontrols below. */
+	padding-right: 0.8em;
+}
+
+QHeaderView::section:checked {
+	color: white;
+	background-color: #808080;
+}
+
+/* Note that this doesn't work for QTreeView unless the header is clickable */
+QHeaderView::section:hover,
+QHeaderView::section::horizontal::first:hover,
+QHeaderView::section::horizontal::only-one:hover,
+QHeaderView::section::vertical::first:hover,
+QHeaderView::section::vertical::only-one:hover {
+	background-color: #353535;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc/win32/version.rc	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,37 @@
+#include "winver.h"
+
+#ifndef WRC_VERSION
+#   define WRC_VERSION 0,0,0,0
+#endif
+
+#ifndef PACKAGE_VERSION
+#	define PACKAGE_VERSION "0.0.0"
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+	FILEVERSION WRC_VERSION
+	PRODUCTVERSION WRC_VERSION
+	FILEFLAGS 0x0L
+	FILEFLAGSMASK 0x3fL
+	FILEOS 0x00040004L
+	FILETYPE 0x1L
+	FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "000004b0"
+        BEGIN
+            VALUE "CompanyName", "Paper"
+            VALUE "FileDescription", "A lightweight anime tracker built with Qt."
+            VALUE "FileVersion", PACKAGE_VERSION
+            VALUE "InternalName", "minori"
+            VALUE "OriginalFilename", "minori.exe"
+            VALUE "ProductName", "Minori"
+            VALUE "ProductVersion", PACKAGE_VERSION
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1252
+    END
+END
--- a/rc/win32/version.rc.in	Wed Jan 24 20:18:14 2024 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#include "winver.h"
-
-#ifndef WRC_VERSION
-#   define WRC_VERSION 0,0,0,0
-#endif
-
-#define RC_INFO_STRING "@RC_INFO_STRING@\0"
-
-VS_VERSION_INFO VERSIONINFO
-	FILEVERSION WRC_VERSION
-	PRODUCTVERSION WRC_VERSION
-	FILEFLAGS 0x0L
-	FILEFLAGSMASK 0x3fL
-	FILEOS 0x00040004L
-	FILETYPE 0x1L
-	FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "000004b0"
-        BEGIN
-            VALUE "CompanyName", "Paper"
-            VALUE "FileDescription", RC_INFO_STRING
-            VALUE "FileVersion", VER_FILEVERSION_STR
-            VALUE "InternalName", "minori"
-            VALUE "OriginalFilename", "minori.exe"
-            VALUE "ProductName", "Minori"
-            VALUE "ProductVersion", VER_PRODUCTVERSION_STR
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1252
-    END
-END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/osx/deploy_build.sh	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# deploy_build.sh:
+# run this in your build dir to get a usable app bundle
+
+SCRIPT_DIR=$(dirname -- "$0")
+BUNDLE_NAME="Minori"
+
+cp -r "$SCRIPT_DIR/../../rc/osx/$BUNDLE_NAME.app" .
+
+mkdir -p "$BUNDLE_NAME.app/Contents/MacOS"
+cp ".libs/minori" "$BUNDLE_NAME.app/Contents/MacOS/minori"
+
+mkdir -p "$BUNDLE_NAME.app/Contents/Frameworks"
+for i in animia pugixml anitomy; do
+	cp "dep/$i/.libs/lib$i.0.dylib" "$BUNDLE_NAME.app/Contents/Frameworks"
+	install_name_tool -change "/usr/local/lib/lib$i.0.dylib" "@executable_path/../Frameworks/lib$i.0.dylib" "$BUNDLE_NAME.app/Contents/MacOS/minori"
+done
+
+macdeployqt "$BUNDLE_NAME.app"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/win32/deploy_build.sh	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# deploys needed libraries for minori on win32
+#
+# this also runs windeployqt to deploy qt crap
+# as well
+
+DIR="${DIR:-minori}"
+
+GetNeededLibraries() {
+	# do not run this on untrusted executables.
+	# see: ldd(1)
+	ldd "$1" | while IFS="" read -r dependency; do
+		lib="$(cut -d' ' -f3 <<< $dependency)"
+		if [[ "$lib" == /"${MSYSTEM,,}"/* ]]; then
+			echo "$lib"
+		fi
+	done
+}
+
+
+if [ -d "$DIR" ]; then
+	rm -r "$DIR"
+fi
+
+mkdir "$DIR"
+
+for lib in $(GetNeededLibraries ".libs/minori.exe"); do
+	cp "$lib" "$DIR/"
+done
+
+cp ".libs/minori.exe" "$DIR/"
+
+windeployqt "$DIR/minori.exe"
+
+zip -r "$DIR.zip" "$DIR"
--- a/src/gui/window.cc	Wed Jan 24 20:18:14 2024 -0500
+++ b/src/gui/window.cc	Wed Jan 24 20:18:59 2024 -0500
@@ -43,6 +43,7 @@
 
 #ifdef MACOSX
 #	include "sys/osx/dark_theme.h"
+#	include "sys/osx/permissions.h"
 #elif defined(WIN32)
 #	include "sys/win32/dark_theme.h"
 #endif
@@ -66,13 +67,12 @@
 }
 
 MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
-	setWindowIcon(QIcon(":/favicon.png"));
+	setWindowIcon(QIcon(":/icons/favicon.png"));
 
 	main_widget.reset(new QWidget(this));
 	new QHBoxLayout(main_widget.get());
 
 	AddMainWidgets();
-
 	setCentralWidget(main_widget.get());
 
 	CreateBars();
@@ -114,6 +114,11 @@
 		thread->start();
 	});
 
+#ifdef MACOSX
+	if (!osx::AskForPermissions())
+		return;
+#endif
+
 	timer->start(5000);
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sys/osx/permissions.cc	Wed Jan 24 20:18:59 2024 -0500
@@ -0,0 +1,30 @@
+#include "sys/osx/permissions.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include <QCoreApplication>
+#include <QMessageBox>
+#include <QDesktopServices>
+#include <QUrl>
+
+namespace osx {
+
+bool AskForPermissions() {
+	if (::AXIsProcessTrusted())
+		return true;
+
+	QMessageBox msg;
+	msg.setIcon(QMessageBox::Information);
+	msg.setText(QCoreApplication::tr("Permissions needed!"));
+	msg.setInformativeText(QCoreApplication::tr("Minori needs access to accessibility features for certain features to work. Open System Preferences?"));
+	msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+	msg.setDefaultButton(QMessageBox::Yes);
+	int ret = msg.exec();
+	if (ret != QMessageBox::Yes)
+		return false;
+
+	QDesktopServices::openUrl(QUrl("x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"));
+	return true;
+}
+
+}