diff options
-rw-r--r-- | .github/workflows/ci.yml | 54 | ||||
-rw-r--r-- | ci/msys-deps.txt | 57 | ||||
-rw-r--r-- | src/abaddon.cpp | 38 | ||||
-rw-r--r-- | src/components/chatinputindicator.cpp | 14 | ||||
-rw-r--r-- | src/discord/snowflake.cpp | 11 | ||||
-rw-r--r-- | src/discord/snowflake.hpp | 2 | ||||
-rw-r--r-- | src/util.cpp | 9 | ||||
m--------- | subprojects/ixwebsocket | 0 |
8 files changed, 164 insertions, 21 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9137bbf..fd44b8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,60 @@ name: Abaddon CI on: [push, pull_request] jobs: + msys2: + name: msys2-mingw64 + runs-on: windows-latest + strategy: + matrix: + buildtype: [Debug, RelWithDebInfo, MinSizeRel] + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v1 + with: + submodules: true + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: mingw64 + update: true + install: >- + git + make + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-ninja + mingw-w64-x86_64-sqlite3 + mingw-w64-x86_64-nlohmann-json + mingw-w64-x86_64-curl + mingw-w64-x86_64-zlib + mingw-w64-x86_64-gtkmm3 + + - name: Build + run: | + cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} + cmake --build build + + - name: Setup Artifact + run: | + mkdir -p build/artifactdir/bin build/artifactdir/ssl/certs build/artifactdir/lib build/artifactdir/share/glib-2.0/schemas + cd build + cp *.exe artifactdir/bin + cd .. + cp /mingw64/ssl/certs/ca-bundle.crt build/artifactdir/ssl/certs + cp -r /mingw64/lib/gdk-pixbuf-2.0 build/artifactdir/lib + cp -r res/css res/res res/fonts build/artifactdir/bin + cp /mingw64/share/glib-2.0/schemas/gschemas.compiled build/artifactdir/share/glib-2.0/schemas + cat "ci/msys-deps.txt" | sed 's/\r$//' | xargs -I % cp /mingw64% build/artifactdir/bin + + - name: Upload build + uses: actions/upload-artifact@v2 + with: + name: build-windows-msys2-${{ matrix.buildtype }} + path: build/artifactdir + windows: name: windows-${{ matrix.buildtype }} runs-on: windows-latest diff --git a/ci/msys-deps.txt b/ci/msys-deps.txt new file mode 100644 index 0000000..ab98a15 --- /dev/null +++ b/ci/msys-deps.txt @@ -0,0 +1,57 @@ +/bin/gdbus.exe +/bin/gspawn-win64-helper-console.exe +/bin/libatk-1.0-0.dll +/bin/libatkmm-1.6-1.dll +/bin/libbrotlicommon.dll +/bin/libbrotlidec.dll +/bin/libbz2-1.dll +/bin/libcairo-2.dll +/bin/libcairo-gobject-2.dll +/bin/libcairomm-1.0-1.dll +/bin/libcrypto-1_1-x64.dll +/bin/libcurl-4.dll +/bin/libdatrie-1.dll +/bin/libdeflate.dll +/bin/libepoxy-0.dll +/bin/libexpat-1.dll +/bin/libffi-7.dll +/bin/libfontconfig-1.dll +/bin/libfreetype-6.dll +/bin/libfribidi-0.dll +/bin/libgcc_s_seh-1.dll +/bin/libgdk-3-0.dll +/bin/libgdk_pixbuf-2.0-0.dll +/bin/libgdkmm-3.0-1.dll +/bin/libgio-2.0-0.dll +/bin/libgiomm-2.4-1.dll +/bin/libglib-2.0-0.dll +/bin/libglibmm-2.4-1.dll +/bin/libgmodule-2.0-0.dll +/bin/libgobject-2.0-0.dll +/bin/libgraphite2.dll +/bin/libgtk-3-0.dll +/bin/libgtkmm-3.0-1.dll +/bin/libharfbuzz-0.dll +/bin/libiconv-2.dll +/bin/libidn2-0.dll +/bin/libintl-8.dll +/bin/libnghttp2-14.dll +/bin/libpango-1.0-0.dll +/bin/libpangocairo-1.0-0.dll +/bin/libpangoft2-1.0-0.dll +/bin/libpangomm-1.4-1.dll +/bin/libpangowin32-1.0-0.dll +/bin/libpcre-1.dll +/bin/libpixman-1-0.dll +/bin/libpng16-16.dll +/bin/libpsl-5.dll +/bin/libsigc-2.0-0.dll +/bin/libsqlite3-0.dll +/bin/libssh2-1.dll +/bin/libssl-1_1-x64.dll +/bin/libstdc++-6.dll +/bin/libthai-0.dll +/bin/libunistring-2.dll +/bin/libwinpthread-1.dll +/bin/libzstd.dll +/bin/zlib1.dll diff --git a/src/abaddon.cpp b/src/abaddon.cpp index 51f8052..bf1c6cf 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -64,18 +64,41 @@ int Abaddon::StartGTK() { m_css_provider = Gtk::CssProvider::create(); m_css_provider->signal_parsing_error().connect([this](const Glib::RefPtr<const Gtk::CssSection> §ion, const Glib::Error &error) { - Gtk::MessageDialog dlg(*m_main_window, "css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + Gtk::MessageDialog dlg("css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); dlg.set_position(Gtk::WIN_POS_CENTER); dlg.run(); }); m_css_low_provider = Gtk::CssProvider::create(); m_css_low_provider->signal_parsing_error().connect([this](const Glib::RefPtr<const Gtk::CssSection> §ion, const Glib::Error &error) { - Gtk::MessageDialog dlg(*m_main_window, "low-priority css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + Gtk::MessageDialog dlg("low-priority css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); dlg.set_position(Gtk::WIN_POS_CENTER); dlg.run(); }); +#ifdef _WIN32 + bool png_found = false; + bool gif_found = false; + for (const auto &fmt : Gdk::Pixbuf::get_formats()) { + if (fmt.get_name() == "png") + png_found = true; + else if (fmt.get_name() == "gif") + gif_found = true; + } + + if (!png_found) { + Gtk::MessageDialog dlg("The PNG pixbufloader wasn't detected. Abaddon may not work as a result.", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + dlg.set_position(Gtk::WIN_POS_CENTER); + dlg.run(); + } + + if (!gif_found) { + Gtk::MessageDialog dlg("The GIF pixbufloader wasn't detected. Animations may not display as a result.", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + dlg.set_position(Gtk::WIN_POS_CENTER); + dlg.run(); + } +#endif + m_main_window = std::make_unique<MainWindow>(); m_main_window->set_title(APP_TITLE); m_main_window->set_position(Gtk::WIN_POS_CENTER); @@ -735,6 +758,17 @@ EmojiResource &Abaddon::GetEmojis() { int main(int argc, char **argv) { if (std::getenv("ABADDON_NO_FC") == nullptr) Platform::SetupFonts(); + + char *systemLocale = std::setlocale(LC_ALL, ""); + try { + std::locale::global(std::locale(systemLocale)); + } catch (...) { + try { + std::locale::global(std::locale::classic()); + std::setlocale(LC_ALL, systemLocale); + } catch (...) {} + } + #if defined(_WIN32) && defined(_MSC_VER) TCHAR buf[2] { 0 }; GetEnvironmentVariableA("GTK_CSD", buf, sizeof(buf)); diff --git a/src/components/chatinputindicator.cpp b/src/components/chatinputindicator.cpp index 9b063b2..ba794f3 100644 --- a/src/components/chatinputindicator.cpp +++ b/src/components/chatinputindicator.cpp @@ -25,16 +25,16 @@ ChatInputIndicator::ChatInputIndicator() if (!std::filesystem::exists(path)) return; auto gif_data = ReadWholeFile(path); auto loader = Gdk::PixbufLoader::create(); - loader->signal_size_prepared().connect([&](int inw, int inh) { - int w, h; - GetImageDimensions(inw, inh, w, h, 20, 10); - loader->set_size(w, h); - }); - loader->write(gif_data.data(), gif_data.size()); try { + loader->signal_size_prepared().connect([&](int inw, int inh) { + int w, h; + GetImageDimensions(inw, inh, w, h, 20, 10); + loader->set_size(w, h); + }); + loader->write(gif_data.data(), gif_data.size()); loader->close(); m_img.property_pixbuf_animation() = loader->get_animation(); - } catch (const std::exception &) {} + } catch (...) {} } void ChatInputIndicator::AddUser(Snowflake channel_id, const UserData &user, int timeout) { diff --git a/src/discord/snowflake.cpp b/src/discord/snowflake.cpp index 8f470a7..efa327d 100644 --- a/src/discord/snowflake.cpp +++ b/src/discord/snowflake.cpp @@ -3,6 +3,7 @@ #include <chrono> #include <ctime> #include <iomanip> +#include <glibmm.h> constexpr static uint64_t DiscordEpochSeconds = 1420070400; @@ -53,14 +54,12 @@ bool Snowflake::IsValid() const { return m_num != Invalid; } -std::string Snowflake::GetLocalTimestamp() const { +Glib::ustring Snowflake::GetLocalTimestamp() const { const time_t secs_since_epoch = (m_num / SecondsInterval) + DiscordEpochSeconds; const std::tm tm = *localtime(&secs_since_epoch); - std::stringstream ss; - const static std::locale locale(""); - ss.imbue(locale); - ss << std::put_time(&tm, "%X %x"); - return ss.str(); + std::array<char, 256> tmp; + std::strftime(tmp.data(), sizeof(tmp), "%X %x", &tm); + return tmp.data(); } void from_json(const nlohmann::json &j, Snowflake &s) { diff --git a/src/discord/snowflake.hpp b/src/discord/snowflake.hpp index f2da5d1..e83317a 100644 --- a/src/discord/snowflake.hpp +++ b/src/discord/snowflake.hpp @@ -13,7 +13,7 @@ struct Snowflake { static Snowflake FromISO8601(std::string_view ts); bool IsValid() const; - std::string GetLocalTimestamp() const; + Glib::ustring GetLocalTimestamp() const; bool operator==(const Snowflake &s) const noexcept { return m_num == s.m_num; diff --git a/src/util.cpp b/src/util.cpp index 6796a3f..0ebe73e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,7 @@ #include "util.hpp" #include <array> #include <filesystem> +#include <array> Semaphore::Semaphore(int count) : m_count(count) {} @@ -94,11 +95,9 @@ std::string FormatISO8601(const std::string &in, int extra_offset, const std::st int offset = GetTimezoneOffset(); tm.tm_sec += offset + extra_offset; mktime(&tm); - std::stringstream ss; - const static std::locale locale(""); - ss.imbue(locale); - ss << std::put_time(&tm, fmt.c_str()); - return ss.str(); + std::array<char, 512> tmp; + std::strftime(tmp.data(), sizeof(tmp), fmt.c_str(), &tm); + return tmp.data(); } void ScrollListBoxToSelected(Gtk::ListBox &list) { diff --git a/subprojects/ixwebsocket b/subprojects/ixwebsocket -Subproject 2fac4bd9ef58c3be3e370222410b8694a4ef0d2 +Subproject e66437b56089be46886084ff3930f352b6d3d90 |