diff --git a/appmenu/CMakeLists.txt b/appmenu/CMakeLists.txt --- a/appmenu/CMakeLists.txt +++ b/appmenu/CMakeLists.txt @@ -6,13 +6,7 @@ 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 @@ 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.h b/appmenu/appmenu.h --- a/appmenu/appmenu.h +++ b/appmenu/appmenu.h @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin Copyright (c) 2011,2012 Cédric Bellegarde + Copyright (c) 2016 Kai Uwe Broulik 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 #include "menuimporter.h" -#include "gtkicons.h" class QDBusPendingCallWatcher; class KDBusMenuImporter; @@ -48,107 +48,51 @@ /** * 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 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.cpp b/appmenu/appmenu.cpp --- a/appmenu/appmenu.cpp +++ b/appmenu/appmenu.cpp @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin Copyright (c) 2011,2012 Cédric Bellegarde + Copyright (c) 2016 Kai Uwe Broulik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,81 +24,96 @@ DEALINGS IN THE SOFTWARE. */ +#include + #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 -#include -#include #include -#include -#include -#include -#include -#include #include #include #include #include -#include +#include +#include + +#if HAVE_X11 +#include +#include +#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", registerPlugin();) AppMenuModule::AppMenuModule(QObject* parent, const QList&) : 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 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 @@ //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_dbus.h b/appmenu/appmenu_dbus.h --- a/appmenu/appmenu_dbus.h +++ b/appmenu/appmenu_dbus.h @@ -46,10 +46,10 @@ 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 @@ /** * 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/appmenu_dbus.cpp b/appmenu/appmenu_dbus.cpp --- a/appmenu/appmenu_dbus.cpp +++ b/appmenu/appmenu_dbus.cpp @@ -58,12 +58,12 @@ 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/glowbar.h b/appmenu/glowbar.h deleted file mode 100644 --- a/appmenu/glowbar.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 - -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/glowbar.cpp b/appmenu/glowbar.cpp deleted file mode 100644 --- a/appmenu/glowbar.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include - -#include -#include -#include - -#include -#include -#include -#include - - -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/gtkicons.h b/appmenu/gtkicons.h deleted file mode 100644 --- a/appmenu/gtkicons.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 - -class GtkIcons : public QMap -{ - public: - GtkIcons( void ) : QMap () - { - 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 --- a/appmenu/kdbusimporter.h +++ b/appmenu/kdbusimporter.h @@ -26,49 +26,25 @@ #ifndef KDBUSMENUIMPORTER_H #define KDBUSMENUIMPORTER_H -#include "gtkicons.h" - -#include -#include - -#include - #include +#include + 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.h b/appmenu/menubar.h deleted file mode 100644 --- a/appmenu/menubar.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 - -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/menubar.cpp b/appmenu/menubar.cpp deleted file mode 100644 --- a/appmenu/menubar.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -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/menubutton.h b/appmenu/menubutton.h deleted file mode 100644 --- a/appmenu/menubutton.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include - -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/menubutton.cpp b/appmenu/menubutton.cpp deleted file mode 100644 --- a/appmenu/menubutton.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include -#include - -#include - -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/menuimporter.h b/appmenu/menuimporter.h --- a/appmenu/menuimporter.h +++ b/appmenu/menuimporter.h @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin Copyright (c) 2011,2012 Cédric Bellegarde + Copyright (c) 2016 Kai Uwe Broulik 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 #include #include #include @@ -67,10 +69,7 @@ QList 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,15 +83,13 @@ private Q_SLOTS: void slotServiceUnregistered(const QString& service); void slotLayoutUpdated(uint revision, int parentId); - void finishFakeUnityAboutToShow(QDBusPendingCallWatcher*); private: QDBusServiceWatcher* m_serviceWatcher; QHash m_menuServices; QHash m_menuPaths; QHash m_windowClasses; - void fakeUnityAboutToShow(); }; #endif /* MENUIMPORTER_H */ diff --git a/appmenu/menuimporter.cpp b/appmenu/menuimporter.cpp --- a/appmenu/menuimporter.cpp +++ b/appmenu/menuimporter.cpp @@ -3,6 +3,7 @@ Copyright (c) 2011 Lionel Chauvin Copyright (c) 2011,2012 Cédric Bellegarde + Copyright (c) 2016 Kai Uwe Broulik 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 #include #include #include -#include #include #include @@ -80,14 +79,14 @@ 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 @@ 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 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 @@ 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 @@ // 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 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 reply = QDBusConnection::sessionBus().asyncCall(msg); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply 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/menuwidget.h b/appmenu/menuwidget.h deleted file mode 100644 --- a/appmenu/menuwidget.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include - -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 m_buttons; - MenuButton *m_currentButton; - qreal m_contentBottomMargin; - QPoint m_mousePosition; - QMenu *m_visibleMenu; - QMenu *m_menu; -}; - -#endif //MENUWIDGET__H diff --git a/appmenu/menuwidget.cpp b/appmenu/menuwidget.cpp deleted file mode 100644 --- a/appmenu/menuwidget.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include -#include -#include - -#include -#include -#include - -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(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(object); - - if (event->type() == QEvent::KeyPress) { - menu->removeEventFilter(this); - QApplication::sendEvent(menu, event); - menu->installEventFilter(this); - if (!event->isAccepted()) { - QKeyEvent* keyEvent = static_cast(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(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(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/org.kde.kappmenu.xml b/appmenu/org.kde.kappmenu.xml --- a/appmenu/org.kde.kappmenu.xml +++ b/appmenu/org.kde.kappmenu.xml @@ -4,28 +4,23 @@ - + + + - - - - + + - + + + - - - - - - - - + diff --git a/appmenu/shadows.h b/appmenu/shadows.h deleted file mode 100644 --- a/appmenu/shadows.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* Copyright 2011 by Aaron Seigo -* -* 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 - -#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/shadows.cpp b/appmenu/shadows.cpp deleted file mode 100644 --- a/appmenu/shadows.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* -* Copyright 2011 by Aaron Seigo -* -* 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 -#include - -#ifdef Q_WS_X11 -#include -#include -#include -#include -#endif - -#include -#include - -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 m_shadowPixmaps; - - QPixmap m_emptyCornerPix; - QPixmap m_emptyCornerLeftPix; - QPixmap m_emptyCornerTopPix; - QPixmap m_emptyCornerRightPix; - QPixmap m_emptyCornerBottomPix; - QPixmap m_emptyVerticalPix; - QPixmap m_emptyHorizontalPix; - - QHash > data; - QHash 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(deletedObject)); - - if (m_windows.isEmpty()) { - clearPixmaps(); - } -} - -void Shadows::Private::updateShadows() -{ - setupPixmaps(); - QHash::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(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/topmenubar.h b/appmenu/topmenubar.h deleted file mode 100644 --- a/appmenu/topmenubar.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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/topmenubar.cpp b/appmenu/topmenubar.cpp deleted file mode 100644 --- a/appmenu/topmenubar.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - This file is part of the KDE project. - - Copyright (c) 2011 Lionel Chauvin - Copyright (c) 2011,2012 Cédric Bellegarde - - 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 -#include - -// Qt -#include -#include -#include -#include -#include -#include - -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/verticalmenu.h b/appmenu/verticalmenu.h --- a/appmenu/verticalmenu.h +++ b/appmenu/verticalmenu.h @@ -27,30 +27,32 @@ #define VERTICALMENU_H #include +#include class VerticalMenu : public QMenu { Q_OBJECT 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