Conversation
Full rewrite of the BigLinux WebApps Manager and Viewer in Rust, replacing the previous Python+GTK3 implementation. Architecture: - 3-crate workspace: webapps-core, webapps-manager, webapps-viewer - webapps-core: shared models, config, desktop entry generation, i18n, templates - webapps-manager: GTK4/Adw GUI for creating, editing, importing/exporting webapps - webapps-viewer: lightweight WebKitGTK6 browser for viewer-mode webapps Manager features: - Create/edit/delete webapps with URL, name, icon, category, browser, profile - Template gallery (Google, Office365, Communication, Media, Productivity) - Welcome dialog with first-run onboarding - Import/export webapps as ZIP archives - Browser selection dialog with system-installed browser detection - Favicon auto-detection from websites - Legacy .desktop migration from Python-era format - Keyboard shortcuts (Ctrl+N, Ctrl+F, Ctrl+Q) Viewer features: - WebKitGTK6 web view with navigation bar (back/forward/reload/fullscreen) - URL bar with Ctrl+L focus, context menu "Open Link in Browser" - Zoom controls (Ctrl+/-, Ctrl+0) with persistent per-webapp zoom level - Developer tools toggle, software rendering mode via desktop action - Download handling with system notification on completion - Edge resize handles for CSD windows Desktop integration: - Sanitized .desktop entry generation with proper Exec/Icon/Categories - Desktop action for software rendering mode (WEBKIT_DISABLE_DMABUF_RENDERER) - Separate browser profiles with isolated cookies/data - XDG menu integration (applications-merged) - Systemd user service for login tasks Internationalization: - gettextrs integration with 80 translatable strings - 29 languages: bg, cs, da, de, el, en, es, et, fi, fr, he, hr, hu, is, it, ja, ko, nl, no, pl, pt, pt-BR, ro, ru, sk, sv, tr, uk, zh - Pre-compiled .mo files in usr/share/locale/ Build: - Release profile: LTO thin, opt-level s, strip, codegen-units 1 - Binaries: gui ~6.3MB, viewer ~2.2MB - Dependencies: gtk4, libadwaita, webkitgtk-6.0, openssl, gettext Removed: - Python source code and dependencies - GTK3/webkit2gtk-4.0 dependency - Legacy bash CLI script (big-webapps) - JSON locale files (replaced by gettext .po/.mo)
- Add missing closing brace in package() function - Switch reqwest from rustls-tls to native-tls backend Ring crate assembly (x25519) fails to link in CI environment native-tls uses system OpenSSL already in depends
- Fix SVG icons rendering blurry: resolve_icon_path now returns icon name (not absolute path) for hicolor theme icons, letting GTK render SVGs at correct pixel size. File-based SVGs use gdk-pixbuf for rasterization at 2x target size. - Fix app mode missing browser indicator: show application-x-executable icon with "App mode" tooltip when webapp uses built-in viewer. - Fix Wayland dock icon: change APP_ID to br.com.biglinux.webapps to match .desktop file name. Update StartupWMClass accordingly. - Reduce webapp list icon size from 64px to 48px for better proportion. - Add gdk-pixbuf dependency for high-quality SVG rasterization.
- Template gallery: rewrite callback to fire directly in connect_activated instead of connect_destroy (GTK4 close() ≠ immediate destroy). Fix RefCell borrow panic when set_text triggers connect_changed during active borrow. - Site detection (favicon.rs): switch reqwest native-tls → rustls-tls (fix builder error on systems w/o OpenSSL). Auto-prepend https:// when URL has no scheme. Always update name on re-detect (remove is_empty guard). - Icon loading: centralize in load_icon() helper (webapp_row.rs). Use gdk-pixbuf for file-based SVGs at 4× pixel_size. Return icon name (not path) for hicolor dirs so GTK renders at correct size. Fix browser icons in browser_dialog.rs via same pipeline. - Detect button: flat button w/ 24px globe icon (emblem-web-symbolic). - CSS system: add style.rs w/ custom classes (.webapp-icon, .webapp-row, .action-btn). Load provider in connect_startup. - Content wrap: AdwClamp max 900px in main window.
- Add WebKitGTK6 cookie persistence via CookieManager with SQLite storage → login sessions (YouTube, Spotify, etc.) now survive app restarts - Disable ITP (Intelligent Tracking Prevention) → prevents WebKit from limiting third-party cookies needed for OAuth flows (accounts.google.com) - Set cookie accept policy to Always → required for cross-domain auth - Switch reqwest from rustls-tls back to native-tls → fixes CI/CD build failure caused by ring crate assembly linkage with lld linker - Add TLS client init error logging in favicon fetch
Audit & Infrastructure - Add PLANNING.md with prioritized fix roadmap + post-fix metrics - Fix README: Python → Rust, update dependency list - cargo fmt: 74 diffs → 0 - cargo clippy: 33 warnings → 0 - cargo audit: 0 vulnerabilities Testing - Add 25 unit tests across 3 crates (service: 10, favicon: 15, registry: 11 deduplicated) - All tests passing, zero regressions Security - URL scheme validation in favicon fetch → block non-http(s) (anti-SSRF) - Permission handler: log auto-granted permission type + TODO - ITP disabled: add justification comment Accessibility - Label ~15 icon-only buttons (back, fwd, reload, fullscreen, menu, search, add, browser, edit, delete, template, detect) - Add live region (status_label with AccessibleRole::Status) for search result count announcements - Set AccessibleRole::Heading on category headers in list + gallery Robustness - Replace 2 unwrap() → expect() with context messages - Geometry parse: match + log::warn on failure instead of silent ignore - Poll interval 100ms → 250ms to reduce CPU churn UX & Compatibility - Disable browser button for App mode webapps (no external browser) - Set Chrome 131 User-Agent in viewer → fix Spotify/Teams blocking WebKitGTK as "incompatible browser"
Browser detection:
- Add multi-path probe: /usr/bin/brave, brave-browser, brave-browser-stable
- Normalize browser_id to "brave" (match BigLinux convention)
- Fix xdg-settings mapping: brave-browser.desktop → "brave"
Mode switch (App ↔ Browser):
- Preserve browser field on App mode toggle (no __viewer__ override)
- Update browser_row subtitle on mode change
- Rewrite same .desktop file on mode switch (no duplicate entries)
- Call update-desktop-database after install/remove
Version:
- APP_VERSION reads from Cargo.toml via env!("CARGO_PKG_VERSION")
UI/UX:
- Globe icon → "Detect" text button with auto-detect on URL change (800ms debounce)
- "+" icon → "Add" text button with suggested-action styling
- Template icon → "Templates" text button with suggested-action styling
- App mode icon: big-webapps colorful SVG (not grey symbolic)
- System accent color (blue) on action buttons via suggested-action CSS
- Dialog: 3 PreferencesGroup cards (Website, Appearance, Behavior)
Translations (pt-BR):
- "Modo do App" → "Modo App"
- Add "Adicionar", Detect "Detectar"
Viewer:
- Chrome 131 User-Agent string (fix Spotify WebKitGTK block)
Fixes:
- RefCell panic: Rc<RefCell<Option<SourceId>>> for debounce timer
- URL normalization: prepend https:// if missing scheme
- Icon resolution: hostname fallback + Google Favicon API
- Cookie persistence: ephemeral → default data manager
- Desktop entry: sanitize fields, proper WM class derivation
big-webapps-exec: always pass --user-data-dir for all profiles.
Previously "Browser" profile skipped it → Brave reused existing
instance → --app= flag ignored → URL opened as regular tab.
desktop.rs: derive_wm_class now generates correct StartupWMClass
for Browser mode matching Chrome/Brave convention:
{browser_prefix}-{url_class}-Default (e.g. brave-www.deezer.com__-Default).
Add browser_wm_prefix() mapping browser binaries to WM_CLASS
prefixes. Add browser_url_class() using url::Url::parse for
proper path normalization.
Template icon fixes → map to existing GTK icon names: messenger→messenger-indicator, signal→signal-desktop, twitch→twitch-indicator, prime-video→amazon, disney-plus→video-television, ms-teams→teams, onedrive→skydrive, canva→applications-graphics, chatgpt→applications-internet, claude→applications-internet, linkedin→applications-internet, google-calendar→calendar DRM handling → WebKitGTK lacks Widevine CDM backend, force Browser mode for DRM-dependent services: - Add requires_drm field to WebAppTemplate - Mark 7 media templates: spotify, youtube-music, netflix, prime-video, disney-plus, tidal, deezer - Lock mode switch + show DRM notice in webapp dialog - Add DRM badge in template gallery - URL-based DRM detection fallback for non-template webapps
Phase 2 fixes: - SEC-02: zip bomb protection in import - QUALITY-02: signal handler leak fix - QUALITY-06: atomic JSON writes (tmp + rename) - UX-01: validation feedback CSS - UX-02: save error Banner display - UX-05: skip auto-detect on template selection - POLISH-03: geometry save accuracy (non-maximized dimensions) - POLISH-05: cancel debounce on dialog close - POLISH-06: context menu action group reuse High priority: - 2.6: permission prompt system — camera/mic/geolocation prompt via AlertDialog, decisions persisted in permissions.json; non-sensitive perms (notifications, clipboard, DRM) auto-granted - 2.3: import/export on background threads via std::thread::spawn + glib::timeout_add_local polling (non-blocking UI) Medium priority: - 3.5: collapse Behavior section for new webapps — "Advanced Settings..." button reveals on click - 3.9: split service.rs (735L) into service/ module directory — mod.rs (249L), browser.rs (126L), io.rs (130L), migration.rs (255L) Build: zero warnings (build + clippy), 35/35 tests pass.
- Manager .desktop: Categories=GTK;Utility → Categories=GTK;Webapps (appears in Webapps folder instead of Utilities) - big-webapps-exec: Default/Browser profile → use native Chrome --profile-directory=Default (keeps user logins/cookies); custom profiles → isolated --user-data-dir (separate session) - desktop.rs: ensure trailing semicolon in Categories= field (freedesktop spec compliance, required for GNOME app-folder matching) fix: align app-folder category filter with desktop files - categories=['WebApps'] → categories=['Webapps'] (matches Categories=Webapps; in generated .desktop files)
- Manager .desktop: Categories=GTK;Utility → Categories=GTK;Webapps - big-webapps-exec: Default/Browser profile → native Chrome --profile-directory=Default (keeps user logins/cookies); custom profiles → isolated --user-data-dir - desktop.rs: ensure trailing semicolon in Categories= field - desktop.rs: reset GNOME app-picker-layout on desktop file change (GNOME Shell caches app positions, preventing category changes from moving apps to correct folder)
- Remove stale service.rs (conflicts with service/mod.rs from split) - Annotate mpsc channel type in window.rs (fixes E0282 on older rustc) - Manager .desktop: Categories=GTK;Utility → Categories=GTK;Webapps - big-webapps-exec: Default/Browser → --profile-directory=Default (use native Chrome session with logins); custom → --user-data-dir - desktop.rs: ensure trailing semicolon in Categories= field - desktop.rs: on GNOME, reset app-picker-layout + write correct categories=['Webapps'] to dconf after desktop file changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated PR created by build_package.py
Conflicts resolved automatically (if any)
Ready for automatic merge