Changelog

What's new in each release.

v0.3.1

Critical

0.3.1

Audio quality

  • Much clearer mic pickup. Quieter voices no longer get muted by the noise gate, and the automatic volume level is stronger without clipping on loud syllables.
  • Fixed "robot voice" on Debian and Ubuntu. On some Linux distributions, audio was being resampled twice in a row, causing audible aliasing, most noticeable on Opus calls. The whole audio pipeline now runs at a single native rate end-to-end, so you hear the other person clearly.
  • Automatic adjustment on older Linux audio systems. The client now detects older PipeWire versions at startup and starts with larger audio buffers on them. If stuttering still occurs, it automatically enlarges the buffer further rather than waiting for a user to report it.

Call window

  • Ended-call summary now shows reliably. The brief recap after a call (name, duration, "Rejected" / "Missed" / "Call Ended") previously showed blank or disappeared early in some cases. It now always plays cleanly.
  • Tap the summary to dismiss it. Want to make another call immediately? Tap anywhere on the summary and it clears instantly instead of waiting for the animation.
  • No more window resize flicker on close. The window no longer grows or flashes on its last frame before closing.
  • Window stays on the right screen. If you unplug a monitor or change resolution, the call window no longer ends up off-screen, it validates its position on every change and re-centres on the current display if needed.
  • Window can't be cropped by the compositor. On some Linux desktops the window could be squeezed below its intended size, cutting off content. That's now prevented.

Settings

  • "Call window always on top" now tells you when it can't work. On GNOME (Wayland), this feature cannot be provided by any Linux desktop app, the desktop itself doesn't support it. Instead of silently doing nothing, the setting is now greyed out with a short explanation and a
    pointer to the GNOME extension that adds the capability. Other environments (KDE, X11, Windows) are unchanged.

Under the hood

  • Rewrote the call-window lifecycle for reliability. The logic that decides when the window appears, what it shows, and when it closes used to be spread across three separate files; it's now centralized, which eliminated a class of rare display glitches and makes future changes to the call window safer.
  • Added diagnostic logging. Call-window state transitions can now be traced with a single env-var flag, making future bug reports faster to diagnose.
Download v0.3.1

v0.3.0

Recommended

0.3.0

Microphone Reliability (Linux)

  • Fixed a long-standing issue where USB microphones would stop working after idle time. The microphone would appear connected but produce no sound until you unplugged and replugged the device, or fiddled with the system volume. This was caused by a known Linux audio subsystem bug. Meow now automatically installs a one-time system fix on first launch that prevents it from happening at all.
  • Fixed an issue where the app would sometimes fail to pick up USB headphones until the microphone volume was manually adjusted.
  • Microphone gain is now much louder and more responsive, with improved automatic noise suppression. The other party will hear you clearly without you having to raise your voice.

Audio Quality

  • Fixed audio stuttering and brief dropouts that some users experienced during calls, even on stable networks. The audio buffers have been retuned for better compatibility with modern Linux audio systems.
  • Fixed false "Connection unstable" warnings that could appear during calls when the network was actually fine.

Audio Device Selection

  • The app now correctly maintains your chosen speaker and microphone regardless of changes to your system's audio output. Previously, changing your system output would cause the app to lose its device selection.
  • Fixed an issue where the microphone would not be used until the headset was unplugged and reconnected.

Call Window

  • Fixed a focus-stealing issue on multi-monitor setups where the call window would grab back focus every time you clicked on another window. The call window now stays visually on top without hijacking your keyboard or interrupting your work.
  • Fixed an issue where the main app window couldn't be closed while a call window was open.
  • Fixed layout issues where caller info or the Accept/Decline buttons could be cut off, especially when a second call came in during an active call.
  • Fixed a rare display glitch where content could appear clipped during window state changes.
  • Redesigned the incoming call view for better clarity.

Caller Display

  • Fixed a display issue where some PBX systems would show the caller's name and phone number mashed together without a space (e.g., "John Smith0521234567"). The number is now properly separated.

Notifications

  • Fixed a bug where desktop notifications for incoming calls would still appear even after you disabled them in Settings.

Update System

  • Fixed auto-update on Windows. the installer now runs correctly after download.
  • Fixed auto-update on RPM-based Linux distributions (Fedora, openSUSE, RHEL) where updates could fail silently.
  • The "Dismiss" button on the update banner now works correctly, hiding the notification for 24 hours.

Wayland Compatibility

  • Fixed a crash on certain Linux distributions (e.g. openSUSE) when running under Wayland.

##Branding & Consistency

  • Cleaned up inconsistent spelling of "Meow" throughout the app. Existing user data is automatically migrated on first launch.

Downloads & Installation

  • Linux packages are now named consistently in lowercase: meow.deb, meow.rpm, meow.AppImage.
  • Windows installer is now meow-setup.exe.
  • Updated installation instructions on the download page.

v0.2.9

Recommended

0.2.9

Contact Name Resolution

  • Fixed incoming call contact lookup being overwritten by PBX caller ID. The call manager now does a local contact lookup before accepting the SIP-provided name, preferring saved contacts over PBX data.
  • Added contact name enrichment for outgoing calls. when dialing a saved contact, their name shows immediately instead of staying blank.

Call Window

  • Fixed runtime toggle. Hide/show cycle forces compositor to re-map the surface with updated flags.

Popup Call Window Setting

  • Wired up existing popupCallView setting that was defined but never used.
  • When disabled: call window starts minimized, showNormal() calls are suppressed.
  • Desktop notifications become mandatory when popup is disabled (only way to answer calls).
  • Hidden on Windows where no notification system exists.
  • Added toggle in Settings > Appearance with dynamic description.

Zoom/Scaling Overhaul

  • All hardcoded pixel values across the entire QML codebase converted to Theme.dp() for proper zoom scaling.

Call Window Performance (Windows)

  • Pre-load call window on Windows to eliminate the 3-5 second delay when placing a call. Linux behavior is unchanged.

v0.2.8

Recommended

New features!

  • Removed tooltip from the silence button in the call window
  • Added option to keep or remove the call window always on top (Settings > Appearance)
  • Added option to enable or disable desktop notifications for incoming calls (Settings > Appearance)
  • App now automatically restarts after installing an update
  • Fixed rendering issues causing lag and stuttering on Wayland (GNOME) with bundled Qt
  • Backup format bumped to v2. Now includes all encrypted and the license.
  • Fixed Add to contact icon not showing for some numbers

v0.2.7

Recommended

Incoming Call View

Incoming Call View

  • Accept, Decline, and Silence buttons are now uniform circular icons in a single row
  • Caller name, number, and status text centered
  • Green dot replaced with pulsing mint-colored "Incoming call" text
  • New bell-off icon for the Silence button

v0.2.6

Critical

Fix call window manager

Not final

  • This is not a final change to the window, this will make it work for now.
  • Call Window: Fixed not showing on GNOME/Wayland
  • Replaced the static CallView with a Loader that creates a fresh window for each call and destroys it after the call.
  • Fedora (GNOME/Wayland): window now shows reliably
  • Ubuntu (X11/XWayland): no longer fails on second+ calls due to focus-stealing prevention
  • Removed redundant visibility Connections in Main.qml that conflicted with CallView's own logic
  • Replaced the arbitrary timer with a direct binding to showingEndedSummary.
  • ICE Fallback: Fixed sound glitch and window flicker on retry
  • Removed unnecessary FBO rendering on call window

v0.2.4

Critical

Fix CPU Usage

UI

  1. Changed the location of the update message to make it less intrusive.

Encryption detection

  1. better detect call encryption

Performance

  1. Fixed: High CPU usage on some Linux systems. The audio device monitor and device enumeration were triggering each other in a loop. This caused PipeWire processes to consume up to ~350% CPU even while the app was idle.

v0.2.3

Recommended

New features

Call Quality Monitoring

  • Always-on stats collection: Call statistics (packet loss, jitter, RTT) are now collected continuously during active calls, not only when the stats panel is open.
  • Connection quality warning: New "Connection unstable" indicator when packet loss > 5%, jitter > 50ms, or RTT > 300ms. Status dot turns red, and an amber warning banner shows the specific issues (e.g. "High packet loss (8.2%) · High jitter (65 ms)").

Encryption Status Fix

  • TLS detection fix: Fixed TLS signaling not being detected because.

Button First-Click Fix

  • pressDelay: 0 on all scrollable containers: Added to every Flickable, ListView, and PageScroll in the app to prevent Qt's gesture disambiguation from swallowing the first click on buttons inside scrollable areas.

Account Registration Spinner

  • Settings account edit: Clicking "Update" now shows a BusyIndicator spinner with "Registering..." while the SIP registration is in progress. Buttons are disabled during registration. Form auto-closes on completion.
  • Setup Wizard: Same spinner and disabled buttons during "Create Account" registration.

Auto-Forward Calls

  • Added support to automatically forward incoming calls after x seconds.

Registration Error Handling

  • Auth failure stops retrying: Wrong credentials (401/403), account not found (404), and proxy auth required (407) no longer retry endlessly. Server errors (408, 503) and connection failures still retry.
  • Error messages: Human-readable error text per account (e.g. "Authentication failed. Check username and password").
  • Settings UI: Error text appears in red below the account in the accounts list.
  • Sidebar tooltips: Hovering over a failed account name in the sidebar shows the specific error.

Backup & Restore

  • Create Backup: Exports the SQLite database and all QSettings into an AES-256-GCM encrypted binary file (FullBackup.meow). Random 32-byte key displayed as base64 with copy button.
  • Restore Backup: File picker, key entry field, validation before any destructive action. Wrong key shows an error without touching app state. Correct key replaces database and settings, then restarts the app automatically.
  • File format: MEOWBAK magic header, version byte, 12-byte nonce, 16-byte GCM auth tag, encrypted payload.

v0.2.2

Recommended

Much More To Love!

Conference Calling

  • Fixed conference calls where connected parties couldn't hear each other. Cross-connects call audio ports on the PJSIP conference bridge.

SIP Registration & Licensing

  • SIP accounts no longer register when the license is expired. Unregisters on expiry, re-registers on activation.
  • Fixed registration retry: replaced escalating delays (5/10/30s) with a fixed 10-second cooldown.
  • Added live countdown displayed next to the account name during retry cooldown.
  • Added "Reset Network" button in Settings under SIP Accounts. Unregisters all, waits 5 seconds, re-registers with IP change handling.
  • Added confirmation dialog before removing a SIP account.

Networking, NAT Traversal, & Reconnect

  • Added STUN servers for public IP discovery behind NAT.
  • Added ICE support on SIP accounts for media path negotiation through firewalls.
  • Added automatic ICE fallback. If a call fails with 488, retries without ICE seamlessly.
  • Added IPv6 transport support (UDP6, TCP6, TLS6) alongside IPv4.
  • Auto-detects network type (IPv4-only, IPv6-only, dual-stack) on startup and after IP changes via pj_gethostip() probe.
  • Dual-stack networks prefer IPv4 for SDP offers; IPv6-only networks use IPv6.
  • Fixed PulseAudio device selection on Ubuntu/PipeWire. Explicitly selects the PulseAudio device instead of letting PJSIP default to raw ALSA locked by PipeWire.
  • Network change handler now does a full unregister/re-register cycle to get fresh transport bindings, fixing the "can't place calls after network reconnect" issue.
  • Auto-recovery: if an outgoing call fails to reach the PBX (transport broken), automatically triggers a network reset.
  • Increased PJSIP transport restart delay from 10ms to 500ms to avoid socket binding races.
  • Added NAT improvements: SIP Outbound (RFC 5626), explicit STUN for signaling and media, source port in Contact header, ICE host candidate limit.

Call Statistics

  • Fixed stats panel not working.
  • Changed stats polling interval from 2 seconds to 1 second.
  • Fixed bitrate display. Computed from total bytes / call connect duration instead of incorrect RTCP timestamp fields.

Encryption Detection & Display

  • Added SRTP encryption detection from PJSIP transport layer.
  • Added encryption indicator badge during active calls with three levels: Green: SRTP + TLS or SRTP = media encrypted. Amber: Media Unencrypted; TLS signaling only, RTP is plaintext. Red: Unencrypted; both signaling and media unencrypted.
  • Added encryption details row in the stats overlay panel with cipher name.
  • Added SRTP status logging for call diagnostics.

Audio Loss Detection

  • Added 5-second audio loss watchdog monitoring RTP packet counts during active calls.
  • Red "Audio lost — no packets received" banner appears on the call screen.
  • Watchdog runs independently of the stats panel.

Call Recording Player

  • Added in-app recording player popup dialog with play, pause, stop, and seek.
  • Seek bar with draggable handle and click-to-seek.
  • Progress display with elapsed/total time.
  • Block-aligned seeking to prevent audio artifacts.

Database

  • Enabled SQLite foreign key enforcement (PRAGMA foreign_keys = ON).
  • Enabled WAL journal mode for crash resilience.
  • Added integrity check on startup with automatic REINDEX repair on failure.
  • Added startup health check. Verifies all tables and columns exist, adds missing ones via.
  • Auto-prunes call history older than 120 days.
  • Fixed recording INSERT to include call_uuid for reliable linkage.
  • Added UUID fallback when looking up recordings. Matches by call_uuid if call_log_id is missing.
  • Added error logging on failed call log inserts.
  • Validated SQL identifiers in tableColumns(), ensureColumn(), and type parameters against injection.

License System

  • Replaced fixed 30-second trial retry with exponential backoff (30s → 60s → 2m → 5m → 10m, max 5 attempts).
  • Changed key/token presence logging from qWarning to qDebug. No partial secrets in production logs.
  • Documented intentional QML property exposure for license UI.

Performance

  • Eliminated idle CPU drain. Uses null sound device when no calls are active; real PulseAudio device activated on-demand when a call's media starts, deactivated when all calls end.
  • Eliminated thread leak. Replaced QThread::create() per tick in CallStatsProvider with a persistent StatsWorker on a single QThread.
  • Added proper CallStatsProvider destructor. Stops timers, quits worker thread, prevents use-after-free on shutdown.
  • Fixed pactl process leak. AudioDeviceHelper was spawning pactl list processes without killing previous in-flight ones, causing dozens of orphan processes that overwhelmed PipeWire. Now tracks processes as members and kills the old one before starting a new one.
  • Removed UI-blocking waitForFinished calls. killPaplay() no longer blocks the main thread for up to 500ms.
  • Deferred SIP initialization. SipEngine::initialize() runs after the event loop starts via QTimer::singleShot(0), so the UI loads instantly instead of waiting 2-5 seconds for STUN DNS resolution.
  • Cached D-Bus dark mode result. portalColorScheme() queried once at startup and on scheme changes, eliminating a 100ms blocking D-Bus call on every darkMode property read.
  • Reduced AudioLevelProvider poll rate from 30Hz to 20Hz. Still visually smooth, 33% less CPU and signal overhead.
  • Debounced audio device sync. setAudioDevices() / meow_pulse_move_streams() coalesced via 200ms timer to prevent burst of redundant PulseAudio move operations.
  • Batched recording lookup queries. callDetails() now uses WHERE IN (...) instead of one query per entry.
  • Incremental model update. addEntry() updates the first group in-place with dataChanged() instead of full beginResetModel()/endResetModel() when the new entry matches the top group.
  • Cached WAV header. Parsed once on playRecording(), reused for all seeks without re-reading the file.
  • Async pactl list device enumeration. Replaced synchronous waitForFinished(2000) with QProcess::finished signal handler.

Code Quality

  • Extracted linkRecordingsToLogEntry() helper. Eliminated duplicate recording-link code in logCallEnd and logCallEntry.
  • Extracted resetCallState() helper. Eliminated duplicate state-reset boilerplate across dial(), answerIncoming(), onSipIncomingCall(), and promoteNextIncoming().
  • Extracted shared Crypto::verifyEd25519() and Crypto::ed25519Payload(). Eliminated duplicate Ed25519 verification in LicenseManager and UpdateManager.
  • Fixed SecondaryButton. DemiBold weight, disabled state uses Theme.textMuted.
  • Fixed QML duplicate id: resetLabel causing SettingsView to fail to load.

Security

  • SIP password no longer returned to QML.
  • PJSIP log level reduced to 2 for release builds to prevents Authorization digest headers from appearing in logs.
  • Windows update batch script arguments sanitized — strips ", %, ^, &, |, <, >, ! to prevent command injection.
  • SQL type parameter validated in ensureColumn() against ^[a-zA-Z0-9 ()_,]+$.
  • Update downloads rejected without checksum for known package formats (deb, rpm, exe, msi, dmg, AppImage) in release builds.
  • s_active_stream pointer in PulseAudioDev changed to std::atomic<pulse_stream*> with acquire/release ordering.
  • Recording files now set to 0600 permissions after save.
  • execPragma() failures now logged instead of silently ignored.

Compatibility

  • Verified full build compatibility with Ubuntu 25.10 (GCC 15.2, Qt 6.9.2, CMake 3.31.6, kernel 6.17).

Call Hold Transfer

  • Added transfer button to the held-only call view, allowing call transfer without unholding first.

Held Call UI Redesign

  • Replaced text buttons with three circular action buttons: End (coral), Resume (teal), Transfer (indigo).
  • Added pulsing fade animation on the amber "On Hold" indicator dot.

Consent Screen Fix

  • Fixed "click twice to register" bug on the privacy consent button by moving it outside the Flickable scroll container (both mobile and desktop layouts).

Window Sizing

  • Increased main window from 820×580 to 860×640.
  • Increased held-only call window height from 320 to 400.
  • Added 16px horizontal and 12px bottom padding to call content area.

Call History Detail View

  • Copy number button now always visible.
  • Replaced bouncing scroll chevrons with gradient fade edges (top/bottom) for a cleaner look.
  • Removed external scrollbar.

Dialer Cursor Fix

  • Fixed cursor indicator positioning in the number input field. It now tracks the AnimatedDigits component instead of the invisible TextInput layout.

v0.2.1

New UX

  1. Fixed cases when transfer a call won't work right after transferring to a disconnected/non existing extension.
  2. Fixed rare cases when ending a call while there are calls waiting would cause the call manager window to become unresponsive till the queue is finished.
  3. Redesign the call manager window to be more robust and handle rapid changes without crashing.