diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp index f1b26da9d..308ecf017 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp @@ -141,6 +141,7 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget * connect(client, &AbstractClient::gameJoinedEventReceived, this, &TabSupervisor::gameJoined); connect(client, &AbstractClient::userMessageEventReceived, this, &TabSupervisor::processUserMessageEvent); connect(client, &AbstractClient::maxPingTime, this, &TabSupervisor::updatePingTime); + connect(client, &AbstractClient::pingStatsUpdated, this, &TabSupervisor::updateLatencyTooltip); connect(client, &AbstractClient::notifyUserEventReceived, this, &TabSupervisor::processNotifyUserEvent); // create tabs menu actions @@ -883,6 +884,23 @@ void TabSupervisor::updatePingTime(int value, int max) setTabIcon(indexOf(tabServer), QIcon(PingPixmapGenerator::generatePixmap(15, value, max))); } +void TabSupervisor::updateLatencyTooltip(int lastMs, int medianMs, int p95Ms, int maxMs, int sampleCount) +{ + if (!tabServer) { + return; + } + + if (sampleCount == 0) { + setTabToolTip(indexOf(tabServer), QString()); + return; + } + + setTabToolTip(indexOf(tabServer), tr("Connection quality over the last %n sample(s):", "", sampleCount) + "\n" + + tr("Last: %1 ms").arg(lastMs) + "\n" + tr("Median: %1 ms").arg(medianMs) + + "\n" + tr("95th percentile: %1 ms").arg(p95Ms) + "\n" + + tr("Maximum: %1 ms").arg(maxMs)); +} + void TabSupervisor::gameJoined(const Event_GameJoined &event) { QMap roomGameTypes; diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h index 32ed14504..bf8210734 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h @@ -220,6 +220,7 @@ private slots: void updateCurrent(int index); void updatePingTime(int value, int max); + void updateLatencyTooltip(int lastMs, int medianMs, int p95Ms, int maxMs, int sampleCount); void gameJoined(const Event_GameJoined &event); void localGameJoined(const Event_GameJoined &event); void gameLeft(TabGame *tab); diff --git a/cockatrice/src/interface/window_main.cpp b/cockatrice/src/interface/window_main.cpp index 199a2d952..45c7c0429 100644 --- a/cockatrice/src/interface/window_main.cpp +++ b/cockatrice/src/interface/window_main.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +145,23 @@ void MainWindow::statusChanged(ClientStatus _status) } } +void MainWindow::updatePingDisplay(int lastMs, int medianMs, int p95Ms, int maxMs, int sampleCount) +{ + if (!pingLabel || sampleCount == 0) { + if (pingLabel) { + pingLabel->hide(); + } + return; + } + + pingLabel->setText(tr("Ping: %1 ms").arg(lastMs)); + pingLabel->setToolTip(tr("Connection quality over the last %n sample(s):", "", sampleCount) + "\n" + + tr("Last: %1 ms").arg(lastMs) + "\n" + tr("Median: %1 ms").arg(medianMs) + "\n" + + tr("95th percentile: %1 ms").arg(p95Ms) + "\n" + tr("Maximum: %1 ms").arg(maxMs)); + pingLabel->setAccessibleDescription(pingLabel->toolTip()); + pingLabel->show(); +} + // Actions void MainWindow::actConnect() @@ -535,6 +553,12 @@ MainWindow::MainWindow(QWidget *parent) [this](bool show) { statusBar()->setVisible(show); }); statusBar()->setVisible(SettingsCache::instance().userInterface().getShowStatusBar()); + pingLabel = new QLabel(this); + pingLabel->setAccessibleName(tr("Ping")); + pingLabel->hide(); + statusBar()->addPermanentWidget(pingLabel); + connect(connectionController, &ConnectionController::pingStatsUpdated, this, &MainWindow::updatePingDisplay); + connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, &MainWindow::refreshShortcuts); refreshShortcuts(); diff --git a/cockatrice/src/interface/window_main.h b/cockatrice/src/interface/window_main.h index 3c0cc6302..42913ec27 100644 --- a/cockatrice/src/interface/window_main.h +++ b/cockatrice/src/interface/window_main.h @@ -50,6 +50,7 @@ class GameReplay; class HandlePublicServers; class LocalClient; class LocalServer; +class QLabel; class QThread; class RemoteClient; class ServerInfo_User; @@ -72,6 +73,7 @@ public slots: private slots: void updateTabMenu(const QList &newMenuList); void statusChanged(ClientStatus _status); + void updatePingDisplay(int lastMs, int medianMs, int p95Ms, int maxMs, int sampleCount); void localGameEnded(); void pixmapCacheSizeChanged(int newSizeInMBs); void actDisconnect(); @@ -146,6 +148,7 @@ private: WndSets *wndSets; ConnectionController *connectionController; LocalServer *localServer; + QLabel *pingLabel = nullptr; ///< status bar label with live round-trip stats LagMonitor lagMonitor; ///< watches the main thread for event loop stalls bool bHasActivated, askedForDbUpdater; QProcess *cardUpdateProcess;