Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package tail-tray for openSUSE:Factory checked in at 2026-04-21 12:43:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tail-tray (Old) and /work/SRC/openSUSE:Factory/.tail-tray.new.11940 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tail-tray" Tue Apr 21 12:43:34 2026 rev:24 rq:1348284 version:0.2.31 Changes: -------- --- /work/SRC/openSUSE:Factory/tail-tray/tail-tray.changes 2026-03-05 17:30:57.845980223 +0100 +++ /work/SRC/openSUSE:Factory/.tail-tray.new.11940/tail-tray.changes 2026-04-21 12:44:05.168596361 +0200 @@ -1,0 +2,28 @@ +Mon Apr 20 17:22:34 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 0.2.31: + * This release fixes a handful of bugs and annoyances with a + bigger focus on account related actions and interactions. + - You will no longer be spammed with device removal + notifications when switching between accounts. + - You can how switch account from both the main settings UI and + from the tray menu. + - Logging out now does the correct thing and removes the + account completely from the UI without requiring a restart. + - Fix settings read/write bug around AllowLanAccess + * Commits + - a488f60: When switching accounts, you get spammed with + notifications about devices being removed, in error #113 + (Marcus Grenängen) + - 9dbd282: Preferences - Account tab should expose a switch + account button #114 (Marcus Grenängen) + - 2b7a682: Preferences - Account tab should expose a switch + account button #114 (Marcus Grenängen) + - 1bc4b1b: Accounts - Properly handle Logout flow & try to load + and assign the profile image if present (Marcus Grenängen) + - 6481e06: Fix checkboxes for AllowLanAccess - Issue #105 + (Marcus Grenängen) + - 47cf078: Bump version to 0.2.31 readying a new release + (Marcus Grenängen) + +------------------------------------------------------------------- Old: ---- tail-tray-0.2.30.obscpio New: ---- tail-tray-0.2.31.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tail-tray.spec ++++++ --- /var/tmp/diff_new_pack.ThWNHj/_old 2026-04-21 12:44:07.720702396 +0200 +++ /var/tmp/diff_new_pack.ThWNHj/_new 2026-04-21 12:44:07.760704058 +0200 @@ -17,7 +17,7 @@ Name: tail-tray -Version: 0.2.30 +Version: 0.2.31 Release: 0 Summary: Tailscale tray menu and UI for the KDE Plasma Desktop License: GPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.ThWNHj/_old 2026-04-21 12:44:08.020714860 +0200 +++ /var/tmp/diff_new_pack.ThWNHj/_new 2026-04-21 12:44:08.068716855 +0200 @@ -2,8 +2,8 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/SneWs/tail-tray</param> <param name="scm">git</param> - <param name="revision">refs/tags/v0.2.30</param> - <param name="match-tag">v0.2.30</param> + <param name="revision">refs/tags/v0.2.31</param> + <param name="match-tag">v0.2.31</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.ThWNHj/_old 2026-04-21 12:44:08.196722173 +0200 +++ /var/tmp/diff_new_pack.ThWNHj/_new 2026-04-21 12:44:08.232723669 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/SneWs/tail-tray</param> - <param name="changesrevision">6d5b36fb0967a4a7ce074cf33540355c3c5ca98c</param></service></servicedata> + <param name="changesrevision">47cf07894fe21ddea5ecd84462b161bba4d84667</param></service></servicedata> (No newline at EOF) ++++++ tail-tray-0.2.30.obscpio -> tail-tray-0.2.31.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/CMakeLists.txt new/tail-tray-0.2.31/CMakeLists.txt --- old/tail-tray-0.2.30/CMakeLists.txt 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/CMakeLists.txt 2026-04-20 00:35:28.000000000 +0200 @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.21) -project(tail-tray VERSION 0.2.30 LANGUAGES CXX) +project(tail-tray VERSION 0.2.31 LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/debian/changelog new/tail-tray-0.2.31/debian/changelog --- old/tail-tray-0.2.30/debian/changelog 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/debian/changelog 2026-04-20 00:35:28.000000000 +0200 @@ -1,4 +1,4 @@ -tail-tray (0.2.30) UNRELEASED; urgency=medium +tail-tray (0.2.31) UNRELEASED; urgency=medium * New upstream release. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/AccountsTabUiManager.cpp new/tail-tray-0.2.31/src/AccountsTabUiManager.cpp --- old/tail-tray-0.2.30/src/AccountsTabUiManager.cpp 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/AccountsTabUiManager.cpp 2026-04-20 00:35:28.000000000 +0200 @@ -4,10 +4,15 @@ #include "AccountsTabUiManager.h" + #include <QDesktopServices> #include <QUrl> #include <QInputDialog> #include <QDir> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QPixmap> +#include <QBuffer> #include "./ui_MainWindow.h" #include "MainWindow.h" @@ -18,6 +23,8 @@ , ui(u) , pAddAccountButtonMenu(nullptr) , pTailRunner(runner) + , pNetworkManager(std::make_unique<QNetworkAccessManager>(this)) + , profilePicCache() { // Add account context menu/split button for control server pAddAccountButtonMenu = std::make_unique<QMenu>(ui->btnAddAccount); @@ -32,9 +39,19 @@ connect(ui->btnLogout, &QPushButton::clicked, this, [this]() { pTailRunner->logout(); - auto* wnd = dynamic_cast<MainWindow*>(this->parent()); + if (ui->lstAccounts->selectedItems().count() > 0) { + auto* selectedItem = ui->lstAccounts->selectedItems().first(); + int row = ui->lstAccounts->row(selectedItem); + if (row >= 0) { + auto* item = ui->lstAccounts->takeItem(row); + delete item; + } + } + + showAccountDetails(false); + auto* wnd = dynamic_cast<MainWindow*>(this->parent()); wnd->userLoggedOut(); - wnd->hide(); + //wnd->hide(); } ); @@ -72,21 +89,44 @@ if (account.account.endsWith('*')) { // This is the active account... onTailStatusChanged(pTailStatus); + + ui->btnLogout->setVisible(true); + ui->btnReAuthenticate->setVisible(true); + ui->btnAdminConsole->setVisible(true); + ui->btnSwitchToAccount->setVisible(false); } else { - // Secondary account not currently active... + // Nth account not currently active... ui->lblUsername->setText(account.account); ui->lblTailnetName->setText(account.tailnet); ui->lblEmail->setText(account.account); ui->lblStatus->setText("Not running"); ui->lblKeyExpiry->setText(""); + + ui->btnAdminConsole->setVisible(false); + ui->btnLogout->setVisible(false); + ui->btnReAuthenticate->setVisible(false); + ui->btnSwitchToAccount->setVisible(true); + } + }); + + connect(ui->btnSwitchToAccount, &QPushButton::clicked, this, [this]() { + auto* item = ui->lstAccounts->currentItem(); + if (!item) { + return; } + + auto accountId = item->data(Qt::UserRole).toString(); + pTailRunner->switchAccount(accountId); }); + + ui->btnSwitchToAccount->setVisible(false); } - void AccountsTabUiManager::onAccountsListed(const QList<TailAccountInfo>& foundAccounts) { +void AccountsTabUiManager::onAccountsListed(const QList<TailAccountInfo>& foundAccounts) { accounts = foundAccounts; ui->lstAccounts->clear(); + ui->btnSwitchToAccount->setVisible(false); for (const auto& account : foundAccounts) { auto loginName = account.account; bool isActiveAccount = false; @@ -102,8 +142,9 @@ font.setBold(true); pCurrent->setFont(font); } - ui->lstAccounts->addItem(pCurrent); + pCurrent->setTextAlignment(Qt::AlignmentFlag::AlignLeft | Qt::AlignmentFlag::AlignVCenter); + ui->lstAccounts->addItem(pCurrent); } } @@ -139,16 +180,13 @@ } showAccountDetails(true); - - if (!pTailStatus.user.profilePicUrl.isEmpty()) { - // ui->lblUsername->setPixmap(QPixmap(pTailStatus->user->profilePicUrl)); - } } void AccountsTabUiManager::showAccountDetails(bool show) { if (!show) ui->lblUsername->setText(tr("Select an account in the list to view details")); - ui->lblUsername->setVisible(true); + + ui->lblUsername->setVisible(show); ui->lblTailnetName->setVisible(show); ui->lblTailnetNameTitle->setVisible(show); @@ -162,4 +200,37 @@ ui->btnLogout->setVisible(show); ui->btnAdminConsole->setVisible(show); ui->btnReAuthenticate->setVisible(show); + + if (!show) { + ui->lblUsername->setPixmap(QPixmap()); // Clear pixmap if no URL + return; + } + + // Load profile picture if URL is not empty + if (!pTailStatus.user.profilePicUrl.isEmpty()) { + if (profilePicCache.find(pTailStatus.user.profilePicUrl) != profilePicCache.end()) { + // Use cached pixmap + ui->lblUsername->setPixmap(profilePicCache[pTailStatus.user.profilePicUrl].scaled(ui->lblUsername->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + return; + } + + QUrl imageUrl(pTailStatus.user.profilePicUrl); + QNetworkRequest request(imageUrl); + QNetworkReply* reply = pNetworkManager->get(request); + connect(reply, &QNetworkReply::finished, this, [this, reply]() { + if (reply->error() == QNetworkReply::NoError) { + QByteArray imageData = reply->readAll(); + QPixmap pixmap; + if (pixmap.loadFromData(imageData)) { + profilePicCache[pTailStatus.user.profilePicUrl] = pixmap; // Cache the pixmap + ui->lblUsername->setPixmap(pixmap.scaled(ui->lblUsername->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + } + } + reply->deleteLater(); + }); + } + else { + profilePicCache[pTailStatus.user.profilePicUrl] = QPixmap(); // Cache empty pixmap for empty URL + ui->lblUsername->setPixmap(QPixmap()); // Clear pixmap if no URL + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/AccountsTabUiManager.h new/tail-tray-0.2.31/src/AccountsTabUiManager.h --- old/tail-tray-0.2.30/src/AccountsTabUiManager.h 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/AccountsTabUiManager.h 2026-04-20 00:35:28.000000000 +0200 @@ -4,7 +4,9 @@ #include "TailRunner.h" #include <QMenu> +#include <QNetworkAccessManager> #include <memory> +#include <map> QT_BEGIN_NAMESPACE namespace Ui { @@ -33,6 +35,8 @@ TailStatus pTailStatus; QList<TailAccountInfo> accounts; TailSettings settings; + std::unique_ptr<QNetworkAccessManager> pNetworkManager; + std::map<QString, QPixmap> profilePicCache; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/MainWindow.cpp new/tail-tray-0.2.31/src/MainWindow.cpp --- old/tail-tray-0.2.30/src/MainWindow.cpp 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/MainWindow.cpp 2026-04-20 00:35:28.000000000 +0200 @@ -448,7 +448,7 @@ } } -void MainWindow::onIpnEvent(const IpnEventData &eventData) { +void MainWindow::onIpnEvent(const IpnEventData& eventData) { if (eventData.Health.Warnings.networkStatus.ImpactsConnectivity) { if (eventData.Health.Warnings.networkStatus.WarnableCode == "network-status") { @@ -824,7 +824,8 @@ if (didChangeState) { seenWarningsAndErrors.clear(); } - } else { + } + else { ui->tabNetworkStatus->setDisabled(true); ui->tabSettings->setDisabled(true); ui->tabTailDrive->setDisabled(true); @@ -837,7 +838,8 @@ pTrayManager->stateChangedTo(newState, pTailStatus); accountsTabUi->onTailStatusChanged(pTailStatus); - if (eCurrentState == TailState::NotConnected) { + if (eCurrentState == TailState::NotConnected || + eCurrentState == TailState::NotLoggedIn) { // Nothing more to do return retVal; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/MainWindow.ui new/tail-tray-0.2.31/src/MainWindow.ui --- old/tail-tray-0.2.30/src/MainWindow.ui 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/MainWindow.ui 2026-04-20 00:35:28.000000000 +0200 @@ -10,7 +10,7 @@ <x>0</x> <y>0</y> <width>780</width> - <height>785</height> + <height>764</height> </rect> </property> <property name="sizePolicy"> @@ -22,7 +22,7 @@ <property name="minimumSize"> <size> <width>588</width> - <height>785</height> + <height>764</height> </size> </property> <property name="maximumSize"> @@ -54,7 +54,7 @@ <enum>QTabWidget::TabPosition::North</enum> </property> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <property name="iconSize"> <size> @@ -75,9 +75,9 @@ <attribute name="title"> <string>Account</string> </attribute> - <layout class="QVBoxLayout" name="verticalLayout_16"> + <layout class="QVBoxLayout" name="verticalLayout_5"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_18"> + <layout class="QHBoxLayout" name="horizontalLayout_37"> <item> <layout class="QVBoxLayout" name="verticalLayout"> <item> @@ -147,10 +147,7 @@ </layout> </item> <item> - <layout class="QVBoxLayout" name="accountDetailsContainer" stretch="0,0,0,0,0,0,0,0,0"> - <property name="bottomMargin"> - <number>0</number> - </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> <item> <layout class="QHBoxLayout" name="horizontalLayout_17"> <item> @@ -511,6 +508,49 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_18"> + <item> + <spacer name="horizontalSpacer_20"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="btnSwitchToAccount"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Activate Account</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_19"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer_4"> <property name="orientation"> <enum>Qt::Orientation::Vertical</enum> @@ -1494,7 +1534,7 @@ <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Policy::MinimumExpanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/NotificationsManager.cpp new/tail-tray-0.2.31/src/NotificationsManager.cpp --- old/tail-tray-0.2.30/src/NotificationsManager.cpp 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/NotificationsManager.cpp 2026-04-20 00:35:28.000000000 +0200 @@ -113,6 +113,7 @@ .arg(nodeName, ipAddress, os), QSystemTrayIcon::Information, 8000); #endif } + void NotificationsManager::showNodeDisconnectedNotification(const QString& nodeName, const QString& ipAddress, const QString& os) { #if defined(KNOTIFICATIONS_ENABLED) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/TailRunner.cpp new/tail-tray-0.2.31/src/TailRunner.cpp --- old/tail-tray-0.2.30/src/TailRunner.cpp 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/TailRunner.cpp 2026-04-20 00:35:28.000000000 +0200 @@ -135,19 +135,18 @@ if (settings.advertiseAsExitNode()) { args << "--advertise-exit-node"; - - // Check if we have an exit node that we should use - if (settings.exitNodeAllowLanAccess()) - args << "--exit-node-allow-lan-access"; - else - args << "--exit-node-allow-lan-access=false"; } else { args << "--advertise-exit-node=false"; - args << "--exit-node-allow-lan-access=false"; } - //qDebug() << "TailRunner::applySettings: " << args; + // From what I can gather, one should be able to set this even when not running as an exit node + if (settings.exitNodeAllowLanAccess()) + args << "--exit-node-allow-lan-access"; + else + args << "--exit-node-allow-lan-access=false"; + + qDebug() << "TailRunner::applySettings: " << args; runCommand(Command::SetSettings, "set", args, false, false); } @@ -512,6 +511,8 @@ auto oldStatus = lastKnownStatus; lastKnownStatus = newStatus; + bool isDifferentAccount = oldStatus.user.id != newStatus.user.id; + emit statusUpdated(newStatus); // If this is startup or a full refresh etc. we do not diff @@ -519,6 +520,10 @@ return; } + if (isDifferentAccount) { + return; + } + // Diff peers and track newly added peers for (const auto& peer : lastKnownStatus.peers) { const auto existsFromBefore = oldStatus.containsPeer(peer); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/TrayMenuManager.cpp new/tail-tray-0.2.31/src/TrayMenuManager.cpp --- old/tail-tray-0.2.30/src/TrayMenuManager.cpp 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/TrayMenuManager.cpp 2026-04-20 00:35:28.000000000 +0200 @@ -480,7 +480,7 @@ exitNodeAllowNwAccess->setCheckable(true); exitNodeAllowNwAccess->setChecked(settings.exitNodeAllowLanAccess()); - exitNodeAllowNwAccess->setEnabled(settings.advertiseAsExitNode()); + exitNodeAllowNwAccess->setEnabled(true); // This can be set even when not running as exit node connect(exitNodeAllowNwAccess, &QAction::triggered, this, [this, exitNodeAllowNwAccess](bool) { settings.exitNodeAllowLanAccess(exitNodeAllowNwAccess->isChecked()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tail-tray-0.2.30/src/Version.h new/tail-tray-0.2.31/src/Version.h --- old/tail-tray-0.2.30/src/Version.h 2026-03-02 15:03:43.000000000 +0100 +++ new/tail-tray-0.2.31/src/Version.h 2026-04-20 00:35:28.000000000 +0200 @@ -1,6 +1,6 @@ #pragma once -#define TAIL_TRAY_VERSION "0.2.30" +#define TAIL_TRAY_VERSION "0.2.31" #define TAIL_TRAY_VERSION_MAJOR 0 #define TAIL_TRAY_VERSION_MINOR 2 -#define TAIL_TRAY_VERSION_PATCH 30 +#define TAIL_TRAY_VERSION_PATCH 31 ++++++ tail-tray.obsinfo ++++++ --- /var/tmp/diff_new_pack.ThWNHj/_old 2026-04-21 12:44:10.160803777 +0200 +++ /var/tmp/diff_new_pack.ThWNHj/_new 2026-04-21 12:44:10.192805106 +0200 @@ -1,5 +1,5 @@ name: tail-tray -version: 0.2.30 -mtime: 1772460223 -commit: 6d5b36fb0967a4a7ce074cf33540355c3c5ca98c +version: 0.2.31 +mtime: 1776638128 +commit: 47cf07894fe21ddea5ecd84462b161bba4d84667
