From 31539a27ac7bf3548d529bf6b9ff61ef5503c210 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 29 Sep 2023 12:02:14 +0200 Subject: [PATCH] improve fullscreen behaviour by setting dialog ownership to parent window --- .../sparrowwallet/sparrow/AppController.java | 28 +++++++++++++++++++ .../sparrowwallet/sparrow/AppServices.java | 2 ++ .../sparrow/DefaultInteractionServices.java | 5 ++-- .../sparrow/control/AddressCell.java | 2 +- .../sparrow/control/CoinTreeTable.java | 1 + .../sparrow/control/EntryCell.java | 6 ++-- .../sparrow/control/FileImportPane.java | 1 + .../control/FileKeystoreExportPane.java | 3 ++ .../sparrow/control/FileWalletExportPane.java | 2 ++ .../sparrow/control/MessageSignDialog.java | 4 +++ .../sparrow/control/MnemonicGridDialog.java | 1 + .../control/MnemonicKeystoreImportPane.java | 1 + .../sparrow/control/MnemonicKeystorePane.java | 2 ++ .../sparrow/control/PayNymCell.java | 1 + .../control/PrivateKeySweepDialog.java | 5 ++++ .../sparrow/control/TextAreaDialog.java | 1 + .../sparrow/control/TransactionDiagram.java | 3 +- .../com/sparrowwallet/sparrow/io/Storage.java | 1 - .../sparrow/paynym/PayNymController.java | 4 +++ .../GeneralPreferencesController.java | 1 + .../ServerPreferencesController.java | 2 ++ .../soroban/CounterpartyController.java | 2 ++ .../sparrow/soroban/InitiatorController.java | 2 ++ .../sparrow/soroban/InitiatorDialog.java | 1 + .../transaction/HeadersController.java | 4 +++ .../sparrow/wallet/AddressesController.java | 1 + .../sparrow/wallet/KeystoreController.java | 10 +++++++ .../sparrow/wallet/PaymentController.java | 3 ++ .../sparrow/wallet/ReceiveController.java | 4 +++ .../sparrow/wallet/SendController.java | 4 +++ .../sparrow/wallet/SettingsController.java | 11 ++++++++ .../sparrow/wallet/UtxosController.java | 3 ++ 32 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index bef4105d..fc2af524 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -451,6 +451,7 @@ public class AppController implements Initializable { public void showIntroduction(ActionEvent event) { WelcomeDialog welcomeDialog = new WelcomeDialog(); + welcomeDialog.initOwner(rootStack.getScene().getWindow()); Optional optionalMode = welcomeDialog.showAndWait(); if(optionalMode.isPresent() && optionalMode.get().equals(Mode.ONLINE)) { openPreferences(PreferenceGroup.SERVER); @@ -539,6 +540,7 @@ public class AppController implements Initializable { public void showInstallUdevMessage() { TextAreaDialog dialog = new TextAreaDialog("sudo " + Config.get().getHwi().getAbsolutePath() + " installudevrules"); + dialog.initOwner(rootStack.getScene().getWindow()); dialog.setTitle("Install Udev Rules"); dialog.getDialogPane().setHeaderText("Installing udev rules ensures devices can connect over USB.\nThis command requires root privileges.\nOpen a shell and enter the following:"); dialog.showAndWait(); @@ -607,6 +609,7 @@ public class AppController implements Initializable { public void openTransactionFromText(ActionEvent event) { TextAreaDialog dialog = new TextAreaDialog(); + dialog.initOwner(rootStack.getScene().getWindow()); dialog.setTitle("Open from text"); dialog.getDialogPane().setHeaderText("Paste a transaction or PSBT:"); Optional text = dialog.showAndWait(); @@ -625,6 +628,7 @@ public class AppController implements Initializable { public void openTransactionFromId(ActionEvent event) { TransactionIdDialog dialog = new TransactionIdDialog(); + dialog.initOwner(rootStack.getScene().getWindow()); Optional optionalTxId = dialog.showAndWait(); if(optionalTxId.isPresent()) { Sha256Hash txId = optionalTxId.get(); @@ -652,6 +656,7 @@ public class AppController implements Initializable { public void openTransactionFromQR(ActionEvent event) { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(rootStack.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); @@ -715,6 +720,7 @@ public class AppController implements Initializable { try { UR ur = UR.fromBytes(transaction.bitcoinSerialize()); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(ur); + qrDisplayDialog.initOwner(rootStack.getScene().getWindow()); qrDisplayDialog.showAndWait(); } catch(Exception e) { log.error("Error creating UR", e); @@ -813,6 +819,7 @@ public class AppController implements Initializable { CryptoPSBT cryptoPSBT = new CryptoPSBT(transactionTabData.getPsbt().serialize()); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(cryptoPSBT.toUR()); + qrDisplayDialog.initOwner(rootStack.getScene().getWindow()); qrDisplayDialog.show(); } } @@ -978,6 +985,7 @@ public class AppController implements Initializable { public void newWallet(ActionEvent event) { WalletNameDialog dlg = new WalletNameDialog(); + dlg.initOwner(rootStack.getScene().getWindow()); Optional optNameAndBirthDate = dlg.showAndWait(); if(optNameAndBirthDate.isPresent()) { WalletNameDialog.NameAndBirthDate nameAndBirthDate = optNameAndBirthDate.get(); @@ -1027,6 +1035,7 @@ public class AppController implements Initializable { loadWalletService.start(); } else { WalletPasswordDialog dlg = new WalletPasswordDialog(storage.getWalletName(null), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(rootStack.getScene().getWindow()); Optional optionalPassword = dlg.showAndWait(); if(optionalPassword.isEmpty()) { return; @@ -1095,6 +1104,7 @@ public class AppController implements Initializable { public void importWallet(ActionEvent event) { List selectedWalletForms = getSelectedWalletForms(); WalletImportDialog dlg = new WalletImportDialog(selectedWalletForms); + dlg.initOwner(rootStack.getScene().getWindow()); Optional optionalWallet = dlg.showAndWait(); if(optionalWallet.isPresent()) { Wallet wallet = optionalWallet.get(); @@ -1132,6 +1142,7 @@ public class AppController implements Initializable { try(FileInputStream inputStream = new FileInputStream(file)) { if(importer.isEncrypted(file) && password == null) { WalletPasswordDialog dlg = new WalletPasswordDialog(file.getName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(rootStack.getScene().getWindow()); Optional optionalPassword = dlg.showAndWait(); if(optionalPassword.isPresent()) { password = optionalPassword.get(); @@ -1154,6 +1165,7 @@ public class AppController implements Initializable { private void addImportedWallet(Wallet wallet) { WalletNameDialog nameDlg = new WalletNameDialog(wallet.getName(), true, wallet.getBirthDate()); + nameDlg.initOwner(rootStack.getScene().getWindow()); Optional optNameAndBirthDate = nameDlg.showAndWait(); if(optNameAndBirthDate.isPresent()) { WalletNameDialog.NameAndBirthDate nameAndBirthDate = optNameAndBirthDate.get(); @@ -1199,6 +1211,7 @@ public class AppController implements Initializable { Storage storage = new Storage(Storage.getWalletFile(wallet.getName())); WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getName(), WalletPasswordDialog.PasswordRequirement.UPDATE_NEW); + dlg.initOwner(rootStack.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { if(password.get().length() == 0) { @@ -1265,6 +1278,7 @@ public class AppController implements Initializable { WalletForm selectedWalletForm = getSelectedWalletForm(); if(selectedWalletForm != null) { WalletExportDialog dlg = new WalletExportDialog(selectedWalletForm.getWallet()); + dlg.initOwner(rootStack.getScene().getWindow()); Optional wallet = dlg.showAndWait(); if(wallet.isPresent()) { //Successful export @@ -1282,6 +1296,7 @@ public class AppController implements Initializable { private void openPreferences(PreferenceGroup preferenceGroup) { PreferencesDialog preferencesDialog = new PreferencesDialog(preferenceGroup); + preferencesDialog.initOwner(rootStack.getScene().getWindow()); preferencesDialog.showAndWait(); configureSwitchServer(); serverToggle.setDisable(!Config.get().hasServer()); @@ -1303,6 +1318,7 @@ public class AppController implements Initializable { messageSignDialog = new MessageSignDialog(); } + messageSignDialog.initOwner(rootStack.getScene().getWindow()); messageSignDialog.showAndWait(); } @@ -1323,6 +1339,7 @@ public class AppController implements Initializable { } sendToManyDialog = new SendToManyDialog(bitcoinUnit); + sendToManyDialog.initOwner(rootStack.getScene().getWindow()); sendToManyDialog.initModality(Modality.NONE); Optional> optPayments = sendToManyDialog.showAndWait(); sendToManyDialog = null; @@ -1343,6 +1360,7 @@ public class AppController implements Initializable { } PrivateKeySweepDialog dialog = new PrivateKeySweepDialog(wallet); + dialog.initOwner(rootStack.getScene().getWindow()); Optional optTransaction = dialog.showAndWait(); optTransaction.ifPresent(transaction -> addTransactionTab(null, null, transaction)); } @@ -1356,6 +1374,7 @@ public class AppController implements Initializable { if(wallet.isEncrypted()) { Wallet copy = wallet.copy(); WalletPasswordDialog dlg = new WalletPasswordDialog(copy.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(rootStack.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage storage = selectedWalletForm.getStorage(); @@ -1369,6 +1388,7 @@ public class AppController implements Initializable { try { soroban.setHDWallet(copy); CounterpartyDialog counterpartyDialog = new CounterpartyDialog(selectedWalletForm.getWalletId(), selectedWalletForm.getWallet()); + counterpartyDialog.initOwner(rootStack.getScene().getWindow()); if(Config.get().isSameAppMixing()) { counterpartyDialog.initModality(Modality.NONE); } @@ -1396,6 +1416,7 @@ public class AppController implements Initializable { } else { soroban.setHDWallet(wallet); CounterpartyDialog counterpartyDialog = new CounterpartyDialog(selectedWalletForm.getWalletId(), selectedWalletForm.getWallet()); + counterpartyDialog.initOwner(rootStack.getScene().getWindow()); if(Config.get().isSameAppMixing()) { counterpartyDialog.initModality(Modality.NONE); } @@ -1403,6 +1424,7 @@ public class AppController implements Initializable { } } else { CounterpartyDialog counterpartyDialog = new CounterpartyDialog(selectedWalletForm.getWalletId(), selectedWalletForm.getWallet()); + counterpartyDialog.initOwner(rootStack.getScene().getWindow()); if(Config.get().isSameAppMixing()) { counterpartyDialog.initModality(Modality.NONE); } @@ -1415,6 +1437,7 @@ public class AppController implements Initializable { WalletForm selectedWalletForm = getSelectedWalletForm(); if(selectedWalletForm != null) { PayNymDialog payNymDialog = new PayNymDialog(selectedWalletForm.getWalletId()); + payNymDialog.initOwner(rootStack.getScene().getWindow()); payNymDialog.showAndWait(); } } @@ -1461,6 +1484,7 @@ public class AppController implements Initializable { List walletForms = subTabs.getTabs().stream().map(subTab -> ((WalletTabData)subTab.getUserData()).getWalletForm()).collect(Collectors.toList()); if(!walletForms.isEmpty()) { SearchWalletDialog searchWalletDialog = new SearchWalletDialog(walletForms); + searchWalletDialog.initOwner(rootStack.getScene().getWindow()); Optional optEntry = searchWalletDialog.showAndWait(); if(optEntry.isPresent()) { Entry entry = optEntry.get(); @@ -1481,6 +1505,7 @@ public class AppController implements Initializable { List walletForms = subTabs.getTabs().stream().map(subTab -> ((WalletTabData)subTab.getUserData()).getWalletForm()).collect(Collectors.toList()); if(!walletForms.isEmpty()) { WalletSummaryDialog walletSummaryDialog = new WalletSummaryDialog(walletForms); + walletSummaryDialog.initOwner(rootStack.getScene().getWindow()); walletSummaryDialog.showAndWait(); } } @@ -2004,6 +2029,7 @@ public class AppController implements Initializable { private void renameWallet(WalletForm selectedWalletForm) { WalletNameDialog walletNameDialog = new WalletNameDialog(selectedWalletForm.getMasterWallet().getName(), false, null, true); + walletNameDialog.initOwner(rootStack.getScene().getWindow()); Optional optName = walletNameDialog.showAndWait(); if(optName.isPresent()) { File walletFile = Storage.getWalletFile(optName.get().getName() + "." + PersistenceType.DB.getExtension()); @@ -2032,6 +2058,7 @@ public class AppController implements Initializable { Storage storage = selectedWalletForm.getStorage(); if(selectedWalletForm.getMasterWallet().isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(selectedWalletForm.getWallet().getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(rootStack.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(storage, password.get(), true); @@ -2099,6 +2126,7 @@ public class AppController implements Initializable { rename.setOnAction(event -> { Label subTabLabel = (Label)subTab.getGraphic(); WalletLabelDialog walletLabelDialog = new WalletLabelDialog(subTabLabel.getText()); + walletLabelDialog.initOwner(rootStack.getScene().getWindow()); Optional optLabel = walletLabelDialog.showAndWait(); if(optLabel.isPresent()) { String label = optLabel.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/AppServices.java b/src/main/java/com/sparrowwallet/sparrow/AppServices.java index e01a9cbc..19a59387 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppServices.java @@ -949,6 +949,7 @@ public class AppServices { Storage storage = AppServices.get().getOpenWallets().get(wallet); Wallet copy = wallet.copy(); WalletPasswordDialog dlg = new WalletPasswordDialog(copy.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(getActiveWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(storage, password.get(), true); @@ -1011,6 +1012,7 @@ public class AppServices { wallet = wallets.iterator().next(); } else { ChoiceDialog walletChoiceDialog = new ChoiceDialog<>(wallets.iterator().next(), wallets); + walletChoiceDialog.initOwner(getActiveWindow()); walletChoiceDialog.setTitle("Choose Wallet"); walletChoiceDialog.setHeaderText("Choose a wallet to " + actionDescription); Image image = new Image("/image/sparrow-small.png"); diff --git a/src/main/java/com/sparrowwallet/sparrow/DefaultInteractionServices.java b/src/main/java/com/sparrowwallet/sparrow/DefaultInteractionServices.java index 2e712f23..fb14d4a0 100644 --- a/src/main/java/com/sparrowwallet/sparrow/DefaultInteractionServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/DefaultInteractionServices.java @@ -15,13 +15,13 @@ import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.sparrowwallet.sparrow.AppServices.moveToActiveWindowScreen; -import static com.sparrowwallet.sparrow.AppServices.setStageIcon; +import static com.sparrowwallet.sparrow.AppServices.*; public class DefaultInteractionServices implements InteractionServices { @Override public Optional showAlert(String title, String content, Alert.AlertType alertType, Node graphic, ButtonType... buttons) { Alert alert = new Alert(alertType, content, buttons); + alert.initOwner(getActiveWindow()); setStageIcon(alert.getDialogPane().getScene().getWindow()); alert.getDialogPane().getScene().getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm()); alert.setTitle(title); @@ -62,6 +62,7 @@ public class DefaultInteractionServices implements InteractionServices { @Override public Optional requestPassphrase(String walletName, Keystore keystore) { KeystorePassphraseDialog passphraseDialog = new KeystorePassphraseDialog(walletName, keystore); + passphraseDialog.initOwner(getActiveWindow()); return passphraseDialog.showAndWait(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/AddressCell.java b/src/main/java/com/sparrowwallet/sparrow/control/AddressCell.java index 37934e24..ec388e0d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/AddressCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/AddressCell.java @@ -40,7 +40,7 @@ public class AddressCell extends TreeTableCell { if(utxoEntry != null) { Address address = addressStatus.getAddress(); setText(address.toString()); - setContextMenu(new EntryCell.AddressContextMenu(address, utxoEntry.getOutputDescriptor(), new NodeEntry(utxoEntry.getWallet(), utxoEntry.getNode()), false)); + setContextMenu(new EntryCell.AddressContextMenu(address, utxoEntry.getOutputDescriptor(), new NodeEntry(utxoEntry.getWallet(), utxoEntry.getNode()), false, getTreeTableView())); Tooltip tooltip = new Tooltip(); tooltip.setShowDelay(Duration.millis(250)); tooltip.setText(getTooltipText(utxoEntry, addressStatus.isDuplicate(), addressStatus.isDustAttack())); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java index e292849e..597062f1 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java @@ -109,6 +109,7 @@ public class CoinTreeTable extends TreeTableView { hyperlink.setTranslateY(30); hyperlink.setOnAction(event -> { WalletBirthDateDialog dlg = new WalletBirthDateDialog(wallet.getBirthDate(), false); + dlg.initOwner(this.getScene().getWindow()); Optional optDate = dlg.showAndWait(); if(optDate.isPresent()) { Storage storage = AppServices.get().getOpenWallets().get(wallet); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java index 693559ad..373d9c03 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java @@ -124,7 +124,7 @@ public class EntryCell extends TreeTableCell implements Confirmati NodeEntry nodeEntry = (NodeEntry)entry; Address address = nodeEntry.getAddress(); setText(address.toString()); - setContextMenu(new AddressContextMenu(address, nodeEntry.getOutputDescriptor(), nodeEntry, true)); + setContextMenu(new AddressContextMenu(address, nodeEntry.getOutputDescriptor(), nodeEntry, true, getTreeTableView())); Tooltip tooltip = new Tooltip(); tooltip.setShowDelay(Duration.millis(250)); tooltip.setText(nodeEntry.getNode().toString()); @@ -149,6 +149,7 @@ public class EntryCell extends TreeTableCell implements Confirmati signMessageButton.setGraphic(getSignMessageGlyph()); signMessageButton.setOnAction(event -> { MessageSignDialog messageSignDialog = new MessageSignDialog(nodeEntry.getWallet(), nodeEntry.getNode()); + messageSignDialog.initOwner(getTreeTableView().getScene().getWindow()); messageSignDialog.showAndWait(); }); actionBox.getChildren().add(signMessageButton); @@ -645,7 +646,7 @@ public class EntryCell extends TreeTableCell implements Confirmati } public static class AddressContextMenu extends ContextMenu { - public AddressContextMenu(Address address, String outputDescriptor, NodeEntry nodeEntry, boolean addUtxoItems) { + public AddressContextMenu(Address address, String outputDescriptor, NodeEntry nodeEntry, boolean addUtxoItems, TreeTableView treetable) { if(nodeEntry == null || !nodeEntry.getWallet().isBip47()) { MenuItem receiveToAddress = new MenuItem("Receive To"); receiveToAddress.setGraphic(getReceiveGlyph()); @@ -663,6 +664,7 @@ public class EntryCell extends TreeTableCell implements Confirmati signVerifyMessage.setOnAction(AE -> { hide(); MessageSignDialog messageSignDialog = new MessageSignDialog(nodeEntry.getWallet(), nodeEntry.getNode()); + messageSignDialog.initOwner(treetable.getScene().getWindow()); messageSignDialog.showAndWait(); }); getItems().add(signVerifyMessage); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java index 6fd51965..9e2806c3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java @@ -150,6 +150,7 @@ public abstract class FileImportPane extends TitledDescriptionPane { private void importQR() { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(this.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreExportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreExportPane.java index f97ae4b5..aa14fd6c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreExportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreExportPane.java @@ -116,6 +116,7 @@ public class FileKeystoreExportPane extends TitledDescriptionPane { if(keystore.getSource() == KeystoreSource.HW_USB || keystore.getWalletModel().isCard()) { TextAreaDialog dialog = new TextAreaDialog(message, false); + dialog.initOwner(this.getScene().getWindow()); dialog.setTitle("Sign " + exporter.getName() + " Export"); dialog.getDialogPane().setHeaderText("The following text needs to be signed by the device.\nClick OK to continue."); dialog.showAndWait(); @@ -126,6 +127,7 @@ public class FileKeystoreExportPane extends TitledDescriptionPane { List operationFingerprints = List.of(keystore.getKeyDerivation().getMasterFingerprint()); DeviceSignMessageDialog deviceSignMessageDialog = new DeviceSignMessageDialog(operationFingerprints, wallet, message, keystore.getKeyDerivation()); + deviceSignMessageDialog.initOwner(this.getScene().getWindow()); Optional optSignature = deviceSignMessageDialog.showAndWait(); if(optSignature.isPresent()) { exporter.addSignature(keystore, optSignature.get(), baos); @@ -155,6 +157,7 @@ public class FileKeystoreExportPane extends TitledDescriptionPane { } else { qrDisplayDialog = new QRDisplayDialog(baos.toString(StandardCharsets.UTF_8)); } + qrDisplayDialog.initOwner(buttonBox.getScene().getWindow()); qrDisplayDialog.showAndWait(); } } catch(Exception e) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java index 0504759a..d2704daf 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletExportPane.java @@ -111,6 +111,7 @@ public class FileWalletExportPane extends TitledDescriptionPane { if(wallet.isEncrypted() && exporter.walletExportRequiresDecryption()) { Wallet copy = wallet.copy(); WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(buttonBox.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { final String walletId = AppServices.get().getOpenWallets().get(wallet).getWalletId(wallet); @@ -155,6 +156,7 @@ public class FileWalletExportPane extends TitledDescriptionPane { } else { qrDisplayDialog = new QRDisplayDialog(outputStream.toString(StandardCharsets.UTF_8)); } + qrDisplayDialog.initOwner(buttonBox.getScene().getWindow()); qrDisplayDialog.showAndWait(); } } catch(Exception e) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java index 62c8ae95..2d711645 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java @@ -384,6 +384,7 @@ public class MessageSignDialog extends Dialog { List fingerprints = List.of(deviceWallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint()); KeyDerivation fullDerivation = deviceWallet.getKeystores().get(0).getKeyDerivation().extend(walletNode.getDerivation()); DeviceSignMessageDialog deviceSignMessageDialog = new DeviceSignMessageDialog(fingerprints, deviceWallet, message.getText().trim(), fullDerivation); + deviceSignMessageDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optSignature = deviceSignMessageDialog.showAndWait(); if(optSignature.isPresent()) { signature.clear(); @@ -468,6 +469,7 @@ public class MessageSignDialog extends Dialog { String qrText = "signmessage " + derivationPath + " ascii:" + message.getText().trim(); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(qrText, true); + qrDisplayDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optButtonType = qrDisplayDialog.showAndWait(); if(optButtonType.isPresent() && optButtonType.get().getButtonData() == ButtonBar.ButtonData.NEXT_FORWARD) { scanQr(); @@ -476,6 +478,7 @@ public class MessageSignDialog extends Dialog { private void scanQr() { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); @@ -517,6 +520,7 @@ public class MessageSignDialog extends Dialog { } WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(getDialogPane().getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(walletNode.getWallet().copy(), password.get()); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java index ef92d223..c3ca01ba 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java @@ -281,6 +281,7 @@ public class MnemonicGridDialog extends Dialog> { ButtonBar.setButtonData(generateButton, buttonData); generateButton.setOnAction(event -> { SeedEntryDialog seedEntryDialog = new SeedEntryDialog("Border Wallets Entropy Grid Recovery Seed", 12); + seedEntryDialog.initOwner(getDialogPane().getScene().getWindow()); Optional> optWords = seedEntryDialog.showAndWait(); if(optWords.isPresent()) { List mnemonicWords = optWords.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java index 6e1c1418..b6e90bfa 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystoreImportPane.java @@ -254,6 +254,7 @@ public class MnemonicKeystoreImportPane extends MnemonicKeystorePane { if(!dryrun) { if(passphraseProperty.get() != null && !passphraseProperty.get().isEmpty()) { KeystorePassphraseDialog keystorePassphraseDialog = new KeystorePassphraseDialog(null, keystore, true); + keystorePassphraseDialog.initOwner(this.getScene().getWindow()); Optional optPassphrase = keystorePassphraseDialog.showAndWait(); if(optPassphrase.isEmpty() || !optPassphrase.get().equals(passphraseProperty.get())) { throw new ImportException("Re-entered passphrase did not match"); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystorePane.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystorePane.java index 7bfea182..016a8f88 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystorePane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicKeystorePane.java @@ -97,6 +97,7 @@ public class MnemonicKeystorePane extends TitledDescriptionPane { protected void showGrid() { MnemonicGridDialog mnemonicGridDialog = new MnemonicGridDialog(); + mnemonicGridDialog.initOwner(this.getScene().getWindow()); Optional> optWords = mnemonicGridDialog.showAndWait(); if(optWords.isPresent()) { List words = optWords.get(); @@ -134,6 +135,7 @@ public class MnemonicKeystorePane extends TitledDescriptionPane { protected void scanQR() { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(this.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/PayNymCell.java b/src/main/java/com/sparrowwallet/sparrow/control/PayNymCell.java index de1f1329..7a81daab 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/PayNymCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/PayNymCell.java @@ -110,6 +110,7 @@ public class PayNymCell extends ListCell { MenuItem rename = new MenuItem("Rename Contact..."); rename.setOnAction(event -> { WalletLabelDialog walletLabelDialog = new WalletLabelDialog(payNym.nymName(), "Contact"); + walletLabelDialog.initOwner(PayNymCell.this.getScene().getWindow()); Optional optLabel = walletLabelDialog.showAndWait(); if(optLabel.isPresent()) { int index = getListView().getItems().indexOf(payNym); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java index 0f4b6e29..519560bd 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/PrivateKeySweepDialog.java @@ -224,6 +224,7 @@ public class PrivateKeySweepDialog extends Dialog { private void decryptKey() { PassphraseDialog passphraseDialog = new PassphraseDialog(); + passphraseDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optPassphrase = passphraseDialog.showAndWait(); if(optPassphrase.isPresent()) { try { @@ -265,6 +266,7 @@ public class PrivateKeySweepDialog extends Dialog { private void scanPrivateKey() { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(getDialogPane().getScene().getWindow()); Optional result = qrScanDialog.showAndWait(); if(result.isPresent() && result.get().payload != null) { key.setText(result.get().payload); @@ -294,6 +296,7 @@ public class PrivateKeySweepDialog extends Dialog { private void unsealPrivateKey() { DeviceUnsealDialog deviceUnsealDialog = new DeviceUnsealDialog(Collections.emptyList()); + deviceUnsealDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optPrivateKey = deviceUnsealDialog.showAndWait(); if(optPrivateKey.isPresent()) { DeviceUnsealDialog.DevicePrivateKey devicePrivateKey = optPrivateKey.get(); @@ -312,6 +315,7 @@ public class PrivateKeySweepDialog extends Dialog { Date since = null; if(Config.get().getServerType() == ServerType.BITCOIN_CORE) { WalletBirthDateDialog addressScanDateDialog = new WalletBirthDateDialog(null, true); + addressScanDateDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optSince = addressScanDateDialog.showAndWait(); if(optSince.isPresent()) { since = optSince.get(); @@ -330,6 +334,7 @@ public class PrivateKeySweepDialog extends Dialog { if(Config.get().getServerType() == ServerType.BITCOIN_CORE) { ServiceProgressDialog serviceProgressDialog = new ServiceProgressDialog("Address Scan", "Scanning address for transactions...", "/image/sparrow.png", addressUtxosService); + serviceProgressDialog.initOwner(getDialogPane().getScene().getWindow()); AppServices.moveToActiveWindowScreen(serviceProgressDialog); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java index b410f178..b5342f78 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java @@ -109,6 +109,7 @@ public class TextAreaDialog extends Dialog { ButtonBar.setButtonData(scanButton, buttonData); scanButton.setOnAction(event -> { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(getDialogPane().getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java index 3a125db8..2c6035f6 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java @@ -1301,7 +1301,7 @@ public class TransactionDiagram extends GridPane { } } - private static class LabelContextMenu extends ContextMenu { + private class LabelContextMenu extends ContextMenu { public LabelContextMenu(Address address, long value) { if(address != null) { MenuItem copyAddress = new MenuItem("Copy Address"); @@ -1317,6 +1317,7 @@ public class TransactionDiagram extends GridPane { showAddress.setOnAction(event -> { hide(); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(address.toString()); + qrDisplayDialog.initOwner(TransactionDiagram.this.getScene().getWindow()); qrDisplayDialog.showAndWait(); }); getItems().add(showAddress); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index 505acd59..2bc9c015 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -8,7 +8,6 @@ import com.sparrowwallet.drongo.wallet.StandardAccount; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.SparrowWallet; -import com.sparrowwallet.sparrow.control.WalletPasswordDialog; import com.sparrowwallet.sparrow.soroban.Soroban; import com.sparrowwallet.sparrow.whirlpool.Whirlpool; import javafx.concurrent.ScheduledService; diff --git a/src/main/java/com/sparrowwallet/sparrow/paynym/PayNymController.java b/src/main/java/com/sparrowwallet/sparrow/paynym/PayNymController.java index 6dbd9cd8..ee9ba771 100644 --- a/src/main/java/com/sparrowwallet/sparrow/paynym/PayNymController.java +++ b/src/main/java/com/sparrowwallet/sparrow/paynym/PayNymController.java @@ -243,11 +243,13 @@ public class PayNymController { public void showQR(ActionEvent event) { QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(getMasterWallet().getPaymentCode().toString()); + qrDisplayDialog.initOwner(payNymName.getScene().getWindow()); qrDisplayDialog.showAndWait(); } public void scanQR(ActionEvent event) { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(payNymName.getScene().getWindow()); Optional optResult = qrScanDialog.showAndWait(); if(optResult.isPresent()) { QRScanDialog.Result result = optResult.get(); @@ -373,6 +375,7 @@ public class PayNymController { Optional optButtonType = AppServices.showAlertDialog("Link contacts?", "Some contacts were found that may be already linked. Link these contacts? Your password is required to check.", Alert.AlertType.CONFIRMATION, ButtonType.NO, ButtonType.YES); if(optButtonType.isPresent() && optButtonType.get() == ButtonType.YES) { WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(payNymName.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(wallet.copy(), password.get()); @@ -495,6 +498,7 @@ public class PayNymController { Storage storage = AppServices.get().getOpenWallets().get(wallet); if(wallet.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(payNymName.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(wallet.copy(), password.get()); diff --git a/src/main/java/com/sparrowwallet/sparrow/preferences/GeneralPreferencesController.java b/src/main/java/com/sparrowwallet/sparrow/preferences/GeneralPreferencesController.java index 5fb0a750..df6fee28 100644 --- a/src/main/java/com/sparrowwallet/sparrow/preferences/GeneralPreferencesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/preferences/GeneralPreferencesController.java @@ -118,6 +118,7 @@ public class GeneralPreferencesController extends PreferencesDetailController { if(newValue != null) { if(newValue == CUSTOM_BLOCK_EXPLORER) { TextfieldDialog textfieldDialog = new TextfieldDialog(); + textfieldDialog.initOwner(blockExplorers.getScene().getWindow()); textfieldDialog.setTitle("Enter Block Explorer URL"); textfieldDialog.setHeaderText("Enter the URL of the block explorer.\n\nIf present, the characters {0} will be replaced with the txid.\nFor example, https://localhost or https://localhost/tx/{0}\n"); textfieldDialog.getEditor().setPromptText("https://localhost"); diff --git a/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java b/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java index f20a58b2..af5a5655 100644 --- a/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/preferences/ServerPreferencesController.java @@ -282,6 +282,7 @@ public class ServerPreferencesController extends PreferencesDetailController { if(newValue != null) { if(newValue == MANAGE_ALIASES_SERVER) { ServerAliasDialog serverAliasDialog = new ServerAliasDialog(ServerType.BITCOIN_CORE); + serverAliasDialog.initOwner(recentCoreServers.getScene().getWindow()); Optional optServer = serverAliasDialog.showAndWait(); recentCoreServers.setItems(getObservableServerList(Config.get().getRecentCoreServers())); Server selectedServer = optServer.orElseGet(() -> Config.get().getCoreServer()); @@ -306,6 +307,7 @@ public class ServerPreferencesController extends PreferencesDetailController { if(newValue != null) { if(newValue == MANAGE_ALIASES_SERVER) { ServerAliasDialog serverAliasDialog = new ServerAliasDialog(ServerType.ELECTRUM_SERVER); + serverAliasDialog.initOwner(recentElectrumServers.getScene().getWindow()); Optional optServer = serverAliasDialog.showAndWait(); recentElectrumServers.setItems(getObservableServerList(Config.get().getRecentElectrumServers())); Server selectedServer = optServer.orElseGet(() -> Config.get().getElectrumServer()); diff --git a/src/main/java/com/sparrowwallet/sparrow/soroban/CounterpartyController.java b/src/main/java/com/sparrowwallet/sparrow/soroban/CounterpartyController.java index e653fd7a..2edbefe6 100644 --- a/src/main/java/com/sparrowwallet/sparrow/soroban/CounterpartyController.java +++ b/src/main/java/com/sparrowwallet/sparrow/soroban/CounterpartyController.java @@ -409,12 +409,14 @@ public class CounterpartyController extends SorobanController { public void showPayNym(ActionEvent event) { PayNymDialog payNymDialog = new PayNymDialog(walletId); + payNymDialog.initOwner(payNym.getScene().getWindow()); payNymDialog.showAndWait(); } public void showPayNymQR(ActionEvent event) { Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet(); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(masterWallet.getPaymentCode().toString()); + qrDisplayDialog.initOwner(payNym.getScene().getWindow()); qrDisplayDialog.showAndWait(); } diff --git a/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorController.java b/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorController.java index b384f153..0df13cda 100644 --- a/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorController.java +++ b/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorController.java @@ -363,6 +363,7 @@ public class InitiatorController extends SorobanController { if(wallet.isEncrypted()) { Wallet copy = wallet.copy(); WalletPasswordDialog dlg = new WalletPasswordDialog(copy.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(payNymFollowers.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage storage = AppServices.get().getOpenWallets().get(wallet); @@ -649,6 +650,7 @@ public class InitiatorController extends SorobanController { public void findPayNym(ActionEvent event) { PayNymDialog payNymDialog = new PayNymDialog(walletId, PayNymDialog.Operation.SELECT, false); + payNymDialog.initOwner(payNymFollowers.getScene().getWindow()); Optional optPayNym = payNymDialog.showAndWait(); optPayNym.ifPresent(payNym -> { counterpartyPayNymName.set(payNym.nymName()); diff --git a/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorDialog.java b/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorDialog.java index bfdaa10a..e9b0896e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/soroban/InitiatorDialog.java @@ -137,6 +137,7 @@ public class InitiatorDialog extends Dialog { private void acceptAndBroadcast(InitiatorController initiatorController, String walletId, Wallet wallet) { if(confirmationRequired && wallet.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(getDialogPane().getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage storage = AppServices.get().getOpenWallets().get(wallet); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index c5b98b8f..9a52641b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -875,6 +875,7 @@ public class HeadersController extends TransactionFormController implements Init boolean includeNonWitnessUtxos = !Arrays.asList(ScriptType.WITNESS_TYPES).contains(headersForm.getSigningWallet().getScriptType()); CryptoPSBT cryptoPSBT = new CryptoPSBT(headersForm.getPsbt().serialize(true, includeNonWitnessUtxos)); QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(cryptoPSBT.toUR(), addLegacyEncodingOption, true); + qrDisplayDialog.initOwner(toggleButton.getScene().getWindow()); Optional optButtonType = qrDisplayDialog.showAndWait(); if(optButtonType.isPresent() && optButtonType.get().getButtonData() == ButtonBar.ButtonData.NEXT_FORWARD) { scanPSBT(event); @@ -886,6 +887,7 @@ public class HeadersController extends TransactionFormController implements Init toggleButton.setSelected(false); QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(toggleButton.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); @@ -985,6 +987,7 @@ public class HeadersController extends TransactionFormController implements Init if(copy.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(copy.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(signButton.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(copy, password.get()); @@ -1029,6 +1032,7 @@ public class HeadersController extends TransactionFormController implements Init } DeviceSignDialog dlg = new DeviceSignDialog(headersForm.getSigningWallet(), fingerprints, headersForm.getPsbt()); + dlg.initOwner(signButton.getScene().getWindow()); dlg.initModality(Modality.NONE); Stage stage = (Stage)dlg.getDialogPane().getScene().getWindow(); stage.setAlwaysOnTop(true); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java index 8f1df168..6758a601 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java @@ -176,6 +176,7 @@ public class AddressesController extends WalletFormController implements Initial public void showPayNymAddresses(ActionEvent event) { PayNymAddressesDialog payNymAddressesDialog = new PayNymAddressesDialog(getWalletForm()); + payNymAddressesDialog.initOwner(showPayNymAddresses.getScene().getWindow()); payNymAddressesDialog.showAndWait(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java index eea9a126..d6d7fe10 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java @@ -366,6 +366,7 @@ public class KeystoreController extends WalletFormController implements Initiali KeyDerivation requiredDerivation = restrictSource ? keystore.getKeyDerivation() : null; WalletModel requiredModel = restrictSource ? keystore.getWalletModel() : null; KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet(), initialSource, requiredDerivation, requiredModel, restrictSource); + dlg.initOwner(selectSourcePane.getScene().getWindow()); Optional result = dlg.showAndWait(); if(result.isPresent()) { selectSourcePane.setVisible(false); @@ -405,6 +406,7 @@ public class KeystoreController extends WalletFormController implements Initiali public void export(ActionEvent event) { KeystoreExportDialog keystoreExportDialog = new KeystoreExportDialog(keystore); + keystoreExportDialog.initOwner(exportButton.getScene().getWindow()); keystoreExportDialog.showAndWait(); } @@ -414,6 +416,7 @@ public class KeystoreController extends WalletFormController implements Initiali if(copy.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(copy.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(viewSeedButton.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(copy, password.get()); @@ -437,9 +440,11 @@ public class KeystoreController extends WalletFormController implements Initiali private void showPrivate(Keystore keystore) { if(keystore.hasSeed()) { SeedDisplayDialog dlg = new SeedDisplayDialog(keystore); + dlg.initOwner(viewSeedButton.getScene().getWindow()); dlg.showAndWait(); } else if(keystore.hasMasterPrivateExtendedKey()) { MasterKeyDisplayDialog dlg = new MasterKeyDisplayDialog(keystore); + dlg.initOwner(viewKeyButton.getScene().getWindow()); dlg.showAndWait(); } } @@ -461,6 +466,7 @@ public class KeystoreController extends WalletFormController implements Initiali } CardPinDialog cardPinDialog = new CardPinDialog(backupOnly); + cardPinDialog.initOwner(cardServiceButtons.getScene().getWindow()); Optional optPinChange = cardPinDialog.showAndWait(); if(optPinChange.isPresent()) { String currentPin = optPinChange.get().currentPin(); @@ -484,6 +490,7 @@ public class KeystoreController extends WalletFormController implements Initiali AppServices.showErrorDialog("Error communicating with card", e.getMessage()); }); ServiceProgressDialog serviceProgressDialog = new ServiceProgressDialog("Authentication Delay", "Waiting for authentication delay to clear...", "/image/tapsigner.png", authDelayService); + serviceProgressDialog.initOwner(cardServiceButtons.getScene().getWindow()); AppServices.moveToActiveWindowScreen(serviceProgressDialog); authDelayService.start(); } else { @@ -504,6 +511,7 @@ public class KeystoreController extends WalletFormController implements Initiali String backup = backupService.getValue(); String filename = fingerprint.getText() + ".aes"; TextAreaDialog backupDialog = new TextAreaDialog(backup, false, filename, Base64.getDecoder().decode(backup)); + backupDialog.initOwner(cardServiceButtons.getScene().getWindow()); backupDialog.setTitle("Backup Private Key"); backupDialog.getDialogPane().setHeaderText((requiresBackup && !backupOnly ? "Please backup first by saving" : "Save") + " the following text in a safe place. It contains an encrypted copy of the card's private key, and can be decrypted using the backup key written on the back of the card."); backupDialog.showAndWait(); @@ -537,6 +545,7 @@ public class KeystoreController extends WalletFormController implements Initiali public void scanXpubQR(ActionEvent event) { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(scanXpubQR.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); @@ -603,6 +612,7 @@ public class KeystoreController extends WalletFormController implements Initiali public void displayXpubQR(ActionEvent event) { QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(xpub.getText()); + qrDisplayDialog.initOwner(xpub.getScene().getWindow()); qrDisplayDialog.showAndWait(); } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java index fe68af33..8b225779 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/PaymentController.java @@ -168,10 +168,12 @@ public class PaymentController extends WalletFormController implements Initializ if(newValue == payNymWallet) { boolean selectLinkedOnly = sendController.getPaymentTabs().getTabs().size() > 1 || !SorobanServices.canWalletMix(sendController.getWalletForm().getWallet()); PayNymDialog payNymDialog = new PayNymDialog(sendController.getWalletForm().getWalletId(), PayNymDialog.Operation.SEND, selectLinkedOnly); + payNymDialog.initOwner(scanQrButton.getScene().getWindow()); Optional optPayNym = payNymDialog.showAndWait(); optPayNym.ifPresent(this::setPayNym); } else if(newValue == nfcCardWallet) { DeviceGetAddressDialog deviceGetAddressDialog = new DeviceGetAddressDialog(Collections.emptyList()); + deviceGetAddressDialog.initOwner(scanQrButton.getScene().getWindow()); Optional
optAddress = deviceGetAddressDialog.showAndWait(); if(optAddress.isPresent()) { address.setText(optAddress.get().toString()); @@ -626,6 +628,7 @@ public class PaymentController extends WalletFormController implements Initializ public void scanQrAddress(ActionEvent event) { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(scanQrButton.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java index 72c0a148..9ec8e452 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java @@ -85,6 +85,7 @@ public class ReceiveController extends WalletFormController implements Initializ qrCode.setOnMouseClicked(event -> { if(currentEntry != null) { QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(currentEntry.getAddress().toString()); + qrDisplayDialog.initOwner(address.getScene().getWindow()); qrDisplayDialog.showAndWait(); } }); @@ -220,6 +221,7 @@ public class ReceiveController extends WalletFormController implements Initializ if(possibleDevices != null && !possibleDevices.isEmpty()) { if(possibleDevices.size() > 1 || possibleDevices.get(0).isNeedsPinSent() || possibleDevices.get(0).isNeedsPassphraseSent()) { DeviceDisplayAddressDialog dlg = new DeviceDisplayAddressDialog(wallet, addressDescriptor); + dlg.initOwner(displayAddress.getScene().getWindow()); dlg.showAndWait(); } else { Device actualDevice = possibleDevices.get(0); @@ -227,6 +229,7 @@ public class ReceiveController extends WalletFormController implements Initializ displayAddressService.setOnFailed(failedEvent -> { Platform.runLater(() -> { DeviceDisplayAddressDialog dlg = new DeviceDisplayAddressDialog(wallet, addressDescriptor); + dlg.initOwner(displayAddress.getScene().getWindow()); dlg.showAndWait(); }); }); @@ -234,6 +237,7 @@ public class ReceiveController extends WalletFormController implements Initializ } } else { DeviceDisplayAddressDialog dlg = new DeviceDisplayAddressDialog(wallet, addressDescriptor); + dlg.initOwner(displayAddress.getScene().getWindow()); dlg.showAndWait(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java index eed3fb3e..82ea5ee4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java @@ -1268,6 +1268,7 @@ public class SendController extends WalletFormController implements Initializabl AppServices.showErrorDialog("Error broadcasting premix transaction", exception.getMessage()); }); ServiceProgressDialog progressDialog = new ServiceProgressDialog("Whirlpool", "Broadcast Premix Transaction", "/image/whirlpool.png", tx0BroadcastService); + progressDialog.initOwner(premixButton.getScene().getWindow()); AppServices.moveToActiveWindowScreen(progressDialog); tx0BroadcastService.start(); } @@ -1277,6 +1278,7 @@ public class SendController extends WalletFormController implements Initializabl Storage storage = AppServices.get().getOpenWallets().get(wallet); if(wallet.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(paymentTabs.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.DecryptWalletService decryptWalletService = new Storage.DecryptWalletService(wallet.copy(), password.get()); @@ -1373,6 +1375,7 @@ public class SendController extends WalletFormController implements Initializabl AppServices.showErrorDialog("Error broadcasting notification transaction", failedEvent.getSource().getException().getMessage()); }); ServiceProgressDialog progressDialog = new ServiceProgressDialog("Broadcast", "Broadcast Notification Transaction", "/image/paynym.png", proxyWorker); + progressDialog.initOwner(notificationButton.getScene().getWindow()); AppServices.moveToActiveWindowScreen(progressDialog); proxyWorker.setMessage("Broadcasting notification transaction..."); proxyWorker.start(); @@ -1693,6 +1696,7 @@ public class SendController extends WalletFormController implements Initializabl Platform.runLater(() -> { InitiatorDialog initiatorDialog = new InitiatorDialog(getWalletForm().getWalletId(), getWalletForm().getWallet(), walletTransactionProperty.get()); + initiatorDialog.initOwner(paymentTabs.getScene().getWindow()); if(Config.get().isSameAppMixing()) { initiatorDialog.initModality(Modality.NONE); } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index d5aa1526..b8173d6d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -257,6 +257,7 @@ public class SettingsController extends WalletFormController implements Initiali String outputDescriptor = OutputDescriptor.getOutputDescriptor(wallet, KeyPurpose.DEFAULT_PURPOSES, null).toString(true); CryptoOutput cryptoOutput = getCryptoOutput(wallet); MultisigBackupDialog dialog = new MultisigBackupDialog(wallet, outputDescriptor, cryptoOutput.toUR()); + dialog.initOwner(apply.getScene().getWindow()); dialog.showAndWait(); } }); @@ -337,6 +338,7 @@ public class SettingsController extends WalletFormController implements Initiali public void scanDescriptorQR(ActionEvent event) { QRScanDialog qrScanDialog = new QRScanDialog(); + qrScanDialog.initOwner(scanDescriptorQR.getScene().getWindow()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); @@ -374,6 +376,7 @@ public class SettingsController extends WalletFormController implements Initiali UR cryptoOutputUR = cryptoOutput.toUR(); QRDisplayDialog qrDisplayDialog = new DescriptorQRDisplayDialog(walletForm.getWallet().getFullDisplayName(), outputDescriptor.toString(true), cryptoOutputUR); + qrDisplayDialog.initOwner(showDescriptorQR.getScene().getWindow()); qrDisplayDialog.showAndWait(); } @@ -433,6 +436,7 @@ public class SettingsController extends WalletFormController implements Initiali String outputDescriptorString = outputDescriptor.toString(walletForm.getWallet().isValid()); TextAreaDialog dialog = new TextAreaDialog(outputDescriptorString); + dialog.initOwner(editDescriptor.getScene().getWindow()); dialog.setTitle("Edit wallet output descriptor"); dialog.getDialogPane().setHeaderText("The wallet configuration is specified in the output descriptor.\nChanges to the output descriptor will modify the wallet configuration." + (walletForm.getWallet().getPolicyType() == PolicyType.MULTI ? "\nKey expressions are shown in canonical order." : "")); @@ -477,6 +481,7 @@ public class SettingsController extends WalletFormController implements Initiali String outputDescriptorString = outputDescriptor.toString(walletForm.getWallet().isValid()); TextAreaDialog dialog = new TextAreaDialog(outputDescriptorString, false); + dialog.initOwner(showDescriptor.getScene().getWindow()); dialog.setTitle("Show wallet output descriptor"); dialog.getDialogPane().setHeaderText("The wallet configuration is specified in the output descriptor.\nThis wallet is no longer editable - create a new wallet to change the descriptor." + (walletForm.getWallet().getPolicyType() == PolicyType.MULTI ? "\nKey expressions are shown in canonical order." : "")); @@ -485,6 +490,7 @@ public class SettingsController extends WalletFormController implements Initiali public void showAdvanced(ActionEvent event) { AdvancedDialog advancedDialog = new AdvancedDialog(walletForm); + advancedDialog.initOwner(apply.getScene().getWindow()); Optional optApply = advancedDialog.showAndWait(); if(optApply.isPresent() && optApply.get() && walletForm.getWallet().isValid()) { revert.setDisable(true); @@ -503,6 +509,7 @@ public class SettingsController extends WalletFormController implements Initiali && entry.getKey().getName().equals(walletForm.getWallet().getName())).map(Map.Entry::getKey).findFirst(); if(optWallet.isPresent()) { WalletExportDialog dlg = new WalletExportDialog(optWallet.get()); + dlg.initOwner(export.getScene().getWindow()); dlg.showAndWait(); } else { AppServices.showErrorDialog("Cannot export wallet", "Wallet cannot be exported, please save it first."); @@ -514,6 +521,7 @@ public class SettingsController extends WalletFormController implements Initiali Wallet masterWallet = openWallet.isMasterWallet() ? openWallet : openWallet.getMasterWallet(); AddAccountDialog addAccountDialog = new AddAccountDialog(masterWallet); + addAccountDialog.initOwner(addAccount.getScene().getWindow()); Optional> optAccounts = addAccountDialog.showAndWait(); if(optAccounts.isPresent()) { List standardAccounts = optAccounts.get(); @@ -530,6 +538,7 @@ public class SettingsController extends WalletFormController implements Initiali if(masterWallet.isEncrypted()) { String walletId = walletForm.getWalletId(); WalletPasswordDialog dlg = new WalletPasswordDialog(masterWallet.getName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(addAccount.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(walletForm.getStorage(), password.get(), true); @@ -604,6 +613,7 @@ public class SettingsController extends WalletFormController implements Initiali if(discoverAccounts && masterWallet.getKeystores().size() == 1 && masterWallet.getKeystores().stream().allMatch(ks -> ks.getSource() == KeystoreSource.HW_USB)) { String fingerprint = masterWallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint(); DeviceKeystoreDiscoverDialog deviceKeystoreDiscoverDialog = new DeviceKeystoreDiscoverDialog(List.of(fingerprint), masterWallet, standardAccounts); + deviceKeystoreDiscoverDialog.initOwner(addAccount.getScene().getWindow()); Optional> optDiscoveredKeystores = deviceKeystoreDiscoverDialog.showAndWait(); if(optDiscoveredKeystores.isPresent()) { Map discoveredKeystores = optDiscoveredKeystores.get(); @@ -815,6 +825,7 @@ public class SettingsController extends WalletFormController implements Initiali } WalletPasswordDialog dlg = new WalletPasswordDialog(null, requirement, suggestChangePassword); + dlg.initOwner(apply.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { if(dlg.isBackupExisting()) { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index 109ae174..532c822b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -280,6 +280,7 @@ public class UtxosController extends WalletFormController implements Initializab public void mixSelected(ActionEvent event) { List selectedEntries = getSelectedUtxos(); WhirlpoolDialog whirlpoolDialog = new WhirlpoolDialog(getWalletForm().getMasterWalletId(), getWalletForm().getWallet(), selectedEntries); + whirlpoolDialog.initOwner(utxosTable.getScene().getWindow()); Optional optTx0Preview = whirlpoolDialog.showAndWait(); optTx0Preview.ifPresent(tx0Preview -> previewPremix(tx0Preview, selectedEntries)); } @@ -290,6 +291,7 @@ public class UtxosController extends WalletFormController implements Initializab if(wallet.isMasterWallet() && !wallet.isWhirlpoolMasterWallet() && wallet.isEncrypted()) { WalletPasswordDialog dlg = new WalletPasswordDialog(wallet.getMasterName(), WalletPasswordDialog.PasswordRequirement.LOAD); + dlg.initOwner(utxosTable.getScene().getWindow()); Optional password = dlg.showAndWait(); if(password.isPresent()) { Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(walletForm.getStorage(), password.get(), true); @@ -428,6 +430,7 @@ public class UtxosController extends WalletFormController implements Initializab public void showMixToDialog(ActionEvent event) { MixToDialog mixToDialog = new MixToDialog(getWalletForm().getWallet()); + mixToDialog.initOwner(mixTo.getScene().getWindow()); Optional optMixConfig = mixToDialog.showAndWait(); if(optMixConfig.isPresent()) { MixConfig changedMixConfig = optMixConfig.get();