diff options
10 files changed, 171 insertions, 5 deletions
diff --git a/src-qt5/core/libLumina/DesktopSettings.cpp b/src-qt5/core/libLumina/DesktopSettings.cpp index cd85df5e..30bd5bc2 100644 --- a/src-qt5/core/libLumina/DesktopSettings.cpp +++ b/src-qt5/core/libLumina/DesktopSettings.cpp @@ -222,6 +222,8 @@ QString DesktopSettings::rel_path(DesktopSettings::File file){ name="session"; break; case DesktopSettings::Desktop: name="desktop"; break; + case DesktopSettings::ContextMenu: + name="contextmenu"; break; case DesktopSettings::Keys: name="keys"; break; case DesktopSettings::Theme: diff --git a/src-qt5/core/libLumina/DesktopSettings.h b/src-qt5/core/libLumina/DesktopSettings.h index 737fd6af..57eede9d 100644 --- a/src-qt5/core/libLumina/DesktopSettings.h +++ b/src-qt5/core/libLumina/DesktopSettings.h @@ -25,7 +25,7 @@ class DesktopSettings : public QObject{ Q_OBJECT public: - enum File{ System, Favorites, Environment, Session, Desktop, Keys, Theme }; + enum File{ System, Favorites, Environment, Session, Desktop, ContextMenu, Keys, Theme }; DesktopSettings(QObject *parent = 0); ~DesktopSettings(); diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index 156029ee..cb0144d5 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -7,6 +7,8 @@ #include "LSession.h" #include "global-objects.h" +#include "src-desktop/ContextMenu.h" + #include "BootSplash.h" #ifndef DEBUG #define DEBUG 1 @@ -51,7 +53,12 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu Lumina::APPLIST = new XDGDesktopList(0, true); //keep this list up to date Lumina::SHORTCUTS = new LShortcutEvents(); //this can be moved to it's own thread eventually as well + //Setup the basic connections between the shortcuts class and the session itself + connect(Lumina::SHORTCUTS, SIGNAL(StartLogout()), this, SLOT(StartLogout()) ); + connect(Lumina::SHORTCUTS, SIGNAL(StartReboot()), this, SLOT(StartReboot()) ); + connect(Lumina::SHORTCUTS, SIGNAL(StartShutdown()), this, SLOT(StartShutdown()) ); //Setup the various connections between the global classes + // NOTE: Most of these connections will only become "active" as the global objects get started during the setupSession routine connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::EFILTER, SLOT(RegisterVirtualRoot(WId)) ); } //end check for primary process @@ -136,6 +143,10 @@ void LSession::setupSession(){ Lumina::ROOTWIN->ChangeWallpaper(scrns[i]->name(), RootWindow::Stretch, LOS::LuminaShare()+"desktop-background.jpg"); } Lumina::ROOTWIN->start(); + DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); + connect(cmenu, SIGNAL(showLeaveDialog()), this, SLOT(StartLogout()) ); + cmenu->start(); + //desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst); //updateDesktops(); //for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running @@ -171,7 +182,7 @@ void LSession::setupSession(){ splash.close(); LSession::processEvents(); //DEBUG: Wait a bit then close down the session - QTimer::singleShot(15000, this, SLOT(StartLogout()) ); + //QTimer::singleShot(15000, this, SLOT(StartLogout()) ); } //================ diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index ab810ada..6a753cd1 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -35,6 +35,7 @@ #include <QParallelAnimationGroup> #include <QWindow> #include <QWidget> +#include <QWidgetAction> #include <QBackingStore> #include <QPaintEvent> #include <QPainter> diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index a583e9d7..497ce635 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -21,6 +21,7 @@ include(../libLumina/RootWindow.pri) #include all the main individual source groups include(src-screensaver/screensaver.pri) include(src-events/events.pri) +include(src-desktop/desktop.pri) TEMPLATE = app diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp new file mode 100644 index 00000000..fa4af5ba --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp @@ -0,0 +1,95 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2012-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "ContextMenu.h" +#include <global-objects.h> + +void DesktopContextMenu::SettingsChanged(DesktopSettings::File file){ + if(file == DesktopSettings::ContextMenu){ UpdateMenu(); } +} + +void DesktopContextMenu::UpdateMenu(){ + //Put a label at the top + unsigned int num = Lumina::EFILTER->currentWorkspace(); //LX11::GetCurrentDesktop(); + workspaceLabel->setText( "<b>"+QString(tr("Workspace %1")).arg(QString::number(num+1))+"</b>"); + this->clear(); //clear it for refresh + this->addAction(wkspaceact); + this->addSeparator(); + //Now load the user's menu setup and fill the menu + QStringList items = Lumina::SETTINGS->value(DesktopSettings::ContextMenu, "itemlist", QStringList()<< "terminal" << "filemanager" << "line" << "settings" <<"lockdesktop").toStringList(); + //usewinmenu=false; + for(int i=0; i<items.length(); i++){ + if(items[i]=="terminal"){ this->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"))->setWhatsThis("lumina-open -terminal"); } + else if(items[i]=="lockdesktop"){ this->addAction(LXDG::findIcon("system-lock-screen",""), tr("Lock Session"), this, SIGNAL(LockSession()) ); } + else if(items[i]=="filemanager"){ this->addAction( LXDG::findIcon("user-home",""), tr("Browse Files"))->setWhatsThis("lumina-open ~"); } + //else if(items[i]=="applications"){ this->addMenu( LSession::handle()->applicationMenu() ); } + else if(items[i]=="line"){ this->addSeparator(); } + //else if(items[i]=="settings"){ this->addMenu( LSession::handle()->settingsMenu() ); } + //else if(items[i]=="windowlist"){ this->addMenu( winMenu); usewinmenu=true;} + else if(items[i].startsWith("app::::") && items[i].endsWith(".desktop")){ + //Custom *.desktop application + QString file = items[i].section("::::",1,1).simplified(); + XDGDesktop xdgf(file);// = LXDG::loadDesktopFile(file, ok); + if(xdgf.type!=XDGDesktop::BAD){ + this->addAction( LXDG::findIcon(xdgf.icon,""), xdgf.name)->setWhatsThis(file); + }else{ + qDebug() << "Could not load application file:" << file; + } + }/*else if(items[i].startsWith("jsonmenu::::")){ + //Custom JSON menu system (populated on demand via external scripts/tools + QStringList info = items[i].split("::::"); //FORMAT:[ "jsonmenu",exec,name, icon(optional)] + if(info.length()>=3){ + qDebug() << "Custom JSON Menu Loaded:" << info; + JsonMenu *tmp = new JsonMenu(info[1], deskMenu); + tmp->setTitle(info[2]); + connect(tmp, SIGNAL(triggered(QAction*)), this, SLOT(SystemApplication(QAction*)) ); + if(info.length()>=4){ tmp->setIcon( LXDG::findIcon(info[3],"") ); } + this->addMenu(tmp); + } + }*/ + } + //Now add the system quit options + this->addSeparator(); + this->addAction(LXDG::findIcon("system-log-out",""), tr("Leave"), this, SIGNAL(showLeaveDialog()) ); +} + +// === PUBLIC === +DesktopContextMenu::DesktopContextMenu(QWidget *parent) : QMenu(parent){ + if(parent!=0){ + parent->setContextMenuPolicy(Qt::CustomContextMenu); + connect(parent, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&)) ); + } + workspaceLabel = new QLabel(0); + wkspaceact = new QWidgetAction(0); + wkspaceact->setDefaultWidget(workspaceLabel); + connect(this, SIGNAL(triggered(QAction*)), this, SLOT(LaunchAction(QAction*)) ); + +} + +DesktopContextMenu::~DesktopContextMenu(){ + //nothing special + //workspaceLabel->deleteLater(); //The QWidgetAction takes ownership of the label when inserted - do not manually delete + wkspaceact->deleteLater(); +} + +void DesktopContextMenu::start(){ + connect(Lumina::SETTINGS, SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(SettingsChanged(DesktopSettings::File)) ); + connect(this, SIGNAL(LockSession()), Lumina::SS, SLOT(LockScreenNow()) ); + + //Still need to connect to some "workspaceChanged(int)" signal + QTimer::singleShot(0, this, SLOT(UpdateMenu()) ); //initial update +} + +// === PRIVATE SLOTS === +void DesktopContextMenu::LaunchAction(QAction *act){ + if(act->whatsThis().isEmpty() || act->parent()!=this ){ return; } + QString cmd = act->whatsThis(); + emit LaunchApplication(cmd); +} + +void DesktopContextMenu::showMenu(const QPoint &pt){ + this->popup(pt); +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h new file mode 100644 index 00000000..1a4befc9 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h @@ -0,0 +1,38 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2012-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_CONTEXT_MENU_H +#define _LUMINA_DESKTOP_CONTEXT_MENU_H + +#include <global-includes.h> + +class DesktopContextMenu : public QMenu{ + Q_OBJECT +public slots: + void SettingsChanged(DesktopSettings::File); + void UpdateMenu(); //re-create the menu + +private: + QLabel *workspaceLabel; + QWidgetAction *wkspaceact; + +public: + DesktopContextMenu(QWidget *parent = 0); + ~DesktopContextMenu(); + + void start(); //setup connections to global objects + +private slots: + void LaunchAction(QAction *act); + void showMenu(const QPoint&); + +signals: + void LaunchApplication(QString); //cmd to run + void LockSession(); + void showLeaveDialog(); +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri new file mode 100644 index 00000000..75aef8a6 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri @@ -0,0 +1,6 @@ +SOURCES *= $${PWD}/ContextMenu.cpp + +HEADERS *= $${PWD}/ContextMenu.h + +#update the includepath so we can just #include as needed without paths +INCLUDEPATH *= ${PWD} diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp index 04ebd4d3..4a192aa4 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp @@ -62,9 +62,15 @@ void EventFilter::stop(){ static_cast<XCBEventFilter*>(EF)->stopSystemTray(); } +//Session Interaction/Information QList<WId> EventFilter::currentTrayApps(){ return static_cast<XCBEventFilter*>(EF)->trayApps(); } + +unsigned int EventFilter::currentWorkspace(){ +return XCB->CurrentWorkspace(); +} + // === PUBLIC SLOTS === void EventFilter::RegisterVirtualRoot(WId id){ XCB->WM_Set_Virtual_Roots( QList<WId>() << id ); @@ -172,7 +178,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_EXPOSE: - qDebug() << "Expose Notify Event:"; + //qDebug() << "Expose Notify Event:"; //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; break; //============================== @@ -208,12 +214,12 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_PROPERTY_NOTIFY: - qDebug() << "Property Notify Event:"; + //qDebug() << "Property Notify Event:"; //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; break; //============================== case XCB_CLIENT_MESSAGE: - qDebug() << "Client Message Event"; + //qDebug() << "Client Message Event"; //qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; if( ((xcb_client_message_event_t*)ev)->type == _NET_SYSTEM_TRAY_OPCODE && ((xcb_client_message_event_t*)ev)->format == 32){ //data32[0] is timestamp, [1] is opcode, [2] is window handle diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h index dc88dcc0..9e76ba53 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h @@ -58,6 +58,9 @@ public: //Public System Tray Functions QList<WId> currentTrayApps(); + //Public Session Interaction Functions + unsigned int currentWorkspace(); + //Variables/Functions needed by the XCBEventFilter class only (not really needed by anything else) LXCB *XCB; //used to interact with the X11 graphics subsystem @@ -69,6 +72,9 @@ signals: void NewManagedWindow(WId); void WindowClosed(WId); void ModifyWindow(WId win, Lumina::WindowAction); + + // Session Signals + void WorkspaceChanged(unsigned int); // System Tray Signals void Tray_AppAdded(WId); //new tray app registered |