├── .gitignore ├── 4ktube_2025.5.23_amd64.snap ├── LICENSE ├── README.md ├── share ├── applications │ └── youtube-downloader-4ktube.desktop ├── icons │ └── icon.png ├── license │ └── LICENSE ├── metainfo │ └── com.warlordsoftwares.youtube-downloader-4ktube.metainfo.xml └── screenshots │ ├── 4ktube-warlordsoftwares_1.jpg │ ├── 4ktube-warlordsoftwares_2.jpg │ ├── 4ktube-warlordsoftwares_3.jpg │ ├── 4ktube-warlordsoftwares_4.jpg │ └── 4ktube-warlordsoftwares_5.jpg ├── snap ├── gui │ └── icon.png └── snapcraft.yaml └── snap_launcher ├── 4ktube.desktop └── bin ├── 4ktube └── desktop-launch /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyo 2 | *.pyc 3 | migrations/ 4 | *.iml 5 | .idea/ 6 | build 7 | dist 8 | formatlab.spec 9 | qrc 10 | resource 11 | -------------------------------------------------------------------------------- /4ktube_2025.5.23_amd64.snap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/4ktube_2025.5.23_amd64.snap -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Rishabh Bhardwaj 2 | 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **ABOUT 4KTUBE :** 2 | 3 | **4KTUBE** is a fast, powerful, and user-friendly application designed to **Download YouTube Videos**, Playlists, and Music in high-definition **(HD, 4K, 8K)** effortlessly. 4 | 5 | ---------- 6 | 7 | 🌟 **WHY CHOOSE 4KTUBE ?** 8 | 9 | ---------- 10 | 11 | 12 | * **One-Click YouTube Video & Audio Downloader :** Save videos in MP4, WEBM, MP3, and more formats instantly. 13 | * **Download Full YouTube Playlists :** Save entire playlists with a single click. 14 | * **YouTube Multi-Language Audio Support :** Download videos with multiple dubbed audio tracks. 15 | * **YouTube Subtitles & Closed Captions Download :** Extract videos with embedded subtitles. 16 | * **Batch Downloading :** Save multiple videos simultaneously for faster downloads. 17 | * **YouTube Music & Audio Extractor :** Convert YouTube videos into high-quality MP3 files. 18 | * **Multi-Platform Video Downloader :** Download from Facebook, Instagram, TikTok, Twitter, Twitch, Vimeo, Rumble, Odysee, Bitchute, Reddit, SoundCloud, and 1400+ other platforms. 19 | * **Ad-Free YouTube Streaming :** Play videos without annoying ads. 20 | * **Super-Fast Download Speeds :** Optimized for high-speed, high-quality downloads. 21 | * **Search YouTube Directly in the App :** Find & download videos quickly with regional language support. 22 | * **Lightweight, Secure & Private :** No ads, no trackers, no malware – just seamless downloads. 23 | * **Added 35+ Popular International Languages :** Global language support for a seamless experience. 24 | 25 | ---------- 26 | 🌟 **WHAT SETS 4KTUBE APART FROM THE OTHER DOWNLOADERS ?** 27 | 28 | ---------- 29 | 30 | * ✅ Supports 4K & 8K Ultra HD Video Downloads 31 | * ✅ Optimized for the Fastest Download Speeds 32 | * ✅ User-Friendly, Minimalist Interface 33 | * ✅ Regular Updates with New Platform Support 34 | 35 | 36 | 📥 **Download 4KTUBE Now & Start Saving Your Favorite Videos in Seconds !** 🔥 37 | 38 | ---------- 39 | **INSTALL 4KTUBE ON LINUX DESKTOP** 40 | 41 | ---------- 42 | 43 | **SNAP PACKAGE** 44 | 45 | [![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/4ktube) 46 | 47 | Install with command-line 48 | 49 | 50 | snap install 4ktube 51 | 52 | 53 | and run 54 | 55 | 56 | 4ktube 57 | 58 | 59 | **FLATPAK PACKAGE** 60 | 61 | Get it from the Flathub Store 62 | 63 | Install with command-line 64 | 65 | 66 | flatpak install flathub com.warlordsoftwares.youtube-downloader-4ktube 67 | 68 | 69 | and run 70 | 71 | 72 | flatpak run com.warlordsoftwares.youtube-downloader-4ktube 73 | 74 | ---------- 75 | **SCREENSHOTS OF 4KTUBE** 76 | 77 | ---------- 78 | 79 | ![4KTUBE](https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_1.jpg?raw=true) 80 | 81 | ![4KTUBE](https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_2.jpg?raw=true) 82 | 83 | ![4KTUBE](https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_3.jpg?raw=true) 84 | 85 | ![4KTUBE](https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_4.jpg?raw=true) 86 | 87 | ---------- 88 | **🔧 IMPORTANT NOTES FOR SNAP USERS !** 89 | 90 | ---------- 91 | 92 | 📌 **Enable Removable Media Access** : To allow downloads to external storage **(USB, SD cards, etc.)**, run: 93 | 94 | 95 | sudo snap connect 4ktube:removable-media 96 | 97 | 98 | 📌 **Fix CPU Temperature in System Monitor** : If the CPU temperature is not displaying correctly, run: 99 | 100 | 101 | sudo snap connect 4ktube:hardware-observe 102 | 103 | 104 | 📌 **App Not Launching After Installation?** : If the app fails to start, fix it with: 105 | 106 | 107 | sudo snap remove 4ktube; sudo snap remove pyqt5-runtime-core22 --purge; sudo snap install pyqt5-runtime-core22; sudo snap install 4ktube; 4ktube 108 | 109 | 110 | Info: Some features may require in-app purchases. 111 | 112 | ---------- 113 | 114 | 115 | *🎯 _(Keywords):_* 116 | 117 | * _YouTube Video Downloader (4K, 8K, HD, MP3)_ 118 | * _YouTube Playlist & Shorts Downloader_ 119 | * _YouTube to MP3, WAV, AAC, FLAC Converter_ 120 | * _Facebook, Instagram, TikTok, Twitter, Twitch, Reddit Video Downloader_ 121 | * _SnapDownloader, Y2mate, SaveFrom, Allavsoft, VideoProc, 4K Video Downloader, Snaptube_ 122 | * _BitDownloader, iTubeGo, YouTube Dashboard, VideoSolo Inovideo, Snapchat Video Downloader_ 123 | * _YTD Video Downloader, VideoHunter, SaveFrom, Addoncrop, ClipGrab, Snaptube_ 124 | * _LinkedIn, ESPN, Yahoo, Brighteon, Pinterest, SoundCloud Downloader_ 125 | 126 | 127 | _(Hashtags):_ 128 | #YouTubeDownloader #4KVideoDownloader #YouTubeToMP3 #SnapDownloader #DownloadYouTubeVideos #MP3Converter #FacebookVideoDownloader #InstagramVideoDownloader #TikTokDownloader #PlaylistDownloader #NoAdsVideoStreaming #BatchDownloadVideos #YouTubePlaylistDownloader #YouTubeToMP3Converter #RumbleDownloader #DownloadOnlineVideos #VideoDownloaderApp #FreeVideoDownloader 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /share/applications/youtube-downloader-4ktube.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=4KTUBE 3 | StartupWMClass=4KTUBE 4 | Comment=4Ktube for Desktop 5 | GenericName=4Ktube for Linux 6 | Exec=4ktube.sh %u 7 | Icon=com.warlordsoftwares.youtube-downloader-4ktube 8 | Terminal=false 9 | Type=Application 10 | StartupNotify=true 11 | Keywords=youtube downloader;video downloader;music downloader;playlist downloader;full HD downloader;audio downloader; youtube; youtube music; 12 | Categories=Utility;Qt; -------------------------------------------------------------------------------- /share/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/icons/icon.png -------------------------------------------------------------------------------- /share/license/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Rishabh Bhardwaj 2 | 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 9 | SOFTWARE. 10 | -------------------------------------------------------------------------------- /share/metainfo/com.warlordsoftwares.youtube-downloader-4ktube.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.warlordsoftwares.youtube-downloader-4ktube 4 | CC0-1.0 5 | LicenseRef-proprietary=https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/license/LICENSE 6 | Warlord Softwares 7 | 8 | #e6e6e6 9 | #161d1d 10 | 11 | 4KTUBE 12 | 4K YouTube Downloader – Download HD YouTube Videos, Playlists, and Music Instantly. 13 | 14 |

ABOUT 4KTUBE :

15 |

4KTUBE is a fast, powerful, and user-friendly application designed to download YouTube videos, playlists, and music in high-definition (HD, 4K, 8K) effortlessly.

16 |

WHY CHOOSE 4KTUBE?

17 | 30 |

WHAT SETS 4KTUBE APART?

31 | 37 |

LANGUAGE SUPPORT :

38 | 41 |
42 | 43 | 44 | 4KTUBE 45 | SnapDownloader 46 | By Click Downloader 47 | VideoHunter 48 | Youtube to mp3 49 | snaptube 50 | youtube dl 51 | video downloader 52 | VideoSolo 53 | Inovideo 54 | MP3 Studio 55 | Leawo 56 | iTubeGo 57 | YouTube to MP3 58 | Audio downloader 59 | Online video downloader 60 | Batch video downloader 61 | Free YouTube downloader 62 | Playlist downloader 63 | Download YouTube videos 64 | Download 4K videos 65 | xvideos downloader 66 | xhamster downloader 67 | xnxx downloader 68 | tube8 downloader 69 | pornhub downloader 70 | youporn downloader 71 | redtube downloader 72 | iporntv downloader 73 | ixxx downloader 74 | beeg downloader 75 | 4K YouTube to MP3 76 | YouTube 4K downloader 77 | Music downloader 78 | 4K Video Downloader 79 | Video downloader for YouTube 80 | Music downloader 81 | Media Downloader 82 | VideoProc 83 | Y2mate 84 | SaveFrom 85 | Youtube Download 86 | SaveMedia 87 | Addoncrop 88 | YouTube Video Downloader 89 | Facebook downloader 90 | Instagram downloader 91 | Tiktok downloader 92 | Youtube shots downloader 93 | Rumble video downloader 94 | All file downloader 95 | Snapchat downloader 96 | linkedin video downloader 97 | SoundCloud Downloader 98 | 99 | YouTube zu MP3 100 | Video-Downloader 101 | Kostenloser YouTube-Downloader 102 | YouTube-Videos herunterladen 103 | 4K-Videos herunterladen 104 | Musik-Downloader 105 | Alle-Dateien-Downloader 106 | Video-Downloader für YouTube 107 | 108 | Téléchargeur de vidéos en ligne 109 | Téléchargeur de vidéos par lot 110 | Téléchargeur YouTube gratuit 111 | Télécharger des vidéos YouTube 112 | Téléchargeur YouTube 4K 113 | 114 | Scaricatore di video 115 | Scaricatore di video online 116 | Scaricatore YouTube 4K 117 | 118 | Descargador gratuito de YouTube 119 | Descargar videos en 4K 120 | Descargador de videos para YouTube 121 | 122 | 無料の YouTube ダウンローダー 123 | 4K ビデオダウンローダー 124 | YouTube ビデオをダウンロード 125 | 126 | Ladda ner YouTube-videor 127 | YouTube 4K nedladdare 128 | Online videonedladdare 129 | 130 | 131 | Utility 132 | AudioVideo 133 | 134 | 135 | 136 | 4KTUBE: YouTube home page 137 | https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_1.jpg 138 | 139 | 140 | 4KTUBE: Video download page 141 | https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_2.jpg 142 | 143 | 144 | 4KTUBE: System monitor page 145 | https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_3.jpg 146 | 147 | 148 | 4KTUBE: About me page 149 | https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_4.jpg 150 | 151 | 152 | 4KTUBE: App settings page 153 | https://raw.githubusercontent.com/rishabh3354/4KTUBE/main/share/screenshots/4ktube-warlordsoftwares_5.jpg 154 | 155 | 156 | https://warlordsoftwares.com/trending-apps/4ktube-pro-best-youtube-video-downloader-linux/ 157 | https://github.com/rishabh3354/4KTUBE/ 158 | https://github.com/rishabh3354/4KTUBE/issues 159 | https://warlordsoftwares.com/contact-us/ 160 | https://www.paypal.me/rishabh3354/10 161 | contact@warlordsoftwares.com 162 | com.warlordsoftwares.youtube-downloader-4ktube.desktop 163 | 164 | 165 | 166 | 167 |

Fix: Download only 720p YouTube videos bug fixed

168 |

Other improvements and fixes

169 |
170 |
171 | 172 | 173 |

New feature added: Automated account restore portal linked via restore button.

174 |

Other platform engine fixes - twitter, twitch etc.

175 |

MPV Player issue fixed.

176 |

Version api check for updates improvements.

177 |
178 |
179 | 180 | 181 |

New feature added: Automated account restore portal linked via restore button

182 |

Other platform engine fixes - twitter, twitch etc

183 |

MPV Player issue fixed.

184 |
185 |
186 | 187 | 188 |

New feature added: Now you can check for urgent app updates from about me tab

189 |

Error message standardization and improvements

190 |

Window icon fixed for main windows

191 |
192 |
193 | 194 | 195 |

Added YouTube Multi-Language Audio Support.

196 |

Added support for downloading from new platforms like twitter, twitch, vimeo etc..

197 |

Added new restore account button in account section.

198 |

New servers added for better reliability of downloads.

199 |

YouTube video download size fix.

200 |

History file details UI enhancement.

201 |

Error message standardization.

202 |

MPV Player issue fixed.

203 |
204 |
205 | 206 | 207 |

Added YouTube Multi-Language Audio Support.

208 |

Added support for downloading from new platforms like twitter, twitch, vimeo etc..

209 |

Added new restore account button in account section.

210 |

New servers added for better reliability of downloads.

211 |

YouTube video download size fix.

212 |

History file details UI enhancement.

213 |

Error message standardization.

214 |

MPV Player issue fixed.

215 |
216 |
217 | 218 | 219 |

Added YouTube Multi-Language Audio Support.

220 |

Added support for downloading from new platforms like twitter, twitch, vimeo etc..

221 |

Added new restore account button in account section.

222 |

New servers added for better reliability of downloads.

223 |

YouTube video download size fix.

224 |

History file details UI enhancement.

225 |

Error message standardization.

226 |

MPV Player issue fixed.

227 |
228 |
229 | 230 | 231 |

New Features:

232 |
    233 |
  • Added YouTube Multi-Language Audio Support.
  • 234 |
  • Added support for downloading from new platforms like twitter, twitch, vimeo etc..
  • 235 |
  • Added new restore account button in account section.
  • 236 |
237 |

Bug Fixes and Improvements:

238 |
    239 |
  • New servers added for better reliability of downloads.
  • 240 |
  • YouTube video download size fix.
  • 241 |
  • History file details UI enhancement.
  • 242 |
  • Error message standardization.
  • 243 |
  • MPV Player issue fixed.
  • 244 |
245 |
246 |
247 | 248 | 249 |

Download engine fixes and improvements

250 |
251 |
252 | 253 | 254 |

Bug fixes and Improvements

255 |
    256 |
  • Now supports 35+ Country Languages
  • 257 |
  • Bug fixes: Combo-box for settings
  • 258 |
  • Mpv streaming player video title issue fixed
  • 259 |
260 |
261 |
262 | 263 | 264 |

Now supports 35+ Country Languages

265 |

Bug fixes: Combo-box for settings

266 |

Mpv streaming player video title issue fixed

267 |
268 |
269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 |
278 |
-------------------------------------------------------------------------------- /share/screenshots/4ktube-warlordsoftwares_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/screenshots/4ktube-warlordsoftwares_1.jpg -------------------------------------------------------------------------------- /share/screenshots/4ktube-warlordsoftwares_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/screenshots/4ktube-warlordsoftwares_2.jpg -------------------------------------------------------------------------------- /share/screenshots/4ktube-warlordsoftwares_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/screenshots/4ktube-warlordsoftwares_3.jpg -------------------------------------------------------------------------------- /share/screenshots/4ktube-warlordsoftwares_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/screenshots/4ktube-warlordsoftwares_4.jpg -------------------------------------------------------------------------------- /share/screenshots/4ktube-warlordsoftwares_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/share/screenshots/4ktube-warlordsoftwares_5.jpg -------------------------------------------------------------------------------- /snap/gui/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/snap/gui/icon.png -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: 4ktube 2 | base: core22 3 | version: '2025.5.23' 4 | summary: Download youtube videos, playlist and music audio in full HD formats 5 | description: 4KTUBE is a powerful GUI application for linux for downloading youtube videos, playlist and music audio in full UHD+ resolutions and supports MP4, WEBM and MP3 formats. 6 | grade: stable 7 | confinement: strict 8 | 9 | icon: snap/gui/icon.png 10 | 11 | architectures: 12 | - build-on: [amd64] 13 | 14 | environment: 15 | SNAP_DESKTOP_RUNTIME: $SNAP/pyqt5-runtime-core22 16 | 17 | apps: 18 | 4ktube: 19 | command: bin/desktop-launch 4ktube 20 | desktop: 4ktube.desktop 21 | environment: 22 | DISABLE_WAYLAND: 1 23 | 24 | plugs: 25 | - home 26 | - gsettings 27 | - network 28 | - network-bind 29 | - network-status 30 | - desktop 31 | - desktop-legacy 32 | - x11 33 | - unity7 34 | - wayland 35 | - opengl 36 | - audio-playback 37 | - hardware-observe 38 | - optical-drive 39 | - removable-media 40 | 41 | plugs: 42 | gsettings: 43 | gtk-3-themes: 44 | interface: content 45 | target: $SNAP/data-dir/themes 46 | default-provider: gtk-common-themes 47 | icon-themes: 48 | interface: content 49 | target: $SNAP/data-dir/icons 50 | default-provider: gtk-common-themes 51 | sound-themes: 52 | interface: content 53 | target: $SNAP/data-dir/sounds 54 | default-provider: gtk-common-themes 55 | pyqt5-runtime-core22: 56 | interface: content 57 | target: $SNAP/pyqt5-runtime-core22 58 | default-provider: pyqt5-runtime-core22 59 | 60 | parts: 61 | snap-launcher: 62 | plugin: dump 63 | source: snap_launcher/ 64 | override-build: | 65 | craftctl default 66 | sed -i 's|Icon=.*|Icon=${SNAP}/meta/gui/icon.png|g' ${SNAPCRAFT_PART_SRC}/4ktube.desktop 67 | mkdir -p ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/ 68 | cp -rf ${SNAPCRAFT_PART_SRC}/4ktube.desktop ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/4ktube.desktop 69 | -------------------------------------------------------------------------------- /snap_launcher/4ktube.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | GenericName=4ktube 4 | Name=4KTUBE 5 | Type=Application 6 | Icon=4ktube.png 7 | Keywords=youtube downloader;video downloader;music downloader;playlist downloader;full HD downloader;audio downloader; youtube; youtube music; 8 | Exec=4ktube %F 9 | Categories=Utility;Qt; 10 | Terminal=false 11 | Name[en_US]=4KTUBE -------------------------------------------------------------------------------- /snap_launcher/bin/4ktube: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishabh3354/4KTUBE/81821974b649238f88a5f6d8118559f94c53a3ff/snap_launcher/bin/4ktube -------------------------------------------------------------------------------- /snap_launcher/bin/desktop-launch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################# 3 | # Launcher init # 4 | ################# 5 | 6 | # shellcheck disable=SC2034 7 | START=$(date +%s.%N) 8 | 9 | # ensure_dir_exists calls `mkdir -p` if the given path is not a directory. 10 | # This speeds up execution time by avoiding unnecessary calls to mkdir. 11 | # 12 | # Usage: ensure_dir_exists []... 13 | # 14 | function ensure_dir_exists() { 15 | [ -d "$1" ] || mkdir -p "$@" 16 | } 17 | 18 | declare -A PIDS 19 | function async_exec() { 20 | "$@" & 21 | PIDS[$!]=$* 22 | } 23 | function wait_for_async_execs() { 24 | for pid in "${!PIDS[@]}" 25 | do 26 | wait "$pid" && continue || echo "ERROR: ${PIDS[$pid]} exited abnormally with status $?" 27 | done 28 | } 29 | 30 | # shellcheck source=/dev/null 31 | 32 | source "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true 33 | if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then 34 | needs_update=false 35 | else 36 | needs_update=true 37 | fi 38 | 39 | 40 | # Set $REALHOME to the users real home directory 41 | REALHOME=$(getent passwd $UID | cut -d ':' -f 6) 42 | 43 | # Set config folder to local path 44 | export XDG_CONFIG_HOME="$SNAP_USER_DATA/.config" 45 | ensure_dir_exists "$XDG_CONFIG_HOME" 46 | chmod 700 "$XDG_CONFIG_HOME" 47 | 48 | # If there is no user user-dirs, don't check for the checksum 49 | if [[ -f "$REALHOME/.config/user-dirs.dirs" ]]; then 50 | # If the user has modified their user-dirs settings, force an update 51 | if [[ -f "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" ]]; then 52 | if [[ "$(md5sum < "$REALHOME/.config/user-dirs.dirs")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum")" || 53 | ( -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" && 54 | "$(md5sum < "$REALHOME/.config/user-dirs.locale")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.locale.md5sum")" ) ]]; then 55 | needs_update=true 56 | fi 57 | else 58 | # shellcheck disable=SC2034 59 | needs_update=true 60 | fi 61 | fi 62 | 63 | if [ "$SNAP_ARCH" = "amd64" ]; then 64 | ARCH="x86_64-linux-gnu" 65 | elif [ "$SNAP_ARCH" = "armhf" ]; then 66 | ARCH="arm-linux-gnueabihf" 67 | elif [ "$SNAP_ARCH" = "arm64" ]; then 68 | ARCH="aarch64-linux-gnu" 69 | elif [ "$SNAP_ARCH" = "ppc64el" ]; then 70 | ARCH="powerpc64le-linux-gnu" 71 | else 72 | ARCH="$SNAP_ARCH-linux-gnu" 73 | fi 74 | 75 | export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH" 76 | 77 | # Don't LD_PRELOAD bindtextdomain for classic snaps 78 | if ! grep -qs "^\s*confinement:\s*classic\s*" "$SNAP/meta/snap.yaml"; then 79 | if [ -f "$SNAP/gnome-platform/lib/$ARCH/bindtextdomain.so" ]; then 80 | export LD_PRELOAD="$LD_PRELOAD:$SNAP/gnome-platform/\$LIB/bindtextdomain.so" 81 | elif [ -f "$SNAP/lib/$ARCH/bindtextdomain.so" ]; then 82 | export LD_PRELOAD="$LD_PRELOAD:$SNAP/\$LIB/bindtextdomain.so" 83 | fi 84 | fi 85 | ############################################### 86 | # Launcher common exports for any desktop app # 87 | ############################################### 88 | 89 | # Note: We avoid using `eval` because we don't want to expand variable names 90 | # in paths. For example: LD_LIBRARY_PATH paths might contain `$LIB`. 91 | function prepend_dir() { 92 | local -n var="$1" 93 | local dir="$2" 94 | # We can't check if the dir exists when the dir contains variables 95 | if [[ "$dir" == *"\$"* || -d "$dir" ]]; then 96 | export "${!var}=${dir}${var:+:$var}" 97 | fi 98 | } 99 | 100 | function append_dir() { 101 | local -n var="$1" 102 | local dir="$2" 103 | # We can't check if the dir exists when the dir contains variables 104 | if [[ "$dir" == *"\$"* || -d "$dir" ]]; then 105 | export "${!var}=${var:+$var:}${dir}" 106 | fi 107 | } 108 | 109 | function can_open_file() { 110 | [ -f "$1" ] && [ -r "$1" ] 111 | } 112 | 113 | function update_xdg_dirs_values() { 114 | local save_initial_values=false 115 | local XDG_DIRS="DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES" 116 | unset XDG_SPECIAL_DIRS_PATHS 117 | 118 | if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" ]; then 119 | # shellcheck source=/dev/null 120 | source "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" 121 | fi 122 | 123 | if [ -z ${XDG_SPECIAL_DIRS+x} ]; then 124 | save_initial_values=true 125 | fi 126 | 127 | for d in $XDG_DIRS; do 128 | var="XDG_${d}_DIR" 129 | value="${!var}" 130 | 131 | if [ "$save_initial_values" = true ]; then 132 | XDG_SPECIAL_DIRS+=("$var") 133 | XDG_SPECIAL_DIRS_INITIAL_PATHS+=("$value") 134 | fi 135 | 136 | XDG_SPECIAL_DIRS_PATHS+=("$value") 137 | done 138 | } 139 | 140 | function is_subpath() { 141 | dir="$(realpath "$1")" 142 | parent="$(realpath "$2")" 143 | [ "${dir##"${parent}"/}" != "${dir}" ] && return 0 || return 1 144 | } 145 | 146 | #RUNTIME_NAME 147 | RUNTIME_NAME="pyqt5-runtime-core22" 148 | 149 | if ! snapctl is-connected $RUNTIME_NAME; then 150 | echo "ERROR: not connected to the $RUNTIME_NAME content interface." 151 | exit 1 152 | fi 153 | 154 | # Fix QtWebEngine resource paths 155 | 156 | 157 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib/$ARCH" 158 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" 159 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib" 160 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib" 161 | 162 | 163 | append_dir PATH "$SNAP_DESKTOP_RUNTIME/usr/bin" 164 | 165 | #samba lib path 166 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/samba/" 167 | 168 | #python 3.10 path 169 | export PYTHONPATH=${PYTHONPATH}:$SNAP_DESKTOP_RUNTIME/usr/lib/python310.zip:$SNAP_DESKTOP_RUNTIME/usr/lib/python3.10:$SNAP_DESKTOP_RUNTIME/usr/lib/python3.10/lib-dynload:$SNAP_DESKTOP_RUNTIME/usr/lib/python3/dist-packages:$SNAP_DESKTOP_RUNTIME/lib/python3.10/site-packages 170 | 171 | #python 3.10 path for pyinstaller 172 | export PYINSTALLER_PYTHONPATH=${PYINSTALLER_PYTHONPATH}:$PYTHONPATH 173 | 174 | # QT platform by warlord 175 | export QT_QPA_PLATFORM_PLUGIN_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/plugins" 176 | 177 | # XKB config 178 | export XKB_CONFIG_ROOT="$SNAP_DESKTOP_RUNTIME/usr/share/X11/xkb" 179 | 180 | # Give XOpenIM a chance to locate locale data. 181 | # This is required for text input to work in SDL2 games. 182 | export XLOCALEDIR="$SNAP_DESKTOP_RUNTIME/usr/share/X11/locale" 183 | 184 | # Set XCursors path 185 | export XCURSOR_PATH="$SNAP_DESKTOP_RUNTIME/usr/share/icons" 186 | prepend_dir XCURSOR_PATH "$SNAP/data-dir/icons" 187 | 188 | # Mesa Libs for OpenGL support 189 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/mesa" 190 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/mesa-egl" 191 | 192 | # Tell libGL and libva where to find the drivers 193 | export LIBGL_DRIVERS_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/dri" 194 | append_dir LD_LIBRARY_PATH "$LIBGL_DRIVERS_PATH" 195 | append_dir LIBVA_DRIVERS_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/dri" 196 | 197 | # Set where the VDPAU drivers are located 198 | export VDPAU_DRIVER_PATH="/usr/lib/$ARCH/vdpau/" 199 | if [ -e "/var/lib/snapd/lib/gl/vdpau/libvdpau_nvidia.so" ]; then 200 | export VDPAU_DRIVER_PATH="/var/lib/snapd/lib/gl/vdpau" 201 | # Prevent picking VA-API (Intel/AMD) over NVIDIA VDPAU; on PRIME systems for example 202 | unset LIBVA_DRIVERS_PATH 203 | fi 204 | 205 | # Workaround in snapd for proprietary nVidia drivers mounts the drivers in 206 | # /var/lib/snapd/lib/gl that needs to be in LD_LIBRARY_PATH 207 | # Without that OpenGL using apps do not work with the nVidia drivers. 208 | # Ref.: https://bugs.launchpad.net/snappy/+bug/1588192 209 | append_dir LD_LIBRARY_PATH "/var/lib/snapd/lib/gl" 210 | append_dir LD_LIBRARY_PATH "/var/lib/snapd/lib/gl/vdpau" 211 | 212 | # Unity7 export (workaround for https://launchpad.net/bugs/1638405) 213 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/libunity" 214 | 215 | # Pulseaudio export 216 | append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/pulseaudio" 217 | 218 | # EGL vendor files on glvnd enabled systems 219 | prepend_dir __EGL_VENDOR_LIBRARY_DIRS "/var/lib/snapd/lib/glvnd/egl_vendor.d" 220 | append_dir __EGL_VENDOR_LIBRARY_DIRS "$SNAP_DESKTOP_RUNTIME/usr/share/glvnd/egl_vendor.d" 221 | 222 | # Tell GStreamer where to find its plugins 223 | export GST_PLUGIN_PATH="$SNAP/usr/lib/$ARCH/gstreamer-1.0" 224 | export GST_PLUGIN_SYSTEM_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/gstreamer-1.0" 225 | # gst plugin scanner doesn't install in the correct path: https://github.com/ubuntu/snapcraft-desktop-helpers/issues/43 226 | export GST_PLUGIN_SCANNER="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner" 227 | 228 | # XDG Config 229 | prepend_dir XDG_CONFIG_DIRS "$SNAP_DESKTOP_RUNTIME/etc/xdg" 230 | prepend_dir XDG_CONFIG_DIRS "$SNAP/etc/xdg" 231 | 232 | # Define snaps' own data dir 233 | prepend_dir XDG_DATA_DIRS "$SNAP_DESKTOP_RUNTIME/usr/share" 234 | prepend_dir XDG_DATA_DIRS "$SNAP/usr/share" 235 | prepend_dir XDG_DATA_DIRS "$SNAP/share" 236 | prepend_dir XDG_DATA_DIRS "$SNAP/data-dir" 237 | prepend_dir XDG_DATA_DIRS "$SNAP_USER_DATA" 238 | 239 | # Set XDG_DATA_HOME to local path 240 | export XDG_DATA_HOME="$SNAP_USER_DATA/.local/share" 241 | ensure_dir_exists "$XDG_DATA_HOME" 242 | 243 | #update mime if mime dir doesn't exist 244 | MIME_DIRECTORY="$XDG_DATA_HOME/mime" 245 | if [ ! -d "$MIME_DIRECTORY" ]; then 246 | needs_update=true 247 | fi 248 | 249 | # Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME: 250 | # https://bugzilla.gnome.org/show_bug.cgi?id=741335 251 | prepend_dir XDG_DATA_DIRS "$XDG_DATA_HOME" 252 | 253 | # Set cache folder to local path 254 | export XDG_CACHE_HOME="$SNAP_USER_COMMON/.cache" 255 | if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$XDG_CACHE_HOME" ]]; then 256 | # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it 257 | mv "$SNAP_USER_DATA/.cache" "$SNAP_USER_COMMON/" 258 | fi 259 | ensure_dir_exists "$XDG_CACHE_HOME" 260 | 261 | # Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed) 262 | # shellcheck disable=SC2174 263 | ensure_dir_exists "$XDG_RUNTIME_DIR" -m 700 264 | 265 | # Ensure the app finds locale definitions (requires locales-all to be installed) 266 | append_dir LOCPATH "$SNAP_DESKTOP_RUNTIME/usr/lib/locale" 267 | 268 | # If any, keep track of where XDG dirs were so we can potentially migrate the content later 269 | update_xdg_dirs_values 270 | 271 | # Setup user-dirs.* or run xdg-user-dirs-update if needed 272 | needs_xdg_update=false 273 | needs_xdg_reload=false 274 | needs_xdg_links=false 275 | 276 | if [ "$HOME" != "$SNAP_USER_DATA" ] && ! is_subpath "$XDG_CONFIG_HOME" "$HOME"; then 277 | for f in user-dirs.dirs user-dirs.locale; do 278 | if [ -f "$HOME/.config/$f" ]; then 279 | mv "$HOME/.config/$f" "$XDG_CONFIG_HOME" 280 | needs_xdg_reload=true 281 | fi 282 | done 283 | fi 284 | 285 | if can_open_file "$REALHOME/.config/user-dirs.dirs"; then 286 | # shellcheck disable=SC2154 287 | if [ "$needs_update" = true ] || [ "$needs_xdg_reload" = true ]; then 288 | sed "/^#/!s#\$HOME#${REALHOME}#g" "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs" 289 | md5sum < "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" 290 | # It's possible user-dirs.dirs exists when user-dirs.locale doesn't. This 291 | # simply means the user opted to never ask to translate their user dirs 292 | if can_open_file "$REALHOME/.config/user-dirs.locale"; then 293 | cp -a "$REALHOME/.config/user-dirs.locale" "$XDG_CONFIG_HOME" 294 | md5sum < "$REALHOME/.config/user-dirs.locale" > "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" 295 | elif [ -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" ]; then 296 | rm "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" 297 | fi 298 | needs_xdg_reload=true 299 | fi 300 | else 301 | needs_xdg_update=true 302 | needs_xdg_links=true 303 | fi 304 | 305 | if [ $needs_xdg_reload = true ]; then 306 | update_xdg_dirs_values 307 | needs_xdg_reload=false 308 | fi 309 | 310 | # Check if we can actually read the contents of each xdg dir 311 | for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do 312 | if ! can_open_file "${XDG_SPECIAL_DIRS_PATHS[$i]}"; then 313 | needs_xdg_update=true 314 | needs_xdg_links=true 315 | break 316 | fi 317 | done 318 | 319 | # If needs XDG update and xdg-user-dirs-update exists in $PATH, run it 320 | if [ "$needs_xdg_update" = true ] && command -v xdg-user-dirs-update >/dev/null; then 321 | xdg-user-dirs-update 322 | update_xdg_dirs_values 323 | fi 324 | 325 | # Create links for user-dirs.dirs 326 | if [ "$needs_xdg_links" = true ]; then 327 | for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do 328 | b="$(realpath "${XDG_SPECIAL_DIRS_PATHS[$i]}" --relative-to="$HOME" 2>/dev/null)" 329 | if [[ -n "$b" && "$b" != "." && -e "$REALHOME/$b" ]]; then 330 | [ -d "$HOME/$b" ] && rmdir "$HOME/$b" 2> /dev/null 331 | [ ! -e "$HOME/$b" ] && ln -s "$REALHOME/$b" "$HOME/$b" 332 | fi 333 | done 334 | else 335 | # If we aren't creating new links, check if we have content saved in old locations and move it 336 | for ((i = 0; i < ${#XDG_SPECIAL_DIRS[@]}; i++)); do 337 | old="${XDG_SPECIAL_DIRS_INITIAL_PATHS[$i]}" 338 | new="${XDG_SPECIAL_DIRS_PATHS[$i]}" 339 | if [ -L "$old" ] && [ -d "$new" ] && [ "$(readlink "$old" 2>/dev/null)" != "$new" ] && 340 | (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then 341 | mv -vn "$old"/* "$new"/ 2>/dev/null 342 | elif [ -d "$old" ] && [ -d "$new" ] && [ "$old" != "$new" ] && 343 | (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then 344 | mv -vn "$old"/* "$new"/ 2>/dev/null 345 | fi 346 | done 347 | fi 348 | 349 | # If detect wayland server socket, then set environment so applications prefer 350 | # wayland, and setup compat symlink (until we use user mounts. Remember, 351 | # XDG_RUNTIME_DIR is /run/user//snap.$SNAP so look in the parent directory 352 | # for the socket. For details: 353 | # https://forum.snapcraft.io/t/wayland-dconf-and-xdg-runtime-dir/186/10 354 | # Applications that don't support wayland natively may define DISABLE_WAYLAND 355 | # (to any non-empty value) to skip that logic entirely. 356 | wayland_available=false 357 | if [[ -n "$XDG_RUNTIME_DIR" && -z "$DISABLE_WAYLAND" ]]; then 358 | wdisplay="wayland-0" 359 | if [ -n "$WAYLAND_DISPLAY" ]; then 360 | wdisplay="$WAYLAND_DISPLAY" 361 | fi 362 | wayland_sockpath="$XDG_RUNTIME_DIR/../$wdisplay" 363 | wayland_snappath="$XDG_RUNTIME_DIR/$wdisplay" 364 | if [ -S "$wayland_sockpath" ]; then 365 | # if running under wayland, use it 366 | #export WAYLAND_DEBUG=1 367 | # shellcheck disable=SC2034 368 | wayland_available=true 369 | # create the compat symlink for now 370 | if [ ! -e "$wayland_snappath" ]; then 371 | ln -s "$wayland_sockpath" "$wayland_snappath" 372 | fi 373 | fi 374 | fi 375 | 376 | # Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR 377 | if [ -n "$XDG_RUNTIME_DIR" ]; then 378 | pulsenative="pulse/native" 379 | pulseaudio_sockpath="$XDG_RUNTIME_DIR/../$pulsenative" 380 | if [ -S "$pulseaudio_sockpath" ]; then 381 | export PULSE_SERVER="unix:${pulseaudio_sockpath}" 382 | fi 383 | fi 384 | 385 | # GI repository 386 | prepend_dir GI_TYPELIB_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/girepository-1.0" 387 | prepend_dir GI_TYPELIB_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/girepository-1.0" 388 | prepend_dir GI_TYPELIB_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/gjs/girepository-1.0" 389 | prepend_dir GI_TYPELIB_PATH "$SNAP/usr/lib/$ARCH/girepository-1.0" 390 | prepend_dir GI_TYPELIB_PATH "$SNAP/usr/lib/girepository-1.0" 391 | prepend_dir GI_TYPELIB_PATH "$SNAP/usr/lib/gjs/girepository-1.0" 392 | 393 | # Keep an array of data dirs, for looping through them 394 | IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS" 395 | 396 | # Font Config and themes 397 | export FONTCONFIG_PATH="$SNAP_DESKTOP_RUNTIME/etc/fonts" 398 | export FONTCONFIG_FILE="$SNAP_DESKTOP_RUNTIME/etc/fonts/fonts.conf" 399 | 400 | function make_user_fontconfig { 401 | echo "" 402 | if [ -d "$REALHOME/.local/share/fonts" ]; then 403 | echo " $REALHOME/.local/share/fonts" 404 | fi 405 | if [ -d "$REALHOME/.fonts" ]; then 406 | echo " $REALHOME/.fonts" 407 | fi 408 | for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do 409 | if [ -d "${data_dirs_array[$i]}/fonts" ]; then 410 | echo " ${data_dirs_array[$i]}/fonts" 411 | fi 412 | done 413 | # fix font render for modified fonts, that discussed on Snapcraft Forum: 414 | # https://forum.snapcraft.io/t/snap-package-cannot-read-fonts-conf/16657 415 | echo ' /etc/fonts/conf.d' 416 | echo ' conf.d' 417 | # We need to include a user-writable cachedir first to support 418 | # caching of per-user fonts. 419 | echo ' fontconfig' 420 | echo " $SNAP_COMMON/fontconfig" 421 | echo "" 422 | } 423 | 424 | if [ "$needs_update" = true ]; then 425 | rm -rf "$XDG_DATA_HOME"/{fontconfig,fonts,fonts-*,themes,.themes} 426 | 427 | # This fontconfig fragment is installed in a location that is 428 | # included by the system fontconfig configuration: namely the 429 | # etc/fonts/conf.d/50-user.conf file. 430 | ensure_dir_exists "$XDG_CONFIG_HOME/fontconfig" 431 | async_exec make_user_fontconfig > "$XDG_CONFIG_HOME/fontconfig/fonts.conf" 432 | 433 | # the themes symlink are needed for GTK 3.18 when the prefix isn't changed 434 | # GTK 3.20 looks into XDG_DATA_DIRS which has connected themes. 435 | if [ -d "$SNAP/data-dir/themes" ]; then 436 | ln -sf "$SNAP/data-dir/themes" "$XDG_DATA_HOME" 437 | ln -sfn "$SNAP/data-dir/themes" "$SNAP_USER_DATA/.themes" 438 | elif [ -d "$SNAP_DESKTOP_RUNTIME/usr/share/themes" ]; then 439 | ln -sf "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$XDG_DATA_HOME" 440 | ln -sfn "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$SNAP_USER_DATA/.themes" 441 | fi 442 | fi 443 | 444 | # Build mime.cache 445 | # needed for gtk and qt icon 446 | if [ "$needs_update" = true ]; then 447 | rm -rf "$XDG_DATA_HOME/mime" 448 | if [ ! -f "$SNAP_DESKTOP_RUNTIME/usr/share/mime/mime.cache" ]; then 449 | if command -v update-mime-database >/dev/null; then 450 | cp --preserve=timestamps -dR "$SNAP_DESKTOP_RUNTIME/usr/share/mime" "$XDG_DATA_HOME" 451 | async_exec update-mime-database "$XDG_DATA_HOME/mime" 452 | fi 453 | fi 454 | fi 455 | 456 | # Gio modules and cache (including gsettings module) 457 | export GIO_MODULE_DIR="$XDG_CACHE_HOME/gio-modules" 458 | function compile_giomodules { 459 | if [ -f "$1/glib-2.0/gio-querymodules" ]; then 460 | rm -rf "$GIO_MODULE_DIR" 461 | ensure_dir_exists "$GIO_MODULE_DIR" 462 | ln -s "$1"/gio/modules/*.so "$GIO_MODULE_DIR" 463 | "$1/glib-2.0/gio-querymodules" "$GIO_MODULE_DIR" 464 | fi 465 | } 466 | if [ "$needs_update" = true ]; then 467 | async_exec compile_giomodules "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" 468 | fi 469 | 470 | # Setup compiled gsettings schema 471 | GS_SCHEMA_DIR="$XDG_DATA_HOME/glib-2.0/schemas" 472 | function compile_schemas { 473 | if [ -f "$1" ]; then 474 | rm -rf "$GS_SCHEMA_DIR" 475 | ensure_dir_exists "$GS_SCHEMA_DIR" 476 | for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do 477 | schema_dir="${data_dirs_array[$i]}/glib-2.0/schemas" 478 | if [ -f "$schema_dir/gschemas.compiled" ]; then 479 | # This directory already has compiled schemas 480 | continue 481 | fi 482 | if [ -n "$(ls -A "$schema_dir"/*.xml 2>/dev/null)" ]; then 483 | ln -s "$schema_dir"/*.xml "$GS_SCHEMA_DIR" 484 | fi 485 | if [ -n "$(ls -A "$schema_dir"/*.override 2>/dev/null)" ]; then 486 | ln -s "$schema_dir"/*.override "$GS_SCHEMA_DIR" 487 | fi 488 | done 489 | # Only compile schemas if we copied anything 490 | if [ -n "$(ls -A "$GS_SCHEMA_DIR"/*.xml "$GS_SCHEMA_DIR"/*.override 2>/dev/null)" ]; then 491 | "$1" "$GS_SCHEMA_DIR" 492 | fi 493 | fi 494 | } 495 | if [ "$needs_update" = true ]; then 496 | async_exec compile_schemas "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/glib-2.0/glib-compile-schemas" 497 | fi 498 | 499 | # Enable gsettings user changes 500 | # symlink the dconf file if home plug is connected for read 501 | DCONF_DEST_USER_DIR="$SNAP_USER_DATA/.config/dconf" 502 | if [ ! -f "$DCONF_DEST_USER_DIR/user" ]; then 503 | if [ -f "$REALHOME/.config/dconf/user" ]; then 504 | ensure_dir_exists "$DCONF_DEST_USER_DIR" 505 | ln -s "$REALHOME/.config/dconf/user" "$DCONF_DEST_USER_DIR" 506 | fi 507 | fi 508 | # symlink the runtime dconf file as well 509 | if [ -r "$XDG_RUNTIME_DIR/../dconf/user" ]; then 510 | ensure_dir_exists "$XDG_RUNTIME_DIR/dconf" 511 | ln -sf "../../dconf/user" "$XDG_RUNTIME_DIR/dconf/user" 512 | fi 513 | 514 | # Testability support 515 | append_dir LD_LIBRARY_PATH "$SNAP/testability" 516 | append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH" 517 | append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH/mesa" 518 | 519 | # Gdk-pixbuf loaders 520 | export GDK_PIXBUF_MODULE_FILE="$XDG_CACHE_HOME/gdk-pixbuf-loaders.cache" 521 | export GDK_PIXBUF_MODULEDIR="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders" 522 | if [ "$needs_update" = true ] || [ ! -f "$GDK_PIXBUF_MODULE_FILE" ]; then 523 | rm -f "$GDK_PIXBUF_MODULE_FILE" 524 | if [ -f "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" ]; then 525 | async_exec "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" > "$GDK_PIXBUF_MODULE_FILE" 526 | fi 527 | fi 528 | 529 | # Icon themes cache 530 | if [ "$needs_update" = true ]; then 531 | rm -rf "$XDG_DATA_HOME/icons" 532 | ensure_dir_exists "$XDG_DATA_HOME/icons" 533 | for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do 534 | # The runtime and theme content snaps should already contain icon caches 535 | # so we skip them to optimise app start time. 536 | if [[ "${data_dirs_array[$i]}" == "$SNAP/data-dir" || "${data_dirs_array[$i]}" == "$SNAP_DESKTOP_RUNTIME/"* ]]; then 537 | continue 538 | fi 539 | for theme in "${data_dirs_array[$i]}"/icons/*; do 540 | if [ -f "$theme/index.theme" ] && [ ! -f "$theme/icon-theme.cache" ]; then 541 | theme_dir="$XDG_DATA_HOME/icons/$(basename "$theme")" 542 | if [ ! -d "$theme_dir" ]; then 543 | ensure_dir_exists "$theme_dir" 544 | ln -s "$theme"/* "$theme_dir" 545 | if [ -f "$SNAP_DESKTOP_RUNTIME/usr/sbin/update-icon-caches" ]; then 546 | async_exec "$SNAP_DESKTOP_RUNTIME/usr/sbin/update-icon-caches" "$theme_dir" 547 | elif [ -f "$SNAP_DESKTOP_RUNTIME/usr/sbin/update-icon-cache.gtk2" ]; then 548 | async_exec "$SNAP_DESKTOP_RUNTIME/usr/sbin/update-icon-cache.gtk2" "$theme_dir" 549 | fi 550 | fi 551 | fi 552 | done 553 | done 554 | fi 555 | 556 | # GTK theme and behavior modifier 557 | # Those can impact the theme engine used by Qt as well 558 | gtk_configs=(gtk-3.0/settings.ini gtk-3.0/bookmarks gtk-2.0/gtkfilechooser.ini) 559 | for f in "${gtk_configs[@]}"; do 560 | dest="$XDG_CONFIG_HOME/$f" 561 | if [ ! -L "$dest" ]; then 562 | ensure_dir_exists "$(dirname "$dest")" 563 | ln -s "$REALHOME/.config/$f" "$dest" 564 | fi 565 | done 566 | 567 | # create symbolic link to ibus socket path for ibus to look up its socket files 568 | # (see comments #3 and #6 on https://launchpad.net/bugs/1580463) 569 | IBUS_CONFIG_PATH="$XDG_CONFIG_HOME/ibus" 570 | ensure_dir_exists "$IBUS_CONFIG_PATH" 571 | [ -d "$IBUS_CONFIG_PATH/bus" ] && rm -rf "$IBUS_CONFIG_PATH/bus" 572 | ln -sfn "$REALHOME/.config/ibus/bus" "$IBUS_CONFIG_PATH" 573 | ################################### 574 | # KDE NEON launcher specific part # 575 | ################################### 576 | 577 | # Add paths for games 578 | append_dir PATH "$SNAP/usr/games" 579 | append_dir PATH "$SNAP_DESKTOP_RUNTIME/usr/games" 580 | 581 | # Qt Libs 582 | prepend_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/libs" 583 | 584 | # Add QT_PLUGIN_PATH (Qt Modules). 585 | append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH/qt5/plugins" 586 | append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH" 587 | append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/plugins" 588 | append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/" 589 | # And QML2_IMPORT_PATH (Qt Modules). 590 | append_dir QML2_IMPORT_PATH "$SNAP/usr/lib/$ARCH/qt5/qml" 591 | append_dir QML2_IMPORT_PATH "$SNAP/lib/$ARCH" 592 | append_dir QML2_IMPORT_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/qml" 593 | append_dir QML2_IMPORT_PATH "$SNAP_DESKTOP_RUNTIME/lib/$ARCH" 594 | 595 | # Fix locating the QtWebEngineProcess executable 596 | export QTWEBENGINEPROCESS_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/libexec/QtWebEngineProcess" 597 | 598 | # Removes Qt warning: Could not find a location 599 | # of the system Compose files 600 | export QTCOMPOSE="$SNAP_DESKTOP_RUNTIME/usr/share/X11/locale" 601 | export QT_XKB_CONFIG_ROOT="/usr/share/X11/xkb" 602 | 603 | # KIO specific 604 | # Directly fork slaves. 605 | export KDE_FORK_SLAVES=1 606 | # Path to KIO slaves. 607 | export KF5_LIBEXEC_DIR="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/libexec/kf5" 608 | 609 | # Add path to VLC plugins 610 | export VLC_PLUGIN_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/x86_64-linux-gnu/vlc/plugins" 611 | 612 | # Ensure QtChooser behaves. 613 | export QTCHOOSER_NO_GLOBAL_DIR=1 614 | export QT_SELECT=5 615 | # qtchooser hardcodes reference paths, we'll need to rewrite them properly 616 | ensure_dir_exists "$XDG_CONFIG_HOME/qtchooser" 617 | echo "$SNAP_DESKTOP_RUNTIME/usr/lib/qt5/bin" > "$XDG_CONFIG_HOME/qtchooser/5.conf" 618 | echo "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" >> "$XDG_CONFIG_HOME/qtchooser/5.conf" 619 | echo "$SNAP_DESKTOP_RUNTIME/usr/lib/qt5/bin" > "$XDG_CONFIG_HOME/qtchooser/default.conf" 620 | echo "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" >> "$XDG_CONFIG_HOME/qtchooser/default.conf" 621 | 622 | # This relies on qtbase patch 623 | # 0001-let-qlibraryinfo-fall-back-to-locate-qt.conf-via-XDG.patch 624 | # to make QLibraryInfo look in XDG_* locations for qt.conf. The paths configured 625 | # here are applied to everything that uses QLibraryInfo as final fallback and 626 | # has no XDG_* fallback before that. Currently the most interesting offender 627 | # is QtWebEngine which will not work unless the Data path is correctly set. 628 | cat << EOF > "$XDG_CONFIG_HOME/qt.conf" 629 | [Paths] 630 | Data = $SNAP_DESKTOP_RUNTIME/usr/share/qt5/ 631 | Translations = $SNAP_DESKTOP_RUNTIME/usr/share/qt5/translations 632 | EOF 633 | 634 | if [ -e "$SNAP_DESKTOP_RUNTIME/usr/share/i18n" ]; then 635 | export I18NPATH="$SNAP_DESKTOP_RUNTIME/usr/share/i18n" 636 | locpath="$XDG_DATA_HOME/locale" 637 | ensure_dir_exists "$locpath" 638 | export LOCPATH="$locpath:/usr/lib/locale" 639 | LC_ALL=C.UTF-8 async_exec "$SNAP/snap/command-chain/locale-gen" 640 | fi 641 | ############################### 642 | # Mark update and exec binary # 643 | ############################### 644 | 645 | # for core 22 ld lib issue: fixed by warlord 646 | LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$SNAP_DESKTOP_RUNTIME/usr/lib/x86_64-linux-gnu/blas:$SNAP_DESKTOP_RUNTIME/usr/lib/x86_64-linux-gnu/lapack" 647 | 648 | export QTWEBENGINE_RESOURCES_PATH="$SNAP_DESKTOP_RUNTIME/usr/share/qt5/resources" 649 | export QTWEBENGINE_LOCALES_PATH="$SNAP_DESKTOP_RUNTIME/usr/share/qt5/translations" 650 | export QT_PLUGIN_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt5/plugins" 651 | 652 | # shellcheck disable=SC2154 653 | [ "$needs_update" = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision" 654 | 655 | wait_for_async_execs 656 | 657 | if [ -n "$SNAP_DESKTOP_DEBUG" ]; then 658 | echo "desktop-launch elapsed time: $(date +%s.%N --date="$START seconds ago")" 659 | echo "Now running: exec $*" 660 | fi 661 | 662 | exec "$@" 663 | --------------------------------------------------------------------------------