There is no built-in option to change this behavior (although it does seem like a bug). However, there are two Select2 events that should work together to do what you want (but it depends on the order in which these events fire): “select2:unselecting” and “select2:opening”.
If “select2:unselecting” fires before “select2:opening”*, then you would set a global** flag (Boolean-valued variable) in the “select2:unselecting” event handler (indicating that a deselecting event has just occurred) and return
true. Then in your “select2:opening” event handler, you’d check the value of this flag. If
true, you’d cancel the “select2:opening” event (by returning
false from the event handler); otherwise you’d return
true to allow the event to proceed. In either case, before returning you’d clear the “deselecting” global flag.
* I believe this is the order these events fire in, based on the example shown in the Select2 Events documentation.
*" “global” in the sense that both event handlers can see the variable.
However, If “select2:opening” fires before “select2:unselecting” you’d have to be a bit more creative. My advice in that case would be to set a timeout for a few milliseconds in the future and then immediately cancel the “select2:opening” event. When your timeout callback runs, it looks for the flag set by the “select2:unselecting” event handler. If the flag is set, the callback just resets the flag and exits; but if the flag is not set, then the callback should progarmmatically open the Select2 (and reset the flag).