Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3
plasma5-workspace
0001-Clean-up-KAppMenu.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Clean-up-KAppMenu.patch of Package plasma5-workspace
From 78f868f687d9b158f639b5407c0037a13b0bda8c Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik <kde@privat.broulik.de> Date: Thu, 5 Jan 2017 17:13:12 +0100 Subject: [PATCH 01/44] Clean up KAppMenu Massively cleanup KAppMenu by removing outdated and unused code. The global menu has been removed as it will eventually be provided by a plasmoid (famous last words). The biggest change, however, is that instead of relying on Windows IDs (which won't work on Wayland) we always speak of DBus service name and object path which will be added as properties to the respective windows. To support 3rd party applications, we also set the property in the RegisterWindow function. This way KWin doesn't need any fallback code and can just rely on those properties. Differential Revision: https://phabricator.kde.org/D3086 --- appmenu/CMakeLists.txt | 13 +- appmenu/appmenu.cpp | 413 ++++++++++++------------------------------- appmenu/appmenu.h | 112 +++--------- appmenu/appmenu_dbus.cpp | 8 +- appmenu/appmenu_dbus.h | 29 +-- appmenu/glowbar.cpp | 109 ------------ appmenu/glowbar.h | 51 ------ appmenu/gtkicons.h | 146 --------------- appmenu/kdbusimporter.h | 40 +---- appmenu/menubar.cpp | 166 ----------------- appmenu/menubar.h | 87 --------- appmenu/menubutton.cpp | 85 --------- appmenu/menubutton.h | 54 ------ appmenu/menuimporter.cpp | 92 +++------- appmenu/menuimporter.h | 9 +- appmenu/menuwidget.cpp | 387 ---------------------------------------- appmenu/menuwidget.h | 143 --------------- appmenu/org.kde.kappmenu.xml | 23 +-- appmenu/shadows.cpp | 381 --------------------------------------- appmenu/shadows.h | 51 ------ appmenu/topmenubar.cpp | 176 ------------------ appmenu/topmenubar.h | 81 --------- appmenu/verticalmenu.h | 22 +-- 23 files changed, 216 insertions(+), 2462 deletions(-) delete mode 100644 appmenu/glowbar.cpp delete mode 100644 appmenu/glowbar.h delete mode 100644 appmenu/gtkicons.h delete mode 100644 appmenu/menubar.cpp delete mode 100644 appmenu/menubar.h delete mode 100644 appmenu/menubutton.cpp delete mode 100644 appmenu/menubutton.h delete mode 100644 appmenu/menuwidget.cpp delete mode 100644 appmenu/menuwidget.h delete mode 100644 appmenu/shadows.cpp delete mode 100644 appmenu/shadows.h delete mode 100644 appmenu/topmenubar.cpp delete mode 100644 appmenu/topmenubar.h diff --git a/appmenu/CMakeLists.txt b/appmenu/CMakeLists.txt index 5060675b..7addb5d1 100644 --- a/appmenu/CMakeLists.txt +++ b/appmenu/CMakeLists.txt @@ -6,13 +6,7 @@ set(kded_appmenu_SRCS appmenu.cpp menuimporter.cpp appmenu_dbus.cpp -# menubutton.cpp -# menuwidget.cpp -# menubar.cpp -# topmenubar.cpp -# glowbar.cpp verticalmenu.cpp -# shadows.cpp ) qt5_add_dbus_adaptor(kded_appmenu_SRCS com.canonical.AppMenu.Registrar.xml @@ -26,16 +20,17 @@ kcoreaddons_desktop_to_json(appmenu appmenu.desktop) target_link_libraries(appmenu Qt5::DBus - Qt5::X11Extras KF5::DBusAddons KF5::KIOCore - KF5::KIOWidgets KF5::WindowSystem - KF5::KDELibs4Support ${X11_LIBRARIES} dbusmenu-qt5 ) +if (HAVE_X11) + target_link_libraries(appmenu Qt5::X11Extras XCB::XCB) +endif() + install(TARGETS appmenu DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kded ) ########### install files ############### diff --git a/appmenu/appmenu.cpp b/appmenu/appmenu.cpp index 86017f8b..14c3d2fe 100644 --- a/appmenu/appmenu.cpp +++ b/appmenu/appmenu.cpp @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> + Copyright (c) 2016 Kai Uwe Broulik <kde@privat.broulik.de> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,31 +24,32 @@ DEALINGS IN THE SOFTWARE. */ +#include <config-X11.h> + #include "appmenu.h" #include "kdbusimporter.h" #include "menuimporteradaptor.h" #include "appmenuadaptor.h" #include "appmenu_dbus.h" -#if 0 -#include "topmenubar.h" -#endif #include "verticalmenu.h" #include <QDBusInterface> -#include <QDBusReply> -#include <QDBusPendingCallWatcher> #include <QMenu> -#include <QApplication> -#include <QDesktopWidget> -#include <KDebug> -#include <KWindowSystem> -#include <KWindowInfo> #include <KConfig> #include <KConfigGroup> #include <kpluginfactory.h> #include <kpluginloader.h> -#include <netwm.h> +#include <KSharedConfig> +#include <KWindowSystem> + +#if HAVE_X11 +#include <QX11Info> +#include <xcb/xcb.h> +#endif + +static const QByteArray s_x11AppMenuServiceNamePropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_SERVICE_NAME"); +static const QByteArray s_x11AppMenuObjectPathPropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_OBJECT_PATH"); K_PLUGIN_FACTORY_WITH_JSON(AppMenuFactory, "appmenu.json", @@ -55,49 +57,63 @@ K_PLUGIN_FACTORY_WITH_JSON(AppMenuFactory, AppMenuModule::AppMenuModule(QObject* parent, const QList<QVariant>&) : KDEDModule(parent), - m_parent(parent), - m_menuImporter(0), - m_appmenuDBus(new AppmenuDBus(parent)), - m_menubar(0), - m_menu(0), - m_screenTimer(new QTimer(this)), - m_waitingAction(0), - m_currentScreen(-1) + m_appmenuDBus(new AppmenuDBus(this)) { reconfigure(); m_appmenuDBus->connectToBus(); - m_currentScreen = currentScreen(); - connect(m_appmenuDBus, &AppmenuDBus::appShowMenu, this, &AppMenuModule::slotShowMenu); - connect(m_appmenuDBus, &AppmenuDBus::moduleReconfigure, this, &AppMenuModule::reconfigure); + connect(m_appmenuDBus, &AppmenuDBus::reconfigured, this, &AppMenuModule::reconfigure); // transfer our signals to dbus connect(this, &AppMenuModule::showRequest, m_appmenuDBus, &AppmenuDBus::showRequest); - connect(this, &AppMenuModule::menuAvailable, m_appmenuDBus, &AppmenuDBus::menuAvailable); - connect(this, &AppMenuModule::clearMenus, m_appmenuDBus, &AppmenuDBus::clearMenus); connect(this, &AppMenuModule::menuHidden, m_appmenuDBus, &AppmenuDBus::menuHidden); - connect(this, &AppMenuModule::WindowRegistered, - m_appmenuDBus, &AppmenuDBus::WindowRegistered); - connect(this, &AppMenuModule::WindowUnregistered, m_appmenuDBus, &AppmenuDBus::WindowUnregistered); + connect(this, &AppMenuModule::menuShown, m_appmenuDBus, &AppmenuDBus::menuShown); + + QDBusConnection::sessionBus().connect({}, {}, QStringLiteral("com.canonical.dbusmenu"), + QStringLiteral("ItemActivationRequested"), + this, SLOT(itemActivationRequested(int,uint))); } -AppMenuModule::~AppMenuModule() +AppMenuModule::~AppMenuModule() = default; + +void AppMenuModule::slotWindowRegistered(WId id, const QString &serviceName, const QDBusObjectPath &menuObjectPath) { - emit clearMenus(); - hideMenubar(); -#if 0 - delete m_menubar; +#ifdef HAVE_X11 + if (KWindowSystem::isPlatformX11()) { + auto *c = QX11Info::connection(); + + static xcb_atom_t s_serviceNameAtom = XCB_ATOM_NONE; + static xcb_atom_t s_objectPathAtom = XCB_ATOM_NONE; + + auto setWindowProperty = [c](WId id, xcb_atom_t &atom, const QByteArray &name, const QByteArray &value) { + if (atom == XCB_ATOM_NONE) { + const xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, false, name.length(), name.constData()); + QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> reply(xcb_intern_atom_reply(c, cookie, Q_NULLPTR)); + if (reply.isNull()) { + return; + } + atom = reply->atom; + if (atom == XCB_ATOM_NONE) { + return; + } + } + + xcb_change_property(c, XCB_PROP_MODE_REPLACE, id, atom, XCB_ATOM_STRING, + 8, value.length(), value.constData()); + }; + + // TODO only set the property if it doesn't already exist + + setWindowProperty(id, s_serviceNameAtom, s_x11AppMenuServiceNamePropertyName, serviceName.toUtf8()); + setWindowProperty(id, s_objectPathAtom, s_x11AppMenuObjectPathPropertyName, menuObjectPath.path().toUtf8()); + } #endif - delete m_menuImporter; - delete m_appmenuDBus; } -void AppMenuModule::slotShowMenu(int x, int y, WId id) +void AppMenuModule::slotShowMenu(int x, int y, const QString &serviceName, const QDBusObjectPath &menuObjectPath) { - static KDBusMenuImporter *importer = 0; - if (!m_menuImporter) { return; } @@ -111,310 +127,101 @@ void AppMenuModule::slotShowMenu(int x, int y, WId id) //dbus call by user (for khotkey shortcut) if (x == -1 || y == -1) { // We do not know kwin button position, so tell kwin to show menu - emit showRequest(KWindowSystem::self()->activeWindow()); + emit showRequest(serviceName, menuObjectPath); return; } - importer = getImporter(id); + auto *importer = new KDBusMenuImporter(serviceName, menuObjectPath.path(), this); + // FIXME this causes a 4 second freeze in dbusmenu when the app times out in aboutToShow + // DBusMenuImporter::slotMenuAboutToShow(): Application did not answer to AboutToShow() before timeout + //QMetaObject::invokeMethod(importer, "updateMenu", Qt::DirectConnection); + QMetaObject::invokeMethod(importer, "updateMenu", Qt::QueuedConnection); - if (!importer) { - return; - } - - QMenu *menu = importer->menu(); - - // Window do not have menu - if (!menu) { - return; - } + /*connect(importer, &DBusMenuImporter::actionActivationRequested, this, [=](QAction *action) { + // else send request to kwin or others dbus interface registrars + m_waitingAction = action; + emit showRequest(serviceName, menuObjectPath); + });*/ - m_menu = new VerticalMenu(); - m_menu->setParentWid(id); - // Populate menu - foreach (QAction *action, menu->actions()) { - m_menu->addAction(action); - } - m_menu->popup(QPoint(x, y)); - // Activate waiting action if exist - if (m_waitingAction) { - m_menu->setActiveAction(m_waitingAction); - m_waitingAction = 0; - } - connect(m_menu, &QMenu::aboutToHide, this, &AppMenuModule::slotAboutToHide); -} + connect(importer, &KDBusMenuImporter::menuUpdated, this, [=] { + QMenu *menu = importer->menu(); + if (!menu) { + return; + } -void AppMenuModule::slotAboutToHide() -{ - if (m_menu) { - emit menuHidden(m_menu->parentWid()); - m_menu->deleteLater(); - m_menu = 0; - } -} + const auto &actions = menu->actions(); + if (actions.isEmpty()) { + return; + } -// New window registered -void AppMenuModule::slotWindowRegistered(WId id, const QString& service, const QDBusObjectPath& path) -{ - KDBusMenuImporter* importer = m_importers.take(id); - if (importer) { - delete importer; - } + m_menu = new VerticalMenu(); + m_menu->setServiceName(serviceName); + m_menu->setMenuObjectPath(menuObjectPath); - // Application already active so check if we need create menubar - if ( m_menuStyle == QLatin1String("TopMenuBar") && id == KWindowSystem::self()->activeWindow()) { - slotActiveWindowChanged(id); - } else if (m_menuStyle == QLatin1String("ButtonVertical")) { - KWindowInfo info(id, 0, NET::WM2WindowClass); - // Tell Kwin menu is available - emit menuAvailable(id); - // FIXME: https://bugs.kde.org/show_bug.cgi?id=317926 - if (info.windowClassName() != "kmix") { - getImporter(id); + for (QAction *action : actions) { + m_menu->addAction(action); } - } - // Send a signal on bus for others dbus interface registrars - emit WindowRegistered(id, service, path); -} + connect(m_menu, &QMenu::aboutToHide, this, [this, importer] { + hideMenu(); + importer->deleteLater(); + }); -// Window unregistered -void AppMenuModule::slotWindowUnregistered(WId id) -{ - KDBusMenuImporter* importer = m_importers.take(id); + //m_menuImporter->fakeUnityAboutToShow(serviceName, menuObjectPath); - // Send a signal on bus for others dbus interface registrars - emit WindowUnregistered(id); + m_menu->popup(QPoint(x, y)); - if (importer) { - delete importer; - } + emit menuShown(serviceName, menuObjectPath); -#if 0 - if (m_menubar && m_menubar->parentWid() == id) { - hideMenubar(); - } -#endif + if (m_waitingAction) { + m_menu->setActiveAction(m_waitingAction); + m_waitingAction = nullptr; + } + }); } -// Keyboard activation requested, transmit it to menu -void AppMenuModule::slotActionActivationRequested(QAction* a) +void AppMenuModule::hideMenu() { - // If we have a topmenubar, activate action -#if 0 - if (m_menubar) { - m_menubar->setActiveAction(a); - m_menubar->show(); - } else -#endif - { // else send request to kwin or others dbus interface registrars - m_waitingAction = a; - emit showRequest(KWindowSystem::self()->activeWindow()); + if (m_menu) { + emit menuHidden(m_menu->serviceName(), m_menu->menuObjectPath()); + m_menu->deleteLater(); + m_menu = nullptr; } } -// Current window change, update menubar -// See comments in slotWindowRegistered() for why we get importers here -void AppMenuModule::slotActiveWindowChanged(WId id) +void AppMenuModule::itemActivationRequested(int winId, uint action) { - KWindowInfo info(id, NET::WMWindowType); - NET::WindowTypes mask = NET::AllTypesMask; - - m_currentScreen = currentScreen(); - - if (id == 0) {// Ignore root window - return; - } else if (info.windowType(mask) & NET::Dock) { // Hide immediatly menubar for docks (krunner) - hideMenubar(); - return; - } - - if (!m_menuImporter->serviceExist(id)) { // No menu exist, check for another menu for application - WId recursiveId = m_menuImporter->recursiveMenuId(id); - if (recursiveId) { - id = recursiveId; - } - } - - KDBusMenuImporter *importer = getImporter(id); - if (!importer) { - hideMenubar(); + // our long-press Alt emits winid 0 and action 0 + // ignore "standard conforming" apps that send actual ids + if (winId != 0 || action != 0) { return; } -#if 0 - QMenu *menu = importer->menu(); - - if(menu) { - showMenuBar(menu); - m_menubar->setParentWid(id); - } else { - hideMenubar(); - } -#endif -} - -void AppMenuModule::slotShowCurrentWindowMenu() -{ - slotActiveWindowChanged(KWindowSystem::self()->activeWindow()); -} - -void AppMenuModule::slotCurrentScreenChanged() -{ - if (m_currentScreen != currentScreen()) { -#if 0 - if (m_menubar) { - m_menubar->setParentWid(0); - } -#endif - slotActiveWindowChanged(KWindowSystem::self()->activeWindow()); - } -} - -void AppMenuModule::slotBarNeedResize() -{ -#if 0 - if (m_menubar) { - m_menubar->updateSize(); - m_menubar->move(centeredMenubarPos()); - } -#endif + emit showRequest(message().service(), QDBusObjectPath(message().path())); } // reload settings void AppMenuModule::reconfigure() { - KConfig config( QStringLiteral("kdeglobals"), KConfig::FullConfig ); - KConfigGroup configGroup = config.group("Appmenu Style"); - m_menuStyle = configGroup.readEntry("Style", "InApplication"); - - m_waitingAction = 0; + m_waitingAction = nullptr; - // hide menubar if exist - hideMenubar(); -#if 0 - delete m_menubar; - m_menubar = 0; -#endif + hideMenu(); // hide window decoration menu if exists - slotAboutToHide(); // hide vertical menu if exist - - // Disconnect all options specifics signals - disconnect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, this, &AppMenuModule::slotActiveWindowChanged); - disconnect(KWindowSystem::self(), &KWindowSystem::workAreaChanged, this, &AppMenuModule::slotShowCurrentWindowMenu); - disconnect(m_screenTimer, &QTimer::timeout, this, &AppMenuModule::slotCurrentScreenChanged); - - m_screenTimer->stop(); - - // Tell kwin to clean its titlebar - emit clearMenus(); - - if (m_menuStyle == QLatin1String("InApplication")) { - if (m_menuImporter) { - delete m_menuImporter; - m_menuImporter = 0; - } + 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("InApplication")) { + delete m_menuImporter; + m_menuImporter = nullptr; return; } // Setup a menu importer if needed if (!m_menuImporter) { - m_menuImporter = new MenuImporter(m_parent); - connect(m_menuImporter, &MenuImporter::WindowRegistered, - this, &AppMenuModule::slotWindowRegistered); - connect(m_menuImporter, &MenuImporter::WindowUnregistered, - this, &AppMenuModule::slotWindowUnregistered); + m_menuImporter = new MenuImporter(this); + connect(m_menuImporter, &MenuImporter::WindowRegistered, this, &AppMenuModule::slotWindowRegistered); m_menuImporter->connectToBus(); } - - if( m_menuStyle == QLatin1String("ButtonVertical") ) { - foreach(WId id, m_menuImporter->ids()) { - emit menuAvailable(id); - } - } - - // Setup top menubar if needed - if (m_menuStyle == QLatin1String("TopMenuBar")) { -#if 0 - m_menubar = new TopMenuBar(); - connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(slotActiveWindowChanged(WId))); - connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(slotShowCurrentWindowMenu())); - connect(m_screenTimer, SIGNAL(timeout()), this, SLOT(slotCurrentScreenChanged())); - connect(m_menubar, SIGNAL(needResize()), SLOT(slotBarNeedResize())); - m_screenTimer->start(1000); - slotShowCurrentWindowMenu(); -#endif - } } -KDBusMenuImporter* AppMenuModule::getImporter(WId id) -{ - KDBusMenuImporter* importer = 0; - if (m_importers.contains(id)) { // importer already exist - importer = m_importers.value(id); - } else if (m_menuImporter->serviceExist(id)) { // get importer - importer = new KDBusMenuImporter(id, m_menuImporter->serviceForWindow(id), &m_icons, - m_menuImporter->pathForWindow(id), this); - if (importer) { - QMetaObject::invokeMethod(importer, "updateMenu", Qt::DirectConnection); - connect(importer, &DBusMenuImporter::actionActivationRequested, - this, &AppMenuModule::slotActionActivationRequested); - m_importers.insert(id, importer); - } - } - return importer; -} - -void AppMenuModule::showMenuBar(QMenu *menu) -{ -#if 0 - if (!menu) { - return; - } - - m_menubar->setMenu(menu); - if (menu->actions().length()) { - m_menubar->enableMouseTracking(); - } -#endif -} - -void AppMenuModule::hideMenubar() -{ -#if 0 - if (!m_menubar) { - return; - } - - m_menubar->enableMouseTracking(false); - if (m_menubar->isVisible()) { - m_menubar->hide(); - } -#endif -} - -int AppMenuModule::currentScreen() -{ - KWindowInfo info(KWindowSystem::self()->activeWindow(), NET::WMGeometry); - int x = info.geometry().x(); - int y = info.geometry().y(); - - QDesktopWidget *desktop = QApplication::desktop(); - return desktop->screenNumber(QPoint(x,y)); -} - - -QPoint AppMenuModule::centeredMenubarPos() -{ - QDesktopWidget *desktop = QApplication::desktop(); - m_currentScreen = currentScreen(); - QRect screen = desktop->availableGeometry(m_currentScreen); -#if 0 - int x = screen.center().x() - m_menubar->sizeHint().width()/2; - return QPoint(x, screen.topLeft().y()); -#else - return QPoint(screen.center().x(), screen.topLeft().y()); -#endif -} - - #include "appmenu.moc" diff --git a/appmenu/appmenu.h b/appmenu/appmenu.h index d4e0f42e..3dc93ff8 100644 --- a/appmenu/appmenu.h +++ b/appmenu/appmenu.h @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> + Copyright (c) 2016 Kai Uwe Broulik <kde@privat.broulik.de> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,7 +29,6 @@ #include <kdedmodule.h> #include "menuimporter.h" -#include "gtkicons.h" class QDBusPendingCallWatcher; class KDBusMenuImporter; @@ -48,107 +48,51 @@ Q_SIGNALS: /** * We do not know where is menu decoration button, so tell kwin to show menu */ - void showRequest(qulonglong); + void showRequest(const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** - * This signal is emitted whenever application menu becomes available + * This signal is emitted whenever popup menu/menubar is shown + * Useful for decorations to know if menu button should look pressed */ - void menuAvailable(qulonglong); - /** - * This signal is emitted whenever menus are unavailables - */ - void clearMenus(); + void menuShown(const QString &service, const QDBusObjectPath &objectPath); /** * This signal is emitted whenever popup menu/menubar is hidden * Useful for decorations to know if menu button should be release */ - void menuHidden(qulonglong); - /** - * This signal is emitted whenever a window register to appmenu - */ - void WindowRegistered(qulonglong wid, const QString& service, const QDBusObjectPath&); - /** - * This signal is emitted whenever a window unregister from appmenu - */ - void WindowUnregistered(qulonglong wid); + void menuHidden(const QString &service, const QDBusObjectPath &objectPath); private Q_SLOTS: /** - * Show menu at QPoint(x,y) for id - * if x or y == -1, show in application window - */ - void slotShowMenu(int x, int y, WId); - /** - * Send menuHidden signal over bus when menu is about to hide - */ - void slotAboutToHide(); - /** - * New window registered to appmenu - * Emit WindowRegistered signal over bus - */ - void slotWindowRegistered(WId id, const QString& service, const QDBusObjectPath& path); - /** - * Window unregistered from appmenu - * Emit WindowUnregistered signal over bus - */ - void slotWindowUnregistered(WId id); - /** - * Open a action in current menu - */ - void slotActionActivationRequested(QAction* a); - /** - * Active window changed, show menubar for id - */ - void slotActiveWindowChanged(WId id); - /** - * Update menubar with current window menu + * A new window was registered to AppMenu + * + * For compatibility this will set the DBus service name and menu object path as properties + * on the window so we keep working with clients that use the DBusMenu "properly". */ - void slotShowCurrentWindowMenu(); + void slotWindowRegistered(WId id, const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** - * Current screen changed, update menubar - */ - void slotCurrentScreenChanged(); - /** - * Resize menubar + * Show menu at QPoint(x,y) for DBus serviceName and menuObjectPath + * if x or y == -1, show in application window */ - void slotBarNeedResize(); + void slotShowMenu(int x, int y, const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** * Reconfigure module */ void reconfigure(); + void itemActivationRequested(int winId, uint action); + private: - /** - * return an importer for window id - */ - KDBusMenuImporter* getImporter(WId id); - /** - * Show menubar and update it with menu - */ - void showMenuBar(QMenu *menu); - /** - * Hide menubar - */ - void hideMenubar(); - /** - * Return current screen - */ - int currentScreen(); - /** - * Return position of menubar for being centered on screen - */ - QPoint centeredMenubarPos(); - - QObject* m_parent; - MenuImporter* m_menuImporter; - AppmenuDBus* m_appmenuDBus; - QHash<WId, KDBusMenuImporter*> m_importers; - GtkIcons m_icons; - QString m_menuStyle; - TopMenuBar* m_menubar; - VerticalMenu* m_menu; - QTimer* m_screenTimer; - QAction *m_waitingAction; - int m_currentScreen; + void hideMenu(); + + void fakeUnityAboutToShow(const QString &service, const QDBusObjectPath &menuObjectPath); + + KDBusMenuImporter *getImporter(const QString &service, const QString &path); + + MenuImporter *m_menuImporter = nullptr; + AppmenuDBus *m_appmenuDBus; + + VerticalMenu *m_menu = nullptr; + QAction *m_waitingAction = nullptr; + }; #endif diff --git a/appmenu/appmenu_dbus.cpp b/appmenu/appmenu_dbus.cpp index f99ac3c0..b1420a70 100644 --- a/appmenu/appmenu_dbus.cpp +++ b/appmenu/appmenu_dbus.cpp @@ -58,12 +58,12 @@ bool AppmenuDBus::connectToBus(const QString& service, const QString& path) return true; } -void AppmenuDBus::showMenu(int x, int y, WId id) +void AppmenuDBus::showMenu(int x, int y, const QString &serviceName, const QDBusObjectPath &menuObjectPath) { - emit appShowMenu(x, y, id); + emit appShowMenu(x, y, serviceName, menuObjectPath); } void AppmenuDBus::reconfigure() { - emit moduleReconfigure(); -} \ No newline at end of file + emit reconfigured(); +} diff --git a/appmenu/appmenu_dbus.h b/appmenu/appmenu_dbus.h index f9aef2f4..7102fc6a 100644 --- a/appmenu/appmenu_dbus.h +++ b/appmenu/appmenu_dbus.h @@ -46,10 +46,10 @@ public: bool connectToBus(const QString& service = QString(), const QString& path = QString()); /** - * DBus method showing menu at QPoint(x,y) for id + * DBus method showing menu at QPoint(x,y) for given DBus service name and menuObjectPath * if x or y == -1, show in application window */ - void showMenu(int x, int y, WId id); + void showMenu(int x, int y, const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** * DBus method reconfiguring kded module */ @@ -59,39 +59,28 @@ Q_SIGNALS: /** * This signal is emitted on showMenu() request */ - void appShowMenu(int x, int y, WId id); + void appShowMenu(int x, int y, const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** * This signal is emitted on reconfigure() request */ - void moduleReconfigure(); + void reconfigured(); // Dbus signals /** * This signal is emitted whenever kded want to show menu * We do not know where is menu decoration button, so tell kwin to show menu */ - void showRequest(qulonglong); + void showRequest(const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** - * This signal is emitted whenever application menu becomes available + * This signal is emitted whenever popup menu/menubar is shown + * Useful for decorations to know if menu button should look pressed */ - void menuAvailable(qulonglong); - /** - * This signal is emitted whenever menus are unavailables - */ - void clearMenus(); + void menuShown(const QString &serviceName, const QDBusObjectPath &menuObjectPath); /** * This signal is emitted whenever popup menu/menubar is hidden * Useful for decorations to know if menu button should be release */ - void menuHidden(qulonglong); - /** - * This signal is emitted whenever a window register to appmenu - */ - void WindowRegistered(qulonglong wid, const QString& service, const QDBusObjectPath&); - /** - * This signal is emitted whenever a window unregister from appmenu - */ - void WindowUnregistered(qulonglong wid); + void menuHidden(const QString &serviceName, const QDBusObjectPath &menuObjectPath); private: QString m_service; diff --git a/appmenu/glowbar.cpp b/appmenu/glowbar.cpp deleted file mode 100644 index 680c8cda..00000000 --- a/appmenu/glowbar.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "glowbar.h" - -#include <X11/extensions/shape.h> -#include <fixx11h.h> - -#include <Plasma/Svg> -#include <KWindowSystem> -#include <KDebug> - -#include <QTimer> -#include <QDebug> -#include <QPainter> -#include <QX11Info> - - -GlowBar::GlowBar() - : QWidget(0), - m_svg(new Plasma::Svg(this)) -{ - m_svg->setImagePath("widgets/glowbar"); - - setWindowFlags(Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint); - setAttribute(Qt::WA_TranslucentBackground); - setAutoFillBackground(false); - KWindowSystem::setType(winId(), NET::Dock); - - QPalette pal = palette(); - pal.setColor(backgroundRole(), Qt::transparent); - setPalette(pal); - - setInputMask(); -} - -GlowBar::~GlowBar() -{ -} - -void GlowBar::paintEvent(QPaintEvent*) -{ - QPixmap l, r, c; - QPoint pixmapPosition(0, 0); - - m_buffer.fill(QColor(0, 0, 0, int(qreal(255)*0.3))); - QPainter p(&m_buffer); - p.setCompositionMode(QPainter::CompositionMode_SourceIn); - l = m_svg->pixmap("bottomleft"); - r = m_svg->pixmap("bottomright"); - c = m_svg->pixmap("bottom"); - p.drawPixmap(pixmapPosition, l); - p.drawTiledPixmap(QRect(l.width(), pixmapPosition.y(), width() - l.width() - r.width(), c.height()), c); - p.drawPixmap(QPoint(width() - r.width(), pixmapPosition.y()), r); - p.end(); - p.begin(this); - p.drawPixmap(QPoint(0, 0), m_buffer); -} - -void GlowBar::setPixmap(const QPoint pos, uint width) -{ - QRect zone = QRect(pos, QSize(width, 10)); - setGeometry(zone); - m_buffer = QPixmap(zone.size()); -} - -void GlowBar::setInputMask() -{ - // Create an empty input mask to achieve click-through effect - // Thanks to MacSlow for this! - Pixmap mask; - - mask = XCreatePixmap(QX11Info::display(), - winId(), - 1, /* width */ - 1, /* height */ - 1 /* depth */); - XShapeCombineMask(QX11Info::display(), - winId(), - ShapeInput, - 0, /* x-offset */ - 0, /* y-offset */ - mask, - ShapeSet); - XFreePixmap(QX11Info::display(), mask); -} -#include "glowbar.moc" diff --git a/appmenu/glowbar.h b/appmenu/glowbar.h deleted file mode 100644 index 2d86fc47..00000000 --- a/appmenu/glowbar.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef GLOWBAR__H -#define GLOWBAR__H - -#include <QWidget> - -namespace Plasma -{ - class Svg; -} - -class GlowBar : public QWidget -{ -Q_OBJECT -public: - GlowBar(); - ~GlowBar(); - - void paintEvent(QPaintEvent*); - - void setPixmap(const QPoint pos, uint width); -private: - void setInputMask(); - Plasma::Svg *m_svg; - QPixmap m_buffer; -}; -#endif \ No newline at end of file diff --git a/appmenu/gtkicons.h b/appmenu/gtkicons.h deleted file mode 100644 index 9468c50f..00000000 --- a/appmenu/gtkicons.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef GTKICONS_H -#define GTKICONS_H - -#include <QtCore/QMap> - -class GtkIcons : public QMap<QString, QString> -{ - public: - GtkIcons( void ) : QMap<QString, QString> () - { - insert(QStringLiteral("gnome-fs-directory"), QStringLiteral("folder.png")); - insert(QStringLiteral("gnome-fs-regular.png"), QStringLiteral("application-x-zerosize.png")); - insert(QStringLiteral("gtk-about"), QStringLiteral("help-about.png")); - insert(QStringLiteral("gtk-add"), QStringLiteral("list-add.png")); - insert(QStringLiteral("gtk-apply"), QStringLiteral("dialog-ok-apply.png ok-apply.png apply.png")); - insert(QStringLiteral("gtk-bold"), QStringLiteral("format-text-bold.png")); - insert(QStringLiteral("gtk-cancel"), QStringLiteral("dialog-cancel.png cancel.png")); - insert(QStringLiteral("gtk-cdrom"), QStringLiteral("media-optical.png")); - insert(QStringLiteral("gtk-clear"), QStringLiteral("edit-clear.png")); - insert(QStringLiteral("gtk-close"), QStringLiteral("window-close.png")); - insert(QStringLiteral("gtk-color-picker"), QStringLiteral("color-picker.png")); - insert(QStringLiteral("gtk-connect"), QStringLiteral("network-connect.png")); - insert(QStringLiteral("gtk-convert"), QStringLiteral("document-export.png")); - insert(QStringLiteral("gtk-copy"), QStringLiteral("edit-copy.png")); - insert(QStringLiteral("gtk-cut"), QStringLiteral("edit-cut.png")); - insert(QStringLiteral("gtk-delete"), QStringLiteral("edit-delete.png")); - insert(QStringLiteral("gtk-dialog-authentication"), QStringLiteral("dialog-password.png document-encrypt.png object-locked.png")); - insert(QStringLiteral("gtk-dialog-error"), QStringLiteral("dialog-error.png")); - insert(QStringLiteral("gtk-dialog-info"), QStringLiteral("dialog-information.png")); - insert(QStringLiteral("gtk-dialog-question"), QStringLiteral("dialog-information.png")); - insert(QStringLiteral("gtk-dialog-warning"), QStringLiteral("dialog-warning.png")); - insert(QStringLiteral("gtk-directory"), QStringLiteral("folder.png")); - insert(QStringLiteral("gtk-disconnect"), QStringLiteral("network-disconnect.png")); - insert(QStringLiteral("gtk-dnd"), QStringLiteral("application-x-zerosize.png")); - insert(QStringLiteral("gtk-dnd-multiple"), QStringLiteral("document-multiple.png")); - insert(QStringLiteral("gtk-edit"), QStringLiteral("document-properties.png")); - insert(QStringLiteral("gtk-execute"), QStringLiteral("fork.png")); - insert(QStringLiteral("gtk-file"), QStringLiteral("application-x-zerosize.png")); - insert(QStringLiteral("gtk-find"), QStringLiteral("edit-find.png")); - insert(QStringLiteral("gtk-find-and-replace"), QStringLiteral("edit-find-replace.png")); - insert(QStringLiteral("gtk-floppy"), QStringLiteral("media-floppy.png")); - insert(QStringLiteral("gtk-fullscreen"), QStringLiteral("view-fullscreen.png")); - insert(QStringLiteral("gtk-goto-bottom"), QStringLiteral("go-bottom.png")); - insert(QStringLiteral("gtk-goto-first"), QStringLiteral("go-first.png")); - insert(QStringLiteral("gtk-goto-last"), QStringLiteral("go-last.png")); - insert(QStringLiteral("gtk-goto-top"), QStringLiteral("go-top.png")); - insert(QStringLiteral("gtk-go-back"), QStringLiteral("go-previous.png")); - insert(QStringLiteral("gtk-go-back-ltr"), QStringLiteral("go-previous.png")); - insert(QStringLiteral("gtk-go-back-rtl"), QStringLiteral("go-next.png")); - insert(QStringLiteral("gtk-go-down"), QStringLiteral("go-down.png")); - insert(QStringLiteral("gtk-go-forward"), QStringLiteral("go-next.png")); - insert(QStringLiteral("gtk-go-forward-ltr"), QStringLiteral("go-next.png")); - insert(QStringLiteral("gtk-go-forward-rtl"), QStringLiteral("go-previous.png")); - insert(QStringLiteral("gtk-go-up"), QStringLiteral("go-up.png")); - insert(QStringLiteral("gtk-harddisk"), QStringLiteral("drive-harddisk.png")); - insert(QStringLiteral("gtk-help"), QStringLiteral("help-contents.png")); - insert(QStringLiteral("gtk-home"), QStringLiteral("go-home.png")); - insert(QStringLiteral("gtk-indent"), QStringLiteral("format-indent-more.png")); - insert(QStringLiteral("gtk-index"), QStringLiteral("help-contents.png")); - insert(QStringLiteral("gtk-info"), QStringLiteral("help-about.png")); - insert(QStringLiteral("gtk-italic"), QStringLiteral("format-text-italic.png")); - insert(QStringLiteral("gtk-jump-to"), QStringLiteral("go-jump.png")); - insert(QStringLiteral("gtk-justify-center"), QStringLiteral("format-justify-center.png")); - insert(QStringLiteral("gtk-justify-fill"), QStringLiteral("format-justify-fill.png")); - insert(QStringLiteral("gtk-justify-left"), QStringLiteral("format-justify-left.png")); - insert(QStringLiteral("gtk-justify-right"), QStringLiteral("format-justify-right.png")); - insert(QStringLiteral("gtk-leave-fullscreen"), QStringLiteral("view-restore.png")); - insert(QStringLiteral("gtk-media-forward"), QStringLiteral("media-seek-forward.png")); - insert(QStringLiteral("gtk-media-next"), QStringLiteral("media-skip-forward.png")); - insert(QStringLiteral("gtk-media-pause"), QStringLiteral("media-playback-pause.png")); - insert(QStringLiteral("gtk-media-play"), QStringLiteral("media-playback-start.png")); - insert(QStringLiteral("gtk-media-previous"), QStringLiteral("media-skip-backward.png")); - insert(QStringLiteral("gtk-media-record"), QStringLiteral("media-record.png")); - insert(QStringLiteral("gtk-media-rewind"), QStringLiteral("media-seek-backward.png")); - insert(QStringLiteral("gtk-media-stop"), QStringLiteral("media-playback-stop.png")); - insert(QStringLiteral("gtk-missing-image"), QStringLiteral("unknown.png")); - insert(QStringLiteral("gtk-network"), QStringLiteral("network-server.png")); - insert(QStringLiteral("gtk-new"), QStringLiteral("document-new.png")); - insert(QStringLiteral("gtk-no"), QStringLiteral("edit-delete.png")); - insert(QStringLiteral("gtk-ok"), QStringLiteral("dialog-ok.png ok.png")); - insert(QStringLiteral("gtk-open"), QStringLiteral("document-open.png")); - insert(QStringLiteral("gtk-paste"), QStringLiteral("edit-paste.png")); - insert(QStringLiteral("gtk-preferences"), QStringLiteral("configure.png")); - insert(QStringLiteral("gtk-print"), QStringLiteral("document-print.png")); - insert(QStringLiteral("gtk-print-preview"), QStringLiteral("document-print-preview.png")); - insert(QStringLiteral("gtk-properties"), QStringLiteral("document-properties.png")); - insert(QStringLiteral("gtk-quit"), QStringLiteral("application-exit.png")); - insert(QStringLiteral("gtk-redo"), QStringLiteral("edit-redo.png")); - insert(QStringLiteral("gtk-refresh"), QStringLiteral("view-refresh.png")); - insert(QStringLiteral("gtk-remove"), QStringLiteral("edit-delete.png")); - insert(QStringLiteral("gtk-revert-to-saved"), QStringLiteral("document-revert.png")); - insert(QStringLiteral("gtk-save"), QStringLiteral("document-save.png")); - insert(QStringLiteral("gtk-save-as"), QStringLiteral("document-save-as.png")); - insert(QStringLiteral("gtk-select-all"), QStringLiteral("edit-select-all.png")); - insert(QStringLiteral("gtk-select-color"), QStringLiteral("color-picker.png")); - insert(QStringLiteral("gtk-select-font"), QStringLiteral("preferences-desktop-font.png")); - insert(QStringLiteral("gtk-sort-ascending"), QStringLiteral("view-sort-ascending.png")); - insert(QStringLiteral("gtk-sort-descending"), QStringLiteral("view-sort-descending.png")); - insert(QStringLiteral("gtk-spell-check"), QStringLiteral("tools-check-spelling.png")); - insert(QStringLiteral("gtk-stop"), QStringLiteral("process-stop.png")); - insert(QStringLiteral("gtk-strikethrough"), QStringLiteral("format-text-strikethrough.png")); - insert(QStringLiteral("gtk-undelete"), QStringLiteral("edit-undo.png")); - insert(QStringLiteral("gtk-underline"), QStringLiteral("format-text-underline.png")); - insert(QStringLiteral("gtk-undo"), QStringLiteral("edit-undo.png")); - insert(QStringLiteral("gtk-unindent"), QStringLiteral("format-indent-less.png")); - insert(QStringLiteral("gtk-yes"), QStringLiteral("dialog-ok.png ok.png")); - insert(QStringLiteral("gtk-zoom-100"), QStringLiteral("zoom-original.png")); - insert(QStringLiteral("gtk-zoom-fit"), QStringLiteral("zoom-fit-best.png")); - insert(QStringLiteral("gtk-zoom-in"), QStringLiteral("zoom-in.png")); - insert(QStringLiteral("gtk-zoom-out"), QStringLiteral("zoom-out.png")); - insert(QStringLiteral("stock_edit-bookmark"), QStringLiteral("bookmarks-organize.png")); - insert(QStringLiteral("gimp-edit"), QStringLiteral("edit.png")); - insert(QStringLiteral("gimp-info"), QStringLiteral("dialog-information.png")); - insert(QStringLiteral("gimp-reset"), QStringLiteral("reload.png")); - insert(QStringLiteral("gimp-warning"), QStringLiteral("dialog-warning.png")); - insert(QStringLiteral("gimp-tool-options"), QStringLiteral("tool.png")); - insert(QStringLiteral("gimp-images"), QStringLiteral("image.png")); - } -}; - -#endif // GTKICONS_H \ No newline at end of file diff --git a/appmenu/kdbusimporter.h b/appmenu/kdbusimporter.h index 8c50c6e2..f5dd65fe 100644 --- a/appmenu/kdbusimporter.h +++ b/appmenu/kdbusimporter.h @@ -26,49 +26,25 @@ #ifndef KDBUSMENUIMPORTER_H #define KDBUSMENUIMPORTER_H -#include "gtkicons.h" - -#include <KIcon> -#include <KIconLoader> - -#include <QDBusArgument> - #include <dbusmenuimporter.h> +#include <QIcon> + class KDBusMenuImporter : public DBusMenuImporter { public: - KDBusMenuImporter(WId wid, const QString &service, GtkIcons *icons, const QString &path, QObject *parent) - : DBusMenuImporter(service, path, parent) - , m_service(service) - , m_path(path) - , m_WId(wid) + KDBusMenuImporter(const QString &service, const QString &path, QObject *parent) + : DBusMenuImporter(service, path, ASYNCHRONOUS, parent) { - m_icons = icons; - } - QString service() const { return m_service; } - QString path() const { return m_path; } - WId wid() const { return m_WId; } + } protected: - QIcon iconForName(const QString &name) - override { - if(m_icons->contains(name)){ - return QIcon::fromTheme(m_icons->value(name)); - } - else if(!KIconLoader::global()->iconPath(name, 1, true ).isNull()){ - return QIcon::fromTheme(name); - } - return QIcon(); + QIcon iconForName(const QString &name) override { + return QIcon::fromTheme(name); } -private: - GtkIcons *m_icons; - QString m_service; - QString m_path; - WId m_WId; }; -#endif //KDBUSMENUIMPORTER_H \ No newline at end of file +#endif //KDBUSMENUIMPORTER_H diff --git a/appmenu/menubar.cpp b/appmenu/menubar.cpp deleted file mode 100644 index 4c20e201..00000000 --- a/appmenu/menubar.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "menubar.h" -#include "shadows.h" - -#include <QGraphicsLinearLayout> -#include <QPainter> -#include <QMenu> -#include <QDesktopWidget> -#include <QGraphicsDropShadowEffect> - -#include <KWindowSystem> -#include <Plasma/FrameSvg> -#include <Plasma/Theme> -#include <Plasma/WindowEffects> -#include <KApplication> - -MenuBar::MenuBar() - : QGraphicsView(), - m_hideTimer(new QTimer(this)), - m_background(new Plasma::FrameSvg(this)), - m_shadows(new Shadows(this)), - m_scene(new QGraphicsScene(this)), - m_container(new MenuWidget(this)) -{ - qreal left, top, right, bottom; - - //Setup the window properties - setWindowFlags(Qt::Tool|Qt::X11BypassWindowManagerHint|Qt::WindowStaysOnTopHint); - setAttribute(Qt::WA_TranslucentBackground); - KWindowSystem::setType(winId(), NET::Dock); - setFrameStyle(QFrame::NoFrame); - viewport()->setAutoFillBackground(false); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - //Setup the widgets - m_background->setImagePath("widgets/tooltip"); - m_background->setEnabledBorders(Plasma::FrameSvg::BottomBorder|Plasma::FrameSvg::LeftBorder|Plasma::FrameSvg::RightBorder); - - m_container->initLayout(); - - m_scene->addItem(m_container); - - setScene(m_scene); - - m_background->getMargins(left, top, right, bottom); - m_container->layout()->setContentsMargins(left, top, right, bottom); - - resize(sizeHint()); - - connect(m_container, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); - connect(m_container, SIGNAL(needResize()), this, SIGNAL(needResize())); - connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(slotAboutToHide())); - - connect(KWindowSystem::self(), SIGNAL(compositingChanged(bool)), this, SLOT(slotCompositingChanged(bool))); -} - -MenuBar::~MenuBar() -{ -} - -QSize MenuBar::sizeHint() const -{ - QSizeF size = m_container->minimumSize(); - return QSize(size.width(), size.height() - m_container->contentBottomMargin()); -} - -void MenuBar::show() -{ - // Add shadow for better readability - if (! Plasma::WindowEffects::isEffectAvailable(Plasma::WindowEffects::BlurBehind)) { - QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(); - shadow->setBlurRadius(5); - shadow->setOffset(QPointF(1, 1)); - shadow->setColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); - setGraphicsEffect(shadow); - } else { - setGraphicsEffect(0); - } - m_hideTimer->start(1000); - QGraphicsView::show(); - -} - -void MenuBar::hide() -{ - emit aboutToHide(); - m_hideTimer->stop(); - QGraphicsView::hide(); -} - -void MenuBar::slotAboutToHide() -{ - if (m_container->aMenuIsVisible()) { // MenuBar::m_hideTimer - m_hideTimer->stop(); // menu is visible, menubar will be hidden by another aboutToHide() signal - } - else if (!cursorInMenuBar()) { //MenuWidget::AboutToHide signal - hide(); - } else if (!m_hideTimer->isActive()){ //use click on menubar button while a popup was shown - m_hideTimer->start(1000); - } -} - -void MenuBar::slotCompositingChanged(bool) -{ - updateMask(); -} - -bool MenuBar::cursorInMenuBar() -{ - return QRect(pos(), size()).contains(QCursor::pos()); -} - -void MenuBar::drawBackground(QPainter *painter, const QRectF &/*rectF*/) -{ - painter->save(); - painter->setCompositionMode(QPainter::CompositionMode_Source); - m_background->paintFrame(painter); - painter->restore(); -} - -void MenuBar::resizeEvent(QResizeEvent*) -{ - m_background->resizeFrame(size()); - m_scene->setSceneRect(0, 0, width(), height()); - updateMask(); -} - -void MenuBar::updateMask() -{ - // Enable the mask only when compositing is disabled; - // As this operation is quite slow, it would be nice to find some - // way to workaround it for no-compositing users. - if (KWindowSystem::compositingActive()) { - clearMask(); - Plasma::WindowEffects::overrideShadow(winId(), true); - Plasma::WindowEffects::enableBlurBehind(winId(), true, m_background->mask()); - m_shadows->addWindow(this, Plasma::FrameSvg::BottomBorder|Plasma::FrameSvg::LeftBorder|Plasma::FrameSvg::RightBorder); - } else { - setMask(m_background->mask()); - } -} \ No newline at end of file diff --git a/appmenu/menubar.h b/appmenu/menubar.h deleted file mode 100644 index 69ca1ebe..00000000 --- a/appmenu/menubar.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef MENUBAR__H -#define MENUBAR__H - -#include "menuwidget.h" - -#include <QGraphicsView> - -class QMenu; -class Shadows; - -namespace Plasma -{ - class FrameSvg; -} - -class MenuBar : public QGraphicsView -{ -Q_OBJECT -public: - MenuBar(); - ~MenuBar(); - - /** - * Set root menu - */ - void setMenu(QMenu *menu) { m_container->setMenu(menu); } - /** - * Auto open menu items on mouse over - */ - void autoOpen() { m_container->autoOpen(); } - /** - * Set action as active menubar action - */ - void setActiveAction(QAction *action) { m_container->setActiveAction(action); } - - virtual QSize sizeHint() const; - virtual void show(); - virtual void hide(); - -private Q_SLOTS: - void slotAboutToHide(); - void slotCompositingChanged(bool); -Q_SIGNALS: - void needResize(); - void aboutToHide(); -protected: - /** - * Return true if cursor in menubar - */ - virtual bool cursorInMenuBar(); - virtual void drawBackground(QPainter* painter, const QRectF &rectF); - virtual void resizeEvent(QResizeEvent* event); -private: - void updateMask(); - QTimer* m_hideTimer; - Plasma::FrameSvg* m_background; - Shadows *m_shadows; - QGraphicsScene* m_scene; - MenuWidget* m_container; -}; - -#endif diff --git a/appmenu/menubutton.cpp b/appmenu/menubutton.cpp deleted file mode 100644 index 10c143a3..00000000 --- a/appmenu/menubutton.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "menubutton.h" - -#include <QAction> -#include <QMenu> -#include <QGraphicsDropShadowEffect> - -#include <Plasma/Theme> - -MenuButton::MenuButton(QGraphicsWidget *parent): - Plasma::ToolButton(parent), - m_enterEvent(false), - m_menu(0) -{ - QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(); - shadow->setBlurRadius(5); - shadow->setOffset(QPointF(1, 1)); - shadow->setColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); - setGraphicsEffect(shadow); -} - -void MenuButton::setHovered(bool hovered) -{ - if (hovered) { - hoverEnterEvent(0); - } else { - hoverLeaveEvent(0); - } -} - -QSizeF MenuButton::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const -{ - QSizeF sh = Plasma::ToolButton::sizeHint(which, constraint); - if (which == Qt::MinimumSize || which == Qt::PreferredSize) { - sh.setHeight(nativeWidget()->fontMetrics().height() + bottomMargin()); - } - return sh; -} - -qreal MenuButton::bottomMargin() const -{ - qreal left, right, top, bottom; - getContentsMargins(&left, &right, &top, &bottom); - return bottom; -} - -void MenuButton::hoverEnterEvent(QGraphicsSceneHoverEvent *e) -{ - m_enterEvent = true; - Plasma::ToolButton::hoverEnterEvent(e); -} - -void MenuButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) -{ - if (m_enterEvent) { - m_enterEvent = false; - Plasma::ToolButton::hoverLeaveEvent(e); - } -} - -#include "menubutton.moc" \ No newline at end of file diff --git a/appmenu/menubutton.h b/appmenu/menubutton.h deleted file mode 100644 index a7702dcf..00000000 --- a/appmenu/menubutton.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef MENUBUTTON__H -#define MENUBUTTON__H - -#include <Plasma/ToolButton> -#include <QToolButton> - -class QMenu; - -class MenuButton : public Plasma::ToolButton -{ -Q_OBJECT -public: - MenuButton(QGraphicsWidget *parent); - - void setHovered(bool hovered); - - QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const; - qreal bottomMargin() const; - - void setMenu(QMenu *menu) { m_menu = menu; } - QMenu* menu() { return m_menu; } -protected: - void hoverEnterEvent(QGraphicsSceneHoverEvent *); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *); -private: - bool m_enterEvent; - QMenu *m_menu; -}; -#endif diff --git a/appmenu/menuimporter.cpp b/appmenu/menuimporter.cpp index c1492f46..319c8f0b 100644 --- a/appmenu/menuimporter.cpp +++ b/appmenu/menuimporter.cpp @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> + Copyright (c) 2016 Kai Uwe Broulik <kde@privat.broulik.de> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,12 +27,10 @@ #include "menuimporter.h" #include "menuimporteradaptor.h" -#include <QApplication> #include <QDBusMessage> #include <QDBusObjectPath> #include <QDBusServiceWatcher> -#include <KDebug> #include <KWindowSystem> #include <KWindowInfo> @@ -80,14 +79,14 @@ MenuImporter::MenuImporter(QObject* parent) m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &MenuImporter::slotServiceUnregistered); - QDBusConnection::sessionBus().connect(QLatin1String(""), QLatin1String(""), QStringLiteral("com.canonical.dbusmenu"), QStringLiteral("LayoutUpdated"), + QDBusConnection::sessionBus().connect(QString(), QString(), QStringLiteral("com.canonical.dbusmenu"), QStringLiteral("LayoutUpdated"), this, SLOT(slotLayoutUpdated(uint,int))); } MenuImporter::~MenuImporter() { QDBusConnection::sessionBus().unregisterService(DBUS_SERVICE); - QDBusConnection::sessionBus().disconnect(QLatin1String(""), QLatin1String(""), QStringLiteral("com.canonical.dbusmenu"), QStringLiteral("LayoutUpdated"), + QDBusConnection::sessionBus().disconnect(QString(), QString(), QStringLiteral("com.canonical.dbusmenu"), QStringLiteral("LayoutUpdated"), this, SLOT(slotLayoutUpdated(uint,int))); } @@ -102,36 +101,6 @@ bool MenuImporter::connectToBus() return true; } -WId MenuImporter::recursiveMenuId(WId id) -{ - KWindowInfo info(id, 0, NET::WM2WindowClass); - QString classClass = info.windowClassClass(); - WId classId = 0; - - // First look at transient windows - WId tid = KWindowSystem::transientFor(id); - while (tid) { - if (serviceExist(tid)) { - classId = tid; - break; - } - tid = KWindowSystem::transientFor(tid); - } - - if (classId == 0) { - // Look at friends windows - QHashIterator<WId, QString> i(m_windowClasses); - while (i.hasNext()) { - i.next(); - if (i.value() == classClass) { - classId = i.key(); - } - } - } - - return classId; -} - void MenuImporter::RegisterWindow(WId id, const QDBusObjectPath& path) { KWindowInfo info(id, NET::WMWindowType, NET::WM2WindowClass); @@ -151,9 +120,11 @@ void MenuImporter::RegisterWindow(WId id, const QDBusObjectPath& path) m_windowClasses.insert(id, classClass); m_menuServices.insert(id, service); m_menuPaths.insert(id, path); - if (! m_serviceWatcher->watchedServices().contains(service)) { + + if (!m_serviceWatcher->watchedServices().contains(service)) { m_serviceWatcher->addWatchedService(service); } + emit WindowRegistered(id, service, path); } @@ -190,37 +161,32 @@ void MenuImporter::slotLayoutUpdated(uint /*revision*/, int parentId) // See: https://bugs.launchpad.net/plasma-idget-menubar/+bug/878165 if (parentId == 0) { //root menu - fakeUnityAboutToShow(); + fakeUnityAboutToShow(message().service(), QDBusObjectPath(message().path())); } } -void MenuImporter::fakeUnityAboutToShow() -{ - QDBusInterface iface(message().service(), message().path(), QStringLiteral("com.canonical.dbusmenu")); - QDBusPendingCall call = iface.asyncCall(QStringLiteral("GetLayout"), 0, 1, QStringList()); - QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(call, this); - watcher->setProperty("service", message().service()); - watcher->setProperty("path", message().path()); - connect(watcher, &QDBusPendingCallWatcher::finished, - this, &MenuImporter::finishFakeUnityAboutToShow); -} - -void MenuImporter::finishFakeUnityAboutToShow(QDBusPendingCallWatcher* watcher) +void MenuImporter::fakeUnityAboutToShow(const QString &service, const QDBusObjectPath &menuObjectPath) { - QDBusPendingReply<uint, DBusMenuLayoutItem> reply = *watcher; - if (reply.isError()) { - kWarning() << "Call to GetLayout failed:" << reply.error().message(); + QDBusMessage msg = QDBusMessage::createMethodCall(service, menuObjectPath.path(), + QStringLiteral("com.canonical.dbusmenu"), + QStringLiteral("GetLayout")); + msg.setArguments({0, 1, QStringList()}); + + QDBusPendingReply<uint, DBusMenuLayoutItem> reply = QDBusConnection::sessionBus().asyncCall(msg); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<uint, DBusMenuLayoutItem> reply = *watcher; + if (reply.isError()) { + qWarning() << "Call to GetLayout failed:" << reply.error().message(); + } else { + const DBusMenuLayoutItem &root = reply.argumentAt<1>(); + + for (const auto &item : root.children) { + QDBusMessage msg = QDBusMessage::createMethodCall(service, menuObjectPath.path(), QStringLiteral("com.canonical.dbusmenu"), QStringLiteral("AboutToShow")); + msg.setArguments({item.id}); + QDBusConnection::sessionBus().asyncCall(msg); + } + } watcher->deleteLater(); - return; - } - QString service = watcher->property("service").toString(); - QString path = watcher->property("path").toString(); - DBusMenuLayoutItem root = reply.argumentAt<1>(); - - watcher->deleteLater(); - - QDBusInterface iface(service, path, QStringLiteral("com.canonical.dbusmenu")); - Q_FOREACH(const DBusMenuLayoutItem& dbusMenuItem, root.children) { - iface.asyncCall(QStringLiteral("AboutToShow"), dbusMenuItem.id); - } + }); } diff --git a/appmenu/menuimporter.h b/appmenu/menuimporter.h index a4b4bbf0..d8d104e6 100644 --- a/appmenu/menuimporter.h +++ b/appmenu/menuimporter.h @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> + Copyright (c) 2016 Kai Uwe Broulik <kde@privat.broulik.de> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,6 +28,7 @@ #define MENUIMPORTER_H // Qt +#include <QDBusArgument> #include <QDBusContext> #include <QDBusObjectPath> #include <QObject> @@ -67,10 +69,7 @@ public: QList<WId> ids() { return m_menuServices.keys(); } - /** - * Return id of first transient/friend window with a menu available - */ - WId recursiveMenuId(WId id); + void fakeUnityAboutToShow(const QString &service, const QDBusObjectPath &menuObjectPath); Q_SIGNALS: void WindowRegistered(WId id, const QString& service, const QDBusObjectPath&); @@ -84,7 +83,6 @@ public Q_SLOTS: private Q_SLOTS: void slotServiceUnregistered(const QString& service); void slotLayoutUpdated(uint revision, int parentId); - void finishFakeUnityAboutToShow(QDBusPendingCallWatcher*); private: QDBusServiceWatcher* m_serviceWatcher; @@ -92,7 +90,6 @@ private: QHash<WId, QDBusObjectPath> m_menuPaths; QHash<WId, QString> m_windowClasses; - void fakeUnityAboutToShow(); }; #endif /* MENUIMPORTER_H */ diff --git a/appmenu/menuwidget.cpp b/appmenu/menuwidget.cpp deleted file mode 100644 index 0a3b4f2a..00000000 --- a/appmenu/menuwidget.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "menuwidget.h" - -#include <QMenu> -#include <QDesktopWidget> -#include <QGraphicsView> -#include <QGraphicsLinearLayout> - -#include <KWindowSystem> -#include <KDebug> -#include <KApplication> - -MenuWidget::MenuWidget(QGraphicsView *view) : - QGraphicsWidget(), - m_mouseTimer(new QTimer(this)), - m_actionTimer(new QTimer(this)), - m_view(view), - m_layout(new QGraphicsLinearLayout(this)), - m_currentButton(0), - m_contentBottomMargin(0), - m_mousePosition(-1, -1), - m_visibleMenu(0), - m_menu(0) -{ - connect(m_actionTimer, SIGNAL(timeout()), SLOT(slotUpdateActions())); - connect(m_mouseTimer, SIGNAL(timeout()), SLOT(slotCheckActiveItem())); -} - -MenuWidget::~MenuWidget() -{ - while (!m_buttons.isEmpty()) { - delete m_buttons.front(); - m_buttons.pop_front(); - } -} - -void MenuWidget::setMenu(QMenu *menu) -{ - if (m_menu) { - disconnect(m_menu, SIGNAL(destroyed()), this, SLOT(slotMenuDestroyed())); - m_menu->removeEventFilter(this); - } - if (menu) { - if (m_mouseTimer->isActive()) { - m_mouseTimer->stop(); - } - m_visibleMenu = 0; - m_menu = menu; - connect(m_menu, SIGNAL(destroyed()), SLOT(slotMenuDestroyed()), Qt::UniqueConnection); - m_menu->installEventFilter(this); - slotUpdateActions(); - } -} - -void MenuWidget::initLayout() -{ - MenuButton* button = 0; - - if (!m_menu) { - return; - } - - foreach (QAction* action, m_menu->actions()) - { - button = createButton(action); - if (button) { - m_layout->addItem(button); - button->setMenu(action->menu()); - m_buttons << button; - } - } - - //Assume all buttons have same margins - if (button) { - m_contentBottomMargin = button->bottomMargin(); - } -} - -bool MenuWidget::eventFilter(QObject* object, QEvent* event) -{ - bool filtered; - if (object == m_menu) { - filtered = menuEventFilter(event); - } else { - filtered = subMenuEventFilter(static_cast<QMenu*>(object), event); - } - return filtered ? true : QGraphicsWidget::eventFilter(object, event); -} - -bool MenuWidget::menuEventFilter(QEvent* event) -{ - switch (event->type()) { - case QEvent::ActionAdded: - case QEvent::ActionRemoved: - case QEvent::ActionChanged: - // Try to limit layout updates - m_actionTimer->start(500); - break; - default: - break; - } - return false; -} - -bool MenuWidget::subMenuEventFilter(QObject* object, QEvent* event) -{ - QMenu *menu = static_cast<QMenu*>(object); - - if (event->type() == QEvent::KeyPress) { - menu->removeEventFilter(this); - QApplication::sendEvent(menu, event); - menu->installEventFilter(this); - if (!event->isAccepted()) { - QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); - switch (keyEvent->key()) { - case Qt::Key_Left: - showLeftRightMenu(false); - break; - case Qt::Key_Right: - showLeftRightMenu(true); - break; - case Qt::Key_Escape: - menu->hide(); - break; - default: - break; - } - } - return true; - } - return false; -} - -void MenuWidget::slotMenuDestroyed() -{ - m_menu = 0; - m_visibleMenu = 0; - m_currentButton = 0; -} - -void MenuWidget::slotCheckActiveItem() -{ - MenuButton* buttonBelow = 0; - QPoint pos = m_view->mapFromGlobal(QCursor::pos()); - QGraphicsItem* item = m_view->itemAt(pos); - - if (pos == m_mousePosition) { - return; - } else { - m_mousePosition = pos; - } - - if (item) { - buttonBelow = qobject_cast<MenuButton*>(item->toGraphicsObject()); - } - - if (!buttonBelow) { - return; - } - - if (buttonBelow != m_currentButton) { - if (m_currentButton && m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(false); - m_currentButton->setHovered(false); - } - m_currentButton = buttonBelow; - if (m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(true); - } - m_visibleMenu = showMenu(); - } -} - -void MenuWidget::slotMenuAboutToHide() -{ - if (m_currentButton && m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(false); - } - - if (m_mouseTimer->isActive()) { - m_mouseTimer->stop(); - } - m_visibleMenu = 0; - emit aboutToHide(); -} - -void MenuWidget::slotButtonClicked() -{ - m_currentButton = qobject_cast<MenuButton*>(sender()); - - if (m_currentButton && m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(true); - } - m_visibleMenu = showMenu(); - // Start auto navigation after click - if (!m_mouseTimer->isActive()) - m_mouseTimer->start(100); -} - -void MenuWidget::slotUpdateActions() -{ - if (m_visibleMenu) { - return; // Later - } - - m_actionTimer->stop(); - m_currentButton = 0; - foreach (MenuButton *button, m_buttons) { - disconnect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked())); - m_layout->removeItem(button); - button->hide(); - m_buttons.removeOne(button); - delete button; - } - initLayout(); - // Menu may be empty on application startup - // slotUpdateActions will be called later by eventFilter() - if (m_menu && m_menu->actions().length()) { - emit needResize(); - } -} - -void MenuWidget::setActiveAction(QAction *action) -{ - if (!m_menu) { - return; - } - - m_currentButton = m_buttons.first(); - - if (action) { - QMenu *menu; - int i = 0; - foreach (MenuButton *button, m_buttons) { - menu = m_menu->actions()[i]->menu(); - if (menu && menu == action->menu()) { - m_currentButton = button; - break; - } - if (++i >= m_menu->actions().length()) { - break; - } - } - } - m_currentButton->nativeWidget()->animateClick(); -} - -void MenuWidget::hide() -{ - if (m_mouseTimer->isActive()) { - m_mouseTimer->stop(); - } - QGraphicsWidget::hide(); -} - -MenuButton* MenuWidget::createButton(QAction *action) -{ - if( action->isSeparator() || !action->menu() || !action->isVisible()) { - return 0; - } - - action->setShortcut(QKeySequence()); - MenuButton *button = new MenuButton(this); - button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); - button->setText(action->text()); - connect(button, SIGNAL(clicked()), SLOT(slotButtonClicked())); - return button; -} - -QMenu* MenuWidget::showMenu() -{ - QMenu *menu = 0; - - if (m_visibleMenu) { - disconnect(m_visibleMenu, SIGNAL(aboutToHide()), this, SLOT(slotMenuAboutToHide())); - m_visibleMenu->hide(); - } - - if (m_currentButton && m_menu) { - menu = m_currentButton->menu(); - } - - // Last chance to get menu - // Some applications like Firefox have empties menus on layout updates - // They should populate this menu later but in fact, they use another object - // So, we check here directly the button name, may fail with menubar with buttons with same name (test apps) - if (menu && menu->actions().length() == 0) { - foreach (QAction *action, m_menu->actions()) { - if (action->text() == m_currentButton->text()) { - menu = action->menu(); - break; - } - } - } - - if (menu) { - QPoint globalPos = m_view->mapToGlobal(QPoint(0,0)); - QPointF parentPos = m_currentButton->mapFromParent(QPoint(0,0)); - QRect screen = KApplication::desktop()->screenGeometry(); - int x = globalPos.x() - parentPos.x(); - int y = globalPos.y() + m_currentButton->size().height() - parentPos.y(); - - menu->popup(QPoint(x, y)); - - // Fix offscreen menu - if (menu->size().height() + y > screen.height() + screen.y()) { - y = globalPos.y() - parentPos.y() - menu->size().height(); - if (menu->size().width() + x > screen.width() + screen.x()) - x = screen.width() + screen.x() - menu->size().width(); - else if (menu->size().width() + x < screen.x()) - x = screen.x(); - menu->move(x, y); - } - - connect(menu, SIGNAL(aboutToHide()), this, SLOT(slotMenuAboutToHide())); - - installEventFilterForAll(menu, this); - } - return menu; -} - -void MenuWidget::showLeftRightMenu(bool next) -{ - if (!m_currentButton) { - return; - } - - int index = m_buttons.indexOf(m_currentButton); - if (index == -1) { - kWarning() << "Couldn't find button!"; - return; - } - if (next) { - index = (index + 1) % m_buttons.count(); - } else { - index = (index == 0 ? m_buttons.count() : index) - 1; - } - - if (m_currentButton && m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(false); - } - m_currentButton = m_buttons.at(index); - if (m_currentButton && m_currentButton->nativeWidget()) { - m_currentButton->nativeWidget()->setDown(true); - } - m_visibleMenu = showMenu(); -} - -void MenuWidget::installEventFilterForAll(QMenu *menu, QObject *object) -{ - if (!menu) { - return; - } - - menu->installEventFilter(this); - - foreach (QAction *action, menu->actions()) { - if (action->menu()) - installEventFilterForAll(action->menu(), object); - } -} - -#include "menuwidget.moc" \ No newline at end of file diff --git a/appmenu/menuwidget.h b/appmenu/menuwidget.h deleted file mode 100644 index 1f47a83a..00000000 --- a/appmenu/menuwidget.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef MENUWIDGET__H -#define MENUWIDGET__H - -#include "menubutton.h" - -#include <QGraphicsWidget> -#include <QTimer> - -class QGraphicsLinearLayout; -class QGraphicsView; - -class MenuWidget : public QGraphicsWidget -{ -Q_OBJECT -public: - MenuWidget(QGraphicsView *view = 0); - ~MenuWidget(); - - /** - * Set root menu - */ - void setMenu(QMenu *menu); - /** - * Init layout with root menu - */ - void initLayout(); - /** - * True if a menu is visible in menuwidget - */ - bool aMenuIsVisible() { return m_visibleMenu; } - /** - * Activate action, or first action if null - */ - void setActiveAction(QAction *action); - - /** - * Auto open menu items on mouse over - */ - void autoOpen() { m_mouseTimer->start(100); } - - /** - * Return content bottom margin - */ - qreal contentBottomMargin() { return m_contentBottomMargin; } - - void hide(); - -protected: - /** - * Use to get keyboard events - */ - virtual bool eventFilter(QObject*, QEvent*); - /** - * Filter events on main menu - */ - bool menuEventFilter(QEvent* event); - /** - * Filter events on submenus - */ - bool subMenuEventFilter(QObject* object, QEvent* event); -private Q_SLOTS: - /** - * Clean menu if destroyed - */ - void slotMenuDestroyed(); - /** - * Check hovered item and active it - */ - void slotCheckActiveItem(); - /** - * A menu is hidding - */ - void slotMenuAboutToHide(); - /** - * Menubar button clicked - */ - void slotButtonClicked(); - /** - * Update pending actions - */ - void slotUpdateActions(); -Q_SIGNALS: - void needResize(); - void aboutToHide(); -private: - /** - * Return a button based on action - */ - MenuButton* createButton(QAction *action); - /** - * Show current button menu - * return showed menu - */ - QMenu* showMenu(); - /** - * Show next menu if next, otherwise previous - */ - void showLeftRightMenu(bool next); - /** - * Install event filter for menu and it submenus - */ - void installEventFilterForAll(QMenu *menu, QObject *object); - - //Follow mouse position - QTimer *m_mouseTimer; - //Update actions - QTimer *m_actionTimer; - QGraphicsView *m_view; - QGraphicsLinearLayout *m_layout; - QList<MenuButton*> m_buttons; - MenuButton *m_currentButton; - qreal m_contentBottomMargin; - QPoint m_mousePosition; - QMenu *m_visibleMenu; - QMenu *m_menu; -}; - -#endif //MENUWIDGET__H diff --git a/appmenu/org.kde.kappmenu.xml b/appmenu/org.kde.kappmenu.xml index fba39a0f..3efdc111 100644 --- a/appmenu/org.kde.kappmenu.xml +++ b/appmenu/org.kde.kappmenu.xml @@ -4,28 +4,23 @@ <method name="showMenu"> <arg name="x" type="i" direction="in"/> <arg name="y" type="i" direction="in"/> - <arg name="WId" type="t" direction="in"/> + <arg name="service" type="s" direction="in"/> + <arg name="objectPath" type="o" direction="in"/> </method> <method name="reconfigure"> </method> + <signal name="reconfigured" /> <signal name="showRequest"> - <arg name="WId" type="t"/> - </signal> - <signal name="menuAvailable"> - <arg name="WId" type="t"/> + <arg name="service" type="s" direction="out"/> + <arg name="objectPath" type="o" direction="out"/> </signal> - <signal name="clearMenus"> + <signal name="menuShown"> + <arg name="service" type="s" direction="out"/> + <arg name="objectPath" type="o" direction="out"/> </signal> <signal name="menuHidden"> - <arg name="WId" type="t"/> - </signal> - <signal name="WindowRegistered"> - <arg name="windowId" type="t" direction="out"/> <arg name="service" type="s" direction="out"/> - <arg name="menuObjectPath" type="o" direction="out"/> - </signal> - <signal name="WindowUnregistered"> - <arg name="windowId" type="t" direction="out"/> + <arg name="objectPath" type="o" direction="out"/> </signal> </interface> </node> diff --git a/appmenu/shadows.cpp b/appmenu/shadows.cpp deleted file mode 100644 index bcf27d9d..00000000 --- a/appmenu/shadows.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* -* Copyright 2011 by Aaron Seigo <aseigo@kde.org> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU Library General Public License version 2, -* or (at your option) any later version. -* -* This program 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 General Public License for more details -* -* You should have received a copy of the GNU Library General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "shadows.h" - -#include <QWidget> -#include <QPainter> - -#ifdef Q_WS_X11 -#include <QX11Info> -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <fixx11h.h> -#endif - -#include <kdebug.h> -#include <kglobal.h> - -class Shadows::Private -{ -public: - Private(Shadows *shadows) - : q(shadows), - m_managePixmaps(false) - { - } - - ~Private() - { - clearPixmaps(); - } - - void clearPixmaps(); - void setupPixmaps(); - void initPixmap(const QString &element); - QPixmap initEmptyPixmap(const QSize &size); - void updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders); - void clearShadow(const QWidget *window); - void updateShadows(); - void windowDestroyed(QObject *deletedObject); - void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders); - - Shadows *q; - QList<QPixmap> m_shadowPixmaps; - - QPixmap m_emptyCornerPix; - QPixmap m_emptyCornerLeftPix; - QPixmap m_emptyCornerTopPix; - QPixmap m_emptyCornerRightPix; - QPixmap m_emptyCornerBottomPix; - QPixmap m_emptyVerticalPix; - QPixmap m_emptyHorizontalPix; - - QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long> > data; - QHash<const QWidget *, Plasma::FrameSvg::EnabledBorders> m_windows; - bool m_managePixmaps; -}; - -class ShadowsSingleton -{ -public: - ShadowsSingleton() - { - } - - Shadows self; -}; - -K_GLOBAL_STATIC(ShadowsSingleton, privateShadowsSelf) - -Shadows::Shadows(QObject *parent, const QString &prefix) - : Plasma::Svg(parent), - d(new Private(this)) -{ - setImagePath(prefix); - connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows())); -} - -Shadows *Shadows::self() -{ - return &privateShadowsSelf->self; -} - -void Shadows::addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders) -{ - if (!window || !window->isWindow()) { - return; - } - - d->m_windows[window] = enabledBorders; - d->updateShadow(window, enabledBorders); - connect(window, SIGNAL(destroyed(QObject*)), - this, SLOT(windowDestroyed(QObject*)), Qt::UniqueConnection); -} - -void Shadows::removeWindow(const QWidget *window) -{ - if (!d->m_windows.contains(window)) { - return; - } - - d->m_windows.remove(window); - disconnect(window, 0, this, 0); - d->clearShadow(window); - - if (d->m_windows.isEmpty()) { - d->clearPixmaps(); - } -} - -void Shadows::Private::windowDestroyed(QObject *deletedObject) -{ - m_windows.remove(static_cast<QWidget *>(deletedObject)); - - if (m_windows.isEmpty()) { - clearPixmaps(); - } -} - -void Shadows::Private::updateShadows() -{ - setupPixmaps(); - QHash<const QWidget *, Plasma::FrameSvg::EnabledBorders>::const_iterator i; - for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) { - updateShadow(i.key(), i.value()); - } -} - -void Shadows::Private::initPixmap(const QString &element) -{ -#ifdef Q_WS_X11 - QPixmap pix = q->pixmap(element); - if (!pix.isNull() && pix.handle() == 0) { - Pixmap xPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), pix.width(), pix.height(), 32); - QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared); - tempPix.fill(Qt::transparent); - QPainter p(&tempPix); - p.drawPixmap(QPoint(0, 0), pix); - m_shadowPixmaps << tempPix; - m_managePixmaps = true; - } else { - m_shadowPixmaps << pix; - } -#endif -} - -QPixmap Shadows::Private::initEmptyPixmap(const QSize &size) -{ - Pixmap emptyXPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), size.width(), size.height(), 32); - QPixmap tempEmptyPix = QPixmap::fromX11Pixmap(emptyXPix, QPixmap::ExplicitlyShared); - tempEmptyPix.fill(Qt::transparent); - return tempEmptyPix; -} - -void Shadows::Private::setupPixmaps() -{ - clearPixmaps(); - initPixmap("shadow-top"); - initPixmap("shadow-topright"); - initPixmap("shadow-right"); - initPixmap("shadow-bottomright"); - initPixmap("shadow-bottom"); - initPixmap("shadow-bottomleft"); - initPixmap("shadow-left"); - initPixmap("shadow-topleft"); - - m_emptyCornerPix = initEmptyPixmap(QSize(1,1)); - m_emptyCornerLeftPix = initEmptyPixmap(QSize(q->elementSize("shadow-topleft").width(), 1)); - m_emptyCornerTopPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-topleft").height())); - m_emptyCornerRightPix = initEmptyPixmap(QSize(q->elementSize("shadow-bottomright").width(), 1)); - m_emptyCornerBottomPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-bottomright").height())); - m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-left").height())); - m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize("shadow-top").width(), 1)); - -} - - -void Shadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders) -{ -#ifdef Q_WS_X11 - //shadow-top - if (enabledBorders & Plasma::FrameSvg::TopBorder) { - data[enabledBorders] << m_shadowPixmaps[0].handle(); - } else { - data[enabledBorders] << m_emptyHorizontalPix.handle(); - } - - //shadow-topright - if (enabledBorders & Plasma::FrameSvg::TopBorder && - enabledBorders & Plasma::FrameSvg::RightBorder) { - data[enabledBorders] << m_shadowPixmaps[1].handle(); - } else if (enabledBorders & Plasma::FrameSvg::TopBorder) { - data[enabledBorders] << m_emptyCornerTopPix.handle(); - } else if (enabledBorders & Plasma::FrameSvg::RightBorder) { - data[enabledBorders] << m_emptyCornerRightPix.handle(); - } else { - data[enabledBorders] << m_emptyCornerPix.handle(); - } - - //shadow-right - if (enabledBorders & Plasma::FrameSvg::RightBorder) { - data[enabledBorders] << m_shadowPixmaps[2].handle(); - } else { - data[enabledBorders] << m_emptyVerticalPix.handle(); - } - - //shadow-bottomright - if (enabledBorders & Plasma::FrameSvg::BottomBorder && - enabledBorders & Plasma::FrameSvg::RightBorder) { - data[enabledBorders] << m_shadowPixmaps[3].handle(); - } else if (enabledBorders & Plasma::FrameSvg::BottomBorder) { - data[enabledBorders] << m_emptyCornerBottomPix.handle(); - } else if (enabledBorders & Plasma::FrameSvg::RightBorder) { - data[enabledBorders] << m_emptyCornerRightPix.handle(); - } else { - data[enabledBorders] << m_emptyCornerPix.handle(); - } - - //shadow-bottom - if (enabledBorders & Plasma::FrameSvg::BottomBorder) { - data[enabledBorders] << m_shadowPixmaps[4].handle(); - } else { - data[enabledBorders] << m_emptyHorizontalPix.handle(); - } - - //shadow-bottomleft - if (enabledBorders & Plasma::FrameSvg::BottomBorder && - enabledBorders & Plasma::FrameSvg::LeftBorder) { - data[enabledBorders] << m_shadowPixmaps[5].handle(); - } else if (enabledBorders & Plasma::FrameSvg::BottomBorder) { - data[enabledBorders] << m_emptyCornerBottomPix.handle(); - } else if (enabledBorders & Plasma::FrameSvg::LeftBorder) { - data[enabledBorders] << m_emptyCornerLeftPix.handle(); - } else { - data[enabledBorders] << m_emptyCornerPix.handle(); - } - - //shadow-left - if (enabledBorders & Plasma::FrameSvg::LeftBorder) { - data[enabledBorders] << m_shadowPixmaps[6].handle(); - } else { - data[enabledBorders] << m_emptyVerticalPix.handle(); - } - - //shadow-topleft - if (enabledBorders & Plasma::FrameSvg::TopBorder && - enabledBorders & Plasma::FrameSvg::LeftBorder) { - data[enabledBorders] << m_shadowPixmaps[7].handle(); - } else if (enabledBorders & Plasma::FrameSvg::TopBorder) { - data[enabledBorders] << m_emptyCornerTopPix.handle(); - } else if (enabledBorders & Plasma::FrameSvg::LeftBorder) { - data[enabledBorders] << m_emptyCornerLeftPix.handle(); - } else { - data[enabledBorders] << m_emptyCornerPix.handle(); - } -#endif - - int left, top, right, bottom = 0; - - QSize marginHint; - if (enabledBorders & Plasma::FrameSvg::TopBorder) { - marginHint = q->elementSize("shadow-hint-top-margin"); - if (marginHint.isValid()) { - top = marginHint.height(); - } else { - top = m_shadowPixmaps[0].height(); // top - } - } else { - top = 1; - } - - if (enabledBorders & Plasma::FrameSvg::RightBorder) { - marginHint = q->elementSize("shadow-hint-right-margin"); - if (marginHint.isValid()) { - right = marginHint.width(); - } else { - right = m_shadowPixmaps[2].width(); // right - } - } else { - right = 1; - } - - if (enabledBorders & Plasma::FrameSvg::BottomBorder) { - marginHint = q->elementSize("shadow-hint-bottom-margin"); - if (marginHint.isValid()) { - bottom = marginHint.height(); - } else { - bottom = m_shadowPixmaps[4].height(); // bottom - } - } else { - bottom = 1; - } - - if (enabledBorders & Plasma::FrameSvg::LeftBorder) { - marginHint = q->elementSize("shadow-hint-left-margin"); - if (marginHint.isValid()) { - left = marginHint.width(); - } else { - left = m_shadowPixmaps[6].width(); // left - } - } else { - left = 1; - } - - data[enabledBorders] << top << right << bottom << left; -} - -void Shadows::Private::clearPixmaps() -{ -#ifdef Q_WS_X11 - if (m_managePixmaps) { - foreach (const QPixmap &pixmap, m_shadowPixmaps) { - XFreePixmap(QX11Info::display(), pixmap.handle()); - } - - XFreePixmap(QX11Info::display(), m_emptyCornerPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyCornerBottomPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyCornerLeftPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyCornerRightPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyCornerTopPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyVerticalPix.handle()); - XFreePixmap(QX11Info::display(), m_emptyHorizontalPix.handle()); - - m_managePixmaps = false; - } -#endif - m_shadowPixmaps.clear(); - data.clear(); -} - -void Shadows::Private::updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders) -{ -#ifdef Q_WS_X11 - if (m_shadowPixmaps.isEmpty()) { - setupPixmaps(); - } - - if (!data.contains(enabledBorders)) { - setupData(enabledBorders); - } - - Display *dpy = QX11Info::display(); - Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False); - - //kDebug() << "going to set the shadow of" << winId() << "to" << data; - XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace, - reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size()); -#endif -} - -void Shadows::Private::clearShadow(const QWidget *window) -{ -#ifdef Q_WS_X11 - Display *dpy = QX11Info::display(); - Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False); - XDeleteProperty(dpy, window->winId(), atom); -#endif -} - -bool Shadows::enabled() const -{ - return hasElement("shadow-left"); -} - -#include "shadows.moc" - diff --git a/appmenu/shadows.h b/appmenu/shadows.h deleted file mode 100644 index afbc49ef..00000000 --- a/appmenu/shadows.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* Copyright 2011 by Aaron Seigo <aseigo@kde.org> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU Library General Public License version 2, -* or (at your option) any later version. -* -* This program 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 General Public License for more details -* -* You should have received a copy of the GNU Library General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef SHADOWS_H -#define SHADOWS_H - -#include <QSet> - -#include "plasma/framesvg.h" -#include "plasma/svg.h" - - -class Shadows : public Plasma::Svg -{ - Q_OBJECT - -public: - explicit Shadows(QObject *parent = 0, const QString &prefix = "widgets/panel-background"); - - static Shadows *self(); - - void addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders); - void removeWindow(const QWidget *window); - - bool enabled() const; - -private: - class Private; - Private * const d; - - Q_PRIVATE_SLOT(d, void updateShadows()) - Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject)) -}; - -#endif - diff --git a/appmenu/topmenubar.cpp b/appmenu/topmenubar.cpp deleted file mode 100644 index 2ae19b38..00000000 --- a/appmenu/topmenubar.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "topmenubar.h" -#include "glowbar.h" - -//KDE -#include <Plasma/Svg> -#include <KWindowSystem> - -// Qt -#include <QMenu> -#include <QTimer> -#include <QDebug> -#include <QApplication> -#include <QPropertyAnimation> -#include <QDesktopWidget> - -TopMenuBar::TopMenuBar() - : MenuBar(), - m_prevCursorPos(-1, -1), - m_mouseTracker(new QTimer(this)), - m_hideGlowTimer(new QTimer(this)), - m_glowBar(new GlowBar()) -{ - connect(this, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); - connect(m_mouseTracker, SIGNAL(timeout()), this, SLOT(slotMouseTracker())); - connect(m_hideGlowTimer, SIGNAL(timeout()), this, SLOT(slotHideGlowBar())); -} - -TopMenuBar::~TopMenuBar() -{ - delete m_mouseTracker; - delete m_hideGlowTimer; - hideGlowBar(); - delete m_glowBar; -} - -void TopMenuBar::enableMouseTracking(bool enable) -{ - if (enable) { - if (!cursorInMenuBar()) { - showGlowBar(); - } - m_mouseTracker->start(250); - } else { - hideGlowBar(); - m_mouseTracker->stop(); - } -} - -void TopMenuBar::updateSize() -{ - // Enable mouse tracking on resize if needed - if (!m_mouseTracker->isActive() && !cursorInMenuBar()) { - enableMouseTracking(); - } - resize(sizeHint()); -} - -void TopMenuBar::move(QPoint p) -{ - MenuBar::move(p); - if (m_glowBar) { - m_glowBar->move(p); - m_glowBar->setPixmap(triggerRect().topLeft(), triggerRect().width()); - } -} - -bool TopMenuBar::cursorInMenuBar() -{ - if (m_mouseTracker->isActive()) { - return triggerRect().contains(QCursor::pos()); - } else { - return MenuBar::cursorInMenuBar(); - } -} - -void TopMenuBar::slotAboutToHide() -{ - enableMouseTracking(); -} - -void TopMenuBar::slotMouseTracker() -{ - QPoint cursorPos = QCursor::pos(); - - // reset timer - if (cursorPos != m_prevCursorPos && m_hideGlowTimer->isActive()) { - m_hideGlowTimer->stop(); - m_hideGlowTimer->start(10000); - } - - if (cursorInMenuBar()) { // show menubar - m_mouseTracker->stop(); - hideGlowBar(); - show(); - } else if(cursorPos != m_prevCursorPos) { // change glowbar opacity - qreal opacity = glowBarOpacity(); - QPropertyAnimation *anim = new QPropertyAnimation(m_glowBar, "windowOpacity"); - anim->setStartValue(m_glowBar->windowOpacity()); - anim->setEndValue(opacity); - anim->setDuration(200); - anim->start(QAbstractAnimation::DeleteWhenStopped); - // Show menubar if auto hidden - if (!m_glowBar->isVisible()) { - m_glowBar->show(); - } - } - m_prevCursorPos = cursorPos; -} - -void TopMenuBar::slotHideGlowBar() -{ - if (m_prevCursorPos == QCursor::pos()) { - hideGlowBar(); - } else { - m_hideGlowTimer->start(10000); - } -} - -void TopMenuBar::showGlowBar() -{ - if (m_glowBar) { - m_hideGlowTimer->start(10000); - m_glowBar->setWindowOpacity(glowBarOpacity()); - m_glowBar->show(); - } -} - -void TopMenuBar::hideGlowBar() -{ - if (m_glowBar) { - m_glowBar->hide(); - } -} - -qreal TopMenuBar::glowBarOpacity() -{ - QPoint cursorPos = QCursor::pos(); - QDesktopWidget *desktop = QApplication::desktop(); - int screen = desktop->screenNumber(cursorPos); - QRect desktopRect = desktop->availableGeometry(screen); - return 1.0 - ((cursorPos.y() - desktopRect.y())/qreal(desktopRect.height())*2.0); -} - -QRect TopMenuBar::triggerRect() -{ - QPoint triggerPoint = QPoint(x(), y()); - QSize triggerSize = QSize(sizeHint().width(), 5); - return QRect(triggerPoint, triggerSize); -} - -#include "topmenubar.moc" \ No newline at end of file diff --git a/appmenu/topmenubar.h b/appmenu/topmenubar.h deleted file mode 100644 index 8712cfd7..00000000 --- a/appmenu/topmenubar.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin <megabigbug@yahoo.fr> - Copyright (c) 2011,2012 Cédric Bellegarde <gnumdk@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef TOPMENUBAR__H -#define TOPMENUBAR__H - -#include "menubar.h" - -class QTimer; -class GlowBar; - -class TopMenuBar : public MenuBar -{ -Q_OBJECT -public: - TopMenuBar(); - ~TopMenuBar(); - - /** - * Start mouse tracking (hide/show on mouse event) - */ - void enableMouseTracking(bool enable = true); - - /** - * Set menubar parent window id - */ - void setParentWid(WId id) { m_wid = id; } - /** - * Get menubar parent window id - */ - WId parentWid() { return m_wid; } - /** - * resize menu bar to feet content - */ - void updateSize(); - /** - * Move menubar and glow bar at position - */ - void move(QPoint p); -protected: - bool cursorInMenuBar(); -private Q_SLOTS: - void slotAboutToHide(); - void slotMouseTracker(); - void slotHideGlowBar(); -private: - void showGlowBar(); - void hideGlowBar(); - qreal glowBarOpacity(); - QRect triggerRect(); - - WId m_wid; - QPoint m_prevCursorPos; - QTimer* m_mouseTracker; - QTimer* m_hideGlowTimer; - GlowBar* m_glowBar; -}; - -#endif diff --git a/appmenu/verticalmenu.h b/appmenu/verticalmenu.h index b7b5986a..ffcb3a11 100644 --- a/appmenu/verticalmenu.h +++ b/appmenu/verticalmenu.h @@ -27,6 +27,7 @@ #define VERTICALMENU_H #include <QMenu> +#include <QDBusObjectPath> class VerticalMenu : public QMenu { @@ -35,22 +36,23 @@ public: VerticalMenu(QWidget * parent = 0); ~VerticalMenu() override; - /** - * Set menu parent window id - */ - void setParentWid(WId id) { m_wid = id; } - /** - * Get menu parent window id - */ - WId parentWid() { return m_wid; } + QString serviceName() const { return m_serviceName; } + void setServiceName(const QString &serviceName) { m_serviceName = serviceName; } + + QDBusObjectPath menuObjectPath() const { return m_menuObjectPath; } + void setMenuObjectPath(const QDBusObjectPath &menuObjectPath) { m_menuObjectPath = menuObjectPath; } + protected: void keyPressEvent(QKeyEvent*) override; void keyReleaseEvent(QKeyEvent*) override; void paintEvent(QPaintEvent*) override; + private: QMenu *leafMenu(); -private: - WId m_wid; + + QString m_serviceName; + QDBusObjectPath m_menuObjectPath; + }; #endif //VERTICALMENU_H -- 2.12.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor