Improve behavior under Wayland
* Add workaround for using QCursor::pos() * Set window flags and parent of TrayMenu to it is shown like a context menu
This commit is contained in:
parent
9f9b9124a4
commit
1bdba31c70
|
@ -111,7 +111,7 @@ void trigger(bool tray, bool webUi)
|
|||
trayWidget->showWebUi();
|
||||
}
|
||||
if (tray) {
|
||||
trayWidget->showAtCursor();
|
||||
trayWidget->showUsingPositioningSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace QtGui {
|
|||
*/
|
||||
TrayIcon::TrayIcon(const QString &connectionConfig, QObject *parent)
|
||||
: QSystemTrayIcon(parent)
|
||||
, m_trayMenu(this)
|
||||
, m_trayMenu(new TrayMenu(this, &m_parentWidget))
|
||||
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
|
||||
, m_dbusNotificationsEnabled(Settings::values().dbusNotifications)
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ TrayIcon::TrayIcon(const QString &connectionConfig, QObject *parent)
|
|||
, m_messageClickedAction(TrayIconMessageClickedAction::None)
|
||||
{
|
||||
// get widget, connection and notifier
|
||||
const auto &widget(m_trayMenu.widget());
|
||||
const auto &widget(trayMenu().widget());
|
||||
const auto &connection(widget.connection());
|
||||
const auto ¬ifier(widget.notifier());
|
||||
|
||||
|
@ -71,7 +71,7 @@ TrayIcon::TrayIcon(const QString &connectionConfig, QObject *parent)
|
|||
tr("Show internal errors"));
|
||||
m_errorsAction->setVisible(false);
|
||||
connect(m_errorsAction, &QAction::triggered, this, &TrayIcon::showInternalErrorsDialog);
|
||||
m_contextMenu.addMenu(m_trayMenu.widget().connectionsMenu());
|
||||
m_contextMenu.addMenu(trayMenu().widget().connectionsMenu());
|
||||
connect(m_contextMenu.addAction(
|
||||
QIcon::fromTheme(QStringLiteral("help-about"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/help-about.svg"))), tr("About")),
|
||||
&QAction::triggered, &widget, &TrayWidget::showAboutDialog);
|
||||
|
@ -109,7 +109,7 @@ TrayIcon::TrayIcon(const QString &connectionConfig, QObject *parent)
|
|||
|
||||
// apply settings, this also establishes the connection to Syncthing (according to settings)
|
||||
// note: it is important to apply settings after all Signals & Slots have been connected (eg. to handle SyncthingConnection::error())
|
||||
m_trayMenu.widget().applySettings(connectionConfig);
|
||||
trayMenu().widget().applySettings(connectionConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -136,10 +136,10 @@ void TrayIcon::handleActivated(QSystemTrayIcon::ActivationReason reason)
|
|||
// can't catch that event on Plasma 5 anyways
|
||||
break;
|
||||
case QSystemTrayIcon::MiddleClick:
|
||||
m_trayMenu.widget().showWebUi();
|
||||
trayMenu().widget().showWebUi();
|
||||
break;
|
||||
case QSystemTrayIcon::Trigger: {
|
||||
m_trayMenu.showAtCursor();
|
||||
trayMenu().showUsingPositioningSettings();
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
|
@ -152,13 +152,13 @@ void TrayIcon::handleMessageClicked()
|
|||
case TrayIconMessageClickedAction::None:
|
||||
return;
|
||||
case TrayIconMessageClickedAction::DismissNotification:
|
||||
m_trayMenu.widget().dismissNotifications();
|
||||
trayMenu().widget().dismissNotifications();
|
||||
break;
|
||||
case TrayIconMessageClickedAction::ShowInternalErrors:
|
||||
showInternalErrorsDialog();
|
||||
break;
|
||||
case TrayIconMessageClickedAction::ShowWebUi:
|
||||
m_trayMenu.widget().showWebUi();
|
||||
trayMenu().widget().showWebUi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ void TrayIcon::handleErrorsCleared()
|
|||
void TrayIcon::showInternalError(
|
||||
const QString &errorMessage, SyncthingErrorCategory category, int networkError, const QNetworkRequest &request, const QByteArray &response)
|
||||
{
|
||||
if (!InternalError::isRelevant(m_trayMenu.widget().connection(), category, networkError)) {
|
||||
if (!InternalError::isRelevant(trayMenu().widget().connection(), category, networkError)) {
|
||||
return;
|
||||
}
|
||||
InternalError error(errorMessage, request.url(), response);
|
||||
|
|
|
@ -49,7 +49,8 @@ private slots:
|
|||
void handleErrorsCleared();
|
||||
|
||||
private:
|
||||
TrayMenu m_trayMenu;
|
||||
QWidget m_parentWidget;
|
||||
TrayMenu *m_trayMenu;
|
||||
#ifndef SYNCTHINGTRAY_UNIFY_TRAY_MENUS
|
||||
QMenu m_contextMenu;
|
||||
QAction *m_errorsAction;
|
||||
|
@ -64,7 +65,7 @@ private:
|
|||
|
||||
inline TrayMenu &TrayIcon::trayMenu()
|
||||
{
|
||||
return m_trayMenu;
|
||||
return *m_trayMenu;
|
||||
}
|
||||
|
||||
} // namespace QtGui
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <qtutilities/misc/dialogutils.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
#include <QDesktopWidget>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
|
@ -25,6 +24,7 @@ TrayMenu::TrayMenu(TrayIcon *trayIcon, QWidget *parent)
|
|||
menuLayout->addWidget(m_trayWidget = new TrayWidget(this));
|
||||
setLayout(menuLayout);
|
||||
setPlatformMenu(nullptr);
|
||||
setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::Popup);
|
||||
}
|
||||
|
||||
QSize TrayMenu::sizeHint() const
|
||||
|
@ -50,10 +50,10 @@ void moveInside(QPoint &point, const QSize &innerRect, const QRect &outerRect)
|
|||
}
|
||||
}
|
||||
|
||||
void TrayMenu::showAtCursor()
|
||||
void TrayMenu::showUsingPositioningSettings()
|
||||
{
|
||||
resize(sizeHint());
|
||||
QPoint pos(QCursor::pos());
|
||||
auto pos = Settings::values().appearance.positioning.positionToUse();
|
||||
moveInside(pos, size(), availableScreenGeometryAtPoint(pos));
|
||||
popup(pos);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
TrayIcon *icon();
|
||||
|
||||
public slots:
|
||||
void showAtCursor();
|
||||
void showUsingPositioningSettings();
|
||||
|
||||
private:
|
||||
TrayWidget *m_trayWidget;
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
#include <QClipboard>
|
||||
#include <QCoreApplication>
|
||||
#include <QCursor>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QFontDatabase>
|
||||
|
@ -278,12 +277,12 @@ void TrayWidget::showNotifications()
|
|||
dismissNotifications();
|
||||
}
|
||||
|
||||
void TrayWidget::showAtCursor()
|
||||
void TrayWidget::showUsingPositioningSettings()
|
||||
{
|
||||
if (m_menu) {
|
||||
m_menu->showAtCursor();
|
||||
m_menu->showUsingPositioningSettings();
|
||||
} else {
|
||||
move(QCursor::pos());
|
||||
move(Settings::values().appearance.positioning.positionToUse());
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public slots:
|
|||
void showOwnDeviceId();
|
||||
void showLog();
|
||||
void showNotifications();
|
||||
void showAtCursor();
|
||||
void showUsingPositioningSettings();
|
||||
#ifdef SYNCTHINGTRAY_UNIFY_TRAY_MENUS
|
||||
void showInternalErrorsButton();
|
||||
void showInternalErrorsDialog();
|
||||
|
|
|
@ -20,24 +20,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="guiElementsLabel">
|
||||
<property name="text">
|
||||
<string>Optional GUI elements</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="showTrafficCheckBox">
|
||||
<property name="text">
|
||||
<string>Traffic statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="menuSizeHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="widthSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
|
@ -67,6 +56,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="heightSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
|
@ -79,17 +71,37 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sizePxLabel">
|
||||
<property name="text">
|
||||
<string> px</string>
|
||||
<spacer name="sizeHorizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="guiElementsLabel">
|
||||
<property name="text">
|
||||
<string>Optional GUI elements</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="showTrafficCheckBox">
|
||||
<property name="text">
|
||||
<string>Traffic statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="frameShapeLabel">
|
||||
<property name="text">
|
||||
|
@ -97,13 +109,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="frameShadowLabel">
|
||||
<property name="text">
|
||||
<string>Frame shadow</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="frameShapeComboBox">
|
||||
<item>
|
||||
|
@ -128,6 +133,13 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="frameShadowLabel">
|
||||
<property name="text">
|
||||
<string>Frame shadow</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="frameShadowComboBox">
|
||||
<item>
|
||||
|
@ -147,14 +159,14 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="tabPosLabel">
|
||||
<property name="text">
|
||||
<string>Tab position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="tabPosComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
|
@ -178,20 +190,129 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="colorsLabel">
|
||||
<property name="text">
|
||||
<string>Colors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="brightTextColorsCheckBox">
|
||||
<property name="text">
|
||||
<string>Bright custom text colors (use for dark color scheme)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="positioningLabel">
|
||||
<property name="text">
|
||||
<string>Positioning</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QVBoxLayout" name="positioningVerticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useCursorPosCheckBox">
|
||||
<property name="text">
|
||||
<string>Use cursor position</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="assumeIconPosLabel">
|
||||
<property name="text">
|
||||
<string>Otherwise assume tray icon coordinates to be:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="positioningHorizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="xPosLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>x:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="xPosSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-10000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="yPosLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>y:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="yPosSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-10000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="positioningHorizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
|
@ -51,6 +52,14 @@ namespace Settings {
|
|||
*/
|
||||
constexpr auto minActiveTimeInSeconds = 5;
|
||||
|
||||
/*!
|
||||
* \brief Returns the position to use.
|
||||
*/
|
||||
QPoint Appearance::Positioning::positionToUse() const
|
||||
{
|
||||
return useCursorPosition ? QCursor::pos() : assumedIconPosition;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Contains the processes for launching extra tools.
|
||||
* \remarks Using std::unordered_map instead of QHash because SyncthingProcess can not be copied.
|
||||
|
@ -245,6 +254,11 @@ void restore()
|
|||
appearance.tabPosition = settings.value(QStringLiteral("tabPos"), appearance.tabPosition).toInt();
|
||||
appearance.brightTextColors = settings.value(QStringLiteral("brightTextColors"), appearance.brightTextColors).toBool();
|
||||
v.statusIcons = StatusIconSettings(settings.value(QStringLiteral("statusIcons")).toString());
|
||||
settings.beginGroup(QStringLiteral("positioning"));
|
||||
auto &positioning = appearance.positioning;
|
||||
positioning.useCursorPosition = settings.value(QStringLiteral("useCursorPos"), positioning.useCursorPosition).toBool();
|
||||
positioning.assumedIconPosition = settings.value(QStringLiteral("assumedIconPos"), positioning.assumedIconPosition).toPoint();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup(QStringLiteral("startup"));
|
||||
|
@ -336,6 +350,10 @@ void save()
|
|||
settings.setValue(QStringLiteral("tabPos"), appearance.tabPosition);
|
||||
settings.setValue(QStringLiteral("brightTextColors"), appearance.brightTextColors);
|
||||
settings.setValue(QStringLiteral("statusIcons"), v.statusIcons.toString());
|
||||
settings.beginGroup(QStringLiteral("positioning"));
|
||||
settings.setValue(QStringLiteral("useCursorPos"), appearance.positioning.useCursorPosition);
|
||||
settings.setValue(QStringLiteral("assumedIconPos"), appearance.positioning.assumedIconPosition);
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup(QStringLiteral("startup"));
|
||||
|
@ -469,6 +487,7 @@ Systemd::ServiceStatus Systemd::status(SyncthingConnection &connection) const
|
|||
const auto isRelevant = service->isSystemdAvailable() && connection.isLocal();
|
||||
return ServiceStatus{ isRelevant, service->isRunning(), considerForReconnect && isRelevant, showButton && isRelevant };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Settings
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QByteArray>
|
||||
#include <QFrame>
|
||||
#include <QHash>
|
||||
#include <QPoint>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QTabWidget>
|
||||
|
@ -51,6 +52,11 @@ struct SYNCTHINGWIDGETS_EXPORT Appearance {
|
|||
int frameStyle = QFrame::NoFrame | QFrame::Plain;
|
||||
int tabPosition = QTabWidget::South;
|
||||
bool brightTextColors = false;
|
||||
struct Positioning {
|
||||
QPoint assumedIconPosition;
|
||||
bool useCursorPosition = true;
|
||||
QPoint positionToUse() const;
|
||||
} positioning;
|
||||
};
|
||||
|
||||
struct SYNCTHINGWIDGETS_EXPORT ToolParameter {
|
||||
|
|
|
@ -457,6 +457,9 @@ bool AppearanceOptionPage::apply()
|
|||
settings.tabPosition = ui()->tabPosComboBox->currentIndex();
|
||||
|
||||
settings.brightTextColors = ui()->brightTextColorsCheckBox->isChecked();
|
||||
|
||||
settings.positioning.useCursorPosition = ui()->useCursorPosCheckBox->isChecked();
|
||||
settings.positioning.assumedIconPosition = QPoint(ui()->xPosSpinBox->value(), ui()->yPosSpinBox->value());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -493,7 +496,12 @@ void AppearanceOptionPage::reset()
|
|||
}
|
||||
ui()->frameShadowComboBox->setCurrentIndex(index);
|
||||
ui()->tabPosComboBox->setCurrentIndex(settings.tabPosition);
|
||||
|
||||
ui()->brightTextColorsCheckBox->setChecked(settings.brightTextColors);
|
||||
|
||||
ui()->useCursorPosCheckBox->setChecked(settings.positioning.useCursorPosition);
|
||||
ui()->xPosSpinBox->setValue(settings.positioning.assumedIconPosition.x());
|
||||
ui()->yPosSpinBox->setValue(settings.positioning.assumedIconPosition.y());
|
||||
}
|
||||
|
||||
// IconsOptionPage
|
||||
|
|
Loading…
Reference in New Issue