diff options
author | Weblate <noreply@weblate.org> | 2017-11-04 19:28:17 +0000 |
---|---|---|
committer | Weblate <noreply@weblate.org> | 2017-11-04 19:28:17 +0000 |
commit | 7787f617656751ee7e0a58c813d0bfd5757c5c97 (patch) | |
tree | 48aa053bbd4fda9c64f89a061a2f442c860ab13d /src-qt5/core | |
parent | Translated using Weblate (Lithuanian) (diff) | |
parent | Merge pull request #497 from a-stjohn/patch-1 (diff) | |
download | lumina-7787f617656751ee7e0a58c813d0bfd5757c5c97.tar.gz lumina-7787f617656751ee7e0a58c813d0bfd5757c5c97.tar.bz2 lumina-7787f617656751ee7e0a58c813d0bfd5757c5c97.zip |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'src-qt5/core')
119 files changed, 2019 insertions, 3309 deletions
diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index b1e56af8..2a6f4949 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -15,6 +15,7 @@ #include <QString> #include <QTimer> #include <QApplication> +#include <QDebug> class ExternalProcess : public QProcess{ Q_OBJECT @@ -23,18 +24,21 @@ private: private slots: void resetCursor(){ + //qDebug() << "External Process: Reset Mouse Cursor =" << !cursorRestored; if(!cursorRestored){ QApplication::restoreOverrideCursor(); cursorRestored = true; } } void processStarting(){ + //qDebug() << "Starting External Process: Mouse Notification =" << !cursorRestored; if(!cursorRestored){ - QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); - QTimer::singleShot(15000, this, SLOT(resetCursor()) ); + QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) ); + QTimer::singleShot(3000, this, SLOT(resetCursor()) ); } } void processFinished(){ + //qDebug() << "External Process Finished: Reset Mouse Cursor =" << !cursorRestored; if(!cursorRestored){ QApplication::restoreOverrideCursor(); cursorRestored = true; @@ -53,6 +57,7 @@ public: this->setStandardOutputFile(logfile); } //Setup the connection for automatic cleanup + connect(this, SIGNAL(started()), this, SLOT(processStarting()) ); connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished()) ); } @@ -62,7 +67,7 @@ public: }*/ } - static void launch(QString program, QStringList args = QStringList(), bool manageCursors = false){ + static void launch(QString program, QStringList args = QStringList(), bool manageCursors = true){ //Quick launch of a process with logging disabled and automatic cleanup ExternalProcess *tmp = new ExternalProcess("", manageCursors); if(args.isEmpty()){ tmp->start(program); } diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 54e660e6..f1b3de17 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -155,8 +155,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(sysDefaults.isEmpty()){ sysDefaults = LUtils::readFile(LOS::LuminaShare()+"luminaDesktop.conf"); } //Find the number of the left-most desktop screen QString screen = "0"; - QDesktopWidget *desk =QApplication::desktop(); QRect screenGeom; + QDesktopWidget *desk =QApplication::desktop(); for(int i=0; i<desk->screenCount(); i++){ if(desk->screenGeometry(i).x()==0){ screen = QString::number(i); @@ -401,7 +401,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QStringList syscolors = LTHEME::availableSystemColors(); //theme file //qDebug() << "Detected Themes/colors:" << systhemes << syscolors; - if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss.template")){ + if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss")){ themesettings[0] = themesettings[0].section(".qss",0,0).simplified(); for(int i=0; i<systhemes.length(); i++){ if(systhemes[i].startsWith(themesettings[0]+"::::",Qt::CaseInsensitive)){ @@ -411,9 +411,9 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } } //color file - if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".qss.colors") ){ + if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".conf") ){ //Remove any extra/invalid extension - themesettings[1] = themesettings[1].section(".qss",0,0).simplified(); + themesettings[1] = themesettings[1].section(".conf",0,0).simplified(); for(int i=0; i<syscolors.length(); i++){ if(syscolors[i].startsWith(themesettings[1]+"::::",Qt::CaseInsensitive)){ themesettings[1] = syscolors[i].section("::::",1,1); //Replace with the full path @@ -434,13 +434,6 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Now save the settings files if(setTheme){ LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]); - QSettings themeset("lthemeengine","lthemeengine"); - themeset.setValue("Appearance/icon_theme",themesettings[2]); - //Quick hack for a "dark" theme/color to be uniform across the desktop/applications - if(themesettings[0].contains("DarkGlass") || themesettings[1].contains("Black")){ - themeset.setValue("Appearance/custom_palette", true); - themeset.setValue("Appearance/color_scheme_path", LOS::LuminaShare().section("/",0,-3)+"/lthemeengine/colors/darker.conf"); - } } LUtils::writeFile(setdir+"/sessionsettings.conf", sesset, true); LUtils::writeFile(setdir+"/desktopsettings.conf", deskset, true); @@ -463,12 +456,14 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } -bool LDesktopUtils::checkUserFiles(QString lastversion){ +bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ + //WARNING: Make sure you create a QApplication instance before calling this function!!! + //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] //returns true if something changed int oldversion = LDesktopUtils::VersionStringToNumber(lastversion); - int nversion = LDesktopUtils::VersionStringToNumber(QApplication::applicationVersion()); + int nversion = LDesktopUtils::VersionStringToNumber(currentversion); bool newversion = ( oldversion < nversion ); //increasing version number bool newrelease = ( lastversion.contains("-devel", Qt::CaseInsensitive) && QApplication::applicationVersion().contains("-release", Qt::CaseInsensitive) ); //Moving from devel to release @@ -510,6 +505,43 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){ } LUtils::writeFile(dset, DS, true); } + if(oldversion<1003004){ + //Lumina 1.3.4 - Migrate theme settings from old format to the new theme engine format + QString themefile = QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/lthemeengine.conf"; + if(!QFile::exists(themefile)){ + QDir dir; + dir.mkpath(themefile.section("/",0,-2)); //make sure the main directory exists first + //Need to migrate theme settings from the old location to the new one + QSettings newtheme(themefile, QSettings::NativeFormat); + qDebug() << "Migrating Theme settings:" << newtheme.fileName(); + QStringList oldtheme = LUtils::readFile( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg" ); + //Find the system install location for the theme engine for use later + QString enginedir = LOS::LuminaShare()+"/../lthemeengine/"; + //Find/match the icon theme + QString tmp = oldtheme.filter("ICONTHEME=").join("\n").section("=",1,-1).section("\n",0,0).simplified(); + if(tmp.isEmpty()){ tmp = "material-design-light"; } //unknown Icon theme - use the default "light" version + newtheme.setValue("Appearance/icon_theme",tmp); + //Quick detect/adjust of the tone of the color theme based on the icons/colors (no 1-to-1 color theme matching between systems) + bool isdarktheme = tmp.contains("dark"); + isdarktheme = isdarktheme || oldtheme.filter("COLORFILE=").join("\n").section("=",1,-1).section("\n",0,0).contains("DarkGlass"); + //Quick adjust for the material-design icon theme to make it match the current dark/light theme + if(tmp.contains("material-design")){ + newtheme.setValue("Appearance/icon_theme", QString("material-design-")+ (isdarktheme ? "dark" : "light") ); + } + if(isdarktheme){ + newtheme.setValue("Appearance/custom_palette", true); + newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/darker.conf"); + newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/DarkGlass.qss"); + }else{ + newtheme.setValue("Appearance/custom_palette", true); + newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/airy.conf"); + newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/Glass.qss"); + } + newtheme.setValue("Appearance/style", "Fusion"); + newtheme.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss"); + newtheme.sync(); //flush this to file right now + } //end check for theme file existance + } //Check the fluxbox configuration files dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; diff --git a/src-qt5/core/libLumina/LDesktopUtils.h b/src-qt5/core/libLumina/LDesktopUtils.h index a9b44c67..b0ce6ba5 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.h +++ b/src-qt5/core/libLumina/LDesktopUtils.h @@ -43,7 +43,7 @@ public: //Load the default setup for the system static void LoadSystemDefaults(bool skipOS = false); - static bool checkUserFiles(QString lastversion); //returns true if something changed + static bool checkUserFiles(QString lastversion, QString currentversion); //returns true if something changed static int VersionStringToNumber(QString version); //convert the lumina version string to a number for comparisons //Migrating desktop settings from one ID to another diff --git a/src-qt5/core/libLumina/LDesktopUtils.pri b/src-qt5/core/libLumina/LDesktopUtils.pri index 80bbcfa8..fcacc586 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.pri +++ b/src-qt5/core/libLumina/LDesktopUtils.pri @@ -5,3 +5,4 @@ INCLUDEPATH *= ${PWD} #Now the other dependendies of it include(LUtils.pri) +include(LuminaThemes.pri) diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp index 491778ca..3d3c878a 100644 --- a/src-qt5/core/libLumina/LUtils.cpp +++ b/src-qt5/core/libLumina/LUtils.cpp @@ -14,7 +14,7 @@ #include <unistd.h> -inline QStringList ProcessRun(QString cmd, QStringList args){ +/*inline QStringList ProcessRun(QString cmd, QStringList args){ //Assemble outputs QStringList out; out << "1" << ""; //error code, string output QProcess proc; @@ -38,50 +38,58 @@ inline QStringList ProcessRun(QString cmd, QStringList args){ out[0] = QString::number(proc.exitCode()); out[1] = info+QString(proc.readAllStandardOutput()); return out; -} +}*/ + //============= // LUtils Functions //============= -int LUtils::runCmd(QString cmd, QStringList args){ - /*QProcess proc; - proc.setProcessChannelMode(QProcess::MergedChannels); - if(args.isEmpty()){ - proc.start(cmd); - }else{ - proc.start(cmd, args); +QString LUtils::runCommand(bool &success, QString command, QStringList arguments, QString workdir, QStringList env){ + QProcess proc; + proc.setProcessChannelMode(QProcess::MergedChannels); //need output + //First setup the process environment as necessary + QProcessEnvironment PE = QProcessEnvironment::systemEnvironment(); + if(!env.isEmpty()){ + for(int i=0; i<env.length(); i++){ + if(!env[i].contains("=")){ continue; } + PE.insert(env[i].section("=",0,0), env[i].section("=",1,100)); + } + } + proc.setProcessEnvironment(PE); + //if a working directory is specified, check it and use it + if(!workdir.isEmpty()){ + proc.setWorkingDirectory(workdir); } - //if(!proc.waitForStarted(30000)){ return 1; } //process never started - max wait of 30 seconds - while(!proc.waitForFinished(300)){ + //Now run the command (with any optional arguments) + if(arguments.isEmpty()){ proc.start(command); } + else{ proc.start(command, arguments); } + //Wait for the process to finish (but don't block the event loop) + QString info; + while(!proc.waitForFinished(1000)){ if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal - QCoreApplication::processEvents(); + QString tmp = proc.readAllStandardOutput(); + if(tmp.isEmpty()){ proc.terminate(); } + else{ info.append(tmp); } } - int ret = proc.exitCode(); - return ret;*/ - QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); - return future.result()[0].toInt(); //turn it back into an integer return code + info.append(proc.readAllStandardOutput()); //make sure we don't miss anything in the output + success = (proc.exitCode()==0); //return success/failure + return info; +} + +int LUtils::runCmd(QString cmd, QStringList args){ + bool success; + LUtils::runCommand(success, cmd, args); + return success; + + /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); + return future.result()[0].toInt(); //turn it back into an integer return code*/ } QStringList LUtils::getCmdOutput(QString cmd, QStringList args){ - /*QProcess proc; - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert("LANG", "C"); - env.insert("LC_MESSAGES", "C"); - proc.setProcessEnvironment(env); - proc.setProcessChannelMode(QProcess::MergedChannels); - if(args.isEmpty()){ - proc.start(cmd); - }else{ - proc.start(cmd,args); - } - //if(!proc.waitForStarted(30000)){ return QStringList(); } //process never started - max wait of 30 seconds - while(!proc.waitForFinished(300)){ - if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal - QCoreApplication::processEvents(); - } - QStringList out = QString(proc.readAllStandardOutput()).split("\n"); - return out;*/ - QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); - return future.result()[1].split("\n"); //Split the return message into lines + bool success; + QString log = LUtils::runCommand(success, cmd, args); + return log.split("\n"); + /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); + return future.result()[1].split("\n"); //Split the return message into lines*/ } QStringList LUtils::readFile(QString filepath){ @@ -113,6 +121,10 @@ bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){ } bool LUtils::isValidBinary(QString& bin){ + //Trim off any quotes + if(bin.startsWith("\"") && bin.endsWith("\"")){ bin.chop(1); bin = bin.remove(0,1); } + if(bin.startsWith("\'") && bin.endsWith("\'")){ bin.chop(1); bin = bin.remove(0,1); } + //Now look for relative/absolute path if(!bin.startsWith("/")){ //Relative path: search for it on the current "PATH" settings QStringList paths = QString(qgetenv("PATH")).split(":"); diff --git a/src-qt5/core/libLumina/LUtils.h b/src-qt5/core/libLumina/LUtils.h index a494d4da..ee04c023 100644 --- a/src-qt5/core/libLumina/LUtils.h +++ b/src-qt5/core/libLumina/LUtils.h @@ -30,6 +30,9 @@ class LUtils{ public: + //Run an external command and return output & exit code + static QString runCommand(bool &success, QString command, QStringList arguments = QStringList(), QString workdir = "", QStringList env = QStringList()); + //Run an external command and return the exit code static int runCmd(QString cmd, QStringList args = QStringList()); //Run an external command and return any text output (one line per entry) diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp new file mode 100644 index 00000000..bddb1cba --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -0,0 +1,120 @@ +#include "LVideoLabel.h" +#include <LuminaXDG.h> +#include <QCoreApplication> + +LVideoLabel::LVideoLabel(QString file, bool icons, QWidget *parent) : QLabel(parent) { + thumbnail = QPixmap(); + entered = false; + this->icons = icons; + filepath = file; + defaultThumbnail = LXDG::findIcon("unknown", "").pixmap(256,256); + + QTimer::singleShot(0, this, SLOT(initializeBackend()) ); +} + +LVideoLabel::~LVideoLabel() { + mediaPlayer->deleteLater(); + surface->deleteLater(); +} + +void LVideoLabel::initializeBackend(){ + mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + surface = new LVideoSurface(this); + mediaPlayer->setVideoOutput(surface); + mediaPlayer->setPlaybackRate(3); + mediaPlayer->setMuted(true); + + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); + mediaPlayer->play(); + + this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); + this->connect(mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(stateChanged(QMediaPlayer::State))); + this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); + this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); +} + +void LVideoLabel::enableIcons() { + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + icons = true; +} + +void LVideoLabel::disableIcons() { + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + icons = false; +} + +void LVideoLabel::stopVideo(QPixmap pix) { + if(!entered) { + emit frameReceived(pix); + if(thumbnail.isNull()) + thumbnail = pix; + if(icons) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + mediaPlayer->pause(); + }else { + if(icons) + this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio)); + } +} + +void LVideoLabel::stateChanged(QMediaPlayer::State state) { + //qDebug() << state; +} + +void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { + //qDebug() << status; + if(status == QMediaPlayer::BufferedMedia && !entered) { //Set duration in the middle to capture the thumbnail + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + mediaPlayer->play(); + }else if(status == QMediaPlayer::EndOfMedia && entered) { //Loop back to the beginning if playback started and at the end of the video + mediaPlayer->setPosition(0); + mediaPlayer->play(); + }else if(status == QMediaPlayer::InvalidMedia){ + mediaPlayer->stop(); + mediaPlayer->play(); + }/*else if(status == QMediaPlayer::LoadingMedia) { + mediaPlayer->pause(); + QTimer timer; + timer.setSingleShot(true); + timer.setInterval(300); + timer.start(); + qDebug() << "Timer Started" << timer.remainingTime(); + while(timer.isActive()) QCoreApplication::processEvents(QEventLoop::AllEvents, 5); + qDebug() << "Timer Finished" << timer.remainingTime(); + mediaPlayer->setPosition(0); + mediaPlayer->play(); + }*/ +} + +void LVideoLabel::resizeEvent(QResizeEvent *event) { + //Resize the current pixmap to match the new size + if(!thumbnail.isNull()){ + if(icons) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + else + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + } + QLabel::resizeEvent(event); +} + +//Start playing the video from the beginning when the mouse enters the label +void LVideoLabel::enterEvent(QEvent *event) { + if(icons) { + entered=true; + emit rollOver(); + mediaPlayer->setPosition(0); + mediaPlayer->play(); + } + QWidget::enterEvent(event); +} + +//Stop the video and set the thumbnail back to the middle of the video when the mouse leaves the label +void LVideoLabel::leaveEvent(QEvent *event) { + if(icons) { + entered=false; + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + emit rollOver(); + } + QWidget::leaveEvent(event); +} diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h new file mode 100644 index 00000000..56defb6a --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -0,0 +1,42 @@ +#ifndef LVIDEOLABEL_H +#define LVIDEOLABEL_H + +#include <QLabel> +#include <QMediaPlayer> +#include <QTimer> +#include <QResizeEvent> +#include "LVideoSurface.h" + +class LVideoLabel : public QLabel{ + Q_OBJECT + public: + LVideoLabel(QString, bool, QWidget* parent=NULL); + ~LVideoLabel(); + void enableIcons(); + void disableIcons(); + + protected: + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + void resizeEvent(QResizeEvent*); + + signals: + void rollOver(); + void frameReceived(QPixmap); + + private slots: + void initializeBackend(); + void stopVideo(QPixmap); + void setDuration(QMediaPlayer::MediaStatus); + void stateChanged(QMediaPlayer::State); + + private: + QMediaPlayer *mediaPlayer; + LVideoSurface *surface; + QPixmap thumbnail; + QPixmap defaultThumbnail; + bool entered; + bool icons; + QString filepath; +}; +#endif diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri new file mode 100644 index 00000000..06395c8d --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.pri @@ -0,0 +1,13 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoLabel.h +HEADERS *= $${PWD}/LVideoSurface.h +HEADERS *= $${PWD}/LVideoWidget.h +SOURCES *= $${PWD}/LVideoLabel.cpp +SOURCES *= $${PWD}/LVideoSurface.cpp +SOURCES *= $${PWD}/LVideoWidget.cpp + +INCLUDEPATH *= ${PWD} + +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp new file mode 100644 index 00000000..3aaa81f0 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -0,0 +1,60 @@ +#include "LVideoSurface.h" +#include <QDebug> + +LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { + frameImage = QPixmap(); + entered = false; +} + +bool LVideoSurface::present(const QVideoFrame &frame) { + //qDebug() << surfaceFormat().frameSize() << frame.size(); + if(!frameImage.isNull() && !entered) { + emit frameReceived(frameImage); + return true; + } + + if(frame.isValid()) { + //qDebug() << "Recording Frame"; + //qDebug() << surfaceFormat().frameSize() << frame.size(); + QVideoFrame icon(frame); + icon.map(QAbstractVideoBuffer::ReadOnly); + QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); + + if((frameImage.isNull() && !entered) or entered) + frameImage = QPixmap::fromImage(img.copy(img.rect())); + + icon.unmap(); + emit frameReceived(frameImage); + return true; + } + return false; +} + +QList<QVideoFrame::PixelFormat> LVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const { + Q_UNUSED(type); + return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; +} + +void LVideoSurface::stop() { + QAbstractVideoSurface::stop(); +} + +void LVideoSurface::switchRollOver() { + entered = !entered; +} + +bool LVideoSurface::start(const QVideoSurfaceFormat &format) { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + //QVideoSurfaceFormat newFormat = format; + //Shrink the frames passed through the format to a smaller, thumbnail appropriate size and increase the frame rate + //newFormat.setFrameSize(258,258); + //newFormat.setFrameRate(90); + + if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) + QAbstractVideoSurface::start(format); + + return (imageFormat != QImage::Format_Invalid && !size.isEmpty()); +} diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h new file mode 100644 index 00000000..7a3dcaad --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -0,0 +1,26 @@ +#ifndef LVIDEOSURFACE_H +#define LVIDEOSURFACE_H + +#include <QAbstractVideoSurface> +#include <QVideoSurfaceFormat> +#include <QPixmap> +#include <QDebug> + +class LVideoSurface : public QAbstractVideoSurface { + Q_OBJECT + + public: + LVideoSurface(QObject *parent=0); + virtual bool present(const QVideoFrame&); + virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; + bool start(const QVideoSurfaceFormat &format); + void stop(); + signals: + void frameReceived(QPixmap); + public slots: + void switchRollOver(); + private: + QPixmap frameImage; + bool entered; +}; +#endif diff --git a/src-qt5/core/libLumina/LVideoSurface.pri b/src-qt5/core/libLumina/LVideoSurface.pri new file mode 100644 index 00000000..469b8c93 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.pri @@ -0,0 +1,9 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoSurface.h +SOURCES *= $${PWD}/LVideoSurface.cpp + +INCLUDEPATH *= ${PWD} + +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp new file mode 100644 index 00000000..f1f74414 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.cpp @@ -0,0 +1,38 @@ +#include "LVideoWidget.h" + +LVideoWidget::LVideoWidget(QString file, QSize iconSize, bool icons, QWidget *parent) : QWidget(parent) { + iconLabel = new LVideoLabel(file, icons, parent); + textLabel = new QLabel(parent); + + layout = new QHBoxLayout(this); + layout->setAlignment(Qt::AlignLeft | Qt::AlignCenter); + layout->setContentsMargins(5,5,5,5); + layout->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space + + textLabel->setText(file.section("/", -1)); + iconLabel->setGeometry(QRect(QPoint(0,0), iconSize)); + iconLabel->setFixedSize(iconSize); + iconLabel->setVisible(true); + textLabel->setVisible(true); + + layout->addWidget(iconLabel); + layout->addWidget(textLabel); +} + +LVideoWidget::~LVideoWidget() { + delete iconLabel; + delete textLabel; + delete layout; +} + +void LVideoWidget::setIconSize(QSize iconSize) { + iconLabel->setFixedSize(iconSize); +} + +void LVideoWidget::enableIcons() { + iconLabel->enableIcons(); +} + +void LVideoWidget::disableIcons() { + iconLabel->disableIcons(); +} diff --git a/src-qt5/core/libLumina/LVideoWidget.h b/src-qt5/core/libLumina/LVideoWidget.h new file mode 100644 index 00000000..610fd9e5 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.h @@ -0,0 +1,22 @@ +#ifndef LVIDEOWIDGET_H +#define LVIDEOWIDGET_H + +#include "LVideoLabel.h" +#include <QHBoxLayout> +#include <QResizeEvent> + +class LVideoWidget : public QWidget { + Q_OBJECT + public: + LVideoWidget(QString, QSize, bool icons, QWidget* parent=NULL); + ~LVideoWidget(); + void setIconSize(QSize); + void disableIcons(); + void enableIcons(); + + private: + LVideoLabel *iconLabel; + QLabel *textLabel; + QHBoxLayout *layout; +}; +#endif diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index b9346565..29a58ec9 100644 --- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp +++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp @@ -27,12 +27,12 @@ QString LOS::SysPrefix(){ return "/usr/"; } //Prefix for system QString LOS::ControlPanelShortcut(){ return "/usr/local/share/applications/pccontrol.desktop"; } //system control panel QString LOS::AppStoreShortcut(){ return "/usr/local/share/applications/appcafe.desktop"; } //graphical app/pkg manager //OS-specific RSS feeds (Format: QStringList[ <name>::::<url> ]; ) -QStringList LOS::RSSFeeds(){ +QStringList LOS::RSSFeeds(){ QStringList feeds; feeds << "FreeBSD News Feed::::https://www.freebsd.org/news/rss.xml"; feeds << "TrueOS News Feed::::http://www.trueos.org/?feed=rss2"; return feeds; - } + } // ==== ExternalDevicePaths() ==== QStringList LOS::ExternalDevicePaths(){ @@ -59,6 +59,25 @@ QStringList LOS::ExternalDevicePaths(){ i--; } } + //Also add info about anything in the "/media" directory + QDir media("/media"); + QFileInfoList list = media.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Type | QDir::Name); + //qDebug() << "Media files found:" << list.length(); + for(int i=0; i<list.length(); i++){ + //qDebug() << "Found media entry:" << list[i].fileName(); + if(list[i].isDir()){ + devs << "UNKNOWN::::::::/media/"+list[i].fileName(); + }else if(list[i].fileName().endsWith(".desktop")){ + QString type = list[i].fileName().section(".desktop",0,-2); + //Determine the type of hardware device based on the dev node + if(type.startsWith("da")){ type = "USB"; } + else if(type.startsWith("ada")){ type = "HDRIVE"; } + else if(type.startsWith("mmsd")){ type = "SDCARD"; } + else if(type.startsWith("cd")||type.startsWith("acd")){ type="DVD"; } + else{ type = "UNKNOWN"; } + devs << type+"::::::::/media/"+list[i].fileName(); + } + } return devs; } diff --git a/src-qt5/core/libLumina/LuminaOS.h b/src-qt5/core/libLumina/LuminaOS.h index e7a72129..98137816 100644 --- a/src-qt5/core/libLumina/LuminaOS.h +++ b/src-qt5/core/libLumina/LuminaOS.h @@ -5,8 +5,8 @@ // See the LICENSE file for full details //=========================================== // This is the main interface for any OS-specific system calls -// To port Lumina to a different operating system, just create a file -// called "LuminaOS-<Operating System>.cpp", and use that file in +// To port Lumina to a different operating system, just create a file +// called "LuminaOS-<Operating System>.cpp", and use that file in // the project (libLumina.pro) instead of LuminaOS-FreeBSD.cpp //=========================================== #ifndef _LUMINA_LIBRARY_OS_H @@ -23,7 +23,7 @@ class LOS{ public: //Return the name of the OS being used - static QString OSName(); + static QString OSName(); //OS-specific prefix(s) static QString LuminaShare(); //Install dir for Lumina share files @@ -34,7 +34,7 @@ public: static QString ControlPanelShortcut(); static QString AppStoreShortcut(); - //OS-specific RSS feeds + //OS-specific RSS feeds static QStringList RSSFeeds(); //Return Format: QStringList[ <name>::::<url> ]; //Scan for mounted external devices @@ -81,13 +81,13 @@ public: static bool batteryIsCharging(); //Battery Time Remaining static int batterySecondsLeft(); //Returns: estimated number of seconds remaining - + //Get the checksum for a file static QStringList Checksums(QStringList filepaths); //Return: checksum of each input file (same order) - + //Get the filesystem capacity static QString FileSystemCapacity(QString dir) ; //Return: percentage capacity as give by the df command - + //System CPU Information static QStringList CPUTemperatures(); //Returns: List containing the temperature of any CPU's ("50C" for example) static int CPUUsagePercent(); //Returns: Overall percentage of the amount of CPU cycles in use (-1 for errors) diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.cpp b/src-qt5/core/libLumina/LuminaSingleApplication.cpp index 6811d147..5d276805 100644 --- a/src-qt5/core/libLumina/LuminaSingleApplication.cpp +++ b/src-qt5/core/libLumina/LuminaSingleApplication.cpp @@ -19,7 +19,7 @@ LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname) if(appname!="lumina-desktop"){ cTrans = LUtils::LoadTranslation(this, appname); }//save the translator for later //Initialize a couple convenience internal variables cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3"; - QString username = QString(getlogin()); + QString username = QString(getuid()); //For locking the process use the official process name - not the user input (no masking) appname = this->applicationName(); cfile = cfile.arg( username, appname, QString::number(QX11Info::appScreen()) ); diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp index ddbc7b37..857e604b 100644 --- a/src-qt5/core/libLumina/LuminaThemes.cpp +++ b/src-qt5/core/libLumina/LuminaThemes.cpp @@ -25,42 +25,42 @@ QStringList LTHEME::availableSystemThemes(){ //returns: [name::::path] for each item - QDir dir(LOS::LuminaShare()+"themes"); - QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name); + QDir dir(LOS::LuminaShare()+"../lthemeengine/desktop_qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each item - QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes"); - QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name); + QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/desktop_qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableSystemColors(){ //returns: [name::::path] for each item //returns: [name::::path] for each item - QDir dir(LOS::LuminaShare()+"colors"); - QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name); + QDir dir(LOS::LuminaShare()+"../lthemeengine/colors"); + QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableLocalColors(){ //returns: [name::::path] for each item - QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors"); - QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name); + QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/colors"); + QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } @@ -122,15 +122,21 @@ QStringList LTHEME::availableSystemCursors(){ //returns: [name] for each item //Save a new theme/color file bool LTHEME::saveLocalTheme(QString name, QStringList contents){ - QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/"; - if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } - return LUtils::writeFile(localdir+name+".qss.template", contents, true); + Q_UNUSED(name); + Q_UNUSED(contents); + return false; //old format - do not use!! + //QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/"; + //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } + //return LUtils::writeFile(localdir+name+".qss.template", contents, true); } bool LTHEME::saveLocalColors(QString name, QStringList contents){ - QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/"; - if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } - return LUtils::writeFile(localdir+name+".qss.colors", contents, true); + Q_UNUSED(name); + Q_UNUSED(contents); + return false; //old format - do not use!! + // QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/"; + //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } + //return LUtils::writeFile(localdir+name+".qss.colors", contents, true); } //Return the currently selected Theme/Colors/Icons @@ -180,23 +186,25 @@ QString LTHEME::currentCursor(){ //Change the current Theme/Colors/Icons bool LTHEME::setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString fontsize){ + Q_UNUSED(font); + Q_UNUSED(fontsize); //QIcon::setThemeName(iconname); + //Save these settings into the theme engine settings QSettings engineset("lthemeengine","lthemeengine"); engineset.setValue("Appearance/icon_theme", iconname); - //engineset.setValue("Appearance/color_scheme_path", colorpath); //re-enable this once the color scheme has been synced with lthemeengine - //Need to add theme path saving here too later - - + engineset.setValue("Appearance/custom_palette", QFile::exists(colorpath) ); + engineset.setValue("Appearance/color_scheme_path", colorpath); + engineset.setValue("Interface/desktop_stylesheets", QStringList() << themepath); + return true; //Now save the theme settings file - QStringList contents; + /*QStringList contents; contents << "THEMEFILE="+themepath; contents << "COLORFILE="+colorpath; contents << "ICONTHEME="+iconname; contents << "FONTFAMILY="+font; contents << "FONTSIZE="+fontsize; bool ok = LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg", contents, true); - - return ok; + return ok;*/ } //Change the current Cursor Theme @@ -299,13 +307,13 @@ QStringList LTHEME::cursorInformation(QString name){ } } return out; -} +} QStringList LTHEME::CustomEnvSettings(bool useronly){ //view all the key=value settings QStringList newinfo; if(!useronly){ QStringList sysfiles; sysfiles << L_ETCDIR+"/lumina_environment.conf" << LOS::LuminaShare()+"lumina_environment.conf"; - for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){ + for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){ newinfo << LUtils::readFile(sysfiles[i]); } } diff --git a/src-qt5/core/libLumina/LuminaThemes.h b/src-qt5/core/libLumina/LuminaThemes.h index 39602f58..ca79e0bd 100644 --- a/src-qt5/core/libLumina/LuminaThemes.h +++ b/src-qt5/core/libLumina/LuminaThemes.h @@ -34,7 +34,7 @@ public: //Save a new theme/color file static bool saveLocalTheme(QString name, QStringList contents); static bool saveLocalColors(QString name, QStringList contents); - + //Return the currently selected Theme/Colors/Icons static QStringList currentSettings(); //returns [theme path, colorspath, iconsname, font, fontsize] static QString currentCursor(); //returns: current cursor theme name @@ -45,16 +45,16 @@ public: //Return the complete stylesheet for a given theme/colors static QString assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize); - + //Additional info for a cursor theme static QStringList cursorInformation(QString name); //returns: [Name, Comment, Sample Image File] - + //Environment settings static QStringList CustomEnvSettings(bool useronly = false); //view all the key=value settings static void LoadCustomEnvSettings(); //will push the custom settings into the environment (recommended before loading the initial QApplication) static bool setCustomEnvSetting(QString var, QString val); //variable/value pair (use an empty val to clear it) static QString readCustomEnvSetting(QString var); - + }; // Qt Style override to allow custom themeing/colors diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index ab1000ab..cf9e0af2 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -72,6 +72,7 @@ void XDGDesktop::sync(){ QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization var = var.section("[",0,0).simplified(); //remove the localization QString val = line.section("=",1,50).simplified(); + if( val.count("\"")==2 && val.startsWith("\"") && val.endsWith("\"")){ val.chop(1); val = val.remove(0,1); } //remove the starting/ending quotes //------------------- if(var=="Name"){ if(insection){ @@ -631,7 +632,7 @@ void XDGDesktopList::populateMenu(QMenu *topmenu, bool byCategory){ void LFileInfo::loadExtraInfo(){ desk = 0; //Now load the extra information - if(this->isDir()){ + if( this->suffix().isEmpty() && (this->absoluteFilePath().startsWith("/net/") || this->isDir()) ){ mime = "inode/directory"; //Special directory icons QString name = this->fileName().toLower(); @@ -644,6 +645,7 @@ void LFileInfo::loadExtraInfo(){ else if(name=="downloads"){ icon = "folder-downloads"; } else if(name=="documents"){ icon = "folder-documents"; } else if(name=="images" || name=="pictures"){ icon = "folder-image"; } + else if(this->absoluteFilePath().startsWith("/net/")){ icon = "folder-shared"; } else if( !this->isReadable() ){ icon = "folder-locked"; } }else if( this->suffix()=="desktop"){ mime = "application/x-desktop"; @@ -664,11 +666,11 @@ LFileInfo::LFileInfo(){ LFileInfo::LFileInfo(QString filepath){ //overloaded contructor this->setFile(filepath); loadExtraInfo(); -} +} LFileInfo::LFileInfo(QFileInfo info){ //overloaded contructor this->swap(info); //use the given QFileInfo without re-loading it loadExtraInfo(); -} +} //Functions for accessing the extra information // -- Return the mimetype for the file @@ -683,7 +685,7 @@ QString LFileInfo::iconfile(){ return icon; }else{ if(!mime.isEmpty()){ - QString tmp = mime; + QString tmp = mime; tmp.replace("/","-"); return tmp; }else if(this->isExecutable()){ @@ -696,7 +698,7 @@ QString LFileInfo::iconfile(){ // -- Check if this is an XDG desktop file bool LFileInfo::isDesktopFile(){ if(desk==0){ return false; } - return (!desk->filePath.isEmpty()); + return (!desk->filePath.isEmpty()); } // -- Allow access to the XDG desktop data structure @@ -726,11 +728,14 @@ bool LFileInfo::isAVFile(){ //==== LXDG Functions ==== bool LXDG::checkExec(QString exec){ //Return true(good) or false(bad) + //Check for quotes around the exec, and remove them as needed + if(exec.startsWith("\"") && exec.count("\"")>=2){ exec = exec.section("\"",1,1).simplified(); } + if(exec.startsWith("\'") && exec.count("\'")>=2){ exec = exec.section("\'",1,1).simplified(); } if(exec.startsWith("/")){ return QFile::exists(exec); } else{ QStringList paths = QString(getenv("PATH")).split(":"); for(int i=0; i<paths.length(); i++){ - if(QFile::exists(paths[i]+"/"+exec)){ return true; } + if(QFile::exists(paths[i]+"/"+exec)){ return true; } } } return false; //could not find the executable in the current path(s) @@ -747,7 +752,7 @@ QStringList LXDG::systemApplicationDirs(){ for(int i=0; i<appDirs.length(); i++){ if( QFile::exists(appDirs[i]+"/applications") ){ out << appDirs[i]+"/applications"; - //Also check any subdirs within this directory + //Also check any subdirs within this directory // (looking at you KDE - stick to the standards!!) out << LUtils::listSubDirectories(appDirs[i]+"/applications"); } @@ -891,7 +896,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ fall << getChildIconDirs(paths[i]+"hicolor"); //XDG fallback (apps add to this) } //Now load all the icon theme dependencies in order (Theme1 -> Theme2 -> Theme3 -> Fallback) - + //fall << LOS::AppPrefix()+"share/pixmaps"; //always use this as well as a final fallback QDir::setSearchPaths("icontheme", theme); QDir::setSearchPaths("default", oxy); @@ -926,7 +931,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ //simple PNG image - load directly into the QIcon structure ico.addFile(srch[i]+":"+iconName+".png"); } - + } //If still no icon found, look for any image format in the "pixmaps" directory if(ico.isNull()){ @@ -946,13 +951,13 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ break; } } - + } } //Use the fallback icon if necessary if(ico.isNull() ){ if(!fallback.isEmpty()){ ico = LXDG::findIcon(fallback,""); } - else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){ + else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){ //mimetype - try to use the generic type icon ico = LXDG::findIcon(iconName.section("-x-",0,0)+"-x-generic", ""); } @@ -969,7 +974,7 @@ QStringList LXDG::getChildIconDirs(QString parent){ QDir D(parent); QStringList out; QStringList dirs = D.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); - if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){ + if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){ //Need to sort these directories by image size //qDebug() << " - Parent:" << parent << "Dirs:" << dirs; for(int i=0; i<dirs.length(); i++){ @@ -1017,7 +1022,7 @@ QStringList LXDG::systemMimeDirs(){ QStringList out; for(int i=0; i<appDirs.length(); i++){ if( QFile::exists(appDirs[i]+"/mime") ){ - out << appDirs[i]+"/mime"; + out << appDirs[i]+"/mime"; } } return out; @@ -1028,7 +1033,7 @@ QIcon LXDG::findMimeIcon(QString extension){ QString mime = LXDG::findAppMimeForFile(extension); if(mime.isEmpty()){ mime = LXDG::findAppMimeForFile(extension.toLower()); } mime.replace("/","-"); //translate to icon mime name - if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback + if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback if(ico.isNull()){ ico = LXDG::findIcon("unknown",""); } //just in case return ico; } @@ -1050,8 +1055,8 @@ while(mimes.isEmpty()){ return extension; } //Look for globs at the end of the filename - if(!extension.isEmpty()){ - mimes = mimefull.filter(":*."+extension); + if(!extension.isEmpty()){ + mimes = mimefull.filter(":*."+extension); //If nothing found, try a case-insensitive search if(mimes.isEmpty()){ mimes = mimefull.filter(":*."+extension, Qt::CaseInsensitive); } //Now ensure that the filter was accurate (*.<extention>.<something> will still be caught) @@ -1062,7 +1067,7 @@ while(mimes.isEmpty()){ } } //Look for globs at the start of the filename - if(mimes.isEmpty()){ + if(mimes.isEmpty()){ mimes = mimefull.filter(":"+filename.left(2)); //look for the first 2 characters initially //Note: This initial filter will only work if the wildcard (*) is not within the first 2 characters of the pattern //Now ensure that the filter was accurate diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp deleted file mode 100644 index 57b6edde..00000000 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ /dev/null @@ -1,423 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "NativeEmbedWidget.h" - -#include <QPainter> -#include <QX11Info> -#include <QApplication> -#include <QScreen> -#include <QDebug> - -#include <xcb/xproto.h> -#include <xcb/xcb_aux.h> -#include <xcb/xcb_event.h> -#include <xcb/xcb_image.h> -//#include <xcb/render.h> -//#include <xcb/xcb_renderutil.h> -#include <xcb/composite.h> -#include <X11/extensions/Xdamage.h> - -#define DISABLE_COMPOSITING true - -/*inline xcb_render_pictformat_t get_pictformat(){ - static xcb_render_pictformat_t format = 0; - if(format==0){ - xcb_render_query_pict_formats_reply_t *reply = xcb_render_query_pict_formats_reply( QX11Info::connection(), xcb_render_query_pict_formats(QX11Info::connection()), NULL); - format = xcb_render_util_find_standard_format(reply, XCB_PICT_STANDARD_ARGB_32)->id; - free(reply); - } - return format; -} - - -inline void renderWindowToWidget(WId id, QWidget *widget, bool hastransparency = true){ - //window and widget are assumed to be the same size - //Pull the XCB pixmap out of the compositing layer - xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); - xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); - if(pix==0){ qDebug() << "Got blank pixmap!"; return; } - - xcb_render_picture_t pic_id = xcb_generate_id(QX11Info::connection()); - xcb_render_create_picture_aux(QX11Info::connection(), pic_id, pix, get_pictformat() , 0, NULL); - // - xcb_render_composite(QX11Info::connection(), hastransparency ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC, pic_id, XCB_RENDER_PICTURE_NONE, widget->x11RenderHandle(), - 0, 0, 0, 0, 0, 0, (uint16_t) widget->width(), (uint16_t) widget->height() ); -}*/ - -#define CLIENT_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_FOCUS_CHANGE | \ - XCB_EVENT_MASK_POINTER_MOTION) - -#define FRAME_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW) - -inline void registerClientEvents(WId id, bool client = true){ - uint32_t values[] = {XCB_NONE}; - values[0] = client ? CLIENT_EVENT_MASK : FRAME_EVENT_MASK ; - /*{ (XCB_EVENT_MASK_PROPERTY_CHANGE - | XCB_EVENT_MASK_BUTTON_PRESS - | XCB_EVENT_MASK_BUTTON_RELEASE - | XCB_EVENT_MASK_POINTER_MOTION - | XCB_EVENT_MASK_BUTTON_MOTION - | XCB_EVENT_MASK_EXPOSURE - | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT - | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY - | XCB_EVENT_MASK_ENTER_WINDOW) - };*/ - xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, values); -} - -// ============ -// PRIVATE -// ============ -//Simplification functions for the XCB/XLib interactions -void NativeEmbedWidget::syncWinSize(QSize sz){ - if(WIN==0){ return; } - else if(!sz.isValid()){ sz = this->size(); } //use the current widget size - //qDebug() << "Sync Window Size:" << sz; - //if(sz == winSize){ return; } //no change - QPoint pt(0,0); - if(!DISABLE_COMPOSITING){ pt = this->mapToGlobal(QPoint(0,0)); } - const uint32_t valList[4] = {(uint32_t) pt.x(), (uint32_t) pt.y(), (uint32_t) sz.width(), (uint32_t) sz.height()}; - const uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - xcb_configure_window(QX11Info::connection(), WIN->id(), mask, valList); - winSize = sz; //save this for checking later -} - -void NativeEmbedWidget::syncWidgetSize(QSize sz){ - //qDebug() << "Sync Widget Size:" << sz; - this->resize(sz); -} - -void NativeEmbedWidget::hideWindow(){ - //qDebug() << "Hide Embed Window"; - xcb_unmap_window(QX11Info::connection(), WIN->id()); -} - -void NativeEmbedWidget::showWindow(){ - //qDebug() << "Show Embed Window"; - xcb_map_window(QX11Info::connection(), WIN->id()); - reregisterEvents(); - if(!DISABLE_COMPOSITING){ - QTimer::singleShot(0,this, SLOT(repaintWindow())); - } -} - -QImage NativeEmbedWidget::windowImage(QRect geom){ - //if(DISABLE_COMPOSITING){ - if(!this->isVisible()){ return QImage(); } //nothing to grab yet - QList<QScreen*> screens = static_cast<QApplication*>( QApplication::instance() )->screens(); - //for(int i=0; i<screens.length(); i++){ - //if(screens[i]->contains(this)){ - if(!screens.isEmpty()){ - return screens[0]->grabWindow(WIN->id(), geom.x(), geom.y(), geom.width(), geom.height()).toImage(); - } - //} - //} - return QImage(); - /*}else{ - //Pull the XCB pixmap out of the compositing layer - xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); - xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); - if(pix==0){ qDebug() << "Got blank pixmap!"; return QImage(); } - - //Convert this pixmap into a QImage - //xcb_image_t *ximg = xcb_image_get(QX11Info::connection(), pix, 0, 0, this->width(), this->height(), ~0, XCB_IMAGE_FORMAT_Z_PIXMAP); - xcb_image_t *ximg = xcb_image_get(QX11Info::connection(), pix, geom.x(), geom.y(), geom.width(), geom.height(), ~0, XCB_IMAGE_FORMAT_Z_PIXMAP); - if(ximg == 0){ qDebug() << "Got blank image!"; return QImage(); } - QImage img(ximg->data, ximg->width, ximg->height, ximg->stride, QImage::Format_ARGB32_Premultiplied); - img = img.copy(); //detach this image from the XCB data structures before we clean them up, otherwise the QImage will try to clean it up a second time on window close and crash - xcb_image_destroy(ximg); - - //Cleanup the XCB data structures - xcb_free_pixmap(QX11Info::connection(), pix); - - return img; - }*/ -} -void NativeEmbedWidget::setWinUnpaused(){ - paused = false; - winImage = QImage(); - if(!DISABLE_COMPOSITING){ - repaintWindow(); //update the cached image right away - }else if(this->isVisible()){ - showWindow(); - } - resyncWindow(); //make sure the window knows about the new location -} -// ============ -// PUBLIC -// ============ -NativeEmbedWidget::NativeEmbedWidget(QWidget *parent) : QWidget(parent){ - WIN = 0; //nothing embedded yet - paused = false; - this->setMouseTracking(true); - //this->setSizeIncrement(2,2); -} - -bool NativeEmbedWidget::embedWindow(NativeWindow *window){ - WIN = window; - - //Now send the embed event to the app - //qDebug() << " - send _XEMBED event"; - /*xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = WIN->id(); - event.type = obj->ATOMS["_XEMBED"]; //_XEMBED - event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY - event.data.data32[2] = 0; - event.data.data32[3] = this->winId(); //WID of the container - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - */ - //Now setup any redirects and return - if(!DISABLE_COMPOSITING){ - xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); - xcb_composite_redirect_subwindows(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //AUTOMATIC); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); - - //Now create/register the damage handler - // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) - // -- Retested 6/29/17 (no change) Ken Moore - //xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer - //xcb_damage_create(QX11Info::connection(), dmgID, WIN->id(), XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); - // -- XLib (Note: This is only used because the XCB routine above does not work - needs to be fixed upstream in XCB itself). - Damage dmgID = XDamageCreate(QX11Info::display(), WIN->id(), XDamageReportRawRectangles); - - WIN->addDamageID( (uint) dmgID); //save this for later - connect(WIN, SIGNAL(VisualChanged()), this, SLOT(repaintWindow()) ); //make sure we repaint the widget on visual change - }else{ - xcb_reparent_window(QX11Info::connection(), WIN->id(), this->winId(), 0, 0); - registerClientEvents(this->winId()); //child events get forwarded through the frame - watch this for changes too - //Also use a partial-composite here - make sure the window pixmap is available even when the window is obscured - xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_AUTOMATIC); - //xcb_composite_redirect_subwindows(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); - //Also alert us when the window visual changes - Damage dmgID = XDamageCreate(QX11Info::display(), WIN->id(), XDamageReportRawRectangles); - - WIN->addDamageID( (uint) dmgID); //save this for later - connect(WIN, SIGNAL(VisualChanged()), this, SLOT(repaintWindow()) ); //make sure we repaint the widget on visual change - } - WIN->addFrameWinID(this->winId()); - registerClientEvents(WIN->id()); - //qDebug() << "Events Registered:" << WIN->id() << this->winId(); - return true; -} - -bool NativeEmbedWidget::detachWindow(){ - xcb_reparent_window(QX11Info::connection(), WIN->id(), QX11Info::appRootWindow(), -1, -1); - //WIN = 0; - return true; -} - -bool NativeEmbedWidget::isEmbedded(){ - return (WIN!=0); -} - -void NativeEmbedWidget::raiseWindow(){ - if(DISABLE_COMPOSITING){ return; } - uint32_t val = XCB_STACK_MODE_ABOVE; - xcb_configure_window(QX11Info::connection(), WIN->id(), XCB_CONFIG_WINDOW_STACK_MODE, &val); -} - -void NativeEmbedWidget::lowerWindow(){ - if(DISABLE_COMPOSITING){ return; } - uint32_t val = XCB_STACK_MODE_BELOW; - xcb_configure_window(QX11Info::connection(), WIN->id(), XCB_CONFIG_WINDOW_STACK_MODE, &val); -} - -// ============== -// PUBLIC SLOTS -// ============== -//Pause/resume -void NativeEmbedWidget::pause(){ - if(DISABLE_COMPOSITING){ - winImage = windowImage(QRect(QPoint(0,0), this->size())); - hideWindow(); - }else{ - if(winImage.isNull()){ repaintWindow(); } //make sure we have one image already cached first - } - paused = true; -} - -void NativeEmbedWidget::resume(){ - //paused = false; - syncWinSize(); - if(DISABLE_COMPOSITING){ - //showWindow(); - }else{ - repaintWindow(); //update the cached image right away - } - QTimer::singleShot(10, this, SLOT(setWinUnpaused()) ); -} - -void NativeEmbedWidget::resyncWindow(){ - if(WIN==0){ return; } - //syncWinSize(); - //if(DISABLE_COMPOSITING){ - // Specs say to send an artificial configure event to the window if the window was reparented into the frame - QPoint loc = this->mapToGlobal( QPoint(0,0) ); - //Send an artificial configureNotify event to the window with the global position/size included - xcb_configure_notify_event_t *event = (xcb_configure_notify_event_t*) calloc(32,1); //always 32-byes long, even if we don't need all of it - event->x = loc.x(); - event->y = loc.y(); - event->width = this->width(); - event->height = this->height(); - event->border_width = 0; - event->above_sibling = XCB_NONE; - event->override_redirect = false; - event->window = WIN->id(); - event->event = WIN->id(); - event->response_type = XCB_CONFIGURE_NOTIFY; - xcb_send_event(QX11Info::connection(), false, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (char *) event); - xcb_flush(QX11Info::connection()); - free(event); - /*}else{ - //Window is floating invisibly - make sure it is in the right place - //Make sure the window size is syncronized and visual up to date - //syncWinSize(); - QTimer::singleShot(10, this, SLOT(repaintWindow()) ); - }*/ - -} - -void NativeEmbedWidget::repaintWindow(){ - //if(DISABLE_COMPOSITING){ return; } - //qDebug() << "Update Window Image:" << !paused; - if(paused){ return; } - /*QImage tmp = windowImage( QRect(QPoint(0,0), this->size()) ); - if(!tmp.isNull()){ - winImage = tmp; - }else{ qDebug() << "Got Null Image!!"; }*/ - this->parentWidget()->update(); //visual changed - need to update the image on the widget -} - -void NativeEmbedWidget::reregisterEvents(){ - if(WIN!=0){ registerClientEvents(WIN->id()); } -} - -// ============== -// PROTECTED -// ============== -void NativeEmbedWidget::resizeEvent(QResizeEvent *ev){ - QWidget::resizeEvent(ev); - if(WIN!=0 && !paused){ - syncWinSize(ev->size()); - } //syncronize the window with the new widget size -} - -void NativeEmbedWidget::showEvent(QShowEvent *ev){ - if(WIN!=0){ showWindow(); } - QWidget::showEvent(ev); -} - -void NativeEmbedWidget::hideEvent(QHideEvent *ev){ - if(WIN!=0){ hideWindow(); } - QWidget::hideEvent(ev); -} - -void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ - QPainter P(this); - P.setClipping(true); - P.setClipRect(0,0,this->width(), this->height()); - P.fillRect(ev->rect(), Qt::transparent); - if(WIN==0){ return; } - QRect geom = ev->rect(); //atomic updates - //qDebug() << "Paint Rect:" << geom; - QImage img; - if(!paused){ img = windowImage(geom); } - else if(!winImage.isNull()){ - if(winImage.size() == this->size()){ img = winImage.copy(geom); } - else{ img = winImage.scaled(geom.size()); } //this is a fast transformation - might be slightly distorted - } - //Need to paint the image from the window onto the widget as an overlay - P.drawImage( geom , img, QRect(QPoint(0,0), img.size()), Qt::NoOpaqueDetection); //1-to-1 mapping - - -} - -void NativeEmbedWidget::enterEvent(QEvent *ev){ - QWidget::enterEvent(ev); - //qDebug() << "Enter Embed Widget"; - //raiseWindow(); //this->grabMouse(); -} - -void NativeEmbedWidget::leaveEvent(QEvent *ev){ - QWidget::leaveEvent(ev); - /*qDebug() << "Leave Embed Widget"; - QPoint pt = QCursor::pos(); - QPoint relpt = this->parentWidget()->mapFromGlobal(pt); - qDebug() << " - Geom:" << this->geometry() << "Global pt:" << pt << "Relative pt:" << relpt; - if(!this->geometry().contains(relpt) ){ lowerWindow(); }*/ -} - -void NativeEmbedWidget::mouseMoveEvent(QMouseEvent *ev){ - QWidget::mouseMoveEvent(ev); - //Forward this event on to the window -} - -void NativeEmbedWidget::mousePressEvent(QMouseEvent *ev){ - QWidget::mousePressEvent(ev); - //Forward this event on to the window -} - -void NativeEmbedWidget::mouseReleaseEvent(QMouseEvent *ev){ - QWidget::mouseReleaseEvent(ev); - //Forward this event on to the window -} - -/*bool NativeEmbedWidget::nativeEvent(const QByteArray &eventType, void *message, long *result){ - if(eventType=="xcb_generic_event_t" && WIN!=0){ - //Convert to known event type (for X11 systems) - xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); - //qDebug() << "Got Embed Window Event:" << xcb_event_get_label(ev->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) << xcb_event_get_request_label(ev->response_type); - uint32_t mask = 0; - switch( ev->response_type & XCB_EVENT_RESPONSE_TYPE_MASK){ - case XCB_BUTTON_PRESS: - //This is a mouse button press - mask = XCB_EVENT_MASK_BUTTON_PRESS; - break; - case XCB_BUTTON_RELEASE: - //This is a mouse button release - //qDebug() << "Button Release Event"; - mask = XCB_EVENT_MASK_BUTTON_RELEASE; - break; - case XCB_MOTION_NOTIFY: - //This is a mouse movement event - mask = XCB_EVENT_MASK_POINTER_MOTION; - break; - case XCB_ENTER_NOTIFY: - //This is a mouse movement event when mouse goes over a new window - mask = XCB_EVENT_MASK_ENTER_WINDOW; - break; - case XCB_LEAVE_NOTIFY: - //This is a mouse movement event when mouse goes leaves a window - mask = XCB_EVENT_MASK_LEAVE_WINDOW; - break; - default: - mask = 0; - } - - //Now forward this event on to the embedded window - if(mask!=0){ - qDebug() << " - Got a mouse event"; - xcb_send_event(QX11Info::connection(), true, WIN->id(),mask, (char*) ev); - return true; - } - } - return false; -}*/ diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h deleted file mode 100644 index 16bb46dc..00000000 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ /dev/null @@ -1,74 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This is a container object for embedding a native window into a QWidget -// and maintaining a 1-to-1 mapping of sizing and other properties -// while also providing compositing effects between the two windows -//=========================================== -#ifndef _LUMINA_NATIVE_EMBED_WIDGET_H -#define _LUMINA_NATIVE_EMBED_WIDGET_H - -#include "NativeWindow.h" -#include <QWidget> -#include <QTimer> -#include <QResizeEvent> -#include <QShowEvent> -#include <QHideEvent> -#include <QPaintEvent> -#include <QMouseEvent> - -class NativeEmbedWidget : public QWidget{ - Q_OBJECT -private: - NativeWindow *WIN; - QSize winSize; - QImage winImage; - bool paused, hasAlphaChannel; - -private slots: - //Simplification functions - void syncWinSize(QSize sz = QSize()); - void syncWidgetSize(QSize sz); - void hideWindow(); - void showWindow(); - QImage windowImage(QRect geom); - - void setWinUnpaused(); - -public: - NativeEmbedWidget(QWidget *parent); - - bool embedWindow(NativeWindow *window); - bool detachWindow(); - bool isEmbedded(); //status of the embed - bool isPaused(){ return paused; } - -public slots: - void raiseWindow(); - void lowerWindow(); - - //Pause/resume - void pause(); - void resume(); - - void resyncWindow(); - void repaintWindow(); - void reregisterEvents(); - -protected: - void resizeEvent(QResizeEvent *ev); - void showEvent(QShowEvent *ev); - void hideEvent(QHideEvent *ev); - void paintEvent(QPaintEvent *ev); - void enterEvent(QEvent *ev); - void leaveEvent(QEvent *ev); - void mouseMoveEvent(QMouseEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); - //bool nativeEvent(const QByteArray &eventType, void *message, long *result); -}; - -#endif diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/core/libLumina/NativeEventFilter.cpp deleted file mode 100644 index c13c1fc8..00000000 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ /dev/null @@ -1,300 +0,0 @@ -//=========================================== -// Lumina-desktop source code -// Copyright (c) 2015-2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "NativeEventFilter.h" -#include <QCoreApplication> -#include <QDebug> - -//#include <xcb/xcb_aux.h> -//#include <xcb/damage.h> - -//================================================== -// NOTE: All the XCB interactions and atoms are accessed via: -// obj->XCB->EWMH.(atom name) -// obj->XCB->(do something) -//================================================== - -/* -List of XCB response types (since almost impossible to find good docs on XCB) -switch (xcb_generic_event_t*->response_type & ~0x80) -case values: -XCB_KEY_[PRESS | RELEASE] -XCB_BUTTON_[PRESS | RELEASE] -XCB_MOTION_NOTIFY -XCB_ENTER_NOTIFY -XCB_LEAVE_NOTIFY -XCB_FOCUS_[IN | OUT] -XCB_KEYMAP_NOTIFY -XCB_EXPOSE -XCB_GRAPHICS_EXPOSURE -XCB_VISIBILITY_NOTIFY -XCB_CREATE_NOTIFY -XCB_DESTROY_NOTIFY -XCB_UNMAP_NOTIFY -XCB_MAP_[NOTIFY | REQUEST] -XCB_REPARENT_NOTIFY -XCB_CONFIGURE_[NOTIFY | REQUEST] -XCB_GRAVITY_NOTIFY -XCB_RESIZE_REQUEST -XCB_CIRCULATE_[NOTIFY | REQUEST] -XCB_PROPERTY_NOTIFY -XCB_SELECTION_[CLEAR | REQUEST | NOTIFY] -XCB_COLORMAP_NOTIFY -XCB_CLIENT_MESSAGE -*/ - -//SYSTEM TRAY STANDARD DEFINITIONS -#define SYSTEM_TRAY_REQUEST_DOCK 0 -#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -#define SYSTEM_TRAY_CANCEL_MESSAGE 2 - -//#include <LuminaX11.h> -#include <QX11Info> -#include <xcb/xcb_ewmh.h> -#include <xcb/xcb_keysyms.h> -#include <xcb/damage.h> - -#define DEBUG 0 - -//Special objects/variables for XCB parsing -static xcb_ewmh_connection_t EWMH; -//static LXCB *XCB = 0; -static xcb_atom_t _NET_SYSTEM_TRAY_OPCODE = 0; - -inline void ParsePropertyEvent(xcb_property_notify_event_t *ev, NativeEventFilter *obj){ - //qDebug() << "Got Property Event:" << ev->window << ev->atom; - NativeWindow::Property prop = NativeWindow::None; - //Now determine which properties are getting changed, and update the native window as appropriate - if(ev->atom == EWMH._NET_WM_NAME){ prop = NativeWindow::Title; } - else if(ev->atom == EWMH._NET_WM_ICON){ prop = NativeWindow::Icon; } - else if(ev->atom == EWMH._NET_WM_ICON_NAME){ prop = NativeWindow::ShortTitle; } - else if(ev->atom == EWMH._NET_WM_DESKTOP){ prop = NativeWindow::Workspace; } - else if(ev->atom == EWMH._NET_WM_WINDOW_TYPE ){ prop = NativeWindow::WinTypes; } - else if( ev->atom == EWMH._NET_WM_STATE){ prop = NativeWindow::States; } - //Send out the signal if necessary - if(prop!=NativeWindow::None){ - //if(DEBUG){ - //qDebug() << "Detected Property Change:" << ev->window << prop; - //} - obj->emit WindowPropertyChanged(ev->window, prop); - }else{ - //Quick re-check of the simple properties (nothing like the icon or other graphics) - obj->emit WindowPropertiesChanged(ev->window, QList<NativeWindow::Property>() << NativeWindow::Title - << NativeWindow::ShortTitle << NativeWindow::Workspace ); - //qDebug() << "Unknown Property Change:" << ev->window << ev->atom; - } -} - -inline void ParseClientMessageEvent(xcb_client_message_event_t *ev, NativeEventFilter *obj){ - NativeWindow::Property prop = NativeWindow::None; - QVariant val; - if(ev->type==EWMH._NET_WM_NAME){ prop = NativeWindow::Title; } - else if(ev->type==EWMH._NET_WM_ICON){ prop = NativeWindow::Icon; } - else if(ev->type==EWMH._NET_WM_ICON_NAME){ prop = NativeWindow::ShortTitle; } - else if(ev->type==EWMH._NET_WM_DESKTOP){ - prop = NativeWindow::Workspace; - val = QVariant( (int) ev->data.data32[0] ); - }else if(ev->type==EWMH._NET_WM_WINDOW_TYPE){ prop = NativeWindow::WinTypes; } - else if(ev->type==EWMH._NET_WM_STATE){ prop = NativeWindow::States; } - - if(prop!=NativeWindow::None){ - //if(DEBUG){ - qDebug() << "Detected Property Change Request:" << ev->window << prop; //} - if(val.isNull()){ obj->emit WindowPropertyChanged(ev->window, prop); } - else{ obj->emit RequestWindowPropertyChange(ev->window, prop, val); } - } - -} - - -//Constructor for the Event Filter wrapper -NativeEventFilter::NativeEventFilter() : QObject(){ - EF = new EventFilter(this); - if(EWMH.nb_screens <=0){ - xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(QX11Info::connection(), &EWMH); - if(!xcb_ewmh_init_atoms_replies(&EWMH, cookie, NULL) ){ - qDebug() << "Error with XCB atom initializations"; - } - } - if(_NET_SYSTEM_TRAY_OPCODE==0){ - //_NET_SYSTEM_TRAY_OPCODE - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), 0, 23,"_NET_SYSTEM_TRAY_OPCODE"); - xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(QX11Info::connection(), cookie, NULL); - if(r){ - _NET_SYSTEM_TRAY_OPCODE = r->atom; - free(r); - } - } -} - -void NativeEventFilter::start(){ - if(DEBUG){ qDebug() << " - Install event filter..."; } - QCoreApplication::instance()->installNativeEventFilter(EF); - if(DEBUG){ qDebug() << " - Run request check..."; } - -} - -void NativeEventFilter::stop(){ - QCoreApplication::instance()->installNativeEventFilter(0); -} - -//============================= -// EventFilter Class -//============================= - -//Constructor for the XCB event filter -EventFilter::EventFilter(NativeEventFilter *parent) : QAbstractNativeEventFilter(){ - obj = parent; -} - -//This function format taken directly from the Qt5.3 documentation -bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *){ - //qDebug() << "New Event"; - if(eventType=="xcb_generic_event_t"){ - //Convert to known event type (for X11 systems) - xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); - //Now parse the event and emit signals as necessary - switch( ev->response_type & ~0x80){ -//============================== -// INTERACTIVITY EVENTS -//============================== - case XCB_KEY_PRESS: - //This is a keyboard key press - //qDebug() << "Key Press Event" - obj->emit KeyPressed( ((xcb_key_press_event_t *) ev)->detail, ((xcb_key_press_event_t *) ev)->root ); - break; - case XCB_KEY_RELEASE: - //This is a keyboard key release - //qDebug() << "Key Release Event"; - obj->emit KeyReleased( ((xcb_key_release_event_t *) ev)->detail, ((xcb_key_release_event_t *) ev)->root ); - break; - case XCB_BUTTON_PRESS: - //This is a mouse button press - //qDebug() << "Button Press Event"; - obj->emit MousePressed( ((xcb_button_press_event_t *) ev)->detail, ((xcb_button_press_event_t *) ev)->root ); - break; - case XCB_BUTTON_RELEASE: - //This is a mouse button release - //qDebug() << "Button Release Event"; - obj->emit MouseReleased( ((xcb_button_release_event_t *) ev)->detail, ((xcb_button_release_event_t *) ev)->root ); - break; - case XCB_MOTION_NOTIFY: - //This is a mouse movement event - if(DEBUG){ qDebug() << "Motion Notify Event"; } - obj->emit MouseMovement(); - break; - case XCB_ENTER_NOTIFY: - //This is a mouse movement event when mouse goes over a new window - //qDebug() << "Enter Notify Event"; - obj->emit MouseEnterWindow( ((xcb_enter_notify_event_t *) ev)->root ); - break; - case XCB_LEAVE_NOTIFY: - //This is a mouse movement event when mouse goes leaves a window - //qDebug() << "Leave Notify Event"; - obj->emit MouseLeaveWindow( ((xcb_leave_notify_event_t *) ev)->root ); - break; -//============================== - case XCB_EXPOSE: - //qDebug() << "Expose Notify Event:"; - //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; - break; -//============================== - case XCB_MAP_NOTIFY: - //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; - obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, true); - break; //This is just a notification that a window was mapped - nothing needs to change here - case XCB_MAP_REQUEST: - //qDebug() << "Window Map Request Event"; - obj->emit WindowCreated( ((xcb_map_request_event_t *) ev)->window ); - break; -//============================== - case XCB_CREATE_NOTIFY: - //qDebug() << "Window Create Event"; - break; -//============================== - case XCB_UNMAP_NOTIFY: - //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; - obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindow::Visible, false); - break; -//============================== - case XCB_DESTROY_NOTIFY: - //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; - obj->emit WindowDestroyed( ((xcb_destroy_notify_event_t *) ev)->window ); - break; -//============================== - case XCB_FOCUS_IN: - //qDebug() << "Focus In Event:"; - break; -//============================== - case XCB_FOCUS_OUT: - //qDebug() << "Focus Out Event:"; - break; -//============================== - case XCB_PROPERTY_NOTIFY: - //qDebug() << "Property Notify Event:"; - ParsePropertyEvent((xcb_property_notify_event_t*)ev, obj); - break; -//============================== - case XCB_CLIENT_MESSAGE: - //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 - if(SYSTEM_TRAY_REQUEST_DOCK == ((xcb_client_message_event_t*)ev)->data.data32[1]){ - obj->emit TrayWindowCreated( ((xcb_client_message_event_t*)ev)->data.data32[2] ); - //addTrayApp( ((xcb_client_message_event_t*)ev)->data.data32[2] ); - } - //Ignore the System Tray messages at the moment - }else if(((xcb_client_message_event_t*)ev)->window != QX11Info::appRootWindow()){ - ParseClientMessageEvent((xcb_client_message_event_t*)ev, obj); - } - break; -//============================== - case XCB_CONFIGURE_NOTIFY: - //qDebug() << "Configure Notify Event"; - /*obj->emit WindowPropertiesChanged( ((xcb_configure_notify_event_t*)ev)->window, - QList<NativeWindow::Property>() << NativeWindow::GlobalPos << NativeWindow::Size, - QList<QVariant>() << QPoint(((xcb_configure_notify_event_t*)ev)->x, ((xcb_configure_notify_event_t*)ev)->y) << - QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) );*/ - obj->emit WindowPropertyChanged( ((xcb_configure_notify_event_t*)ev)->window, NativeWindow::Size, - QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) ); - break; -//============================== - case XCB_CONFIGURE_REQUEST: - //qDebug() << "Configure Request Event"; - obj->emit RequestWindowPropertiesChange( ((xcb_configure_request_event_t*)ev)->window, - QList<NativeWindow::Property>() << NativeWindow::GlobalPos << NativeWindow::Size, - QList<QVariant>() << QPoint(((xcb_configure_request_event_t*)ev)->x, ((xcb_configure_request_event_t*)ev)->y) << - QSize(((xcb_configure_request_event_t*)ev)->width, ((xcb_configure_request_event_t*)ev)->height) ); - break; -//============================== - case XCB_RESIZE_REQUEST: - //qDebug() << "Resize Request Event"; - obj->emit RequestWindowPropertyChange( ((xcb_resize_request_event_t*)ev)->window, - NativeWindow::Size, QSize(((xcb_resize_request_event_t*)ev)->width, ((xcb_resize_request_event_t*)ev)->height) ); - break; -//============================== - case XCB_SELECTION_CLEAR: - //qDebug() << "Selection Clear Event"; - break; -//============================== - case 85: //not sure what event this is - but it seems to come up very often (just hide the notice) - case 0: - case XCB_GE_GENERIC: - break; //generic event - don't do anything special - default: - //if( (ev->response_type & ~0x80)==TrayDmgID){ - obj->emit PossibleDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable ); - //checkDamageID( ((xcb_damage_notify_event_t*)ev)->drawable ); - //}else{ - //qDebug() << "Default Event:" << (ev->response_type & ~0x80); - //} -//============================== - } - } - return false; - //never stop event handling (this will not impact the X events themselves - just the internal Qt application) -} diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/core/libLumina/NativeEventFilter.h deleted file mode 100644 index a3be3ef1..00000000 --- a/src-qt5/core/libLumina/NativeEventFilter.h +++ /dev/null @@ -1,71 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2012-2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This class provides the XCB event handling/registrations that are needed -//=========================================== -#ifndef _LUMINA_DESKTOP_NATIVE_EVENT_FILTER_H -#define _LUMINA_DESKTOP_NATIVE_EVENT_FILTER_H - -#include <QAbstractNativeEventFilter> -#include <QObject> -#include <QByteArray> - -#include "NativeWindow.h" - - -class NativeEventFilter : public QObject{ - Q_OBJECT -private: - QAbstractNativeEventFilter* EF; - WId WMFlag; //used to flag a running WM process - -public: - NativeEventFilter(); - ~NativeEventFilter(){} - - void start(); - void stop(); - -signals: - //Window Signals - void WindowCreated(WId); - void WindowDestroyed(WId); - void WindowPropertyChanged(WId, NativeWindow::Property); - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>); - void RequestWindowPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestWindowPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); - - //System Tray Signals - void TrayWindowCreated(WId); - void TrayWindowDestroyed(WId); - - //Miscellaneos Signals - void PossibleDamageEvent(WId); - - //Input Event Signals - void KeyPressed(int, WId); - void KeyReleased(int, WId); - void MousePressed(int, WId); - void MouseReleased(int, WId); - void MouseMovement(); - void MouseEnterWindow(WId); - void MouseLeaveWindow(WId); -}; - -class EventFilter : public QAbstractNativeEventFilter{ -public: - EventFilter(NativeEventFilter *parent); - ~EventFilter(){} - - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *); - -private: - NativeEventFilter *obj; -}; - -#endif diff --git a/src-qt5/core/libLumina/NativeKeyToQt.cpp b/src-qt5/core/libLumina/NativeKeyToQt.cpp deleted file mode 100644 index 06056be7..00000000 --- a/src-qt5/core/libLumina/NativeKeyToQt.cpp +++ /dev/null @@ -1,528 +0,0 @@ - -#include <NativeWindowSystem.h> - -#include <QKeySequence> -#include <QX11Info> - -// XCB/X11 Includes -#define XK_MISCELLANY -#define XK_XKB_KEYS -#define XK_LATIN1 -#define XK_LATIN2 -#define XK_LATIN3 -#define XK_LATIN4 -#define XK_LATIN8 -#define XK_LATIN9 -//NOTE: Look at the keysymdef.h file for additional define/characters which we may need later -#include <X11/keysymdef.h> -#include <xcb/xcb_keysyms.h> - - -//Small simplification functions -Qt::Key NativeWindowSystem::KeycodeToQt(int keycode){ - static xcb_key_symbols_t *SYM = 0; - if(SYM==0){ SYM = xcb_key_symbols_alloc(QX11Info::connection()); } - xcb_keysym_t symbol = xcb_key_symbols_get_keysym(SYM, keycode,0); - //not sure about the "column" input - we want raw keys though so ignore the "modified" key states (columns) for now - //qDebug() << "Try to convert keycode to Qt::Key:" << keycode << symbol; - //Now map this symbol to the appropriate Qt::Key enumeration - switch(symbol){ - //FUNCTION KEYS - case XK_F1: return Qt::Key_F1; - case XK_F2: return Qt::Key_F2; - case XK_F3: return Qt::Key_F3; - case XK_F4: return Qt::Key_F4; - case XK_F5: return Qt::Key_F5; - case XK_F6: return Qt::Key_F6; - case XK_F7: return Qt::Key_F7; - case XK_F8: return Qt::Key_F8; - case XK_F9: return Qt::Key_F9; - case XK_F10: return Qt::Key_F10; - case XK_F11: return Qt::Key_F11; - case XK_F12: return Qt::Key_F12; - case XK_F13: return Qt::Key_F13; - case XK_F14: return Qt::Key_F14; - case XK_F15: return Qt::Key_F15; - case XK_F16: return Qt::Key_F16; - case XK_F17: return Qt::Key_F17; - case XK_F18: return Qt::Key_F18; - case XK_F19: return Qt::Key_F19; - case XK_F20: return Qt::Key_F20; - case XK_F21: return Qt::Key_F21; - case XK_F22: return Qt::Key_F22; - case XK_F23: return Qt::Key_F23; - case XK_F24: return Qt::Key_F24; - case XK_F25: return Qt::Key_F25; - case XK_F26: return Qt::Key_F26; - case XK_F27: return Qt::Key_F27; - case XK_F28: return Qt::Key_F28; - case XK_F29: return Qt::Key_F29; - case XK_F30: return Qt::Key_F30; - case XK_F31: return Qt::Key_F31; - case XK_F32: return Qt::Key_F32; - case XK_F33: return Qt::Key_F33; - case XK_F34: return Qt::Key_F34; - case XK_F35: return Qt::Key_F35; - //Miscellaneous Keys - case XK_BackSpace: return Qt::Key_Backspace; - case XK_Delete: return Qt::Key_Delete; - //case XK_LineFeed: return Qt::Key_Backspace; - case XK_Clear: return Qt::Key_Clear; - case XK_Return: return Qt::Key_Return; - case XK_Pause: return Qt::Key_Pause; - case XK_Scroll_Lock: return Qt::Key_ScrollLock; - case XK_Sys_Req: return Qt::Key_SysReq; - case XK_Escape: return Qt::Key_Escape; - case XK_Select: return Qt::Key_Select; - case XK_Print: return Qt::Key_Print; - //case XK_Execute: return Qt::Key_Execute; - case XK_Insert: return Qt::Key_Insert; - case XK_Undo: return Qt::Key_Undo; - case XK_Redo: return Qt::Key_Redo; - case XK_Menu: return Qt::Key_Menu; - case XK_Find: return Qt::Key_Find; - case XK_Cancel: return Qt::Key_Cancel; - case XK_Help: return Qt::Key_Help; - //case XK_Break: return Qt::Key_Break; - //case XK_Mode_switch: return Qt::Key_Backspace; - //case XK_script_switch: return Qt::Key_Backspace; - case XK_Num_Lock: return Qt::Key_NumLock; - //Cursor Controls - case XK_Home: return Qt::Key_Home; - case XK_Left: return Qt::Key_Left; - case XK_Up: return Qt::Key_Up; - case XK_Right: return Qt::Key_Right; - case XK_Down: return Qt::Key_Down; - //case XK_Prior: return Qt::Key_Backspace; - case XK_Page_Up: return Qt::Key_PageUp; - case XK_Page_Down: return Qt::Key_PageDown; - //case XK_Next: return Qt::Key_Backspace; - case XK_End: return Qt::Key_End; - //case XK_Begin: return Qt::Key_Backspace; - // Keypad Functions and numbers - case XK_KP_Space: return Qt::Key_Space; - case XK_KP_Tab: return Qt::Key_Tab; - case XK_KP_Enter: return Qt::Key_Enter; - case XK_KP_F1: return Qt::Key_F1; - case XK_KP_F2: return Qt::Key_F2; - case XK_KP_F3: return Qt::Key_F3; - case XK_KP_F4: return Qt::Key_F4; - case XK_KP_Home: return Qt::Key_Home; - case XK_KP_Left: return Qt::Key_Left; - case XK_KP_Up: return Qt::Key_Up; - case XK_KP_Right: return Qt::Key_Right; - case XK_KP_Down: return Qt::Key_Down; - //case XK_KP_Prior: return Qt::Key_ - case XK_KP_Page_Up: return Qt::Key_PageUp; - //case XK_KP_Next: return Qt::Key_ - case XK_KP_Page_Down: return Qt::Key_PageDown; - case XK_KP_End: return Qt::Key_End; - //case XK_KP_Begin: return Qt::Key_ - case XK_KP_Insert: return Qt::Key_Insert; - case XK_KP_Delete: return Qt::Key_Delete; - case XK_KP_Equal: return Qt::Key_Equal; - case XK_KP_Multiply: return Qt::Key_Asterisk; - case XK_KP_Add: return Qt::Key_Plus; - case XK_KP_Separator: return Qt::Key_Comma; //X11 definitions say this is often comma - case XK_KP_Subtract: return Qt::Key_Minus; - case XK_KP_Decimal: return Qt::Key_Period; - case XK_KP_Divide: return Qt::Key_Slash; - case XK_KP_0: return Qt::Key_0; - case XK_KP_1: return Qt::Key_1; - case XK_KP_2: return Qt::Key_2; - case XK_KP_3: return Qt::Key_3; - case XK_KP_4: return Qt::Key_4; - case XK_KP_5: return Qt::Key_5; - case XK_KP_6: return Qt::Key_6; - case XK_KP_7: return Qt::Key_7; - case XK_KP_8: return Qt::Key_8; - case XK_KP_9: return Qt::Key_9; - // Modifier Keys - case XK_Shift_L: return Qt::Key_Shift; - case XK_Shift_R: return Qt::Key_Shift; - case XK_Control_L: return Qt::Key_Control; - case XK_Control_R: return Qt::Key_Control; - case XK_Caps_Lock: return Qt::Key_CapsLock; - //case XK_Shift_Lock: return Qt::Key_ShiftLock; - case XK_Meta_L: return Qt::Key_Meta; - case XK_Meta_R: return Qt::Key_Meta; - case XK_Alt_L: return Qt::Key_Alt; - case XK_Alt_R: return Qt::Key_Alt; - case XK_Super_L: return Qt::Key_Super_L; - case XK_Super_R: return Qt::Key_Super_R; - case XK_Hyper_L: return Qt::Key_Hyper_L; - case XK_Hyper_R: return Qt::Key_Hyper_R; - case XK_space: return Qt::Key_Space; - case XK_exclam: return Qt::Key_Exclam; - case XK_quotedbl: return Qt::Key_QuoteDbl; - case XK_numbersign: return Qt::Key_NumberSign; - case XK_dollar: return Qt::Key_Dollar; - case XK_percent: return Qt::Key_Percent; - case XK_ampersand: return Qt::Key_Ampersand; - case XK_apostrophe: return Qt::Key_Apostrophe; - case XK_parenleft: return Qt::Key_ParenLeft; - case XK_parenright: return Qt::Key_ParenRight; - case XK_asterisk: return Qt::Key_Asterisk; - case XK_plus: return Qt::Key_Plus; - case XK_comma: return Qt::Key_Comma; - case XK_minus: return Qt::Key_Minus; - case XK_period: return Qt::Key_Period; - case XK_slash: return Qt::Key_Slash; - case XK_0: return Qt::Key_0; - case XK_1: return Qt::Key_1; - case XK_2: return Qt::Key_2; - case XK_3: return Qt::Key_3; - case XK_4: return Qt::Key_4; - case XK_5: return Qt::Key_5; - case XK_6: return Qt::Key_6; - case XK_7: return Qt::Key_7; - case XK_8: return Qt::Key_8; - case XK_9: return Qt::Key_9; - case XK_colon: return Qt::Key_Colon; - case XK_semicolon: return Qt::Key_Semicolon; - case XK_less: return Qt::Key_Less; - case XK_equal: return Qt::Key_Equal; - case XK_greater: return Qt::Key_Greater; - case XK_question: return Qt::Key_Question; - case XK_at: return Qt::Key_At; - case XK_A: return Qt::Key_A; - case XK_B: return Qt::Key_B; - case XK_C: return Qt::Key_C; - case XK_D: return Qt::Key_D; - case XK_E: return Qt::Key_E; - case XK_F: return Qt::Key_F; - case XK_G: return Qt::Key_G; - case XK_H: return Qt::Key_H; - case XK_I: return Qt::Key_I; - case XK_J: return Qt::Key_J; - case XK_K: return Qt::Key_K; - case XK_L: return Qt::Key_L; - case XK_M: return Qt::Key_M; - case XK_N: return Qt::Key_N; - case XK_O: return Qt::Key_O; - case XK_P: return Qt::Key_P; - case XK_Q: return Qt::Key_Q; - case XK_R: return Qt::Key_R; - case XK_S: return Qt::Key_S; - case XK_T: return Qt::Key_T; - case XK_U: return Qt::Key_U; - case XK_V: return Qt::Key_V; - case XK_W: return Qt::Key_W; - case XK_X: return Qt::Key_X; - case XK_Y : return Qt::Key_Y; - case XK_Z: return Qt::Key_Z; - case XK_bracketleft: return Qt::Key_BracketLeft; - case XK_backslash: return Qt::Key_Backslash; - case XK_bracketright: return Qt::Key_BracketRight; - case XK_asciicircum: return Qt::Key_AsciiCircum; - case XK_underscore: return Qt::Key_Underscore; - case XK_grave: return Qt::Key_Agrave; - case XK_a: return Qt::Key_A; - case XK_b: return Qt::Key_B; - case XK_c: return Qt::Key_C; - case XK_d: return Qt::Key_D; - case XK_e: return Qt::Key_E; - case XK_f : return Qt::Key_F; - case XK_g: return Qt::Key_G; - case XK_h: return Qt::Key_H; - case XK_i: return Qt::Key_I; - case XK_j: return Qt::Key_J; - case XK_k: return Qt::Key_K; - case XK_l: return Qt::Key_L; - case XK_m: return Qt::Key_M; - case XK_n: return Qt::Key_N; - case XK_o: return Qt::Key_O; - case XK_p: return Qt::Key_P; - case XK_q: return Qt::Key_Q; - case XK_r: return Qt::Key_R; - case XK_s: return Qt::Key_S; - case XK_t : return Qt::Key_T; - case XK_u: return Qt::Key_U; - case XK_v: return Qt::Key_V; - case XK_w: return Qt::Key_W; - case XK_x: return Qt::Key_X; - case XK_y: return Qt::Key_Y; - case XK_z: return Qt::Key_Z; - case XK_braceleft: return Qt::Key_BraceLeft; - case XK_bar: return Qt::Key_Bar; - case XK_braceright: return Qt::Key_BraceRight; - case XK_asciitilde: return Qt::Key_AsciiTilde; - - case XK_nobreakspace: return Qt::Key_nobreakspace; - case XK_exclamdown: return Qt::Key_exclamdown; - case XK_cent: return Qt::Key_cent; - case XK_sterling: return Qt::Key_sterling; - case XK_currency: return Qt::Key_currency; - case XK_yen: return Qt::Key_yen; - case XK_brokenbar: return Qt::Key_brokenbar; - case XK_section: return Qt::Key_section; - case XK_diaeresis: return Qt::Key_diaeresis; - case XK_copyright: return Qt::Key_copyright; - case XK_ordfeminine: return Qt::Key_ordfeminine; - case XK_guillemotleft: return Qt::Key_guillemotleft; - case XK_notsign: return Qt::Key_notsign; - case XK_hyphen: return Qt::Key_hyphen; - case XK_registered: return Qt::Key_registered; - case XK_macron: return Qt::Key_macron; - case XK_degree: return Qt::Key_degree; - case XK_plusminus: return Qt::Key_plusminus; - case XK_twosuperior: return Qt::Key_twosuperior; - case XK_threesuperior: return Qt::Key_threesuperior; - case XK_acute: return Qt::Key_acute; - case XK_mu: return Qt::Key_mu; - case XK_paragraph: return Qt::Key_paragraph; - case XK_periodcentered: return Qt::Key_periodcentered; - case XK_cedilla: return Qt::Key_cedilla; - case XK_onesuperior: return Qt::Key_onesuperior; - case XK_masculine: return Qt::Key_masculine; - case XK_guillemotright: return Qt::Key_guillemotright; - case XK_onequarter: return Qt::Key_onequarter; - case XK_onehalf: return Qt::Key_onehalf; - case XK_threequarters: return Qt::Key_threequarters; - case XK_questiondown: return Qt::Key_questiondown; - case XK_Agrave: return Qt::Key_Agrave; - case XK_Aacute: return Qt::Key_Aacute; - case XK_Acircumflex: return Qt::Key_Acircumflex; - case XK_Atilde: return Qt::Key_Atilde; - case XK_Adiaeresis: return Qt::Key_Adiaeresis; - case XK_Aring: return Qt::Key_Aring; - case XK_AE: return Qt::Key_AE; - case XK_Ccedilla: return Qt::Key_Ccedilla; - case XK_Egrave: return Qt::Key_Egrave; - case XK_Eacute: return Qt::Key_Eacute; - case XK_Ecircumflex: return Qt::Key_Ecircumflex; - case XK_Ediaeresis: return Qt::Key_Ediaeresis; - case XK_Igrave: return Qt::Key_Igrave; - case XK_Iacute: return Qt::Key_Iacute; - case XK_Icircumflex: return Qt::Key_Icircumflex; - case XK_Idiaeresis: return Qt::Key_Idiaeresis; - case XK_ETH: return Qt::Key_ETH; - //case XK_Eth: return Qt::Key_Eth; - case XK_Ntilde: return Qt::Key_Ntilde; - case XK_Ograve: return Qt::Key_Ograve; - case XK_Oacute: return Qt::Key_Oacute; - case XK_Ocircumflex: return Qt::Key_Ocircumflex; - case XK_Otilde: return Qt::Key_Otilde; - case XK_Odiaeresis: return Qt::Key_Odiaeresis; - case XK_multiply: return Qt::Key_multiply; - //case XK_Oslash: return Qt::Key_AsciiTilde; - case XK_Ooblique: return Qt::Key_Ooblique; - case XK_Ugrave: return Qt::Key_Ugrave; - case XK_Uacute: return Qt::Key_Uacute; - case XK_Ucircumflex: return Qt::Key_Ucircumflex; - case XK_Udiaeresis: return Qt::Key_Udiaeresis; - case XK_Yacute: return Qt::Key_Yacute; - case XK_THORN: return Qt::Key_THORN; - //case XK_Thorn: return Qt::Key_AsciiTilde; - case XK_ssharp: return Qt::Key_ssharp; - /*case XK_agrave: return Qt::Key_AsciiTilde; - case XK_aacute: return Qt::Key_AsciiTilde; - case XK_acircumflex: return Qt::Key_AsciiTilde; - case XK_atilde: return Qt::Key_AsciiTilde; - case XK_adiaeresis: return Qt::Key_AsciiTilde; - case XK_aring: return Qt::Key_AsciiTilde; - case XK_ae: return Qt::Key_AsciiTilde; - case XK_ccedilla: return Qt::Key_AsciiTilde; - case XK_egrave: return Qt::Key_AsciiTilde; - case XK_eacute: return Qt::Key_AsciiTilde; - case XK_ecircumflex: return Qt::Key_AsciiTilde; - case XK_ediaeresis: return Qt::Key_AsciiTilde; - case XK_igrave: return Qt::Key_AsciiTilde; - case XK_iacute: return Qt::Key_AsciiTilde; - case XK_icircumflex: return Qt::Key_AsciiTilde; - case XK_idiaeresis: return Qt::Key_AsciiTilde; - case XK_eth: return Qt::Key_AsciiTilde; - case XK_ntilde: return Qt::Key_AsciiTilde; - case XK_ograve: return Qt::Key_AsciiTilde; - case XK_oacute: return Qt::Key_AsciiTilde; - case XK_ocircumflex: return Qt::Key_AsciiTilde; - case XK_otilde: return Qt::Key_AsciiTilde; - case XK_odiaeresis: return Qt::Key_AsciiTilde; - case XK_division: return Qt::Key_AsciiTilde; - case XK_oslash: return Qt::Key_AsciiTilde; - case XK_ooblique: return Qt::Key_AsciiTilde; - case XK_ugrave: return Qt::Key_AsciiTilde; - case XK_uacute: return Qt::Key_AsciiTilde; - case XK_ucircumflex: return Qt::Key_AsciiTilde; - case XK_udiaeresis: return Qt::Key_AsciiTilde; - case XK_yacute: return Qt::Key_AsciiTilde; - case XK_thorn: return Qt::Key_AsciiTilde; - case XK_ydiaeresis: return Qt::Key_AsciiTilde; - - case: XK_Agonek: return Qt::Key_AsciiTilde; - case XK_breve: return Qt::Key_AsciiTilde; - case XK_Lstroke: return Qt::Key_AsciiTilde; - case XK_Lcaron: return Qt::Key_AsciiTilde; - case XK_Sacute: return Qt::Key_AsciiTilde; - case XK_Scaron: return Qt::Key_AsciiTilde; - case XK_Scedilla: return Qt::Key_AsciiTilde; - case XK_Tcaron: return Qt::Key_AsciiTilde; - case XK_Zacute: return Qt::Key_AsciiTilde; - case XK_Zcaron: return Qt::Key_AsciiTilde; - case XK_Zabovedot: return Qt::Key_AsciiTilde; - case XK_aogonek: return Qt::Key_AsciiTilde; - case XK_ogonek: return Qt::Key_AsciiTilde; - case XK_lstroke: return Qt::Key_AsciiTilde; - case XK_lcaron: return Qt::Key_AsciiTilde; - case XK_sacute: return Qt::Key_AsciiTilde; - case XK_caron: return Qt::Key_AsciiTilde; - case XK_scaron: return Qt::Key_AsciiTilde; - case XK_scedilla: return Qt::Key_AsciiTilde; - case XK_tcaron: return Qt::Key_AsciiTilde; - case XK_zacute: return Qt::Key_AsciiTilde; - case XK_doubleacute: return Qt::Key_AsciiTilde; - case XK_zcaron: return Qt::Key_AsciiTilde; - case XK_zabovedot: return Qt::Key_AsciiTilde; - case XK_Racute: return Qt::Key_AsciiTilde; - case XK_Abreve: return Qt::Key_AsciiTilde; - case XK_Lacute: return Qt::Key_AsciiTilde; - case XK_Cacute: return Qt::Key_AsciiTilde; - case XK_Ccaron: return Qt::Key_AsciiTilde; - case XK_Eogonek: return Qt::Key_AsciiTilde; - case XK_Ecaron: return Qt::Key_AsciiTilde; - case XK_Dcaron: return Qt::Key_AsciiTilde; - case XK_Dstroke: return Qt::Key_AsciiTilde; - case XK_Nacute: return Qt::Key_AsciiTilde; - case XK_Ncaron: return Qt::Key_AsciiTilde; - case XK_Odoubleacute: return Qt::Key_AsciiTilde; - case XK_Rcaron: return Qt::Key_AsciiTilde; - case XK_Uring: return Qt::Key_AsciiTilde; - case XK_Udoubleacute: return Qt::Key_AsciiTilde; - case XK_Tcedilla: return Qt::Key_AsciiTilde; - case XK_racute: return Qt::Key_AsciiTilde; - case XK_abreve: return Qt::Key_AsciiTilde; - case XK_lacute: return Qt::Key_AsciiTilde; - case XK_cacute: return Qt::Key_AsciiTilde; - case XK_ccaron: return Qt::Key_AsciiTilde; - case XK_eogonek: return Qt::Key_AsciiTilde; - case XK_ecaron: return Qt::Key_AsciiTilde; - case XK_dcaron: return Qt::Key_AsciiTilde; - case XK_dstroke: return Qt::Key_AsciiTilde; - case XK_nacute: return Qt::Key_AsciiTilde; - case XK_ncaron: return Qt::Key_AsciiTilde; - case XK_odoubleacute: return Qt::Key_AsciiTilde; - case XK_rcaron: return Qt::Key_AsciiTilde; - case XK_uring: return Qt::Key_AsciiTilde; - case XK_udoubleacute: return Qt::Key_AsciiTilde; - case XK_tcedilla: return Qt::Key_AsciiTilde; - case XK_abovedot: return Qt::Key_AsciiTilde; - case XK_Hstroke: return Qt::Key_AsciiTilde; - case XK_Hcircumflex: return Qt::Key_AsciiTilde; - case XK_Iabovedot: return Qt::Key_AsciiTilde; - case XK_Gbreve: return Qt::Key_AsciiTilde; - case XK_Jcircumflex: return Qt::Key_AsciiTilde; - case XK_hstroke: return Qt::Key_AsciiTilde; - case XK_hcircumflex: return Qt::Key_AsciiTilde; - case XK_idotless: return Qt::Key_AsciiTilde; - case XK_gbreve: return Qt::Key_AsciiTilde; - case XK_jcircumflex: return Qt::Key_AsciiTilde; - case XK_Cabovedot: return Qt::Key_AsciiTilde; - case XK_Ccircumflex: return Qt::Key_AsciiTilde; - case XK_Gabovedot: return Qt::Key_AsciiTilde; - case XK_Gcircumflex: return Qt::Key_AsciiTilde; - case XK_Ubreve: return Qt::Key_AsciiTilde; - case XK_Scircumflex: return Qt::Key_AsciiTilde; - case XK_cabovedot: return Qt::Key_AsciiTilde; - case XK_ccircumflex: return Qt::Key_AsciiTilde; - case XK_gabovedot: return Qt::Key_AsciiTilde; - case XK_gcircumflex: return Qt::Key_AsciiTilde; - case XK_ubreve: return Qt::Key_AsciiTilde; - case XK_scircumflex: return Qt::Key_AsciiTilde; - case XK_kra: return Qt::Key_AsciiTilde; - case XK_kappa: return Qt::Key_AsciiTilde; - case XK_Rcedilla: return Qt::Key_AsciiTilde; - case XK_Itilde: return Qt::Key_AsciiTilde; - case XK_Lcedilla: return Qt::Key_AsciiTilde; - case XK_Emacron: return Qt::Key_AsciiTilde; - case XK_Gcedilla: return Qt::Key_AsciiTilde; - case XK_Tslash: return Qt::Key_AsciiTilde; - case XK_rcedilla: return Qt::Key_AsciiTilde; - case XK_itilde: return Qt::Key_AsciiTilde; - case XK_lcedilla: return Qt::Key_AsciiTilde; - case XK_emacron: return Qt::Key_AsciiTilde; - case XK_gcedilla: return Qt::Key_AsciiTilde; - case XK_tslash: return Qt::Key_AsciiTilde; - case XK_ENG: return Qt::Key_AsciiTilde; - case XK_eng: return Qt::Key_AsciiTilde; - case XK_Amacron: return Qt::Key_AsciiTilde; - case XK_Iogonek: return Qt::Key_AsciiTilde; - case XK_Eabovedot: return Qt::Key_AsciiTilde; - case XK_Imacron: return Qt::Key_AsciiTilde; - case XK_Ncedilla: return Qt::Key_AsciiTilde; - case XK_Omacron: return Qt::Key_AsciiTilde; - case XK_Kcedilla: return Qt::Key_AsciiTilde; - case XK_Uogonek: return Qt::Key_AsciiTilde; - case XK_Utilde: return Qt::Key_AsciiTilde; - case XK_Umacron: return Qt::Key_AsciiTilde; - case XK_amacron: return Qt::Key_AsciiTilde; - case XK_iogonek: return Qt::Key_AsciiTilde; - case XK_eabovedot: return Qt::Key_AsciiTilde; - case XK_imacron: return Qt::Key_AsciiTilde; - case XK_ncedilla: return Qt::Key_AsciiTilde; - case XK_omacron: return Qt::Key_AsciiTilde; - case XK_kcedilla: return Qt::Key_AsciiTilde; - case XK_uogonek: return Qt::Key_AsciiTilde; - case XK_utilde: return Qt::Key_AsciiTilde; - case XK_umacron: return Qt::Key_AsciiTilde; - case XK_Wcircumflex: return Qt::Key_AsciiTilde; - case XK_wcircumflex: return Qt::Key_AsciiTilde; - case XK_Ycircumflex: return Qt::Key_AsciiTilde; - case XK_ycircumflex: return Qt::Key_AsciiTilde; - case XK_Babovedot: return Qt::Key_AsciiTilde; - case XK_babovedot: return Qt::Key_AsciiTilde; - case XK_Dabovedot: return Qt::Key_AsciiTilde; - case XK_dabovedot: return Qt::Key_AsciiTilde; - case XK_Fabovedot: return Qt::Key_AsciiTilde; - case XK_fabovedot: return Qt::Key_AsciiTilde; - case XK_Mabovedot: return Qt::Key_AsciiTilde; - case XK_mabovedot: return Qt::Key_AsciiTilde; - case XK_Pabovedot: return Qt::Key_AsciiTilde; - case XK_pabovedot: return Qt::Key_AsciiTilde; - case XK_Sabovedot: return Qt::Key_AsciiTilde; - case XK_sabovedot: return Qt::Key_AsciiTilde; - case XK_Tabovedot: return Qt::Key_AsciiTilde; - case XK_tabovedot: return Qt::Key_AsciiTilde; - case XK_Wgrave: return Qt::Key_AsciiTilde; - case XK_wgrave: return Qt::Key_AsciiTilde; - case XK_Wacute: return Qt::Key_AsciiTilde; - case XK_wacute: return Qt::Key_AsciiTilde; - case XK_Wdiaeresis: return Qt::Key_AsciiTilde; - case XK_wdiaeresis: return Qt::Key_AsciiTilde; - case XK_Ygrave: return Qt::Key_AsciiTilde; - case XK_ygrave: return Qt::Key_AsciiTilde; - case XK_OE: return Qt::Key_AsciiTilde; - case XK_oe: return Qt::Key_AsciiTilde; - case XK_Ydiaeresis: return Qt::Key_AsciiTilde;*/ - default: - qDebug() << "Unknown Key"; - } - qDebug() << " -- Simple Qt Map:" << (Qt::Key)(symbol); - qDebug() << " -- Key Sequence Map:" << QKeySequence(symbol); - qDebug() << " - Not implemented yet"; - return Qt::Key_unknown; -} - -NativeWindowSystem::MouseButton NativeWindowSystem::MouseToQt(int keycode){ - switch(keycode){ - case 1: - return NativeWindowSystem::LeftButton; - case 3: - return NativeWindowSystem::RightButton; - case 2: - return NativeWindowSystem::MidButton; - case 4: - return NativeWindowSystem::WheelUp; - case 5: - return NativeWindowSystem::WheelDown; - case 6: - return NativeWindowSystem::WheelLeft; - case 7: - return NativeWindowSystem::WheelRight; - case 8: - return NativeWindowSystem::BackButton; //Not sure if this is correct yet (1/27/17) - case 9: - return NativeWindowSystem::ForwardButton; //Not sure if this is correct yet (1/27/17) - default: - return NativeWindowSystem::NoButton; - } -} diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp deleted file mode 100644 index 02cc001e..00000000 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ /dev/null @@ -1,123 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "NativeWindow.h" - -#include <QDebug> - -// === PUBLIC === -NativeWindow::NativeWindow(WId id) : QObject(){ - winid = id; - frameid = 0; - dmgID = 0; -} - -NativeWindow::~NativeWindow(){ - hash.clear(); -} - -void NativeWindow::addFrameWinID(WId fid){ - frameid = fid; -} - -void NativeWindow::addDamageID(unsigned int dmg){ - dmgID = dmg; -} - -bool NativeWindow::isRelatedTo(WId tmp){ - return (relatedTo.contains(tmp) || winid == tmp || frameid == tmp); -} - -WId NativeWindow::id(){ - return winid; -} - -WId NativeWindow::frameId(){ - return frameid; -} - -unsigned int NativeWindow::damageId(){ - return dmgID; -} - -QVariant NativeWindow::property(NativeWindow::Property prop){ - if(hash.contains(prop)){ return hash.value(prop); } - else if(prop == NativeWindow::RelatedWindows){ return QVariant::fromValue(relatedTo); } - return QVariant(); //null variant -} - -void NativeWindow::setProperty(NativeWindow::Property prop, QVariant val, bool force){ - if(prop == NativeWindow::RelatedWindows){ relatedTo = val.value< QList<WId> >(); } - else if(prop == NativeWindow::None || (!force && hash.value(prop)==val)){ return; } - else{ hash.insert(prop, val); } - emit PropertiesChanged(QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); -} - -void NativeWindow::setProperties(QList<NativeWindow::Property> props, QList<QVariant> vals, bool force){ - for(int i=0; i<props.length(); i++){ - if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindow::None || (!force && (hash.value(props[i]) == vals[i])) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value - hash.insert(props[i], vals[i]); - } - emit PropertiesChanged(props, vals); -} - -void NativeWindow::requestProperty(NativeWindow::Property prop, QVariant val, bool force){ - if(prop == NativeWindow::None || prop == NativeWindow::RelatedWindows || (!force && hash.value(prop)==val) ){ return; } - emit RequestPropertiesChange(winid, QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); -} - -void NativeWindow::requestProperties(QList<NativeWindow::Property> props, QList<QVariant> vals, bool force){ - //Verify/adjust inputs as needed - for(int i=0; i<props.length(); i++){ - if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindow::None || props[i] == NativeWindow::RelatedWindows || (!force && hash.value(props[i])==vals[i]) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value - /*if( (props[i] == NativeWindow::Visible || props[i] == NativeWindow::Active) && frameid !=0){ - //These particular properties needs to change the frame - not the window itself - emit RequestPropertiesChange(frameid, QList<NativeWindow::Property>() << props[i], QList<QVariant>() << vals[i]); - props.removeAt(i); vals.removeAt(i); i--; - }*/ - } - emit RequestPropertiesChange(winid, props, vals); -} - -QRect NativeWindow::geometry(){ - //Calculate the "full" geometry of the window + frame (if any) - //Check that the size is between the min/max limitations - QSize size = hash.value(NativeWindow::Size).toSize(); - QSize min = hash.value(NativeWindow::MinSize).toSize(); - QSize max = hash.value(NativeWindow::MaxSize).toSize(); - if(min.isValid() && min.width() > size.width() ){ size.setWidth(min.width()); } - if(min.isValid() && min.height() > size.height()){ size.setHeight(min.height()); } - if(max.isValid() && max.width() < size.width() && max.width()>min.width()){ size.setWidth(max.width()); } - if(max.isValid() && max.height() < size.height() && max.height()>min.height()){ size.setHeight(max.height()); } - //Assemble the full geometry - QRect geom( hash.value(NativeWindow::GlobalPos).toPoint(), size ); - //Now adjust the window geom by the frame margins - QList<int> frame = hash.value(NativeWindow::FrameExtents).value< QList<int> >(); //Left,Right,Top,Bottom - //qDebug() << "Calculate Geometry:" << geom << frame; - if(frame.length()==4){ - geom = geom.adjusted( -frame[0], -frame[2], frame[1], frame[3] ); - } - //qDebug() << " - Total:" << geom; - return geom; -} -// ==== PUBLIC SLOTS === -void NativeWindow::toggleVisibility(){ - setProperty(NativeWindow::Visible, !property(NativeWindow::Visible).toBool() ); -} - -void NativeWindow::requestClose(){ - emit RequestClose(winid); -} - -void NativeWindow::requestKill(){ - emit RequestKill(winid); -} - -void NativeWindow::requestPing(){ - emit RequestPing(winid); -} diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h deleted file mode 100644 index 67436259..00000000 --- a/src-qt5/core/libLumina/NativeWindow.h +++ /dev/null @@ -1,118 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This is a container object for setting/announcing changes -// in a native window's properties. -// The WM will usually run the "setProperty" function on this object, -// and any other classes/widgets which watch this window can act appropriatly after-the-fact -// Non-WM classes should use the "Request" signals to ask the WM to do something, and listen for changes later -//=========================================== -#ifndef _LUMINA_DESKTOP_NATIVE_WINDOW_H -#define _LUMINA_DESKTOP_NATIVE_WINDOW_H - -#include <QString> -#include <QRect> -#include <QSize> -#include <QObject> -#include <QWindow> -#include <QHash> -#include <QVariant> - -class NativeWindow : public QObject{ - Q_OBJECT -public: - enum State{ S_MODAL, S_STICKY, S_MAX_VERT, S_MAX_HORZ, S_SHADED, S_SKIP_TASKBAR, S_SKIP_PAGER, S_HIDDEN, S_FULLSCREEN, S_ABOVE, S_BELOW, S_ATTENTION }; - enum Type{T_DESKTOP, T_DOCK, T_TOOLBAR, T_MENU, T_UTILITY, T_SPLASH, T_DIALOG, T_DROPDOWN_MENU, T_POPUP_MENU, T_TOOLTIP, T_NOTIFICATION, T_COMBO, T_DND, T_NORMAL }; - enum Action {A_MOVE, A_RESIZE, A_MINIMIZE, A_SHADE, A_STICK, A_MAX_VERT, A_MAX_HORZ, A_FULLSCREEN, A_CHANGE_DESKTOP, A_CLOSE, A_ABOVE, A_BELOW}; - - enum Property{ /*QVariant Type*/ - None=0, /*null*/ - MinSize=1, /*QSize*/ - MaxSize=2, /*QSize*/ - Size=3, /*QSize*/ - GlobalPos=4, /*QPoint*/ - Title=5, /*QString*/ - ShortTitle=6, /*QString*/ - Icon=7, /*QIcon*/ - Name=8, /*QString*/ - Workspace=9, /*int*/ - States=10, /*QList<NativeWindow::State> : Current state of the window */ - WinTypes=11, /*QList<NativeWindow::Type> : Current type of window (typically does not change)*/ - WinActions=12, /*QList<NativeWindow::Action> : Current actions that the window allows (Managed/set by the WM)*/ - FrameExtents=13, /*QList<int> : [Left, Right, Top, Bottom] in pixels */ - RelatedWindows=14, /* QList<WId> - better to use the "isRelatedTo(WId)" function instead of reading this directly*/ - Active=15, /*bool*/ - Visible=16 /*bool*/ - }; - - static QList<NativeWindow::Property> allProperties(){ - //Return all the available properties (excluding "None" and "FrameExtents" (WM control only) ) - QList<NativeWindow::Property> props; - props << MinSize << MaxSize << Size << GlobalPos << Title << ShortTitle << Icon << Name << Workspace \ - << States << WinTypes << WinActions << RelatedWindows << Active << Visible; - return props; - }; - - NativeWindow(WId id); - ~NativeWindow(); - - void addFrameWinID(WId); - void addDamageID(unsigned int); - bool isRelatedTo(WId); - - WId id(); - WId frameId(); - unsigned int damageId(); - - //QWindow* window(); - - QVariant property(NativeWindow::Property); - void setProperty(NativeWindow::Property, QVariant, bool force = false); - void setProperties(QList<NativeWindow::Property>, QList<QVariant>, bool force = false); - void requestProperty(NativeWindow::Property, QVariant, bool force = false); - void requestProperties(QList<NativeWindow::Property>, QList<QVariant>, bool force = false); - - QRect geometry(); //this returns the "full" geometry of the window (window + frame) - -public slots: - void toggleVisibility(); - void requestClose(); //ask the app to close the window (may/not depending on activity) - void requestKill(); //ask the WM to kill the app associated with this window (harsh - only use if not responding) - void requestPing(); //ask the app if it is still active (a WindowNotResponding signal will get sent out if there is no reply); - -private: - QHash <NativeWindow::Property, QVariant> hash; - //QWindow *WIN; - WId winid, frameid; - QList<WId> relatedTo; - unsigned int dmgID; - -signals: - //General Notifications - void PropertiesChanged(QList<NativeWindow::Property>, QList<QVariant>); - void RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); - void WindowClosed(WId); - void WindowNotResponding(WId); //will be sent out if a window does not respond to a ping request - void VisualChanged(); - - //Action Requests (not automatically emitted - typically used to ask the WM to do something) - //Note: "WId" should be the NativeWindow id() - void RequestClose(WId); //Close the window - void RequestKill(WId); //Kill the window/app (usually from being unresponsive) - void RequestPing(WId); //Verify that the window is still active (such as not closing after a request - void RequestReparent(WId, WId, QPoint); //client window, frame window, relative origin point in frame - // System Tray Icon Embed/Unembed Requests - //void RequestEmbed(WId, QWidget*); - //void RequestUnEmbed(WId, QWidget*); -}; - -// Declare the enumerations as Qt MetaTypes -Q_DECLARE_METATYPE(NativeWindow::Type); -Q_DECLARE_METATYPE(NativeWindow::Action); -Q_DECLARE_METATYPE(NativeWindow::State); -Q_DECLARE_METATYPE(NativeWindow::Property); - -#endif diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri deleted file mode 100644 index c906d6fd..00000000 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ /dev/null @@ -1,18 +0,0 @@ - -# Files -QT *= x11extras -LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage -#QT *= -lxcb-render -lxcb-render-util - -SOURCES *= $${PWD}/NativeWindow.cpp \ - $${PWD}/NativeWindowSystem.cpp \ - $${PWD}/NativeKeyToQt.cpp \ - $${PWD}/NativeEventFilter.cpp \ - $${PWD}/NativeEmbedWidget.cpp - -HEADERS *= $${PWD}/NativeWindow.h \ - $${PWD}/NativeWindowSystem.h \ - $${PWD}/NativeEventFilter.h \ - $${PWD}/NativeEmbedWidget.h - -INCLUDEPATH *= $${PWD} diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp deleted file mode 100644 index e8e9655a..00000000 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ /dev/null @@ -1,986 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This is the XCB version of the NativeWindowSystem class, -// used for interacting with the X11 display system on BSD/Linux/Unix systems -//=========================================== -#include "NativeWindowSystem.h" - -//Additional Qt includes -#include <QX11Info> -#include <QDebug> -#include <QApplication> -#include <QScreen> -#include <QFont> -#include <QFontMetrics> -#include <QKeySequence> - - -//XCB Library includes -#include <xcb/xcb.h> -#include <xcb/xcb_atom.h> -#include <xcb/xproto.h> -#include <xcb/xcb_ewmh.h> -#include <xcb/xcb_icccm.h> -#include <xcb/xcb_image.h> -#include <xcb/xcb_aux.h> -#include <xcb/composite.h> -#include <xcb/damage.h> - -//XLib includes (XCB Damage lib does not appear to register for damage events properly) -#include <X11/extensions/Xdamage.h> - -//SYSTEM TRAY STANDARD DEFINITIONS -#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 -#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1 -#define SYSTEM_TRAY_REQUEST_DOCK 0 -#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -#define SYSTEM_TRAY_CANCEL_MESSAGE 2 - -#define URGENCYHINT (1L << 8) //For window urgency detection - -#define ROOT_WIN_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_PROPERTY_CHANGE | \ - XCB_EVENT_MASK_FOCUS_CHANGE | \ - XCB_EVENT_MASK_ENTER_WINDOW) - -#define NORMAL_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_BUTTON_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW | \ - XCB_EVENT_MASK_PROPERTY_CHANGE | \ - XCB_EVENT_MASK_FOCUS_CHANGE) - -#define CLIENT_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_FOCUS_CHANGE | \ - XCB_EVENT_MASK_POINTER_MOTION) - -#define FRAME_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW) - -inline void registerClientEvents(WId id, bool client = true){ - uint32_t values[] = {XCB_NONE}; - values[0] = client ? CLIENT_EVENT_MASK : FRAME_EVENT_MASK ; - /*{ (XCB_EVENT_MASK_PROPERTY_CHANGE - | XCB_EVENT_MASK_BUTTON_PRESS - | XCB_EVENT_MASK_BUTTON_RELEASE - | XCB_EVENT_MASK_POINTER_MOTION - | XCB_EVENT_MASK_BUTTON_MOTION - | XCB_EVENT_MASK_EXPOSURE - | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT - | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY - | XCB_EVENT_MASK_ENTER_WINDOW) - };*/ - xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, values); -} - -/*inline void registerClientEvents(WId id){ - uint32_t value_list[1] = {NORMAL_WIN_EVENT_MASK}; - xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); -}*/ - -//Internal XCB private objects class -class NativeWindowSystem::p_objects{ -public: - xcb_ewmh_connection_t EWMH; //This is where all the screen info and atoms are located - QHash<QString, xcb_atom_t> ATOMS; - xcb_screen_t *root_screen; - xcb_window_t root_window, wm_window, tray_window; - - //Functions for setting up these objects as needed - bool init_ATOMS(){ - xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(QX11Info::connection(), &EWMH); - if(!xcb_ewmh_init_atoms_replies(&EWMH, cookie, NULL) ){ - qDebug() << "Error with XCB atom initializations"; - return false; - } - - QStringList atoms; - atoms << "WM_TAKE_FOCUS" << "WM_DELETE_WINDOW" << "WM_PROTOCOLS" << "_NET_WM_WINDOW_OPACITY" - << "WM_CHANGE_STATE" << "_NET_SYSTEM_TRAY_OPCODE" << "_NET_SYSTEM_TRAY_ORIENTATION" << "_XEMBED" - << "_NET_SYSTEM_TRAY_VISUAL" << QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(QX11Info::appScreen())); - //Create all the requests for the atoms - QList<xcb_intern_atom_reply_t*> reply; - for(int i=0; i<atoms.length(); i++){ - reply << xcb_intern_atom_reply(QX11Info::connection(), \ - xcb_intern_atom(QX11Info::connection(), 0, atoms[i].length(), atoms[i].toLocal8Bit()), NULL); - } - //Now evaluate all the requests and save the atoms - for(int i=0; i<reply.length(); i++){ //NOTE: this will always be the same length as the "atoms" list - if(reply[i]!=0){ - ATOMS.insert(atoms[i], reply[i]->atom); - free(reply[i]); //done with this reply - }else{ - //Invalid atom - could not be created - qDebug() << "Could not initialize XCB atom:" << atoms[i]; - } - } //loop over reply - return (ATOMS.keys().length() == atoms.length()); - } - - WId getTransientFor(WId win){ - xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for_unchecked(QX11Info::connection(), win); - xcb_window_t trans; - if(1!= xcb_icccm_get_wm_transient_for_reply(QX11Info::connection(), cookie, &trans, NULL) ){ - return win; //error in fetching transient window ID (or none found) - }else{ - return trans; - } -} - - bool register_wm(){ - uint32_t value_list[1] = {ROOT_WIN_EVENT_MASK}; - xcb_generic_error_t *status = xcb_request_check( QX11Info::connection(), xcb_change_window_attributes_checked(QX11Info::connection(), root_window, XCB_CW_EVENT_MASK, value_list)); - if(status!=0){ return false; } - uint32_t params[] = {1}; - wm_window = xcb_generate_id(QX11Info::connection()); //need a new ID - xcb_create_window(QX11Info::connection(), root_screen->root_depth, \ - wm_window, root_window, -1, -1, 1, 1, 0, \ - XCB_WINDOW_CLASS_INPUT_OUTPUT, root_screen->root_visual, \ - XCB_CW_OVERRIDE_REDIRECT, params); - if(wm_window==0){ return false; } - //Set the _NET_SUPPORTING_WM property on the root window first - xcb_ewmh_set_supporting_wm_check(&EWMH, root_window, wm_window); - //Also set this property on the child window (pointing to itself) - xcb_ewmh_set_supporting_wm_check(&EWMH, wm_window, wm_window); - //Now also setup the root event mask on the wm_window - status = xcb_request_check( QX11Info::connection(), xcb_change_window_attributes_checked(QX11Info::connection(), wm_window, XCB_CW_EVENT_MASK, value_list)); - if(status!=0){ return false; } - return true; - } - - bool start_system_tray(){ - xcb_atom_t _NET_SYSTEM_TRAY_S = ATOMS.value( QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(QX11Info::appScreen())) ); - //Make sure that there is no other system tray running - xcb_get_selection_owner_reply_t *ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \ - xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL); - if(ownreply == 0){ - qWarning() << " - Could not get owner selection reply"; - return false; - }else if(ownreply->owner != 0){ - free(ownreply); - qWarning() << " - An alternate system tray is currently in use"; - return false; - } - free(ownreply); - //Now create the window to use (just offscreen) - tray_window = xcb_generate_id(QX11Info::connection()); //need a new ID - uint32_t params[] = {1}; - xcb_create_window(QX11Info::connection(), root_screen->root_depth, \ - tray_window, root_screen->root, -1, -1, 1, 1, 0, \ - XCB_WINDOW_CLASS_INPUT_OUTPUT, root_screen->root_visual, \ - XCB_CW_OVERRIDE_REDIRECT, params); - //Now register this widget as the system tray - xcb_set_selection_owner(QX11Info::connection(), tray_window, _NET_SYSTEM_TRAY_S, XCB_CURRENT_TIME); - //Make sure that it was registered properly - ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \ - xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL); - if(ownreply==0 || ownreply->owner != tray_window){ - if(ownreply!=0){ free(ownreply); } - qWarning() << " - Could not register the system tray"; - xcb_destroy_window(QX11Info::connection(), tray_window); - return false; - } - free(ownreply); //done with structure - //Now register the orientation of the system tray - uint32_t orient = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; - xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, tray_window, \ - ATOMS.value("_NET_SYSTEM_TRAY_ORIENTATION"), XCB_ATOM_CARDINAL, 32, 1, &orient); - - //Now set the visual ID for the system tray (same as the root window, but TrueColor) - xcb_visualtype_t *type = xcb_aux_find_visual_by_attrs(root_screen, XCB_VISUAL_CLASS_TRUE_COLOR, 32); - if(type!=0){ - xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, tray_window, \ - ATOMS.value("_NET_SYSTEM_TRAY_VISUAL"), XCB_ATOM_VISUALID, 32, 1, &type->visual_id); - }else{ - qWarning() << " - Could not set TrueColor visual for system tray"; - } - - //Finally, send out an X event letting others know that the system tray is up and running - xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = root_screen->root; - event.type = EWMH.MANAGER; //MANAGER atom - event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[1] = _NET_SYSTEM_TRAY_S; //_NET_SYSTEM_TRAY_S atom - event.data.data32[2] = tray_window; - event.data.data32[3] = 0; - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, root_screen->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - return true; - } - -}; //end private objects class - - -//inline functions for setting up the internal objects - - -// === PUBLIC === -NativeWindowSystem::NativeWindowSystem() : QObject(){ - obj = 0; - pingTimer = 0; - screenLocked = false; -} - -NativeWindowSystem::~NativeWindowSystem(){ - xcb_ewmh_connection_wipe(&(obj->EWMH)); - free(obj); -} - -//Overarching start/stop functions -bool NativeWindowSystem::start(){ - //Initialize the XCB/EWMH objects - if(obj==0){ - obj = new p_objects(); //instantiate the private objects - obj->wm_window = 0; - obj->tray_window = 0; - xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(QX11Info::connection(), &obj->EWMH); - if(!xcb_ewmh_init_atoms_replies(&obj->EWMH, cookie, NULL) ){ - qDebug() << "Error with XCB atom initializations"; - return false; - } - obj->root_screen = xcb_aux_get_screen(QX11Info::connection(), QX11Info::appScreen()); - obj->root_window = obj->root_screen->root; //simplification for later - minor duplication of memory (unsigned int) - //Initialize all the extra atoms that the EWMH object does not have - if( !obj->init_ATOMS() ){ return false; } - } //Done with private object init - bool ok = obj->register_wm(); - if(ok){ - setRoot_supportedActions(); - ok = obj->start_system_tray(); - }else{ - qWarning() << "Could not register the WM"; - } - return ok; -} - -void NativeWindowSystem::stop(){ - -} - -// === PRIVATE === -NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ - //qDebug() << "Find Window:" << id; - for(int i=0; i<NWindows.length(); i++){ - if(id==NWindows[i]->id() ){ return NWindows[i]; } - else if(id==NWindows[i]->frameId() ){ return NWindows[i]; } - //if(checkRelated && NWindows[i]->isRelatedTo(id)){ return NWindows[i]; } - //else if(!checkRelated && id==NWindows[i]->id()){ return NWindows[i]; } - } - //Check to see if this is a transient for some other window - if(checkRelated){ - //WId tid = obj->getTransientFor(id); - //if(tid!=id){ return findWindow(tid, checkRelated); } //call it recursively as needed - //qDebug() << " -- Could not find Window!"; - } - return 0; -} - -NativeWindow* NativeWindowSystem::findTrayWindow(WId id){ - for(int i=0; i<TWindows.length(); i++){ - if(TWindows[i]->isRelatedTo(id)){ return TWindows[i]; } - } - return 0; -} - -void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props){ - //Put the properties in logical groups as appropriate (some XCB calls return multiple properties) - if(props.contains(NativeWindow::Title)){ - //Try the EWMH standards first - // _NET_WM_NAME - QString name; - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ - xcb_ewmh_get_utf8_strings_reply_t data; - if( 1 == xcb_ewmh_get_wm_name_reply(&obj->EWMH, cookie, &data, NULL) ){ - name = QString::fromUtf8(data.strings, data.strings_len); - } - } - if(name.isEmpty()){ - //_NET_WM_VISIBLE_NAME - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ - xcb_ewmh_get_utf8_strings_reply_t data; - if( 1 == xcb_ewmh_get_wm_visible_name_reply(&obj->EWMH, cookie, &data, NULL) ){ - name = QString::fromUtf8(data.strings, data.strings_len); - } - } - } - if(name.isEmpty()){ - //Now try the ICCCM standard - xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_name_unchecked(QX11Info::connection(), win->id()); - xcb_icccm_get_text_property_reply_t reply; - if(1 == xcb_icccm_get_wm_name_reply(QX11Info::connection(), cookie, &reply, NULL) ){ - name = QString::fromLocal8Bit(reply.name, reply.name_len); - xcb_icccm_get_text_property_reply_wipe(&reply); - } - } - win->setProperty(NativeWindow::Title, name); - } //end TITLE property - - if(props.contains(NativeWindow::ShortTitle)){ - //Try the EWMH standards first - // _NET_WM_ICON_NAME - QString name; - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ - xcb_ewmh_get_utf8_strings_reply_t data; - if( 1 == xcb_ewmh_get_wm_icon_name_reply(&obj->EWMH, cookie, &data, NULL) ){ - name = QString::fromUtf8(data.strings, data.strings_len); - } - } - if(name.isEmpty()){ - //_NET_WM_VISIBLE_ICON_NAME - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_icon_name_unchecked(&obj->EWMH, win->id()); - if(cookie.sequence != 0){ - xcb_ewmh_get_utf8_strings_reply_t data; - if( 1 == xcb_ewmh_get_wm_visible_icon_name_reply(&obj->EWMH, cookie, &data, NULL) ){ - name = QString::fromUtf8(data.strings, data.strings_len); - } - } - } - if(name.isEmpty()){ - //Now try the ICCCM standard - xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_icon_name_unchecked(QX11Info::connection(), win->id()); - xcb_icccm_get_text_property_reply_t reply; - if(1 == xcb_icccm_get_wm_icon_name_reply(QX11Info::connection(), cookie, &reply, NULL) ){ - name = QString::fromLocal8Bit(reply.name, reply.name_len); - xcb_icccm_get_text_property_reply_wipe(&reply); - } - } - win->setProperty(NativeWindow::ShortTitle, name); - } //end SHORTTITLE property - - if(props.contains(NativeWindow::Icon)){ - //See if this is a tray icon first (different routine - entire app window is the icon) - QIcon icon; - if(win == findTrayWindow(win->id())){ - //Tray Icon Window - QPixmap pix; - //Get the current QScreen (for XCB->Qt conversion) - QList<QScreen*> scrnlist = QApplication::screens(); - //Try to grab the given window directly with Qt - for(int i=0; i<scrnlist.length() && pix.isNull(); i++){ - pix = scrnlist[i]->grabWindow(win->id()); - } - icon.addPixmap(pix); - }else{ - //Standard window - //Fetch the _NET_WM_ICON for the window and return it as a QIcon - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_unchecked(&obj->EWMH, win->id()); - xcb_ewmh_get_wm_icon_reply_t reply; - if(1 == xcb_ewmh_get_wm_icon_reply(&obj->EWMH, cookie, &reply, NULL)){ - xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply); - //Just use the first - bool done =false; - while(!done){ - //Now convert the current data into a Qt image - // - first 2 elements are width and height (removed via XCB functions) - // - data in rows from left to right and top to bottom - QImage image(iter.width, iter.height, QImage::Format_ARGB32); //initial setup - uint* dat = iter.data; - //dat+=2; //remember the first 2 element offset - for(int i=0; i<image.byteCount()/4; ++i, ++dat){ - ((uint*)image.bits())[i] = *dat; - } - icon.addPixmap(QPixmap::fromImage(image)); //layer this pixmap onto the icon - //Now see if there are any more icons available - done = (iter.rem<1); //number of icons remaining - if(!done){ xcb_ewmh_get_wm_icon_next(&iter); } //get the next icon data - } - xcb_ewmh_get_wm_icon_reply_wipe(&reply); - } - } //end type of window - win->setProperty(NativeWindow::Icon, icon); - } //end ICON property - - if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) - || props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ - //Try the ICCCM "Normal Hints" structure first (newer spec?) - xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_normal_hints_unchecked(QX11Info::connection(), win->id()); - xcb_size_hints_t reply; - bool ok = false; - if(1==xcb_icccm_get_wm_normal_hints_reply(QX11Info::connection(), cookie, &reply, NULL) ){ ok = true; } - else{ - //Could not find normal hints, try the older "size hints" instead - cookie = xcb_icccm_get_wm_size_hints_unchecked(QX11Info::connection(), win->id(), XCB_ATOM_WM_SIZE_HINTS); - if(1==xcb_icccm_get_wm_size_hints_reply(QX11Info::connection(), cookie, &reply, NULL) ){ ok = true; } - } - if(ok){ - bool initsize = win->property(NativeWindow::Size).isNull(); //initial window size - if( (reply.flags&XCB_ICCCM_SIZE_HINT_US_POSITION)==XCB_ICCCM_SIZE_HINT_US_POSITION ){ win->setProperty(NativeWindow::GlobalPos, QPoint(reply.x,reply.y)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_US_SIZE)==XCB_ICCCM_SIZE_HINT_US_SIZE ){ win->setProperty(NativeWindow::Size, QSize(reply.width, reply.height)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_POSITION)==XCB_ICCCM_SIZE_HINT_P_POSITION ){ win->setProperty(NativeWindow::GlobalPos, QPoint(reply.x,reply.y)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_SIZE)==XCB_ICCCM_SIZE_HINT_P_SIZE ){ win->setProperty(NativeWindow::Size, QSize(reply.width, reply.height)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)==XCB_ICCCM_SIZE_HINT_P_MIN_SIZE ){ win->setProperty(NativeWindow::MinSize, QSize(reply.min_width, reply.min_height)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)==XCB_ICCCM_SIZE_HINT_P_MAX_SIZE ){ win->setProperty(NativeWindow::MaxSize, QSize(reply.max_width, reply.max_height)); } - if( (reply.flags&XCB_ICCCM_SIZE_HINT_BASE_SIZE)==XCB_ICCCM_SIZE_HINT_BASE_SIZE && initsize ){ win->setProperty(NativeWindow::Size, QSize(reply.base_width, reply.base_height)); } - //if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)==XCB_ICCCM_SIZE_HINT_P_RESIZE_INC ){ hints.width_inc=reply.width_inc; hints.height_inc=reply.height_inc; } - //if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_ASPECT)==XCB_ICCCM_SIZE_HINT_P_ASPECT ){ hints.min_aspect_num=reply.min_aspect_num; hints.min_aspect_den=reply.min_aspect_den; hints.max_aspect_num=reply.max_aspect_num; hints.max_aspect_den=reply.max_aspect_den;} - //if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)==XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY ){ hints.win_gravity=reply.win_gravity; } - } - } //end of geometry properties - - if(props.contains(NativeWindow::Name)){ - //Put the app/class name here (much more static than the "Title" properties - xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class_unchecked(QX11Info::connection(), win->id()); - xcb_icccm_get_wm_class_reply_t reply; - if(1 == xcb_icccm_get_wm_class_reply(QX11Info::connection(), cookie, &reply, NULL) ){ - //Returns: "<instance name>::::<class name>" - win->setProperty(NativeWindow::Name, ( QString::fromLocal8Bit(reply.instance_name)+"::::"+QString::fromLocal8Bit(reply.class_name) )); - xcb_icccm_get_wm_class_reply_wipe(&reply); - } - } //end NAME property - - if(props.contains(NativeWindow::Workspace)){ - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop_unchecked(&obj->EWMH, win->id()); - uint32_t num = 0; - int wkspace = -1; - if(1==xcb_ewmh_get_wm_desktop_reply(&obj->EWMH, cookie, &num, NULL) ){ - if(num!=0xFFFFFFFF){ wkspace = num; } - }/*else{ - //Error in fetching property (not set?) - // - put it on the current screen - out = WM_Get_Current_Desktop(); - }*/ - win->setProperty(NativeWindow::Workspace, wkspace); - } - if(props.contains(NativeWindow::FrameExtents)){ - //Just assign default values to this - need to automate it later - //win->setProperty(NativeWindow::FrameExtents, QVariant::fromValue<QList<int> >(QList<int>() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); - } - if(props.contains(NativeWindow::RelatedWindows)){ - WId orig = win->id(); - WId tid = obj->getTransientFor(orig); - QList<WId> list; - while(tid != orig){ - list << tid; - orig = tid; - tid = obj->getTransientFor(orig); - } - win->setProperty(NativeWindow::RelatedWindows, QVariant::fromValue(list)); - } - if(props.contains(NativeWindow::Visible)){ - xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), xcb_get_window_attributes(QX11Info::connection(), win->id()) , NULL); - if(attr != 0){ - win->setProperty(NativeWindow::Visible, attr->map_state == XCB_MAP_STATE_VIEWABLE); - free(attr); - } - } - if(props.contains(NativeWindow::WinTypes)){ - QList< NativeWindow::Type> types; - xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type_unchecked(&obj->EWMH, win->id()); - xcb_ewmh_get_atoms_reply_t reply; - if(1==xcb_ewmh_get_wm_window_type_reply(&obj->EWMH, cookie, &reply, NULL) ){ - for(unsigned int i=0; i<reply.atoms_len; i++){ - if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ types << NativeWindow::T_DESKTOP; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DOCK){ types << NativeWindow::T_DOCK; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ types << NativeWindow::T_TOOLBAR; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_MENU){ types << NativeWindow::T_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY){ types << NativeWindow::T_UTILITY; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH){ types << NativeWindow::T_SPLASH; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG){ types << NativeWindow::T_DIALOG; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ types << NativeWindow::T_DROPDOWN_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ types << NativeWindow::T_POPUP_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ types << NativeWindow::T_TOOLTIP; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ types << NativeWindow::T_NOTIFICATION; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_COMBO){ types << NativeWindow::T_COMBO; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DND){ types << NativeWindow::T_DND; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL){ types << NativeWindow::T_NORMAL; } - } - } - if(types.isEmpty()){ types << NativeWindow::T_NORMAL; } - win->setProperty(NativeWindow::WinTypes, QVariant::fromValue< QList<NativeWindow::Type> >(types) ); - } -} - -void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList<QVariant> vals){ - if(props.length() == 0 || vals.length()!=props.length() || win ==0 ){ return; } - //qDebug() << "Change Window Properties:" << props << vals; - if(props.contains(NativeWindow::Title)){ - - } - if(props.contains(NativeWindow::ShortTitle)){ - - } - if(props.contains(NativeWindow::Icon)){ - - } - if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ - /*xcb_configure_window_value_list_t valList; - //valList.x = 0; //Note that this is the relative position - should always be 0,0 relative to the embed widget - //valList.y = 0; - QSize sz = win->property(NativeWindow::Size).toSize(); - if(props.contains(NativeWindow::Size)){ - sz = vals[ props.indexOf(NativeWindow::Size) ] .toSize(); - } - valList.width = sz.width(); - valList.height = sz.height(); - if(props.contains(NativeWindow::GlobalPos)){ - QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); - valList.x = pt.x(); - valList.y = pt.y(); - }else{ - valList.x = win->property(NativeWindow::GlobalPos).toPoint().x(); - valList.y = win->property(NativeWindow::GlobalPos).toPoint().y(); - } - uint16_t mask = 0; - mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - //qDebug() << "Configure window Geometry:" << sz; - xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList);*/ - } - if(props.contains(NativeWindow::Name)){ - - } - if(props.contains(NativeWindow::Workspace)){ - int num = vals[ props.indexOf(NativeWindow::Workspace) ].toInt(); - xcb_ewmh_set_wm_desktop(&obj->EWMH, win->id(), (num<0 ? 0xFFFFFFFF : qAbs(num) ) ); - } - if(props.contains(NativeWindow::RelatedWindows)){ - - } - if(props.contains(NativeWindow::Visible)){ - //qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindow::Visible) ]; - if( vals[ props.indexOf(NativeWindow::Visible) ].toBool() ){ - //qDebug() << " - Map it!"; - xcb_map_window(QX11Info::connection(), win->id()); - }else{ - //qDebug() << " - Unmap it!"; - xcb_unmap_window(QX11Info::connection(), win->id()); - } - } - if(props.contains(NativeWindow::Active)){ - //Only one window can be "Active" at a time - so only do anything if this window wants to be active - if(vals[props.indexOf(NativeWindow::Active)].toBool() ){ - //Lower the currently active window (invisible window) to the bottom of the stack - xcb_window_t cactive; - if( 1 == xcb_ewmh_get_active_window_reply( &obj->EWMH, - xcb_ewmh_get_active_window_unchecked(&obj->EWMH, QX11Info::appScreen()), - &cactive, NULL) ){ - uint32_t val = XCB_STACK_MODE_BELOW; - xcb_configure_window(QX11Info::connection(), cactive, XCB_CONFIG_WINDOW_STACK_MODE, &val); - } - - xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), win->id() ); - //Also send the active window a message to take input focus - xcb_set_input_focus(QX11Info::connection(), XCB_INPUT_FOCUS_PARENT, win->id(), XCB_CURRENT_TIME); - //Send the window a WM_TAKE_FOCUS message -/* xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = win->id(); - event.type = obj->ATOMS["WM_PROTOCOLS"]; - event.data.data32[0] = obj->ATOMS["WM_TAKE_FOCUS"]; - event.data.data32[1] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[2] = 0; - event.data.data32[3] = 0; - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, win->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - xcb_flush(QX11Info::connection()); -*/ - } - } - -} - -// === PUBLIC SLOTS === -//These are the slots which are typically only used by the desktop system itself or the NativeEventFilter -void NativeWindowSystem::RegisterVirtualRoot(WId id){ - //Convert to XCB array - xcb_window_t array[1]; - array[0] = id; - //Set the property - xcb_ewmh_set_virtual_roots(&obj->EWMH, QX11Info::appScreen(), 1, array); - //Now also enable automatic compositing for children of this window - //xcb_composite_redirect_window(QX11Info::connection(), id, XCB_COMPOSITE_REDIRECT_AUTOMATIC); - //xcb_composite_redirect_subwindows(QX11Info::connection(), id, XCB_COMPOSITE_REDIRECT_AUTOMATIC); -} - -void NativeWindowSystem::setRoot_supportedActions(){ -//NET_WM standards (ICCCM implied - no standard way to list those) - xcb_atom_t list[] = {obj->EWMH._NET_WM_NAME, - obj->EWMH._NET_WM_ICON, - obj->EWMH._NET_WM_ICON_NAME, - obj->EWMH._NET_WM_DESKTOP, - /*obj->ATOMS["_NET_WM_WINDOW_OPACITY"],*/ - /*_NET_WINDOW_TYPE (and all the various types - 15 in total*/ - obj->EWMH._NET_WM_WINDOW_TYPE, obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP, obj->EWMH._NET_WM_WINDOW_TYPE_DOCK, - obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR, obj->EWMH._NET_WM_WINDOW_TYPE_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY, - obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH, obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG, obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL, - obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU, obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP, - obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION, obj->EWMH._NET_WM_WINDOW_TYPE_COMBO, obj->EWMH._NET_WM_WINDOW_TYPE_DND, - }; - xcb_ewmh_set_supported(&obj->EWMH, QX11Info::appScreen(), 20,list); -} - -void NativeWindowSystem::setRoot_numberOfWorkspaces(QStringList names){ - if(names.isEmpty()){ names << "one"; } - //First set the overall number of workspaces - xcb_ewmh_set_number_of_desktops(&obj->EWMH, QX11Info::appScreen(), names.length()); - //Now set the names for the workspaces - //EWMH LIBRARY BROKEN - appears to be a mismatch in the function header (looking for a single char array, instead of a list of char arrays) - // Ken Moore - 6/27/17 - /* - char *array[ names.length() ]; - for(int i=0; i<names.length(); i++){array[i] = names[i].toUtf8().data(); } //Convert to an array of char arrays - xcb_ewmh_set_desktop_names(&obj->EWMH, QX11Info::appScreen(), names.length(), array); - */ -} - -void NativeWindowSystem::setRoot_currentWorkspace(int num){ - xcb_ewmh_set_current_desktop(&obj->EWMH, QX11Info::appScreen(), num); -} - -void NativeWindowSystem::setRoot_clientList(QList<WId> list, bool stackorder){ - //convert the QList into a generic array - xcb_window_t array[list.length()]; - for(int i=0; i<list.length(); i++){ array[i] = list[i]; } - if(stackorder){ - xcb_ewmh_set_client_list_stacking(&obj->EWMH, QX11Info::appScreen(), list.length(), array); - }else{ - xcb_ewmh_set_client_list(&obj->EWMH, QX11Info::appScreen(), list.length(), array); - } -} - -void NativeWindowSystem::setRoot_desktopGeometry(QRect geom){ - //This one is a combo function - // This will set the "DESKTOP_VIEWPORT" property (point) - // as well as the "DESKTOP_GEOMETRY" property (size) - //Turn the QList into xcb_ewmh_coordinates_t* - xcb_ewmh_coordinates_t array[1]; - array[0].x=geom.x(); array[0].y=geom.y(); - //Now set the property - xcb_ewmh_set_desktop_viewport(&obj->EWMH, QX11Info::appScreen(), 1, array); - xcb_ewmh_set_desktop_geometry(&obj->EWMH, QX11Info::appScreen(), geom.width(), geom.height()); -} - -void NativeWindowSystem::setRoot_desktopWorkarea(QList<QRect> list){ - //Convert to the XCB/EWMH data structures - xcb_ewmh_geometry_t array[list.length()]; - for(int i=0; i<list.length(); i++){ - array[i].x = list[i].x(); array[i].y = list[i].y(); - array[i].width = list[i].width(); array[i].height = list[i].height(); - } - //Now set the property - xcb_ewmh_set_workarea(&obj->EWMH, QX11Info::appScreen(), list.length(), array); -} - -void NativeWindowSystem::setRoot_activeWindow(WId win){ - /*xcb_ewmh_set_active_window(&obj->EWMH, QX11Info::appScreen(), win); - //Also send the active window a message to take input focus - //Send the window a WM_TAKE_FOCUS message - xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = win; - event.type = obj->ATOMS["WM_PROTOCOLS"]; - event.data.data32[0] = obj->ATOMS["WM_TAKE_FOCUS"]; - event.data.data32[1] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[2] = 0; - event.data.data32[3] = 0; - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - xcb_flush(QX11Info::connection());*/ -} - -int NativeWindowSystem::currentWorkspace(){ - xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&obj->EWMH, QX11Info::appScreen()); - uint32_t num = 0; - if(1==xcb_ewmh_get_current_desktop_reply(&obj->EWMH, cookie, &num, NULL) ){ - return num; - }else{ - return 0; - } -} - -//NativeWindowEventFilter interactions -void NativeWindowSystem::NewWindowDetected(WId id){ - //Make sure this can be managed first - if(findWindow(id, false) != 0){ findWindow(id,false)->setProperty(NativeWindow::Visible, true, true); return; } //already managed - xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(QX11Info::connection(), id); - xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), cookie, NULL); - if(attr == 0){ return; } //could not get attributes of window - if(attr->override_redirect){ free(attr); return; } //window has override redirect set (do not manage) - free(attr); - //Now go ahead and create/populate the container for this window - NativeWindow *win = new NativeWindow(id); - //Register for events from this window - registerClientEvents(win->id()); - NWindows << win; - UpdateWindowProperties(win, NativeWindow::allProperties()); - qDebug() << "New Window [& associated ID's]:" << win->id() << win->property(NativeWindow::Name).toString(); - //Now setup the connections with this window - connect(win, SIGNAL(RequestClose(WId)), this, SLOT(RequestClose(WId)) ); - connect(win, SIGNAL(RequestKill(WId)), this, SLOT(RequestKill(WId)) ); - 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<NativeWindow::Property>, QList<QVariant>)), this, SLOT(RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>)) ); - emit NewWindowAvailable(win); -} - -void NativeWindowSystem::NewTrayWindowDetected(WId id){ - //Make sure this can be managed first - if(findTrayWindow(id) != 0){ return; } //already managed - xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(QX11Info::connection(), id); - xcb_get_window_attributes_reply_t *attr = xcb_get_window_attributes_reply(QX11Info::connection(), cookie, NULL); - if(attr == 0){ return; } //could not get attributes of window - if(attr->override_redirect){ free(attr); return; } //window has override redirect set (do not manage) - free(attr); - //Register for events from this window - #define TRAY_WIN_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | \ - XCB_EVENT_MASK_BUTTON_RELEASE | \ - XCB_EVENT_MASK_POINTER_MOTION | \ - XCB_EVENT_MASK_BUTTON_MOTION | \ - XCB_EVENT_MASK_EXPOSURE | \ - XCB_EVENT_MASK_STRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \ - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \ - XCB_EVENT_MASK_ENTER_WINDOW) - - uint32_t value_list[1] = {TRAY_WIN_EVENT_MASK}; - xcb_change_window_attributes(QX11Info::connection(), id, XCB_CW_EVENT_MASK, value_list); - //Now go ahead and create/populate the container for this window - NativeWindow *win = new NativeWindow(id); - TWindows << win; - UpdateWindowProperties(win, NativeWindow::allProperties()); - emit NewTrayWindowAvailable(win); -} - -void NativeWindowSystem::WindowCloseDetected(WId id){ - NativeWindow *win = findWindow(id, false); - //qDebug() << "Got Window Closed" << id << win; - //qDebug() << "Old Window List:" << NWindows.length(); - if(win!=0){ - NWindows.removeAll(win); - //RequestReparent(id, QX11Info::appRootWindow(), QPoint(0,0)); - win->emit WindowClosed(id); - //qDebug() << "Visible Window Closed!!!"; - //win->deleteLater(); - }else{ - win = findTrayWindow(id); - if(win!=0){ - TWindows.removeAll(win); - win->emit WindowClosed(id); - win->deleteLater(); - } - } - //qDebug() << " - Now:" << NWindows.length(); -} - -void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ - //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves - NativeWindow *win = findWindow(id, prop!=NativeWindow::Visible); - if(win==0){ win = findTrayWindow(id); } - if(win!=0){ - UpdateWindowProperties(win, QList<NativeWindow::Property>() << prop); - }else if(prop != 0){ - //Could not find the window for a specific property with an undefined value - // - update this property for all the windows just in case - for(int i=0; i<NWindows.length(); i++){ - UpdateWindowProperties( NWindows[i], QList<NativeWindow::Property>() << prop); - } - } -} - -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindow::Property> props){ - //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves - NativeWindow *win = findWindow(id); - if(win==0){ win = findTrayWindow(id); } - if(win!=0){ - UpdateWindowProperties(win, props); - }else{ - //Could not find the window for a specific property with an undefined value - // - update this property for all the windows just in case - for(int i=0; i<NWindows.length(); i++){ - UpdateWindowProperties( NWindows[i], props); - } - } -} - -void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop, QVariant val){ - NativeWindow *win = findWindow(id,prop!=NativeWindow::Visible); - if(win==0){ win = findTrayWindow(id); } - if(win!=0){ - win->setProperty(prop, val); - } -} - -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindow::Property> props, QList<QVariant> vals){ - NativeWindow *win = findWindow(id); - if(win==0){ win = findTrayWindow(id); } - if(win!=0){ - for(int i=0; i<props.length() && i<vals.length(); i++){ win->setProperty(props[i], vals[i]); } - } -} - -void NativeWindowSystem::RequestPropertyChange(WId id, NativeWindow::Property prop, QVariant val){ - //This is just a simplified version of the multiple-property function - RequestPropertiesChange(id, QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); -} - -void NativeWindowSystem::RequestPropertiesChange(WId win, QList<NativeWindow::Property> props, QList<QVariant> vals){ - //Find the window object associated with this id - bool istraywin = false; //just in case we care later if it is a tray window or a regular window - NativeWindow *WIN = findWindow(win); - if(WIN==0){ istraywin = true; WIN = findTrayWindow(win); } - if(WIN==0){ return; } //invalid window ID - no longer available - //Now make any changes as needed - ChangeWindowProperties(WIN, props, vals); -} - -void NativeWindowSystem::GotPong(WId id){ - if(waitingForPong.contains(id)){ - waitingForPong.remove(id); - } - if(waitingForPong.isEmpty() && pingTimer!=0){ pingTimer->stop(); } -} - -void NativeWindowSystem::NewKeyPress(int keycode, WId win){ - emit NewInputEvent(); - if(screenLocked){ return; } - Qt::Key key = KeycodeToQt(keycode); - if(key!=Qt::Key_unknown){ emit KeyPressDetected(win, key); } -} - -void NativeWindowSystem::NewKeyRelease(int keycode, WId win){ - emit NewInputEvent(); - if(screenLocked){ return; } - Qt::Key key = KeycodeToQt(keycode); - if(key!=Qt::Key_unknown){ emit KeyReleaseDetected(win, key); } -} - -void NativeWindowSystem::NewMousePress(int buttoncode, WId win){ - emit NewInputEvent(); - if(screenLocked){ return; } - emit MousePressDetected(win, MouseToQt(buttoncode)); -} - -void NativeWindowSystem::NewMouseRelease(int buttoncode, WId win){ - emit NewInputEvent(); - if(screenLocked){ return; } - emit MouseReleaseDetected(win, MouseToQt(buttoncode)); -} - -void NativeWindowSystem::CheckDamageID(WId win){ - for(int i=0; i<NWindows.length(); i++){ - if(NWindows[i]->damageId() == win || NWindows[i]->id() == win || NWindows[i]->frameId()==win){ - NWindows[i]->emit VisualChanged(); - //qDebug() << "Got DAMAGE Event"; - return; - } - } - NativeWindow *WIN = findTrayWindow(win); - if(WIN!=0){ - UpdateWindowProperties(WIN, QList<NativeWindow::Property>() << NativeWindow::Icon); - } -} - -// === PRIVATE SLOTS === -//These are the slots which are built-in and automatically connected when a new NativeWindow is created - -void NativeWindowSystem::RequestClose(WId win){ - //Send the window a WM_DELETE_WINDOW message - xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = win; - event.type = obj->ATOMS.value("WM_PROTOCOLS"); - event.data.data32[0] = obj->ATOMS.value("WM_DELETE_WINDOW"); - event.data.data32[1] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[2] = 0; - event.data.data32[3] = 0; - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - xcb_flush(QX11Info::connection()); -} - -void NativeWindowSystem::RequestKill(WId win){ - xcb_kill_client(QX11Info::connection(), win); -} - -void NativeWindowSystem::RequestPing(WId win){ - waitingForPong.insert(win, QDateTime::currentDateTime().addSecs(5) ); - xcb_ewmh_send_wm_ping(&obj->EWMH, win, XCB_CURRENT_TIME); - if(pingTimer==0){ - pingTimer = new QTimer(this); - pingTimer->setInterval(2000); //2seconds - connect(pingTimer, SIGNAL(timeout()), this, SLOT(checkPings()) ); - } - pingTimer->start(); -} - -void NativeWindowSystem::RequestReparent(WId win, WId container, QPoint relorigin){ - NativeWindow *WIN = findWindow(win); - if(WIN==0){ return; } //could not find corresponding window structure -//Reparent the window into the container - xcb_reparent_window(QX11Info::connection(), win, container, relorigin.x(), relorigin.y()); - //xcb_map_window(QX11Info::connection(), win); - - //Now send the embed event to the app - //qDebug() << " - send _XEMBED event"; - xcb_client_message_event_t event; - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.window = win; - event.type = obj->ATOMS["_XEMBED"]; //_XEMBED - event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; - event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY - event.data.data32[2] = 0; - event.data.data32[3] = container; //WID of the container - event.data.data32[4] = 0; - - xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); - - //Now setup any redirects and return - //this->SelectInput(win, true); //Notify of structure changes - registerClientEvents(win); - //xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL); //XCB_COMPOSITE_REDIRECT_[MANUAL/AUTOMATIC]); - - //Now map the window (will be a transparent child of the container) - xcb_map_window(QX11Info::connection(), win); - xcb_map_window(QX11Info::connection(), container); - //Now create/register the damage handler - // -- XCB (Note: The XCB damage registration is completely broken at the moment - 9/15/15, Ken Moore) - // -- Retested 6/29/17 (no change) Ken Moore - //xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer - //xcb_damage_create(QX11Info::connection(), dmgID, win, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); - // -- XLib (Note: This is only used because the XCB routine above does not work - needs to be fixed upstream in XCB itself). - Damage dmgID = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles); - WIN->addDamageID( (uint) dmgID); //save this for later - //qDebug() << " - Done"; - //return ( (uint) dmgID ); -} -/* - xcb_reparent_window(QX11Info::connection(), client, parent, relorigin.x(), relorigin.y()); - - //Now ensure that we still get event for these windows - registerClientEvents(client); //make sure we re-do this after reparenting - registerClientEvents(parent); - xcb_map_window(QX11Info::connection(), parent); -}*/ diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h deleted file mode 100644 index b67ecc94..00000000 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ /dev/null @@ -1,139 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This is a Qt5/Lumina wrapper around native graphics system calls -// It is primarily designed around the creation/modification of instances of -// the "NativeWindow" class for passing information around -//=========================================== -#ifndef _LUMINA_NATIVE_WINDOW_SYSTEM_H -#define _LUMINA_NATIVE_WINDOW_SYSTEM_H - -#include "NativeWindow.h" -#include <QDateTime> -#include <QTimer> -#include <QDebug> - -class NativeWindowSystem : public QObject{ - Q_OBJECT -private: - QList<NativeWindow*> NWindows; - QList<NativeWindow*> TWindows; - - //Simplifications to find an already-created window object - NativeWindow* findWindow(WId id, bool checkRelated = true); - - NativeWindow* findTrayWindow(WId id); - - //Now define a simple private_objects class so that each implementation - // has a storage container for defining/placing private objects as needed - class p_objects; - p_objects* obj; - - //Internal timers/variables for managing pings - QTimer *pingTimer; - QHash<WId, QDateTime> waitingForPong; - void checkPings(){ - QDateTime cur = QDateTime::currentDateTime(); - QList<WId> waiting = waitingForPong.keys(); - for(int i=0; i<waiting.length(); i++){ - if(waitingForPong.value(waiting[i]) < cur){ - waitingForPong.remove(waiting[i]); //Timeout on this window - if(waitingForPong.isEmpty() && pingTimer!=0){ pingTimer->stop(); } - NativeWindow *win = findWindow(waiting[i]); - if(win==0){ win = findTrayWindow(waiting[i]); } - if(win!=0){ win->emit WindowNotResponding(waiting[i]); } - } - } - } - - // Since some properties may be easier to update in bulk - // let the native system interaction do them in whatever logical groups are best - void UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props); - void ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList<QVariant> vals); - - //Generic private variables - bool screenLocked; - -public: - //enum Property{ None, CurrentWorkspace, Workspaces, VirtualRoots, WorkAreas }; - enum MouseButton{NoButton, LeftButton, RightButton, MidButton, BackButton, ForwardButton, TaskButton, WheelUp, WheelDown, WheelLeft, WheelRight}; - - NativeWindowSystem(); - ~NativeWindowSystem(); - - //Overarching start/stop functions - bool start(); - void stop(); - - //General-purpose listing functions - QList<NativeWindow*> currentWindows(){ return NWindows; } - QList<NativeWindow*> currentTrayWindows(){ return TWindows; } - - //Small simplification functions - static Qt::Key KeycodeToQt(int keycode); - static NativeWindowSystem::MouseButton MouseToQt(int button); - -public slots: - //These are the slots which are typically only used by the desktop system itself or the NativeWindowEventFilter - - //This is called by the lock screen to keep the NWS aware of the current status - // it is **NOT** the function to call for the user to actually lock the session (that is in the screensaver/lockscreen class) - void ScreenLockChanged(bool lock){ - screenLocked = lock; - } - - //Root Window property registrations - void RegisterVirtualRoot(WId); - void setRoot_supportedActions(); - void setRoot_numberOfWorkspaces(QStringList names); - void setRoot_currentWorkspace(int); - void setRoot_clientList(QList<WId>, bool stackorder = false); - void setRoot_desktopGeometry(QRect); - void setRoot_desktopWorkarea(QList<QRect>); - void setRoot_activeWindow(WId); - - // - Workspaces - int currentWorkspace(); - //void GoToWorkspace(int); - - - //NativeWindowEventFilter interactions - void NewWindowDetected(WId); //will automatically create the new NativeWindow object - void NewTrayWindowDetected(WId); //will automatically create the new NativeWindow object - void WindowCloseDetected(WId); //will update the lists and make changes if needed - void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //will save that property/value to the right object - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>); - void RequestPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); - void GotPong(WId); - - void NewKeyPress(int keycode, WId win = 0); - void NewKeyRelease(int keycode, WId win = 0); - void NewMousePress(int buttoncode, WId win = 0); - void NewMouseRelease(int buttoncode, WId win = 0); - void CheckDamageID(WId); - -private slots: - //These are the slots which are built-in and automatically connected when a new NativeWindow is created - void RequestClose(WId); - void RequestKill(WId); - void RequestPing(WId); - void RequestReparent(WId, WId, QPoint); //client, parent, relative origin point in parent - -signals: - void NewWindowAvailable(NativeWindow*); - void NewTrayWindowAvailable(NativeWindow*); - void NewInputEvent(); //a mouse or keypress was detected (lock-state independent); - void KeyPressDetected(WId, Qt::Key); //only emitted if lockstate = false - void KeyReleaseDetected(WId, Qt::Key); //only emitted if lockstate = false - void MousePressDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false - void MouseReleaseDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false - -}; - -#endif diff --git a/src-qt5/core/libLumina/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp index efab20fe..efab20fe 100644 --- a/src-qt5/core/libLumina/RootSubWindow-animations.cpp +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp index 5040f2f9..5040f2f9 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/obsolete/RootSubWindow.h index 598298e2..598298e2 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.h diff --git a/src-qt5/core/libLumina/RootWindow-mgmt.cpp b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp index 24ea639b..24ea639b 100644 --- a/src-qt5/core/libLumina/RootWindow-mgmt.cpp +++ b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/obsolete/RootWindow.cpp index 705297be..705297be 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/obsolete/RootWindow.cpp diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/obsolete/RootWindow.h index c5cd44a0..c5cd44a0 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/obsolete/RootWindow.h diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/obsolete/RootWindow.pri index 9426b6b4..9426b6b4 100644 --- a/src-qt5/core/libLumina/RootWindow.pri +++ b/src-qt5/core/libLumina/obsolete/RootWindow.pri diff --git a/src-qt5/core/lumina-checkpass/main.c b/src-qt5/core/lumina-checkpass/main.c index e12e7c78..2f54c8e6 100644 --- a/src-qt5/core/lumina-checkpass/main.c +++ b/src-qt5/core/lumina-checkpass/main.c @@ -14,23 +14,56 @@ //=========================================== //Standard C libary #include <unistd.h> // Standard C +#include <stdlib.h> #include <stdio.h> // Usage output #include <pwd.h> // User DB information +#include <string.h> //PAM/security libraries #include <sys/types.h> #include <security/pam_appl.h> #include <security/openpam.h> +void showUsage(){ + puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such)."); + puts("Usage:"); + //puts(" lumina-checkpass <password>"); + puts(" lumina-checkpass -fd <file descriptor>"); + puts(" lumina-checkpass -f <file path>"); + puts("Returns: 0 for a valid password, 1 for invalid"); +} + int main(int argc, char** argv){ //Check the inputs - if(argc!=2){ + if(argc!=3){ //Invalid inputs - show the help text - puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such)."); - puts("Usage: lumina-checkpass <password>"); - puts("Returns: 0 for a valid password, 1 for invalid"); + showUsage(); return 1; } + char*pass = 0; + if(argc==3 && 0==strcmp(argv[1],"-fd") ){ + FILE *fp = fdopen(atoi(argv[2]), "r"); + size_t len; + if(fp!=0){ + ssize_t slen = getline(&pass, &len, fp); + if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; } + } + fclose(fp); + }else if(argc==3 && 0==strcmp(argv[1],"-f") ){ + FILE *fp = fopen(argv[2], "r"); + size_t len; + if(fp!=0){ + ssize_t slen = getline(&pass, &len, fp); + if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; } + }else{ + puts("[ERROR] Unknown option provided"); + puts("----------------"); + showUsage(); + return 1; + } + fclose(fp); + } + if(pass == 0){ puts("Could not read password!!"); return 1; } //error in reading password //Validate current user (make sure current UID matches the logged-in user, char* cUser = getlogin(); struct passwd *pwd = 0; @@ -44,7 +77,7 @@ int main(int argc, char** argv){ int ret = pam_start( "system", cUser, &pamc, &pamh); if(ret != PAM_SUCCESS){ return 1; } //could not init PAM //char* cPassword = argv[1]; - ret = pam_set_item(pamh, PAM_AUTHTOK, argv[1]); + ret = pam_set_item(pamh, PAM_AUTHTOK, pass); //Authenticate with PAM ret = pam_authenticate(pamh,0); //this can be true without verifying password if pam_self.so is used in the auth procedures (common) if( ret == PAM_SUCCESS ){ ret = pam_acct_mgmt(pamh,0); } //Check for valid, unexpired account and verify access restrictions diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index d70ff973..e1251c01 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -104,7 +104,7 @@ void LSession::setupSession(){ splash.showScreen("user"); if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} //checkUserFiles(); //adds these files to the watcher as well - + Lumina::ROOTWIN->start(); //Initialize the internal variables //DESKTOPS.clear(); @@ -116,7 +116,6 @@ void LSession::setupSession(){ if(DEBUG){ qDebug() << " - Populate App List:" << timer->elapsed();} Lumina::APPLIST->updateList(); //appmenu = new AppMenu(); - splash.showScreen("menus"); //if(DEBUG){ qDebug() << " - Init SettingsMenu:" << timer->elapsed();} //settingsmenu = new SettingsMenu(); @@ -129,15 +128,16 @@ void LSession::setupSession(){ QList<QScreen*> scrns= QApplication::screens(); for(int i=0; i<scrns.length(); i++){ qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name(); - Lumina::ROOTWIN->ChangeWallpaper(scrns[i]->name(), RootWindow::Stretch, LOS::LuminaShare()+"desktop-background.jpg"); + RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() ); } - Lumina::ROOTWIN->start(); Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two"); Lumina::NWS->setRoot_currentWorkspace(0); + if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; } - DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); + + /*DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); connect(cmenu, SIGNAL(showLeaveDialog()), this, SLOT(StartLogout()) ); - cmenu->start(); + cmenu->start();*/ //desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst); //updateDesktops(); @@ -228,7 +228,9 @@ void LSession::setupGlobalConnections(){ //Root window connections connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::NWS, SLOT(RegisterVirtualRoot(WId)) ); connect(Lumina::ROOTWIN, SIGNAL(RootResized(QRect)), Lumina::NWS, SLOT(setRoot_desktopGeometry(QRect)) ); - connect(Lumina::ROOTWIN, SIGNAL(MouseMoved()), Lumina::SS, SLOT(newInputEvent()) ); + connect(RootDesktopObject::instance(), SIGNAL(mouseMoved()), Lumina::SS, SLOT(newInputEvent()) ); + connect(RootDesktopObject::instance(), SIGNAL(startLogout()), this, SLOT(StartLogout()) ); + connect(RootDesktopObject::instance(), SIGNAL(lockScreen()), Lumina::SS, SLOT(LockScreenNow()) ); //Native Window Class connections connect(Lumina::NEF, SIGNAL(WindowCreated(WId)), Lumina::NWS, SLOT(NewWindowDetected(WId))); @@ -356,12 +358,12 @@ void LSession::launchStartupApps(){ void LSession::checkUserFiles(){ //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] - QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String + /*QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String bool changed = LDesktopUtils::checkUserFiles(OVS); if(changed){ //Save the current version of the session to the settings file (for next time) DesktopSettings::instance()->setValue(DesktopSettings::System,"DesktopVersion", this->applicationVersion()); - } + }*/ } diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE deleted file mode 100644 index aa601d5e..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE +++ /dev/null @@ -1,7 +0,0 @@ -These audio files are BSD-licensed and were created/owned by the TrueOS Project: - - Login.ogg - - Logout.ogg - -These audio files are freely available on jewelbeat.com: -"Music by JewelBeat. Download your free music and free sound effects at www.jewelbeat.com." - - low-battery.ogg (http://www.jewelbeat.com/free/free-sound-effects/musical%20effects/Tympani_2.mp3 - converted to OGG afterward) diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg Binary files differdeleted file mode 100644 index 43a07e27..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg Binary files differdeleted file mode 100644 index e63ae07f..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg Binary files differdeleted file mode 100644 index d129a2b3..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop b/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop deleted file mode 100644 index 7d87f93a..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop +++ /dev/null @@ -1,34 +0,0 @@ -[Desktop Entry] -Exec=start-lumina-desktop -TryExec=start-lumina-desktop -Icon=Lumina-DE -Type=Application -Name=Lumina -Name[de]=Lumina -Name[en_GB]=Lumina -Name[en_ZA]=Lumina -Name[et]=Lumina -Name[fr]=Lumina -Name[fr_CA]=Lumina -Name[hi]=ल्यूमिना -Name[ja]=Lumina -Name[mt]=Lumina -Name[pl]=Lumina -Name[pt_BR]=Lumina -Name[ru]=Lumina -Name[uk]=Lumina -Name[vi]=Lumina -Comment=A Lightweight Desktop for FreeBSD -Comment[de]=Eine leichtgewichtige Arbeitsplatzumgebung für FreeBSD -Comment[en_GB]=A Lightweight Desktop for FreeBSD -Comment[en_ZA]=A Lightweight Desktop for FreeBSD -Comment[et]=Minimalistlik töölauakeskkond FreeBSD-le -Comment[fr]=Un environnement bureau léger pour FreeBSD -Comment[fr_CA]=Un environnement bureau léger pour FreeBSD -Comment[hi]=एक हल्का डेस्कटॉप फ्री बी.एस.डी के लिए -Comment[ja]=FreeBSD の為に作られた軽快なデスクトップ環境 -Comment[mt]=A Desktop irqiq għal FreeBSD -Comment[pl]=Lekkie Środowisko graficzne dla FreeBSD -Comment[pt_BR]=Um ambiente de trabalho leve para FreeBSD -Comment[uk]=Легковісне оточення стільниці для FreeBSD -Comment[vi]=Một máy tính để bàn nhẹ cho FreeBSD diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json new file mode 100644 index 00000000..c09de308 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json @@ -0,0 +1,26 @@ +{ + "name" : { + "default" : "Fireflies" + }, + "description" : { + "default" : "Dancing balls of light on the screen" + }, + "author" : { + "name" : "Ken Moore", + "email" : "ken@ixsystems.com", + "website" : "https://github.com/beanpole135", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171010", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Fireflies.qml", + "additional_files" : ["qml_scripts/Firefly.qml"] + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md new file mode 100644 index 00000000..d9093b44 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md @@ -0,0 +1,79 @@ +## Screensaver Format +The screensaver system for the Lumina desktop allows for the creation and use of scripts written in the QML language, with a number of screensavers and other examples installed out-of-box. There are only a couple warnings/caveats to consider when developing a new screensaver: + +1. The root object in your QML script will be automatically sized to fit the screen as needed. Avoid trying to hard-code specific screen dimensions within your script as it will not work properly. +2. A JSON manifest file must be created (format listed below) and placed into one of the screensaver plugin directories for it to be recognized as a valid screensaver by the desktop. + + +### JSON Manifest +The manifest file contains all the information needed to actually validate/launch the screensaver, as well as additional information about the author and/or the screensaver itself. + +Example JSON manifest file (sample.json): +``` +{ + "name" : { + "default" : "sample", + "en_US" : "US English localization of the name", + "en" : "Generic english localization of the name" + }, + + "description" : { + "default" : "sample screensaver", + "en_US" : "US English Localization of the description" + }, + + "author" : { + "name" : "Me", + "email" : "Me@myself.net", + "website" : "http://mywebsite.net", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171010", + "date_updated" : "20171011", + "version" : "1.0" + }, + + "qml" : { + "exec" : "absolute/or/relative/path/to/script.qml", + "additional_files" : ["file/which/must/exist.png"], + "qt_min_version" : "5.0", + "qt_max_version" : "6.0" + } +} +``` + +Details of the individual items in the manifest: +* NOTE: for locale codes, both long and short version are acceptable: + Example 1: If the current locale is "en_GB", but the JSON manifest lists translations for "en_US" and "en", then the "en" translation will be used. + Example 2: If the current locale is "en_GB", but neither "en_GB" nor "en" translations exist, then the "default" version will be used. + +* **name** : (required) This is the official name of the screensaver to show to users + * *default* : (required) Non-translated name of the screensaver + * *[locale]* : (optional) Translated name for specific [locale] +* **description** : (required) This is a short description of the screensaver to show to users + * *default* : (required) Non-translated description of the screensaver + * *[locale]* : (optional) Translated description for specific [locale] +* **author** : (all optional) Additional information about the author(s) of the screensaver + * *name* : Name of the author + * *email* : Email to contact the author (useful for licensing questions and such) + * *website* : Personal website for the author (github/facebook/twitter profile, etc) + * *company* : Company for which the author is creating this screensaver + * *company_website* : Website for the company +* **meta** : (all optional) Additional information about the screensaver itself + * *license* : License the screensaver is released under + * *license_url* : Website which contains the full text of the license + * *copyright* : Copyright notice for this screensaver + * *date_created* : (yyyyMMdd) Date the screensaver was initially created + * *date_updated* : (yyyyMMdd) Date the screensaver was last updated + * *version* : Current version of the screensaver (typically updated every time "date_updated" is changed) +* **qml** : (required) Information about launching the screensaver and checking validity + * *exec* : (required) Absolute or relative path to the QML script (relative to the directory which contains the JSON manifest) + * *additional_files* : (optional) Array of paths for other files/scripts which must exist for the screensaver to work properly. + * *qt_min_version* : (optional) Minimum version of the Qt libraries that this screensaver supports + * *qt_max_version* : (optional) Maximum version of the Qt libraries that this screensaver supports diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json new file mode 100644 index 00000000..2fa6e6da --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json @@ -0,0 +1,25 @@ +{ + "name" : { + "default" : "Video" + }, + "description" : { + "default" : "Play a single video or a list of videos in a loop" + }, + "author" : { + "name" : "Zackary Welch", + "email" : "zwelch@ixsystems.com", + "website" : "https://github.com/ZackaryWelch", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171025", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Video.qml" + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json new file mode 100644 index 00000000..888df01f --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json @@ -0,0 +1,25 @@ +{ + "name" : { + "default" : "Warp" + }, + "description" : { + "default" : "Warp trail through the stars" + }, + "author" : { + "name" : "Ken Moore", + "email" : "ken@ixsystems.com", + "website" : "https://github.com/beanpole135", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171012", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Warp.qml" + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml new file mode 100644 index 00000000..d8dcc1ed --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 +import QtGraphicalEffects 1.0 +import "." as QML + +Rectangle { + id : canvas + anchors.fill: parent + color: "black" + + Repeater { + model: Math.round(Math.random()*canvas.width/10)+100 + QML.Firefly { + parent: canvas + x: Math.round(Math.random()*canvas.width) + y: Math.round(Math.random()*canvas.height) + } + } //end of Repeater + +} //end of canvas rectangle diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml new file mode 100644 index 00000000..7b65d8ec --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml @@ -0,0 +1,63 @@ +import QtQuick 2.0 +import QtQuick.Window 2.2 +import QtGraphicalEffects 1.0 + +Item { + + RectangularGlow { + anchors.fill: fly + glowRadius: Math.round(fly.radius /2) + spread: 0.5 + color: Qt.rgba(1,1,1,0.3) + cornerRadius: fly.radius + glowRadius + } + + Rectangle { + id: fly + width: Math.round(Math.random()*canvas.width/200)+2 + height: width + x: parent.x + y: parent.y + color: Qt.rgba(Math.random(),Math.random(),0,0.5) + radius: Math.floor(width/2) + property int jitterX: Math.round(Math.random()*100)+10 + property int jitterY: Math.round(Math.random()*100)+10 + + Behavior on color { + ColorAnimation { + duration: 500 + } + } + Behavior on x { + SmoothedAnimation { + velocity: 10+Math.random()*canvas.width/100 + } + } + Behavior on y { + SmoothedAnimation { + velocity: 10+Math.random()*canvas.height/100 + } + } + + } + + + + Timer { + interval: 5 + repeat: true + running: true + property bool starting: true + onTriggered: { + if(starting){ interval = Math.round(Math.random()*1000)+500; starting = false; } + if ( (fly.x+fly.jitterX)>parent.width || (fly.x+fly.jitterX)<0 ){ fly.jitterX = 0-fly.jitterX } + fly.x = fly.x+fly.jitterX + if( (fly.y+fly.jitterY)>parent.height || (fly.y+fly.jitterY)<0 ){ fly.jitterY = 0-fly.jitterY } + fly.y = fly.y+fly.jitterY + fly.jitterX = (Math.round(Math.random())*2 - 1) *fly.jitterX + fly.jitterY = (Math.round(Math.random())*2 - 1) *fly.jitterY + fly.color = Qt.rgba(Math.random(),Math.random(),Math.random(),0.5) + + } + } //end of timer +} //end of item diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml new file mode 100644 index 00000000..d5245c9b --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml @@ -0,0 +1,106 @@ +import QtQuick 2.7 +import QtGraphicalEffects 1.0 + +Rectangle { + id : canvas + anchors.fill: parent + width: 800 + height: 600 + color: "black" + + //Between 5 and 15 planets, read from settings + property var planets: Math.round(( Math.random() * 10 ) + 5 ) + + //Create planets + Repeater { + model: planets + + Rectangle { + id : index + parent: canvas + + //Place the planet randomly on the canvas, but not too close to the edge + x: Math.round(Math.random()*canvas.width) + + //Check to make sure the planets are not too close to the sun (outside a 50px radius) + //while( Math.round(Math.random()*canvas.width) < (width/2 + 50) or Math.round(Math.random()*canvas.width) > (width/2 - 50)) + + y: Math.round(Math.random()*canvas.height) + + + //Create the orbit animation + + //Planet size between 14 and 32 pixels + width: Math.round(1.75 * (((Math.random() * 10) + 8 ))) + height: width + + //Make each rectangle look circular + radius: width / 2 + + //Give each planet a random color, semi-transparent + color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.5) + } + } + + //Create the star + Rectangle{ + id: star + parent: canvas + + //Centers in star in the center of the canvas + x: Math.round(canvas.width / 2) + y: Math.round(canvas.height / 2) + + width: 60 + height: width + + //Create the wobble animation + SequentialAnimation on height { + loops: Animation.Infinite + PropertyAnimation { duration: 2000; to: 90 } + PropertyAnimation { duration: 2000; to: 60 } + } + + SequentialAnimation on width { + loops: Animation.Infinite + PropertyAnimation { duration: 2000; to: 90 } + PropertyAnimation { duration: 2000; to: 60 } + } + + //border.width: 4 + //border.color: "blue" + color: "black" + radius: width / 2 + + //Creates a radial gradient to make the star look cool + RadialGradient { + anchors.fill: parent + gradient: Gradient { + GradientStop { position:0 ;color: Qt.rgba(0,0,0,0)} + GradientStop { position:0.18 ;color: Qt.rgba(0,0,0,0)} + GradientStop { position:0.2 ;color: Qt.rgba(0.32,0.47,0.30,0.13)} + GradientStop { position:0.3 ;color: Qt.rgba(0.62,0.92,0.58,0.25)} + GradientStop { position:0.4 ;color: Qt.rgba(1.00,0.93,0.59,0.51)} + GradientStop { position:0.5 ;color: Qt.rgba(0,0,0,0)} + } + } + + } + + /*Motion timer + Timer { + interval: 1 + repeat: true + running: true + property bool starting: true + + onTriggered: { + if(starting) { interval = 3010; starting = false; } + + } + }*/ + + Component.onCompleted: { + //console.log(Math.random()) + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml new file mode 100644 index 00000000..e7d0626d --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 +import QtMultimedia 5.7 +import QtQuick.Window 2.2 +import Qt.labs.folderlistmodel 2.1 + +Rectangle { + //width: Screen.width + //height: Screen.height + width: 800 + height: 600 + color: "black" + + FolderListModel { + id: folderModel + folder: "/usr/local/videos" + } + + Repeater { + model: folderModel + Component { + Item { + Component.onCompleted: { playlist.addItem(fileURL) } + } + } + } + + Playlist { + id: playlist + playbackMode: Playlist.Random + PlaylistItem { source: "/" } + onError: { console.log("ERROR") } + } + + MediaPlayer { + id: player + autoPlay: true + playlist: playlist + } + + VideoOutput { + id: videoOutput + source: player + anchors.fill: parent + } + + Component.onCompleted: { + playlist.shuffle() + console.log(playlist.itemCount) + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml new file mode 100644 index 00000000..1cf9bc37 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml @@ -0,0 +1,64 @@ +import QtQuick 2.0 +import QtGraphicalEffects 1.0 + +Rectangle { + id : canvas + anchors.fill: parent + color: "black" + + function getStarColor(num){ + if(num < 1) { return "white" } + if(num < 2) { return "mistyrose" } + return "lightblue" + } + + // CREATE STARFIELD + Repeater { + model: Math.round(Math.random()*canvas.width/10)+500 + Rectangle { + parent: canvas + x: Math.round(Math.random()*canvas.width) + y: Math.round(Math.random()*canvas.height) + width: Math.round(Math.random()*3)+3 + height: width + radius: width/2 + color: getStarColor( (index%3) ) + + } + } //end of Repeater + + // NOW CREATE THE WARP EFFECT + ZoomBlur { + id: blur + anchors.fill: canvas + source: canvas + samples: 24 + length: canvas.width / 20 + horizontalOffset: 0 + verticalOffset: 0 + + Behavior on horizontalOffset{ + NumberAnimation{ + duration: 3000 + } + } + Behavior on verticalOffset{ + NumberAnimation{ + duration: 3000 + } + } + } //end of zoom blur + + Timer { + interval: 5 + repeat: true + running: true + property bool starting: true + onTriggered: { + if(starting){ interval = 3010; starting = false; } + blur.horizontalOffset = (Math.random()*canvas.width/4) - (canvas.width/8) + blur.verticalOffset = (Math.random()*canvas.height/4) - (canvas.height/8) + } + } //end of timer + +} //end of canvas rectangle diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg Binary files differdeleted file mode 100644 index 481ca438..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg Binary files differdeleted file mode 100644 index 9da67596..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg Binary files differdeleted file mode 100644 index cba03cee..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg Binary files differdeleted file mode 100644 index 80b0d3e3..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg Binary files differdeleted file mode 100644 index 4f753ed5..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg Binary files differdeleted file mode 100644 index c214cd78..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg Binary files differdeleted file mode 100644 index e4c3d7a8..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg Binary files differdeleted file mode 100644 index a092f636..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index 184f5b8d..91604362 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -19,6 +19,7 @@ #include <QMouseEvent> #include <QAction> #include <QPoint> +#include <QTemporaryFile> #include <QFile> #include <QDir> #include <QString> @@ -53,7 +54,14 @@ #include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> +#include <QQuickView> +#include <QQmlContext> +#include <QQmlEngine> +#include <QQuickImageProvider> +// C++ Backend classes for QML interface +#include <RootDesktopObject.h> +#include <ScreenObject.h> // libLumina includes #include <LuminaX11.h> @@ -64,7 +72,6 @@ #include <LDesktopUtils.h> #include <LuminaSingleApplication.h> #include <DesktopSettings.h> -#include <RootWindow.h> #include <ExternalProcess.h> #include <NativeWindow.h> #include <NativeWindowSystem.h> @@ -72,8 +79,6 @@ #include <XDGMime.h> #include <LIconCache.h> -// Standard C includes -#include <unistd.h> //Setup any global defines (no classes or global objects: use "global-objects.h" for that) diff --git a/src-qt5/core/lumina-desktop-unified/global-objects.h b/src-qt5/core/lumina-desktop-unified/global-objects.h index 0c990dc6..c204587f 100644 --- a/src-qt5/core/lumina-desktop-unified/global-objects.h +++ b/src-qt5/core/lumina-desktop-unified/global-objects.h @@ -25,8 +25,12 @@ #include "src-screensaver/LScreenSaver.h" //#include "src-WM/LWindowManager.h" +#include <RootWindow.h> #include "LSession.h" +// Standard C includes +#include <unistd.h> + //Any special defines for settings/testing #define ANIMTIME 80 //animation time in milliseconds diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index e8cf2f28..21e46b22 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -1,26 +1,30 @@ include($${PWD}/../../OS-detect.pri) -QT += core gui network -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia multimediawidgets concurrent svg +lessThan(QT_MAJOR_VERSION, 5) { + message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") + exit +} +lessThan(QT_MINOR_VERSION, 4){ + message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") + exit +} +QT *= core gui network widgets x11extras multimedia multimediawidgets concurrent svg quick qml TARGET = lumina-desktop-unified target.path = $${L_BINDIR} #include all the special classes from the Lumina tree -include(../libLumina/ResizeMenu.pri) include(../libLumina/LDesktopUtils.pri) #includes LUtils and LOS include(../libLumina/LuminaXDG.pri) -#include(../libLumina/LuminaX11.pri) include(../libLumina/LuminaSingleApplication.pri) -include(../libLumina/LuminaThemes.pri) include(../libLumina/DesktopSettings.pri) -include(../libLumina/RootWindow.pri) include(../libLumina/ExternalProcess.pri) -include(../libLumina/NativeWindow.pri) +include(../../src-cpp/NativeWindow.pri) include(../libLumina/XDGMime.pri) -include(../libLumina/LIconCache.pri) + +include(../../src-cpp/plugins-screensaver.pri) #include all the main individual source groups include(src-screensaver/screensaver.pri) @@ -36,8 +40,7 @@ SOURCES += main.cpp \ HEADERS += global-includes.h \ global-objects.h \ LSession.h \ - BootSplash.h \ - JsonMenu.h + BootSplash.h FORMS += BootSplash.ui @@ -54,6 +57,9 @@ desktop.files = lumina-desktop.desktop defaults.path = $${L_SHAREDIR}/lumina-desktop defaults.files = defaults/* +extrafiles.path = $${L_SHAREDIR}/lumina-desktop +extrafiles.files = extrafiles/* + TRANSLATIONS = i18n/lumina-desktop_af.ts \ i18n/lumina-desktop_ar.ts \ i18n/lumina-desktop_az.ts \ @@ -120,7 +126,7 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \ dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ -INSTALLS += target desktop defaults +INSTALLS += target desktop defaults extrafiles WITH_I18N{ INSTALLS += dotrans diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp new file mode 100644 index 00000000..0cfa4e6b --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp @@ -0,0 +1,44 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootWindow.h" + +RootWindow::RootWindow() : QObject(){ + root_win = QWindow::fromWinId( QX11Info::appRootWindow() ); // + root_view = new QQuickView(root_win); //make it a child of the root window + root_obj = RootDesktopObject::instance(); + syncRootSize(); + connect(root_win, SIGNAL(widthChanged(int)), this, SLOT(syncRootSize()) ); + connect(root_win, SIGNAL(heightChanged(int)),this, SLOT(syncRootSize()) ); + //Now setup the QQuickView + root_view->setResizeMode(QQuickView::SizeRootObjectToView); + root_view->engine()->rootContext()->setContextProperty("RootObject", root_obj); + RootDesktopObject::RegisterType(); //make sure object classes are registered with the QML subsystems +} + +RootWindow::~RootWindow(){ + root_view->deleteLater(); + root_obj->deleteLater(); +} + +void RootWindow::start(){ + root_view->setSource(QUrl("qrc:///qml/RootDesktop.qml")); + root_win->show(); + root_view->show(); +} + +void RootWindow::syncRootSize(){ + //qDebug() << "Sync Root Size:" << root_win->width() << root_win->height() << root_view->geometry(); + QList<QScreen*> screens = QApplication::screens(); + QRect unif; + for(int i=0; i<screens.length(); i++){ unif = unif.united(screens[i]->geometry()); } + if(unif.width() != root_view->width() || unif.height() != root_view->height()){ + root_view->setGeometry(0, 0, unif.width(), unif.height() ); + emit RootResized(root_view->geometry()); + } + root_obj->updateScreens(); + //qDebug() << " - after:" << root_view->geometry(); +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h new file mode 100644 index 00000000..ba489465 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h @@ -0,0 +1,34 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_ROOT_WINDOW_H +#define _LUMINA_DESKTOP_ROOT_WINDOW_H +#include <global-includes.h> + +class RootWindow : public QObject{ + Q_OBJECT +private: + QWindow *root_win; + QQuickView *root_view; + RootDesktopObject *root_obj; + +public: + RootWindow(); + ~RootWindow(); + + void start(); + +public slots: + void syncRootSize(); + +signals: + void startLogout(); + void RegisterVirtualRoot(WId); + void RootResized(QRect); + void MouseMoved(); +}; + +#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 index 75aef8a6..e4c4faeb 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri @@ -1,6 +1,11 @@ -SOURCES *= $${PWD}/ContextMenu.cpp +QT *= gui widgets qml quick -HEADERS *= $${PWD}/ContextMenu.h +SOURCES *= $${PWD}/RootWindow.cpp + +HEADERS *= $${PWD}/RootWindow.h #update the includepath so we can just #include as needed without paths -INCLUDEPATH *= ${PWD} +INCLUDEPATH *= $${PWD} + +include($${PWD}/src-cpp/src-cpp.pri) +include($${PWD}/src-qml/src-qml.pri) 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 new file mode 100644 index 00000000..9842712e --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -0,0 +1,77 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootDesktopObject.h" +#include <QQmlEngine> +#include <QApplication> +#include <QScreen> + +#include <QDebug> + +// === PUBLIC === +RootDesktopObject::RootDesktopObject(QObject *parent) : QObject(parent){ + updateScreens(); //make sure the internal list is updated right away +} + +RootDesktopObject::~RootDesktopObject(){ + +} + +void RootDesktopObject::RegisterType(){ + qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject"); + //Also register any types that are needed by this class + ScreenObject::RegisterType(); +} + +RootDesktopObject* RootDesktopObject::instance(){ + static RootDesktopObject* r_obj = new RootDesktopObject(); + return r_obj; +} + +//QML Read Functions +QList<ScreenObject*> RootDesktopObject::screens(){ + return s_objects; +} + +void RootDesktopObject::logout(){ + emit startLogout(); +} + +void RootDesktopObject::lockscreen(){ + emit lockScreen(); +} + +void RootDesktopObject::mousePositionChanged(){ + emit mouseMoved(); +} + +// === PUBLIC SLOTS === +void RootDesktopObject::updateScreens(){ + QList<QScreen*> scrns = QApplication::screens(); + QList<ScreenObject*> tmp; //copy of the internal array initially + for(int i=0; i<scrns.length(); i++){ + bool found = false; + 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); } + } + //Delete any leftover objects + for(int i=0; i<s_objects.length(); i++){ s_objects[i]->deleteLater(); } + s_objects = tmp; + emit screensChanged(); + for(int i=0; i<s_objects.length(); i++){ + s_objects[i]->emit geomChanged(); + } +} + +void RootDesktopObject::ChangeWallpaper(QString screen, QString value){ + for(int i=0; i<s_objects.length(); i++){ + if(s_objects[i]->name()==screen){ s_objects[i]->setBackground(value); break; } + } +} + +// === PRIVATE === 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 new file mode 100644 index 00000000..dd7c7ab3 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -0,0 +1,54 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base C++ object that is used to pass information to the QML "RootDesktop" object +//=========================================== +#ifndef _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H +#define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H +#include <QObject> +#include <QList> + +#include "ScreenObject.h" + +class RootDesktopObject : public QObject{ + Q_OBJECT + //Define all the QML Properties here (interface between QML and the C++ methods below) + Q_PROPERTY( QList<ScreenObject*> screens READ screens NOTIFY screensChanged) + +public: + //main contructor/destructor + RootDesktopObject(QObject *parent = 0); + ~RootDesktopObject(); + + static void RegisterType(); + + //primary interface to fetch the current instance of the class (so only one is running at any given time) + static RootDesktopObject* instance(); + + //QML Read Functions + QList<ScreenObject*> screens(); + + //QML Access Functions + Q_INVOKABLE void logout(); + Q_INVOKABLE void lockscreen(); + Q_INVOKABLE void mousePositionChanged(); +private: + QList<ScreenObject*> s_objects; + +public slots: + void updateScreens(); //rescan/update screen objects + void ChangeWallpaper(QString screen, QString); + +private slots: + +signals: + void screensChanged(); + void startLogout(); + void mouseMoved(); + void lockScreen(); + +}; +#endif 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 new file mode 100644 index 00000000..4c1d6189 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -0,0 +1,31 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "ScreenObject.h" +#include <QQmlEngine> +#include <QDebug> + +ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){ + bg_screen = scrn; +} + +void ScreenObject::RegisterType(){ + qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject"); +} + +QString ScreenObject::name(){ return bg_screen->name(); } +QString ScreenObject::background(){ qDebug() << "Got Background:" << bg_screen->name() << bg << bg_screen->geometry(); return bg; } +int ScreenObject::x(){ return bg_screen->geometry().x(); } +int ScreenObject::y(){ return bg_screen->geometry().y(); } +int ScreenObject::width(){ return bg_screen->geometry().width(); } +int ScreenObject::height(){ return bg_screen->geometry().height(); } + +void ScreenObject::setBackground(QString fileOrColor){ + if(bg!=fileOrColor){ + bg = fileOrColor; + emit backgroundChanged(); + } +} 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 new file mode 100644 index 00000000..8076f1ae --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h @@ -0,0 +1,48 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base C++ object that is used to pass Screen/Wallpaper info to the QML classes +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H +#define _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H +#include <QObject> +#include <QString> +#include <QScreen> + +class ScreenObject : public QObject { + Q_OBJECT + Q_PROPERTY( QString name READ name ) + Q_PROPERTY( QString background READ background NOTIFY backgroundChanged) + Q_PROPERTY( int x READ x NOTIFY geomChanged) + Q_PROPERTY( int y READ y NOTIFY geomChanged) + Q_PROPERTY( int width READ width NOTIFY geomChanged) + Q_PROPERTY( int height READ height NOTIFY geomChanged) + +private: + QScreen *bg_screen; + QString bg; + +public: + ScreenObject(QScreen *scrn = 0, QObject *parent = 0); + + static void RegisterType(); + + Q_INVOKABLE QString name(); + Q_INVOKABLE QString background(); + Q_INVOKABLE int x(); + Q_INVOKABLE int y(); + Q_INVOKABLE int width(); + Q_INVOKABLE int height(); + +public slots: + void setBackground(QString fileOrColor); + +signals: + void backgroundChanged(); + void geomChanged(); +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri new file mode 100644 index 00000000..33b699da --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri @@ -0,0 +1,8 @@ +SOURCES *= $${PWD}/RootDesktopObject.cpp \ + $${PWD}/ScreenObject.cpp + +HEADERS *= $${PWD}/RootDesktopObject.h \ + $${PWD}/ScreenObject.h + +INCLUDEPATH *= $${PWD} + diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml new file mode 100644 index 00000000..e5bac0b5 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml @@ -0,0 +1,36 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import Lumina.Backend.RootDesktopObject 2.0 + +Menu { + id: contextMenu + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + MenuItem { + text: "Lock Screen" + onTriggered: { + RootObject.lockscreen() + } + } + + MenuItem { + text: "Logout" + //iconName: "system-log-out" + indicator: Image{ + asynchronous: true + //autoTransform: true + //source: "image://theme/system-logout" + source: "file:///usr/local/share/icons/material-design-light/scalable/actions/system-log-out.svg" + } + onTriggered: { + RootObject.logout() + } + } + } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml new file mode 100644 index 00000000..a1a9164f --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml @@ -0,0 +1,57 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base QML script the launches/controls the desktop interface itself +//=========================================== +// NOTE: This needs to be paired/used with the corresponding C++ class: RootDesktopObject +// Which should be added as the "RootObject" context property to the QML engine +//------------------ +// Example Code: +// RootDesktopObject *rootobj = new RootDesktopObject(); +// QQuickView *root = new QQuickView(); +// root->setResizeMode(QQuickView::SizeRootObjectToView); +// root->engine()->rootContext()->setContextProperty("RootObject", rootobj); +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import "." as QML + +import Lumina.Backend.RootDesktopObject 2.0 +import Lumina.Backend.ScreenObject 2.0 + +Rectangle { + id: rootCanvas + color: "black" + + //Setup the right-click context menu + MouseArea { + anchors.fill: rootCanvas + acceptedButtons: Qt.RightButton + onClicked: { + contextMenu.x = mouseX + contextMenu.y = mouseY + contextMenu.open() + } + onPositionChanged: { + RootObject.mousePositionChanged() + } + } + + //Create the context menu itself + QML.ContextMenu { id: contextMenu } + + //Setup the wallpapers + Repeater{ + model: RootObject.screens + QML.WallpaperImage{ + //console.log( modelData.name() ) + object: modelData + z: 0+index + } + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml new file mode 100644 index 00000000..4d39b0b8 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml @@ -0,0 +1,25 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import Lumina.Backend.ScreenObject 2.0 + +AnimatedImage { + //C++ backend object + property ScreenObject object + + //Normal geometries/placements + asynchronous: true + clip: true + source: object.background + x: object.x + y: object.y + width: object.width + height: object.height + } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri new file mode 100644 index 00000000..99905253 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri @@ -0,0 +1,7 @@ +#Show the QML files to lupdate for translation purposes - not for the actual build +lupdate_only{ + SOURCES *= $${PWD}/RootDesktop.qml \ + $${PWD}/ContextMenu.qml +} + +RESOURCES *= $${PWD}/src-qml.qrc diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc new file mode 100644 index 00000000..ebdcc606 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="qml"> + <file>RootDesktop.qml</file> + <file>ContextMenu.qml</file> + <file>WallpaperImage.qml</file> + </qresource> +</RCC> diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp index 0ff70142..b791ffd2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp @@ -77,7 +77,18 @@ void LLockScreen::TryUnlock(){ this->setEnabled(false); QString pass = ui->line_password->text(); ui->line_password->clear(); - bool ok = (LUtils::runCmd("lumina-checkpass", QStringList() << pass) == 0); + //Create a temporary file for the password, then pass that file descriptor to lumina-checkpass + QTemporaryFile *TF = new QTemporaryFile(".XXXXXXXXXX"); + TF->setAutoRemove(true); + bool ok = false; + if( TF->open() ){ + QTextStream in(TF); + in << pass; + in.flush(); //make sure we push it to the file **right now** since we need to keep the file open + ok = (LUtils::runCmd("lumina-checkpass", QStringList() << "-f" << TF->fileName() ) == 0); + TF->close(); + } + delete TF; if(ok){ emit ScreenUnlocked(); this->setEnabled(true); diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp index a6d5be60..122307b3 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp @@ -12,19 +12,19 @@ // ======== // PUBLIC // ======== -SSBaseWidget::SSBaseWidget(QWidget *parent) : QWidget(parent){ +SSBaseWidget::SSBaseWidget(QWidget *parent) : QQuickView(parent->windowHandle()){ this->setObjectName("LuminaBaseSSWidget"); - ANIM = 0; - this->setMouseTracking(true); + this->setResizeMode(QQuickView::SizeRootObjectToView); + this->setColor(QColor("black")); //default color for the view + this->setCursor(Qt::BlankCursor); plugType="none"; restartTimer = new QTimer(this); - restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 60).toInt() * 1000); + restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 120).toInt() * 1000); restartTimer->setSingleShot(true); connect(restartTimer, SIGNAL(timeout()), this, SLOT(startPainting()) ); } SSBaseWidget::~SSBaseWidget(){ - if(ANIM!=0){ this->stopPainting(); } } void SSBaseWidget::setPlugin(QString plug){ @@ -35,54 +35,27 @@ void SSBaseWidget::setPlugin(QString plug){ // PUBLIC SLOTS // ============= void SSBaseWidget::startPainting(){ - cplug = plugType; //free up any old animation instance - if(ANIM!=0){ - stopPainting(); - } + stopPainting(); //If a random plugin - grab one of the known plugins - if(cplug=="random"){ - QStringList valid = BaseAnimGroup::KnownAnimations(); - valid.removeAll("none"); //they want a screensaver - remove the "none" option from the valid list - if(valid.isEmpty()){ cplug = "none"; } //no known plugins - else{ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin - } - if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug; } - //Now list all the various plugins and start them appropriately - QString style; - if(cplug=="none"){ - style = "background: black;"; //show the underlying black parent widget - }else{ - style = "background: black;"; + if(plugType=="random"){ + QList<SSPlugin> valid = SSPluginSystem::findAllPlugins(); + if(!valid.isEmpty()){ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin + }else if(plugType!="none"){ + cplug = SSPluginSystem::findPlugin(plugType); } - this->setStyleSheet("QWidget#LuminaBaseSSWidget{ "+style+"}"); - this->repaint(); - //If not a stylesheet-based plugin - set it here - if(cplug!="none"){ - ANIM = BaseAnimGroup::NewAnimation(cplug, this); - connect(ANIM, SIGNAL(finished()), this, SLOT(startPainting()) ); //repeat the plugin as needed - ANIM->LoadAnimations(); + if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug.scriptURL() << cplug.isValid(); } + if(cplug.isValid()){ + this->setSource( cplug.scriptURL() ); + if(plugType=="random"){ restartTimer->start(); } } - //Now start the animation(s) - if(ANIM!=0){ - if(ANIM->animationCount()>0){ - if(DEBUG){ qDebug() << " - Starting SS Plugin:" << cplug << ANIM->animationCount() << ANIM->duration() << ANIM->loopCount(); } - ANIM->start(); - } - } - restartTimer->start(); + } void SSBaseWidget::stopPainting(){ - if(ANIM!=0){ - if(DEBUG){ qDebug() << "Stopping Animation!!"; } - ANIM->stop(); - //ANIM->clear(); - ANIM->deleteLater(); - ANIM = 0; - //Delete any child widgets of the canvas - QList<QWidget*> widgets = this->findChildren<QWidget*>("",Qt::FindDirectChildrenOnly); - for(int i=0; i<widgets.length(); i++){ widgets[i]->deleteLater(); } + if(!this->source().isEmpty()){ + this->setSource(QUrl()); + cplug = SSPlugin(); //empty structure } if(restartTimer->isActive()){ restartTimer->stop(); } } diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h index af809127..72e02702 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h @@ -10,9 +10,9 @@ #define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_WIDGET_H #include "global-includes.h" -#include "animations/BaseAnimGroup.h" +#include <plugins-screensaver.h> -class SSBaseWidget : public QWidget{ +class SSBaseWidget : public QQuickView{ Q_OBJECT public: SSBaseWidget(QWidget *parent); @@ -25,8 +25,8 @@ public slots: void stopPainting(); private: - QString plugType, cplug; //type of custom painting to do - BaseAnimGroup *ANIM; + QString plugType; + SSPlugin cplug; QTimer *restartTimer; private slots: @@ -43,12 +43,6 @@ protected: ev->accept(); emit InputDetected(); } - void paintEvent(QPaintEvent*){ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - } }; diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri index f95891c1..92cc7bd2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri @@ -9,7 +9,7 @@ HEADERS *= $${PWD}/LLockScreen.h \ FORMS *= $${PWD}/LLockScreen.ui #update the includepath so we can just (#include <LScreenSaver.h>) as needed without paths -INCLUDEPATH *= ${PWD} +INCLUDEPATH *= $${PWD} #Now include all the screensaver animations/options -include(animations/animations.pri) +#include(animations/animations.pri) diff --git a/src-qt5/core/lumina-desktop/LDesktop.cpp b/src-qt5/core/lumina-desktop/LDesktop.cpp index f9ea1534..71b10bd5 100644 --- a/src-qt5/core/lumina-desktop/LDesktop.cpp +++ b/src-qt5/core/lumina-desktop/LDesktop.cpp @@ -341,7 +341,7 @@ void LDesktop::UpdateMenu(bool fast){ void LDesktop::UpdateWinMenu(){ winMenu->clear(); //Get the current list of windows - QList<WId> wins = LSession::handle()->XCB->WindowList(); + QList<WId> wins = LSession::handle()->XCB->WindowList(); //Now add them to the menu for(int i=0; i<wins.length(); i++){ LWinInfo info(wins[i]); @@ -352,7 +352,7 @@ void LDesktop::UpdateWinMenu(){ } void LDesktop::winClicked(QAction* act){ - LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() ); + LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() ); } void LDesktop::UpdateDesktop(){ @@ -393,7 +393,7 @@ void LDesktop::UpdateDesktop(){ if(settings->value(DPREFIX+"generateMediaIcons",true).toBool()){ QDir media("/media"); QStringList mediadirs = media.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Name); - for(int i=0; i<mediadirs.length(); i++){ + for(int i=0; i<mediadirs.length(); i++){ filelist << media.absoluteFilePath(mediadirs[i]); } } @@ -406,8 +406,8 @@ void LDesktop::RemoveDeskPlugin(QString ID){ //This is called after a plugin is manually removed by the user // just need to ensure that the plugin is also removed from the settings file QStringList plugs = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList(); - if(plugs.contains(ID)){ - plugs.removeAll(ID); + if(plugs.contains(ID)){ + plugs.removeAll(ID); issyncing=true; //don't let the change cause a refresh settings->setValue(DPREFIX+"pluginlist", plugs); settings->sync(); @@ -437,7 +437,7 @@ void LDesktop::DecreaseDesktopPluginIcons(){ settings->setValue(DPREFIX+"GridSize",cur); settings->sync(); QTimer::singleShot(200, this, SLOT(UnlockSettings()) ); - bgDesktop->SetIconSize(cur); + bgDesktop->SetIconSize(cur); } void LDesktop::UpdatePanels(){ @@ -484,18 +484,18 @@ void LDesktop::UpdateDesktopPluginArea(){ QRegion shifted = visReg; QString loc = settings->value(PANELS[i]->prefix()+"location","top").toString().toLower(); int vis = PANELS[i]->visibleWidth(); - if(loc=="top"){ + if(loc=="top"){ if(!shifted.contains(QRect(rawRect.x(), rawRect.y(), rawRect.width(), vis))){ continue; } - shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() ); + shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() ); }else if(loc=="bottom"){ - if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; } - shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom()); - }else if(loc=="left"){ + if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; } + shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom()); + }else if(loc=="left"){ if( !shifted.contains(QRect(rawRect.x(), rawRect.y(), vis,rawRect.height())) ){ continue; } - shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0); + shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0); }else{ //right if(!shifted.contains(QRect(rawRect.right()-vis, rawRect.y(), vis,rawRect.height())) ){ continue; } - shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0); + shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0); } visReg = visReg.intersected( shifted ); } @@ -535,11 +535,20 @@ void LDesktop::UpdateBackground(){ //Get the list of background(s) to show QStringList bgL = settings->value(DPREFIX+"background/filelist-workspace-"+QString::number( LSession::handle()->XCB->CurrentWorkspace()), QStringList()).toStringList(); if(bgL.isEmpty()){ bgL = settings->value(DPREFIX+"background/filelist", QStringList()).toStringList(); } - + //qDebug() << " - List:" << bgL << CBG; //Remove any invalid files for(int i=0; i<bgL.length(); i++){ - if( (!QFile::exists(bgL[i]) && bgL[i]!="default" && !bgL[i].startsWith("rgb(") ) || bgL[i].isEmpty()){ bgL.removeAt(i); i--; } + if(bgL[i]=="default" || bgL[i].startsWith("rgb(") ){ continue; } //built-in definitions - treat them as valid + if(bgL[i].isEmpty()){ bgL.removeAt(i); i--; } + if( !QFile::exists(bgL[i]) ){ + //Quick Detect/replace for new path for Lumina wallpapers (change in 1.3.4) + if(bgL[i].contains("/wallpapers/Lumina-DE/")){ + bgL[i] = bgL[i].replace("/wallpapers/Lumina-DE/", "/wallpapers/lumina-desktop/"); i--; //modify the path and re-check it + }else{ + bgL.removeAt(i); i--; + } + } } if(bgL.isEmpty()){ bgL << "default"; } //always fall back on the default //Determine if the background needs to be changed @@ -552,13 +561,32 @@ void LDesktop::UpdateBackground(){ } oldBGL = bgL; //save this for later //Determine which background to use next - int index ( qrand() % bgL.length() ); - if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again - //Go to the next in the list - if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first - else{ index++; } //go to next + QString bgFile; + while(bgFile.isEmpty() || QFileInfo(bgFile).isDir()){ + QString prefix; + if(!bgFile.isEmpty()){ + //Got a directory - update the list of files and re-randomize the selection + QStringList imgs = LUtils::imageExtensions(); + for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); } + QDir tdir(bgFile); + prefix=bgFile+"/"; + bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name); + //If directory no longer has any valid images - remove it from list and try again + if(bgL.isEmpty()){ + oldBGL.removeAll(bgFile); //invalid directory - remove it from the list for the moment + bgL = oldBGL; //reset the list back to the original list (not within a directory) + } + } + //Verify that there are files in the list - otherwise use the default + if(bgL.isEmpty()){ bgFile="default"; break; } + int index = ( qrand() % bgL.length() ); + if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again + //Go to the next in the list + if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first + else{ index++; } //go to next + } + bgFile = prefix+bgL[index]; } - QString bgFile = bgL[index]; //Save this file as the current background CBG = bgFile; //qDebug() << " - Set Background to:" << CBG << index << bgL; @@ -570,7 +598,7 @@ void LDesktop::UpdateBackground(){ bgDesktop->setBackground(backPix); //Now reset the timer for the next change (if appropriate) if(bgtimer->isActive()){ bgtimer->stop(); } - if(bgL.length() > 1){ + if(bgL.length()>1 || oldBGL.length()>1){ //get the length of the timer (in minutes) int min = settings->value(DPREFIX+"background/minutesToChange",5).toInt(); //restart the internal timer @@ -633,9 +661,9 @@ void LDesktop::NewDesktopFile(QString name){ QDir desktop(QDir::homePath()); if(desktop.exists(tr("Desktop"))){ desktop.cd(tr("Desktop")); } //translated folder else{ desktop.cd("Desktop"); } //default/english folder - if(!desktop.exists(name)){ + if(!desktop.exists(name)){ QFile file(desktop.absoluteFilePath(name)); - if(file.open(QIODevice::WriteOnly) ){ file.close(); } + if(file.open(QIODevice::WriteOnly) ){ file.close(); } } } } diff --git a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp index 41a1017d..9e964f5d 100644 --- a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp +++ b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp @@ -21,7 +21,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){ //this->setAttribute(Qt::WA_TranslucentBackground); //this->setAttribute(Qt::WA_NoSystemBackground); this->setAutoFillBackground(false); - this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); + this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); this->setWindowFlags(Qt::WindowStaysOnBottomHint | Qt::CustomizeWindowHint | Qt::FramelessWindowHint); this->setAcceptDrops(true); this->setContextMenuPolicy(Qt::NoContextMenu); @@ -34,7 +34,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){ } LDesktopPluginSpace::~LDesktopPluginSpace(){ - + } void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){ @@ -76,7 +76,7 @@ void LDesktopPluginSpace::setBackground(QPixmap pix){ void LDesktopPluginSpace::setDesktopArea(QRect area){ //qDebug() << "Setting Desktop Plugin Area:" << area; desktopRect = area; - + } // =================== @@ -222,7 +222,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start //else{ row++; } } if(!found){ col++; row=0; } //go to the next column - } + } }else if(reversed && (startRow>0 || startCol>0) ){ //Arrange Left->Right (work backwards) while(row>=0 && !found){ @@ -242,7 +242,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start //else{ col++; } } if(!found){ row--; col=colCount-gridwidth;} //go to the previous row - } + } }else{ //Arrange Left->Right while(row<(rowCount-gridheight) && !found){ @@ -296,8 +296,8 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){ QStringList plugs = plugins; QStringList items = deskitems; for(int i=0; i<ITEMS.length(); i++){ - - if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){ + + if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){ //Change the size of the existing plugin - preserving the location if possible /*QRect geom = ITEMS[i]->loadPluginGeometry(); //pixel coords if(!geom.isNull()){ @@ -306,14 +306,14 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){ ITEMS[i]->savePluginGeometry( gridToGeom(geom)); //save it back in pixel coords }*/ //Now remove the plugin for the moment - run it through the re-creation routine below - ITEMS.takeAt(i)->deleteLater(); + ITEMS.takeAt(i)->deleteLater(); i--; } else if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); } else if(items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50))){ items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)); } else{ ITEMS[i]->removeSettings(true); ITEMS.takeAt(i)->deleteLater(); i--; } //this is considered a permanent removal (cleans settings) } - + //Now create any new items //First load the plugins (almost always have fixed locations) for(int i=0; i<plugs.length(); i++){ diff --git a/src-qt5/core/lumina-desktop/LSession.cpp b/src-qt5/core/lumina-desktop/LSession.cpp index 2a1ec783..dab30f01 100644 --- a/src-qt5/core/lumina-desktop/LSession.cpp +++ b/src-qt5/core/lumina-desktop/LSession.cpp @@ -98,7 +98,7 @@ void LSession::setupSession(){ qDebug() << "Initializing Session"; if(QFile::exists("/tmp/.luminastopping")){ QFile::remove("/tmp/.luminastopping"); } QTime* timer = 0; - //if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();} + if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();} //Setup the QSettings default paths splash.showScreen("settings"); @@ -118,9 +118,9 @@ void LSession::setupSession(){ } //use the system settings //Setup the user's lumina settings directory as necessary - splash.showScreen("user"); - if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} - checkUserFiles(); //adds these files to the watcher as well + //splash.showScreen("user"); + //if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} + //checkUserFiles(); //adds these files to the watcher as well //Initialize the internal variables DESKTOPS.clear(); @@ -147,11 +147,12 @@ void LSession::setupSession(){ if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed();} 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 + //if(DEBUG){ qDebug() << " - Process Events (6x):" << timer->elapsed();} + //for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running //Now setup the system watcher for changes splash.showScreen("final"); - qDebug() << " - Initialize file system watcher"; + //qDebug() << " - Initialize file system watcher"; if(DEBUG){ qDebug() << " - Init QFileSystemWatcher:" << timer->elapsed();} watcher = new QFileSystemWatcher(this); QString confdir = sessionsettings->fileName().section("/",0,-2); @@ -171,14 +172,18 @@ void LSession::setupSession(){ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherChange(QString)) ); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherChange(QString)) ); connect(this, SIGNAL(aboutToQuit()), this, SLOT(SessionEnding()) ); - if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;} - for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen + //if(DEBUG){ qDebug() << " - Process Events (4x):" << timer->elapsed();} + //for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen + if(DEBUG){ qDebug() << " - Launch Startup Apps:" << timer->elapsed();} //launchStartupApps(); QTimer::singleShot(500, this, SLOT(launchStartupApps()) ); - splash.hide(); - LSession::processEvents(); + //if(DEBUG){ qDebug() << " - Hide Splashscreen:" << timer->elapsed();} + //splash.hide(); + //LSession::processEvents(); + if(DEBUG){ qDebug() << " - Close Splashscreen:" << timer->elapsed();} splash.close(); - LSession::processEvents(); + //LSession::processEvents(); + if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;} } void LSession::CleanupSession(){ @@ -289,7 +294,7 @@ void LSession::launchStartupApps(){ qDebug() << " - - Screen Brightness:" << QString::number(tmp)+"%"; } //QProcess::startDetached("nice lumina-open -autostart-apps"); - ExternalProcess::launch("nice lumina-open -autostart-apps"); + ExternalProcess::launch("lumina-open", QStringList() << "-autostart-apps", false); //Re-load the screen brightness and volume settings from the previous session // Wait until after the XDG-autostart functions, since the audio system might be started that way @@ -303,7 +308,7 @@ void LSession::launchStartupApps(){ QString sfile = sessionsettings->value("audiofiles/login", LOS::LuminaShare()+"Login.ogg").toString(); playAudioFile(sfile); } - qDebug() << "[DESKTOP INIT FINISHED]"; + //qDebug() << "[DESKTOP INIT FINISHED]"; } void LSession::StartLogout(){ @@ -384,15 +389,26 @@ void LSession::checkWindowGeoms(){ } } -void LSession::checkUserFiles(){ +bool LSession::checkUserFiles(){ //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] - QString OVS = sessionsettings->value("DesktopVersion","0").toString(); //Old Version String - bool changed = LDesktopUtils::checkUserFiles(OVS); + qDebug() << "Check User Files"; + //char tmp[] = "junk\0"; + //int tmpN = 0; + //QApplication A(tmpN, (char **)&tmp); + QSettings sset("lumina-desktop", "sessionsettings"); + QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String + qDebug() << " - Old Version:" << OVS; + qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion(); + bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion()); + qDebug() << " - Made Changes:" << changed; if(changed){ //Save the current version of the session to the settings file (for next time) - sessionsettings->setValue("DesktopVersion", this->applicationVersion()); + sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion()); } + qDebug() << "Finished with user files check"; + //delete A; + return changed; } void LSession::refreshWindowManager(){ @@ -573,7 +589,7 @@ void LSession::SessionEnding(){ //=============== void LSession::LaunchApplication(QString cmd){ //LSession::setOverrideCursor(QCursor(Qt::BusyCursor)); - ExternalProcess::launch(cmd); + ExternalProcess::launch(cmd, QStringList(), true); //QProcess::startDetached(cmd); } @@ -674,7 +690,7 @@ void LSession::WindowPropertyEvent(){ if(RunningApps.length() < newapps.length()){ //New Window found //qDebug() << "New window found"; - LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) + //LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) //Perform sanity checks on any new window geometries for(int i=0; i<newapps.length() && !TrayStopping; i++){ if(!RunningApps.contains(newapps[i])){ @@ -826,7 +842,7 @@ void LSession::attachTrayWindow(WId win){ if(RunningTrayApps.contains(win)){ return; } //already managed qDebug() << "Session Tray: Window Added"; RunningTrayApps << win; - LSession::restoreOverrideCursor(); + //LSession::restoreOverrideCursor(); if(DEBUG){ qDebug() << "Tray List Changed"; } emit TrayListChanged(); } diff --git a/src-qt5/core/lumina-desktop/LSession.h b/src-qt5/core/lumina-desktop/LSession.h index 0d69df84..a25f3c15 100644 --- a/src-qt5/core/lumina-desktop/LSession.h +++ b/src-qt5/core/lumina-desktop/LSession.h @@ -39,7 +39,7 @@ #define SYSTEM_TRAY_CANCEL_MESSAGE 2 /*class MenuProxyStyle : public QProxyStyle{ -public: +public: int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const{ if(metric==PM_SmallIconSize){ return 22; } //override QMenu icon size (make it larger) else{ return QProxyStyle::pixelMetric(metric, option, widget); } //use the current style for everything else @@ -51,6 +51,8 @@ class LSession : public LSingleApplication{ public: LSession(int &argc, char **argv); ~LSession(); + + static bool checkUserFiles(); //Functions to be called during startup void setupSession(); @@ -63,7 +65,7 @@ public: bool registerStartButton(QString ID); void unregisterStartButton(QString ID); - //Special functions for XCB event filter parsing only + //Special functions for XCB event filter parsing only // (DO NOT USE MANUALLY) void RootSizeChange(); void WindowPropertyEvent(); @@ -73,37 +75,37 @@ public: void WindowConfigureEvent(WId); void WindowDamageEvent(WId); void WindowSelectionClearEvent(WId); - + //System Access //Return a pointer to the current session static LSession* handle(){ return static_cast<LSession*>(LSession::instance()); } - + static void LaunchApplication(QString cmd); QFileInfoList DesktopFiles(); - + QRect screenGeom(int num); - + AppMenu* applicationMenu(); void systemWindow(); SettingsMenu* settingsMenu(); LXCB *XCB; //class for XCB usage - + QSettings* sessionSettings(); QSettings* DesktopPluginSettings(); - + //Keep track of which non-desktop window should be treated as active WId activeWindow(); //This will return the last active window if a desktop element is currently active - + //Temporarily change the session locale (nothing saved between sessions) void switchLocale(QString localeCode); - + //Play System Audio void playAudioFile(QString filepath); //Window Adjustment Routine (due to Fluxbox not respecting _NET_WM_STRUT) void adjustWindowGeom(WId win, bool maximize = false); - + private: //WMProcess *WM; QList<LDesktop*> DESKTOPS; @@ -136,9 +138,9 @@ private: QFileInfoList desktopFiles; void CleanupSession(); - + int VersionStringToNumber(QString version); - + public slots: void StartLogout(); void StartShutdown(bool skipupdates = false); @@ -161,7 +163,6 @@ private slots: void removeTrayWindow(WId); //Internal simplification functions - void checkUserFiles(); void refreshWindowManager(); void updateDesktops(); void registerDesktopWindows(); @@ -189,7 +190,7 @@ signals: void DesktopFilesChanged(); void MediaFilesChanged(); void WorkspaceChanged(); - + }; #endif diff --git a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp index ca7fb38d..038872ff 100644 --- a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp @@ -52,8 +52,8 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->emit WorkspaceChanged(); }else if( SysNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Update the status/list of all running windows - session->WindowPropertyEvent(); - + session->WindowPropertyEvent(); + //window-specific property change }else if( WinNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Ping only that window @@ -61,7 +61,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->WindowPropertyEvent(); } break; -//============================== +//============================== case XCB_CLIENT_MESSAGE: //qDebug() << "Client Message Event"; //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); @@ -72,7 +72,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->SysTrayDockRequest( ((xcb_client_message_event_t*)ev)->data.data32[2] ); } //Ignore the System Tray messages at the moment (let the WM handle it) - + //window-specific property changes /*}else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){ if( session->XCB->WindowIsMaximized( ((xcb_client_message_event_t*)ev)->window ) ){ @@ -86,22 +86,22 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->WindowPropertyEvent(); } break; -//============================== +//============================== case XCB_DESTROY_NOTIFY: //qDebug() << "Window Closed Event"; session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window ); break; -//============================== +//============================== case XCB_CONFIGURE_NOTIFY: //qDebug() << "Configure Notify Event"; session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window ); break; -//============================== +//============================== case XCB_SELECTION_CLEAR: //qDebug() << "Selection Clear Event"; - session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); + session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); break; -//============================== +//============================== default: if(TrayDmgFlag!=0){ //if( (ev->response_type & ~0x80)==TrayDmgFlag){ diff --git a/src-qt5/core/lumina-desktop/WMProcess.cpp b/src-qt5/core/lumina-desktop/WMProcess.cpp index aa01b730..0687c1fe 100644 --- a/src-qt5/core/lumina-desktop/WMProcess.cpp +++ b/src-qt5/core/lumina-desktop/WMProcess.cpp @@ -30,7 +30,7 @@ void WMProcess::startWM(){ if(!isRunning()){this->start(cmd); } /*if(ssaver->state() == QProcess::NotRunning \ && LSession::handle()->sessionSettings()->value("WindowManager", "fluxbox").toString() != "lumina-wm"){ - ssaver->start("xscreensaver -no-splash"); + ssaver->start("xscreensaver -no-splash"); }*/ } @@ -52,8 +52,8 @@ void WMProcess::restartWM(){ inShutdown = true; this->kill(); if(!this->waitForFinished(5000) ){ this->terminate(); }; - inShutdown = false; - } + inShutdown = false; + } this->startWM(); } diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf index e453c0b8..e9520a3c 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf @@ -53,7 +53,7 @@ mime_default_application/x-tar_ifexists=lumina-archiver.desktop #THEME SETTINGS theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) -theme_colorfile=Black #Name of the color spec file to use for theming +theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Noto Sans #Name of the font family to use theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) ) diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf index 1327f148..40ece4f0 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf @@ -51,7 +51,7 @@ mime_default_application/x-shellscript=lumina-textedit.desktop #THEME SETTINGS theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) -theme_colorfile=Black #Name of the color spec file to use for theming +theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Arial #Name of the font family to use theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) ) diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp index 0258d561..0bf087c1 100644 --- a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp +++ b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp @@ -44,7 +44,8 @@ void AppLauncherPlugin::loadButton(){ QFileInfo info(path); this->contextMenu()->clear(); //qDebug() << "Default Application Launcher:" << def << path; - bool ok = QFile::exists(path); + bool ok = info.canonicalPath().startsWith("/net/"); + if(!ok){ ok = QFile::exists(path); } //do it this way to ensure the file existance check never runs for /net/ files if(!ok){ emit RemovePlugin(this->ID()); return;} icosize = this->height()-4 - 2.2*button->fontMetrics().height(); button->setFixedSize( this->width()-4, this->height()-4); diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro index d4e57c5c..2c944a11 100644 --- a/src-qt5/core/lumina-desktop/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro @@ -77,17 +77,6 @@ fluxconf.files = fluxboxconf/fluxbox-init-rc \ fluxboxconf/fluxbox-keys fluxconf.path = $${L_SHAREDIR}/lumina-desktop/ -wallpapers.files = wallpapers/Lumina_Wispy_gold.jpg \ - wallpapers/Lumina_Wispy_green.jpg \ - wallpapers/Lumina_Wispy_purple.jpg \ - wallpapers/Lumina_Wispy_red.jpg \ - wallpapers/Lumina_Wispy_blue-grey.jpg \ - wallpapers/Lumina_Wispy_blue-grey-zoom.jpg \ - wallpapers/Lumina_Wispy_grey-blue.jpg \ - wallpapers/Lumina_Wispy_grey-blue-zoom.jpg -wallpapers.path = $${L_SHAREDIR}/wallpapers/Lumina-DE - - defaults.files = defaults/luminaDesktop.conf \ defaults/compton.conf \ audiofiles/Logout.ogg \ diff --git a/src-qt5/core/lumina-desktop/main.cpp b/src-qt5/core/lumina-desktop/main.cpp index b2bfa9be..826d697c 100644 --- a/src-qt5/core/lumina-desktop/main.cpp +++ b/src-qt5/core/lumina-desktop/main.cpp @@ -78,33 +78,19 @@ int main(int argc, char ** argv) //Startup the session LSession a(argc, argv); if(!a.isPrimaryProcess()){ return 0; } + //Ensure that the user's config files exist + /*if( LSession::checkUserFiles() ){ //make sure to create any config files before creating the QApplication + qDebug() << "User files changed - restarting the desktop session"; + return 787; //return special restart code + }*/ //Setup the log file - /* logfile.setFileName( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/logs/runtime.log" ); - qDebug() << "Lumina Log File:" << logfile.fileName(); - if(QFile::exists(logfile.fileName()+".old")){ QFile::remove(logfile.fileName()+".old"); } - if(logfile.exists()){ QFile::rename(logfile.fileName(), logfile.fileName()+".old"); } - //Make sure the parent directory exists - if(!QFile::exists(QDir::homePath()+"/.lumina/logs")){ - QDir dir; - dir.mkpath(QDir::homePath()+"/.lumina/logs"); - } - logfile.open(QIODevice::WriteOnly | QIODevice::Append);*/ QTime *timer=0; if(DEBUG){ timer = new QTime(); timer->start(); } - //Setup Log File - //qInstallMessageHandler(MessageOutput); - //if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); } - //LuminaThemeEngine theme(&a); - //QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) ); - //if(DEBUG){ qDebug() << "Load Locale:" << timer->elapsed(); } - //LUtils::LoadTranslation(&a, "lumina-desktop"); if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); } a.setupSession(); - //theme.refresh(); if(DEBUG){ qDebug() << "Exec Time:" << timer->elapsed(); delete timer;} int retCode = a.exec(); //qDebug() << "Stopping the window manager"; qDebug() << "Finished Closing Down Lumina"; - //logfile.close(); return retCode; } 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 cae73d13..7a6b0e7c 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp @@ -20,6 +20,7 @@ LBattery::LBattery(QWidget *parent, QString id, bool horizontal) : LPPlugin(pare connect(timer,SIGNAL(timeout()), this, SLOT(updateBattery()) ); timer->start(); QTimer::singleShot(0,this,SLOT(OrientationChange()) ); //update the sizing/icon + sessionsettings = new QSettings("lumina-desktop", "sessionsettings"); } LBattery::~LBattery(){ @@ -78,7 +79,8 @@ void LBattery::updateBattery(bool force){ } if(icon<iconOld && icon==0){ //Play some audio warning chime when - QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString(); + 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); } @@ -95,6 +97,7 @@ void LBattery::updateBattery(bool force){ else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); } label->setToolTip(tt); } +} QString LBattery::getRemainingTime(){ int secs = LOS::batterySecondsLeft(); 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 d14cfc53..3c23be1c 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h @@ -30,6 +30,7 @@ private: QTimer *timer; QLabel *label; int iconOld; + QSettings *sessionsettings; private slots: void updateBattery(bool force = false); diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp index f44add77..30e82c47 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp @@ -26,9 +26,10 @@ LStartButtonPlugin::LStartButtonPlugin(QWidget *parent, QString id, bool horizon connect(startmenu, SIGNAL(CloseMenu()), this, SLOT(closeMenu()) ); connect(startmenu, SIGNAL(UpdateQuickLaunch(QStringList)), this, SLOT(updateQuickLaunch(QStringList))); menu->setContents(startmenu); - QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(0,0)).toSize(); + QRect screenSize = QApplication::desktop()->availableGeometry(this); + QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(screenSize.width() * 0.2, screenSize.height())).toSize(); if(!saved.isNull()){ startmenu->setFixedSize(saved); } //re-load the previously saved value - + button->setMenu(menu); connect(menu, SIGNAL(aboutToHide()), this, SLOT(updateButtonVisuals()) ); QTimer::singleShot(0,this, SLOT(OrientationChange())); //Update icons/sizes 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 e8df8390..c99e2b4b 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp @@ -138,7 +138,7 @@ void StartMenu::UpdateMenu(bool forceall){ } void StartMenu::ReLoadQuickLaunch(){ - emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() ); + emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() ); } void StartMenu::UpdateQuickLaunch(QString path, bool keep){ @@ -431,7 +431,9 @@ void StartMenu::UpdateFavs(){ tmp.sort(); //Sort alphabetically by name (dirs/files) for(int i=0; i<tmp.length(); i++){ if(type<2){ rest.removeAll(tmp[i]); } - if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it + if( !tmp[i].section("::::",2,-1).startsWith("/net/") ){ + if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it + } ItemWidget *it = 0; if( tmp[i].section("::::",2,-1).endsWith(".desktop")){ XDGDesktop item(tmp[i].section("::::",2,-1)); @@ -493,7 +495,7 @@ void StartMenu::on_stackedWidget_currentChanged(int val){ if(tot>1){ ui->frame_wkspace->setVisible(true); int cur = LSession::handle()->XCB->CurrentWorkspace(); - ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); + ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); }else{ ui->frame_wkspace->setVisible(false); } @@ -635,14 +637,14 @@ void StartMenu::on_tool_mute_audio_clicked(){ ui->slider_volume->setValue(0); } } - + //Screen Brightness void StartMenu::on_slider_bright_valueChanged(int val){ ui->label_bright->setText(QString::number(val)+"%"); LOS::setScreenBrightness(val); } - + //Workspace void StartMenu::on_tool_set_nextwkspace_clicked(){ int cur = LSession::handle()->XCB->CurrentWorkspace(); @@ -663,10 +665,10 @@ void StartMenu::on_tool_set_prevwkspace_clicked(){ if(cur<0){ cur = tot-1; } //back to end //qDebug() << " - New Current:" << cur; LSession::handle()->XCB->SetCurrentWorkspace(cur); - ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); + ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); } - + //Locale void StartMenu::on_combo_locale_currentIndexChanged(int){ //Get the currently selected Locale @@ -677,7 +679,7 @@ void StartMenu::on_combo_locale_currentIndexChanged(int){ LSession::handle()->switchLocale(locale); } - + //Search void StartMenu::on_line_search_textEdited(QString){ if(searchTimer->isActive()){ searchTimer->stop(); } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h index 8ab04d94..e2dbb273 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h @@ -34,13 +34,13 @@ private: Ui::StartMenu *ui; QStringList favs; QString CCat, CSearch, topsearch; //current category/search - QTimer *searchTimer; + QTimer *searchTimer; //Simple utility functions //void deleteChildren(QWidget *obj); //recursive function void ClearScrollArea(QScrollArea *area); void SortScrollArea(QScrollArea *area); - void do_search(QString search, bool force); + void do_search(QString search, bool force); bool promptAboutUpdates(bool &skip); diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg Binary files differdeleted file mode 100644 index 481ca438..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg Binary files differdeleted file mode 100644 index 9da67596..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg Binary files differdeleted file mode 100644 index cba03cee..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg Binary files differdeleted file mode 100644 index 80b0d3e3..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg Binary files differdeleted file mode 100644 index 4f753ed5..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg Binary files differdeleted file mode 100644 index c214cd78..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg Binary files differdeleted file mode 100644 index e4c3d7a8..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg Binary files differdeleted file mode 100644 index a092f636..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-open/LFileDialog.cpp b/src-qt5/core/lumina-open/LFileDialog.cpp index ce7c6a6f..dbdb6362 100644 --- a/src-qt5/core/lumina-open/LFileDialog.cpp +++ b/src-qt5/core/lumina-open/LFileDialog.cpp @@ -54,9 +54,9 @@ QString LFileDialog::getDefaultApp(QString extension){ void LFileDialog::setDefaultApp(QString extension, QString appFile){ if(!extension.contains("/")){ extension = LXDG::findAppMimeForFile(appFile); } - //mime type default: set on the system itself - if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path - LXDG::setDefaultAppForMime(extension, appFile); + //mime type default: set on the system itself + //if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path + LXDG::setDefaultAppForMime(extension, appFile); } // ----------- diff --git a/src-qt5/core/lumina-open/lumina-open.1 b/src-qt5/core/lumina-open/lumina-open.1 index e8c555ee..cb671da3 100644 --- a/src-qt5/core/lumina-open/lumina-open.1 +++ b/src-qt5/core/lumina-open/lumina-open.1 @@ -19,7 +19,7 @@ .Sh DESCRIPTION Given a file with an absolute pathway or URL, the .Nm -utility finds the appropriate application which which to open the +utility finds the appropriate application with which to open the file. If the file is a *.desktop application shortcut, .Nm starts the application automatically. Using the appropriate flags diff --git a/src-qt5/core/lumina-open/main.cpp b/src-qt5/core/lumina-open/main.cpp index 72d09f42..2b9e9184 100644 --- a/src-qt5/core/lumina-open/main.cpp +++ b/src-qt5/core/lumina-open/main.cpp @@ -29,6 +29,8 @@ #include <LuminaOS.h> #include <LuminaThemes.h> +#define DEBUG 0 + void printUsageInfo(){ qDebug() << "lumina-open: Application launcher for the Lumina Desktop Environment"; qDebug() << "Description: Given a file (with absolute path) or URL, this utility will try to find the appropriate application with which to open the file. If the file is a *.desktop application shortcut, it will just start the application appropriately. It can also perform a few specific system operations if given special flags."; @@ -48,7 +50,6 @@ void ShowErrorDialog(int argc, char **argv, QString message){ //Setup the application QApplication App(argc, argv); App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); LUtils::LoadTranslation(&App,"lumina-open"); QMessageBox dlg(QMessageBox::Critical, QObject::tr("File Error"), message ); dlg.exec(); @@ -68,7 +69,7 @@ void showOSD(int argc, char **argv, QString message){ splash.setAlignment(Qt::AlignCenter); - qDebug() << "Display OSD"; + if(DEBUG) qDebug() << "Display OSD"; splash.setText(message); //Make sure it is centered on the current screen QPoint center = App.desktop()->screenGeometry(QCursor::pos()).center(); @@ -89,7 +90,7 @@ void LaunchAutoStart(){ if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); } //Now run the command if(!cmd.isEmpty()){ - qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath; + if(DEBUG) qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath; QProcess::startDetached(cmd); } } @@ -98,130 +99,129 @@ void LaunchAutoStart(){ } QString cmdFromUser(int argc, char **argv, QString inFile, QString extension, QString& path, bool showDLG=false){ - //First check to see if there is a default for this extension - QString defApp; - if(extension=="mimetype"){ + //First check to see if there is a default for this extension + QString defApp; + if(extension=="mimetype"){ //qDebug() << "inFile:" << inFile; QStringList matches = LXDG::findAppMimeForFile(inFile, true).split("::::"); //allow multiple matches - qDebug() << "Mimetype Matches:" << matches; + if(DEBUG) qDebug() << "Mimetype Matches:" << matches; for(int i=0; i<matches.length(); i++){ defApp = LXDG::findDefaultAppForMime(matches[i]); - //qDebug() << "MimeType:" << matches[i] << defApp; + //qDebug() << "MimeType:" << matches[i] << defApp; if(!defApp.isEmpty()){ extension = matches[i]; break; } else if(i+1==matches.length()){ extension = matches[0]; } } - }else{ defApp = LFileDialog::getDefaultApp(extension); } - qDebug() << "Mimetype:" << extension << "defApp:" << defApp; - if( !defApp.isEmpty() && !showDLG ){ - if(defApp.endsWith(".desktop")){ - XDGDesktop DF(defApp); - if(DF.isValid()){ - QString exec = DF.getDesktopExec(); - if(!exec.isEmpty()){ - qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile; - if(!DF.path.isEmpty()){ path = DF.path; } - return exec; - } + }else{ defApp = LFileDialog::getDefaultApp(extension); } + if(DEBUG) qDebug() << "Mimetype:" << extension << "defApp:" << defApp; + if( !defApp.isEmpty() && !showDLG ){ + if(defApp.endsWith(".desktop")){ + XDGDesktop DF(defApp); + if(DF.isValid()){ + QString exec = DF.getDesktopExec(); + if(!exec.isEmpty()){ + if(DEBUG) qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile; + if(!DF.path.isEmpty()){ path = DF.path; } + return exec; } - }else{ - //Only binary given - if(LUtils::isValidBinary(defApp)){ - qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile; - return defApp; //just use the binary - } } - //invalid default - reset it and continue on - LFileDialog::setDefaultApp(extension, ""); - } - //Final catch: directory given - no valid default found - use lumina-fm - if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; } - //No default set -- Start up the application selection dialog - LTHEME::LoadCustomEnvSettings(); - QApplication App(argc, argv); - App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); - LUtils::LoadTranslation(&App,"lumina-open"); - - LFileDialog w; - if(extension=="email" || extension.startsWith("x-scheme-handler/")){ - //URL - w.setFileInfo(inFile, extension, false); }else{ - //File - if(inFile.endsWith("/")){ inFile.chop(1); } - w.setFileInfo(inFile.section("/",-1), extension, true); + //Only binary given + if(LUtils::isValidBinary(defApp)){ + if(DEBUG) qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile; + return defApp; //just use the binary } + } + //invalid default - reset it and continue on + LFileDialog::setDefaultApp(extension, ""); + } + //Final catch: directory given - no valid default found - use lumina-fm + if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; } + //No default set -- Start up the application selection dialog + LTHEME::LoadCustomEnvSettings(); + QApplication App(argc, argv); + App.setAttribute(Qt::AA_UseHighDpiPixmaps); + LUtils::LoadTranslation(&App,"lumina-open"); - w.show(); - App.exec(); - if(!w.appSelected){ return ""; } - //Return the run path if appropriate - if(!w.appPath.isEmpty()){ path = w.appPath; } - //Just do the default application registration here for now - // might move it to the runtime phase later after seeing that the app has successfully started - if(w.setDefault){ - if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); } - else{ LFileDialog::setDefaultApp(extension, w.appExec); } - } - //Now return the resulting application command - return w.appExec; + LFileDialog w; + if(extension=="email" || extension.startsWith("x-scheme-handler/")){ + //URL + w.setFileInfo(inFile, extension, false); + }else{ + //File + if(inFile.endsWith("/")){ inFile.chop(1); } + w.setFileInfo(inFile.section("/",-1), extension, true); + } + + w.show(); + App.exec(); + if(!w.appSelected){ return ""; } + //Return the run path if appropriate + if(!w.appPath.isEmpty()){ path = w.appPath; } + //Just do the default application registration here for now + // might move it to the runtime phase later after seeing that the app has successfully started + if(w.setDefault){ + if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); } + else{ LFileDialog::setDefaultApp(extension, w.appExec); } + } + //Now return the resulting application command + return w.appExec; } void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& path, bool& watch){ - //Get the input file - //Make sure to load the proper system encoding first - LUtils::LoadTranslation(0,""); //bypass application modification - QString inFile, ActionID; - bool showDLG = false; //flag to bypass any default application setting - if(argc > 1){ - for(int i=1; i<argc; i++){ - if(QString(argv[i]).simplified() == "-select"){ - showDLG = true; - }else if(QString(argv[i]).simplified() == "-testcrash"){ - //Test the crash handler - binary = "internalcrashtest"; watch=true; - return; - }else if(QString(argv[i]).simplified() == "-autostart-apps"){ - LaunchAutoStart(); - return; - }else if(QString(argv[i]).simplified() == "-volumeup"){ - int vol = LOS::audioVolume()+5; //increase 5% - if(vol>100){ vol=100; } - LOS::setAudioVolume(vol); - showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); - return; - }else if(QString(argv[i]).simplified() == "-volumedown"){ - int vol = LOS::audioVolume()-5; //decrease 5% - if(vol<0){ vol=0; } - LOS::setAudioVolume(vol); - showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); - return; - }else if(QString(argv[i]).simplified() == "-brightnessup"){ - int bright = LOS::ScreenBrightness(); - if(bright > 0){ //brightness control available - bright = bright+5; //increase 5% - if(bright>100){ bright = 100; } - LOS::setScreenBrightness(bright); - showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); - } - return; - }else if(QString(argv[i]).simplified() == "-brightnessdown"){ - int bright = LOS::ScreenBrightness(); - if(bright > 0){ //brightness control available - bright = bright-5; //decrease 5% - if(bright<0){ bright = 0; } - LOS::setScreenBrightness(bright); - showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); - } - return; - }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){ - ActionID = QString(argv[i+1]); - i++; //skip the next input - }else if(QString(argv[i]).simplified()=="-terminal"){ - inFile = LXDG::findDefaultAppForMime("application/terminal"); - break; - }else{ - inFile = QString::fromLocal8Bit(argv[i]); +//Get the input file + //Make sure to load the proper system encoding first + LUtils::LoadTranslation(0,""); //bypass application modification +QString inFile, ActionID; +bool showDLG = false; //flag to bypass any default application setting +if(argc > 1){ + for(int i=1; i<argc; i++){ + if(QString(argv[i]).simplified() == "-select"){ + showDLG = true; + }else if(QString(argv[i]).simplified() == "-testcrash"){ +//Test the crash handler +binary = "internalcrashtest"; watch=true; +return; + }else if(QString(argv[i]).simplified() == "-autostart-apps"){ +LaunchAutoStart(); +return; + }else if(QString(argv[i]).simplified() == "-volumeup"){ +int vol = LOS::audioVolume()+5; //increase 5% +if(vol>100){ vol=100; } +LOS::setAudioVolume(vol); +showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); +return; + }else if(QString(argv[i]).simplified() == "-volumedown"){ +int vol = LOS::audioVolume()-5; //decrease 5% +if(vol<0){ vol=0; } +LOS::setAudioVolume(vol); +showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); +return; + }else if(QString(argv[i]).simplified() == "-brightnessup"){ +int bright = LOS::ScreenBrightness(); +if(bright > 0){ //brightness control available + bright = bright+5; //increase 5% + if(bright>100){ bright = 100; } + LOS::setScreenBrightness(bright); + showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); +} +return; + }else if(QString(argv[i]).simplified() == "-brightnessdown"){ +int bright = LOS::ScreenBrightness(); +if(bright > 0){ //brightness control available + bright = bright-5; //decrease 5% + if(bright<0){ bright = 0; } + LOS::setScreenBrightness(bright); + showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); +} +return; + }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){ + ActionID = QString(argv[i+1]); +i++; //skip the next input + }else if(QString(argv[i]).simplified()=="-terminal"){ + inFile = LXDG::findDefaultAppForMime("application/terminal"); + break; + }else{ + inFile = QString::fromLocal8Bit(argv[i]); break; } } @@ -268,14 +268,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat } switch(DF.type){ case XDGDesktop::APP: - qDebug() << "Found .desktop application:" << ActionID; + if(DEBUG) qDebug() << "Found .desktop application:" << ActionID; if(!DF.exec.isEmpty()){ cmd = DF.getDesktopExec(ActionID); - qDebug() << "Got command:" << cmd; + if(DEBUG) qDebug() << "Got command:" << cmd; if(!DF.path.isEmpty()){ path = DF.path; } - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) ); } break; case XDGDesktop::LINK: @@ -284,11 +284,11 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat inFile = DF.url; cmd.clear(); extension = inFile.section(":",0,0); - if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type + if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type extension.prepend("x-scheme-handler/"); - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) ); } break; case XDGDesktop::DIR: @@ -297,14 +297,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat inFile = DF.path; cmd.clear(); extension = "inode/directory"; - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) ); } break; default: - qDebug() << DF.type << DF.name << DF.icon << DF.exec; - ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) ); + if(DEBUG) qDebug() << DF.type << DF.name << DF.icon << DF.exec; + ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) ); } } if(cmd.isEmpty()){ @@ -344,7 +344,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat cmd.append(" \""+inFile+"\""); } } - qDebug() << "Found Command:" << cmd << "Extension:" << extension; + if(DEBUG) qDebug() << "Found Command:" << cmd << "Extension:" << extension; //Clean up any leftover "Exec" field codes (should have already been replaced earlier) if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); } binary = cmd; //pass this string to the calling function @@ -367,10 +367,10 @@ int main(int argc, char **argv){ QString bin = cmd.section(" ",0,0); if( !LUtils::isValidBinary(bin) ){ //invalid binary for some reason - open a dialog to warn the user instead - QMessageBox::warning(0, QObject::tr("Binary Missing"), QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd); + ShowErrorDialog(argc,argv, QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd); return 1; } - qDebug() << "[lumina-open] Running Cmd:" << cmd; + if(DEBUG) qDebug() << "[lumina-open] Running Cmd:" << cmd; int retcode = 0; //Provide an override file for never watching running processes. if(watch){ watch = !QFile::exists( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/nowatch" ); } @@ -391,12 +391,12 @@ int main(int argc, char **argv){ }else{ QProcess *p = new QProcess(); p->setProcessEnvironment(QProcessEnvironment::systemEnvironment()); - if(!path.isEmpty() && QFile::exists(path)){ + if(!path.isEmpty() && QFile::exists(path)){ //qDebug() << " - Setting working path:" << path; - p->setWorkingDirectory(path); + p->setWorkingDirectory(path); } p->start(cmd); - + //Now check up on it once every minute until it is finished while(!p->waitForFinished(60000)){ //qDebug() << "[lumina-open] process check:" << p->state(); @@ -410,19 +410,17 @@ int main(int argc, char **argv){ //qDebug() << "[lumina-open] Finished Cmd:" << cmd << retcode << p->exitStatus(); if( QFile::exists("/tmp/.luminastopping") ){ watch = false; } //closing down session - ignore "crashes" (app could have been killed during cleanup) if( (retcode < 0) && watch){ //-1 is used internally for crashed processes - most apps return >=0 - qDebug() << "[lumina-open] Application Error:" << retcode; - //Setup the application - QApplication App(argc, argv); - App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); - LUtils::LoadTranslation(&App,"lumina-open"); + //Setup the application + QApplication App(argc, argv); + App.setAttribute(Qt::AA_UseHighDpiPixmaps); + LUtils::LoadTranslation(&App,"lumina-open"); //App.setApplicationName("LuminaOpen"); - QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd ); - dlg.setWindowFlags(Qt::Window); - if(!log.isEmpty()){ dlg.setDetailedText(log); } - dlg.exec(); - } + QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd ); + dlg.setWindowFlags(Qt::Window); + if(!log.isEmpty()){ dlg.setDetailedText(log); } + dlg.exec(); + } } return retcode; } diff --git a/src-qt5/core/lumina-session/main.cpp b/src-qt5/core/lumina-session/main.cpp index 71244a8b..3b71bdca 100644 --- a/src-qt5/core/lumina-session/main.cpp +++ b/src-qt5/core/lumina-session/main.cpp @@ -55,14 +55,6 @@ int main(int argc, char ** argv) return QProcess::execute("xinit", args); } qDebug() << "Starting the Lumina desktop on current X11 session:" << disp; - //Setup any initialization values - LTHEME::LoadCustomEnvSettings(); - LXDG::setEnvironmentVars(); - setenv("DESKTOP_SESSION","Lumina",1); - setenv("XDG_CURRENT_DESKTOP","Lumina",1); - unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default... - //Check for any missing user config files - //Check for any stale desktop lock files and clean them up QString cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3"; @@ -81,14 +73,22 @@ int main(int argc, char ** argv) } //Configure X11 monitors if needed - if(LUtils::isValidBinary("lumina-xconfig")){ + if(LUtils::isValidBinary("lumina-xconfig")){ qDebug() << " - Resetting monitor configuration to last-used settings"; QProcess::execute("lumina-xconfig --reset-monitors"); } qDebug() << " - Starting the session..."; + //Setup any initialization values + LTHEME::LoadCustomEnvSettings(); + LXDG::setEnvironmentVars(); + setenv("DESKTOP_SESSION","Lumina",1); + setenv("XDG_CURRENT_DESKTOP","Lumina",1); + unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default... //Startup the session - QCoreApplication a(argc, argv); + QApplication a(argc, argv); + setenv("QP_QPA_PLATFORMTHEME","lthemeengine",1); //make sure this is after the QApplication - not actually using the theme plugin for **this** process LSession sess; + sess.checkFiles(); //Make sure user files are created/installed first sess.start(unified); int retCode = a.exec(); qDebug() << "Finished Closing Down Lumina"; diff --git a/src-qt5/core/lumina-session/session.cpp b/src-qt5/core/lumina-session/session.cpp index 3fdf9e66..743fc396 100644 --- a/src-qt5/core/lumina-session/session.cpp +++ b/src-qt5/core/lumina-session/session.cpp @@ -15,6 +15,7 @@ #include <LUtils.h> #include <LuminaOS.h> +#include <LDesktopUtils.h> void LSession::stopall(){ stopping = true; @@ -38,8 +39,12 @@ void LSession::procFinished(){ stopped++; if(!stopping){ //See if this process is the main desktop binary - if(PROCS[i]->objectName()=="runtime"){ stopall(); } - else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM + if(PROCS[i]->objectName()=="runtime"){ + qDebug() << "Got Desktop Process Finished:" << PROCS[i]->exitCode(); + //if(PROCS[i]->exitCode()==787){ PROCS[i]->start(QIODevice::ReadOnly); } //special internal restart code + //else{ + stopall(); //} + }else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM //if(PROCS[i]->program().section("/",-1) == "lumina-desktop"){ stopall(); } //start closing down everything //else{ PROCS[i]->start(QIODevice::ReadOnly); } //restart the process //break; @@ -164,3 +169,20 @@ void LSession::start(bool unified){ startProcess("runtime","lumina-desktop-unified"); } } + +void LSession::checkFiles(){ +//internal version conversion examples: + // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] + qDebug() << "[Lumina] Checking User Files"; + QSettings sset("lumina-desktop", "sessionsettings"); + QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String + qDebug() << " - Old Version:" << OVS; + qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion(); + bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion()); + qDebug() << " - Made Changes:" << changed; + if(changed){ + //Save the current version of the session to the settings file (for next time) + sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion()); + } + qDebug() << "Finished with user files check"; +} diff --git a/src-qt5/core/lumina-session/session.h b/src-qt5/core/lumina-session/session.h index 5cf1ccfa..3bbcbb8e 100644 --- a/src-qt5/core/lumina-session/session.h +++ b/src-qt5/core/lumina-session/session.h @@ -83,4 +83,6 @@ public: void start(bool unified = false); + void checkFiles(); + }; diff --git a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss index 265ff20c..d0c9b448 100644 --- a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss +++ b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss @@ -11,7 +11,7 @@ QScrollBar:vertical{ QScrollBar::handle{ background: palette(base); border: 1px solid transparent; - border-radius: 7px; + border-radius: 1px; } QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{ background: palette(highlight); diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss new file mode 100644 index 00000000..e8311e92 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss @@ -0,0 +1,70 @@ +/* SLIDERS */ +QSlider::groove:horizontal { +border: 1px solid transparent; +background: palette(alternate-window); +height: 10px; +border-radius: 3px; +} +QSlider::groove:vertical { +border: 1px solid transparent; +background: palette(alternate-window); +width: 10px; +border-radius: 3px; +} +QSlider::sub-page:horizontal { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::sub-page:vertical { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::add-page:horizontal{ +background: palette(alternate-window); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::add-page:vertical{ +background: palette(alternate-window); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::handle:horizontal{ +background: palette(mid); +border: 1px solid palette(mid); +width: 1em; +border-radius: 1px; +} +QSlider::handle:vertical{ +background: palette(mid); +border: 1px solid palette(mid); +height: 1em; +border-radius: 1px; +} +QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{ +border: 1px solid palette(highlight); +background: palette(highlight); +} + +QSlider::sub-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::add-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::handle:horizontal:disabled { +background: palette(alternate-window); +border: 1px solid palette(highlight); +} diff --git a/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss new file mode 100644 index 00000000..9bee3e08 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss @@ -0,0 +1,7 @@ +QToolTip{ + background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 palette(window), stop: 1 palette(alternate-window)); + border-radius: 3px; + border: 1px solid palette(highlight); + padding: 1px; + color: palette(text); +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp index d4544c7b..28a5e558 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp @@ -55,7 +55,7 @@ void MainWindow::on_buttonBox_clicked(QAbstractButton *button){ if(p) { p->writeSettings(); } } } - if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel){ + if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel || id== QDialogButtonBox::Close){ close(); qApp->quit(); } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui index dd676c37..0dc3245d 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui @@ -293,7 +293,7 @@ Styles</string> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set> </property> </widget> </item> diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp index cd88fb56..6377016c 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp @@ -31,6 +31,7 @@ QSSPage::QSSPage(QWidget *parent, bool desktop) : TabPage(parent), m_ui(new Ui:: m_ui->removeButton->setIcon(QIcon::fromTheme("edit-delete")); m_ui->tool_enable->setEnabled(false); m_ui->tool_disable->setEnabled(false); + m_ui->copyButton->setEnabled(false); } QSSPage::~QSSPage(){ @@ -56,6 +57,7 @@ void QSSPage::on_qssListWidget_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_disable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -76,6 +78,7 @@ void QSSPage::on_list_disabled_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_enable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -127,6 +130,36 @@ void QSSPage::on_editButton_clicked(){ } } +void QSSPage::on_copyButton_clicked(){ + QListWidgetItem *sel = currentSelection(); + if(sel==0){ return; } + QString name = QInputDialog::getText(this, tr("Enter Style Sheet Name"), tr("File name:"), QLineEdit::Normal, sel->text().section(".qss",0,0)+"_copy"); + if(name.isEmpty()){ return; } + if(!name.endsWith(".qss", Qt::CaseInsensitive)){ name.append(".qss"); } + QString filePath; + if(desktop_qss){ filePath = lthemeengine::userDesktopStyleSheetPath() + name; } + else{ filePath = lthemeengine::userStyleSheetPath() + name; } + if(QFile::exists(filePath)){ + QMessageBox::warning(this, tr("Error"), tr("The file \"%1\" already exists").arg(filePath)); + return; + } + // Make sure the directory exists + QString dir = filePath.section("/",0,-2); + if(!QFile::exists(dir)){ + QDir D(dir); + D.mkpath(dir); + } + //Copy the file over + QFile::copy(sel->data(QSS_FULL_PATH_ROLE).toString(), filePath); + //creating item + QFileInfo info(filePath); + QListWidgetItem *item = new QListWidgetItem(info.fileName(), m_ui->list_disabled); + item->setToolTip(info.filePath()); + item->setData(QSS_FULL_PATH_ROLE, info.filePath()); + item->setData(QSS_WRITABLE_ROLE, info.isWritable()); + m_ui->list_disabled->setCurrentRow(m_ui->list_disabled->count()-1); +} + void QSSPage::on_removeButton_clicked(){ QListWidgetItem *item = currentSelection(); if(!item){ return; } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h index 5b0025c5..07df4ac2 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h @@ -24,6 +24,7 @@ private slots: void on_qssListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_list_disabled_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_createButton_clicked(); + void on_copyButton_clicked(); void on_editButton_clicked(); void on_removeButton_clicked(); void on_renameButton_clicked(); diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui index f9a980f3..def99dd0 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui @@ -63,7 +63,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -168,7 +168,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -222,16 +222,41 @@ <property name="enabled"> <bool>true</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Create</string> </property> </widget> </item> <item> + <widget class="QToolButton" name="copyButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Copy</string> + </property> + </widget> + </item> + <item> <widget class="QPushButton" name="editButton"> <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Edit</string> </property> @@ -242,6 +267,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Rename</string> </property> @@ -252,6 +283,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Remove</string> </property> |