diff options
Diffstat (limited to 'src-qt5/core')
26 files changed, 391 insertions, 128 deletions
diff --git a/src-qt5/core/libLumina/LFileInfo.cpp b/src-qt5/core/libLumina/LFileInfo.cpp index 3b659c75..d4e0cfde 100644 --- a/src-qt5/core/libLumina/LFileInfo.cpp +++ b/src-qt5/core/libLumina/LFileInfo.cpp @@ -6,9 +6,12 @@ //=========================================== #include "LFileInfo.h" #include <LUtils.h> +#include <QRegExp> +#include <unistd.h> LFileInfo::LFileInfo() : QFileInfo(){ desk = 0; + c_uid = -1; } LFileInfo::LFileInfo(QString filepath) : QFileInfo(){ //overloaded contructor @@ -30,6 +33,7 @@ LFileInfo::~LFileInfo(){ void LFileInfo::loadExtraInfo(){ if(desk!=0){ desk->deleteLater(); } desk = 0; + c_uid = geteuid(); //Now load the extra information if(this->absoluteFilePath().startsWith("/net/") || this->isDir() ){ mime = "inode/directory"; @@ -49,7 +53,6 @@ void LFileInfo::loadExtraInfo(){ iconList << "folder"; }else if( this->suffix()=="desktop"){ mime = "application/x-desktop"; - iconList << "application-x-desktop"; //default value desk = new XDGDesktop(this->absoluteFilePath(), 0); if(desk->type!=XDGDesktop::BAD){ //use the specific desktop file info (if possible) @@ -81,8 +84,32 @@ void LFileInfo::getZfsDataset(){ //Use the "atime" property for this check - been around since the earliest versions of ZFS and should take no time to probe QString out = LUtils::runCommand(ok, "zfs", QStringList() << "get" << "-H" << "atime" << this->canonicalFilePath() ); if(!ok){ zfs_ds = "."; } //just something that is not empty - but is clearly not a valid dataset - else{ zfs_ds = out.section("\n",0,0).section("\t",0,0).simplified(); } + else{ + zfs_ds = out.section("\n",0,0).section("\t",0,0).simplified(); + zfs_dspath = this->canonicalFilePath().section(zfs_ds.section("/",1,-1), 1,-1); //relative path + if(!zfs_dspath.isEmpty()){ zfs_dspath.prepend(zfs_ds); } + else{ zfs_dspath = zfs_ds; } //on the current dataset "root" + //qDebug() << "Got ZFS dataset:" << zfs_ds << zfs_dspath; + } //qDebug() << "Found Dataset:" << zfs_ds << out << ok; + if(ok){ + //Also get the list of permissions this user has for modifying the ZFS dataset + QStringList perms = LUtils::runCommand(ok, "zfs", QStringList() << "allow" << zfs_ds ).split("\n"); + //qDebug() << "Permissions:" << perms; + if(!perms.isEmpty() && ok){ + //Now need to filter/combine the permissions for all the groups this user is a part of + QStringList gplist = LUtils::runCommand(ok, "id", QStringList() << "-np").split("\n").filter("groups"); + if(!gplist.isEmpty()){ gplist = gplist.first().replace("\t", " ").split(" ",QString::SkipEmptyParts); gplist.removeAll("groups"); } + for(int i=0; i<gplist.length(); i++){ + QStringList tmp = perms.filter(QRegExp("[user|group] "+gplist[i])); + if(tmp.isEmpty()){ continue; } + zfs_perms << tmp.first().section(" ",2,2,QString::SectionSkipEmpty).split(",",QString::SkipEmptyParts); + } + zfs_perms.removeDuplicates(); + //qDebug() << "Got ZFS Permissions:" << zfs_ds << zfs_perms; + } + } + } } @@ -138,7 +165,11 @@ bool LFileInfo::isAVFile(){ return (mime.startsWith("audio/") || mime.startsWith("video/") ); } -bool LFileInfo::isZfsDataset(){ +bool LFileInfo::isZfsDataset(QString path){ + if(!path.isEmpty() && zfsAvailable() ){ + //manual check of a dir + return (0 == LUtils::runCmd("zfs", QStringList() << "get" << "-H" << "atime" << path) ); + } if(!goodZfsDataset()){ return false; } return ( ("/"+zfs_ds.section("/",1,-1)) == this->canonicalFilePath()); } @@ -185,3 +216,84 @@ bool LFileInfo::zfsSetProperty(QString property, QString value){ if(!ok){ qDebug() << "Error Setting ZFS Property:" << property+"="+value << info; } return ok; } + +//ZFS Permissions/Modifications +bool LFileInfo::canZFScreate(){ + if(!goodZfsDataset()){ return false; } + return (zfs_perms.contains("create") || (c_uid==0) ); +} + +bool LFileInfo::zfsCreateDataset(QString subdir){ + if(!canZFScreate()){ return false; } + if(subdir.startsWith("/")){ qDebug() << "Not a relative path!!"; return false; } + if( QFile::exists(this->canonicalFilePath()+"/"+subdir) ){ + return false; + } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "create" << zfs_dspath+"/"+subdir ); + if(!ok){ qDebug() << "Error Creating ZFS Dataset:" << subdir << info; } + return ok; +} + +bool LFileInfo::canZFSdestroy(){ + if(!goodZfsDataset()){ return false; } + return (zfs_perms.contains("destroy") || (c_uid==0) ); +} + +bool LFileInfo::zfsDestroyDataset(QString subdir){ + if(!canZFSdestroy()){ return false; } + if(!subdir.isEmpty() && !subdir.startsWith("/")){ + if( isZfsDataset(this->canonicalFilePath()+"/"+subdir) ){ subdir = zfs_dspath+"/"+subdir; } + } + else if(subdir.isEmpty() && (zfs_ds == zfs_dspath) ){ subdir = zfs_ds; } + else{ qDebug() << "Invalid subdir:" << subdir; return false; } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "destroy" << subdir); + if(!ok){ qDebug() << "Error Destroying ZFS Dataset:" << subdir << info; } + return ok; +} + +bool LFileInfo::zfsDestroySnapshot(QString snapshot){ + if(!canZFSdestroy()){ return false; } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "destroy" << zfs_ds+"@"+snapshot); + if(!ok){ qDebug() << "Error Destroying ZFS Snapshot:" << snapshot << info; } + return ok; +} + +bool LFileInfo::canZFSclone(){ + if(!goodZfsDataset()){ return false; } + return (zfs_perms.contains("clone") || (c_uid==0) ); +} + +bool LFileInfo::zfsCloneDataset(QString subdir, QString newsubdir){ + if(!canZFSclone()){ return false; } + + return false; +} + +bool LFileInfo::canZFSsnapshot(){ + if(!goodZfsDataset()){ return false; } + return (zfs_perms.contains("snapshot") || (c_uid==0) ); +} + +bool LFileInfo::zfsSnapshot(QString snapname){ + if(!canZFSsnapshot()){ return false; } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "snapshot" << zfs_ds+"@"+snapname); + if(!ok){ qDebug() << "Error Creating ZFS Snapshot:" << snapname << info; } + return ok; +} + +bool LFileInfo::canZFSrollback(){ + if(!goodZfsDataset()){ return false; } + return (zfs_perms.contains("rollback") || (c_uid==0) ); +} + +bool LFileInfo::zfsRollback(QString snapname){ + if(!canZFSrollback()){ return false; } + bool ok = false; + QString info = LUtils::runCommand(ok, "zfs", QStringList() << "rollback" << zfs_ds+"@"+snapname); + if(!ok){ qDebug() << "Error Rolling back to ZFS Snapshot:" << snapname << info; } + return ok; +} diff --git a/src-qt5/core/libLumina/LFileInfo.h b/src-qt5/core/libLumina/LFileInfo.h index f72c8649..21aae19d 100644 --- a/src-qt5/core/libLumina/LFileInfo.h +++ b/src-qt5/core/libLumina/LFileInfo.h @@ -17,8 +17,9 @@ class LFileInfo : public QFileInfo{ private: - QString mime, zfs_ds; - QStringList iconList; + QString mime, zfs_ds, zfs_dspath; + QStringList iconList, zfs_perms; + int c_uid; XDGDesktop *desk; void loadExtraInfo(); @@ -51,12 +52,26 @@ public: bool isVideo(); //Is a readable video file (for thumbnail support) bool isAVFile(); //Is an audio/video file - bool isZfsDataset(); + //ZFS Information + bool isZfsDataset(QString path = ""); QString zfsPool(); QStringList zfsSnapshots(); //Format: "snapshot name::::path/to/snapshot" QJsonObject zfsProperties(); bool zfsSetProperty(QString property, QString value); + //ZFS Permissions/Modifications + bool canZFScreate(); + bool zfsCreateDataset(QString subdir); + bool canZFSdestroy(); + bool zfsDestroyDataset(QString subdir); + bool zfsDestroySnapshot(QString snapshot); + bool canZFSclone(); + bool zfsCloneDataset(QString subdir, QString newsubdir); + bool canZFSsnapshot(); + bool zfsSnapshot(QString snapname); + bool canZFSrollback(); + bool zfsRollback(QString snapname); + }; typedef QList<LFileInfo> LFileInfoList; diff --git a/src-qt5/core/libLumina/LIconCache.cpp b/src-qt5/core/libLumina/LIconCache.cpp index 84428546..c3b0cc1b 100644 --- a/src-qt5/core/libLumina/LIconCache.cpp +++ b/src-qt5/core/libLumina/LIconCache.cpp @@ -53,6 +53,7 @@ bool LIconCache::isLoaded(QString icon){ QString LIconCache::findFile(QString icon){ if(icon.isEmpty()){ return ""; } + //Get the currently-set theme QString cTheme = QIcon::themeName(); if(cTheme.isEmpty()){ @@ -328,7 +329,7 @@ void LIconCache::ReadFile(LIconCache *obj, QString id, QString path){ } bool LIconCache::isThemeIcon(QString id){ - return (!id.contains("/") && !id.contains(".") && !id.contains("libreoffice") ); + return (!id.contains("/") && !id.contains(".") ); //&& !id.contains("libreoffice") ); } QIcon LIconCache::iconFromTheme(QString id){ diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index 95585f1e..a17f1e7c 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -851,7 +851,7 @@ void LXDG::setEnvironmentVars(){ QIcon LXDG::findIcon(QString iconName, QString fallback){ //With the addition of the Lumina theme engine (8/3/17), switch back to using the Qt icon from theme method for apps QIcon tmp; - if(!iconName.contains("libreoffice")){ //libreoffice is stupid - their svg icons are un-renderable with Qt + if(!iconName.contains("libreoffice") || !QIcon::themeName().startsWith("material-design") ){ //libreoffice is stupid - their svg icons are un-renderable with Qt tmp = QIcon::fromTheme(iconName); /*if(iconName.contains("start-here")){ qDebug() << "[ICON]" << iconName << "found:" << !tmp.isNull() << tmp.name(); diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index 1c103fab..5e931e5f 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -169,7 +169,7 @@ void LSession::CleanupSession(){ //Now perform any other cleanup //Lumina::NEF->stop(); //Now wait a moment for things to close down before quitting - if(playaudio){ + if(playaudio && mediaObj!=0){ //wait a max of 5 seconds for audio to finish bool waitmore = true; for(int i=0; i<100 && waitmore; i++){ diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp index 32f84f93..7e763b02 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp @@ -129,6 +129,7 @@ void DesktopManager::NewWindowAvailable(NativeWindowObject* win){ #ifdef USE_WIDGETS qDebug() << "Got New Widget Window:" << win->name(); NativeWindow *tmp = new NativeWindow(win); + //qDebug() << " - Embed Into frame:" << tmp->relativeOrigin(); //Lumina::NWS->RequestReparent(win->id(), win->frameId(), tmp->relativeOrigin()); QTimer::singleShot(10, tmp, SLOT(initProperties()) ); #endif @@ -205,6 +206,24 @@ void DesktopManager::updatePanelSettings(){ } //qDebug() << "Panel Settings Changed:" << total_ids; RootDesktopObject::instance()->setPanels(total_ids); //put the new ones in place + QTimer::singleShot(500, this, SLOT(updatePanelReservations()) ); +} + +void DesktopManager::updatePanelReservations(){ + /*QRect raw_session, reserved_session; + QList<ScreenObject*> screens = RootDesktopObject::instance()->screenObjects(); + //Calculate the total session rectangle and session panel reservations + QList<PanelObject*> tmp = RootDesktopObject::instance()->panelObjectList(); + for(int i=0; i<screens.length(); i++){ + raw_session = raw_session.united(screens[i]->geometry()); + } + for(int i=0; i<tmp.length(); i++){ + reserved_session = + } + //Go through all the panels and calculate the current screen reservations + */ + + } void DesktopManager::updatePluginSettings(){ diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h index b3511318..4d73c8ec 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h @@ -39,6 +39,7 @@ private slots: void updateSessionSettings(); void updateDesktopSettings(); void updatePanelSettings(); + void updatePanelReservations(); void updatePluginSettings(); void updateMenuSettings(); void updateAnimationSettings(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp index c9dd97f8..45aa1101 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp @@ -268,10 +268,11 @@ void NativeWindowObject::updateGeometry(int x, int y, int width, int height, boo QPoint pos(x+fgeom[0], y+fgeom[2]); QSize sz(width-fgeom[0]-fgeom[1], height-fgeom[2]-fgeom[3]); newgeom = QRect(pos, sz); + lastgeom = QRect(x,y,width,height); //save this for later if(!now){ //qDebug() << "Update Geometry:" << fgeom << QRect(x,y,width,height) << pos << sz; //requestProperties(QList<NativeWindowObject::Property>() << NativeWindowObject::GlobalPos << NativeWindowObject::Size, QList<QVariant>() << pos << sz); - if(!geomTimer->isActive()){ geomTimer->start(); } + if(!geomTimer->isActive()){ QTimer::singleShot(0,geomTimer, SLOT(start())); } }else{ sendNewGeom(); } @@ -295,18 +296,23 @@ void NativeWindowObject::toggleMaximize(){ } } //Now compare the current geometry to the screen geometry + qDebug() << "Maximize Toggle:" << curgeom << max; if(curgeom!=max){ + qDebug() << " - maximize"; setGeometryNow(max); //will set newgeom to max - newgeom = curgeom; //now reset newgeom + lastgeom = curgeom; //save this for later }else{ + qDebug() << " - restore" << lastgeom; //Already maximized, look at the old geometry and figure out how to restore it - if(newgeom.isNull()){ + if(lastgeom.isNull() || lastgeom == max){ + qDebug() << " -- Reset lastgeom to half-screen size"; //no old info available - center the window at half maximum size - newgeom = QRect(max.x()-max.width()/2, max.y()-max.height()/2, max.width()/2, max.height()/2); + lastgeom = QRect(max.x()-max.width()/2, max.y()-max.height()/2, max.width()/2, max.height()/2); } - setGeometryNow(newgeom); + setGeometryNow(lastgeom); } - emit geomChanged(); + qDebug() << "After toggle:" << lastgeom; + //emit geomChanged(); } void NativeWindowObject::requestClose(){ diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h index ed52c956..c1851d0e 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h @@ -133,7 +133,7 @@ private: unsigned int dmgID, dmg, icodmg; //Collation/Delay for window resize events QTimer *geomTimer; - QRect newgeom; + QRect newgeom, lastgeom; void emitSinglePropChanged(NativeWindowObject::Property); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp index e8830bde..94079bf7 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp @@ -48,6 +48,7 @@ void PanelObject::setBackground(QString fileOrColor){ void PanelObject::setGeometry( QRect newgeom ){ if(geom!=newgeom){ geom = newgeom; + fullside_geom = geom; //unknown full-side geom - no parent info given emit geomChanged(); } } @@ -88,10 +89,19 @@ void PanelObject::syncWithSettings(QRect parent_geom){ this->setBackground( DesktopSettings::instance()->value(DesktopSettings::Panels, id+"/background", "rgba(0,0,0,120)").toString() ); // qDebug() << "Update Panel:" << panel_id << id << anchor+"/"+align << length << width; //Now calculate the geometry of the panel - QRect newgeom; + QRect newgeom, newfullsidegeom; //Figure out the size of the panel - if(anchor=="top" || anchor=="bottom"){ newgeom.setWidth( parent_geom.width()*length ); newgeom.setHeight(width); } - else{ newgeom.setWidth(width); newgeom.setHeight(parent_geom.height()*length); } + if(anchor=="top" || anchor=="bottom"){ + newgeom.setWidth( parent_geom.width()*length ); newgeom.setHeight(width); + newfullsidegeom.setWidth(parent_geom.width()); newfullsidegeom.setHeight(width); + if(anchor=="top"){ newfullsidegeom.moveTopLeft(QPoint(0,0)); } + else{ newfullsidegeom.moveBottomLeft( QPoint(0, parent_geom.height()) ); } + }else{ + newgeom.setWidth(width); newgeom.setHeight(parent_geom.height()*length); + newfullsidegeom.setWidth(width); newfullsidegeom.setHeight(parent_geom.height()); + if(anchor=="left"){ newfullsidegeom.moveTopLeft(QPoint(0,0)); } + else{ newfullsidegeom.moveTopRight( QPoint(parent_geom.width(), 0) ); } + } //qDebug() << " - Size:" << newgeom; //Now figure out the location of the panel if(align=="left" || align=="top"){ @@ -114,7 +124,9 @@ void PanelObject::syncWithSettings(QRect parent_geom){ //qDebug() << " - Calculated Geometry (relative to parent):" << newgeom; //Note: newgeom is currently in parent-relative coordinates (not global) newgeom.translate(parent_geom.x(), parent_geom.y()); + newfullsidegeom.translate(parent_geom.x(), parent_geom.y()); + fullside_geom = newfullsidegeom; //qDebug() << " - Calculated Geometry (global):" << newgeom; - this->setGeometry(newgeom); //shift to global coordinates + this->setGeometry(newgeom); //in global coordinates this->setPlugins( DesktopSettings::instance()->value(DesktopSettings::Panels, id+"/plugins", QStringList()).toStringList() ); } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h index 5ae75ea4..645e20c0 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h @@ -25,7 +25,7 @@ class PanelObject : public QObject { private: QString panel_id, bg; - QRect geom; + QRect geom, fullside_geom; QStringList panel_plugins; public: @@ -42,6 +42,7 @@ public: Q_INVOKABLE bool isVertical(); Q_INVOKABLE QStringList plugins(); Q_INVOKABLE QRect geometry(){ return geom; } + Q_INVOKABLE QRect fullSideGeometry(){ return fullside_geom; } public slots: void setBackground(QString fileOrColor); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp index d9a81f54..79737ddc 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -18,6 +18,10 @@ RootDesktopObject::RootDesktopObject(QObject *parent) : QObject(parent){ connect(this, SIGNAL(changePanels(QStringList)), this, SLOT(setPanels(QStringList)) ); currentTimeTimer = new QTimer(this); connect(currentTimeTimer, SIGNAL(timeout()), this, SLOT(updateCurrentTime()) ); + availgeomTimer = new QTimer(this); + availgeomTimer->setInterval(100); + availgeomTimer->setSingleShot(true); + connect(availgeomTimer, SIGNAL(timeout()), this, SLOT(submitSessionGeom()) ); } RootDesktopObject::~RootDesktopObject(){ @@ -170,6 +174,16 @@ void RootDesktopObject::setPanels(QStringList ids){ change = true; //list changed } } //end loop over screens+session + //Now calculate the available session geometry + QRegion sess(geom); + for(int i=0; i<panel_objects.length(); i++){ + sess = sess.subtracted( QRegion(panel_objects[i].geometry()) ); + } + if(sess != session_avail_geom){ + session_avail_geom = sess; + emit sessionGeomAvailableChanged(); } + } + if(change){ emit panelsChanged(); } } @@ -242,6 +256,10 @@ QList<NativeWindowObject*> RootDesktopObject::windowObjects(){ return window_objects; } +QList<ScreenObject*> RootDesktopObject::screenObjects(){ + return s_objects; +} + // === PUBLIC SLOTS === void RootDesktopObject::updateScreens(){ QList<QScreen*> scrns = QApplication::screens(); @@ -251,7 +269,11 @@ void RootDesktopObject::updateScreens(){ for(int j=0; j<s_objects.length() && !found; j++){ if(s_objects[j]->name()==scrns[i]->name()){ found = true; tmp << s_objects.takeAt(j); } } - if(!found){ tmp << new ScreenObject(scrns[i], this); } + if(!found){ + //Create new screen object + tmp << new ScreenObject(scrns[i], this); + connect(tmp.last(), SIGNAL(availableGeomChanged()), this, SLOT(availableScreenGeomChanged()) ); + } } //Delete any leftover objects for(int i=0; i<s_objects.length(); i++){ s_objects[i]->deleteLater(); } @@ -291,3 +313,12 @@ void RootDesktopObject::updateCurrentTime(){ emit currentTimeChanged(); } } + +void RootDesktopObject::availableScreenGeomChanged(){ + if(availgeomTimer->isActive()){ availgeomTimer->stop(); } + availgeomTimer->start(); +} + +void RootDesktopObject::submitSessionGeom(){ + //TODO - read off the available geom from each ScreenObject and register that with NativeWindowSystem +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h index 3c525848..4a722ec0 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -57,6 +57,7 @@ public: //C++ Access Functions (simplifications for the QML ones) QList<NativeWindowObject*> windowObjects(); + QList<ScreenObject*> screenObjects(); private: QList<ScreenObject*> s_objects; @@ -64,9 +65,10 @@ private: QList<NativeWindowObject*> window_objects; QList<NativeWindowObject*> tray_window_objects; QPointer<NativeWindowObject> last_window_up; - QTimer *currentTimeTimer; + QTimer *currentTimeTimer, *availgeomTimer; QString currentTimeFormat, currentTimeString; QDateTime currentDateTimeStruct; + QRegion session_avail_geom; public slots: void updateScreens(); //rescan/update screen objects @@ -84,6 +86,8 @@ public slots: private slots: void updateCurrentTime(); + void availableScreenGeomChanged(); + void submitSessionGeom(); signals: void screensChanged(); @@ -91,6 +95,7 @@ signals: void windowsChanged(); void trayWindowsChanged(); void currentTimeChanged(); + void sessionGeomAvailableChanged(); void startLogout(); void mouseMoved(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp index c754906d..d6e0abb6 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -11,6 +11,7 @@ ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){ bg_screen = scrn; connect(this, SIGNAL(changePanels(QStringList)), this, SLOT(setPanels(QStringList)) ); + connect(RootWindowObject::instance(), SIGNAL(sessionGeomAvailableChanged()), this, SLOT(updateAvailableGeometry()) ); } void ScreenObject::RegisterType(){ @@ -49,12 +50,15 @@ void ScreenObject::setPanels(QStringList ids){ return; } + QRegion *sess = RootDesktopObject::instance()->availableGeometry(); + QRect avail = sess->intersected(bg_screen->geometry()).boundingRect(); + if(session_available_geometry.isNull()){ avail = bg_screen->geometry(); } //First update/remove any current panel objects bool change = false; for(int i=0; i<panel_objects.length(); i++){ if(ids.contains(panel_objects[i]->name()) ){ ids.removeAll(panel_objects[i]->name()); //already handled - panel_objects[i]->syncWithSettings(bg_screen->geometry()); + panel_objects[i]->syncWithSettings(avail); }else{ panel_objects.takeAt(i)->deleteLater(); i--; @@ -87,3 +91,23 @@ PanelObject* ScreenObject::panel(QString id){ } return 0; } + +QRect ScreenObject::availableGeometry(){ + return avail_geom; +} + +void ScreenObject::updateAvailableGeometry(){ + QRegion *sess = RootDesktopObject::instance()->availableGeometry(); + QRegion availRegion = sess->intersected(bg_screen->geometry()); + QRect avail = availRegion.boundingRect(); + for(int i=0; i<panel_objects.length(); i++){ + panel_objects[i]->syncWithSettings(avail); + //Note: Use the "full side" geometry to ensure that we are cleanly cutting off the entire side of the region + availRegion = availRegion.subtracted( panel_objects[i]->fullSideGeometry() ); + } + avail = availRegion.boundingRect(); + if(avail != avail_geom){ + avail_geom = avail; + emit availableGeomChanged(); + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h index 250c9403..66c30969 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h @@ -24,11 +24,13 @@ class ScreenObject : public QObject { Q_PROPERTY( int width READ width NOTIFY geomChanged) Q_PROPERTY( int height READ height NOTIFY geomChanged) Q_PROPERTY( QStringList panels READ panels NOTIFY panelsChanged) + Q_PROPERTY( QRect availableGeom READ availableGeometry NOTIFY availableGeomChanged) private: QScreen *bg_screen; QString bg; QList<PanelObject*> panel_objects; + QRect avail_geom; public: ScreenObject(QScreen *scrn = 0, QObject *parent = 0); @@ -44,6 +46,7 @@ public: Q_INVOKABLE QStringList panels(); Q_INVOKABLE PanelObject* panel(QString id); Q_INVOKABLE QRect geometry(){ return bg_screen->geometry(); } + Q_INVOKABLE QRect availableGeometry(); void setPanels(QList<PanelObject*> list); @@ -52,10 +55,12 @@ public: public slots: void setPanels(QStringList ids); void setBackground(QString fileOrColor); + void updateAvailableGeometry(); signals: void backgroundChanged(); void geomChanged(); + void availableGeomChanged(); void panelsChanged(); //Internal signals for thread-safety diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp index 86dd8482..93bff6db 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.cpp @@ -13,7 +13,7 @@ NativeWindow::NativeWindow( NativeWindowObject *obj ) : QFrame(0, Qt::Window | Qt::FramelessWindowHint){ WIN = obj; createFrame(); - WIN->addFrameWinID(container->winId()); + //WIN->addFrameWinID(this->winId()); } NativeWindow::~NativeWindow(){ @@ -23,14 +23,11 @@ NativeWindow::~NativeWindow(){ QPoint NativeWindow::relativeOrigin(){ //Update all the margins for the frame - /*QList<int> frame = WIN->property(NativeWindowObject::FrameExtents).value<QList<int> >(); + QList<int> frame = WIN->property(NativeWindowObject::FrameExtents).value<QList<int> >(); //QList<int> : [Left, Right, Top, Bottom] in pixels - int topM = frame[2] - titleLabel->fontMetrics().height(); //figure out how much extra we have to work with - if(topM<0){ topM = 0; } - int botM = topM/2.0; - QPoint containerCorner(frame[0], topM-botM); - return containerCorner;*/ - return QPoint(0,0); + QPoint containerCorner(frame[0], frame[2]); + return containerCorner; + //return QPoint(0,0); } void NativeWindow::initProperties(){ @@ -59,7 +56,7 @@ void NativeWindow::initProperties(){ syncWinType(); syncGeom(); syncVisibility(true); //init visibility - force it visible to start with - + container->activateWindow(); } // === PRIVATE === @@ -81,13 +78,12 @@ void NativeWindow::createFrame(){ vlayout->setSpacing(0); toolbarL = new QHBoxLayout(); toolbarL->setSpacing(0); - container = QWidget::createWindowContainer(QWindow::fromWinId(WIN->id()), this); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + qDebug() << "Create Native Embed Widget"; + container = new NativeEmbedWidget(this, WIN); + container->widget()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //vlayout.align titleLabel = new QLabel(this); titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - //contentW = new QWidget(this); - //contentW->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //Now put the widgets in the right places toolbarL->addWidget(otherB); toolbarL->addWidget(titleLabel); @@ -95,7 +91,8 @@ void NativeWindow::createFrame(){ toolbarL->addWidget(maxB); toolbarL->addWidget(closeB); vlayout->addLayout(toolbarL); - vlayout->addWidget(container); + //vlayout->addStretch(); + vlayout->addWidget(container->widget()); this->setLayout(vlayout); // Load the icons for the buttons loadIcons(); @@ -115,7 +112,7 @@ void NativeWindow::syncWinImage(){ } void NativeWindow::syncName(){ - qDebug() << "Got Name Change:" << WIN->name(); + //qDebug() << "Got Name Change:" << WIN->name(); } void NativeWindow::syncTitle(){ @@ -129,20 +126,20 @@ void NativeWindow::syncIcon(){ } void NativeWindow::syncSticky(){ - qDebug() << "Got Sticky Change:" << WIN->isSticky(); + //qDebug() << "Got Sticky Change:" << WIN->isSticky(); } void NativeWindow::syncVisibility(bool init){ if(init){ WIN->setProperty(NativeWindowObject::Visible, true, true); //force it - }else{ - qDebug() << "Sync Visibility:" << WIN->isVisible(); + }else if(this->isVisible() != WIN->isVisible()){ + //qDebug() << "Sync Visibility:" << WIN->isVisible(); this->setVisible(WIN->isVisible()); } } void NativeWindow::syncWinType(){ - qDebug() << "Sync Win Type"; + //qDebug() << "Sync Win Type"; closeB->setVisible(WIN->showCloseButton()); maxB->setVisible(WIN->showMaxButton()); minB->setVisible(WIN->showMinButton()); @@ -163,7 +160,10 @@ void NativeWindow::syncWinType(){ } void NativeWindow::syncGeom(){ - qDebug() << "Sync Geometry:" << WIN->name(); - qDebug() << " Frame:" << WIN->frameGeometry() << "Win:" << WIN->imageGeometry(); - this->setGeometry( WIN->frameGeometry() ); + //qDebug() << "Sync Geometry:" << WIN->name(); + //qDebug() << " Frame:" << WIN->frameGeometry() << "Win:" << WIN->imageGeometry(); + QRect geom = WIN->frameGeometry(); + if(geom!=this->geometry()){ + this->setGeometry( geom ); + } } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h index f2fd822c..47699ae6 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/NativeWindow.h @@ -9,6 +9,7 @@ #include <global-includes.h> #include <NativeWindowObject.h> +#include "NativeEmbedWidget.h" class NativeWindow : public QFrame{ Q_OBJECT @@ -32,7 +33,8 @@ private: QHBoxLayout *toolbarL; QVBoxLayout *vlayout; QLabel *titleLabel; - QWidget *container; + NativeEmbedWidget *container; + // Info cache variables QRect oldgeom; 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 index 7ed228f7..5ed94f1b 100644 --- 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 @@ -9,5 +9,6 @@ SOURCES *= $${PWD}/RootDesktop.cpp \ HEADERS *= $${PWD}/RootDesktop.h \ $${PWD}/ContextMenu.h \ $${PWD}/NativeWindow.h \ + $${PWD}/NativeEmbedWidget.h \ $${PWD}/Panel.h \ $${PWD}/Plugin.h diff --git a/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp index 0d1e9c10..2afdd8c2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp @@ -568,12 +568,12 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindowObject* win, QList< } if(props.contains(NativeWindowObject::Visible)){ - qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindowObject::Visible) ]; + //qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindowObject::Visible) ]; if( vals[ props.indexOf(NativeWindowObject::Visible) ].toBool() ){ - qDebug() << " - Map it!"; + //qDebug() << " - Map it!"; xcb_map_window(QX11Info::connection(), win->id()); }else{ - qDebug() << " - Unmap it!"; + //qDebug() << " - Unmap it!"; xcb_unmap_window(QX11Info::connection(), win->id()); } } @@ -630,6 +630,7 @@ void NativeWindowSystem::SetupNewWindow(NativeWindowObject *win){ Damage dmgID = XDamageCreate(QX11Info::display(), win->id(), XDamageReportRawRectangles); win->addDamageID( (uint) dmgID); //save this for later + registerClientEvents(win->id()); }else{ /* //xcb_reparent_window(QX11Info::connection(), win->id(), this->winId(), 0, 0); @@ -643,7 +644,7 @@ void NativeWindowSystem::SetupNewWindow(NativeWindowObject *win){ */ } //win->addFrameWinID(this->winId()); - registerClientEvents(win->id()); + //registerClientEvents(win->id()); } QImage NativeWindowSystem::GetWindowImage(NativeWindowObject* win){ @@ -802,7 +803,7 @@ void NativeWindowSystem::NewWindowDetected(WId id){ NativeWindowObject *win = new NativeWindowObject(id); //Register for events from this window - registerClientEvents(win->id()); + //registerClientEvents(win->id()); NWindows << win; UpdateWindowProperties(win, NativeWindowObject::allProperties()); if(win->showWindowFrame()){ @@ -815,11 +816,16 @@ void NativeWindowSystem::NewWindowDetected(WId id){ connect(win, SIGNAL(RequestPing(WId)), this, SLOT(RequestPing(WId)) ); connect(win, SIGNAL(RequestReparent(WId, WId, QPoint)), this, SLOT(RequestReparent(WId, WId, QPoint)) ); connect(win, SIGNAL(RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>)), this, SLOT(RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>)) ); - connect(win, SIGNAL(VerifyNewGeometry(WId)), this, SLOT(CheckWindowPosition(WId)) ); + connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(WindowCloseDetected(WId)) ); + //connect(win, SIGNAL(VerifyNewGeometry(WId)), this, SLOT(CheckWindowPosition(WId)) ); + qDebug() << " - Setup New Window"; SetupNewWindow(win); - CheckWindowPosition(id, true); //first time placement - xcb_map_window(QX11Info::connection(), win->id()); + qDebug() << " - Setup window position"; + CheckWindowPosition(win, true); //first time placement + //xcb_map_window(QX11Info::connection(), win->id()); + qDebug() << " - Emit new window signal"; emit NewWindowAvailable(win); + connect(win, SIGNAL(VerifyNewGeometry(WId)), this, SLOT(CheckWindowPosition(WId)) ); } void NativeWindowSystem::NewTrayWindowDetected(WId id){ diff --git a/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h index f6033674..405d3bc3 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h @@ -140,6 +140,7 @@ private slots: void ArrangeWindows(WId primary, QString type); void TileWindows(WId primary, QString type); void CheckWindowPosition(WId id, bool newwindow = false); + void CheckWindowPosition(NativeWindowObject *win, bool newwindow = false); void arrangeWindows(NativeWindowObject *primary, QString type, bool primaryonly = false); signals: diff --git a/src-qt5/core/lumina-desktop-unified/src-events/Window-mgmt.cpp b/src-qt5/core/lumina-desktop-unified/src-events/Window-mgmt.cpp index 0b45c208..23bd3e40 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/Window-mgmt.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/Window-mgmt.cpp @@ -91,8 +91,13 @@ void NativeWindowSystem::CheckWindowPosition(WId id, bool newwindow){ //used after a "drop" to validate/snap/re-arrange window(s) as needed // if "newwindow" is true, then this is the first-placement routine for a window before it initially appears NativeWindowObject* win = findWindow(id); + CheckWindowPosition(win, newwindow); +} + +void NativeWindowSystem::CheckWindowPosition(NativeWindowObject *win, bool newwindow){ if(win==0){ return; } //invalid window QRect geom = win->geometry(); + qDebug() << "Got Window Geometry:" << geom; bool changed = false; //Make sure it is on the screen (quick check) if(geom.x() < 0){ changed = true; geom.moveLeft(0); } @@ -101,5 +106,6 @@ void NativeWindowSystem::CheckWindowPosition(WId id, bool newwindow){ if(geom.height() < 20){ changed = true; geom.setHeight(100); } if(changed){ win->setGeometryNow(geom); } //Now run it through the window arrangement routine + qDebug() << "ArrangeWindows"; arrangeWindows(win, newwindow ?"center" : "snap", true); } diff --git a/src-qt5/core/lumina-desktop/LSession.cpp b/src-qt5/core/lumina-desktop/LSession.cpp index fe399e40..1e686e51 100644 --- a/src-qt5/core/lumina-desktop/LSession.cpp +++ b/src-qt5/core/lumina-desktop/LSession.cpp @@ -95,6 +95,64 @@ LSession::~LSession(){ } } +//Static function so everything can get the same icon name +QString LSession::batteryIconName(int charge, bool charging){ + int icon = -1; + if (charge > 90) { icon = 4; } + else if (charge > 70) { icon = 3; } + else if (charge > 20) { icon = 2; } + else if (charge > 5) { icon = 1; } + else if (charge > 0 ) { icon = 0; } + if(charging){ icon = icon+10; } + QStringList iconList; + switch (icon) { + case 0: + iconList << "battery-20" << "battery-020" << "battery-empty" << "battery-caution"; + break; + case 1: + iconList << "battery-40" << "battery-040" << "battery-low" << "battery-caution"; + break; + case 2: + iconList << "battery-60" << "battery-060" << "battery-good"; + break; + case 3: + iconList << "battery-80" << "battery-080" << "battery-good"; + break; + case 4: + iconList << "battery-100" << "battery-full"; + break; + case 10: + iconList << "battery-20-charging" << "battery-020-charging" << "battery-empty-charging" << "battery-caution-charging" + << "battery-charging-20" << "battery-charging-020" << "battery-charging-empty" << "battery-charging-caution"; + break; + case 11: + iconList << "battery-40-charging" << "battery-040-charging" << "battery-low-charging" << "battery-caution-charging" + << "battery-charging-40" << "battery-charging-040" << "battery-charging-low" << "battery-charging-caution"; + break; + case 12: + iconList << "battery-60-charging" << "battery-060-charging" << "battery-good-charging" + << "battery-charging-60" << "battery-charging-060" << "battery-charging-good"; + break; + case 13: + iconList << "battery-80-charging" << "battery-080-charging" << "battery-good-charging" + << "battery-charging-80" << "battery-charging-080" << "battery-charging-good"; + break; + case 14: + if(charge==100){ iconList << "battery-full-charged"; } + iconList << "battery-100-charging" << "battery-full-charging" + << "battery-charging-100" << "battery-charging-full"; + break; + default: + iconList << "battery-unknown" << "battery-missing"; + break; + } + iconList << "battery"; //generic battery icon + for(int i=0; i<iconList.length(); i++){ + if( QIcon::hasThemeIcon(iconList[i]) ){ return iconList[i]; } + } + return ""; //no icon found +} + void LSession::setupSession(){ //Seed random number generator (if needed) qsrand( QTime::currentTime().msec() ); @@ -205,7 +263,8 @@ void LSession::CleanupSession(){ if(vol>=0){ sessionsettings->setValue("last_session_state/audio_volume", vol); } bool playaudio = sessionsettings->value("PlayLogoutAudio",true).toBool(); if( playaudio ){ - QString sfile = sessionsettings->value("audiofiles/logout", LOS::LuminaShare()+"Logout.ogg").toString(); + QString sfile = sessionsettings->value("audiofiles/logout", "").toString(); + if(sfile.isEmpty() || !QFile::exists(sfile)){ sfile = LOS::LuminaShare()+"Logout.ogg"; } playAudioFile(sfile); } //Stop the background system tray (detaching/closing apps as necessary) @@ -242,7 +301,7 @@ void LSession::CleanupSession(){ // this will leave the wallpapers up for a few moments (preventing black screens) } //Now wait a moment for things to close down before quitting - if(playaudio){ + if(playaudio && mediaObj!=0){ //wait a max of 5 seconds for audio to finish bool waitmore = true; for(int i=0; i<100 && waitmore; i++){ @@ -312,7 +371,8 @@ void LSession::launchStartupApps(){ //Now play the login music since we are finished if(sessionsettings->value("PlayStartupAudio",true).toBool()){ - QString sfile = sessionsettings->value("audiofiles/login", LOS::LuminaShare()+"Login.ogg").toString(); + QString sfile = sessionsettings->value("audiofiles/login", "").toString(); + if(sfile.isEmpty() || !QFile::exists(sfile)){ sfile = LOS::LuminaShare()+"Login.ogg"; } playAudioFile(sfile); } //qDebug() << "[DESKTOP INIT FINISHED]"; diff --git a/src-qt5/core/lumina-desktop/LSession.h b/src-qt5/core/lumina-desktop/LSession.h index 824eede7..bc36b6b8 100644 --- a/src-qt5/core/lumina-desktop/LSession.h +++ b/src-qt5/core/lumina-desktop/LSession.h @@ -53,6 +53,8 @@ public: LSession(int &argc, char **argv); ~LSession(); + static QString batteryIconName(int charge, bool charging); + static bool checkUserFiles(); //Functions to be called during startup void setupSession(); diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp index 1870eefb..10ac2507 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp @@ -30,72 +30,31 @@ LBattery::~LBattery(){ void LBattery::updateBattery(bool force){ // Get current state of charge - //QStringList result = LUtils::getCmdOutput("/usr/sbin/apm", QStringList() << "-al"); - int charge = LOS::batteryCharge(); //result.at(1).toInt(); -//qDebug() << "1: " << result.at(0).toInt() << " 2: " << result.at(1).toInt(); - int icon = -1; - if (charge > 90) { icon = 4; } - else if (charge > 70) { icon = 3; } - else if (charge > 20) { icon = 2; } - else if (charge > 5) { icon = 1; } - else if (charge > 0 ) { icon = 0; } - if(LOS::batteryIsCharging()){ icon = icon+10; } - //icon = icon + result.at(0).toInt() * 10; - if (icon != iconOld || force) { - switch (icon) { - case 0: - label->setPixmap( LXDG::findIcon("battery-20","battery-caution").pixmap(label->size()) ); - break; - case 1: - label->setPixmap( LXDG::findIcon("battery-40", "battery-040").pixmap(label->size()) ); - break; - case 2: - label->setPixmap( LXDG::findIcon("battery-60", "battery-060").pixmap(label->size()) ); - break; - case 3: - label->setPixmap( LXDG::findIcon("battery-80", "battery-080").pixmap(label->size()) ); - break; - case 4: - label->setPixmap( LXDG::findIcon("battery-100", "battery").pixmap(label->size()) ); - break; - case 10: - label->setPixmap( LXDG::findIcon("battery-charging-20", "battery-charging-caution").pixmap(label->size()) ); - break; - case 11: - label->setPixmap( LXDG::findIcon("battery-charging-40", "battery-charging-040").pixmap(label->size()) ); - break; - case 12: - label->setPixmap( LXDG::findIcon("battery-charging-60", "battery-charging-060").pixmap(label->size()) ); - break; - case 13: - label->setPixmap( LXDG::findIcon("battery-charging-80", "battery-charging-080").pixmap(label->size()) ); - break; - case 14: - label->setPixmap( LXDG::findIcon("battery-charging-100", "battery-charging").pixmap(label->size()) ); - break; - default: - label->setPixmap( LXDG::findIcon("battery-unknown", "battery-missing").pixmap(label->size()) ); - break; - } - } - if(icon<iconOld && icon==0){ - //Play some audio warning chime when - bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool(); - if( playaudio ){ - QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString(); - LSession::handle()->playAudioFile(sfile); + int charge = LOS::batteryCharge(); + bool charging = LOS::batteryIsCharging(); + QString batt_icon = LSession::batteryIconName(charge, charging); + if(iconOld != batt_icon){ + label->setPixmap( QIcon::fromTheme(batt_icon).pixmap(label->size()) ); + if(charge <= 5 && !charging){ + //Play some audio warning chime when + bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool(); + if( playaudio ){ + QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", "").toString(); + if(sfile.isEmpty()){ sfile = LOS::LuminaShare()+"low-battery.ogg"; } + LSession::handle()->playAudioFile(sfile); + } } + iconOld = batt_icon; //save for later } - if(icon==0){ label->setStyleSheet("QLabel{ background: red;}"); } - else if(icon==14 && charge>98){ label->setStyleSheet("QLabel{ background: green;}"); } + if(charge<=5 && !charging){ label->setStyleSheet("QLabel{ background: red;}"); } + else if(charge>98 && charging){ label->setStyleSheet("QLabel{ background: green;}"); } else{ label->setStyleSheet("QLabel{ background: transparent;}"); } - iconOld = icon; //Now update the display QString tt; //Make sure the tooltip can be properly translated as necessary (Ken Moore 5/9/14) - if(icon > 9 && icon < 15){ tt = QString(tr("%1 % (Charging)")).arg(QString::number(charge)); } + if(charging){ tt = QString(tr("%1 % (Charging)")).arg(QString::number(charge)); } else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); } label->setToolTip(tt); } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h index 3c23be1c..e2fa411d 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h @@ -29,7 +29,7 @@ public: private: QTimer *timer; QLabel *label; - int iconOld; + QString iconOld; QSettings *sessionsettings; private slots: diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp index ee3e0f80..e0ac6639 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp @@ -465,24 +465,18 @@ void StartMenu::on_stackedWidget_currentChanged(int val){ if(!ui->label_status_battery->whatsThis().isEmpty()){ //Battery available - update the status button int charge = LOS::batteryCharge(); - QString TT, ICON; - if(charge<=5){ ICON="-20"; } - else if(charge<=20){ ICON="-40"; } - else if(charge<=70){ ICON="-60"; } - else if(charge<=90){ ICON="-80"; } - else{ ICON="-100"; } - if(LOS::batteryIsCharging()){ - if(charge>=80){ ICON.clear(); } //for charging, there is no suffix to the icon name over 80% - ICON.prepend("battery-charging"); + bool charging = LOS::batteryIsCharging(); + QString batt_icon = LSession::batteryIconName(charge, charging); + QString TT; + if(charging){ TT = QString(tr("%1% (Plugged In)")).arg(QString::number(charge)); }else{ - ICON.prepend("battery"); int secs = LOS::batterySecondsLeft(); if(secs>1){ TT = QString(tr("%1% (%2 Estimated)")).arg(QString::number(charge), LUtils::SecondsToDisplay(secs)); } else{ TT = QString(tr("%1% Remaining")).arg(QString::number(charge)); } } //qDebug() << " Battery Icon:" << ICON << val << TT - ui->label_status_battery->setPixmap( LXDG::findIcon(ICON,"").pixmap(ui->tool_goto_apps->iconSize()/2) ); + ui->label_status_battery->setPixmap( QIcon::fromTheme(batt_icon).pixmap(ui->tool_goto_apps->iconSize()/2) ); ui->label_status_battery->setToolTip(TT); } //Network Status |