Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qt: Remove dbus notification code #575

Closed
wants to merge 1 commit into from
Closed
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
29 changes: 2 additions & 27 deletions build-aux/m4/bitcoin_qt.m4
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,6 @@ AC_DEFUN([BITCOIN_QT_INIT],[
AC_ARG_WITH([qt-translationdir],[AS_HELP_STRING([--with-qt-translationdir=PLUGIN_DIR],[specify qt translation path (overridden by pkgconfig)])], [qt_translation_path=$withval], [])
AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], [])

AC_ARG_WITH([qtdbus],
[AS_HELP_STRING([--with-qtdbus],
[enable DBus support (default is yes if qt is enabled and QtDBus is found, except on Android)])],
[use_dbus=$withval],
[use_dbus=auto])

dnl Android doesn't support D-Bus and certainly doesn't use it for notifications
case $host in
*android*)
if test "$use_dbus" != "yes"; then
use_dbus=no
fi
;;
esac

AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path)
])

Expand All @@ -102,7 +87,7 @@ dnl BITCOIN_QT_CONFIGURE([MINIMUM-VERSION])
dnl
dnl Outputs: See _BITCOIN_QT_FIND_LIBS
dnl Outputs: Sets variables for all qt-related tools.
dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test
dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_test
AC_DEFUN([BITCOIN_QT_CONFIGURE],[
qt_version=">= $1"
qt_lib_prefix="Qt5"
Expand Down Expand Up @@ -251,13 +236,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
if test "$have_qt_test" = "no"; then
bitcoin_enable_qt_test=no
fi
bitcoin_enable_qt_dbus=no
if test "$use_dbus" != "no" && test "$have_qt_dbus" = "yes"; then
bitcoin_enable_qt_dbus=yes
fi
if test "$use_dbus" = "yes" && test "$have_qt_dbus" = "no"; then
AC_MSG_ERROR([libQtDBus not found. Install libQtDBus or remove --with-qtdbus.])
fi
if test "$LUPDATE" = ""; then
AC_MSG_WARN([lupdate tool is required to update Qt translations.])
fi
Expand Down Expand Up @@ -369,7 +347,7 @@ dnl _BITCOIN_QT_FIND_LIBS
dnl ---------------------
dnl
dnl Outputs: All necessary QT_* variables are set.
dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
dnl Outputs: have_qt_test are set (if applicable) to yes|no.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
dnl Outputs: have_qt_test are set (if applicable) to yes|no.
dnl Outputs: have_qt_test is set (if applicable) to yes|no.

AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[
BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"],
Expand All @@ -390,8 +368,5 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[

BITCOIN_QT_CHECK([
PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
if test "$use_dbus" != "no"; then
PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
fi
])
])
10 changes: 1 addition & 9 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,6 @@ if test "$enable_fuzz" = "yes"; then
build_bitcoin_libs=no
bitcoin_enable_qt=no
bitcoin_enable_qt_test=no
bitcoin_enable_qt_dbus=no
use_bench=no
use_external_signer=no
use_upnp=no
Expand All @@ -1318,7 +1317,7 @@ if test "$enable_fuzz" = "yes"; then
else
BITCOIN_QT_INIT

dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test
BITCOIN_QT_CONFIGURE([5.11.3])

dnl Keep a copy of the original $QT_INCLUDES and use it when invoking qt's moc
Expand Down Expand Up @@ -1757,13 +1756,6 @@ fi
dnl these are only used when qt is enabled
BUILD_TEST_QT=""
if test "$bitcoin_enable_qt" != "no"; then
dnl enable dbus support
AC_MSG_CHECKING([whether to build GUI with support for D-Bus])
if test "$bitcoin_enable_qt_dbus" != "no"; then
AC_DEFINE([USE_DBUS], [1], [Define if dbus support should be compiled in])
fi
AC_MSG_RESULT([$bitcoin_enable_qt_dbus])

dnl enable qr support
AC_MSG_CHECKING([whether to build GUI with support for QR codes])
if test "$have_qrencode" = "no"; then
Expand Down
2 changes: 1 addition & 1 deletion doc/build-unix.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ To build without GUI pass `--without-gui`.

To build with Qt 5 you need the following:

sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools
sudo apt-get install libqt5gui5 libqt5core5a qttools5-dev qttools5-dev-tools

Additionally, to support Wayland protocol for modern desktop environments:

Expand Down
4 changes: 2 additions & 2 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ void BitcoinGUI::message(const QString& title, QString message, unsigned int sty
QString strTitle{PACKAGE_NAME};
// Default to information icon
int nMBoxIcon = QMessageBox::Information;
int nNotifyIcon = Notificator::Information;
Notificator::Class nNotifyIcon = Notificator::Information;

QString msgType;
if (!title.isEmpty()) {
Expand Down Expand Up @@ -1176,7 +1176,7 @@ void BitcoinGUI::message(const QString& title, QString message, unsigned int sty
if (ret != nullptr)
*ret = r == QMessageBox::Ok;
} else {
notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message);
notificator->notify(nNotifyIcon, strTitle, message);
}
}

Expand Down
170 changes: 1 addition & 169 deletions src/qt/notificator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,22 @@
#include <QSystemTrayIcon>
#include <QTemporaryFile>
#include <QVariant>
#ifdef USE_DBUS
#include <stdint.h>
#include <QtDBus>
#endif
#ifdef Q_OS_MAC
#include <qt/macnotificationhandler.h>
#endif


#ifdef USE_DBUS
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128;
#endif

Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon, QWidget *_parent) :
QObject(_parent),
parent(_parent),
programName(_programName),
mode(None),
trayIcon(_trayIcon)
#ifdef USE_DBUS
,interface(nullptr)
#endif
{
if(_trayIcon && _trayIcon->supportsMessages())
{
mode = QSystemTray;
}
#ifdef USE_DBUS
interface = new QDBusInterface("org.freedesktop.Notifications",
"/org/freedesktop/Notifications", "org.freedesktop.Notifications");
if(interface->isValid())
{
mode = Freedesktop;
}
#endif
#ifdef Q_OS_MAC
// check if users OS has support for NSUserNotification
if( MacNotificationHandler::instance()->hasUserNotificationCenterSupport()) {
Expand All @@ -59,151 +39,8 @@ Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon

Notificator::~Notificator()
{
#ifdef USE_DBUS
delete interface;
#endif
}

#ifdef USE_DBUS

// Loosely based on https://www.qtcentre.org/archive/index.php/t-25879.html
class FreedesktopImage
{
public:
FreedesktopImage() {}
explicit FreedesktopImage(const QImage &img);

static int metaType();

// Image to variant that can be marshalled over DBus
static QVariant toVariant(const QImage &img);

private:
int width, height, stride;
bool hasAlpha;
int channels;
int bitsPerSample;
QByteArray image;

friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i);
friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i);
};

Q_DECLARE_METATYPE(FreedesktopImage);

// Image configuration settings
const int CHANNELS = 4;
const int BYTES_PER_PIXEL = 4;
const int BITS_PER_SAMPLE = 8;

FreedesktopImage::FreedesktopImage(const QImage &img):
width(img.width()),
height(img.height()),
stride(img.width() * BYTES_PER_PIXEL),
hasAlpha(true),
channels(CHANNELS),
bitsPerSample(BITS_PER_SAMPLE)
{
// Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format
QImage tmp = img.convertToFormat(QImage::Format_ARGB32);
const uint32_t *data = reinterpret_cast<const uint32_t*>(tmp.bits());

unsigned int num_pixels = width * height;
image.resize(num_pixels * BYTES_PER_PIXEL);

for(unsigned int ptr = 0; ptr < num_pixels; ++ptr)
{
image[ptr*BYTES_PER_PIXEL+0] = data[ptr] >> 16; // R
image[ptr*BYTES_PER_PIXEL+1] = data[ptr] >> 8; // G
image[ptr*BYTES_PER_PIXEL+2] = data[ptr]; // B
image[ptr*BYTES_PER_PIXEL+3] = data[ptr] >> 24; // A
}
}

QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i)
{
a.beginStructure();
a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image;
a.endStructure();
return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i)
{
a.beginStructure();
a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image;
a.endStructure();
return a;
}

int FreedesktopImage::metaType()
{
return qDBusRegisterMetaType<FreedesktopImage>();
}

QVariant FreedesktopImage::toVariant(const QImage &img)
{
FreedesktopImage fimg(img);
return QVariant(FreedesktopImage::metaType(), &fimg);
}

void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
{
// https://developer.gnome.org/notification-spec/
// Arguments for DBus "Notify" call:
QList<QVariant> args;

// Program Name:
args.append(programName);

// Replaces ID; A value of 0 means that this notification won't replace any existing notifications:
args.append(0U);

// Application Icon, empty string
args.append(QString());

// Summary
args.append(title);

// Body
args.append(text);

// Actions (none, actions are deprecated)
QStringList actions;
args.append(actions);

// Hints
QVariantMap hints;

// If no icon specified, set icon based on class
QIcon tmpicon;
if(icon.isNull())
{
QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion;
switch(cls)
{
case Information: sicon = QStyle::SP_MessageBoxInformation; break;
case Warning: sicon = QStyle::SP_MessageBoxWarning; break;
case Critical: sicon = QStyle::SP_MessageBoxCritical; break;
default: break;
}
tmpicon = QApplication::style()->standardIcon(sicon);
}
else
{
tmpicon = icon;
}
hints["icon_data"] = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage());
args.append(hints);

// Timeout (in msec)
args.append(millisTimeout);

// "Fire and forget"
interface->callWithArgumentList(QDBus::NoBlock, "Notify", args);
}
#endif

void Notificator::notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout)
{
QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon;
Expand All @@ -224,15 +61,10 @@ void Notificator::notifyMacUserNotificationCenter(const QString &title, const QS
}
#endif

void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
void Notificator::notify(Class cls, const QString &title, const QString &text, int millisTimeout)
{
switch(mode)
{
#ifdef USE_DBUS
case Freedesktop:
notifyDBus(cls, title, text, icon, millisTimeout);
break;
#endif
case QSystemTray:
notifySystray(cls, title, text, millisTimeout);
break;
Expand Down
11 changes: 1 addition & 10 deletions src/qt/notificator.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
QT_BEGIN_NAMESPACE
class QSystemTrayIcon;

#ifdef USE_DBUS
class QDBusInterface;
#endif
QT_END_NAMESPACE

/** Cross-platform desktop notification client. */
Expand Down Expand Up @@ -45,12 +42,11 @@ public Q_SLOTS:
@param[in] cls general message class
@param[in] title title shown with message
@param[in] text message content
@param[in] icon optional icon to show with message
@param[in] millisTimeout notification timeout in milliseconds (defaults to 10 seconds)
@note Platform implementations are free to ignore any of the provided fields except for \a text.
*/
void notify(Class cls, const QString &title, const QString &text,
const QIcon &icon = QIcon(), int millisTimeout = 10000);
int millisTimeout = 10000);

private:
QWidget *parent;
Expand All @@ -63,11 +59,6 @@ public Q_SLOTS:
QString programName;
Mode mode;
QSystemTrayIcon *trayIcon;
#ifdef USE_DBUS
QDBusInterface *interface;

void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
#endif
void notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout);
#ifdef Q_OS_MAC
void notifyMacUserNotificationCenter(const QString &title, const QString &text);
Expand Down