Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,10 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)

GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
connect(wallet_controller, &WalletController::destroyed, this, [this] {
// wallet_controller gets destroyed manually, but it leaves our member copy dangling
m_wallet_controller = nullptr;
});

auto activity = new LoadWalletsActivity(m_wallet_controller, this);
activity->load();
Expand All @@ -692,7 +696,7 @@ WalletController* BitcoinGUI::getWalletController()

void BitcoinGUI::addWallet(WalletModel* walletModel)
{
if (!walletFrame) return;
if (!walletFrame || !m_wallet_controller) return;

WalletView* wallet_view = new WalletView(walletModel, platformStyle, walletFrame);
if (!walletFrame->addView(wallet_view)) return;
Expand Down Expand Up @@ -742,7 +746,7 @@ void BitcoinGUI::removeWallet(WalletModel* walletModel)

void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
{
if (!walletFrame) return;
if (!walletFrame || !m_wallet_controller) return;
walletFrame->setCurrentWallet(wallet_model);
for (int index = 0; index < m_wallet_selector->count(); ++index) {
if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
Expand Down
13 changes: 9 additions & 4 deletions src/qt/sendcoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,10 +600,15 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
entry->clear();
entry->setFocus();
ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
qApp->processEvents();
QScrollBar* bar = ui->scrollArea->verticalScrollBar();
if(bar)
bar->setSliderPosition(bar->maximum());

// Scroll to the newly added entry on a QueuedConnection because Qt doesn't
// adjust the scroll area and scrollbar immediately when the widget is added.
// Invoking on a DirectConnection will only scroll to the second-to-last entry.
QMetaObject::invokeMethod(ui->scrollArea, [this] {
if (ui->scrollArea->verticalScrollBar()) {
ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
}
}, Qt::QueuedConnection);
Comment on lines +607 to +611
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is most likely because we are creating the widget in a separate thread.

Try this:

diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
--- a/src/qt/sendcoinsdialog.cpp	(revision 114d738830368dc155f27a72128adf91b4fffd37)
+++ b/src/qt/sendcoinsdialog.cpp	(date 1672923728012)
@@ -600,11 +600,9 @@
     entry->clear();
     entry->setFocus();
     ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
-    QMetaObject::invokeMethod(ui->scrollArea, [this] {
-        if (ui->scrollArea->verticalScrollBar()) {
-            ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
-        }
-    }, Qt::QueuedConnection);
+    if (ui->scrollArea->verticalScrollBar()) {
+        ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
+    }
 
     updateTabsAndLabels();
     return entry;
@@ -697,6 +695,13 @@
     return true;
 }
 
+void SendCoinsDialog::showEvent(QShowEvent* event)
+{
+    if (ui->scrollArea->verticalScrollBar()) {
+        ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
+    }
+}
+
 void SendCoinsDialog::setBalance(const interfaces::WalletBalances& balances)
 {
     if(model && model->getOptionsModel())
Index: src/qt/sendcoinsdialog.h
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
--- a/src/qt/sendcoinsdialog.h	(revision 114d738830368dc155f27a72128adf91b4fffd37)
+++ b/src/qt/sendcoinsdialog.h	(date 1672923728023)
@@ -49,6 +49,8 @@
     void pasteEntry(const SendCoinsRecipient &rv);
     bool handlePaymentRequest(const SendCoinsRecipient &recipient);
 
+    void showEvent(QShowEvent* event) override;
+
 public Q_SLOTS:
     void clear();
     void reject() override;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion!

While this (also) fixes the first segfault, it doesn't achieve the intended scrolling behavior (at least on my macOS setup).

Before clicking 'Add Recipient':

image

After:

image

Whereas the original workaround (and my workaround of the workaround) gives this "After":

image

It seems to be a fairly common issue without an ideal solution. There are more involved solutions, like subscribing to rangeChanged signals, but those would require much more logic (eg - ignore those when manually resizing the viewport, etc.).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm true, ok. Sounds good to go with the simplest fix here.
Would be good to add a comment above so we don't forget the rationale behind it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Adding.


updateTabsAndLabels();
return entry;
Expand Down
2 changes: 2 additions & 0 deletions src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ void TestGUI(interfaces::Node& node)
QCOMPARE(transactionTableModel->rowCount({}), 105);
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
// Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
qApp->processEvents();
QCOMPARE(transactionTableModel->rowCount({}), 107);
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
Expand Down