Skip to content

Auto-merge: dev-talesam → main#126

Merged
talesam merged 16 commits intomainfrom
dev-talesam
Apr 20, 2026
Merged

Auto-merge: dev-talesam → main#126
talesam merged 16 commits intomainfrom
dev-talesam

Conversation

@talesam
Copy link
Copy Markdown
Contributor

@talesam talesam commented Apr 20, 2026

Automated PR created by build_package.py

Conflicts resolved automatically (if any)
Ready for automatic merge

talesam and others added 16 commits April 15, 2026 15:20
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
@talesam talesam merged commit f0f3e90 into main Apr 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant