UnigramDev/Unigram/develop • de28263 • 1 files, +39/-6
Stop the gallery from taking input while it closes (#3354)
Closing the gallery is animated: OnBackRequestedOverride calls Unload()
synchronously, which drops the data context, while Hide() only runs when the
closing animation completes. In between the window is still visible and still
hit-testable, so a click on a caption hyperlink ran Caption_TextEntityClick
with a null ViewModel and crashed in the MessageDelegate constructor
(NullReferenceException, reported by crash telemetry on 12.9.1). The caption
sits outside ScrollingHost, so the tap-to-close handler never consumes it.
Unload() now clears IsHitTestVisible, which closes the whole "input after
unload" family instead of one handler at a time; Caption_TextEntityClick is
guarded as well, because a focused hyperlink can still be invoked from the
keyboard or by automation, neither of which hit tests.
Also fix the same method leaving the window on screen forever: the connected
animation's Completed was subscribed before TryStart, and when TryStart failed
translate became false, so neither Hide() was reachable. Hide() now runs off
the fade batch, which is started on every path, and Completed is subscribed
only when the animation actually started.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
UnigramDev/Unigram/develop • 162781d • 3 files, +37/-1
Detach the emoji and sticker drawers from their collections (#3355)
InvalidComObjectException — "COM object that has been separated from its
underlying RCW cannot be used" — reported by crash telemetry on 12.9.1,
raised from MvxObservableCollection.ReplaceWith inside
EmojiDrawerViewModel.Update.
EmojiDrawer's CollectionViewSource and its two toolbars bind straight to the
view model's collections, so their native peers subscribe to CollectionChanged.
Deactivate() only called Bindings.StopTracking(), which stops the bindings from
updating but leaves the value they already pushed in place, and it runs right
before XamlMarkupHelper.UnloadObject destroys those peers. The view model
subscribes to the aggregator in its constructor and Handle queues Update on the
UI thread, so a queued update outlives the drawer and raises into the dead
peers.
Clear the collection sources in Deactivate so nothing native is still attached
once the peers go away. StickerDrawer has the same shape and the same terminal
Deactivate contract, so it gets the same treatment.
EmojiMenuFlyout never deactivated its drawer at all, and only one of its three
constructors subscribed to Popup.Closed; move that subscription into Initialize
and tear the drawer down there, matching what StickerPanel does when it unloads
a drawer.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
#unigram
Post #20651
43