Commit 19ab6f3b authored by Marco Martin's avatar Marco Martin

Make Appmenu work based on the presence of a visual representation

Summary:
drop the internal settings InApp,Menu, Decoration
but instead export the menu based on the presence of a dbus service called
org.kde.appmenuview, exported by either the menubar applet or the
kwin decoration button

let the decoration button and the globalmenubar work at the same time

not necessary anymore to have the setting in the kcm

Test Plan:
adding an appmenu applet causes apps started afterwards
to export their menubar, removing it causes new apps to
have their menubar internal again

Reviewers: #plasma, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: davidedmundson, ngraham, mvourlakos, broulik, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D9215
parent 0fb97c86
......@@ -30,24 +30,53 @@
#include <QQuickWindow>
#include <QScreen>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCall>
#include <QDBusConnectionInterface>
#include <QTimer>
int AppMenuApplet::s_refs = 0;
static const QString s_viewService(QStringLiteral("org.kde.kappmenuview"));
AppMenuApplet::AppMenuApplet(QObject *parent, const QVariantList &data)
: Plasma::Applet(parent, data)
{
++s_refs;
//if we're the first, regster the service
if (s_refs == 1) {
QDBusConnection::sessionBus().interface()->registerService(s_viewService,
QDBusConnectionInterface::QueueService,
QDBusConnectionInterface::DontAllowReplacement);
}
/*it registers or unregisters the service when the destroyed value of the applet change,
and not in the dtor, because:
when we "delete" an applet, it just hides it for about a minute setting its status
to destroyed, in order to be able to do a clean undo: if we undo, there will be
another destroyedchanged and destroyed will be false.
When this happens, if we are the only appmenu applet existing, the dbus interface
will have to be registered again*/
connect(this, &Applet::destroyedChanged, this, [this](bool destroyed) {
if (destroyed) {
//if we were the last, unregister
if (--s_refs == 0) {
QDBusConnection::sessionBus().interface()->unregisterService(s_viewService);
}
} else {
//if we're the first, regster the service
if (++s_refs == 1) {
QDBusConnection::sessionBus().interface()->registerService(s_viewService,
QDBusConnectionInterface::QueueService,
QDBusConnectionInterface::DontAllowReplacement);
}
}
});
}
AppMenuApplet::~AppMenuApplet() = default;
void AppMenuApplet::init()
{
// TODO Wayland PlasmaShellSurface stuff
QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.kappmenu"),
QStringLiteral("/KAppMenu"),
QStringLiteral("org.kde.kappmenu"),
QStringLiteral("reconfigured"),
this, SLOT(updateAppletEnabled()));
updateAppletEnabled();
}
AppMenuModel *AppMenuApplet::model() const
......@@ -102,24 +131,6 @@ void AppMenuApplet::setButtonGrid(QQuickItem *buttonGrid)
}
}
bool AppMenuApplet::appletEnabled() const
{
return m_appletEnabled;
}
void AppMenuApplet::updateAppletEnabled()
{
KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("Appmenu Style"));
const QString &menuStyle = config.readEntry(QStringLiteral("Style"));
const bool enabled = (menuStyle == QLatin1String("Widget"));
if (m_appletEnabled != enabled) {
m_appletEnabled = enabled;
emit appletEnabledChanged();
}
}
QMenu *AppMenuApplet::createMenu(int idx) const
{
QMenu *menu = nullptr;
......
......@@ -33,8 +33,6 @@ class AppMenuApplet : public Plasma::Applet
{
Q_OBJECT
Q_PROPERTY(bool appletEnabled READ appletEnabled NOTIFY appletEnabledChanged)
Q_PROPERTY(AppMenuModel* model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(int view READ view WRITE setView NOTIFY viewChanged)
......@@ -65,18 +63,14 @@ public:
int view() const;
void setView(int type);
bool appletEnabled() const;
signals:
void modelChanged();
void viewChanged();
void currentIndexChanged();
void buttonGridChanged();
void appletEnabledChanged();
void requestActivateIndex(int index);
public slots:
void updateAppletEnabled();
void trigger(QQuickItem *ctx, int idx);
protected:
......@@ -90,8 +84,8 @@ private:
int m_currentIndex = -1;
int m_viewType = FullView;
bool m_appletEnabled = true;
QPointer<QMenu> m_currentMenu;
QPointer<QQuickItem> m_buttonGrid;
QPointer<AppMenuModel> m_model;
static int s_refs;
};
......@@ -30,7 +30,6 @@ Item {
id: root
readonly property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
readonly property bool appletEnabled: plasmoid.nativeInterface.appletEnabled
readonly property bool view: plasmoid.configuration.compactView
readonly property bool menuAvailable: appMenuModel.menuAvailable
......@@ -40,7 +39,7 @@ Item {
plasmoid.nativeInterface.view = view
}
Plasmoid.preferredRepresentation: (plasmoid.configuration.compactView || vertical || !appletEnabled) ? Plasmoid.compactRepresentation : Plasmoid.fullRepresentation
Plasmoid.preferredRepresentation: (plasmoid.configuration.compactView || vertical) ? Plasmoid.compactRepresentation : Plasmoid.fullRepresentation
Plasmoid.compactRepresentation: PlasmaComponents.ToolButton {
readonly property int fakeIndex: 0
......@@ -48,23 +47,17 @@ Item {
Layout.fillHeight: false
Layout.minimumWidth: implicitWidth
Layout.maximumWidth: implicitWidth
enabled: appletEnabled ? menuAvailable : kcmAuthorized
checkable: appletEnabled && menuAvailable && plasmoid.nativeInterface.currentIndex === fakeIndex
enabled: menuAvailable
checkable: menuAvailable && plasmoid.nativeInterface.currentIndex === fakeIndex
checked: checkable
iconSource: appletEnabled ? "application-menu" : "emblem-warning"
onClicked: {
if (appletEnabled) {
plasmoid.nativeInterface.trigger(this, 0);
} else {
KCMShell.open("style")
}
}
iconSource: i18n("application-menu")
onClicked: plasmoid.nativeInterface.trigger(this, 0);
}
Plasmoid.fullRepresentation: GridLayout {
id: buttonGrid
//when we're not enabled set to active to show the configure button
Plasmoid.status: !appletEnabled || buttonRepeater.count > 0 ?
Plasmoid.status: buttonRepeater.count > 0 ?
PlasmaCore.Types.ActiveStatus : PlasmaCore.Types.HiddenStatus
Layout.minimumWidth: implicitWidth
Layout.minimumHeight: implicitHeight
......@@ -107,10 +100,6 @@ Item {
}
}
Plasmoid.toolTipMainText: appletEnabled ? "" : i18n("Application Menu Widget is disabled")
Plasmoid.toolTipSubText: appletEnabled || !root.kcmAuthorized ? ""
: i18nc("it being the 'Application Menu Widget'", "Go to System Settings > Application Style > Fine Tuning (tab) to enable it.");
AppMenuPrivate.AppMenuModel {
id: appMenuModel
onRequestActivateIndex: plasmoid.nativeInterface.requestActivateIndex(index)
......
......@@ -71,6 +71,35 @@ AppMenuModule::AppMenuModule(QObject* parent, const QList<QVariant>&)
connect(this, &AppMenuModule::showRequest, m_appmenuDBus, &AppmenuDBus::showRequest);
connect(this, &AppMenuModule::menuHidden, m_appmenuDBus, &AppmenuDBus::menuHidden);
connect(this, &AppMenuModule::menuShown, m_appmenuDBus, &AppmenuDBus::menuShown);
m_menuViewWatcher = new QDBusServiceWatcher(QStringLiteral("org.kde.kappmenuview"), QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForRegistration|QDBusServiceWatcher::WatchForUnregistration, this);
auto setupMenuImporter = [this]() {
QDBusConnection::sessionBus().connect({}, {}, QStringLiteral("com.canonical.dbusmenu"),
QStringLiteral("ItemActivationRequested"),
this, SLOT(itemActivationRequested(int,uint)));
// Setup a menu importer if needed
if (!m_menuImporter) {
m_menuImporter = new MenuImporter(this);
connect(m_menuImporter, &MenuImporter::WindowRegistered, this, &AppMenuModule::slotWindowRegistered);
m_menuImporter->connectToBus();
}
};
connect(m_menuViewWatcher, &QDBusServiceWatcher::serviceRegistered, this, setupMenuImporter);
connect(m_menuViewWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](const QString &service) {
Q_UNUSED(service)
QDBusConnection::sessionBus().disconnect({}, {}, QStringLiteral("com.canonical.dbusmenu"),
QStringLiteral("ItemActivationRequested"),
this, SLOT(itemActivationRequested(int,uint)));
delete m_menuImporter;
m_menuImporter = nullptr;
});
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kappmenuview"))) {
setupMenuImporter();
}
}
AppMenuModule::~AppMenuModule() = default;
......@@ -174,36 +203,9 @@ void AppMenuModule::itemActivationRequested(int actionId, uint timeStamp)
emit showRequest(message().service(), QDBusObjectPath(message().path()), actionId);
}
// reload settings
// this method is not really used anymore but has to be kept for DBus compatibility
void AppMenuModule::reconfigure()
{
hideMenu(); // hide window decoration menu if exists
KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("Appmenu Style"));
const QString &menuStyle = config.readEntry("Style", "InApplication");
// TODO enum or Kconfigxt or what not?
if (menuStyle == QLatin1String("Decoration")) {
QDBusConnection::sessionBus().connect({}, {}, QStringLiteral("com.canonical.dbusmenu"),
QStringLiteral("ItemActivationRequested"),
this, SLOT(itemActivationRequested(int,uint)));
} else {
QDBusConnection::sessionBus().disconnect({}, {}, QStringLiteral("com.canonical.dbusmenu"),
QStringLiteral("ItemActivationRequested"),
this, SLOT(itemActivationRequested(int,uint)));
}
if (menuStyle == QLatin1String("InApplication")) {
delete m_menuImporter;
m_menuImporter = nullptr;
return;
}
// Setup a menu importer if needed
if (!m_menuImporter) {
m_menuImporter = new MenuImporter(this);
connect(m_menuImporter, &MenuImporter::WindowRegistered, this, &AppMenuModule::slotWindowRegistered);
m_menuImporter->connectToBus();
}
}
#include "appmenu.moc"
......@@ -33,6 +33,7 @@
#include "menuimporter.h"
class QDBusPendingCallWatcher;
class QDBusServiceWatcher;
class KDBusMenuImporter;
class AppmenuDBus;
class TopMenuBar;
......@@ -91,6 +92,7 @@ private:
MenuImporter *m_menuImporter = nullptr;
AppmenuDBus *m_appmenuDBus;
QDBusServiceWatcher *m_menuViewWatcher;
QPointer<VerticalMenu> m_menu;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment