mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
kdeui: replace libdbusmenu-qt dependency with custom classes
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
3db230c695
commit
819cca1e41
19 changed files with 760 additions and 117 deletions
|
@ -107,13 +107,6 @@ if(X11_FOUND)
|
|||
endif(NOT HAVE_XSYNC AND NOT HAVE_XSCREENSAVER)
|
||||
endif(X11_FOUND)
|
||||
|
||||
kde4_optional_find_package(DBusMenuQt)
|
||||
set_package_properties(DBusMenuQt PROPERTIES
|
||||
DESCRIPTION "Support for notification area menus via the DBusMenu protocol"
|
||||
URL "https://osdn.net/projects/kde/"
|
||||
TYPE RECOMMENDED
|
||||
)
|
||||
|
||||
kde4_optional_find_package(MPV 0.23.0)
|
||||
set_package_properties(MPV PROPERTIES
|
||||
DESCRIPTION "A fork of mplayer2 and MPlayer"
|
||||
|
|
|
@ -15,7 +15,6 @@ include(CMakePushCheckState)
|
|||
# definitions like _GNU_SOURCE that are needed on each platform.
|
||||
set(CMAKE_REQUIRED_DEFINITIONS ${_KDE4_PLATFORM_DEFINITIONS})
|
||||
|
||||
kde4_bool_to_01(DBUSMENUQT_FOUND HAVE_DBUSMENUQT) # kdeui
|
||||
kde4_bool_to_01(LibArchive_FOUND HAVE_LIBARCHIVE) # karchive
|
||||
kde4_bool_to_01(BZIP2_FOUND HAVE_BZIP2) # karchive
|
||||
kde4_bool_to_01(LIBLZMA_FOUND HAVE_LIBLZMA) # karchive
|
||||
|
|
|
@ -27,7 +27,6 @@ set(cmakeFilesDontInstall
|
|||
# compatible).
|
||||
set(cmakeFiles
|
||||
cmake-modules-styleguide.txt
|
||||
FindDBusMenuQt.cmake
|
||||
FindDjVuLibre.cmake
|
||||
FindEPub.cmake
|
||||
FindExiv2.cmake
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
# Try to find the DBusMenuQt library, once done this will define:
|
||||
#
|
||||
# DBUSMENUQT_FOUND - system has DBusMenuQt
|
||||
# DBUSMENUQT_INCLUDE_DIR - the DBusMenuQt include directory
|
||||
# DBUSMENUQT_LIBRARIES - the libraries needed to use DBusMenuQt
|
||||
# DBUSMENUQT_DEFINITIONS - compiler switches required for using DBusMenuQt
|
||||
#
|
||||
# Copyright (c) 2020 Ivailo Monev <xakepa10@gmail.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
set(DBUSMENU_QT_NAMES dbusmenu-katie dbusmenu-qt dbusmenu-qtd)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
foreach(name ${DBUSMENU_QT_NAMES})
|
||||
if(NOT PC_DBUSMENUQT_FOUND)
|
||||
pkg_check_modules(PC_DBUSMENUQT QUIET ${name})
|
||||
|
||||
set(DBUSMENUQT_INCLUDE_DIR ${PC_DBUSMENUQT_INCLUDE_DIRS})
|
||||
set(DBUSMENUQT_LIBRARIES ${PC_DBUSMENUQT_LIBRARIES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(DBUSMENUQT_VERSION ${PC_DBUSMENUQT_VERSION})
|
||||
set(DBUSMENUQT_DEFINITIONS ${PC_DBUSMENUQT_CFLAGS_OTHER})
|
||||
|
||||
if(NOT DBUSMENUQT_INCLUDE_DIR OR NOT DBUSMENUQT_LIBRARIES)
|
||||
find_path(DBUSMENUQT_INCLUDE_DIR
|
||||
NAMES dbusmenuexporter.h
|
||||
PATH_SUFFIXES ${DBUSMENU_QT_NAMES}
|
||||
HINTS $ENV{DBUSMENUQTDIR}/include
|
||||
)
|
||||
|
||||
find_library(DBUSMENUQT_LIBRARIES
|
||||
NAMES ${DBUSMENU_QT_NAMES}
|
||||
HINTS $ENV{DBUSMENUQTDIR}/lib
|
||||
)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DBusMenuQt
|
||||
VERSION_VAR DBUSMENUQT_VERSION
|
||||
REQUIRED_VARS DBUSMENUQT_LIBRARIES DBUSMENUQT_INCLUDE_DIR
|
||||
)
|
||||
|
||||
mark_as_advanced(DBUSMENUQT_INCLUDE_DIR DBUSMENUQT_LIBRARIES)
|
|
@ -38,9 +38,6 @@
|
|||
/* Define to 1 if you have the XSync extension */
|
||||
#cmakedefine HAVE_XSYNC 1
|
||||
|
||||
/* Define to 1 if you have DBusMenuQt */
|
||||
#cmakedefine HAVE_DBUSMENUQT 1
|
||||
|
||||
/* Define to 1 if you have libarchive */
|
||||
#cmakedefine HAVE_LIBARCHIVE 1
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ install(
|
|||
KDateTimeWidget
|
||||
KDateValidator
|
||||
KDateWidget
|
||||
KDBusMenuExporter
|
||||
KDBusMenuImporter
|
||||
KDesktopFile
|
||||
KDialog
|
||||
KDialogButtonBox
|
||||
|
|
1
includes/KDBusMenuExporter
Normal file
1
includes/KDBusMenuExporter
Normal file
|
@ -0,0 +1 @@
|
|||
#include "../kdbusmenuexporter.h"
|
1
includes/KDBusMenuImporter
Normal file
1
includes/KDBusMenuImporter
Normal file
|
@ -0,0 +1 @@
|
|||
#include "../kdbusmenuimporter.h"
|
|
@ -30,6 +30,7 @@
|
|||
297 kdeui (KNotificationRestrictions)
|
||||
299 kdeui (KNotification)
|
||||
300 kdeui (KConfigDialogManager)
|
||||
301 kdeui (KDBusMenu)
|
||||
700 kutils (KSettings::Dialog)
|
||||
701 kutils (KSettings::Dispatcher)
|
||||
702 kutils (KPluginSelector)
|
||||
|
|
|
@ -154,6 +154,9 @@ set(kdeui_LIB_SRCS
|
|||
notifications/knotification.cpp
|
||||
notifications/knotificationmanager.cpp
|
||||
notifications/knotificationrestrictions.cpp
|
||||
notifications/kdbusmenuexporter.cpp
|
||||
notifications/kdbusmenuimporter.cpp
|
||||
notifications/kdbusmenu_p.cpp
|
||||
paged/kpagedialog.cpp
|
||||
paged/kpagemodel.cpp
|
||||
paged/kpageview.cpp
|
||||
|
@ -258,15 +261,6 @@ set(kdeui_LIB_SRCS
|
|||
notifications/kstatusnotifieritemdbus_p.cpp
|
||||
)
|
||||
|
||||
if(DBUSMENUQT_FOUND)
|
||||
include_directories(${DBUSMENUQT_INCLUDE_DIR})
|
||||
|
||||
set(KDEUI_EXTRA_LIBS
|
||||
${KDEUI_EXTRA_LIBS}
|
||||
${DBUSMENUQT_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
qt4_add_dbus_interface(kdeui_LIB_SRCS
|
||||
notifications/org.kde.StatusNotifierWatcher.xml
|
||||
statusnotifierwatcher_interface
|
||||
|
@ -478,6 +472,8 @@ install(
|
|||
notifications/ksystemtrayicon.h
|
||||
notifications/knotification.h
|
||||
notifications/knotificationrestrictions.h
|
||||
notifications/kdbusmenuexporter.h
|
||||
notifications/kdbusmenuimporter.h
|
||||
paged/kpagedialog.h
|
||||
paged/kpagemodel.h
|
||||
paged/kpageview.h
|
||||
|
|
71
kdeui/notifications/kdbusmenu_p.cpp
Normal file
71
kdeui/notifications/kdbusmenu_p.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "kdbusmenu_p.h"
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument &argument, const KDBusMenu &kdbusmenu)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << kdbusmenu.icon;
|
||||
argument << kdbusmenu.title;
|
||||
argument << kdbusmenu.icondata;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument& operator>>(const QDBusArgument &argument, KDBusMenu &kdbusmenu)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> kdbusmenu.icon;
|
||||
argument >> kdbusmenu.title;
|
||||
argument >> kdbusmenu.icondata;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument &argument, const KDBusMenuAction &kdbusmenuaction)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << kdbusmenuaction.id;
|
||||
argument << kdbusmenuaction.text << kdbusmenuaction.icon;
|
||||
argument << kdbusmenuaction.tooltip << kdbusmenuaction.statustip << kdbusmenuaction.whatsthis;
|
||||
argument << kdbusmenuaction.separator << kdbusmenuaction.checkable << kdbusmenuaction.checked << kdbusmenuaction.enabled << kdbusmenuaction.visible;
|
||||
argument << kdbusmenuaction.shortcuts;
|
||||
argument << kdbusmenuaction.icondata;
|
||||
argument << kdbusmenuaction.title;
|
||||
argument << kdbusmenuaction.exclusive;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument& operator>>(const QDBusArgument &argument, KDBusMenuAction &kdbusmenuaction)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> kdbusmenuaction.id;
|
||||
argument >> kdbusmenuaction.text >> kdbusmenuaction.icon;
|
||||
argument >> kdbusmenuaction.tooltip >> kdbusmenuaction.statustip >> kdbusmenuaction.whatsthis;
|
||||
argument >> kdbusmenuaction.separator >> kdbusmenuaction.checkable >> kdbusmenuaction.checked >> kdbusmenuaction.enabled >> kdbusmenuaction.visible;
|
||||
argument >> kdbusmenuaction.shortcuts;
|
||||
argument >> kdbusmenuaction.icondata;
|
||||
argument >> kdbusmenuaction.title;
|
||||
argument >> kdbusmenuaction.exclusive;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
76
kdeui/notifications/kdbusmenu_p.h
Normal file
76
kdeui/notifications/kdbusmenu_p.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KDBUSMENU_H
|
||||
#define KDBUSMENU_H
|
||||
|
||||
#include "kiconloader.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDBusArgument>
|
||||
#include <QAction>
|
||||
#include <QImageWriter>
|
||||
|
||||
static const int s_kdbusmenuiconsize = KIconLoader::SizeSmall;
|
||||
static const QByteArray s_kdbusmenuiconformat = QImageWriter::defaultImageFormat();
|
||||
// see kdebug.areas
|
||||
static const int s_kdbusmenuarea = 301;
|
||||
|
||||
struct KDBusMenu
|
||||
{
|
||||
QString icon;
|
||||
QString title;
|
||||
QByteArray icondata;
|
||||
};
|
||||
Q_DECLARE_METATYPE(KDBusMenu);
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument &argument, const KDBusMenu &kdbusmenu);
|
||||
const QDBusArgument& operator>>(const QDBusArgument &argument, KDBusMenu &kdbusmenu);
|
||||
|
||||
struct KDBusMenuAction
|
||||
{
|
||||
quint64 id;
|
||||
QString text;
|
||||
QString icon;
|
||||
QString tooltip;
|
||||
QString statustip;
|
||||
QString whatsthis;
|
||||
bool separator;
|
||||
bool checkable;
|
||||
bool checked;
|
||||
bool enabled;
|
||||
bool visible;
|
||||
QStringList shortcuts;
|
||||
QByteArray icondata;
|
||||
bool title;
|
||||
bool exclusive;
|
||||
};
|
||||
Q_DECLARE_METATYPE(KDBusMenuAction);
|
||||
Q_DECLARE_METATYPE(QList<KDBusMenuAction>);
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument &argument, const KDBusMenuAction &kdbusmenuaction);
|
||||
const QDBusArgument& operator>>(const QDBusArgument &argument, KDBusMenuAction &kdbusmenuaction);
|
||||
|
||||
static quint64 kDBusMenuActionID(const QAction *action)
|
||||
{
|
||||
return quint64(quintptr(action));
|
||||
}
|
||||
|
||||
#endif // KDBUSMENU_H
|
261
kdeui/notifications/kdbusmenuexporter.cpp
Normal file
261
kdeui/notifications/kdbusmenuexporter.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "kdbusmenuexporter.h"
|
||||
#include "kdebug.h"
|
||||
#include "kdbusmenu_p.h"
|
||||
|
||||
#include <QDBusAbstractAdaptor>
|
||||
#include <QPointer>
|
||||
#include <QBuffer>
|
||||
#include <QToolButton>
|
||||
#include <QWidgetAction>
|
||||
#include <qdbusmetatype.h>
|
||||
|
||||
class KDBusMenuAdaptor: public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.DBusMenu")
|
||||
public:
|
||||
KDBusMenuAdaptor(KDBusMenuExporter *exporter, QMenu* menu);
|
||||
|
||||
public Q_SLOTS:
|
||||
QString status() const;
|
||||
void setStatus(const QString &status);
|
||||
|
||||
KDBusMenu menu() const;
|
||||
|
||||
QList<KDBusMenuAction> actions() const;
|
||||
bool triggerAction(quint64 actionid) const;
|
||||
|
||||
private:
|
||||
KDBusMenuExporter* m_exporter;
|
||||
QString m_status;
|
||||
QPointer<QMenu> m_menu;
|
||||
};
|
||||
|
||||
KDBusMenuAdaptor::KDBusMenuAdaptor(KDBusMenuExporter *exporter, QMenu* menu)
|
||||
: QDBusAbstractAdaptor(exporter),
|
||||
m_exporter(exporter),
|
||||
m_status(QString::fromLatin1("normal")),
|
||||
m_menu(menu)
|
||||
{
|
||||
qDBusRegisterMetaType<KDBusMenu>();
|
||||
qDBusRegisterMetaType<KDBusMenuAction>();
|
||||
qDBusRegisterMetaType<QList<KDBusMenuAction>>();
|
||||
}
|
||||
|
||||
QString KDBusMenuAdaptor::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void KDBusMenuAdaptor::setStatus(const QString &status)
|
||||
{
|
||||
kDebug(s_kdbusmenuarea) << "Changing status to" << status;
|
||||
if (status != QLatin1String("normal") && status != QLatin1String("notice")) {
|
||||
kWarning(s_kdbusmenuarea) << "Invalid status" << status;
|
||||
}
|
||||
m_status = status;
|
||||
}
|
||||
|
||||
KDBusMenu KDBusMenuAdaptor::menu() const
|
||||
{
|
||||
KDBusMenu result;
|
||||
if (m_menu.isNull()) {
|
||||
kWarning(s_kdbusmenuarea) << "Menu is null";
|
||||
return result;
|
||||
}
|
||||
// NOTE: KStatusNotifierItem adds actions to the menu when aboutToShow is emitted
|
||||
const bool menusignaled = QMetaObject::invokeMethod(m_menu.data(), "aboutToShow", Qt::DirectConnection);
|
||||
if (!menusignaled) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not invoke menu aboutToShow() signal";
|
||||
}
|
||||
const QIcon menuicon = m_menu->icon();
|
||||
result.icon = menuicon.name();
|
||||
result.title = m_menu->title();
|
||||
if (result.icon.isEmpty()) {
|
||||
QBuffer iconbuffer;
|
||||
QPixmap iconpixmap = menuicon.pixmap(s_kdbusmenuiconsize);
|
||||
if (iconpixmap.isNull()) {
|
||||
kWarning(s_kdbusmenuarea) << "Menu icon name is empty and icon pixmap is null";
|
||||
} else {
|
||||
const bool savedicon = iconpixmap.save(&iconbuffer, s_kdbusmenuiconformat);
|
||||
if (!savedicon) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not save menu icon pixmap";
|
||||
} else {
|
||||
result.icondata = iconbuffer.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<KDBusMenuAction> KDBusMenuAdaptor::actions() const
|
||||
{
|
||||
QList<KDBusMenuAction> result;
|
||||
if (m_menu.isNull()) {
|
||||
kWarning(s_kdbusmenuarea) << "Menu is null";
|
||||
return result;
|
||||
}
|
||||
foreach (QAction* action, m_menu->actions()) {
|
||||
const quint64 actionid = kDBusMenuActionID(action);
|
||||
kDebug(s_kdbusmenuarea) << "Exporting action" << actionid;
|
||||
const QMenu* actionmenu = action->menu();
|
||||
if (actionmenu) {
|
||||
kWarning(s_kdbusmenuarea) << "Menu actions are not supported";
|
||||
continue;
|
||||
}
|
||||
KDBusMenuAction actionproperties;
|
||||
// see kdeui/widgets/kmenu.cpp
|
||||
actionproperties.title = (action->objectName() == QLatin1String("kmenu_title"));
|
||||
if (actionproperties.title) {
|
||||
const QWidgetAction *actionwidget = qobject_cast<QWidgetAction*>(action);
|
||||
if (!actionwidget) {
|
||||
kWarning(s_kdbusmenuarea) << "Title has no widget" << actionid;
|
||||
} else {
|
||||
const QToolButton *actionbutton = qobject_cast<QToolButton*>(actionwidget->defaultWidget());
|
||||
if (!actionbutton) {
|
||||
kWarning(s_kdbusmenuarea) << "Title has no button" << actionid;
|
||||
} else {
|
||||
action = actionbutton->defaultAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
actionproperties.id = actionid;
|
||||
actionproperties.text = action->text();
|
||||
actionproperties.icon = m_exporter->iconNameForAction(action);
|
||||
actionproperties.tooltip = action->toolTip();
|
||||
actionproperties.statustip = action->statusTip();
|
||||
actionproperties.whatsthis = action->whatsThis();
|
||||
actionproperties.separator = action->isSeparator();
|
||||
actionproperties.checkable = action->isCheckable();
|
||||
actionproperties.checked = action->isChecked();
|
||||
actionproperties.enabled = action->isEnabled();
|
||||
actionproperties.visible = action->isVisible();
|
||||
QStringList shortcuts;
|
||||
foreach (const QKeySequence &keysequence, action->shortcuts()) {
|
||||
shortcuts.append(keysequence.toString());
|
||||
}
|
||||
actionproperties.shortcuts = shortcuts;
|
||||
if (actionproperties.icon.isEmpty()) {
|
||||
QBuffer iconbuffer;
|
||||
QPixmap iconpixmap = action->icon().pixmap(s_kdbusmenuiconsize);
|
||||
if (iconpixmap.isNull()) {
|
||||
kWarning(s_kdbusmenuarea) << "Icon name is empty and icon pixmap is null" << actionid;
|
||||
} else {
|
||||
const bool savedicon = iconpixmap.save(&iconbuffer, s_kdbusmenuiconformat);
|
||||
if (!savedicon) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not save icon pixmap" << actionid;
|
||||
} else {
|
||||
actionproperties.icondata = iconbuffer.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
const QActionGroup* actiongroup = action->actionGroup();
|
||||
actionproperties.exclusive = (actiongroup && actiongroup->isExclusive());
|
||||
result.append(actionproperties);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool KDBusMenuAdaptor::triggerAction(quint64 actionid) const
|
||||
{
|
||||
kDebug(s_kdbusmenuarea) << "Triggering action" << actionid;
|
||||
if (m_menu.isNull()) {
|
||||
kWarning(s_kdbusmenuarea) << "Menu is null";
|
||||
return false;
|
||||
}
|
||||
foreach (QAction* action, m_menu->actions()) {
|
||||
const quint64 itactionid = kDBusMenuActionID(action);
|
||||
if (itactionid == actionid) {
|
||||
return QMetaObject::invokeMethod(action, "triggered");
|
||||
}
|
||||
}
|
||||
kWarning(s_kdbusmenuarea) << "Could not find action for" << actionid;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class KDBusMenuExporterPrivate
|
||||
{
|
||||
public:
|
||||
KDBusMenuExporterPrivate();
|
||||
|
||||
KDBusMenuAdaptor* adaptor;
|
||||
QString objectpath;
|
||||
QString connectionname;
|
||||
};
|
||||
|
||||
KDBusMenuExporterPrivate::KDBusMenuExporterPrivate()
|
||||
: adaptor(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KDBusMenuExporter::KDBusMenuExporter(const QString &objectpath, QMenu *menu, const QDBusConnection &connection)
|
||||
: QObject(menu),
|
||||
d(new KDBusMenuExporterPrivate())
|
||||
{
|
||||
kDebug(s_kdbusmenuarea) << "Exporting menu" << objectpath;
|
||||
|
||||
d->adaptor = new KDBusMenuAdaptor(this, menu);
|
||||
d->objectpath = objectpath;
|
||||
d->connectionname = connection.name();
|
||||
|
||||
QDBusConnection dbusconnection(connection.name());
|
||||
dbusconnection.registerObject(objectpath, this);
|
||||
}
|
||||
|
||||
KDBusMenuExporter::~KDBusMenuExporter()
|
||||
{
|
||||
QDBusConnection dbusconnection(d->connectionname);
|
||||
dbusconnection.unregisterObject(d->objectpath);
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString KDBusMenuExporter::status() const
|
||||
{
|
||||
return d->adaptor->status();
|
||||
}
|
||||
|
||||
void KDBusMenuExporter::setStatus(const QString &status)
|
||||
{
|
||||
d->adaptor->setStatus(status);
|
||||
}
|
||||
|
||||
void KDBusMenuExporter::activateAction(QAction *action)
|
||||
{
|
||||
const quint64 actionid = kDBusMenuActionID(action);
|
||||
d->adaptor->triggerAction(actionid);
|
||||
}
|
||||
|
||||
QString KDBusMenuExporter::iconNameForAction(QAction *action)
|
||||
{
|
||||
if (!action) {
|
||||
return QString();
|
||||
}
|
||||
const QIcon icon = action->icon();
|
||||
if (action->isIconVisibleInMenu() && !icon.isNull()) {
|
||||
return icon.name();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
#include "kdbusmenuexporter.moc"
|
53
kdeui/notifications/kdbusmenuexporter.h
Normal file
53
kdeui/notifications/kdbusmenuexporter.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KDBUSMENUEXPORTER_H
|
||||
#define KDBUSMENUEXPORTER_H
|
||||
|
||||
#include "kdeui_export.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
class KDBusMenuExporterPrivate;
|
||||
|
||||
class KDEUI_EXPORT KDBusMenuExporter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KDBusMenuExporter(const QString &objectpath, QMenu *menu, const QDBusConnection &connection = QDBusConnection::sessionBus());
|
||||
virtual ~KDBusMenuExporter();
|
||||
|
||||
QString status() const;
|
||||
void setStatus(const QString &status);
|
||||
|
||||
void activateAction(QAction *action);
|
||||
|
||||
protected:
|
||||
virtual QString iconNameForAction(QAction *action);
|
||||
|
||||
private:
|
||||
KDBusMenuExporterPrivate *d;
|
||||
Q_DISABLE_COPY(KDBusMenuExporter);
|
||||
|
||||
friend class KDBusMenuAdaptor;
|
||||
};
|
||||
|
||||
#endif // KDBUSMENUEXPORTER_H
|
173
kdeui/notifications/kdbusmenuimporter.cpp
Normal file
173
kdeui/notifications/kdbusmenuimporter.cpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "kdbusmenuimporter.h"
|
||||
#include "kicon.h"
|
||||
#include "kmenu.h"
|
||||
#include "kdebug.h"
|
||||
#include "kdbusmenu_p.h"
|
||||
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <qdbusmetatype.h>
|
||||
|
||||
class KDBusMenuImporterPrivate
|
||||
{
|
||||
public:
|
||||
KDBusMenuImporterPrivate();
|
||||
|
||||
QDBusInterface* interface;
|
||||
QMenu* menu;
|
||||
};
|
||||
|
||||
KDBusMenuImporterPrivate::KDBusMenuImporterPrivate()
|
||||
: interface(nullptr),
|
||||
menu(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KDBusMenuImporter::KDBusMenuImporter(const QString &service, const QString &path, QObject *parent)
|
||||
: QObject(parent),
|
||||
d(new KDBusMenuImporterPrivate())
|
||||
{
|
||||
kDebug(s_kdbusmenuarea) << "Importing menu" << service << path;
|
||||
|
||||
qDBusRegisterMetaType<KDBusMenu>();
|
||||
qDBusRegisterMetaType<KDBusMenuAction>();
|
||||
qDBusRegisterMetaType<QList<KDBusMenuAction>>();
|
||||
|
||||
QDBusConnection dbusconnection = QDBusConnection::sessionBus();
|
||||
d->interface = new QDBusInterface(service, path, QString::fromLatin1("org.kde.DBusMenu"), dbusconnection, this);
|
||||
}
|
||||
|
||||
KDBusMenuImporter::~KDBusMenuImporter()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QMenu* KDBusMenuImporter::menu() const
|
||||
{
|
||||
return d->menu;
|
||||
}
|
||||
|
||||
void KDBusMenuImporter::updateMenu()
|
||||
{
|
||||
kDebug(s_kdbusmenuarea) << "Updating menu";
|
||||
if (d->menu) {
|
||||
delete d->menu;
|
||||
d->menu = nullptr;
|
||||
}
|
||||
d->menu = KDBusMenuImporter::createMenu(nullptr);
|
||||
QDBusReply<KDBusMenu> menureply = d->interface->call("menu");
|
||||
if (!menureply.isValid()) {
|
||||
kWarning(s_kdbusmenuarea) << "Invalid menu reply" << menureply.error();
|
||||
return;
|
||||
}
|
||||
const KDBusMenu menuproperties = menureply.value();
|
||||
d->menu->setTitle(menuproperties.title);
|
||||
QIcon menuicon = KDBusMenuImporter::iconForName(menuproperties.icon);
|
||||
if (menuicon.isNull() && !menuproperties.icondata.isEmpty()) {
|
||||
QPixmap menupixmap;
|
||||
const bool pixmaploaded = menupixmap.loadFromData(menuproperties.icondata, s_kdbusmenuiconformat);
|
||||
if (!pixmaploaded) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not load menu icon pixmap";
|
||||
} else {
|
||||
menuicon = QIcon(menupixmap);
|
||||
}
|
||||
}
|
||||
d->menu->setIcon(menuicon);
|
||||
|
||||
QDBusReply<QList<KDBusMenuAction>> actionsreply = d->interface->call("actions");
|
||||
if (!actionsreply.isValid()) {
|
||||
kWarning(s_kdbusmenuarea) << "Invalid actions reply" << actionsreply.error();
|
||||
return;
|
||||
}
|
||||
foreach (const KDBusMenuAction &actionproperties, actionsreply.value()) {
|
||||
const quint64 actionid = actionproperties.id;
|
||||
kDebug(s_kdbusmenuarea) << "Importing action" << actionid;
|
||||
QIcon actionicon = KDBusMenuImporter::iconForName(actionproperties.icon);
|
||||
if (actionicon.isNull() && !actionproperties.icondata.isEmpty()) {
|
||||
QPixmap actionpixmap;
|
||||
const bool pixmaploaded = actionpixmap.loadFromData(actionproperties.icondata, s_kdbusmenuiconformat);
|
||||
if (!pixmaploaded) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not load icon pixmap" << actionid;
|
||||
} else {
|
||||
actionicon = QIcon(actionpixmap);
|
||||
}
|
||||
}
|
||||
QAction* action = nullptr;
|
||||
if (actionproperties.title) {
|
||||
// see kdeui/widgets/kmenu.cpp
|
||||
action = KMenu::titleAction(actionicon, actionproperties.text, d->menu);
|
||||
} else {
|
||||
action = new QAction(d->menu);
|
||||
action->setText(actionproperties.text);
|
||||
action->setIcon(actionicon);
|
||||
action->setToolTip(actionproperties.tooltip);
|
||||
action->setStatusTip(actionproperties.statustip);
|
||||
action->setWhatsThis(actionproperties.whatsthis);
|
||||
action->setSeparator(actionproperties.separator);
|
||||
action->setCheckable(actionproperties.checkable);
|
||||
action->setChecked(actionproperties.checked);
|
||||
action->setEnabled(actionproperties.enabled);
|
||||
action->setVisible(actionproperties.visible);
|
||||
QList<QKeySequence> shortcuts;
|
||||
foreach (const QString &keysequence, actionproperties.shortcuts) {
|
||||
shortcuts.append(QKeySequence::fromString(keysequence));
|
||||
}
|
||||
action->setShortcuts(shortcuts);
|
||||
if (actionproperties.exclusive) {
|
||||
QActionGroup *actiongroup = new QActionGroup(action);
|
||||
actiongroup->addAction(action);
|
||||
}
|
||||
}
|
||||
action->setData(QVariant(actionid));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(slotActionTriggered()));
|
||||
d->menu->addAction(action);
|
||||
}
|
||||
emit menuUpdated();
|
||||
}
|
||||
|
||||
QMenu* KDBusMenuImporter::createMenu(QWidget *parent)
|
||||
{
|
||||
return new QMenu(parent);
|
||||
}
|
||||
|
||||
QIcon KDBusMenuImporter::iconForName(const QString &name)
|
||||
{
|
||||
return QIcon::fromTheme(name);
|
||||
}
|
||||
|
||||
void KDBusMenuImporter::slotActionTriggered()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
const quint64 actionid = action->data().toULongLong();
|
||||
kDebug(s_kdbusmenuarea) << "Action triggered" << actionid;
|
||||
QDBusReply<bool> reply = d->interface->call("triggerAction", actionid);
|
||||
if (!reply.isValid()) {
|
||||
kWarning(s_kdbusmenuarea) << "Invalid action trigger reply" << reply.error();
|
||||
return;
|
||||
}
|
||||
if (reply.value() != true) {
|
||||
kWarning(s_kdbusmenuarea) << "Could not trigger action" << actionid;
|
||||
return;
|
||||
}
|
||||
emit actionActivationRequested(action);
|
||||
}
|
60
kdeui/notifications/kdbusmenuimporter.h
Normal file
60
kdeui/notifications/kdbusmenuimporter.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* This file is part of the KDE libraries
|
||||
Copyright (C) 2023 smil3y <xakepa10@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KDBUSMENUIMPORTER_H
|
||||
#define KDBUSMENUIMPORTER_H
|
||||
|
||||
#include "kdeui_export.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QIcon>
|
||||
#include <QWidget>
|
||||
#include <QAction>
|
||||
|
||||
class KDBusMenuImporterPrivate;
|
||||
|
||||
class KDEUI_EXPORT KDBusMenuImporter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KDBusMenuImporter(const QString &service, const QString &path, QObject *parent = 0);
|
||||
virtual ~KDBusMenuImporter();
|
||||
|
||||
QMenu* menu() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateMenu();
|
||||
|
||||
Q_SIGNALS:
|
||||
void menuUpdated();
|
||||
void actionActivationRequested(QAction *action);
|
||||
|
||||
protected:
|
||||
virtual QMenu *createMenu(QWidget *parent);
|
||||
virtual QIcon iconForName(const QString &name);
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotActionTriggered();
|
||||
|
||||
private:
|
||||
KDBusMenuImporterPrivate *d;
|
||||
Q_DISABLE_COPY(KDBusMenuImporter);
|
||||
};
|
||||
|
||||
#endif // KDBUSMENUIMPORTER_H
|
|
@ -40,6 +40,7 @@
|
|||
#include <kactioncollection.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kglobal.h>
|
||||
#include <kdbusmenuexporter.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
@ -47,10 +48,6 @@
|
|||
|
||||
static const QString s_statusNotifierWatcherServiceName("org.kde.StatusNotifierWatcher");
|
||||
|
||||
#ifdef HAVE_DBUSMENUQT
|
||||
# include <dbusmenuexporter.h>
|
||||
#endif
|
||||
|
||||
KStatusNotifierItem::KStatusNotifierItem(QObject *parent)
|
||||
: QObject(parent),
|
||||
d(new KStatusNotifierItemPrivate(this))
|
||||
|
@ -373,23 +370,17 @@ void KStatusNotifierItem::setContextMenu(KMenu *menu)
|
|||
if (d->systemTrayIcon) {
|
||||
d->systemTrayIcon->setContextMenu(menu);
|
||||
} else if (d->menu != menu) {
|
||||
#ifdef HAVE_DBUSMENUQT
|
||||
if (getenv("KSNI_NO_DBUSMENU")) {
|
||||
#else
|
||||
d->setLegacySystemTrayEnabled(true);
|
||||
#endif
|
||||
// This is a hack to make it possible to disable DBusMenu in an
|
||||
// application. The string "/NO_DBUSMENU" must be the same as in
|
||||
// DBusSystemTrayWidget::findDBusMenuInterface() in the Plasma
|
||||
// systemtray applet.
|
||||
d->menuObjectPath = "/NO_DBUSMENU";
|
||||
menu->installEventFilter(this);
|
||||
#ifdef HAVE_DBUSMENUQT
|
||||
} else {
|
||||
d->menuObjectPath = "/MenuBar";
|
||||
new DBusMenuExporter(d->menuObjectPath, menu, d->statusNotifierItemDBus->dbusConnection());
|
||||
new KDBusMenuExporter(d->menuObjectPath, menu, d->statusNotifierItemDBus->dbusConnection());
|
||||
}
|
||||
#endif
|
||||
|
||||
connect(menu, SIGNAL(aboutToShow()), this, SLOT(contextMenuAboutToShow()));
|
||||
}
|
||||
|
|
|
@ -42,28 +42,24 @@
|
|||
|
||||
static const char KMENU_TITLE[] = "kmenu_title";
|
||||
|
||||
class KMenu::KMenuPrivate
|
||||
: public QObject
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The event filter which is installed on the widget prevent clicks (what would
|
||||
* change down and focus properties on the title) on the title of the menu.
|
||||
*
|
||||
* @author Rafael Fernández López <ereslibre@kde.org>
|
||||
*/
|
||||
class KMenuToolButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KMenuPrivate (KMenu *_parent);
|
||||
~KMenuPrivate ();
|
||||
KMenuToolButton(QWidget *parent) : QToolButton(parent)
|
||||
{
|
||||
// prevent clicks on the title of the menu
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
void resetKeyboardVars(bool noMatches = false);
|
||||
void actionHovered(QAction* action);
|
||||
void showCtxMenu(const QPoint &pos);
|
||||
void skipTitles(QKeyEvent *event);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* This event filter which is installed
|
||||
* on the title of the menu, which is a QToolButton. This will
|
||||
* prevent clicks (what would change down and focus properties on
|
||||
* the title) on the title of the menu.
|
||||
*
|
||||
* @author Rafael Fernández López <ereslibre@kde.org>
|
||||
*/
|
||||
bool eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(object);
|
||||
|
@ -77,6 +73,19 @@ public:
|
|||
event->accept();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class KMenu::KMenuPrivate
|
||||
: public QObject
|
||||
{
|
||||
public:
|
||||
KMenuPrivate (KMenu *_parent);
|
||||
~KMenuPrivate ();
|
||||
|
||||
void resetKeyboardVars(bool noMatches = false);
|
||||
void actionHovered(QAction* action);
|
||||
void showCtxMenu(const QPoint &pos);
|
||||
void skipTitles(QKeyEvent *event);
|
||||
|
||||
KMenu *parent;
|
||||
|
||||
|
@ -172,22 +181,7 @@ QAction* KMenu::addTitle(const QString &text, QAction* before)
|
|||
|
||||
QAction* KMenu::addTitle(const QIcon &icon, const QString &text, QAction* before)
|
||||
{
|
||||
QAction *buttonAction = new QAction(this);
|
||||
QFont font = buttonAction->font();
|
||||
font.setBold(true);
|
||||
buttonAction->setFont(font);
|
||||
buttonAction->setText(text);
|
||||
buttonAction->setIcon(icon);
|
||||
|
||||
QWidgetAction *action = new QWidgetAction(this);
|
||||
action->setObjectName(KMENU_TITLE);
|
||||
QToolButton *titleButton = new QToolButton(this);
|
||||
titleButton->installEventFilter(d); // prevent clicks on the title of the menu
|
||||
titleButton->setDefaultAction(buttonAction);
|
||||
titleButton->setDown(true); // prevent hover style changes in some styles
|
||||
titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
action->setDefaultWidget(titleButton);
|
||||
|
||||
QAction *action = KMenu::titleAction(icon, text, this);
|
||||
insertAction(before, action);
|
||||
return action;
|
||||
}
|
||||
|
@ -555,6 +549,25 @@ QAction * KMenu::contextMenuFocusAction( )
|
|||
return 0L;
|
||||
}
|
||||
|
||||
QAction* KMenu::titleAction(const QIcon &icon, const QString &text, QWidget* parent)
|
||||
{
|
||||
QAction *buttonAction = new QAction(parent);
|
||||
QFont font = buttonAction->font();
|
||||
font.setBold(true);
|
||||
buttonAction->setFont(font);
|
||||
buttonAction->setText(text);
|
||||
buttonAction->setIcon(icon);
|
||||
|
||||
QWidgetAction *action = new QWidgetAction(parent);
|
||||
action->setObjectName(KMENU_TITLE);
|
||||
KMenuToolButton *titleButton = new KMenuToolButton(parent);
|
||||
titleButton->setDefaultAction(buttonAction);
|
||||
titleButton->setDown(true); // prevent hover style changes in some styles
|
||||
titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
action->setDefaultWidget(titleButton);
|
||||
return action;
|
||||
}
|
||||
|
||||
void KMenu::contextMenuEvent(QContextMenuEvent* e)
|
||||
{
|
||||
if (d->ctxMenu)
|
||||
|
@ -598,9 +611,6 @@ void KMenu::hideEvent(QHideEvent *e)
|
|||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
KMenuContext::KMenuContext( )
|
||||
: m_menu(0L)
|
||||
, m_action(0L)
|
||||
|
@ -620,3 +630,4 @@ KMenuContext::KMenuContext(QPointer<KMenu> menu,QPointer<QAction> action)
|
|||
}
|
||||
|
||||
#include "moc_kmenu.cpp"
|
||||
#include "kmenu.moc"
|
||||
|
|
|
@ -120,6 +120,11 @@ public:
|
|||
*/
|
||||
static QAction* contextMenuFocusAction();
|
||||
|
||||
/**
|
||||
* returns QAction for use as title
|
||||
*/
|
||||
static QAction* titleAction(const QIcon &icon, const QString &text, QWidget* parent);
|
||||
|
||||
/**
|
||||
* Return the state of the mouse buttons when the last menuitem was activated.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue