├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── ATTRIBUTION ├── COPYING ├── README.md ├── apps ├── 16 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ └── zotero.svg ├── 24 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ └── zotero.svg ├── 32 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ └── zotero.svg ├── 48 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ ├── wezterm.svg │ └── zotero.svg ├── 64 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ └── zotero.svg ├── 128 │ ├── alacritty.svg │ ├── discord.svg │ ├── ghostty.svg │ ├── obsidian.svg │ ├── slack.svg │ └── zotero.svg └── meson.build ├── index.theme.in ├── meson.build ├── meson_options.txt └── pre-commit /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | root = true 3 | 4 | # elementary defaults 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = tab 9 | indent_style = space 10 | insert_final_newline = true 11 | max_line_length = 80 12 | tab_width = 4 13 | 14 | [{*.policy,*.xml,*.xml.in,*.yml}] 15 | tab_width = 2 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [wpkelso] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | build/ 3 | -------------------------------------------------------------------------------- /ATTRIBUTION: -------------------------------------------------------------------------------- 1 | Attribution 2 | 3 | Build system derived from the work of elementary Inc. and contributors 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Expandtheon 2 | 3 | Static Badge 4 | 5 | ![Obsidian](./apps/48/obsidian.svg) 6 | ![Alacritty](./apps/48/alacritty.svg) 7 | ![Discord](./apps/48/discord.svg) 8 | ![Slack](./apps/48/slack.svg) 9 | ![Zotero](./apps/48/zotero.svg) 10 | ![Ghostty](./apps/48/ghostty.svg) 11 | ![WezTerm](./apps/48/wezterm.svg) 12 | 13 | A vector icon theme that brings third-party support to elementary OS and it's 14 | desktop environment, Pantheon. 15 | 16 | This theme is designed to be installed on top of and extend the regular [icons theme](https://github.com/elementary/icons) for elementary OS. 17 | 18 | ## Building and Installation 19 | 20 | You'll need the following dependencies: 21 | 22 | * meson 23 | 24 | Run `meson` to configure the build environment and then `ninja` to build 25 | 26 | meson build --prefix=/usr 27 | cd build 28 | ninja 29 | 30 | To install, use `ninja install` 31 | 32 | sudo ninja install 33 | -------------------------------------------------------------------------------- /apps/128/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 149 | -------------------------------------------------------------------------------- /apps/128/zotero.svg: -------------------------------------------------------------------------------- 1 | 2 | 382 | -------------------------------------------------------------------------------- /apps/16/alacritty.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 214 | -------------------------------------------------------------------------------- /apps/16/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 84 | -------------------------------------------------------------------------------- /apps/16/obsidian.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 125 | -------------------------------------------------------------------------------- /apps/16/slack.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 186 | -------------------------------------------------------------------------------- /apps/16/zotero.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 226 | -------------------------------------------------------------------------------- /apps/24/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 136 | -------------------------------------------------------------------------------- /apps/24/slack.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 294 | -------------------------------------------------------------------------------- /apps/24/zotero.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 369 | -------------------------------------------------------------------------------- /apps/32/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 132 | -------------------------------------------------------------------------------- /apps/32/slack.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 282 | -------------------------------------------------------------------------------- /apps/48/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 142 | -------------------------------------------------------------------------------- /apps/64/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 137 | -------------------------------------------------------------------------------- /apps/64/zotero.svg: -------------------------------------------------------------------------------- 1 | 2 | 364 | -------------------------------------------------------------------------------- /apps/meson.build: -------------------------------------------------------------------------------- 1 | fs = import('fs') 2 | icon_sizes = ['16', '24', '32', '48', '64', '128'] 3 | 4 | icon_links = [ 5 | # The first argument is the original icon name, 6 | # the second is the link. 7 | # `alt` files do not get symlinked, 8 | # they should be changed in the relevant `desktop` file 9 | 10 | ['alacritty', 'com.alacritty.Alacritty'], 11 | ['alacritty', 'Alacritty'], 12 | 13 | ['discord', 'com.discordapp.Discord'], 14 | 15 | ['slack', 'com.slack.Slack'], 16 | 17 | ['obsidian', 'md.obsidian.Obsidian'], 18 | 19 | ['zotero', 'org.zotero.Zotero'], 20 | 21 | ['ghostty', 'com.mitchellh.ghostty'], 22 | 23 | ['wezterm', 'org.wezfurlong.wezterm'], 24 | ] 25 | 26 | foreach link : icon_links 27 | foreach size : icon_sizes 28 | # only symlink to files that actually exist 29 | if fs.is_file(size / link[0] + '.svg') 30 | install_symlink( 31 | link[1] + '.svg', 32 | install_dir: icon_dir / 'apps' / size, 33 | pointing_to: link[0] + '.svg', 34 | ) 35 | endif 36 | endforeach 37 | endforeach 38 | -------------------------------------------------------------------------------- /index.theme.in: -------------------------------------------------------------------------------- 1 | [Icon Theme] 2 | Name=expandtheon 3 | Comment=Designed for elementary OS, meshing popular apps with the Pantheon desktop 4 | Inherits=elementary, hicolor 5 | 6 | Example=directory-x-normal 7 | 8 | Directories=@DIRECTORY_LIST@ 9 | @DIRECTORY_DETAILS@ 10 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project ( 2 | 'com.wpkelso.expandtheon', 3 | version: '1.0.0', 4 | meson_version: '>=0.61', 5 | ) 6 | 7 | i18n = import('i18n') 8 | fs = import('fs') 9 | 10 | icon_dir = join_paths(get_option('datadir'), 'icons', 'expandtheon') 11 | 12 | scale_factors = get_option('scale_factors') 13 | 14 | # Add a directory here to the list if needed. 15 | directories = [ 16 | # The first argument is the name of the folder, 17 | # the second is the associated Context 18 | ['apps', 'Applications'], 19 | ] 20 | 21 | # Add a size here to the list if needed. 22 | sizes = ['16', '24', '32', '48', '64', '128', 'symbolic'] 23 | 24 | # Symbolic icons are made to have a maximum size. 25 | max_size_symbolic = '512' 26 | 27 | # This is the minimal size all icons can theorically have. 28 | min_size_ever = '8' 29 | 30 | # Let's do fancy things 31 | msg_warning = false 32 | msg = '\nPLEASE VERIFY THE CONFIGURATION:' 33 | 34 | if (sizes.length() >= 7) 35 | msg += '\nAvailable sizes: @0@ ✔'.format (', '.join (sizes)) 36 | else 37 | msg += '\nAvailable sizes: @0@ ⛔'.format (', '.join (sizes)) 38 | msg_warning = true 39 | endif 40 | 41 | if (scale_factors.length() > 1) 42 | msg += '\nAvailable scale factors: @0@ ✔'.format (', '.join (scale_factors)) 43 | else 44 | msg += '\nAvailable scale factors: @0@ ⛔'.format (', '.join (scale_factors)) 45 | msg_warning = true 46 | endif 47 | 48 | if (get_option('prefix') == '/usr') 49 | msg += '\nInstallation prefix: @0@ ✔'.format (get_option('prefix')) 50 | else 51 | msg += '\nInstallation prefix: @0@ ⛔'.format (get_option('prefix')) 52 | msg_warning = true 53 | endif 54 | 55 | if (msg_warning) 56 | warning(msg + '\n') 57 | else 58 | message(msg + '\n') 59 | endif 60 | 61 | # Here begins the real work 62 | foreach directory : directories 63 | install_subdir( 64 | directory[0], 65 | install_dir : icon_dir 66 | ) 67 | endforeach 68 | 69 | template = ''' 70 | [@0@] 71 | Size=@1@@2@ 72 | Context=@3@ 73 | MinSize=@4@ 74 | MaxSize=@5@ 75 | Type=Scalable''' 76 | 77 | directory_path_list = [] 78 | directory_details = [] 79 | 80 | foreach directory_entry : directories 81 | directory = directory_entry[0] 82 | directory_context = directory_entry[1] 83 | foreach size: sizes 84 | if (fs.exists(meson.project_source_root () / directory / size)) 85 | foreach scale_factor : scale_factors 86 | # The Scale=1 attribute is useless, don't add it 87 | if (scale_factor.to_int() > 1) 88 | scale_entry = '\nScale=@0@'.format (scale_factor) 89 | directory_name = join_paths('@0@@@1@x'.format (directory, scale_factor), size) 90 | else 91 | scale_entry = '' 92 | directory_name = join_paths(directory, size) 93 | endif 94 | 95 | # Append it to add it to the final Directories= line 96 | directory_path_list += directory_name 97 | 98 | if (size == 'symbolic') 99 | size_entry = '16' 100 | # symbolic covers the whole size panel by definition 101 | max_size = max_size_symbolic 102 | else 103 | size_entry = size 104 | # Get the next size on the list 105 | size_found = false 106 | foreach lookup_size: sizes 107 | if (size == lookup_size) 108 | size_found = true 109 | # if the next size if 'symbolic', that means that this is the biggest size. 110 | elif (size_found == true) 111 | if (lookup_size == 'symbolic') 112 | max_size = max_size_symbolic 113 | else 114 | # the maximal icon size of an entry is the next available size minus 1 115 | max_size = (lookup_size.to_int() - 1).to_string() 116 | endif 117 | size_found = false 118 | endif 119 | endforeach 120 | endif 121 | 122 | directory_details += template.format( 123 | directory_name, 124 | size_entry, 125 | scale_entry, 126 | directory_context, 127 | min_size_ever, 128 | max_size 129 | ) 130 | endforeach 131 | else 132 | message ('Directory "@0@/@1@" doesn\'t exist and won\'t be listed in the theme file.'.format (directory, size)) 133 | endif 134 | endforeach 135 | endforeach 136 | 137 | configuration_data_object = configuration_data() 138 | configuration_data_object.set('DIRECTORY_LIST', ','.join (directory_path_list)) 139 | configuration_data_object.set('DIRECTORY_DETAILS', '\n'.join (directory_details)) 140 | 141 | # Create the symlinks 142 | configure_file( 143 | input: 'index.theme.in', 144 | output: '@BASENAME@', 145 | configuration: configuration_data_object, 146 | install_dir: icon_dir 147 | ) 148 | 149 | # Create the symlinks 150 | foreach directoy_entry : directories 151 | foreach scale_factor : scale_factors 152 | # We only create a symlink to the @1 directory, it's all the point of using SVG assets... 153 | if (scale_factor.to_int() > 1) 154 | directory = directory_entry[0] 155 | install_symlink( 156 | '@0@@@1@x'.format(directory, scale_factor), 157 | install_dir: icon_dir, 158 | pointing_to: directory, 159 | ) 160 | endif 161 | endforeach 162 | endforeach 163 | 164 | subdir('apps') 165 | 166 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('scale_factors', type : 'array', value : ['1', '2', '3'], description : 'Available scale factors, add or remove to enable so HiDPI features') 2 | -------------------------------------------------------------------------------- /pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Runs Inkscape vacuum to clean up svgs 4 | 5 | CDIR=$(git rev-parse --show-toplevel) 6 | echo "Running Inkscape vacuum. This may take some time..." 7 | 8 | # Check if Inkscape is a flatpak or not 9 | if [ $(which inkscape &>/dev/null; echo $?) == 0 ]; then 10 | INKSCAPE='inkscape' 11 | else 12 | INKSCAPE='flatpak run org.inkscape.Inkscape' 13 | fi 14 | 15 | git diff --cached --name-status --diff-filter=ACMR | while read STATUS FILE; do 16 | if [[ "$FILE" =~ ^.+(svg)$ ]]; then 17 | $INKSCAPE --vacuum-defs -z $CDIR/$FILE --export-plain-svg=$CDIR/$FILE 18 | fi 19 | done 20 | 21 | git add . 22 | exit 0 23 | --------------------------------------------------------------------------------