aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xJsonMenu_Scripts/ls.json.sh10
-rw-r--r--src-qt5/core/libLumina/LuminaUtils.cpp18
-rw-r--r--src-qt5/core/libLumina/themes/Glass.qss.template4
-rw-r--r--src-qt5/core/lumina-desktop/JsonMenu.h68
-rw-r--r--src-qt5/core/lumina-desktop/LDesktop.cpp12
-rw-r--r--src-qt5/core/lumina-desktop/fluxboxconf/fluxbox-keys6
-rw-r--r--src-qt5/core/lumina-desktop/lumina-desktop.pro3
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp29
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h3
9 files changed, 144 insertions, 9 deletions
diff --git a/JsonMenu_Scripts/ls.json.sh b/JsonMenu_Scripts/ls.json.sh
new file mode 100755
index 00000000..9a6ab847
--- /dev/null
+++ b/JsonMenu_Scripts/ls.json.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+cmd="ls $1"
+OUT=""
+for name in `${cmd}`; do
+ if [ "${OUT}" != "" ] ; then
+ OUT="${OUT},"
+ fi
+ OUT="${OUT} \"${name}\" : { \"type\" : \"item\", \"action\" : \"${name}\"}"
+done
+echo "{ ${OUT} }"
diff --git a/src-qt5/core/libLumina/LuminaUtils.cpp b/src-qt5/core/libLumina/LuminaUtils.cpp
index bf90161d..1d0e186c 100644
--- a/src-qt5/core/libLumina/LuminaUtils.cpp
+++ b/src-qt5/core/libLumina/LuminaUtils.cpp
@@ -1008,30 +1008,35 @@ void ResizeMenu::mouseMoveEvent(QMouseEvent *ev){
// since the window will be moved again the next time it is shown
// The "-2" in the sizing below accounts for the menu margins
QPoint gpos = this->mapToGlobal(ev->pos());
+ bool handled = false;
switch(resizeSide){
case TOP:
if(gpos.y() >= geom.bottom()-1){ break; }
geom.setTop(gpos.y());
this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2)); }
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
break;
case BOTTOM:
if(gpos.y() <= geom.top()+1){ break; }
geom.setBottom( gpos.y());
this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2)); }
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
break;
case LEFT:
if(gpos.x() >= geom.right()-1){ break; }
geom.setLeft(gpos.x());
this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2)); }
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
break;
case RIGHT:
if(gpos.x() <= geom.left()+1){ break; }
geom.setRight(gpos.x());
this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2)); }
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
break;
default: //NONE
//qDebug() << " - Mouse At:" << ev->pos();
@@ -1042,7 +1047,7 @@ void ResizeMenu::mouseMoveEvent(QMouseEvent *ev){
else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ this->setCursor(Qt::SizeVerCursor); }
else{ this->setCursor(Qt::ArrowCursor); }
}
- QMenu::mouseMoveEvent(ev); //do normal processing as well
+ if(!handled){ QMenu::mouseMoveEvent(ev); } //do normal processing as well
}
void ResizeMenu::mousePressEvent(QMouseEvent *ev){
@@ -1054,11 +1059,12 @@ void ResizeMenu::mousePressEvent(QMouseEvent *ev){
else if(ev->pos().y()<=1 && ev->pos().y() >= -1){ resizeSide = TOP; used = true; }
else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ resizeSide = BOTTOM; used = true; }
}
- if(used){ ev->accept(); }
+ if(used){ ev->accept(); this->grabMouse(); }
else{ QMenu::mousePressEvent(ev); } //do normal processing
}
void ResizeMenu::mouseReleaseEvent(QMouseEvent *ev){
+ this->releaseMouse();
if(ev->button() == Qt::LeftButton && resizeSide!=NONE ){
//qDebug() << "Mouse Release Event:" << ev->pos() << resizeSide;
resizeSide = NONE;
diff --git a/src-qt5/core/libLumina/themes/Glass.qss.template b/src-qt5/core/libLumina/themes/Glass.qss.template
index f3c25ec4..827d8de4 100644
--- a/src-qt5/core/libLumina/themes/Glass.qss.template
+++ b/src-qt5/core/libLumina/themes/Glass.qss.template
@@ -473,6 +473,10 @@ QWidget#LuminaBootSplash{
border-radius: 5px;
}
+LDPlugin#applauncher{
+ background-color: transparent;
+ border: none;
+}
LDPlugin#applauncher QToolButton, LDPlugin, LDPlugin#desktopview QListWidget::item{
background-color: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 30), stop:1 rgba(229, 229, 229, 70));
border-width: 3px;
diff --git a/src-qt5/core/lumina-desktop/JsonMenu.h b/src-qt5/core/lumina-desktop/JsonMenu.h
new file mode 100644
index 00000000..fbb80d28
--- /dev/null
+++ b/src-qt5/core/lumina-desktop/JsonMenu.h
@@ -0,0 +1,68 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This menu is used to automatically generate menu contents
+// based on the JSON output of an external script/utility
+//===========================================
+#ifndef _LUMINA_DESKTOP_JSON_MENU_H
+#define _LUMINA_DESKTOP_JSON_MENU_H
+
+#include <QMenu>
+#include <QString>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+
+#include <LuminaUtils.h>
+#include <LuminaXDG.h>
+
+class JsonMenu : public QMenu{
+ Q_OBJECT
+private:
+ QString exec;
+
+public:
+ JsonMenu(QString execpath, QWidget *parent = 0) : QMenu(parent){
+ exec = execpath;
+ connect(this, SIGNAL(aboutToShow()), this, SLOT(updateMenu()) );
+ }
+
+private slots:
+ void parseObject(QString label, QJsonObject obj){
+ if( label.isEmpty() || !obj.contains("type") ){ return; }
+ QString type = obj.value("type").toString();
+ if(type.toLower()=="item"){
+ QAction *act = this->addAction(label);
+ if(obj.contains("icon")){ act->setIcon( LXDG::findIcon(obj.value("icon").toString(),"") ); }
+ if(obj.contains("action")){ act->setWhatsThis( obj.value("action").toString() ); }
+ else{ act->setEnabled(false); } //not interactive
+ }else if(type.toLower()=="menu"){
+
+ }else if(type.toLower()=="jsonmenu"){
+ //This is a recursive JSON menu object
+ if(!obj.contains("exec")){ return; }
+ JsonMenu *menu = new JsonMenu(obj.value("exec").toString(), this);
+ menu->setTitle(label);
+ if(obj.contains("icon")){ menu->setIcon(LXDG::findIcon(obj.value("icon").toString(),"") ); }
+ this->addMenu(menu);
+ }
+ }
+ void updateMenu(){
+ this->clear();
+ QJsonDocument doc = QJsonDocument::fromJson( LUtils::getCmdOutput(exec).join(" ").toLocal8Bit() );
+ if(doc.isNull() || !doc.isObject()){
+ this->addAction( QString(tr("Error parsing script output: %1")).arg("\n"+exec) )->setEnabled(false);
+ }else{
+ QStringList keys = doc.object().keys();
+ for(int i=0; i<keys.length(); i++){
+ if(doc.object().value(keys[i]).isObject()){
+ parseObject(keys[i], doc.object().value(keys[i]).toObject());
+ }
+ }
+ }
+ }
+};
+#endif
diff --git a/src-qt5/core/lumina-desktop/LDesktop.cpp b/src-qt5/core/lumina-desktop/LDesktop.cpp
index 772ead8a..c759d641 100644
--- a/src-qt5/core/lumina-desktop/LDesktop.cpp
+++ b/src-qt5/core/lumina-desktop/LDesktop.cpp
@@ -10,6 +10,7 @@
#include <LuminaOS.h>
#include <LuminaX11.h>
#include "LWinInfo.h"
+#include "JsonMenu.h"
#define DEBUG 0
@@ -291,6 +292,17 @@ void LDesktop::UpdateMenu(bool fast){
}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],"") ); }
+ deskMenu->addMenu(tmp);
+ }
}
}
//Now add the system quit options
diff --git a/src-qt5/core/lumina-desktop/fluxboxconf/fluxbox-keys b/src-qt5/core/lumina-desktop/fluxboxconf/fluxbox-keys
index 21027f4c..c3bafdaf 100644
--- a/src-qt5/core/lumina-desktop/fluxboxconf/fluxbox-keys
+++ b/src-qt5/core/lumina-desktop/fluxboxconf/fluxbox-keys
@@ -47,8 +47,10 @@ OnTitlebar Mouse2 :Lower
OnTitlebar Mouse3 :WindowMenu
# alt-tab
-Mod1 Tab :NextWindow {groups} (workspace=[current]) (workspace=[current]) !! FBCV13 !!
-Mod1 Shift Tab :PrevWindow {groups} (workspace=[current]) (workspace=[current]) !! FBCV13 !!
+Mod1 Tab :NextWindow (workspace=[current]) (workspace=[current]) !! FBCV13 !!
+Mod1 Shift Tab :PrevWindow (workspace=[current]) (workspace=[current]) !! FBCV13 !!
+Control Tab :NextGroup (workspace=[current]) (workspace=[current])
+Control Shift Tab :PrevGroup (workspace=[current]) (workspace=[current])
# cycle through tabs in the current window
Mod4 Tab :NextTab
diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro
index 4cebf3de..7b0e5250 100644
--- a/src-qt5/core/lumina-desktop/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro
@@ -27,7 +27,7 @@ SOURCES += main.cpp \
SettingsMenu.cpp \
SystemWindow.cpp \
BootSplash.cpp \
- desktop-plugins/LDPlugin.cpp \
+ desktop-plugins/LDPlugin.cpp
HEADERS += Globals.h \
@@ -48,6 +48,7 @@ HEADERS += Globals.h \
panel-plugins/LTBWidget.h \
desktop-plugins/LDPlugin.h \
desktop-plugins/NewDP.h \
+ JsonMenu.h
FORMS += SystemWindow.ui \
BootSplash.ui
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
index 7e2e53de..0dd68bb0 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
@@ -157,6 +157,12 @@ void LTaskButton::UpdateMenus(){
}
}
actMenu->addAction( LXDG::findIcon("window-close",""), tr("Close Window"), this, SLOT(closeWindow()) );
+ if(WINLIST.length()>1 && !winMenu->isVisible()){
+ actMenu->addSeparator();
+ actMenu->addAction( LXDG::findIcon("layer-visible-on",""), tr("Show All Windows"), this, SLOT(showAllWindows()) );
+ actMenu->addAction( LXDG::findIcon("layer-visible-off",""), tr("Minimize All Windows"), this, SLOT(hideAllWindows()) );
+ actMenu->addAction( LXDG::findIcon("window-close",""), tr("Close All Windows"), this, SLOT(closeAllWindows()) );
+ }
}
//=============
@@ -196,6 +202,29 @@ void LTaskButton::minimizeWindow(){
QTimer::singleShot(100, this, SLOT(UpdateButton()) ); //make sure to update this button if losing active status
}
+void LTaskButton::showAllWindows(){
+ for(int i=WINLIST.length()-1; i>=0; i--){
+ if(WINLIST[i].status()==LXCB::INVISIBLE){
+ LSession::handle()->XCB->RestoreWindow(WINLIST[i].windowID());
+ }
+ }
+}
+
+void LTaskButton::hideAllWindows(){
+ for(int i=WINLIST.length()-1; i>=0; i--){
+ LXCB::WINDOWVISIBILITY state = WINLIST[i].status();
+ if(state==LXCB::VISIBLE || state==LXCB::ACTIVE){
+ LSession::handle()->XCB->MinimizeWindow(WINLIST[i].windowID());
+ }
+ }
+}
+
+void LTaskButton::closeAllWindows(){
+ for(int i=WINLIST.length()-1; i>=0; i--){
+ LSession::handle()->XCB->CloseWindow(WINLIST[i].windowID());
+ }
+}
+
void LTaskButton::triggerWindow(){
LWinInfo win = currentWindow();
//Check which state the window is currently in and flip it to the other
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h b/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
index 43dbaa90..6b171c6a 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
+++ b/src-qt5/core/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
@@ -60,6 +60,9 @@ private slots:
void closeWindow(); //send the signal to close a window
void maximizeWindow(); //send the signal to maximize/restore a window
void minimizeWindow(); //send the signal to minimize a window (iconify)
+ void showAllWindows();
+ void hideAllWindows();
+ void closeAllWindows();
void triggerWindow(); //change b/w visible and invisible
void winClicked(QAction*);
void openActionMenu();
bgstack15