Compare commits

...

10 Commits

Author SHA1 Message Date
Umbrix Developer
e79b508531 feat: enable update system with localhost:8000 server
Some checks failed
Release / build-release (push) Waiting to run
CI / run (push) Has been cancelled
2026-01-18 06:56:35 +03:00
Umbrix Developer
8c5696b6aa fix: install libcore.so via CMake for proper packaging 2026-01-18 06:36:16 +03:00
Umbrix Developer
abb6929e19 fix: single instance - present existing window instead of creating new 2026-01-18 06:18:01 +03:00
Umbrix Developer
ee39acbeec revert: back to GTK defaults like original Hiddify 2026-01-18 06:05:19 +03:00
Umbrix Developer
af21f6d16e fix: restore window from minimized state 2026-01-18 05:56:12 +03:00
Umbrix Developer
d8cdee91fe feat: window activation with xdotool 2026-01-18 05:31:59 +03:00
Umbrix Developer
b0e23312d8 fix: single instance with lock file only 2026-01-17 22:06:01 +03:00
Umbrix Developer
43ab81e8d1 fix: icon permissions and GTK single instance
- Use GTK default flags for single instance
- Fix icon path to absolute /usr/share/icons
- Add postinstall chmod 644 for icon
- Remove Dart-level single instance code
2026-01-17 20:10:04 +03:00
Umbrix Developer
9300488d2b feat: single instance with window activation
- Check for existing process via PID
- Activate existing window with wmctrl
- Remove stale lock files
- Prevent multiple instances opening
2026-01-17 18:38:54 +03:00
Umbrix Developer
053d7e5855 fix: icon display in application menu
- Changed Icon path to absolute in desktop file
- Fixed icon file permissions (chmod 644)
- Icon now shows correctly in GNOME/KDE menus

Desktop file updated: Icon=umbrix → Icon=/usr/share/icons/hicolor/256x256/apps/umbrix.png
2026-01-17 17:35:05 +03:00
13 changed files with 480 additions and 74 deletions

335
UPDATE_SERVER_README.md Normal file
View File

@@ -0,0 +1,335 @@
# 🚀 Umbrix Update Server - Инструкция
## 📋 Обзор
Umbrix использует систему автообновлений через **Sparkle Appcast XML**. Приложение проверяет файл `appcast.xml` на вашем сервере и уведомляет пользователей о новых версиях.
## 🏗️ Структура системы обновлений
### 1. **appcast.xml** - Манифест обновлений
Находится: `/home/vodorod/dorod/hiddify-umbrix-v1.7.0/appcast.xml`
```xml
<item>
<title>Umbrix 2.5.8</title>
<description>🚀 Новые функции...</description>
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
<sparkle:version>2.5.8</sparkle:version>
<!-- Linux DEB -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
sparkle:version="2.5.8"
sparkle:os="linux-deb"
type="application/x-debian-package" />
</item>
```
### 2. **Настройки в коде**
Файл: `lib/core/model/constants.dart`
```dart
// URL вашего сервера appcast.xml
static const appCastUrl = "http://localhost:8000/api/appcast.xml";
// Для публичного домена:
// static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
```
## 📂 Структура веб-сервера
```
/home/vodorod/update-server/
├── api/
│ └── appcast.xml # Копия из проекта
├── downloads/ # Файлы обновлений
│ ├── umbrix-2.5.8-linux.deb
│ ├── umbrix-2.5.8-linux.rpm
│ ├── umbrix-2.5.8-linux.AppImage
│ └── umbrix-2.5.8-windows.exe
└── admin/ # Ваш Update Manager (localhost:8000/admin/)
└── index.html
```
## 🔄 Процесс публикации обновления
### Шаг 1: Собрать новую версию
```bash
cd ~/dorod/hiddify-umbrix-v1.7.0
./build-all-packages.sh
```
### Шаг 2: Скопировать файлы на сервер
```bash
# Создать папку для версии
mkdir -p /home/vodorod/update-server/downloads/
# Скопировать пакеты
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.deb \
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.deb
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.rpm \
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.rpm
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.AppImage \
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.AppImage
```
### Шаг 3: Обновить appcast.xml
Раскомментируйте и измените секцию в `appcast.xml`:
```xml
<item>
<title>Umbrix 2.5.8</title>
<description>🚀 Новые функции:
- Улучшена стабильность
- Исправлены ошибки</description>
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
<sparkle:version>2.5.8</sparkle:version>
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
<!-- Linux DEB (Debian/Ubuntu) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
sparkle:version="2.5.8"
sparkle:os="linux-deb"
type="application/x-debian-package"
length="30000000" />
<!-- Linux RPM (Fedora/CentOS) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
sparkle:version="2.5.8"
sparkle:os="linux-rpm"
type="application/x-rpm"
length="36000000" />
<!-- Linux AppImage (Universal) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
sparkle:version="2.5.8"
sparkle:os="linux-appimage"
type="application/x-appimage"
length="38000000" />
</item>
```
### Шаг 4: Скопировать appcast.xml на сервер
```bash
cp appcast.xml /home/vodorod/update-server/api/appcast.xml
```
## 🌐 Запуск локального сервера
### Вариант 1: Python HTTP сервер (простой)
```bash
cd /home/vodorod/update-server
python3 -m http.server 8000
```
Доступ:
- Appcast: `http://localhost:8000/api/appcast.xml`
- Скачивания: `http://localhost:8000/downloads/`
- Admin: `http://localhost:8000/admin/`
### Вариант 2: Nginx (продакшн)
```nginx
server {
listen 8000;
server_name localhost;
root /home/vodorod/update-server;
location /api/appcast.xml {
add_header Content-Type application/xml;
add_header Access-Control-Allow-Origin *;
}
location /downloads/ {
autoindex on;
}
}
```
## 📱 Про поле "URL для скачивания APK" в веб-интерфейсе
**ВАЖНО**: Это поле осталось от оригинального Hiddify (Android приложение). Для **Umbrix Linux десктоп** оно **НЕ используется**.
Umbrix для Linux использует:
-**DEB пакеты** (Debian/Ubuntu)
-**RPM пакеты** (Fedora/CentOS)
-**AppImage** (универсальный формат)
Поле "APK" в веб-интерфейсе можно:
1. **Игнорировать** (оставить пустым)
2. **Переименовать** в "URL для скачивания DEB/RPM/AppImage"
3. **Удалить** из веб-интерфейса
## 🔐 Безопасность
### Для продакшн (публичный домен):
1. **HTTPS обязателен**:
```dart
static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
```
2. **Подписывание обновлений** (Sparkle поддерживает):
```bash
# Генерация ключей
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout > public_key.pem
# Подпись файла
openssl dgst -sha256 -sign private_key.pem \
umbrix-2.5.8-linux.deb > signature.txt
```
3. **Добавить signature в appcast.xml**:
```xml
<enclosure
url="https://updates.umbrix.net/downloads/umbrix-2.5.8-linux.deb"
sparkle:dsaSignature="MC0CFQCqfTq..." />
```
## 🧪 Тестирование
### 1. Проверить доступность appcast.xml
```bash
curl http://localhost:8000/api/appcast.xml
```
### 2. Проверить в приложении
- Запустить Umbrix
- Зайти в Настройки → Проверить обновления
- Приложение скачает appcast.xml и покажет уведомление о новой версии
### 3. Логи отладки
В коде установлен `_debugUpgrader = true`, логи будут в консоли:
```
[UPGRADER] Checking appcast: http://localhost:8000/api/appcast.xml
[UPGRADER] Current version: 1.7.0
[UPGRADER] Latest version: 2.5.8
[UPGRADER] Update available!
```
## 📊 Мониторинг скачиваний
### Вариант 1: Nginx access.log
```bash
tail -f /var/log/nginx/access.log | grep "/downloads/"
```
### Вариант 2: Python скрипт с логированием
```python
from http.server import HTTPServer, SimpleHTTPRequestHandler
import datetime
class LoggingHandler(SimpleHTTPRequestHandler):
def log_message(self, format, *args):
print(f"[{datetime.datetime.now()}] {args[0]}")
HTTPServer(('', 8000), LoggingHandler).serve_forever()
```
## 🚀 Миграция на публичный домен
Когда будете готовы к продакшну:
1. **Купить домен**: `updates.umbrix.net`
2. **Настроить DNS**:
```
A updates.umbrix.net → 123.45.67.89
```
3. **Изменить в коде**:
```dart
static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
```
4. **Пересобрать и выпустить обновление**:
```bash
./build-all-packages.sh
```
5. **Все последующие версии** будут проверять новый домен
## ❓ FAQ
### Q: Как часто приложение проверяет обновления?
A: Раз в 12 часов (настройка `durationUntilAlertAgain`)
### Q: Можно ли принудительно проверить обновления?
A: Да, через меню "Настройки → Проверить обновления"
### Q: Что делать, если обновление не находится?
A: Проверьте:
1. Доступен ли `appcast.xml` по URL
2. Версия в `<sparkle:version>` больше текущей
3. Логи отладки в консоли приложения
### Q: Как откатить обновление?
A: Удалите или закомментируйте `<item>` новой версии в `appcast.xml`
## 📝 Пример полного appcast.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
<channel>
<title>Umbrix Updates</title>
<description>Umbrix VPN автообновления</description>
<link>http://localhost:8000</link>
<language>ru</language>
<!-- Новая версия 2.5.8 -->
<item>
<title>Umbrix 2.5.8</title>
<description>🚀 Новые функции:
- Улучшена стабильность
- Исправлены ошибки
- Добавлена поддержка новых протоколов</description>
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
<sparkle:version>2.5.8</sparkle:version>
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
sparkle:version="2.5.8"
sparkle:os="linux-deb"
type="application/x-debian-package"
length="30000000" />
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
sparkle:version="2.5.8"
sparkle:os="linux-rpm"
type="application/x-rpm"
length="36000000" />
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
sparkle:version="2.5.8"
sparkle:os="linux-appimage"
type="application/x-appimage"
length="38000000" />
</item>
<!-- Текущая версия 1.7.0 -->
<item>
<title>Umbrix 1.7.0</title>
<description>Стабильный релиз</description>
<pubDate>Fri, 17 Jan 2026 08:49:07 +0000</pubDate>
<sparkle:version>1.7.0</sparkle:version>
<sparkle:shortVersionString>1.7.0</sparkle:shortVersionString>
</item>
</channel>
</rss>
```
## 🎯 Готово!
Теперь система обновлений полностью настроена и готова к использованию!

View File

@@ -2,6 +2,64 @@
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle"> <rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
<channel> <channel>
<title>Umbrix Updates</title> <title>Umbrix Updates</title>
<!-- No updates available - this is Umbrix, not Hiddify --> <description>Umbrix VPN автообновления</description>
<link>http://localhost:8000</link>
<language>ru</language>
<!-- Пример структуры для обновления версии 2.5.8 -->
<!-- Раскомментируйте и измените, когда будет новая версия -->
<!--
<item>
<title>Umbrix 2.5.8</title>
<description>🚀 Новые функции:
- Улучшена стабильность
- Исправлены ошибки</description>
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
<sparkle:version>2.5.8</sparkle:version>
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
<!-- Linux DEB (Debian/Ubuntu) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
sparkle:version="2.5.8"
sparkle:os="linux-deb"
type="application/x-debian-package"
length="30000000" />
<!-- Linux RPM (Fedora/CentOS) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
sparkle:version="2.5.8"
sparkle:os="linux-rpm"
type="application/x-rpm"
length="36000000" />
<!-- Linux AppImage (Universal) -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
sparkle:version="2.5.8"
sparkle:os="linux-appimage"
type="application/x-appimage"
length="38000000" />
<!-- Windows EXE -->
<enclosure
url="http://localhost:8000/downloads/umbrix-2.5.8-windows.exe"
sparkle:version="2.5.8"
sparkle:os="windows"
type="application/x-msdownload"
length="45000000" />
</item>
-->
<!-- Текущая версия 1.7.0 (без обновлений) -->
<item>
<title>Umbrix 1.7.0</title>
<description>Стабильный релиз</description>
<pubDate>Fri, 17 Jan 2026 08:49:07 +0000</pubDate>
<sparkle:version>1.7.0</sparkle:version>
<sparkle:shortVersionString>1.7.0</sparkle:shortVersionString>
</item>
</channel> </channel>
</rss> </rss>

View File

@@ -61,6 +61,7 @@ echo -e "${GREEN}✓${NC} Custom libcore integrated: $NEW_SIZE"
# Step 5: Add icon and prepare data directory # Step 5: Add icon and prepare data directory
echo -e "\n${YELLOW}[5/6]${NC} Preparing bundle assets..." echo -e "\n${YELLOW}[5/6]${NC} Preparing bundle assets..."
cp -f "$PROJECT_DIR/logo/ic_launcher_playstore.png" "$BUNDLE_DIR/umbrix.png" cp -f "$PROJECT_DIR/logo/ic_launcher_playstore.png" "$BUNDLE_DIR/umbrix.png"
chmod 644 "$BUNDLE_DIR/umbrix.png"
mkdir -p "$BUNDLE_DIR/data" mkdir -p "$BUNDLE_DIR/data"
echo -e "${GREEN}${NC} Icon and data directory ready" echo -e "${GREEN}${NC} Icon and data directory ready"

View File

@@ -3,7 +3,7 @@ abstract class Constants {
static const githubUrl = "https://github.com/umbrix-app/umbrix"; static const githubUrl = "https://github.com/umbrix-app/umbrix";
static const githubReleasesApiUrl = "https://api.github.com/repos/umbrix-app/umbrix/releases"; static const githubReleasesApiUrl = "https://api.github.com/repos/umbrix-app/umbrix/releases";
static const githubLatestReleaseUrl = "https://github.com/umbrix-app/umbrix/releases/latest"; static const githubLatestReleaseUrl = "https://github.com/umbrix-app/umbrix/releases/latest";
static const appCastUrl = "https://raw.githubusercontent.com/umbrix-app/umbrix/main/appcast.xml"; static const appCastUrl = "http://localhost:8000/api/appcast.xml";
static const telegramChannelUrl = "https://t.me/umbrix_app"; static const telegramChannelUrl = "https://t.me/umbrix_app";
static const privacyPolicyUrl = "https://umbrix.net/privacy.html"; static const privacyPolicyUrl = "https://umbrix.net/privacy.html";
static const termsAndConditionsUrl = "https://umbrix.net/terms.html"; static const termsAndConditionsUrl = "https://umbrix.net/terms.html";
@@ -15,9 +15,10 @@ abstract class Constants {
// Собственный сервер обновлений (для приватного репозитория) // Собственный сервер обновлений (для приватного репозитория)
// 📝 ИНСТРУКЦИЯ: Замените на URL вашего API сервера // 📝 ИНСТРУКЦИЯ: Замените на URL вашего API сервера
// Пример: "https://api.umbrix.net/api/latest" // Пример: "https://api.umbrix.net/api/latest"
// 🧪 Для тестирования в эмуляторе используйте: "http://10.0.2.2:8000/api.php" // 🖥️ Для Linux десктопа используйте: "http://localhost:8000/api/appcast.xml"
// 📱 Для Android эмулятора используйте: "http://10.0.2.2:8000/api/appcast.xml"
// См. документацию в папке: update-server/README.md // См. документацию в папке: update-server/README.md
static const customUpdateServerUrl = "http://10.0.2.2:8000/api.php"; static const customUpdateServerUrl = "http://localhost:8000/api/appcast.xml";
// Использовать собственный сервер обновлений вместо GitHub // Использовать собственный сервер обновлений вместо GitHub
// true = использовать customUpdateServerUrl (для приватного репозитория) // true = использовать customUpdateServerUrl (для приватного репозитория)

View File

@@ -50,26 +50,26 @@ GoRouter router(RouterRef ref) {
} }
final tabLocations = [ final tabLocations = [
const HomeRoute().location, // 0: Главная const HomeRoute().location, // 0: Главная
const ProxiesRoute().location, // 1: Локации const ProxiesRoute().location, // 1: Локации
const PerAppProxyRoute().location, // 2: Исключения const PerAppProxyRoute().location, // 2: Исключения
const SettingsRoute().location, // 3: Настройки const SettingsRoute().location, // 3: Настройки
const AboutRoute().location, // 4: О программе const AboutRoute().location, // 4: О программе
]; ];
int getCurrentIndex(BuildContext context) { int getCurrentIndex(BuildContext context) {
final String location = GoRouterState.of(context).uri.path; final String location = GoRouterState.of(context).uri.path;
// Проверяем точное совпадение для главной // Проверяем точное совпадение для главной
if (location == const HomeRoute().location) return 0; if (location == const HomeRoute().location) return 0;
// Проверяем остальные маршруты по порядку // Проверяем остальные маршруты по порядку
// ВАЖНО: более длинные пути проверяем раньше! // ВАЖНО: более длинные пути проверяем раньше!
if (location.startsWith(const PerAppProxyRoute().location)) return 2; // /settings/per-app-proxy if (location.startsWith(const PerAppProxyRoute().location)) return 2; // /settings/per-app-proxy
if (location.startsWith(const ProxiesRoute().location)) return 1; // /proxies if (location.startsWith(const ProxiesRoute().location)) return 1; // /proxies
if (location.startsWith(const SettingsRoute().location)) return 3; // /settings if (location.startsWith(const SettingsRoute().location)) return 3; // /settings
if (location.startsWith(const AboutRoute().location)) return 4; // /about if (location.startsWith(const AboutRoute().location)) return 4; // /about
return 0; return 0;
} }

View File

@@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:umbrix/core/app_info/app_info_provider.dart'; import 'package:umbrix/core/app_info/app_info_provider.dart';
import 'package:umbrix/core/localization/locale_preferences.dart'; import 'package:umbrix/core/localization/locale_preferences.dart';
import 'package:umbrix/core/model/constants.dart';
import 'package:umbrix/core/preferences/preferences_provider.dart'; import 'package:umbrix/core/preferences/preferences_provider.dart';
import 'package:umbrix/core/utils/preferences_utils.dart'; import 'package:umbrix/core/utils/preferences_utils.dart';
import 'package:umbrix/features/app_update/data/app_update_data_providers.dart'; import 'package:umbrix/features/app_update/data/app_update_data_providers.dart';
@@ -18,7 +19,7 @@ const _debugUpgrader = true;
@riverpod @riverpod
Upgrader upgrader(UpgraderRef ref) => Upgrader( Upgrader upgrader(UpgraderRef ref) => Upgrader(
// Removed appcastConfig - no updates for Umbrix appcastConfig: AppcastConfiguration(url: Constants.appCastUrl),
debugLogging: _debugUpgrader && kDebugMode, debugLogging: _debugUpgrader && kDebugMode,
durationUntilAlertAgain: const Duration(hours: 12), durationUntilAlertAgain: const Duration(hours: 12),
messages: UpgraderMessages( messages: UpgraderMessages(

View File

@@ -172,49 +172,49 @@ class _CustomAdaptiveScaffold extends HookConsumerWidget {
child: ListView( child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
children: [ children: [
// О программе // О программе
Builder( Builder(
builder: (context) { builder: (context) {
final t = ref.watch(translationsProvider); final t = ref.watch(translationsProvider);
return _DrawerMenuItem( return _DrawerMenuItem(
icon: FluentIcons.info_24_regular, icon: FluentIcons.info_24_regular,
selectedIcon: FluentIcons.info_24_filled, selectedIcon: FluentIcons.info_24_filled,
label: t.about.pageTitle, label: t.about.pageTitle,
isSelected: false, isSelected: false,
onTap: () { onTap: () {
RootScaffold.stateKey.currentState?.closeDrawer(); RootScaffold.stateKey.currentState?.closeDrawer();
const AboutRoute().push(context); const AboutRoute().push(context);
}, },
); );
}, },
),
// Настройки
Builder(
builder: (context) {
final t = ref.watch(translationsProvider);
return _DrawerMenuItem(
icon: FluentIcons.settings_24_regular,
selectedIcon: FluentIcons.settings_24_filled,
label: t.settings.pageTitle,
isSelected: false,
onTap: () {
RootScaffold.stateKey.currentState?.closeDrawer();
const SettingsRoute().push(context);
},
);
},
),
const SizedBox(height: 16),
const Divider(),
const _DrawerThemeItem(),
const _DrawerLanguageItem(),
const _DrawerLicensesItem(),
],
),
), ),
// Настройки
Builder(
builder: (context) {
final t = ref.watch(translationsProvider);
return _DrawerMenuItem(
icon: FluentIcons.settings_24_regular,
selectedIcon: FluentIcons.settings_24_filled,
label: t.settings.pageTitle,
isSelected: false,
onTap: () {
RootScaffold.stateKey.currentState?.closeDrawer();
const SettingsRoute().push(context);
},
);
},
),
const SizedBox(height: 16),
const Divider(),
const _DrawerThemeItem(),
const _DrawerLanguageItem(),
const _DrawerLicensesItem(),
], ],
), ),
), ),
],
),
),
body: AdaptiveLayout( body: AdaptiveLayout(
primaryNavigation: SlotLayout( primaryNavigation: SlotLayout(
config: <Breakpoint, SlotLayoutConfig>{ config: <Breakpoint, SlotLayoutConfig>{

View File

@@ -67,16 +67,16 @@ class PerAppProxyPage extends HookConsumerWidget with PresLogger {
tooltip: localizations.searchFieldLabel, tooltip: localizations.searchFieldLabel,
), ),
], ],
bottom: PlatformUtils.isDesktop bottom: PlatformUtils.isDesktop
? null // На Desktop только вкладка "Домены" ? null // На Desktop только вкладка "Домены"
: TabBar( : TabBar(
controller: tabController, controller: tabController,
onTap: (index) => currentTab.value = index, onTap: (index) => currentTab.value = index,
tabs: [ tabs: [
Tab(text: t.settings.network.excludedDomains.domainsTab), Tab(text: t.settings.network.excludedDomains.domainsTab),
Tab(text: t.settings.network.excludedDomains.appsTab), Tab(text: t.settings.network.excludedDomains.appsTab),
], ],
), ),
); );
final searchAppBar = SliverAppBar( final searchAppBar = SliverAppBar(

View File

@@ -19,11 +19,6 @@ class WindowNotifier extends _$WindowNotifier with AppLogger {
Future<void> build() async { Future<void> build() async {
if (!PlatformUtils.isDesktop) return; if (!PlatformUtils.isDesktop) return;
// if (Platform.isWindows) {
// loggy.debug("ensuring single instance");
// await WindowsSingleInstance.ensureSingleInstance([], "Hiddify");
// }
await windowManager.ensureInitialized(); await windowManager.ensureInitialized();
await windowManager.setMinimumSize(minimumWindowSize); await windowManager.setMinimumSize(minimumWindowSize);
await windowManager.setSize(defaultWindowSize); await windowManager.setSize(defaultWindowSize);

View File

@@ -108,8 +108,14 @@ install(CODE "
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(FILES "../libcore/bin/lib/libcore.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" # Install custom libcore (49MB with FFI parse function)
COMPONENT Runtime) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../libcore/bin/lib/libcore.so")
install(FILES "../libcore/bin/lib/libcore.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
message(STATUS "Custom libcore.so will be installed")
else()
message(WARNING "Custom libcore.so not found, application may fail at runtime")
endif()
install( install(
FILES "../libcore/bin/HiddifyCli" FILES "../libcore/bin/HiddifyCli"

View File

@@ -2,7 +2,7 @@
Name=Umbrix Name=Umbrix
Comment=Cross Platform Multi Protocol Proxy Frontend Comment=Cross Platform Multi Protocol Proxy Frontend
Exec=umbrix %U Exec=umbrix %U
Icon=umbrix Icon=/usr/share/icons/hicolor/256x256/apps/umbrix.png
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Network; Categories=Network;

View File

@@ -14,12 +14,20 @@ struct _MyApplication
}; };
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
#define ICON_PATH "./umbrix.png" #define ICON_PATH "/usr/share/icons/hicolor/256x256/apps/umbrix.png"
// Implements GApplication::activate. // Implements GApplication::activate.
static void my_application_activate(GApplication *application) static void my_application_activate(GApplication *application)
{ {
MyApplication *self = MY_APPLICATION(application); MyApplication *self = MY_APPLICATION(application);
// Check if window already exists - if so, just present it
GList* windows = gtk_application_get_windows(GTK_APPLICATION(application));
if (windows) {
gtk_window_present(GTK_WINDOW(windows->data));
return;
}
GtkWindow *window = GtkWindow *window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
gtk_window_set_icon_from_file(window, ICON_PATH, NULL); gtk_window_set_icon_from_file(window, ICON_PATH, NULL);

View File

@@ -11,6 +11,7 @@ essential: false
icon: ./logo/ic_launcher_playstore.png icon: ./logo/ic_launcher_playstore.png
postinstall_scripts: postinstall_scripts:
- chmod 644 /usr/share/icons/hicolor/256x256/apps/umbrix.png
- echo "Installed Umbrix VPN" - echo "Installed Umbrix VPN"
postuninstall_scripts: postuninstall_scripts:
- echo "Uninstalled Umbrix" - echo "Uninstalled Umbrix"