Skip to content

Auto-merge: dev-talesam → main#125

Merged
talesam merged 15 commits intomainfrom
dev-talesam
Apr 15, 2026
Merged

Auto-merge: dev-talesam → main#125
talesam merged 15 commits intomainfrom
dev-talesam

Conversation

@talesam
Copy link
Copy Markdown
Contributor

@talesam talesam commented Apr 15, 2026

Automated PR created by build_package.py

Conflicts resolved automatically (if any)
Ready for automatic merge

talesam and others added 15 commits April 10, 2026 00:15
…iewer (v3.1.0)

SECURITY FIXES:
- Eliminate all shell=True command injection vectors in command_executor.py
  Replace subprocess shell calls with argv lists
- Fix ZIP path traversal vulnerability (ZipSlip) in webapp import
- Remove relative path usage, use absolute paths consistently

BUG FIXES:
- Fix F823: translation function `_` referenced before assignment
- Fix Gtk.Label.set_ellipsize wrong API call (use Pango.EllipsizeMode)
- Fix _open_folder infinite recursion on missing xdg-open
- Fix get_system_default_browser regex failure on empty xdg output
- Fix dual application IDs (unified to br.com.biglinux.webapps)
- Fix duplicate gtk_box_append in webapp_dialog
- Fix base_dir resolution for icon paths
- Fix icon persistence when editing webapps

CODE QUALITY:
- Add type hints to 120+ functions across 12 files
- Add ruff.toml config (E402 per-file ignores for gi.repository)
- Format all files with ruff (line-length 88)
- Replace print statements with structured logging
- Remove unused variables and dead code
- Upgrade AdwAboutWindow → AdwAboutDialog (libadwaita ≥1.5)
- Add enhanced delete confirmation dialog with app name
- Use uuid4 for unique webapp IDs instead of sequential counters
- Clean up legacy ~/.bigwebapps path references
- Centralize version in APP_VERSION variable (3.1.0)

NEW FEATURE — big-webapps-viewer (Qt6/PySide6 + Chromium WebEngine):
- CSD frameless window with custom Adwaita-style headerbar
- System icon theme integration (bigicons-papient with fallback chain)
- SVG icon recoloring adapts to light/dark system themes
- Window controls (minimize, maximize, close) matching GNOME style
- Navigation buttons (back, forward, reload) in headerbar
- Fullscreen mode with auto-hide nav overlay on hover
- Per-webapp persistent profile (cookies, localStorage, cache)
- Keyboard shortcuts: F5/Ctrl+R reload, Ctrl+Q quit, Alt+←/→ nav,
  F11 fullscreen, Escape exit fullscreen
- Geometry persistence (size, maximized state) per app-id
- Rounded top corners matching libadwaita window style
- SIGINT handler for clean Ctrl+C termination from terminal

FILES ADDED:
- biglinux-webapps/usr/bin/big-webapps-viewer
- ruff.toml
- PLANNING.md (audit roadmap and tracking)
…con selector

Application Mode ("Modo Aplicativo") integration:
- webapp_model.py: add app_mode field ("browser"|"app"), default "browser"
- webapp_dialog.py: add Application Mode toggle (Adw.ActionRow + Gtk.Switch),
  hide browser/profile rows when active, restore on deactivate
- command_executor.py: pass "__viewer__" as browser when app_mode == "app"
- big-webapps (bash): create viewer .desktop with big-webapps-viewer Exec line,
  add StartupWMClass=br.com.biglinux.webapp.$app_id for taskbar icon matching,
  json command detects both big-webapps-exec and big-webapps-viewer files,
  Exec parser extracts --url from viewer lines, short_browser maps __viewer__
  to "viewer" for filename generation, app_mode included in JSON output

Fix custom icon persistence:
- big-webapps: copy custom icons to ~/.local/share/icons/hicolor/scalable/apps/
  (proper icon theme hierarchy) instead of flat ~/.local/share/icons/,
  use absolute path in Icon= field so desktop environment resolves correctly
- big-webapps: remove broken icon normalization in JSON parsing that was
  overwriting .desktop files and stripping paths unnecessarily
- webapp_model.py: app_icon_url falls back to app_icon when empty,
  fixing icon loss when editing webapp without changing icon

Icon selector improvements (select_icon.sh):
- Persist last-used directory in ~/.config/biglinux-webapps/last_icon_dir,
  zenity/yad opens in last chosen folder on subsequent selections
- Fix geticons resolution: "; exit" was unconditionally exiting after first
  size attempt — replaced with proper loop over sizes 128→64→48→32
- Add stderr redirect (2>&1) to "type" checks for cleaner output

UI cleanup:
- main_window.py: remove app icon from header bar (left side)
- command_executor.py: add debug logging for create_webapp argv and icon values
…le .mo

- Fix 26 .po files: welcome dialog msgstr missing trailing \n
- Fill ~60 empty translations (OK, Continue, Yes, No) in 26 langs
- Compile all 28 .mo files

chore: remove debug print() from command_executor
…on + cleanup on delete

- Lock window size via min/max constraints; only unlock during user-
  initiated grip drag, fullscreen, or maximize. Prevents web content
  from resizing the window.
- Add custom _ResizeGrip subclass that manages lock/unlock lifecycle.
- Inject JS to neutralize window.resizeTo/resizeBy/moveTo/moveBy.
- Enable FullScreenSupportEnabled and handle JS fullscreen requests
  (e.g. video players).
- Handle newWindowRequested — open popups in same window.
- Center window on primary screen at startup.
- Reduce default height from 768 to 720.
- Disable WebGL, AutoLoadIcons, TouchIcons, and PluginsEnabled to
  reduce memory footprint.
- Add Chromium flags: --disable-sync, --disable-translate,
  --disable-background-networking, --renderer-process-limit=1.
- Clean up viewer config and persistent data when deleting an
  app-mode webapp (command_executor.py).
… lock

- re-enable PluginsEnabled → Widevine/DRM playback works again
- remove WebGLEnabled from disabled list → sites using WebGL render OK
- remove _ResizeGrip subclass + _lock_size/_unlock_size mechanism
- keep JS injection neutralizing window.resizeTo/resizeBy (proper fix)
- use standard QSizeGrip → user can freely resize window
…oss security, a11y, architecture & UX

Security:
- Fix command injection: shell=True → subprocess.run(list) in CommandExecutor
- Fix zip path traversal in import (validate member paths)
- Fix shell script quoting (big-webapps, big-webapps-exec)
- Replace fragile manual JSON generation with _json_escape() + printf
- Convert browser_exec to bash array (big-webapps-exec)
- Add cmp -s guard for icon copy on every launch
- Add flock advisory locking for Wayland .desktop race condition
- Replace sed chain with case statement for browser name mapping

Architecture:
- Create webapp_service.py: centralized business logic layer (CRUD, export/import)
- Create browser_registry.py: single source of truth for browser ID/name/pattern mapping
- Create favicon_picker.py: extracted FlowBox icon selector widget
- Eliminate get_json.sh chain → direct big-webapps json + enrich_webapps_with_icons()
- Simplify application.py (-120L): all business logic moved to WebAppService
- Simplify main_window.py: all CRUD delegated to service layer
- Split webapp_dialog.py setup_ui() monolith → 5 builder methods
- Remove dead find_all_widget_types() method → use self.name_row directly
- State management: find_webapp() uses app_file (desktop filename) as stable ID

Accessibility (Orca screen reader):
- Add accessible labels to all interactive elements (buttons, entries, switches, dropdown)
- Add accessible descriptions to FlowBox favicon items
- Category headings: AccessibleRole.HEADING + focusable (Orca h-key nav)
- Destructive toasts: HIGH priority (assertive for screen readers)
- Empty state: focusable AdwStatusPage with grab_focus()
- Loading overlay: accessible description for screen readers
- Delete button: destructive-action CSS class (color + icon shape = dual indicator)
- Dynamic focus order: URL for new webapps, Name for editing

UX:
- Progressive disclosure: profile settings in AdwExpanderRow (collapsed by default)
- Save feedback: loading overlay + background thread + GLib.idle_add callback
- URL real-time validation: urlparse check + suffix icon (success/error) + CSS classes
- Welcome dialog: rename "Show dialog on startup" → "Don't show this again" (inverted logic)
- Remove-all: replace double-confirm dialog with single text-confirm entry
- FaviconPicker: .favicon-selected CSS class for visual selection feedback
- Delete confirmation: include URL and browser info for disambiguation

Code Quality:
- Migrate get_app_icon_url.py from GTK3 to GTK4
- Reduce cyclomatic complexity: 6 functions refactored (avg CC 54→5)
- Add type hints to all function signatures
- Fix unused variables (prefix _ for GTK callback params)
- Fix BROWSER_ICONS_PATH relative → absolute path
- Fix name_label.set_ellipsize(True) → Pango.EllipsizeMode.END
- Fix _open_folder infinite recursion
- Replace print() with structured logging (logging module)
- Consistent UUID-based webapp file IDs
- ruff lint: 0 errors, all checks passed
- bash -n: all shell scripts valid
…cements

Template System:
- WebAppTemplate dataclass (13 fields: mime_types, url_schemes, features, etc.)
- TemplateRegistry with search, match_url, category grouping
- 45 pre-built templates across 5 modules:
  office365 (8), google (10), communication (7), media (8), productivity (12)
- Template Gallery UI (Adw.Window, FlowBox grid, search, category sections)
- Gallery integrated into webapp_dialog.py headerbar ("Templates" button)
- Template selection auto-fills: URL, name, icon, category, app mode

Desktop Integration:
- .desktop generation: MimeType, Comment, GenericName, Keywords, X-BigWebApp-Template
- URL scheme handlers → x-scheme-handler/* MIME type auto-conversion
- %f positional arg in Exec line when MIME types present
- File handler: FileAwarePage(QWebEnginePage) with chooseFiles() intercept
- Download handler: QFileDialog.getSaveFileName via xdg-desktop-portal
- Notifications: setNotificationPresenter → notify-send bridge
- Permissions: auto-grant notifications, camera, microphone
- MPRIS media keys: optional D-Bus service + JS Media Session bridge
- command_executor: extra_env param for template metadata env vars
- webapp_model: template fields + apply_template() method

Viewer Fixes:
- fix Wayland/KWin resize bug: lock window size during navigation
  (setFixedSize on loadStarted, unlock on loadFinished)
- _on_new_window: use request.openIn(page) instead of setUrl()
- _enforce_screen_limits: setMaximumSize to screen bounds
- _load_geometry: clamp saved dimensions to 90% of screen
- _toggle_fullscreen: lift/restore max-size limits properly
Problem: KWin bypasses Qt's setMaximumSize for frameless windows during
cross-origin navigation (YouTube sign-in). Window stretches to ~3300px
when compositor receives null textures from QtWebEngine during page load.

Root cause: Wayland compositors reset frameless window geometry when
QtWebEngine produces null textures during cross-origin navigation.

Fix: lock window size with setFixedSize() on loadStarted, unlock on
loadFinished. Prevents compositor geometry changes during vulnerable
transition period.

Additional fixes:
- Add _ResizeHandle widget class → transparent edge overlays for CSD
  resize from left/right/bottom borders + bottom corners
- Replace broken mouseMoveEvent/mousePressEvent approach (child widgets
  consume events) with independent handle widgets per edge
- Each handle owns its cursor + calls startSystemResize() on drag
- Handles hidden when maximized/fullscreen, repositioned on resize
- JS reflow dispatch on loadFinished → fix YouTube sidebar layout after
  size lock release
- Clamp restored geometry to 90% of screen in _load_geometry()
- Enforce screen-size max via _enforce_screen_limits()
- Lift max-size limit before fullscreen, restore after exit
@talesam talesam merged commit f59acf1 into main Apr 15, 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