Compare commits

..
Author SHA1 Message Date
anthropic-code-agent[bot]andashaduri 37090a8556 Fix Type tooltip and FailTime condition per PR feedback
Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ashaduri/gsmartcontrol/sessions/b9ea2530-2c7d-4061-accb-eb7d7bb1dc16
2026-03-22 17:09:02 +00:00
anthropic-code-agent[bot]andashaduri 99d358396b Make Type bold only on pre-failure attribute failure
- Type column now shows bold text only when BOTH conditions are met:
  1. Attribute has actually failed (when_failed != None)
  2. Attribute type is pre-failure
- This provides visual emphasis for genuine pre-failure warnings
- Normal pre-failure attributes (not failed) remain normal weight

Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
2026-03-06 19:02:55 +00:00
anthropic-code-agent[bot]andashaduri d1d64693db Clarify Type attribute explanation and remove bold formatting
- Updated tooltip to clearly explain Type indicates alarm meaning
- Removed bold formatting for "pre-failure" to reduce visual alarm
- Changed text to emphasize Type is about alarm interpretation, not current status

Co-authored-by: ashaduri <2302268+ashaduri@users.noreply.github.com>
2026-03-06 14:52:28 +00:00
anthropic-code-agent[bot] 480e060682 Initial plan 2026-03-06 14:50:23 +00:00
2 changed files with 8 additions and 118 deletions
+5 -2
View File
@@ -1139,7 +1139,7 @@ void GscInfoWindow::fill_ui_ata_attributes(const StoragePropertyRepository& prop
model_columns.add(columns_->ata_attribute_table_columns.type);
num_tree_col = app_gtkmm_create_tree_view_column(columns_->ata_attribute_table_columns.type, *treeview,
_("Type"), _("Alarm condition is reached when normalized value becomes less than or equal to threshold. Type indicates whether it's a signal of drive's pre-failure time or just an old age."), false, true);
_("Type"), _("Indicates whether an alarm for this attribute signals drive failure (pre-failure) or normal wear from drive age (old age)."), false, true);
// Doesn't carry that much info. Advanced users can look at the flags.
// model_columns.add(attribute_table_columns.updated);
@@ -2098,7 +2098,10 @@ void GscInfoWindow::cell_renderer_for_ata_attributes(Gtk::CellRenderer* cr,
crt->property_weight() = Pango::WEIGHT_BOLD;
}
if (column_index == columns_->ata_attribute_table_columns.type.index()) {
if (attribute.attr_type == AtaStorageAttribute::AttributeType::Prefail) {
// Bold only when attribute has failed AND it's pre-failure type
if ((attribute.when_failed == AtaStorageAttribute::FailTime::Past
|| attribute.when_failed == AtaStorageAttribute::FailTime::Now)
&& attribute.attr_type == AtaStorageAttribute::AttributeType::Prefail) {
crt->property_weight() = Pango::WEIGHT_BOLD;
} else { // reset to default value if reloading
crt->property_weight().reset_value();
+3 -116
View File
@@ -21,11 +21,6 @@ Copyright:
#include "win32_tools.h" // hz::win32_utf8_to_utf16
#else
#include <memory>
#include <unistd.h> // geteuid, fork, execvp, setuid, setgid
#include <sys/types.h> // uid_t, gid_t
#include <sys/wait.h> // waitpid
#include <pwd.h> // getpwuid
#include "env_tools.h" // hz::env_get_value
#endif
@@ -34,89 +29,6 @@ Copyright:
namespace hz {
#ifndef _WIN32
/// Launch URL as the original user when running as root.
/// This is needed because gtk_show_uri_on_window() doesn't work when running as root
/// (D-Bus session is not accessible).
/// \return error message on error, empty string on success.
inline std::string launch_url_as_original_user(const std::string& link)
{
// Get the original user's UID from environment variables
// SUDO_UID is set by sudo, PKEXEC_UID is set by pkexec
std::string uid_str;
uid_t original_uid = 0;
gid_t original_gid = 0;
if (hz::env_get_value("SUDO_UID", uid_str) || hz::env_get_value("PKEXEC_UID", uid_str)) {
try {
original_uid = static_cast<uid_t>(std::stoul(uid_str));
} catch (...) {
return "Cannot parse original user UID";
}
// Get the original user's GID
struct passwd* pw = getpwuid(original_uid);
if (pw) {
original_gid = pw->pw_gid;
} else {
return "Cannot get original user information";
}
} else {
return "Cannot determine original user UID";
}
// Fork and execute xdg-open as the original user
pid_t pid = fork();
if (pid < 0) {
return "Cannot fork process";
}
if (pid == 0) {
// Child process
// Restore HOME environment variable if available
// This helps xdg-open find the correct configuration
std::string sudo_user;
if (hz::env_get_value("SUDO_USER", sudo_user)) {
struct passwd* pw = getpwnam(sudo_user.c_str());
if (pw && pw->pw_dir) {
setenv("HOME", pw->pw_dir, 1);
}
}
// Drop privileges to original user
// Set GID first, then UID (order matters for security)
if (setgid(original_gid) != 0) {
_exit(1);
}
if (setuid(original_uid) != 0) {
_exit(1);
}
// Execute xdg-open with the URL
const char* argv[] = {"xdg-open", link.c_str(), nullptr};
execvp("xdg-open", const_cast<char* const*>(argv));
// If execvp returns, it failed
_exit(1);
}
// Parent process - wait for child
int status = 0;
if (waitpid(pid, &status, 0) == -1) {
return "Cannot wait for child process";
}
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
return {}; // Success
}
return "xdg-open failed to launch URL";
}
#endif // _WIN32
/// Open URL in browser or mailto: link in mail client.
/// Return error message on error, empty string otherwise.
@@ -138,41 +50,16 @@ inline std::string launch_url([[maybe_unused]] GtkWindow* window, const std::str
#else
GError* error = nullptr;
bool status = false;
// Check if running as root
bool is_root = (geteuid() == 0);
// If running as root, try to launch as the original user first
if (is_root) {
std::string result = launch_url_as_original_user(link);
if (result.empty()) {
return {}; // Success
}
// If launching as original user failed, fall through to try GTK method
}
// Try the standard GTK method
#if GTK_CHECK_VERSION(3, 22, 0)
status = static_cast<bool>(gtk_show_uri_on_window(window, link.c_str(), GDK_CURRENT_TIME, &error));
bool status = static_cast<bool>(gtk_show_uri_on_window(window, link.c_str(), GDK_CURRENT_TIME, &error));
#else
GdkScreen* screen = (window ? gtk_window_get_screen(window) : nullptr);
status = static_cast<bool>(gtk_show_uri(screen, link.c_str(), GDK_CURRENT_TIME, &error));
bool status = static_cast<bool>(gtk_show_uri(screen, link.c_str(), GDK_CURRENT_TIME, &error));
#endif
std::unique_ptr<GError, decltype(&g_error_free)> uerror(error, &g_error_free);
if (!status) {
// GTK method failed. If running as root, we already tried the fallback.
// Otherwise, try the fallback now.
if (!is_root) {
std::string result = launch_url_as_original_user(link);
if (result.empty()) {
return {}; // Success
}
}
// Both methods failed, return error
return std::string("Cannot open URL")
return std::string("Cannot open URL: ")
+ ((error && error->message) ? (std::string(": ") + error->message) : ".");
}
return {};