aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets')
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp184
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h48
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp120
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h44
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri8
5 files changed, 404 insertions, 0 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp
new file mode 100644
index 00000000..139eee89
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp
@@ -0,0 +1,184 @@
+//===========================================
+// 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>
+#include <JsonMenu.h>
+#include <LIconCache.h>
+
+void DesktopContextMenu::SettingsChanged(DesktopSettings::File file){
+ if(file == DesktopSettings::ContextMenu){ UpdateMenu(false); }
+}
+
+void DesktopContextMenu::UpdateMenu(bool fast){
+ //Put a label at the top
+ unsigned int num = Lumina::NWS->currentWorkspace();
+ workspaceLabel->setText( "<b>"+QString(tr("Workspace %1")).arg(QString::number(num+1))+"</b>");
+ if(fast && usewinmenu){ updateWinMenu(); }
+ if(fast){ return; } //already done
+ this->clear(); //clear it for refresh
+ this->addAction(wkspaceact);
+ this->addSeparator();
+ //Now load the user's menu setup and fill the menu
+ QStringList items = DesktopSettings::instance()->value(DesktopSettings::ContextMenu, "itemlist", QStringList()<< "terminal" << "filemanager" << "line" << "applications" << "windowlist" << "settings" << "lockdesktop").toStringList();
+ usewinmenu=false;
+ for(int i=0; i<items.length(); i++){
+ if(items[i]=="terminal"){
+ QAction *act = this->addAction( tr("Terminal"));
+ LIconCache::instance()->loadIcon(act, "utilities-terminal");
+ act->setWhatsThis("--terminal");
+ }
+ else if(items[i]=="lockdesktop"){
+ QAction *act = this->addAction( tr("Lock Session"), this, SIGNAL(LockSession()) );
+ LIconCache::instance()->loadIcon(act, "system-lock-screen");
+ }
+ else if(items[i]=="filemanager"){
+ QAction *act = this->addAction( tr("Browse Files"));
+ LIconCache::instance()->loadIcon(act, "user-home");
+ act->setWhatsThis(QDir::homePath());
+ }
+ else if(items[i]=="applications"){
+ if(appMenu==0){ updateAppMenu(); }
+ this->addMenu( appMenu );
+ }
+ else if(items[i]=="line"){ this->addSeparator(); }
+ //else if(items[i]=="settings"){ this->addMenu( LSession::handle()->settingsMenu() ); }
+ else if(items[i]=="windowlist"){
+ if(winMenu==0){ updateWinMenu(); }
+ 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();
+ //Try to use the pre-loaded app entry for this
+ XDGDesktop *xdg = XDGDesktopList::instance()->findAppFile(file);
+ if(xdg!=0){ xdg->addToMenu(this); }
+ else{
+ XDGDesktop xdgf(file);// = LXDG::loadDesktopFile(file, ok);
+ if(xdgf.type!=XDGDesktop::BAD){ xdgf.addToMenu(this); }
+ }
+ }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], this);
+ 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()) );
+}
+
+// === PRIVATE ===
+void DesktopContextMenu::AddWindowToMenu(NativeWindowObject *win){
+ QString label = win->property(NativeWindowObject::ShortTitle).toString();
+ if(label.isEmpty()){ label = win->property(NativeWindowObject::Title).toString(); }
+ if(label.isEmpty()){ label = win->property(NativeWindowObject::Name).toString(); }
+ QAction *tmp = winMenu->addAction( win->property(NativeWindowObject::Icon).value<QIcon>(), label, win, SLOT(toggleVisibility()) );
+ //Need to change the visual somehow to indicate whether it is visible or not
+ //bool visible = win->property(NativeWindow::Visible).toBool();
+ // TODO
+}
+
+// === 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&)) );
+ }
+ appMenu = 0;
+ winMenu = 0;
+ usewinmenu = false;
+ workspaceLabel = new QLabel(0);
+ workspaceLabel->setAlignment(Qt::AlignCenter);
+ wkspaceact = new QWidgetAction(0);
+ wkspaceact->setDefaultWidget(workspaceLabel);
+ connect(this, SIGNAL(triggered(QAction*)), this, SLOT(LaunchAction(QAction*)) );
+ //Connect to a couple global objects
+ connect(this, SIGNAL(aboutToShow()), this, SLOT(UpdateMenu()) ); //this will do a "fast" update
+ qDebug() << "Done Creating Context Menu";
+}
+
+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(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(SettingsChanged(DesktopSettings::File)) );
+ connect(this, SIGNAL(LockSession()), Lumina::SS, SLOT(LockScreenNow()) );
+ connect(XDGDesktopList::instance(), SIGNAL(appsUpdated()), this, SLOT(updateAppMenu()) );
+ UpdateMenu(false);
+ //Still need to connect to some "workspaceChanged(int)" signal
+}
+
+// === PRIVATE SLOTS ===
+void DesktopContextMenu::LaunchAction(QAction *act){
+ //qDebug() << "Launch Action Triggered:" << act->whatsThis();
+ if(act->whatsThis().isEmpty() || act->parent()!=this ){ return; }
+ qDebug() << "Launch Menu Action:" << act->whatsThis();
+ QString cmd = act->whatsThis();
+ if(cmd.startsWith("-action ")){
+ LaunchApp(act); //forward this to the XDGDesktop parser
+ }else if(cmd.startsWith("--") || cmd.endsWith(".desktop")){
+ LSession::instance()->LaunchStandardApplication(cmd);
+ }else if(QFile::exists(cmd)){
+ QString mime = XDGMime::fromFileName(cmd);
+ LSession::instance()->LaunchStandardApplication(mime, QStringList() << cmd);
+ }
+}
+
+void DesktopContextMenu::LaunchApp(QAction *act){
+
+ // The "whatsThis() field is set by the XDGDesktop object/format
+ if(act->whatsThis().isEmpty()){ return; }
+ QString action, file;
+ QString wt = act->whatsThis();
+ if(wt.startsWith("-action")){
+ action = wt.section(" ",1,1); action=action.remove("\"");
+ file = wt.section(" ",2,-1); file=file.remove("\"");
+ }
+ else{ file = wt; }
+ LSession::instance()->LaunchDesktopApplication(file, action);
+
+}
+
+void DesktopContextMenu::showMenu(const QPoint &pt){
+ this->popup(pt);
+}
+
+void DesktopContextMenu::updateAppMenu(){
+ //qDebug() << "Update App Menu";
+ if(appMenu==0){
+ appMenu = new QMenu(this);
+ appMenu->setTitle( tr("Applications"));
+ LIconCache::instance()->loadIcon( appMenu, "system-run");
+ connect(appMenu, SIGNAL(triggered(QAction*)), this, SLOT(LaunchApp(QAction*)) );
+ }
+ //qDebug() << "Populate App Menu";
+ XDGDesktopList::instance()->populateMenu(appMenu);
+}
+
+void DesktopContextMenu::updateWinMenu(){
+ //qDebug() << "Update Win Menu";
+ if(winMenu==0){
+ winMenu = new QMenu(this);
+ winMenu->setTitle( tr("Task Manager") );
+ LIconCache::instance()->loadIcon( winMenu, "preferences-system-windows");
+ }
+ winMenu->clear();
+ QList<NativeWindowObject*> wins = RootDesktopObject::instance()->windowObjects();
+ for(int i=0; i<wins.length(); i++){
+ AddWindowToMenu(wins.at(i));
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h
new file mode 100644
index 00000000..b20087ef
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h
@@ -0,0 +1,48 @@
+//===========================================
+// 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(bool fast = true); //re-create the menu
+
+private:
+ QLabel *workspaceLabel;
+ QWidgetAction *wkspaceact;
+ QMenu *appMenu, *winMenu;
+ bool usewinmenu;
+
+ void AddWindowToMenu(NativeWindowObject*);
+
+public:
+ DesktopContextMenu(QWidget *parent = 0);
+ ~DesktopContextMenu();
+
+ void start(); //setup connections to global objects
+
+private slots:
+ void LaunchAction(QAction *act);
+ void LaunchApp(QAction *act);
+
+ void showMenu(const QPoint&);
+
+ void updateAppMenu();
+ void updateWinMenu();
+
+signals:
+ void LockSession();
+ void showLeaveDialog();
+ void LaunchStandardApplication(QString);
+ void LaunchApplication(QString);
+};
+
+#endif
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp
new file mode 100644
index 00000000..9e22a143
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp
@@ -0,0 +1,120 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include <global-objects.h>
+#include "RootDesktop.h"
+
+// === PUBLIC ===
+RootDesktop::RootDesktop(QWindow *) : QWidget(0, Qt::Widget | Qt::FramelessWindowHint | Qt::WindowStaysOnBottomHint){
+
+}
+
+RootDesktop::~RootDesktop(){
+
+}
+
+void RootDesktop::start(){
+ //qDebug() << "Starting RootDesktop" << this->geometry() << this->isVisible();
+ bgTimer = new QTimer(this);
+ bgTimer->setInterval(50);
+ bgTimer->setSingleShot(true);
+ connect(bgTimer, SIGNAL(timeout()), this, SLOT(bgTimerUpdate()) );
+
+ cmenu = new DesktopContextMenu(this);
+
+ //Setup the connections to the main objects
+ connect(RootDesktopObject::instance(), SIGNAL(screensChanged()), this, SLOT(on_screensChanged()) );
+ connect(RootDesktopObject::instance(), SIGNAL(panelsChanged()), this, SLOT(on_panelsChanged()) );
+ connect(RootDesktopObject::instance(), SIGNAL(windowsChanged()), this, SLOT(on_windowsChanged()) );
+ connect(RootDesktopObject::instance(), SIGNAL(trayWindowsChanged()), this, SLOT(on_trayWindowsChanged()) );
+
+ connect(cmenu, SIGNAL(LockSession()), RootDesktopObject::instance(), SIGNAL(lockScreen()) );
+ connect(cmenu, SIGNAL(showLeaveDialog()), RootDesktopObject::instance(), SIGNAL(startLogout()) );
+ connect(cmenu, SIGNAL(LaunchStandardApplication(QString)), RootDesktopObject::instance(), SIGNAL(launchApplication(QString)) );
+ connect(cmenu, SIGNAL(LaunchApplication(QString)), RootDesktopObject::instance(), SIGNAL(launchApplication(QString)) );
+
+ on_screensChanged(); //make sure this is setup right away (sets up connections
+ QTimer::singleShot(0, this, SLOT(on_panelsChanged()) );
+ QTimer::singleShot(2, this, SLOT(on_windowsChanged()) );
+ QTimer::singleShot(4, this, SLOT(on_trayWindowsChanged()) );
+
+ //Now start the first-run of the background change system
+ cmenu->start();
+ bgTimer->start();
+ this->show();
+}
+
+// === PRIVATE ===
+//QImage bgimage;
+
+
+// === PRIVATE SLOTS ===
+//RootDesktopObject connections
+void RootDesktop::on_screensChanged(){
+ QStringList screens = RootDesktopObject::instance()->screens();
+ //qDebug() << "Screens Changed:" << lastscreens << screens;
+ for(int i=0; i<screens.length(); i++){
+ if(!lastscreens.contains(screens[i])){
+ connect(RootDesktopObject::instance()->screen(screens[i]), SIGNAL(backgroundChanged()), this, SLOT(on_screen_bg_changed()) );
+ }
+ }
+ on_screen_bg_changed(); //start the timer to update the backgrounds now
+ lastscreens = screens; //save this for later
+}
+
+void RootDesktop::on_panelsChanged(){
+
+}
+
+void RootDesktop::on_windowsChanged(){
+
+}
+
+void RootDesktop::on_trayWindowsChanged(){
+
+}
+
+void RootDesktop::on_screen_bg_changed(){
+ if(!bgTimer->isActive()){ bgTimer->start(); }
+}
+
+//Internal use
+void RootDesktop::bgTimerUpdate(){
+ //qDebug() << "bgTimerUpdate";
+ //QtConcurrent::run(this, &RootDesktop::updateBG, this);
+ updateBG(this);
+}
+
+void RootDesktop::updateBG(RootDesktop* obj){
+
+ QImage tmp(obj->size(), QImage::Format_ARGB32_Premultiplied);
+ QStringList scr = RootDesktopObject::instance()->screens();
+ //qDebug() << "updateBG" << scr << tmp.size() << obj->geometry();
+ QPainter imgpaint(&tmp);
+ for(int i=0; i<scr.length(); i++){
+ ScreenObject * screen = RootDesktopObject::instance()->screen(scr[i]);
+ QString file = screen->background(); //in URL format
+ //qDebug() << "Got BG File:" << file << QUrl(file).toLocalFile();
+ QImage img(QUrl(file).toLocalFile());
+ //qDebug() << " - BG File is null:" << img.isNull();
+ imgpaint.drawImage(screen->geometry(), img, QRect(0,0,img.width(), img.height()) );
+ }
+ bgimage = tmp;
+ //QTimer::singleShot(0, obj, SLOT(update()) );
+ obj->update();
+}
+
+// === PROTECTED ===
+void RootDesktop::paintEvent(QPaintEvent *ev){
+ //qDebug() << "Paint Event:" << bgimage.isNull();
+ if (!bgimage.isNull()) {
+ //qDebug() << "Wallpaper paint Event:" << ev->rect();
+ QPainter painter(this);
+ painter.drawImage(ev->rect(), bgimage, ev->rect());
+ }else{
+ QWidget::paintEvent(ev);
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h
new file mode 100644
index 00000000..16ce0e47
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h
@@ -0,0 +1,44 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_DESKTOP_WIDGETS_ROOT_DESKTOP_H
+#define _LUMINA_DESKTOP_WIDGETS_ROOT_DESKTOP_H
+
+#include <global-includes.h>
+#include "ContextMenu.h"
+
+class RootDesktop : public QWidget{
+ Q_OBJECT
+public:
+ RootDesktop(QWindow *root);
+ ~RootDesktop();
+
+ void start();
+
+private:
+ QImage bgimage;
+ QStringList lastscreens;
+ QTimer *bgTimer;
+ DesktopContextMenu *cmenu;
+
+private slots:
+ //RootDesktopObject connections
+ void on_screensChanged();
+ void on_panelsChanged();
+ void on_windowsChanged();
+ void on_trayWindowsChanged();
+ void on_screen_bg_changed();
+
+ //Internal use
+ void bgTimerUpdate();
+ void updateBG(RootDesktop* obj); //designed to be run in a background thread
+
+protected:
+ virtual void paintEvent(QPaintEvent *ev);
+
+};
+
+#endif
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri
new file mode 100644
index 00000000..7994bb93
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri
@@ -0,0 +1,8 @@
+#update the includepath so we can just #include as needed without paths
+INCLUDEPATH *= $${PWD}
+
+SOURCES *= $${PWD}/RootDesktop.cpp \
+ $${PWD}/ContextMenu.cpp
+
+HEADERS *= $${PWD}/RootDesktop.h \
+ $${PWD}/ContextMenu.h
bgstack15