Le patch yoda 5b838a67 est conserve (il initialise les plafonds sink ET
source, contrairement au code inline amont) mais il est desormais dans
une closure recevant `app: &mut Self` : l appel sur `self` ne compilait
plus.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
max_sink_volume and max_source_volume were only computed in the
TogglePopup handler, so they kept their Default value of 0 until the
popup had been opened once. The scroll-to-adjust handler clamps against
max_sink_volume, which meant every wheel event resolved to
SetSinkVolume(0) until the user had clicked the applet icon: scrolling
up did nothing and scrolling down muted the sink.
Extract refresh_volume_limits() and call it from init() as well as from
TogglePopup, so the popup still picks up amplification config changes
made during the session.
This is the actual cause of "scroll does not adjust volume until the
applet is clicked once" — the wheel events were reaching the widget all
along, which is why a single click made scrolling work on plain hover
from then on.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Move the on_mouse_wheel handler before the cursor.is_over(bounds)
guard. The panel's nested compositor only routes axis events to the
applet surface when the pointer is over it, making the bounds check
redundant for scroll events. This fixes scroll-to-adjust-volume not
working on the audio applet after a fresh login, when the cursor
coordinates sent by the panel may not match the applet's surface-local
coordinate space.
Avec Wayland axis_v120 (scroll haute-résolution sur souris HID modernes),
un cran physique génère 5–8 events ScrollDelta::Pixels (~15–20px chacun).
L'ancien code passait chaque sub-event par .signum() puis -1/+1 à sink_volume,
donc un seul cran physique faisait varier le volume de 5 à 40% — résultat :
scroll up sur l'icône audio panel / dock coupait le son si le volume était
déjà bas.
Fix : thread_local accumulator des deltas Pixels, émission seulement
au passage du seuil de 15px par cran logique. Lines (souris classique
sans axis_v120) reste proportionnel y * WHEEL_STEP. round() au lieu de
truncation finale pour ne pas perdre les fractions de pourcent.
Leyoda 2026 - GPLv3
Unstable sorting should be slightly faster than stable sorting, and if
the vector was built asynchronously then preserving the initial order
doesn't matter too much.
Continue to use stable sorting where the vector is not built
asynchronously, or if the vector is partially sorted (e.g. when new
elements are pushed to a sorted vector).