Skip to content

Commit bdfb376

Browse files
committed
change how windows icons work
1 parent 581522a commit bdfb376

2 files changed

Lines changed: 88 additions & 12 deletions

File tree

‎build.rs‎

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ enum ActivePoField {
3434
StrPlural(usize),
3535
}
3636

37+
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
38+
struct ResourceFileEntry {
39+
source: String,
40+
alias: Option<String>,
41+
}
42+
43+
impl ResourceFileEntry {
44+
fn source(source: String) -> Self {
45+
Self {
46+
source,
47+
alias: None,
48+
}
49+
}
50+
51+
fn alias(source: impl Into<String>, alias: impl Into<String>) -> Self {
52+
Self {
53+
source: source.into(),
54+
alias: Some(alias.into()),
55+
}
56+
}
57+
}
58+
3759
fn main() {
3860
let docs_enabled = env::var_os("CARGO_FEATURE_DOCS").is_some();
3961

@@ -66,10 +88,11 @@ fn main() {
6688
fs::create_dir_all(data_dir).expect("Failed to create data directory");
6789
fs::create_dir_all(po_dir).expect("Failed to create po directory");
6890

69-
let mut icons = Vec::new();
70-
collect_icon_assets(data_dir, data_dir, &mut icons);
71-
icons.sort();
72-
write_resources_xml(data_dir, &icons);
91+
let mut resource_files = Vec::new();
92+
collect_icon_assets(data_dir, data_dir, &mut resource_files);
93+
extend_windows_icon_theme_resources(data_dir, &mut resource_files);
94+
resource_files.sort();
95+
write_resources_xml(data_dir, &resource_files);
7396

7497
glib_build_tools::compile_resources(&[data_dir], "data/resources.xml", "compiled.gresource");
7598

@@ -1107,12 +1130,18 @@ fn write_if_changed_binary(path: &Path, contents: &[u8]) {
11071130
.unwrap_or_else(|err| panic!("Failed to write {}: {err}", path.display()));
11081131
}
11091132

1110-
fn write_resources_xml(data_dir: &Path, icons: &[String]) {
1133+
fn write_resources_xml(data_dir: &Path, resource_files: &[ResourceFileEntry]) {
11111134
let mut xml = String::from("<gresources>\n");
11121135
writeln!(xml, "\t<gresource prefix=\"{}\">", resource_id())
11131136
.expect("Failed to format resource prefix");
1114-
for icon in icons {
1115-
writeln!(xml, "\t\t<file>{icon}</file>").expect("Failed to format resource entry");
1137+
for file in resource_files {
1138+
if let Some(alias) = file.alias.as_deref() {
1139+
writeln!(xml, "\t\t<file alias=\"{alias}\">{}</file>", file.source)
1140+
.expect("Failed to format aliased resource entry");
1141+
} else {
1142+
writeln!(xml, "\t\t<file>{}</file>", file.source)
1143+
.expect("Failed to format resource entry");
1144+
}
11161145
}
11171146
xml.push_str("\t</gresource>\n</gresources>\n");
11181147
let path = data_dir.join("resources.xml");
@@ -1259,13 +1288,13 @@ fn find_locked_package_version(lockfile: &str, package: &str) -> Option<String>
12591288
None
12601289
}
12611290

1262-
fn collect_icon_assets(dir: &Path, data_dir: &Path, icons: &mut Vec<String>) {
1291+
fn collect_icon_assets(dir: &Path, data_dir: &Path, resource_files: &mut Vec<ResourceFileEntry>) {
12631292
for entry in fs::read_dir(dir).expect("Failed to read resource directory") {
12641293
let entry = entry.expect("Failed to read resource directory entry");
12651294
let path = entry.path();
12661295

12671296
if path.is_dir() {
1268-
collect_icon_assets(&path, data_dir, icons);
1297+
collect_icon_assets(&path, data_dir, resource_files);
12691298
} else if matches!(
12701299
path.extension().and_then(|value| value.to_str()),
12711300
Some("png" | "svg")
@@ -1276,11 +1305,55 @@ fn collect_icon_assets(dir: &Path, data_dir: &Path, icons: &mut Vec<String>) {
12761305
let rel = path
12771306
.strip_prefix(data_dir)
12781307
.expect("Resource path should stay within data/");
1279-
icons.push(rel.to_string_lossy().into_owned());
1308+
resource_files.push(ResourceFileEntry::source(
1309+
rel.to_string_lossy().into_owned(),
1310+
));
12801311
}
12811312
}
12821313
}
12831314

1315+
fn extend_windows_icon_theme_resources(
1316+
data_dir: &Path,
1317+
resource_files: &mut Vec<ResourceFileEntry>,
1318+
) {
1319+
let theme_index = data_dir.join("windows/share/icons/hicolor/index.theme");
1320+
if theme_index.is_file() {
1321+
resource_files.push(ResourceFileEntry::source(
1322+
"windows/share/icons/hicolor/index.theme".to_string(),
1323+
));
1324+
}
1325+
1326+
let sources = resource_files
1327+
.iter()
1328+
.map(|entry| entry.source.clone())
1329+
.collect::<Vec<_>>();
1330+
for source in sources {
1331+
for alias in windows_icon_theme_aliases(&source) {
1332+
resource_files.push(ResourceFileEntry::alias(source.clone(), alias));
1333+
}
1334+
}
1335+
}
1336+
1337+
fn windows_icon_theme_aliases(source: &str) -> Vec<String> {
1338+
if source.starts_with("256x256/apps/") || source.starts_with("scalable/apps/") {
1339+
return vec![format!("windows/share/icons/hicolor/{source}")];
1340+
}
1341+
1342+
if let Some(file_name) = source.strip_prefix("symbolic/apps/") {
1343+
let mut aliases = vec![format!(
1344+
"windows/share/icons/hicolor/symbolic/actions/{file_name}"
1345+
)];
1346+
if file_name.starts_with("io.github.noobping.") {
1347+
aliases.push(format!(
1348+
"windows/share/icons/hicolor/symbolic/apps/{file_name}"
1349+
));
1350+
}
1351+
return aliases;
1352+
}
1353+
1354+
Vec::new()
1355+
}
1356+
12841357
#[cfg(not(feature = "setup"))]
12851358
fn desktop_file() {
12861359
let app_id = app_id();

‎src/main.rs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ use winsafe::{self as w, co};
6868

6969
const APP_ID: &str = env!("APP_ID");
7070
const RESOURCE_ID: &str = env!("RESOURCE_ID");
71+
#[cfg(target_os = "windows")]
72+
const WINDOWS_ICON_RESOURCE_PATH: &str = concat!(env!("RESOURCE_ID"), "/windows/share/icons");
7173
const ISSUE_URL: &str = concat!(env!("CARGO_PKG_REPOSITORY"), "/issues");
7274
const MAIN_WINDOW_ACTIVATING_KEY: &str = "main-window-activating";
7375
const RIPASSO_VERSION: &str = env!("RIPASSO_VERSION");
@@ -136,7 +138,7 @@ fn main() -> ExitCode {
136138
let theme = IconTheme::for_display(&display);
137139
theme.add_resource_path(RESOURCE_ID);
138140
#[cfg(target_os = "windows")]
139-
add_windows_icon_search_path(&theme);
141+
add_windows_icon_theme_paths(&theme);
140142

141143
match backend::prepare_startup() {
142144
Ok(backend::StartupPreparation::Ready) => {}
@@ -463,7 +465,8 @@ fn quoted_pixbuf_loader_name(line: &str) -> Option<&str> {
463465
}
464466

465467
#[cfg(target_os = "windows")]
466-
fn add_windows_icon_search_path(theme: &IconTheme) {
468+
fn add_windows_icon_theme_paths(theme: &IconTheme) {
469+
theme.add_resource_path(WINDOWS_ICON_RESOURCE_PATH);
467470
if let Some(path) = windows_icon_search_path() {
468471
theme.add_search_path(path);
469472
}

0 commit comments

Comments
 (0)