#include "autostart.h" #include #if defined(TARGET_LINUX) #include #include #include #include #include #include #include #include #include #include namespace fs = std::filesystem; #define NOO_DESKTOP_NAME "noo.desktop" static std::string read_desktop_file() { QFile f(":/assets/misc/noo.desktop"); f.open(QFile::ReadOnly); auto bytes = f.readAll(); return bytes.toStdString(); } static std::string fixup_desktop_file(const std::string& desktop_unit, const std::string& path) { // load set with first file std::istringstream inf(desktop_unit); std::vector lines; std::string line; for (unsigned int i=0; std::getline(inf,line); i++) { if (line.find("Exec=") == 0) { line = "Exec=" + path; } lines.push_back(line); } std::ostringstream oss; std::copy(lines.begin(), lines.end(), std::ostream_iterator(oss, "\n")); return oss.str(); } static fs::path home_dir() { struct passwd *pw = getpwuid(getuid()); return pw ? pw->pw_dir : std::string(); } static fs::path autostart_dir() { return home_dir() / ".config" / "autostart"; } static fs::path autostart_path() { return autostart_dir() / NOO_DESKTOP_NAME; } void autostart::enable(const std::string& path_to_me) { // Put .desktop file to ~/.config/autostart std::ofstream ofs(autostart_path()); if (ofs.is_open()) { ofs << fixup_desktop_file(read_desktop_file(), path_to_me); ofs.close(); } else qDebug() << "Failed to write the desktop entry into autostart dir. Error: " << errno; } void autostart::disable() { // Remove .desktop file from ~/.config/autostart ::remove(autostart_path().c_str()); } bool autostart::is_enabled() { return fs::exists(fs::path(autostart_path())); } // ----- appmenu ----- static fs::path appmenu_install_dir() { // Global one // return fs::path("/usr/share/applications"); // User only return home_dir() / ".local" / "share" / "applications"; } void appmenu::install(const std::string& path_to_me) { auto path_to_desktop = appmenu_install_dir() / NOO_DESKTOP_NAME; // Check if app is installed already. // The code below checks for path to app; as this app is distributed as .AppImage with version numbers - every new version will trigger desktop file rewriting std::ifstream ifs(path_to_desktop); std::string content((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); if (content.find(path_to_me) != std::string::npos) return; // Remove old one std::string uninstall_cmd = "/usr/bin/xdg-desktop-menu uninstall --novendor " + (appmenu_install_dir() / NOO_DESKTOP_NAME).string(); system(uninstall_cmd.c_str()); // Put .desktop file to ~/.config/autostart std::ofstream ofs(path_to_desktop); if (ofs.is_open()) { ofs << fixup_desktop_file(read_desktop_file(), path_to_me); ofs.close(); } else qDebug() << "Failed to write the desktop entry into app menu dir. Error: " << errno; // Install latest icons { auto icons = {"16x16", "32x32", "64x64", "128x128", "256x256"}; // Here Qt part auto target_dir = QFileInfo(QDir::homePath() + "/.local/share/icons/hicolor").absoluteFilePath(); if (QFileInfo::exists(target_dir)) { // Copy icons from resources for (auto& icon_suffix: icons) { QString icon_src = QString(":/assets/images/app_icon/linux/noo_") + icon_suffix + ".png", icon_dst = target_dir + "/" + icon_suffix + "/apps/noo.png"; if (QFile::exists(icon_src)) QFile::copy(icon_src, icon_dst); } } } std::string install_cmd = "/usr/bin/xdg-desktop-menu install --novendor " + (appmenu_install_dir() / NOO_DESKTOP_NAME).string(); system(install_cmd.c_str()); } void appmenu::uninstall() { if (is_installed()) fs::remove(appmenu_install_dir() / NOO_DESKTOP_NAME); } bool appmenu::is_installed() { return fs::exists(appmenu_install_dir() / NOO_DESKTOP_NAME); } #endif