From f3ba25df7d2f6e3dd33aa075a3345c8bd186134d Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Mon, 2 Mar 2026 18:04:08 +0100 Subject: [PATCH] qt: utxo_list: only enable 'fully spend...' menu if there are unfrozen coins in the selection. otherwise, when selecting only frozen coins, the set of usable coins is empty, and the menu options will instead fall back to using ALL coins without informing the user. --- electrum/gui/qt/utxo_list.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/electrum/gui/qt/utxo_list.py b/electrum/gui/qt/utxo_list.py index 94f8fe086..a5aef66e4 100644 --- a/electrum/gui/qt/utxo_list.py +++ b/electrum/gui/qt/utxo_list.py @@ -301,11 +301,15 @@ class UTXOList(MyTreeView): def create_menu(self, position): selected = self.get_selected_outpoints() - menu = QMenu() - menu.setSeparatorsCollapsible(True) # consecutive separators are merged together coins = [self._utxo_dict[name] for name in selected] + if not coins: return + + unfrozen_coins = self._filter_frozen_coins(coins) + menu = QMenu() + menu.setSeparatorsCollapsible(True) # consecutive separators are merged together + if len(coins) == 1: idx = self.indexAt(position) if not idx.isValid(): @@ -320,18 +324,20 @@ class UTXOList(MyTreeView): cc = self.add_copy_menu(menu, idx) cc.addAction(_("Long Output point"), lambda: self.place_text_on_clipboard(utxo.prevout.to_str(), title="Long Output point")) # fully spend - menu_spend = menu.addMenu(_("Fully spend") + '…') - m = menu_spend.addAction(_("send to address in clipboard"), lambda: self.pay_to_clipboard_address(coins)) + m = menu_spend = menu.addMenu(_("Fully spend") + '…') + m.setEnabled(bool(unfrozen_coins)) + m = menu_spend.addAction(_("send to address in clipboard"), lambda: self.pay_to_clipboard_address(unfrozen_coins)) m.setEnabled(self.clipboard_contains_address()) - m = menu_spend.addAction(_("in new channel"), lambda: self.open_channel_with_coins(coins)) - m.setEnabled(self.can_open_channel(coins)) - m = menu_spend.addAction(_("in submarine swap"), lambda: self.swap_coins(coins)) - m.setEnabled(self.can_swap_coins(coins)) + m = menu_spend.addAction(_("in new channel"), lambda: self.open_channel_with_coins(unfrozen_coins)) + m.setEnabled(self.can_open_channel(unfrozen_coins)) + m = menu_spend.addAction(_("in submarine swap"), lambda: self.swap_coins(unfrozen_coins)) + m.setEnabled(self.can_swap_coins(unfrozen_coins)) # coin control if self.are_in_coincontrol(coins): menu.addAction(_("Remove from coin control"), lambda: self.remove_from_coincontrol(coins)) else: - menu.addAction(_("Add to coin control"), lambda: self.add_to_coincontrol(coins)) + m = menu.addAction(_("Add to coin control"), lambda: self.add_to_coincontrol(coins)) + m.setEnabled(bool(unfrozen_coins)) # Freeze menu if len(coins) == 1: utxo = coins[0]