# HG changeset patch # User Paper # Date 1727924803 14400 # Node ID f81bed4e04ac8a7ad3c9b55c21886269b28457a3 # Parent 99c961c91809d8ee536fc4c734ccd346fad2b213 *: megacommit that probably breaks things diff -r 99c961c91809 -r f81bed4e04ac dep/animone/src/fd/proc.cc --- a/dep/animone/src/fd/proc.cc Tue Jul 16 21:15:59 2024 -0400 +++ b/dep/animone/src/fd/proc.cc Wed Oct 02 23:06:43 2024 -0400 @@ -21,7 +21,34 @@ namespace animone::internal::proc { -static bool IsRegularFile(std::string link) { +struct Fdinfo { + bool Parse(std::istream& istr); + std::unordered_map data; +}; + +bool Fdinfo::Parse(std::istream& istr) { + /* shift to the start of the stream */ + istr.seekg(0); + + for (std::string line; std::getline(istr, line); ) { + if (line.empty()) /* huh? */ + continue; + + std::size_t colon = line.find(':'); + if (colon == std::string::npos) + return false; + + std::string key = line.substr(0, colon); + std::string value = line.substr(colon + 1); + util::TrimLeft(value, " "); + + data[key] = value; + } + + return true; +} + +static bool IsRegularFile(const std::string& link) { struct stat sb; if (stat(link.c_str(), &sb) == -1) return false; @@ -37,15 +64,22 @@ if (!file) return false; - int flags = 0; - for (std::string line; std::getline(file, line);) - if (line.find("flags:", 0) == 0) - flags = util::StringToInt(line.substr(line.find_last_not_of("0123456789") + 1)); + Fdinfo fdinfo; + if (!fdinfo.Parse(file)) + return false; + + if (fdinfo.data.find("flags") == fdinfo.data.end()) + return false; /* check if the file was opened in a write mode */ - int accflags = flags & O_ACCMODE; - if (accflags == O_WRONLY || accflags == O_RDWR) - return false; + try { + const long long accflags = std::stoll(fdinfo.data["flags"]) & O_ACCMODE; + + if (accflags == O_WRONLY || accflags == O_RDWR) + return false; + } catch (const std::exception& ex) { + return false; /* huh ? */ + } return true; } diff -r 99c961c91809 -r f81bed4e04ac dep/animone/src/fd/xnu.cc --- a/dep/animone/src/fd/xnu.cc Tue Jul 16 21:15:59 2024 -0400 +++ b/dep/animone/src/fd/xnu.cc Wed Oct 02 23:06:43 2024 -0400 @@ -35,21 +35,28 @@ namespace animone::internal::xnu { bool EnumerateOpenProcesses(process_proc_t process_proc) { - size_t pids_size = 256; - std::unique_ptr pids; + /* pre-allocate 256 pids */ + std::vector pids(256); + int returned_size_bytes = 0; + + for (;;) { + returned_size_bytes = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), pids.size() * sizeof(pid_t)); + if (returned_size_bytes <= 0) /* probably an error ? */ + return false; - int returned_size = 0; - do { - pids.reset(new pid_t[pids_size *= 2]); - returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t)); - if (returned_size == -1) - return false; - } while ((pids_size * sizeof(size_t)) < returned_size); + /* break out of the loop if we have everything */ + if ((pids.size() * sizeof(pid_t)) > returned_size_bytes) + break; + + pids.resize(pids.size() * 2); + } - for (int i = 0; i < pids_size; i++) { + pids.resize(returned_size_bytes); + + for (const auto& pid : pids) { std::string result; - GetProcessName(pids[i], result); - if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pids[i], .comm = result})) + GetProcessName(pid, result); + if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pid, .comm = result})) return false; } @@ -61,36 +68,41 @@ return false; for (const auto& pid : pids) { - const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (bufsz < 0) - return false; + /* most processes probably don't even have that many files opened! */ + std::vector fds(4); + int returned_size_bytes = 0; + + for (;;) { + returned_size_bytes = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds.data(), fds.size()); + if (returned_size_bytes <= 0) /* probably an error ? */ + return false; - const size_t info_len = bufsz / sizeof(struct proc_fdinfo); - if (info_len < 1) - return false; + /* break out of the loop if we have everything */ + if ((fds.size() * sizeof(struct proc_fdinfo)) > returned_size_bytes) + break; - std::unique_ptr info(new struct proc_fdinfo[info_len]); - if (!info) - return false; + fds.resize(fds.size() * 2); + } - proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz); + fds.resize(returned_size_bytes / sizeof(struct proc_fdinfo)); - for (size_t i = 0; i < info_len; i++) { - if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { - struct vnode_fdinfowithpath vnodeInfo; + for (const auto& fd : fds) { + if (fd.proc_fdtype != PROX_FDTYPE_VNODE) + continue; + + struct vnode_fdinfowithpath vnodeInfo; - int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, - PROC_PIDFDVNODEPATHINFO_SIZE); - if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) - return false; + int sz = proc_pidfdinfo(pid, fd.proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, + PROC_PIDFDVNODEPATHINFO_SIZE); + if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) + return false; - /* why would a media player open a file in write mode? */ - if (vnodeInfo.pfi.fi_openflags & FWRITE) - continue; + /* why would a media player open a file in write mode? */ + if (vnodeInfo.pfi.fi_openflags & FWRITE) + continue; - if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) - return false; - } + if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) + return false; } } @@ -100,7 +112,7 @@ static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) { result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0'); - int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char)); + int ret = proc_pidpath(pid, result.data(), result.size()); if (ret <= 0) return false; @@ -116,7 +128,7 @@ static bool GetProcessNameFromProcName(pid_t pid, std::string& result) { result.assign(2 * MAXCOMLEN, '\0'); - int size = proc_name(pid, &result.front(), result.length()); + int size = proc_name(pid, result.data(), result.length()); /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume * this method won't work and our result is truncated */ diff -r 99c961c91809 -r f81bed4e04ac include/gui/widgets/anime_button.h --- a/include/gui/widgets/anime_button.h Tue Jul 16 21:15:59 2024 -0400 +++ b/include/gui/widgets/anime_button.h Wed Oct 02 23:06:43 2024 -0400 @@ -13,7 +13,7 @@ class Anime; } -class AnimeButton : public QFrame { +class AnimeButton final : public QFrame { Q_OBJECT public: @@ -21,6 +21,9 @@ AnimeButton(const Anime::Anime& anime, QWidget* parent = nullptr); void SetAnime(const Anime::Anime& anime); + bool hasHeightForWidth() const override; + int heightForWidth(int w) const override; + protected: Poster _poster; QLabel _title; diff -r 99c961c91809 -r f81bed4e04ac include/gui/widgets/graph.h --- a/include/gui/widgets/graph.h Tue Jul 16 21:15:59 2024 -0400 +++ b/include/gui/widgets/graph.h Wed Oct 02 23:06:43 2024 -0400 @@ -103,6 +103,8 @@ /* only draw this if we actually have any data */ if (total) { + const int rect_width = (static_cast(value) / total) * (width - offset - HORIZ_SPACING - value_width); + painter.save(); QPen pen(painter.pen()); @@ -110,12 +112,11 @@ painter.setPen(pen); QPainterPath path; - path.addRect(x + offset, y, - (static_cast(value) / total) * (width - offset - HORIZ_SPACING - value_width), each_height); + path.addRect(x + offset, y, rect_width, each_height); painter.fillPath(path, Qt::darkGreen); painter.drawPath(path); - offset += (static_cast(value) / total) * (width - offset - HORIZ_SPACING - value_width); + offset += rect_width; painter.restore(); } diff -r 99c961c91809 -r f81bed4e04ac include/gui/widgets/text.h --- a/include/gui/widgets/text.h Tue Jul 16 21:15:59 2024 -0400 +++ b/include/gui/widgets/text.h Wed Oct 02 23:06:43 2024 -0400 @@ -30,6 +30,21 @@ QPointer separator_; }; +class Label final : public QLabel { + Q_OBJECT + +public: + Label(QWidget *parent = nullptr); + Label(const QString &string, QWidget *parent = nullptr); + void SetElidingMode(bool elide); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + bool elide_; +}; + /* This is a nice clean wrapper around Label suitable for our needs. */ class Paragraph : public QWidget { Q_OBJECT @@ -65,7 +80,7 @@ QPointer contents_; QPointer contents_layout_; - std::vector, QSharedPointer>> data_; + std::vector, QSharedPointer