From 8ada7303ef98d97b0da1d8cd05c4ad32d43bb858 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 21 Sep 2017 13:45:33 -0400 Subject: Fix up the application of theme settings from the system config file. --- src-qt5/core/libLumina/LDesktopUtils.cpp | 13 ++------ src-qt5/core/libLumina/LuminaThemes.cpp | 56 +++++++++++++++++--------------- src-qt5/core/libLumina/LuminaThemes.h | 8 ++--- 3 files changed, 36 insertions(+), 41 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 54e660e6..9b7ee6d0 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -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::::] - 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[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[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[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,17 @@ 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); + 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); + 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 @@ -181,22 +183,22 @@ QString LTHEME::currentCursor(){ //Change the current Theme/Colors/Icons bool LTHEME::setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString 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 +301,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 Date: Thu, 21 Sep 2017 15:23:09 -0400 Subject: Oops - need to make sure that status function does not access any global QApplication instance. --- src-qt5/core/libLumina/LDesktopUtils.cpp | 4 ++-- src-qt5/core/libLumina/LDesktopUtils.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 9b7ee6d0..6c0543c0 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -456,12 +456,12 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } -bool LDesktopUtils::checkUserFiles(QString lastversion){ +bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ //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 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 -- cgit From 836dd026ae707965df8faf556debfde7a007b5d1 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 21 Sep 2017 16:04:22 -0400 Subject: Quick fix to ensure the status checkUserFiles function truly is static --- src-qt5/core/libLumina/LDesktopUtils.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 6c0543c0..a5c1bd77 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -481,7 +481,10 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ //Convert from the old desktop numbering system to the new one (change occured with 1.0.1) if(oldversion<=1000001){ QStringList DS = LUtils::readFile(dset); - QList screens = QApplication::screens(); + char *tmp; + int tmpN = 0; + QApplication A(tmpN, &tmp); + QList screens = A.screens(); for(int i=0; i Date: Thu, 21 Sep 2017 16:13:28 -0400 Subject: Urg - more fixes... --- src-qt5/core/libLumina/LDesktopUtils.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index a5c1bd77..262bf47b 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; iscreenCount(); i++){ if(desk->screenGeometry(i).x()==0){ screen = QString::number(i); @@ -479,7 +479,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ LDesktopUtils::upgradeFavorites(oldversion); } //Convert from the old desktop numbering system to the new one (change occured with 1.0.1) - if(oldversion<=1000001){ + /*if(oldversion<=1000001){ QStringList DS = LUtils::readFile(dset); char *tmp; int tmpN = 0; @@ -505,7 +505,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ } } LUtils::writeFile(dset, DS, true); - } + }*/ //Check the fluxbox configuration files dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; -- cgit From a27815312eaac620881d67e8776c743595975b38 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 21 Sep 2017 16:15:49 -0400 Subject: Final fix - re-enable some backwards-compatible code and put a big warning at the top of the function --- src-qt5/core/libLumina/LDesktopUtils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 262bf47b..fb13a2a3 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -457,6 +457,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } 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 @@ -479,7 +481,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ LDesktopUtils::upgradeFavorites(oldversion); } //Convert from the old desktop numbering system to the new one (change occured with 1.0.1) - /*if(oldversion<=1000001){ + if(oldversion<=1000001){ QStringList DS = LUtils::readFile(dset); char *tmp; int tmpN = 0; @@ -505,7 +507,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ } } LUtils::writeFile(dset, DS, true); - }*/ + } //Check the fluxbox configuration files dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; -- cgit From 711b219a001d0c4fdd61367903696fa1c6ff1a3d Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Tue, 3 Oct 2017 15:24:26 -0400 Subject: Added experimental video thumbnails in lumina-fm and fileinfo --- src-qt5/core/libLumina/LVideoSurface.cpp | 32 ++++++++++++++++++++++++++++++++ src-qt5/core/libLumina/LVideoSurface.h | 20 ++++++++++++++++++++ src-qt5/core/libLumina/LVideoSurface.pri | 9 +++++++++ 3 files changed, 61 insertions(+) create mode 100644 src-qt5/core/libLumina/LVideoSurface.cpp create mode 100644 src-qt5/core/libLumina/LVideoSurface.h create mode 100644 src-qt5/core/libLumina/LVideoSurface.pri (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp new file mode 100644 index 00000000..6adec5d2 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -0,0 +1,32 @@ +#include "LVideoSurface.h" +#include + +LVideoSurface::LVideoSurface() : QAbstractVideoSurface() { + recording = 0; + frameImage = QImage(); +} + +QImage LVideoSurface::currentFrame() { + return frameImage; +} + +bool LVideoSurface::present(const QVideoFrame &frame) { + if(frame.isValid()) { + qDebug() << "Recording Frame" << frame.pixelFormat(); + QVideoFrame icon(frame); + icon.map(QAbstractVideoBuffer::ReadOnly); + frameImage = QImage(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QImage::Format_ARGB32_Premultiplied); + icon.unmap(); + emit frameReceived(frameImage); + if(recording++ == 2) ready = true; + return true; + } + ready = false; + return false; +} + +QList LVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const { + Q_UNUSED(type); + return QList() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; +} diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h new file mode 100644 index 00000000..adb4611d --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -0,0 +1,20 @@ +#include +#include +#include + +class LVideoSurface : public QAbstractVideoSurface { + Q_OBJECT + + public: + LVideoSurface(); + virtual bool present(const QVideoFrame&); + virtual QList supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; + QImage currentFrame(); + bool frameReady(); + signals: + void frameReceived(QImage); + private: + int recording; + QImage frameImage; + bool ready; +}; 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) -- cgit From 3005f7ab6b19cabf423b85ec7c3845d840c7cb18 Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Tue, 3 Oct 2017 18:36:51 -0400 Subject: Reworked the VideoSurface subclass --- src-qt5/core/libLumina/LVideoSurface.cpp | 46 +++++++++++++++++++++++++------- src-qt5/core/libLumina/LVideoSurface.h | 15 ++++++----- 2 files changed, 44 insertions(+), 17 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp index 6adec5d2..895a3a32 100644 --- a/src-qt5/core/libLumina/LVideoSurface.cpp +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -1,27 +1,29 @@ #include "LVideoSurface.h" #include -LVideoSurface::LVideoSurface() : QAbstractVideoSurface() { - recording = 0; - frameImage = QImage(); -} - -QImage LVideoSurface::currentFrame() { - return frameImage; +LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { + frameImage = QPixmap(); } bool LVideoSurface::present(const QVideoFrame &frame) { + if(!frameImage.isNull()) { + emit frameReceived(frameImage); + return true; + } + if(frame.isValid()) { qDebug() << "Recording Frame" << frame.pixelFormat(); QVideoFrame icon(frame); icon.map(QAbstractVideoBuffer::ReadOnly); - frameImage = QImage(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QImage::Format_ARGB32_Premultiplied); + QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); + + if(frameImage.isNull()) + frameImage = QPixmap::fromImage(img.copy(img.rect())); + icon.unmap(); emit frameReceived(frameImage); - if(recording++ == 2) ready = true; return true; } - ready = false; return false; } @@ -30,3 +32,27 @@ QList LVideoSurface::supportedPixelFormats(QAbstractVi return QList() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; } + +/*bool VideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + return imageFormat != QImage::Format_Invalid && !size.isEmpty() && format.handleType() == QAbstractVideoBuffer::NoHandle; +} + +void VideoSurface::stop() { + QAbstractVideoSurface::stop(); +} + +bool VideoSurface::start(const QVideoSurfaceFormat &format) { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) { + this->imageFormat = imageFormat; + QAbstractVideoSurface::start(format); + return true; + } else { + return false; + } +}*/ diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h index adb4611d..42a140d9 100644 --- a/src-qt5/core/libLumina/LVideoSurface.h +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -1,20 +1,21 @@ #include #include +#include #include class LVideoSurface : public QAbstractVideoSurface { Q_OBJECT public: - LVideoSurface(); + LVideoSurface(QObject *parent=0); virtual bool present(const QVideoFrame&); virtual QList supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; - QImage currentFrame(); - bool frameReady(); + /*virtual QList Date: Thu, 5 Oct 2017 17:06:58 -0400 Subject: Finished video thumnails for lumina-fm and lumina-fileinfo --- src-qt5/core/libLumina/LVideoSurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp index 895a3a32..bd6b2c95 100644 --- a/src-qt5/core/libLumina/LVideoSurface.cpp +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -12,7 +12,7 @@ bool LVideoSurface::present(const QVideoFrame &frame) { } if(frame.isValid()) { - qDebug() << "Recording Frame" << frame.pixelFormat(); + //qDebug() << "Recording Frame" << frame.pixelFormat(); QVideoFrame icon(frame); icon.map(QAbstractVideoBuffer::ReadOnly); QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); -- cgit From f649d4976e64cfdf9b32022d55bfd08f39d00a8f Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Wed, 11 Oct 2017 20:51:56 -0400 Subject: Added framework to play video when the mouse is put over them. Breaks picture and video preview for lumina-fileinfo currently --- src-qt5/core/libLumina/LVideoLabel.cpp | 61 ++++++++++++++++++++++++++++++++ src-qt5/core/libLumina/LVideoLabel.h | 30 ++++++++++++++++ src-qt5/core/libLumina/LVideoLabel.pri | 8 +++++ src-qt5/core/libLumina/LVideoSurface.cpp | 23 ++++++------ src-qt5/core/libLumina/LVideoSurface.h | 11 ++++-- 5 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 src-qt5/core/libLumina/LVideoLabel.cpp create mode 100644 src-qt5/core/libLumina/LVideoLabel.h create mode 100644 src-qt5/core/libLumina/LVideoLabel.pri (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp new file mode 100644 index 00000000..20b2cad4 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -0,0 +1,61 @@ +#include "LVideoLabel.h" + +LVideoLabel::LVideoLabel(QString file, bool video) : QLabel(){ + this->setScaledContents(true); + if(video) { + mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + thumbnail = QPixmap(); + entered = false; + surface = new LVideoSurface(this); + mediaPlayer->setVideoOutput(surface); + mediaPlayer->setMedia(QUrl("file://" + file)); + mediaPlayer->setPlaybackRate(3); + mediaPlayer->setMuted(true); + mediaPlayer->play(); + mediaPlayer->pause(); + this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); + this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); + this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); + }else{ + thumbnail = QPixmap(file); + this->setPixmap(thumbnail); + } +} + +LVideoLabel::~LVideoLabel() { + mediaPlayer->deleteLater(); + surface->deleteLater(); +} + +void LVideoLabel::stopVideo(QPixmap pix) { + if(!entered) { + if(thumbnail.isNull()) + thumbnail = QPixmap(pix.scaledToHeight(64)); + this->setPixmap(thumbnail); + mediaPlayer->pause(); + }else { + this->setPixmap(QPixmap(pix.scaledToHeight(64))); + } +} + +void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { + if(status == QMediaPlayer::BufferedMedia) { + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + mediaPlayer->play(); + } +} + +void LVideoLabel::enterEvent(QEvent *event) { + entered=true; + emit rollOver(); + mediaPlayer->setPosition(0); + mediaPlayer->play(); + QLabel::enterEvent(event); +} + +void LVideoLabel::leaveEvent(QEvent *event) { + entered=false; + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + emit rollOver(); + QLabel::leaveEvent(event); +} diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h new file mode 100644 index 00000000..fd293200 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -0,0 +1,30 @@ +#ifndef LVIDEOLABEL_H +#define LVIDEOLABEL_H + +#include +#include +#include "LVideoSurface.h" + +//class LVideoSurface; + +class LVideoLabel : public QLabel { + Q_OBJECT + public: + LVideoLabel(QString, bool); + ~LVideoLabel(); + protected: + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + signals: + void rollOver(); + public slots: + void stopVideo(QPixmap); + void setDuration(QMediaPlayer::MediaStatus); + private: + QMediaPlayer *mediaPlayer; + LVideoSurface *surface; + QVideoWidget *videoPlayer; + QPixmap thumbnail; + bool entered; +}; +#endif diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri new file mode 100644 index 00000000..f609df08 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.pri @@ -0,0 +1,8 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoLabel.h +SOURCES *= $${PWD}/LVideoLabel.cpp + +INCLUDEPATH *= ${PWD} + +include(LVideoSurface.pri) diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp index bd6b2c95..e3e87667 100644 --- a/src-qt5/core/libLumina/LVideoSurface.cpp +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -3,10 +3,12 @@ LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { frameImage = QPixmap(); + entered = false; } bool LVideoSurface::present(const QVideoFrame &frame) { - if(!frameImage.isNull()) { + //qDebug() << surfaceFormat().pixelFormat() << frame.pixelFormat() << surfaceFormat().frameSize() << frame.size(); + if(!frameImage.isNull() && !entered) { emit frameReceived(frameImage); return true; } @@ -15,9 +17,10 @@ bool LVideoSurface::present(const QVideoFrame &frame) { //qDebug() << "Recording Frame" << frame.pixelFormat(); QVideoFrame icon(frame); icon.map(QAbstractVideoBuffer::ReadOnly); + //qDebug() << icon.width() << icon.height(); QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); - if(frameImage.isNull()) + if((frameImage.isNull() && !entered) or entered) frameImage = QPixmap::fromImage(img.copy(img.rect())); icon.unmap(); @@ -33,26 +36,22 @@ QList LVideoSurface::supportedPixelFormats(QAbstractVi << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; } -/*bool VideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const { - const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); - const QSize size = format.frameSize(); - - return imageFormat != QImage::Format_Invalid && !size.isEmpty() && format.handleType() == QAbstractVideoBuffer::NoHandle; +void LVideoSurface::stop() { + QAbstractVideoSurface::stop(); } -void VideoSurface::stop() { - QAbstractVideoSurface::stop(); +void LVideoSurface::switchRollOver() { + entered = !entered; } -bool VideoSurface::start(const QVideoSurfaceFormat &format) { +bool LVideoSurface::start(const QVideoSurfaceFormat &format) { const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); const QSize size = format.frameSize(); if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) { - this->imageFormat = imageFormat; QAbstractVideoSurface::start(format); return true; } else { return false; } -}*/ +} diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h index 42a140d9..7a3dcaad 100644 --- a/src-qt5/core/libLumina/LVideoSurface.h +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -1,3 +1,6 @@ +#ifndef LVIDEOSURFACE_H +#define LVIDEOSURFACE_H + #include #include #include @@ -10,12 +13,14 @@ class LVideoSurface : public QAbstractVideoSurface { LVideoSurface(QObject *parent=0); virtual bool present(const QVideoFrame&); virtual QList supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; - /*virtual QList Date: Fri, 13 Oct 2017 16:25:18 -0400 Subject: Another checkpoint commit for Lumina 2 Almost have the QML-based desktop canvas working - still tracking down some QML syntax issues. --- src-qt5/core/libLumina/LDesktopUtils.pri | 1 + src-qt5/core/libLumina/NativeEmbedWidget.cpp | 423 --------- src-qt5/core/libLumina/NativeEmbedWidget.h | 74 -- src-qt5/core/libLumina/NativeEventFilter.cpp | 300 ------- src-qt5/core/libLumina/NativeEventFilter.h | 71 -- src-qt5/core/libLumina/NativeKeyToQt.cpp | 528 ----------- src-qt5/core/libLumina/NativeWindow.cpp | 123 --- src-qt5/core/libLumina/NativeWindow.h | 118 --- src-qt5/core/libLumina/NativeWindow.pri | 18 - src-qt5/core/libLumina/NativeWindowSystem.cpp | 986 --------------------- src-qt5/core/libLumina/NativeWindowSystem.h | 139 --- .../core/libLumina/RootSubWindow-animations.cpp | 116 --- src-qt5/core/libLumina/RootSubWindow.cpp | 601 ------------- src-qt5/core/libLumina/RootSubWindow.h | 109 --- src-qt5/core/libLumina/RootWindow-mgmt.cpp | 95 -- src-qt5/core/libLumina/RootWindow.cpp | 283 ------ src-qt5/core/libLumina/RootWindow.h | 92 -- src-qt5/core/libLumina/RootWindow.pri | 17 - .../obsolete/RootSubWindow-animations.cpp | 116 +++ src-qt5/core/libLumina/obsolete/RootSubWindow.cpp | 601 +++++++++++++ src-qt5/core/libLumina/obsolete/RootSubWindow.h | 109 +++ .../core/libLumina/obsolete/RootWindow-mgmt.cpp | 95 ++ src-qt5/core/libLumina/obsolete/RootWindow.cpp | 283 ++++++ src-qt5/core/libLumina/obsolete/RootWindow.h | 92 ++ src-qt5/core/libLumina/obsolete/RootWindow.pri | 17 + 25 files changed, 1314 insertions(+), 4093 deletions(-) delete mode 100644 src-qt5/core/libLumina/NativeEmbedWidget.cpp delete mode 100644 src-qt5/core/libLumina/NativeEmbedWidget.h delete mode 100644 src-qt5/core/libLumina/NativeEventFilter.cpp delete mode 100644 src-qt5/core/libLumina/NativeEventFilter.h delete mode 100644 src-qt5/core/libLumina/NativeKeyToQt.cpp delete mode 100644 src-qt5/core/libLumina/NativeWindow.cpp delete mode 100644 src-qt5/core/libLumina/NativeWindow.h delete mode 100644 src-qt5/core/libLumina/NativeWindow.pri delete mode 100644 src-qt5/core/libLumina/NativeWindowSystem.cpp delete mode 100644 src-qt5/core/libLumina/NativeWindowSystem.h delete mode 100644 src-qt5/core/libLumina/RootSubWindow-animations.cpp delete mode 100644 src-qt5/core/libLumina/RootSubWindow.cpp delete mode 100644 src-qt5/core/libLumina/RootSubWindow.h delete mode 100644 src-qt5/core/libLumina/RootWindow-mgmt.cpp delete mode 100644 src-qt5/core/libLumina/RootWindow.cpp delete mode 100644 src-qt5/core/libLumina/RootWindow.h delete mode 100644 src-qt5/core/libLumina/RootWindow.pri create mode 100644 src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp create mode 100644 src-qt5/core/libLumina/obsolete/RootSubWindow.cpp create mode 100644 src-qt5/core/libLumina/obsolete/RootSubWindow.h create mode 100644 src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp create mode 100644 src-qt5/core/libLumina/obsolete/RootWindow.cpp create mode 100644 src-qt5/core/libLumina/obsolete/RootWindow.h create mode 100644 src-qt5/core/libLumina/obsolete/RootWindow.pri (limited to 'src-qt5/core/libLumina') 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/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 -#include -#include -#include -#include - -#include -#include -#include -#include -//#include -//#include -#include -#include - -#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 screens = static_cast( QApplication::instance() )->screens(); - //for(int i=0; icontains(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(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 -#include -#include -#include -#include -#include -#include - -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 -#include - -//#include -//#include - -//================================================== -// 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 -#include -#include -#include -#include - -#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::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(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::GlobalPos << NativeWindow::Size, - QList() << 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::GlobalPos << NativeWindow::Size, - QList() << 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 -#include -#include - -#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); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); - void WindowPropertiesChanged(WId, QList, QList); - void RequestWindowPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestWindowPropertiesChange(WId, QList, QList); - - //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 - -#include -#include - -// 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 -#include - - -//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 - -// === 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 >(); } - else if(prop == NativeWindow::None || (!force && hash.value(prop)==val)){ return; } - else{ hash.insert(prop, val); } - emit PropertiesChanged(QList() << prop, QList() << val); -} - -void NativeWindow::setProperties(QList props, QList vals, bool force){ - for(int i=0; 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() << prop, QList() << val); -} - -void NativeWindow::requestProperties(QList props, QList vals, bool force){ - //Verify/adjust inputs as needed - for(int i=0; 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() << props[i], QList() << 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 frame = hash.value(NativeWindow::FrameExtents).value< QList >(); //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 -#include -#include -#include -#include -#include -#include - -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 : Current state of the window */ - WinTypes=11, /*QList : Current type of window (typically does not change)*/ - WinActions=12, /*QList : Current actions that the window allows (Managed/set by the WM)*/ - FrameExtents=13, /*QList : [Left, Right, Top, Bottom] in pixels */ - RelatedWindows=14, /* QList - better to use the "isRelatedTo(WId)" function instead of reading this directly*/ - Active=15, /*bool*/ - Visible=16 /*bool*/ - }; - - static QList allProperties(){ - //Return all the available properties (excluding "None" and "FrameExtents" (WM control only) ) - QList 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, QList, bool force = false); - void requestProperty(NativeWindow::Property, QVariant, bool force = false); - void requestProperties(QList, QList, 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 hash; - //QWindow *WIN; - WId winid, frameid; - QList relatedTo; - unsigned int dmgID; - -signals: - //General Notifications - void PropertiesChanged(QList, QList); - void RequestPropertiesChange(WId, QList, QList); - 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 -#include -#include -#include -#include -#include -#include - - -//XCB Library includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//XLib includes (XCB Damage lib does not appear to register for damage events properly) -#include - -//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 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 reply; - for(int i=0; iatom); - 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; iid() ){ 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; iisRelatedTo(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 scrnlist = QApplication::screens(); - //Try to grab the given window directly with Qt - for(int i=0; igrabWindow(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; isetProperty(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: "::::" - 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() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); - } - if(props.contains(NativeWindow::RelatedWindows)){ - WId orig = win->id(); - WId tid = obj->getTransientFor(orig); - QList 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; iEWMH._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 >(types) ); - } -} - -void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList 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; iEWMH, 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 list, bool stackorder){ - //convert the QList into a generic array - xcb_window_t array[list.length()]; - for(int i=0; iEWMH, 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 list){ - //Convert to the XCB/EWMH data structures - xcb_ewmh_geometry_t array[list.length()]; - for(int i=0; iEWMH, 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, QList)), this, SLOT(RequestPropertiesChange(WId, QList, QList)) ); - 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() << 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() << prop); - } - } -} - -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList 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; isetProperty(prop, val); - } -} - -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList props, QList vals){ - NativeWindow *win = findWindow(id); - if(win==0){ win = findTrayWindow(id); } - if(win!=0){ - for(int i=0; isetProperty(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() << prop, QList() << val); -} - -void NativeWindowSystem::RequestPropertiesChange(WId win, QList props, QList 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; idamageId() == 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::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 -#include -#include - -class NativeWindowSystem : public QObject{ - Q_OBJECT -private: - QList NWindows; - QList 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 waitingForPong; - void checkPings(){ - QDateTime cur = QDateTime::currentDateTime(); - QList waiting = waitingForPong.keys(); - for(int i=0; istop(); } - 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 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 currentWindows(){ return NWindows; } - QList 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, bool stackorder = false); - void setRoot_desktopGeometry(QRect); - void setRoot_desktopWorkarea(QList); - 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); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //will save that property/value to the right object - void WindowPropertiesChanged(WId, QList, QList); - void RequestPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestPropertiesChange(WId, QList, QList); - 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/RootSubWindow-animations.cpp deleted file mode 100644 index efab20fe..00000000 --- a/src-qt5/core/libLumina/RootSubWindow-animations.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//=========================================== -// Lumina Desktop source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "RootSubWindow.h" -#include - -QStringList RootSubWindow::validAnimations(NativeWindow::Property prop){ - QStringList valid; - if(prop == NativeWindow::Visible){ - valid << "zoom" << "wipe-center-vertical" << "wipe-center-horizontal" << "shade-top" << "shade-right" << "shade-left" << "shade-bottom"; - }else if(prop == NativeWindow::Size){ - //Note: this is used for pretty much all geometry changes to the window where it is visible both before/after animation - valid << "direct"; - } - return valid; -} - -void RootSubWindow::loadAnimation(QString name, NativeWindow::Property prop, QVariant nval){ - if(anim->state()==QAbstractAnimation::Running){ return; } //already running - animResetProp.clear(); - //Special case - random animation each time - if(name=="random"){ - QStringList valid = validAnimations(prop); - if(!valid.isEmpty()){ name = valid.at(qrand()%valid.length()); } - } - //Now setup the animation - if(prop == NativeWindow::Visible){ - //NOTE: Assigns values for "invisible->visible" animation: will reverse it afterwards as needed - anim->setPropertyName("geometry"); - QRect geom = this->geometry(); - if(name == "zoom"){ - //Zoom to/from the center point - anim->setStartValue( QRect(geom.center(), QSize(0,0)) ); - anim->setEndValue(geom); - }else if(name == "wipe-center-vertical"){ - anim->setStartValue( QRect( geom.center().x(), geom.y(), 0, geom.height()) ); - anim->setEndValue( geom ); - }else if(name == "wipe-center-horizontal"){ - anim->setStartValue( QRect( geom.x(), geom.center().y(), geom.width(), 0) ); - anim->setEndValue( geom ); - }else if(name == "shade-top"){ - anim->setStartValue( QRect( geom.x(), geom.y(), geom.width(), 0) ); - anim->setEndValue( geom ); - }else if(name == "shade-bottom"){ - anim->setStartValue( QRect( geom.x(), geom.y()+geom.height(), geom.width(), 0) ); - anim->setEndValue( geom ); - }else if(name == "shade-left"){ - anim->setStartValue( QRect( geom.x(), geom.y(), 0, geom.height()) ); - anim->setEndValue( geom ); - }else if(name == "shade-right"){ - anim->setStartValue( QRect( geom.x()+geom.width(), geom.y(), 0, geom.height()) ); - anim->setEndValue( geom ); - }else{ - //Invalid/None animation - if(nval.toBool()){ this->show(); } - else{ this->hide(); } - return; - } - if(nval.toBool()){ - this->setGeometry( anim->startValue().toRect() ); //ensure the window is the initial geom before it becomes visible - //QTimer::singleShot( anim->duration()+5, this, SLOT(activate()) ); - }else{ - QVariant tmp = anim->startValue(); - anim->setStartValue(anim->endValue()); - anim->setEndValue(tmp); - animResetProp = anim->startValue(); - QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); - } - WinWidget->pause(); - anim->start(); - this->show(); - } //end of Visibility animation - else if(prop == NativeWindow::Size){ - //This is pretty much all geometry animations where the window is visible->visible - anim->setPropertyName("geometry"); - anim->setStartValue(this->geometry()); - anim->setEndValue(nval.toRect()); - /*if(name==""){ - // TO-DO modify the path from beginning->end somehow - }*/ - // Now start the animation - WinWidget->pause(); - anim->start(); - this->show(); - } -} - -void RootSubWindow::animFinished(){ - if(closing){ this->close(); return;} - else if(anim->propertyName()=="geometry"){ - if(!animResetProp.isNull()){ - /*qDebug() << "Animation Finished, Reset Geometry:" << animResetProp.toRect(); - qDebug() << " - Starting Value:" << anim->startValue().toRect(); - qDebug() << " - Ending Value:" << anim->endValue().toRect();*/ - this->setGeometry( animResetProp.toRect() ); - //Also ensure that the proper geometry is saved to the window structure - QRect curg = this->geometry(); - QRect wing = WIN->geometry(); - //qDebug() << " - After Animation Reset:" << curg << wing; - if(curg!=wing){ - QRect clientg = clientGlobalGeom(); - //qDebug() << "Sub Window geometry:" << clientg; - WIN->setProperties(QList< NativeWindow::Property>() << NativeWindow::Size << NativeWindow::GlobalPos, - QList() << clientg.size() << clientg.topLeft() ); - } - } - WinWidget->resyncWindow(); //also let the window know about the current geometry - } - animResetProp = QVariant(); //clear the variable - //QTimer::singleShot(10, WinWidget, SLOT(resume()) ); - WinWidget->resume(); - emit windowAnimFinished(); -} diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp deleted file mode 100644 index 5040f2f9..00000000 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ /dev/null @@ -1,601 +0,0 @@ -//=========================================== -// Lumina Desktop source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "RootSubWindow.h" -#include -#include -#include -#include -#include -#include - -#define WIN_BORDER 5 - -#include -#include - -// === PUBLIC === -RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ - this->setAttribute(Qt::WA_DeleteOnClose); - this->setMouseTracking(true); - //Create the QWindow and QWidget containers for the window - WIN = win; - closing = false; - initWindowFrame(); - //Hookup the signals/slots - connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); - WinWidget->embedWindow(WIN); - //qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); - activeState = RootSubWindow::Normal; - LoadAllProperties(); -} - -RootSubWindow::~RootSubWindow(){ - //qDebug() << "Visible Window Destroyed"; - WIN->deleteLater(); -} - -WId RootSubWindow::id(){ - return WIN->id(); -} - -NativeWindow* RootSubWindow::nativeWindow(){ - return WIN; -} - -// === PRIVATE === -RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset){ - //Note: pt should be in widget-relative coordinates, not global - if(!WinWidget->geometry().contains(pt) && !titleBar->geometry().contains(pt)){ - //above the frame itself - need to figure out which quadrant it is in (8-directions) - if(pt.y() < WIN_BORDER){ - //One of the top options - if(pt.x() < this->width()/5){ - if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner - return ResizeTopLeft; - }else if(pt.x() > (this->width()*4.0/5.0)){ - if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()); } //difference from top-right corner - return ResizeTopRight; - }else{ - if(setoffset){ offset.setX(0); offset.setY(pt.y()); } //difference from top edge (X does not matter) - return ResizeTop; - } - }else if(pt.y() > (this->height()-WIN_BORDER) ){ - //One of the bottom options - if(pt.x() < this->width()/5){ - if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()-this->height()); } //difference from bottom-left corner - return ResizeBottomLeft; - }else if(pt.x() > (this->width()*4.0/5.0)){ - if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()-this->height()); } //difference from bottom-right corner - return ResizeBottomRight; - }else{ - if(setoffset){ offset.setX(0); offset.setY(pt.y()-this->height()); } //difference from bottom edge (X does not matter) - return ResizeBottom; - } - }else if(pt.x() < WIN_BORDER){ - //Left side options - if(pt.y() < this->height()/5){ - if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner - return ResizeTopLeft; - }else if(pt.y() > (this->height()*4.0/5.0)){ - if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()-this->height()); } //difference from bottom-left corner - return ResizeBottomLeft; - }else{ - if(setoffset){ offset.setX(pt.x()); offset.setY(0); } //difference from left edge (Y does not matter) - return ResizeLeft; - } - }else if(pt.x() > (this->width()-WIN_BORDER) ){ - //Right side options - if(pt.y() < this->height()/5){ - if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()); } //difference from top-right corner - return ResizeTopRight; - }else if(pt.y() > (this->height()*4.0/5.0)){ - if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()-this->height()); } //difference from bottom-right corner - return ResizeBottomRight; - }else{ - if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(0); } //difference from right edge (Y does not matter) - return ResizeRight; - } - }else{ - return Normal; - } - } - //if it gets this far just return normal - return Normal; -} - -void RootSubWindow::setMouseCursor(ModState state, bool override){ - if(currentCursor==state && !override){ return; } //nothing to change - Qt::CursorShape shape; - switch(state){ - case Normal: - shape = Qt::ArrowCursor; - break; - case Move: - shape = Qt::SizeAllCursor; - break; - case ResizeTop: - shape = Qt::SizeVerCursor; - break; - case ResizeTopRight: - shape = Qt::SizeBDiagCursor; - break; - case ResizeRight: - shape = Qt::SizeHorCursor; - break; - case ResizeBottomRight: - shape = Qt::SizeFDiagCursor; - break; - case ResizeBottom: - shape = Qt::SizeVerCursor; - break; - case ResizeBottomLeft: - shape = Qt::SizeBDiagCursor; - break; - case ResizeLeft: - shape = Qt::SizeHorCursor; - break; - case ResizeTopLeft: - shape = Qt::SizeFDiagCursor; - break; - } - if(override){ - QApplication::setOverrideCursor(QCursor(shape)); - }else{ - currentCursor = state; - this->setCursor(shape); - } -} - -void RootSubWindow::initWindowFrame(){ - //qDebug() << "Create RootSubWindow Frame"; - this->setContentsMargins(0,0,0,0); - mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(0,0,0,0); - titleBar = new QWidget(this); - titleBar->setContentsMargins(0,0,0,0); - titleBarL = new QHBoxLayout(titleBar); - titleBarL->setContentsMargins(0,0,0,0); - closeB = new QToolButton(this); - maxB = new QToolButton(this); - minB = new QToolButton(this); - otherB = new QToolButton(this); - anim = new QPropertyAnimation(this); - anim->setTargetObject(this); - anim->setDuration(200); //1/5 second (appx) - connect(anim, SIGNAL(finished()), this, SLOT(animFinished()) ); - titleLabel = new QLabel(this); - titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - otherM = new QMenu(this); //menu of other actions - otherB->setMenu(otherM); - otherB->setPopupMode(QToolButton::InstantPopup); - otherB->setAutoRaise(true); - WinWidget = new NativeEmbedWidget(this); - connect(closeB, SIGNAL(clicked()), this, SLOT(triggerClose()) ); - connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); - connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); - //Now assemble the frame layout based on the current settings - titleBarL->addWidget(otherB); - titleBarL->addWidget(titleLabel); - titleBarL->addWidget(minB); - titleBarL->addWidget(maxB); - titleBarL->addWidget(closeB); - WinWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - titleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - mainLayout->addWidget(titleBar); - mainLayout->addWidget(WinWidget); - mainLayout->setAlignment(titleBar, Qt::AlignTop); - //Setup the cursors for the buttons - closeB->setCursor(Qt::ArrowCursor); - minB->setCursor(Qt::ArrowCursor); - maxB->setCursor(Qt::ArrowCursor); - otherB->setCursor(Qt::ArrowCursor); - titleLabel->setCursor(Qt::ArrowCursor); - WinWidget->setCursor(Qt::ArrowCursor); - //Now all the stylesheet options - this->setObjectName("WindowFrame"); - closeB->setObjectName("Button_Close"); - minB->setObjectName("Button_Minimize"); - maxB->setObjectName("Button_Maximize"); - otherM->setObjectName("Menu_Actions"); - titleLabel->setObjectName("Label_Title"); - this->setStyleSheet("QFrame#WindowFrame{background-color: rgba(0,0,0,125)} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; border-radius: 3px; } QToolButton::hover{background-color: rgba(255,255,255,150); } QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); - //And adjust the margins - mainLayout->setSpacing(0); - titleBarL->setSpacing(1); - this->setFrameStyle(QFrame::NoFrame); - this->setLineWidth(0); - this->setMidLineWidth(0); - this->setFrameRect(QRect(0,0,0,0)); - - //Setup the timer object to syncronize info - moveTimer = new QTimer(this); - moveTimer->setSingleShot(true); - moveTimer->setInterval(100); //1/10 second - connect(moveTimer, SIGNAL(timeout()), WinWidget, SLOT(resyncWindow()) ); - - //Now load the icons for the button - LIconCache::instance()->loadIcon(closeB, "window-close"); - LIconCache::instance()->loadIcon(maxB, "window-maximize"); - LIconCache::instance()->loadIcon(minB, "window-minimize"); - LIconCache::instance()->loadIcon(otherB, "list"); -} - -void RootSubWindow::enableFrame(bool on){ - //Make the individual frame elements visible as needed - if(on){ this->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); }//default border - else{ this->setContentsMargins(0, 0, 0, 0); } - titleBar->setVisible(on); - //And now calculate/save the frame extents - QList extents; extents << 0 << 0 << 0 << 0; //left, right, top, bottom - if(on){ - extents[0] = WIN_BORDER; - extents[1] = WIN_BORDER; - extents[2] = WIN_BORDER + titleBar->height(); - extents[3] = WIN_BORDER; - } - //qDebug() << "SET FRAME EXTENTS:" << extents; - WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save on raw window itself - WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save to structure now -} - -void RootSubWindow::enableFrame(QList types){ - static QList noframe; - if(noframe.isEmpty()){ noframe << NativeWindow::T_DESKTOP << NativeWindow::T_DOCK << NativeWindow::T_TOOLBAR << NativeWindow::T_MENU << NativeWindow::T_SPLASH << NativeWindow::T_DROPDOWN_MENU << NativeWindow::T_POPUP_MENU << NativeWindow::T_TOOLTIP << NativeWindow::T_NOTIFICATION << NativeWindow::T_COMBO << NativeWindow::T_DND; } - for(int i=0; i list){ - QList vals; - //Always ensure that visibility changes are evaluated last - bool addvisible = false; - for(int i=0; iproperty(list[i]); - } - //if(addvisible){ list << NativeWindow::Visible; vals << WIN->property(NativeWindow::Visible); } - propertiesChanged(list, vals); -} - -QRect RootSubWindow::clientGlobalGeom(){ - QRect tot = this->geometry(); - QList frame = WIN->property(NativeWindow::FrameExtents).value< QList >(); - //Now adjust this to take out the frame - tot.adjust(frame[0], frame[2], -frame[1], -frame[3]); - return tot; -} - -// === PUBLIC SLOTS === -void RootSubWindow::clientClosed(){ - //qDebug() << "Client Closed"; - closing = true; - if(anim->state()!=QAbstractAnimation::Running){ this->close(); } -} - -void RootSubWindow::LoadAllProperties(){ - QList< NativeWindow::Property> list; - list << NativeWindow::WinTypes << NativeWindow::WinActions << NativeWindow::States - << NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Title << NativeWindow::ShortTitle - << NativeWindow::Icon << NativeWindow::Size << NativeWindow::GlobalPos;// << NativeWindow::Visible << NativeWindow::Active; - LoadProperties(list); - //WIN->requestProperty(NativeWindow::Visible, true); -} - -//Button Actions - public so they can be tied to key shortcuts and stuff as well -void RootSubWindow::toggleMinimize(){ - WIN->toggleVisibility(); -} - -void RootSubWindow::toggleMaximize(){ - //Get the current screen that this window is on - QList screens = QApplication::screens(); - QRect rect; - int primaryscreen = 0; //fallback value - for(int i=0; igeometry().intersected(this->geometry()); - if( (intersect.width()-rect.width() + intersect.height()-rect.height()) > 0){ - rect = intersect; - primaryscreen = i; - } - } - //Now that we have the screen dimensions, lets check/change the window - rect = screens[primaryscreen]->availableGeometry(); - QList< NativeWindow::State > states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State> >(); - if(rect == this->geometry() || states.contains(NativeWindow::S_MAX_VERT) || states.contains(NativeWindow::S_MAX_HORZ)){ - //Already maximized - try to restore it to the previous size/location - if(!lastMaxGeom.isNull()){ - rect = lastMaxGeom; - }else{ - // no last geometry - started out maximized? - // make it half the screen size and centered on the screen - QPoint center = rect.center(); - rect.setWidth( rect.width()/2 ); - rect.setHeight( rect.height()/2 ); - rect.moveTopLeft( center - QPoint(rect.width()/2, rect.height()/2) ); - } - lastMaxGeom = QRect(); //clear this saved geom - }else{ - //Not maximized yet - go ahead and make it so - lastMaxGeom = this->geometry(); //save this for later; - } - //qDebug() << "Toggle Maximize:" << this->geometry() << rect; - QString anim_type = DesktopSettings::instance()->value(DesktopSettings::Animation, "window/move", "random").toString(); - loadAnimation(anim_type, NativeWindow::Size, rect); -} - -void RootSubWindow::triggerClose(){ - WIN->requestClose(); -} - -void RootSubWindow::toggleSticky(){ - QList< NativeWindow::State> states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State > >(); - if(states.contains(NativeWindow::S_STICKY)){ - states.removeAll(NativeWindow::S_STICKY); - }else{ - states << NativeWindow::S_STICKY; - } - WIN->requestProperty(NativeWindow::States, QVariant::fromValue >(states) ); -} - -void RootSubWindow::activate(){ - //WinWidget->raiseWindow(); - WIN->requestProperty(NativeWindow::Active, true, true); -} - -//Mouse Interactivity -void RootSubWindow::startMoving(){ - //If the cursor is not over this window, move it to the center of the titlebar - QPoint curpt = QCursor::pos(); //global coords - if(!this->geometry().contains(curpt)){ - curpt = this->mapToGlobal(titleBar->geometry().center()); - QCursor::setPos(curpt); - } - //Calculate the offset - activeState = Move; - offset = this->mapFromGlobal(curpt); - setMouseCursor(activeState, true); //this one is an override cursor - WinWidget->pause(); - this->grabMouse(); -} - -void RootSubWindow::startResizing(){ - activeState = getStateAtPoint( this->mapFromGlobal(QCursor::pos()), true); //also have it set the offset variable - setMouseCursor(activeState, true); //this one is an override cursor - WinWidget->pause(); - this->grabMouse(); -} - -// === PRIVATE SLOTS === -void RootSubWindow::propertiesChanged(QList props, QList vals){ - for(int i=0; iisPaused() && (this->isVisible()!=vals[i].toBool()) && activeState==Normal ){ - //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); - if(vals[i].toBool()){ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/appear", "random").toString(), NativeWindow::Visible, vals[i]); } - else{ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/disappear", "random").toString(), NativeWindow::Visible, vals[i]); } - } - break; - case NativeWindow::Title: - titleLabel->setText(vals[i].toString()); - break; - case NativeWindow::Icon: - //qDebug() << "Got Icon Change:" << vals[i]; - if(vals[i].value().isNull() ){ LIconCache::instance()->loadIcon(otherB, "list"); } - else{ otherB->setIcon(vals[i].value()); } - break; - case NativeWindow::GlobalPos: - if(vals[i].toPoint()!=QPoint(0,0)){ - WinWidget->resyncWindow(); - } - break; - case NativeWindow::Size: - //qDebug() << " - SIZE CHANGE"; - if(WIN->property(NativeWindow::FrameExtents).isNull() && (iisPaused() && activeState==Normal){ - if(WIN->property(NativeWindow::Size).toSize() != WinWidget->size()){ - //qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); - this->setGeometry( QRect(this->geometry().topLeft(), WIN->geometry().size()) ); - WinWidget->resyncWindow(); - } - } - break; - case NativeWindow::MinSize: - if(vals[i].toSize().isValid()){ - //Just larger than titlebar, with enough space for 8 characters in the titlebar (+4 buttons) - //qDebug() << "Got invalid Min Size: Set a reasonable default minimum"; - WinWidget->setMinimumSize( QSize( this->fontMetrics().height()*4 + this->fontMetrics().width("O")*10, this->fontMetrics().height()*10) ); - WIN->setProperty(NativeWindow::MinSize, WinWidget->minimumSize()); - }else{ - WinWidget->setMinimumSize(vals[i].toSize()); - } - if(WIN->property(NativeWindow::Size).toSize().width() < WinWidget->minimumSize().width() \ - || WIN->property(NativeWindow::Size).toSize().height() < WinWidget->minimumSize().height() ){ - WIN->setProperty(NativeWindow::Size, WinWidget->minimumSize(), true); //force this - //WinWidget->resize(WinWidget->minimumSize()); - } - break; - case NativeWindow::MaxSize: - WinWidget->setMaximumSize(vals[i].toSize()); - break; - case NativeWindow::Active: - if(vals[i].toBool()){ activate(); } //WinWidget->raiseWindow(); } - break; - /*case NativeWindow::FrameExtents: - qDebug() << " - FRAME CHANGE"; - if(vals[i].isNull()){ - vals[i] = QVariant::fromValue >( QList() << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height() ); - WIN->setProperty(NativeWindow::FrameExtents, vals[i]); - } - qDebug() << "Setting Frame Extents:" << vals[i].value >(); - mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); - break;*/ - case NativeWindow::WinTypes: - //qDebug() << "Got Window Types:" << vals[i].value< QList >(); - enableFrame(vals[i].value< QList >() ); - break; - default: - qDebug() << "Window Property Unused:" << props[i] << vals[i]; - } - } -} - -// === PROTECTED === -void RootSubWindow::mousePressEvent(QMouseEvent *ev){ - activate(); - this->raise(); - QFrame::mousePressEvent(ev); - //qDebug() << "Frame Mouse Press Event"; - if(activeState != Normal){ return; } // do nothing - already in a state of grabbed mouse - offset.setX(0); offset.setY(0); - if(ev->button()==Qt::LeftButton){ - if(this->childAt(ev->pos())!=0){ - //Clicked on the titlebar - startMoving(); - }else{ - //Clicked on the frame somewhere - startResizing(); - } - } - -} - -void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ - QFrame::mouseMoveEvent(ev); - if(activeState == Normal){ - setMouseCursor( getStateAtPoint(ev->pos()) ); //just update the mouse cursor - }else{ - //Currently in a modification state - QRect geom = this->geometry(); - QSize minsize(WinWidget->minimumSize().width() + (2*WIN_BORDER), WinWidget->minimumSize().height()+(2*WIN_BORDER)+titleBar->geometry().size().height()); - switch(activeState){ - case Move: - geom.moveTopLeft(ev->globalPos()-offset); //will not change size - break; - case ResizeTop: - geom.setTop(ev->globalPos().y()-offset.y()); - if(geom.size().height() < minsize.height()){ - geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height - } - break; - case ResizeTopRight: - geom.setTopRight(ev->globalPos()-offset); - if(geom.size().height() < minsize.height()){ - geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height - } - if(geom.size().width() < minsize.width()){ - geom.setRight(geom.x() + minsize.width()); //reset back to min width - } - break; - case ResizeRight: - geom.setRight(ev->globalPos().x()-offset.x()); - if(geom.size().width() < minsize.width()){ - geom.setRight(geom.x() + minsize.width()); //reset back to min width - } - break; - case ResizeBottomRight: - geom.setBottomRight(ev->globalPos()-offset); - if(geom.size().height() < minsize.height()){ - geom.setBottom(geom.y() + minsize.height()); //reset back to min height - } - if(geom.size().width() < minsize.width()){ - geom.setRight(geom.x() + minsize.width()); //reset back to min width - } - break; - case ResizeBottom: - geom.setBottom(ev->globalPos().y()-offset.y()); - if(geom.size().height() < minsize.height()){ - geom.setBottom(geom.y() + minsize.height()); //reset back to min height - } - break; - case ResizeBottomLeft: - geom.setBottomLeft(ev->globalPos()-offset); - if(geom.size().height() < minsize.height()){ - geom.setBottom(geom.y() + minsize.height()); //reset back to min height - } - if(geom.size().width() < minsize.width()){ - geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width - } - break; - case ResizeLeft: - geom.setLeft(ev->globalPos().x()-offset.x()); - if(geom.size().width() < minsize.width()){ - geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width - } - break; - case ResizeTopLeft: - geom.setTopLeft(ev->globalPos()-offset); - if(geom.size().height() < minsize.height()){ - geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height - } - if(geom.size().width() < minsize.width()){ - geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width - } - break; - default: - break; - } - //if( (geom.width()%2==0 && geom.height()%2==0) || activeState==Move){ - //qDebug() << " Change Window:" << this->geometry() << geom; - if(activeState==Move){ this->setGeometry(geom); } - else{ - //qDebug() << " Change Window Dimensions:" << this->geometry() << geom; - //qDebug() << " - Mouse Pos:" << ev->globalPos() << ev->pos() << "Offset" << offset; - this->setGeometry(geom); - } - //} - } -} - -void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){ - //Check for a right-click event - //qDebug() << "Frame Mouse Release Event"; - QFrame::mouseReleaseEvent(ev); - if( (activeState==Normal) && (titleBar->geometry().contains(ev->pos())) && (ev->button()==Qt::RightButton) ){ - //WinWidget->raiseWindow();//need to ensure the native window is always on top of this frame but under the menu - otherM->popup(ev->globalPos()); - return; - } - if(activeState!=Normal){ - if(WinWidget->isPaused()){ WinWidget->resume(); } - activeState = Normal; - QApplication::restoreOverrideCursor(); - setMouseCursor( getStateAtPoint(ev->pos()) ); - } - if(QFrame::mouseGrabber() == this){ this->releaseMouse(); } - activate(); - //QTimer::singleShot(0, WinWidget, SLOT(raiseWindow()) ); -} - -/*void RootSubWindow::enterEvent(QEvent *ev){ - QFrame::enterEvent(ev); - WinWidget->raiseWindow(); -}*/ -/*void RootSubWindow::leaveEvent(QEvent *ev){ - QFrame::leaveEvent(ev); - if(activeState == Normal){ - setMouseCursor(Normal); - } - if(!QRect(QPoint(0,0),this->size()).contains( this->mapFromGlobal(QCursor::pos())) ){ WinWidget->lowerWindow(); } -}*/ - -void RootSubWindow::moveEvent(QMoveEvent *ev){ - //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); - QFrame::moveEvent(ev); - if(!closing && !WinWidget->isPaused()){ - moveTimer->start(); - } -} diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h deleted file mode 100644 index 598298e2..00000000 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ /dev/null @@ -1,109 +0,0 @@ -//=========================================== -// Lumina Desktop source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This class embeds a native window -// within the RootWindow area -//=========================================== -#ifndef _LUMINA_ROOT_WINDOW_SUB_WINDOW_H -#define _LUMINA_ROOT_WINDOW_SUB_WINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class RootSubWindow : public QFrame{ - Q_OBJECT -public: - RootSubWindow(QWidget *root, NativeWindow *win); - ~RootSubWindow(); - - WId id(); - NativeWindow* nativeWindow(); - -private: - //Window status - enum ModState{Normal, Move, ResizeTop, ResizeTopRight, ResizeRight, ResizeBottomRight, ResizeBottom, ResizeBottomLeft, ResizeLeft, ResizeTopLeft}; - ModState activeState; - ModState currentCursor; - QPoint offset; //needed for movement calculations (offset from mouse click to movement point) - //Functions for getting/setting state - ModState getStateAtPoint(QPoint pt, bool setoffset = false); //generally used for mouse location detection - void setMouseCursor(ModState, bool override = false); //Update the mouse cursor based on state - - //Native window embed objects - NativeWindow *WIN; - NativeEmbedWidget *WinWidget; - bool closing; - //Title bar objects - QBoxLayout *titleBarL, *mainLayout; - QToolButton *closeB, *maxB, *minB, *otherB; - QLabel *titleLabel; - QMenu *otherM; //menu of other actions - QWidget *titleBar; - //Other random objects (animations,etc) - QPropertyAnimation *anim; - QVariant animResetProp; - QTimer *moveTimer; - QRect lastGeom, lastMaxGeom; //frame coordinates - - void initWindowFrame(); - void enableFrame(bool); - void enableFrame(QList types); - - void LoadProperties( QList< NativeWindow::Property> list); - - static QStringList validAnimations(NativeWindow::Property); - -public slots: - void ensureVisible(){ WIN->setProperty(NativeWindow::Visible, true); } - void giveMouseFocus(){ WinWidget->raiseWindow(); } - void removeMouseFocus(){ WinWidget->lowerWindow(); } - void giveKeyboardFocus(){ WIN->requestProperty(NativeWindow::Active, true, true); } - - void clientClosed(); - void LoadAllProperties(); - - QRect clientGlobalGeom(); - - //Button Actions - public so they can be tied to key shortcuts and stuff as well - void toggleMinimize(); - void toggleMaximize(); - void triggerClose(); - void toggleSticky(); - void activate(); - - //Mouse Interactivity - void startMoving(); - void startResizing(); - -private slots: - void propertiesChanged(QList, QList); - - void loadAnimation(QString name, NativeWindow::Property, QVariant nval); //new val - void animFinished(); - -protected: - void mousePressEvent(QMouseEvent*); - void mouseMoveEvent(QMouseEvent*); - void mouseReleaseEvent(QMouseEvent*); - //void leaveEvent(QEvent *ev); - //void enterEvent(QEvent *ev); - void moveEvent(QMoveEvent *ev); - -signals: - void windowMoved(RootSubWindow*); - void windowAnimFinished(); -}; - -#endif diff --git a/src-qt5/core/libLumina/RootWindow-mgmt.cpp b/src-qt5/core/libLumina/RootWindow-mgmt.cpp deleted file mode 100644 index 24ea639b..00000000 --- a/src-qt5/core/libLumina/RootWindow-mgmt.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2016, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "RootWindow.h" - -//Primary/private function -void RootWindow::arrangeWindows(RootSubWindow *primary, QString type, bool primaryonly){ - if(type.isEmpty()){ type = "center"; } - if(primary==0){ - //Get the currently active window and treat that as the primary - for(int i=0; inativeWindow()->property(NativeWindow::Active).toBool()){ primary = WINDOWS[i]; } - } - if(primary==0 && !WINDOWS.isEmpty()){ primary = WINDOWS[0]; } //just use the first one in the list - } - //Now get the current screen that the mouse cursor is over (and valid area) - QScreen *screen = screenUnderMouse(); - QRect desktopArea = screen->availableGeometry(); - //qDebug() << "Arrange Windows:" << primary->geometry() << type << primaryonly << desktopArea; - //Now start filtering out all the windows that need to be ignored - int wkspace = primary->nativeWindow()->property(NativeWindow::Workspace).toInt(); - QList winlist = WINDOWS; - for(int i=0; inativeWindow()->property(NativeWindow::Workspace).toInt()!=wkspace - || !winlist[i]->nativeWindow()->property(NativeWindow::Visible).toBool() - || desktopArea.intersected(winlist[i]->geometry()).isNull() ){ - //window is outside of the desired area or invisible - ignore it - winlist.removeAt(i); - i--; - } - } - if(!winlist.contains(primary)){ winlist << primary; } //could be doing this on a window right before it is shown - else if(primaryonly){ winlist.removeAll(primary); winlist << primary; } //move primary window to last - //QRegion used; - for(int i=0; igeometry(); - //verify that the window is contained by the desktop area - if(geom.width()>desktopArea.width()){ geom.setWidth(desktopArea.width()); } - if(geom.height()>desktopArea.height()){ geom.setHeight(desktopArea.height()); } - //Now apply the proper placement routine - if(type=="center"){ - QPoint ct = desktopArea.center(); - winlist[i]->setGeometry( ct.x()-(geom.width()/2), ct.y()-(geom.height()/2), geom.width(), geom.height()); - }else if(type=="snap"){ - - }else if(type=="single_max"){ - winlist[i]->setGeometry( desktopArea.x(), desktopArea.y(), desktopArea.width(), desktopArea.height()); - }else if(type=="under-mouse"){ - QPoint ct = QCursor::pos(); - geom = QRect(ct.x()-(geom.width()/2), ct.y()-(geom.height()/2), geom.width(), geom.height() ); - //Now verify that the top of the window is still contained within the desktop area - if(geom.y() < desktopArea.y() ){ geom.moveTop(desktopArea.y()); } - winlist[i]->setGeometry(geom); - - } - //qDebug() << " - New Geometry:" << winlist[i]->geometry(); - } //end loop over winlist -} - -// ================ -// Public slots for starting the arrangement routine(s) above -// ================ -void RootWindow::ArrangeWindows(WId primary, QString type){ - RootSubWindow* win = windowForId(primary); - if(type.isEmpty()){ type = "center"; } //grab the default arrangement format - arrangeWindows(win, type); -} - -void RootWindow::TileWindows(WId primary, QString type){ - RootSubWindow* win = windowForId(primary); - if(type.isEmpty()){ type = "single_max"; } //grab the default arrangement format for tiling - arrangeWindows(win, type); -} - -void RootWindow::CheckWindowPosition(WId id, bool newwindow){ - //used after a "drop" to validate/snap/re-arrange window(s) as needed - // if "newwindow" is true, then this is the first-placement routine for a window before it initially appears - RootSubWindow* win = windowForId(id); - if(win==0){ return; } //invalid window - QRect geom = win->nativeWindow()->geometry(); - bool changed = false; - //Make sure it is on the screen (quick check) - if(geom.x() < 0){ changed = true; geom.moveLeft(0); } - if(geom.y() < 0){ changed = true; geom.moveTop(0); } - if(geom.width() < 20){ changed = true; geom.setWidth(100); } - if(geom.height() < 20){ changed = true; geom.setHeight(100); } - if(changed){ win->setGeometry(geom); } - //Now run it through the window arrangement routine - arrangeWindows(win, newwindow ?"center" : "snap", true); -} diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp deleted file mode 100644 index 705297be..00000000 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ /dev/null @@ -1,283 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2016, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "RootWindow.h" - -#include -#include -#include - -#define DEBUG 0 - -// === PUBLIC === -RootWindow::RootWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ - qRegisterMetaType("WId"); - autoResizeTimer = 0; - lastActiveMouse = 0; - mouseFocusTimer = 0; - this->setMouseTracking(true); -} - -RootWindow::~RootWindow(){ - -} - -void RootWindow::start(){ - - if(autoResizeTimer==0){ - autoResizeTimer = new QTimer(this); - autoResizeTimer->setInterval(100); //1/10 second (collect all nearly-simultaneous signals and compress into a single update) - autoResizeTimer->setSingleShot(true); - connect(autoResizeTimer, SIGNAL(timeout()), this, SLOT(ResizeRoot()) ); - connect(QApplication::desktop(), SIGNAL(resized(int)), autoResizeTimer, SLOT(start()) ); - connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), autoResizeTimer, SLOT(start()) ); - } - if(mouseFocusTimer==0){ - mouseFocusTimer = new QTimer(this); - mouseFocusTimer->setInterval(100); - connect(mouseFocusTimer, SIGNAL(timeout()), this, SLOT(checkMouseFocus()) ); - - } - this->show(); - ResizeRoot(); - emit RegisterVirtualRoot(this->winId()); -} - -// === PRIVATE === -void RootWindow::updateScreenPixmap(screeninfo *info){ - QPixmap pix(info->area.size()); - if(info->scale == RootWindow::SolidColor){ - QColor color; - if(info->file.startsWith("rgb(")){ - QStringList colors = info->file.section(")",0,0).section("(",1,1).split(","); - color = QColor(colors[0].toInt(), colors[1].toInt(), colors[2].toInt()); - }else{ - color = QColor(info->file); - } - pix.fill(color); - }else{ - QPixmap raw(info->file); //load the image from file - //Now apply the proper aspect ratio as needed - if(info->scale == RootWindow::Stretch || info->scale == RootWindow::Full || info->scale == RootWindow::Fit){ - Qt::AspectRatioMode armode = Qt::KeepAspectRatio; - if(info->scale == RootWindow::Stretch ){ armode = Qt::IgnoreAspectRatio; } - else if(info->scale == RootWindow::Full ){ armode = Qt::KeepAspectRatioByExpanding; } - if(raw.height()!=info->area.height() && raw.width() !=info->area.width()){ - raw = raw.scaled(info->area.size(), armode); - } - } - //Now calculate offset and draw width/height - QRect drawRect(0,0, raw.width(), raw.height()); - if(info->scale == RootWindow::Full ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); - }else if(info->scale == RootWindow::Fit ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); - }else if(info->scale == RootWindow::Center ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); - }else if(info->scale == RootWindow::Tile ){ - //Draw the entire area - no offset - drawRect.setHeight(info->area.height()); - drawRect.setWidth(info->area.width()); - }else if(info->scale == RootWindow::BottomLeft ){ - drawRect.moveTo( 0 , info->area.height() - raw.height() ); - }else if(info->scale == RootWindow::BottomRight ){ - drawRect.moveTo( (info->area.width() - raw.width()), (info->area.height() - raw.height()) ); - }else if(info->scale == RootWindow::BottomCenter ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, info->area.height() - raw.height() ); - }else if(info->scale == RootWindow::TopLeft ){ - drawRect.moveTo( 0, 0 ); - }else if(info->scale == RootWindow::TopRight ){ - drawRect.moveTo( (info->area.width() - raw.width()), 0); - }else if(info->scale == RootWindow::TopCenter ){ - drawRect.moveTo( (info->area.width() - raw.width())/2, 0); - }else if(info->scale == RootWindow::CenterLeft ){ - drawRect.moveTo( 0, (info->area.height() - raw.height())/2 ); - }else if(info->scale == RootWindow::CenterRight ){ - drawRect.moveTo( (info->area.width() - raw.width()), (info->area.height() - raw.height())/2 ); - } - - QPainter P(&pix); - P.setBrush(raw); - P.setBrushOrigin( drawRect.x(), drawRect.y() ); - P.drawRect( drawRect ); -} //end SolidColor Check - - info->wallpaper = pix; -} - -RootSubWindow* RootWindow::windowForId(WId id){ - RootSubWindow *tmp = 0; - for(int i=0; iid() == id){ tmp = WINDOWS[i]; } - } - return tmp; -} - -QScreen* RootWindow::screenUnderMouse(){ - QPoint mpos = QCursor::pos(); - QList scrns = QApplication::screens(); - for(int i=0; igeometry().contains(mpos)){ return scrns[i]; } - } - //Could not find an exact match - just return the first one - return scrns.first(); -} - -// === PUBLIC SLOTS === -void RootWindow::ResizeRoot(){ - if(DEBUG){ qDebug() << "Resize Root..."; } - QList scrns = QApplication::screens(); - //Update all the screen locations and ID's in the WALLPAPERS list - QRect fullscreen; - QStringList valid; - //Update the size of the rootWindow itself - for(int i=0; iname() << scrns[i]->geometry(); } - fullscreen = fullscreen.united(scrns[i]->geometry()); - valid << scrns[i]->name(); - for(int j=0; jname()){ - QSize oldsize = WALLPAPERS[j].area.size(); - WALLPAPERS[j].area = scrns[i]->geometry(); - if(oldsize != WALLPAPERS[j].area.size()){ updateScreenPixmap(&WALLPAPERS[j]); } - break; - } - } - } - //Now clean up any invalid screen info in the WALLPAPERS List - QStringList invalid; - for(int i=0; isetGeometry(fullscreen); - this->update(); - emit RootResized(fullscreen); - if(!valid.isEmpty()){ emit NewScreens(valid); } - if(!invalid.isEmpty()){ emit RemovedScreens(invalid); } - if(DEBUG){ qDebug() << " - Geom after change:" << this->geometry(); } -} - -void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file){ - bool found = false; - for(int i=0; i scrns = QApplication::screens(); - for(int i=0; iname()==id){ - screeninfo info; - info.id = id; - info.file = file; - info.scale = scale; - info.area = scrns[i]->geometry(); - updateScreenPixmap(&info); - //qDebug() << " --- Loaded Wallpaper:" << info.id << info.file << info.area; - WALLPAPERS << info; - break; - } - } - } //end check for a new id - -} - -void RootWindow::checkMouseFocus(){ - QPoint cpos = QCursor::pos(); - if(lastCursorPos != cpos){ emit MouseMoved(); } - lastCursorPos = cpos; - QWidget *child = this->childAt(QCursor::pos()); - while(child!=0 && child->whatsThis()!="RootSubWindow"){ - child = child->parentWidget(); - if(child==this){ child = 0;} //end of the line - } - - if(child==lastActiveMouse){ return; } //nothing new to do - //Make sure the child is actually a RootSubWindow - if(lastActiveMouse!=0){ lastActiveMouse->removeMouseFocus(); lastActiveMouse = 0; } - if(child!=0){ - lastActiveMouse = static_cast(child); - - if(DesktopSettings::instance()->value(DesktopSettings::WM, "focusFollowsMouse", true).toBool()){ - lastActiveMouse->giveKeyboardFocus(); - if(DesktopSettings::instance()->value(DesktopSettings::WM, "raiseOnFocus", false).toBool()){ - lastActiveMouse->raise(); - } - } - lastActiveMouse->giveMouseFocus(); //always give mouse focus on mouseover - } -} - -void RootWindow::NewWindow(NativeWindow *win){ - RootSubWindow *subwin = 0; - //qDebug() << "Got New Window:" << win->property(NativeWindow::Title); - for(int i=0; iid() == win->id()){ subwin = WINDOWS[i]; } - } - if(subwin==0){ - subwin = new RootSubWindow(this, win); - subwin->setWhatsThis("RootSubWindow"); - connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(CloseWindow(WId)) ); - connect(subwin, SIGNAL(windowAnimFinished()), this, SLOT(checkMouseFocus()) ); - WINDOWS << subwin; - } - //QApplication::processEvents(); - CheckWindowPosition(win->id(), true); //first-time run - //QTimer::singleShot(300, subwin, SLOT(ensureVisible())); - win->setProperty(NativeWindow::Visible, true); - //win->requestProperty( NativeWindow::Active, true); - //win->requestProperties(QList() << NativeWindow::Visible << NativeWindow::Active, QList() << true << true, true); - if(!mouseFocusTimer->isActive()){ mouseFocusTimer->start(); } -} - -void RootWindow::CloseWindow(WId win){ - for(int i=0; iid() == win){ - if(lastActiveMouse==WINDOWS[i]){ lastActiveMouse = 0; } //no longer valid - WINDOWS.takeAt(i)->clientClosed(); - break; - } - } - if(WINDOWS.isEmpty()){ mouseFocusTimer->stop(); } //no windows to look for -} - -// === PRIVATE SLOTS === - -// === PROTECTED === -void RootWindow::paintEvent(QPaintEvent *ev){ - //qDebug() << "RootWindow: PaintEvent:" << ev->rect(); //<< QDateTime::currentDateTime()->toString(QDateTime::ShortDate); - //QWidget::paintEvent(ev); - bool found = false; - QPainter painter(this); - QRect geom = ev->rect(); - geom.adjust(-100,-100,100,100); //give it a few more pixels in each direction to repaint (noticing some issues in Qt 5.7.1) - for(int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "RootSubWindow.h" - -#include -#include - -class RootWindow : public QWidget{ - Q_OBJECT -public: - enum ScaleType{ SolidColor, Stretch, Full, Fit, Center, Tile, BottomLeft, BottomRight, BottomCenter, \ - TopLeft, TopRight, TopCenter, CenterLeft, CenterRight}; - - RootWindow(); - ~RootWindow(); - - void start(); - -private: - struct screeninfo{ - QString id; - QRect area; - QString file; - ScaleType scale; - QPixmap wallpaper; //Note: This pixmap will always be the same size as "area" - }; - QTimer *autoResizeTimer, *mouseFocusTimer; - RootSubWindow *lastActiveMouse; - QPoint lastCursorPos; - - QList WALLPAPERS; - void updateScreenPixmap(screeninfo *info); //used for recalculating the wallpaper pixmap based on file/area/scale as needed - - //Window Management - QList WINDOWS; - RootSubWindow* windowForId(WId id); - void arrangeWindows(RootSubWindow *primary = 0, QString type = "", bool primaryonly = false); - - QScreen* screenUnderMouse(); - - -public slots: - void ResizeRoot(); - void ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file); - //Note: for "SingleColor" scaling the "file" variable should be "rgb(R,G,B)" or "#hexcode" - void checkMouseFocus(); - - void NewWindow(NativeWindow*); - void CloseWindow(WId); //automatically connected for any new native window - - //Window arrangement functions - defined in "RootWindow-mgmt.cpp" - void ArrangeWindows(WId primary = 0, QString type = ""); - void TileWindows(WId primary = 0, QString type = ""); - void CheckWindowPosition(WId, bool newwindow = false); //used after a "drop" to validate/snap/re-arrange window(s) as needed - -private slots: - -protected: - void paintEvent(QPaintEvent *ev); - -signals: - void RegisterVirtualRoot(WId); - void RootResized(QRect); - void NewScreens(QStringList); // [screen_id_1, screen_id_2, etc..] - void RemovedScreens(QStringList); // [screen_id_1, screen_id_2, etc..] - void WorkspaceChanged(int); - void MouseMoved(); - -}; - -#endif diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/RootWindow.pri deleted file mode 100644 index 9426b6b4..00000000 --- a/src-qt5/core/libLumina/RootWindow.pri +++ /dev/null @@ -1,17 +0,0 @@ - -# Files -SOURCES *= $${PWD}/RootWindow.cpp \ - $${PWD}/RootWindow-mgmt.cpp \ - $${PWD}/RootSubWindow.cpp \ - $${PWD}/RootSubWindow-animations.cpp - -HEADERS *= $${PWD}/RootWindow.h \ - $${PWD}/RootSubWindow.h - -INCLUDEPATH *= ${PWD} - -# include other library dependencies -include(LUtils.pri) -include(NativeWindow.pri) -include(LIconCache.pri) -include(DesktopSettings.pri) diff --git a/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp new file mode 100644 index 00000000..efab20fe --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp @@ -0,0 +1,116 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootSubWindow.h" +#include + +QStringList RootSubWindow::validAnimations(NativeWindow::Property prop){ + QStringList valid; + if(prop == NativeWindow::Visible){ + valid << "zoom" << "wipe-center-vertical" << "wipe-center-horizontal" << "shade-top" << "shade-right" << "shade-left" << "shade-bottom"; + }else if(prop == NativeWindow::Size){ + //Note: this is used for pretty much all geometry changes to the window where it is visible both before/after animation + valid << "direct"; + } + return valid; +} + +void RootSubWindow::loadAnimation(QString name, NativeWindow::Property prop, QVariant nval){ + if(anim->state()==QAbstractAnimation::Running){ return; } //already running + animResetProp.clear(); + //Special case - random animation each time + if(name=="random"){ + QStringList valid = validAnimations(prop); + if(!valid.isEmpty()){ name = valid.at(qrand()%valid.length()); } + } + //Now setup the animation + if(prop == NativeWindow::Visible){ + //NOTE: Assigns values for "invisible->visible" animation: will reverse it afterwards as needed + anim->setPropertyName("geometry"); + QRect geom = this->geometry(); + if(name == "zoom"){ + //Zoom to/from the center point + anim->setStartValue( QRect(geom.center(), QSize(0,0)) ); + anim->setEndValue(geom); + }else if(name == "wipe-center-vertical"){ + anim->setStartValue( QRect( geom.center().x(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else if(name == "wipe-center-horizontal"){ + anim->setStartValue( QRect( geom.x(), geom.center().y(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-top"){ + anim->setStartValue( QRect( geom.x(), geom.y(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-bottom"){ + anim->setStartValue( QRect( geom.x(), geom.y()+geom.height(), geom.width(), 0) ); + anim->setEndValue( geom ); + }else if(name == "shade-left"){ + anim->setStartValue( QRect( geom.x(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else if(name == "shade-right"){ + anim->setStartValue( QRect( geom.x()+geom.width(), geom.y(), 0, geom.height()) ); + anim->setEndValue( geom ); + }else{ + //Invalid/None animation + if(nval.toBool()){ this->show(); } + else{ this->hide(); } + return; + } + if(nval.toBool()){ + this->setGeometry( anim->startValue().toRect() ); //ensure the window is the initial geom before it becomes visible + //QTimer::singleShot( anim->duration()+5, this, SLOT(activate()) ); + }else{ + QVariant tmp = anim->startValue(); + anim->setStartValue(anim->endValue()); + anim->setEndValue(tmp); + animResetProp = anim->startValue(); + QTimer::singleShot(anim->duration(), this, SLOT(hide()) ); + } + WinWidget->pause(); + anim->start(); + this->show(); + } //end of Visibility animation + else if(prop == NativeWindow::Size){ + //This is pretty much all geometry animations where the window is visible->visible + anim->setPropertyName("geometry"); + anim->setStartValue(this->geometry()); + anim->setEndValue(nval.toRect()); + /*if(name==""){ + // TO-DO modify the path from beginning->end somehow + }*/ + // Now start the animation + WinWidget->pause(); + anim->start(); + this->show(); + } +} + +void RootSubWindow::animFinished(){ + if(closing){ this->close(); return;} + else if(anim->propertyName()=="geometry"){ + if(!animResetProp.isNull()){ + /*qDebug() << "Animation Finished, Reset Geometry:" << animResetProp.toRect(); + qDebug() << " - Starting Value:" << anim->startValue().toRect(); + qDebug() << " - Ending Value:" << anim->endValue().toRect();*/ + this->setGeometry( animResetProp.toRect() ); + //Also ensure that the proper geometry is saved to the window structure + QRect curg = this->geometry(); + QRect wing = WIN->geometry(); + //qDebug() << " - After Animation Reset:" << curg << wing; + if(curg!=wing){ + QRect clientg = clientGlobalGeom(); + //qDebug() << "Sub Window geometry:" << clientg; + WIN->setProperties(QList< NativeWindow::Property>() << NativeWindow::Size << NativeWindow::GlobalPos, + QList() << clientg.size() << clientg.topLeft() ); + } + } + WinWidget->resyncWindow(); //also let the window know about the current geometry + } + animResetProp = QVariant(); //clear the variable + //QTimer::singleShot(10, WinWidget, SLOT(resume()) ); + WinWidget->resume(); + emit windowAnimFinished(); +} diff --git a/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp new file mode 100644 index 00000000..5040f2f9 --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp @@ -0,0 +1,601 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootSubWindow.h" +#include +#include +#include +#include +#include +#include + +#define WIN_BORDER 5 + +#include +#include + +// === PUBLIC === +RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ + this->setAttribute(Qt::WA_DeleteOnClose); + this->setMouseTracking(true); + //Create the QWindow and QWidget containers for the window + WIN = win; + closing = false; + initWindowFrame(); + //Hookup the signals/slots + connect(WIN, SIGNAL(PropertiesChanged(QList, QList)), this, SLOT(propertiesChanged(QList, QList))); + WinWidget->embedWindow(WIN); + //qDebug() << "[NEW WINDOW]" << WIN->id() << WinWidget->winId() << this->winId(); + activeState = RootSubWindow::Normal; + LoadAllProperties(); +} + +RootSubWindow::~RootSubWindow(){ + //qDebug() << "Visible Window Destroyed"; + WIN->deleteLater(); +} + +WId RootSubWindow::id(){ + return WIN->id(); +} + +NativeWindow* RootSubWindow::nativeWindow(){ + return WIN; +} + +// === PRIVATE === +RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset){ + //Note: pt should be in widget-relative coordinates, not global + if(!WinWidget->geometry().contains(pt) && !titleBar->geometry().contains(pt)){ + //above the frame itself - need to figure out which quadrant it is in (8-directions) + if(pt.y() < WIN_BORDER){ + //One of the top options + if(pt.x() < this->width()/5){ + if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner + return ResizeTopLeft; + }else if(pt.x() > (this->width()*4.0/5.0)){ + if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()); } //difference from top-right corner + return ResizeTopRight; + }else{ + if(setoffset){ offset.setX(0); offset.setY(pt.y()); } //difference from top edge (X does not matter) + return ResizeTop; + } + }else if(pt.y() > (this->height()-WIN_BORDER) ){ + //One of the bottom options + if(pt.x() < this->width()/5){ + if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()-this->height()); } //difference from bottom-left corner + return ResizeBottomLeft; + }else if(pt.x() > (this->width()*4.0/5.0)){ + if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()-this->height()); } //difference from bottom-right corner + return ResizeBottomRight; + }else{ + if(setoffset){ offset.setX(0); offset.setY(pt.y()-this->height()); } //difference from bottom edge (X does not matter) + return ResizeBottom; + } + }else if(pt.x() < WIN_BORDER){ + //Left side options + if(pt.y() < this->height()/5){ + if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner + return ResizeTopLeft; + }else if(pt.y() > (this->height()*4.0/5.0)){ + if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()-this->height()); } //difference from bottom-left corner + return ResizeBottomLeft; + }else{ + if(setoffset){ offset.setX(pt.x()); offset.setY(0); } //difference from left edge (Y does not matter) + return ResizeLeft; + } + }else if(pt.x() > (this->width()-WIN_BORDER) ){ + //Right side options + if(pt.y() < this->height()/5){ + if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()); } //difference from top-right corner + return ResizeTopRight; + }else if(pt.y() > (this->height()*4.0/5.0)){ + if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(pt.y()-this->height()); } //difference from bottom-right corner + return ResizeBottomRight; + }else{ + if(setoffset){ offset.setX(pt.x()-this->width()); offset.setY(0); } //difference from right edge (Y does not matter) + return ResizeRight; + } + }else{ + return Normal; + } + } + //if it gets this far just return normal + return Normal; +} + +void RootSubWindow::setMouseCursor(ModState state, bool override){ + if(currentCursor==state && !override){ return; } //nothing to change + Qt::CursorShape shape; + switch(state){ + case Normal: + shape = Qt::ArrowCursor; + break; + case Move: + shape = Qt::SizeAllCursor; + break; + case ResizeTop: + shape = Qt::SizeVerCursor; + break; + case ResizeTopRight: + shape = Qt::SizeBDiagCursor; + break; + case ResizeRight: + shape = Qt::SizeHorCursor; + break; + case ResizeBottomRight: + shape = Qt::SizeFDiagCursor; + break; + case ResizeBottom: + shape = Qt::SizeVerCursor; + break; + case ResizeBottomLeft: + shape = Qt::SizeBDiagCursor; + break; + case ResizeLeft: + shape = Qt::SizeHorCursor; + break; + case ResizeTopLeft: + shape = Qt::SizeFDiagCursor; + break; + } + if(override){ + QApplication::setOverrideCursor(QCursor(shape)); + }else{ + currentCursor = state; + this->setCursor(shape); + } +} + +void RootSubWindow::initWindowFrame(){ + //qDebug() << "Create RootSubWindow Frame"; + this->setContentsMargins(0,0,0,0); + mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0,0,0,0); + titleBar = new QWidget(this); + titleBar->setContentsMargins(0,0,0,0); + titleBarL = new QHBoxLayout(titleBar); + titleBarL->setContentsMargins(0,0,0,0); + closeB = new QToolButton(this); + maxB = new QToolButton(this); + minB = new QToolButton(this); + otherB = new QToolButton(this); + anim = new QPropertyAnimation(this); + anim->setTargetObject(this); + anim->setDuration(200); //1/5 second (appx) + connect(anim, SIGNAL(finished()), this, SLOT(animFinished()) ); + titleLabel = new QLabel(this); + titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + otherM = new QMenu(this); //menu of other actions + otherB->setMenu(otherM); + otherB->setPopupMode(QToolButton::InstantPopup); + otherB->setAutoRaise(true); + WinWidget = new NativeEmbedWidget(this); + connect(closeB, SIGNAL(clicked()), this, SLOT(triggerClose()) ); + connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) ); + connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) ); + //Now assemble the frame layout based on the current settings + titleBarL->addWidget(otherB); + titleBarL->addWidget(titleLabel); + titleBarL->addWidget(minB); + titleBarL->addWidget(maxB); + titleBarL->addWidget(closeB); + WinWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + titleBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + mainLayout->addWidget(titleBar); + mainLayout->addWidget(WinWidget); + mainLayout->setAlignment(titleBar, Qt::AlignTop); + //Setup the cursors for the buttons + closeB->setCursor(Qt::ArrowCursor); + minB->setCursor(Qt::ArrowCursor); + maxB->setCursor(Qt::ArrowCursor); + otherB->setCursor(Qt::ArrowCursor); + titleLabel->setCursor(Qt::ArrowCursor); + WinWidget->setCursor(Qt::ArrowCursor); + //Now all the stylesheet options + this->setObjectName("WindowFrame"); + closeB->setObjectName("Button_Close"); + minB->setObjectName("Button_Minimize"); + maxB->setObjectName("Button_Maximize"); + otherM->setObjectName("Menu_Actions"); + titleLabel->setObjectName("Label_Title"); + this->setStyleSheet("QFrame#WindowFrame{background-color: rgba(0,0,0,125)} QWidget#Label_Title{background-color: transparent; color: white; } QToolButton{background-color: transparent; border: 1px solid transparent; border-radius: 3px; } QToolButton::hover{background-color: rgba(255,255,255,150); } QToolButton::pressed{ background-color: white; } QToolButton::menu-arrow{ image: none; }"); + //And adjust the margins + mainLayout->setSpacing(0); + titleBarL->setSpacing(1); + this->setFrameStyle(QFrame::NoFrame); + this->setLineWidth(0); + this->setMidLineWidth(0); + this->setFrameRect(QRect(0,0,0,0)); + + //Setup the timer object to syncronize info + moveTimer = new QTimer(this); + moveTimer->setSingleShot(true); + moveTimer->setInterval(100); //1/10 second + connect(moveTimer, SIGNAL(timeout()), WinWidget, SLOT(resyncWindow()) ); + + //Now load the icons for the button + LIconCache::instance()->loadIcon(closeB, "window-close"); + LIconCache::instance()->loadIcon(maxB, "window-maximize"); + LIconCache::instance()->loadIcon(minB, "window-minimize"); + LIconCache::instance()->loadIcon(otherB, "list"); +} + +void RootSubWindow::enableFrame(bool on){ + //Make the individual frame elements visible as needed + if(on){ this->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER); }//default border + else{ this->setContentsMargins(0, 0, 0, 0); } + titleBar->setVisible(on); + //And now calculate/save the frame extents + QList extents; extents << 0 << 0 << 0 << 0; //left, right, top, bottom + if(on){ + extents[0] = WIN_BORDER; + extents[1] = WIN_BORDER; + extents[2] = WIN_BORDER + titleBar->height(); + extents[3] = WIN_BORDER; + } + //qDebug() << "SET FRAME EXTENTS:" << extents; + WIN->requestProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save on raw window itself + WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList >(extents) ); //save to structure now +} + +void RootSubWindow::enableFrame(QList types){ + static QList noframe; + if(noframe.isEmpty()){ noframe << NativeWindow::T_DESKTOP << NativeWindow::T_DOCK << NativeWindow::T_TOOLBAR << NativeWindow::T_MENU << NativeWindow::T_SPLASH << NativeWindow::T_DROPDOWN_MENU << NativeWindow::T_POPUP_MENU << NativeWindow::T_TOOLTIP << NativeWindow::T_NOTIFICATION << NativeWindow::T_COMBO << NativeWindow::T_DND; } + for(int i=0; i list){ + QList vals; + //Always ensure that visibility changes are evaluated last + bool addvisible = false; + for(int i=0; iproperty(list[i]); + } + //if(addvisible){ list << NativeWindow::Visible; vals << WIN->property(NativeWindow::Visible); } + propertiesChanged(list, vals); +} + +QRect RootSubWindow::clientGlobalGeom(){ + QRect tot = this->geometry(); + QList frame = WIN->property(NativeWindow::FrameExtents).value< QList >(); + //Now adjust this to take out the frame + tot.adjust(frame[0], frame[2], -frame[1], -frame[3]); + return tot; +} + +// === PUBLIC SLOTS === +void RootSubWindow::clientClosed(){ + //qDebug() << "Client Closed"; + closing = true; + if(anim->state()!=QAbstractAnimation::Running){ this->close(); } +} + +void RootSubWindow::LoadAllProperties(){ + QList< NativeWindow::Property> list; + list << NativeWindow::WinTypes << NativeWindow::WinActions << NativeWindow::States + << NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Title << NativeWindow::ShortTitle + << NativeWindow::Icon << NativeWindow::Size << NativeWindow::GlobalPos;// << NativeWindow::Visible << NativeWindow::Active; + LoadProperties(list); + //WIN->requestProperty(NativeWindow::Visible, true); +} + +//Button Actions - public so they can be tied to key shortcuts and stuff as well +void RootSubWindow::toggleMinimize(){ + WIN->toggleVisibility(); +} + +void RootSubWindow::toggleMaximize(){ + //Get the current screen that this window is on + QList screens = QApplication::screens(); + QRect rect; + int primaryscreen = 0; //fallback value + for(int i=0; igeometry().intersected(this->geometry()); + if( (intersect.width()-rect.width() + intersect.height()-rect.height()) > 0){ + rect = intersect; + primaryscreen = i; + } + } + //Now that we have the screen dimensions, lets check/change the window + rect = screens[primaryscreen]->availableGeometry(); + QList< NativeWindow::State > states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State> >(); + if(rect == this->geometry() || states.contains(NativeWindow::S_MAX_VERT) || states.contains(NativeWindow::S_MAX_HORZ)){ + //Already maximized - try to restore it to the previous size/location + if(!lastMaxGeom.isNull()){ + rect = lastMaxGeom; + }else{ + // no last geometry - started out maximized? + // make it half the screen size and centered on the screen + QPoint center = rect.center(); + rect.setWidth( rect.width()/2 ); + rect.setHeight( rect.height()/2 ); + rect.moveTopLeft( center - QPoint(rect.width()/2, rect.height()/2) ); + } + lastMaxGeom = QRect(); //clear this saved geom + }else{ + //Not maximized yet - go ahead and make it so + lastMaxGeom = this->geometry(); //save this for later; + } + //qDebug() << "Toggle Maximize:" << this->geometry() << rect; + QString anim_type = DesktopSettings::instance()->value(DesktopSettings::Animation, "window/move", "random").toString(); + loadAnimation(anim_type, NativeWindow::Size, rect); +} + +void RootSubWindow::triggerClose(){ + WIN->requestClose(); +} + +void RootSubWindow::toggleSticky(){ + QList< NativeWindow::State> states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State > >(); + if(states.contains(NativeWindow::S_STICKY)){ + states.removeAll(NativeWindow::S_STICKY); + }else{ + states << NativeWindow::S_STICKY; + } + WIN->requestProperty(NativeWindow::States, QVariant::fromValue >(states) ); +} + +void RootSubWindow::activate(){ + //WinWidget->raiseWindow(); + WIN->requestProperty(NativeWindow::Active, true, true); +} + +//Mouse Interactivity +void RootSubWindow::startMoving(){ + //If the cursor is not over this window, move it to the center of the titlebar + QPoint curpt = QCursor::pos(); //global coords + if(!this->geometry().contains(curpt)){ + curpt = this->mapToGlobal(titleBar->geometry().center()); + QCursor::setPos(curpt); + } + //Calculate the offset + activeState = Move; + offset = this->mapFromGlobal(curpt); + setMouseCursor(activeState, true); //this one is an override cursor + WinWidget->pause(); + this->grabMouse(); +} + +void RootSubWindow::startResizing(){ + activeState = getStateAtPoint( this->mapFromGlobal(QCursor::pos()), true); //also have it set the offset variable + setMouseCursor(activeState, true); //this one is an override cursor + WinWidget->pause(); + this->grabMouse(); +} + +// === PRIVATE SLOTS === +void RootSubWindow::propertiesChanged(QList props, QList vals){ + for(int i=0; iisPaused() && (this->isVisible()!=vals[i].toBool()) && activeState==Normal ){ + //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); + if(vals[i].toBool()){ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/appear", "random").toString(), NativeWindow::Visible, vals[i]); } + else{ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/disappear", "random").toString(), NativeWindow::Visible, vals[i]); } + } + break; + case NativeWindow::Title: + titleLabel->setText(vals[i].toString()); + break; + case NativeWindow::Icon: + //qDebug() << "Got Icon Change:" << vals[i]; + if(vals[i].value().isNull() ){ LIconCache::instance()->loadIcon(otherB, "list"); } + else{ otherB->setIcon(vals[i].value()); } + break; + case NativeWindow::GlobalPos: + if(vals[i].toPoint()!=QPoint(0,0)){ + WinWidget->resyncWindow(); + } + break; + case NativeWindow::Size: + //qDebug() << " - SIZE CHANGE"; + if(WIN->property(NativeWindow::FrameExtents).isNull() && (iisPaused() && activeState==Normal){ + if(WIN->property(NativeWindow::Size).toSize() != WinWidget->size()){ + //qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); + this->setGeometry( QRect(this->geometry().topLeft(), WIN->geometry().size()) ); + WinWidget->resyncWindow(); + } + } + break; + case NativeWindow::MinSize: + if(vals[i].toSize().isValid()){ + //Just larger than titlebar, with enough space for 8 characters in the titlebar (+4 buttons) + //qDebug() << "Got invalid Min Size: Set a reasonable default minimum"; + WinWidget->setMinimumSize( QSize( this->fontMetrics().height()*4 + this->fontMetrics().width("O")*10, this->fontMetrics().height()*10) ); + WIN->setProperty(NativeWindow::MinSize, WinWidget->minimumSize()); + }else{ + WinWidget->setMinimumSize(vals[i].toSize()); + } + if(WIN->property(NativeWindow::Size).toSize().width() < WinWidget->minimumSize().width() \ + || WIN->property(NativeWindow::Size).toSize().height() < WinWidget->minimumSize().height() ){ + WIN->setProperty(NativeWindow::Size, WinWidget->minimumSize(), true); //force this + //WinWidget->resize(WinWidget->minimumSize()); + } + break; + case NativeWindow::MaxSize: + WinWidget->setMaximumSize(vals[i].toSize()); + break; + case NativeWindow::Active: + if(vals[i].toBool()){ activate(); } //WinWidget->raiseWindow(); } + break; + /*case NativeWindow::FrameExtents: + qDebug() << " - FRAME CHANGE"; + if(vals[i].isNull()){ + vals[i] = QVariant::fromValue >( QList() << WinWidget->geometry().x() << this->width()-WinWidget->geometry().x()-WinWidget->geometry().width() << WinWidget->y() << this->height() - WinWidget->y() - WinWidget->geometry().height() ); + WIN->setProperty(NativeWindow::FrameExtents, vals[i]); + } + qDebug() << "Setting Frame Extents:" << vals[i].value >(); + mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); + break;*/ + case NativeWindow::WinTypes: + //qDebug() << "Got Window Types:" << vals[i].value< QList >(); + enableFrame(vals[i].value< QList >() ); + break; + default: + qDebug() << "Window Property Unused:" << props[i] << vals[i]; + } + } +} + +// === PROTECTED === +void RootSubWindow::mousePressEvent(QMouseEvent *ev){ + activate(); + this->raise(); + QFrame::mousePressEvent(ev); + //qDebug() << "Frame Mouse Press Event"; + if(activeState != Normal){ return; } // do nothing - already in a state of grabbed mouse + offset.setX(0); offset.setY(0); + if(ev->button()==Qt::LeftButton){ + if(this->childAt(ev->pos())!=0){ + //Clicked on the titlebar + startMoving(); + }else{ + //Clicked on the frame somewhere + startResizing(); + } + } + +} + +void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ + QFrame::mouseMoveEvent(ev); + if(activeState == Normal){ + setMouseCursor( getStateAtPoint(ev->pos()) ); //just update the mouse cursor + }else{ + //Currently in a modification state + QRect geom = this->geometry(); + QSize minsize(WinWidget->minimumSize().width() + (2*WIN_BORDER), WinWidget->minimumSize().height()+(2*WIN_BORDER)+titleBar->geometry().size().height()); + switch(activeState){ + case Move: + geom.moveTopLeft(ev->globalPos()-offset); //will not change size + break; + case ResizeTop: + geom.setTop(ev->globalPos().y()-offset.y()); + if(geom.size().height() < minsize.height()){ + geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height + } + break; + case ResizeTopRight: + geom.setTopRight(ev->globalPos()-offset); + if(geom.size().height() < minsize.height()){ + geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height + } + if(geom.size().width() < minsize.width()){ + geom.setRight(geom.x() + minsize.width()); //reset back to min width + } + break; + case ResizeRight: + geom.setRight(ev->globalPos().x()-offset.x()); + if(geom.size().width() < minsize.width()){ + geom.setRight(geom.x() + minsize.width()); //reset back to min width + } + break; + case ResizeBottomRight: + geom.setBottomRight(ev->globalPos()-offset); + if(geom.size().height() < minsize.height()){ + geom.setBottom(geom.y() + minsize.height()); //reset back to min height + } + if(geom.size().width() < minsize.width()){ + geom.setRight(geom.x() + minsize.width()); //reset back to min width + } + break; + case ResizeBottom: + geom.setBottom(ev->globalPos().y()-offset.y()); + if(geom.size().height() < minsize.height()){ + geom.setBottom(geom.y() + minsize.height()); //reset back to min height + } + break; + case ResizeBottomLeft: + geom.setBottomLeft(ev->globalPos()-offset); + if(geom.size().height() < minsize.height()){ + geom.setBottom(geom.y() + minsize.height()); //reset back to min height + } + if(geom.size().width() < minsize.width()){ + geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width + } + break; + case ResizeLeft: + geom.setLeft(ev->globalPos().x()-offset.x()); + if(geom.size().width() < minsize.width()){ + geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width + } + break; + case ResizeTopLeft: + geom.setTopLeft(ev->globalPos()-offset); + if(geom.size().height() < minsize.height()){ + geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height + } + if(geom.size().width() < minsize.width()){ + geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width + } + break; + default: + break; + } + //if( (geom.width()%2==0 && geom.height()%2==0) || activeState==Move){ + //qDebug() << " Change Window:" << this->geometry() << geom; + if(activeState==Move){ this->setGeometry(geom); } + else{ + //qDebug() << " Change Window Dimensions:" << this->geometry() << geom; + //qDebug() << " - Mouse Pos:" << ev->globalPos() << ev->pos() << "Offset" << offset; + this->setGeometry(geom); + } + //} + } +} + +void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){ + //Check for a right-click event + //qDebug() << "Frame Mouse Release Event"; + QFrame::mouseReleaseEvent(ev); + if( (activeState==Normal) && (titleBar->geometry().contains(ev->pos())) && (ev->button()==Qt::RightButton) ){ + //WinWidget->raiseWindow();//need to ensure the native window is always on top of this frame but under the menu + otherM->popup(ev->globalPos()); + return; + } + if(activeState!=Normal){ + if(WinWidget->isPaused()){ WinWidget->resume(); } + activeState = Normal; + QApplication::restoreOverrideCursor(); + setMouseCursor( getStateAtPoint(ev->pos()) ); + } + if(QFrame::mouseGrabber() == this){ this->releaseMouse(); } + activate(); + //QTimer::singleShot(0, WinWidget, SLOT(raiseWindow()) ); +} + +/*void RootSubWindow::enterEvent(QEvent *ev){ + QFrame::enterEvent(ev); + WinWidget->raiseWindow(); +}*/ +/*void RootSubWindow::leaveEvent(QEvent *ev){ + QFrame::leaveEvent(ev); + if(activeState == Normal){ + setMouseCursor(Normal); + } + if(!QRect(QPoint(0,0),this->size()).contains( this->mapFromGlobal(QCursor::pos())) ){ WinWidget->lowerWindow(); } +}*/ + +void RootSubWindow::moveEvent(QMoveEvent *ev){ + //qDebug() << "Got Move Event:" << ev->pos() << WinWidget->geometry(); + QFrame::moveEvent(ev); + if(!closing && !WinWidget->isPaused()){ + moveTimer->start(); + } +} diff --git a/src-qt5/core/libLumina/obsolete/RootSubWindow.h b/src-qt5/core/libLumina/obsolete/RootSubWindow.h new file mode 100644 index 00000000..598298e2 --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.h @@ -0,0 +1,109 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This class embeds a native window +// within the RootWindow area +//=========================================== +#ifndef _LUMINA_ROOT_WINDOW_SUB_WINDOW_H +#define _LUMINA_ROOT_WINDOW_SUB_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RootSubWindow : public QFrame{ + Q_OBJECT +public: + RootSubWindow(QWidget *root, NativeWindow *win); + ~RootSubWindow(); + + WId id(); + NativeWindow* nativeWindow(); + +private: + //Window status + enum ModState{Normal, Move, ResizeTop, ResizeTopRight, ResizeRight, ResizeBottomRight, ResizeBottom, ResizeBottomLeft, ResizeLeft, ResizeTopLeft}; + ModState activeState; + ModState currentCursor; + QPoint offset; //needed for movement calculations (offset from mouse click to movement point) + //Functions for getting/setting state + ModState getStateAtPoint(QPoint pt, bool setoffset = false); //generally used for mouse location detection + void setMouseCursor(ModState, bool override = false); //Update the mouse cursor based on state + + //Native window embed objects + NativeWindow *WIN; + NativeEmbedWidget *WinWidget; + bool closing; + //Title bar objects + QBoxLayout *titleBarL, *mainLayout; + QToolButton *closeB, *maxB, *minB, *otherB; + QLabel *titleLabel; + QMenu *otherM; //menu of other actions + QWidget *titleBar; + //Other random objects (animations,etc) + QPropertyAnimation *anim; + QVariant animResetProp; + QTimer *moveTimer; + QRect lastGeom, lastMaxGeom; //frame coordinates + + void initWindowFrame(); + void enableFrame(bool); + void enableFrame(QList types); + + void LoadProperties( QList< NativeWindow::Property> list); + + static QStringList validAnimations(NativeWindow::Property); + +public slots: + void ensureVisible(){ WIN->setProperty(NativeWindow::Visible, true); } + void giveMouseFocus(){ WinWidget->raiseWindow(); } + void removeMouseFocus(){ WinWidget->lowerWindow(); } + void giveKeyboardFocus(){ WIN->requestProperty(NativeWindow::Active, true, true); } + + void clientClosed(); + void LoadAllProperties(); + + QRect clientGlobalGeom(); + + //Button Actions - public so they can be tied to key shortcuts and stuff as well + void toggleMinimize(); + void toggleMaximize(); + void triggerClose(); + void toggleSticky(); + void activate(); + + //Mouse Interactivity + void startMoving(); + void startResizing(); + +private slots: + void propertiesChanged(QList, QList); + + void loadAnimation(QString name, NativeWindow::Property, QVariant nval); //new val + void animFinished(); + +protected: + void mousePressEvent(QMouseEvent*); + void mouseMoveEvent(QMouseEvent*); + void mouseReleaseEvent(QMouseEvent*); + //void leaveEvent(QEvent *ev); + //void enterEvent(QEvent *ev); + void moveEvent(QMoveEvent *ev); + +signals: + void windowMoved(RootSubWindow*); + void windowAnimFinished(); +}; + +#endif diff --git a/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp new file mode 100644 index 00000000..24ea639b --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp @@ -0,0 +1,95 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2016, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootWindow.h" + +//Primary/private function +void RootWindow::arrangeWindows(RootSubWindow *primary, QString type, bool primaryonly){ + if(type.isEmpty()){ type = "center"; } + if(primary==0){ + //Get the currently active window and treat that as the primary + for(int i=0; inativeWindow()->property(NativeWindow::Active).toBool()){ primary = WINDOWS[i]; } + } + if(primary==0 && !WINDOWS.isEmpty()){ primary = WINDOWS[0]; } //just use the first one in the list + } + //Now get the current screen that the mouse cursor is over (and valid area) + QScreen *screen = screenUnderMouse(); + QRect desktopArea = screen->availableGeometry(); + //qDebug() << "Arrange Windows:" << primary->geometry() << type << primaryonly << desktopArea; + //Now start filtering out all the windows that need to be ignored + int wkspace = primary->nativeWindow()->property(NativeWindow::Workspace).toInt(); + QList winlist = WINDOWS; + for(int i=0; inativeWindow()->property(NativeWindow::Workspace).toInt()!=wkspace + || !winlist[i]->nativeWindow()->property(NativeWindow::Visible).toBool() + || desktopArea.intersected(winlist[i]->geometry()).isNull() ){ + //window is outside of the desired area or invisible - ignore it + winlist.removeAt(i); + i--; + } + } + if(!winlist.contains(primary)){ winlist << primary; } //could be doing this on a window right before it is shown + else if(primaryonly){ winlist.removeAll(primary); winlist << primary; } //move primary window to last + //QRegion used; + for(int i=0; igeometry(); + //verify that the window is contained by the desktop area + if(geom.width()>desktopArea.width()){ geom.setWidth(desktopArea.width()); } + if(geom.height()>desktopArea.height()){ geom.setHeight(desktopArea.height()); } + //Now apply the proper placement routine + if(type=="center"){ + QPoint ct = desktopArea.center(); + winlist[i]->setGeometry( ct.x()-(geom.width()/2), ct.y()-(geom.height()/2), geom.width(), geom.height()); + }else if(type=="snap"){ + + }else if(type=="single_max"){ + winlist[i]->setGeometry( desktopArea.x(), desktopArea.y(), desktopArea.width(), desktopArea.height()); + }else if(type=="under-mouse"){ + QPoint ct = QCursor::pos(); + geom = QRect(ct.x()-(geom.width()/2), ct.y()-(geom.height()/2), geom.width(), geom.height() ); + //Now verify that the top of the window is still contained within the desktop area + if(geom.y() < desktopArea.y() ){ geom.moveTop(desktopArea.y()); } + winlist[i]->setGeometry(geom); + + } + //qDebug() << " - New Geometry:" << winlist[i]->geometry(); + } //end loop over winlist +} + +// ================ +// Public slots for starting the arrangement routine(s) above +// ================ +void RootWindow::ArrangeWindows(WId primary, QString type){ + RootSubWindow* win = windowForId(primary); + if(type.isEmpty()){ type = "center"; } //grab the default arrangement format + arrangeWindows(win, type); +} + +void RootWindow::TileWindows(WId primary, QString type){ + RootSubWindow* win = windowForId(primary); + if(type.isEmpty()){ type = "single_max"; } //grab the default arrangement format for tiling + arrangeWindows(win, type); +} + +void RootWindow::CheckWindowPosition(WId id, bool newwindow){ + //used after a "drop" to validate/snap/re-arrange window(s) as needed + // if "newwindow" is true, then this is the first-placement routine for a window before it initially appears + RootSubWindow* win = windowForId(id); + if(win==0){ return; } //invalid window + QRect geom = win->nativeWindow()->geometry(); + bool changed = false; + //Make sure it is on the screen (quick check) + if(geom.x() < 0){ changed = true; geom.moveLeft(0); } + if(geom.y() < 0){ changed = true; geom.moveTop(0); } + if(geom.width() < 20){ changed = true; geom.setWidth(100); } + if(geom.height() < 20){ changed = true; geom.setHeight(100); } + if(changed){ win->setGeometry(geom); } + //Now run it through the window arrangement routine + arrangeWindows(win, newwindow ?"center" : "snap", true); +} diff --git a/src-qt5/core/libLumina/obsolete/RootWindow.cpp b/src-qt5/core/libLumina/obsolete/RootWindow.cpp new file mode 100644 index 00000000..705297be --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootWindow.cpp @@ -0,0 +1,283 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2016, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootWindow.h" + +#include +#include +#include + +#define DEBUG 0 + +// === PUBLIC === +RootWindow::RootWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ + qRegisterMetaType("WId"); + autoResizeTimer = 0; + lastActiveMouse = 0; + mouseFocusTimer = 0; + this->setMouseTracking(true); +} + +RootWindow::~RootWindow(){ + +} + +void RootWindow::start(){ + + if(autoResizeTimer==0){ + autoResizeTimer = new QTimer(this); + autoResizeTimer->setInterval(100); //1/10 second (collect all nearly-simultaneous signals and compress into a single update) + autoResizeTimer->setSingleShot(true); + connect(autoResizeTimer, SIGNAL(timeout()), this, SLOT(ResizeRoot()) ); + connect(QApplication::desktop(), SIGNAL(resized(int)), autoResizeTimer, SLOT(start()) ); + connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), autoResizeTimer, SLOT(start()) ); + } + if(mouseFocusTimer==0){ + mouseFocusTimer = new QTimer(this); + mouseFocusTimer->setInterval(100); + connect(mouseFocusTimer, SIGNAL(timeout()), this, SLOT(checkMouseFocus()) ); + + } + this->show(); + ResizeRoot(); + emit RegisterVirtualRoot(this->winId()); +} + +// === PRIVATE === +void RootWindow::updateScreenPixmap(screeninfo *info){ + QPixmap pix(info->area.size()); + if(info->scale == RootWindow::SolidColor){ + QColor color; + if(info->file.startsWith("rgb(")){ + QStringList colors = info->file.section(")",0,0).section("(",1,1).split(","); + color = QColor(colors[0].toInt(), colors[1].toInt(), colors[2].toInt()); + }else{ + color = QColor(info->file); + } + pix.fill(color); + }else{ + QPixmap raw(info->file); //load the image from file + //Now apply the proper aspect ratio as needed + if(info->scale == RootWindow::Stretch || info->scale == RootWindow::Full || info->scale == RootWindow::Fit){ + Qt::AspectRatioMode armode = Qt::KeepAspectRatio; + if(info->scale == RootWindow::Stretch ){ armode = Qt::IgnoreAspectRatio; } + else if(info->scale == RootWindow::Full ){ armode = Qt::KeepAspectRatioByExpanding; } + if(raw.height()!=info->area.height() && raw.width() !=info->area.width()){ + raw = raw.scaled(info->area.size(), armode); + } + } + //Now calculate offset and draw width/height + QRect drawRect(0,0, raw.width(), raw.height()); + if(info->scale == RootWindow::Full ){ + drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); + }else if(info->scale == RootWindow::Fit ){ + drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); + }else if(info->scale == RootWindow::Center ){ + drawRect.moveTo( (info->area.width() - raw.width())/2, (info->area.height() - raw.height())/2 ); + }else if(info->scale == RootWindow::Tile ){ + //Draw the entire area - no offset + drawRect.setHeight(info->area.height()); + drawRect.setWidth(info->area.width()); + }else if(info->scale == RootWindow::BottomLeft ){ + drawRect.moveTo( 0 , info->area.height() - raw.height() ); + }else if(info->scale == RootWindow::BottomRight ){ + drawRect.moveTo( (info->area.width() - raw.width()), (info->area.height() - raw.height()) ); + }else if(info->scale == RootWindow::BottomCenter ){ + drawRect.moveTo( (info->area.width() - raw.width())/2, info->area.height() - raw.height() ); + }else if(info->scale == RootWindow::TopLeft ){ + drawRect.moveTo( 0, 0 ); + }else if(info->scale == RootWindow::TopRight ){ + drawRect.moveTo( (info->area.width() - raw.width()), 0); + }else if(info->scale == RootWindow::TopCenter ){ + drawRect.moveTo( (info->area.width() - raw.width())/2, 0); + }else if(info->scale == RootWindow::CenterLeft ){ + drawRect.moveTo( 0, (info->area.height() - raw.height())/2 ); + }else if(info->scale == RootWindow::CenterRight ){ + drawRect.moveTo( (info->area.width() - raw.width()), (info->area.height() - raw.height())/2 ); + } + + QPainter P(&pix); + P.setBrush(raw); + P.setBrushOrigin( drawRect.x(), drawRect.y() ); + P.drawRect( drawRect ); +} //end SolidColor Check + + info->wallpaper = pix; +} + +RootSubWindow* RootWindow::windowForId(WId id){ + RootSubWindow *tmp = 0; + for(int i=0; iid() == id){ tmp = WINDOWS[i]; } + } + return tmp; +} + +QScreen* RootWindow::screenUnderMouse(){ + QPoint mpos = QCursor::pos(); + QList scrns = QApplication::screens(); + for(int i=0; igeometry().contains(mpos)){ return scrns[i]; } + } + //Could not find an exact match - just return the first one + return scrns.first(); +} + +// === PUBLIC SLOTS === +void RootWindow::ResizeRoot(){ + if(DEBUG){ qDebug() << "Resize Root..."; } + QList scrns = QApplication::screens(); + //Update all the screen locations and ID's in the WALLPAPERS list + QRect fullscreen; + QStringList valid; + //Update the size of the rootWindow itself + for(int i=0; iname() << scrns[i]->geometry(); } + fullscreen = fullscreen.united(scrns[i]->geometry()); + valid << scrns[i]->name(); + for(int j=0; jname()){ + QSize oldsize = WALLPAPERS[j].area.size(); + WALLPAPERS[j].area = scrns[i]->geometry(); + if(oldsize != WALLPAPERS[j].area.size()){ updateScreenPixmap(&WALLPAPERS[j]); } + break; + } + } + } + //Now clean up any invalid screen info in the WALLPAPERS List + QStringList invalid; + for(int i=0; isetGeometry(fullscreen); + this->update(); + emit RootResized(fullscreen); + if(!valid.isEmpty()){ emit NewScreens(valid); } + if(!invalid.isEmpty()){ emit RemovedScreens(invalid); } + if(DEBUG){ qDebug() << " - Geom after change:" << this->geometry(); } +} + +void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file){ + bool found = false; + for(int i=0; i scrns = QApplication::screens(); + for(int i=0; iname()==id){ + screeninfo info; + info.id = id; + info.file = file; + info.scale = scale; + info.area = scrns[i]->geometry(); + updateScreenPixmap(&info); + //qDebug() << " --- Loaded Wallpaper:" << info.id << info.file << info.area; + WALLPAPERS << info; + break; + } + } + } //end check for a new id + +} + +void RootWindow::checkMouseFocus(){ + QPoint cpos = QCursor::pos(); + if(lastCursorPos != cpos){ emit MouseMoved(); } + lastCursorPos = cpos; + QWidget *child = this->childAt(QCursor::pos()); + while(child!=0 && child->whatsThis()!="RootSubWindow"){ + child = child->parentWidget(); + if(child==this){ child = 0;} //end of the line + } + + if(child==lastActiveMouse){ return; } //nothing new to do + //Make sure the child is actually a RootSubWindow + if(lastActiveMouse!=0){ lastActiveMouse->removeMouseFocus(); lastActiveMouse = 0; } + if(child!=0){ + lastActiveMouse = static_cast(child); + + if(DesktopSettings::instance()->value(DesktopSettings::WM, "focusFollowsMouse", true).toBool()){ + lastActiveMouse->giveKeyboardFocus(); + if(DesktopSettings::instance()->value(DesktopSettings::WM, "raiseOnFocus", false).toBool()){ + lastActiveMouse->raise(); + } + } + lastActiveMouse->giveMouseFocus(); //always give mouse focus on mouseover + } +} + +void RootWindow::NewWindow(NativeWindow *win){ + RootSubWindow *subwin = 0; + //qDebug() << "Got New Window:" << win->property(NativeWindow::Title); + for(int i=0; iid() == win->id()){ subwin = WINDOWS[i]; } + } + if(subwin==0){ + subwin = new RootSubWindow(this, win); + subwin->setWhatsThis("RootSubWindow"); + connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(CloseWindow(WId)) ); + connect(subwin, SIGNAL(windowAnimFinished()), this, SLOT(checkMouseFocus()) ); + WINDOWS << subwin; + } + //QApplication::processEvents(); + CheckWindowPosition(win->id(), true); //first-time run + //QTimer::singleShot(300, subwin, SLOT(ensureVisible())); + win->setProperty(NativeWindow::Visible, true); + //win->requestProperty( NativeWindow::Active, true); + //win->requestProperties(QList() << NativeWindow::Visible << NativeWindow::Active, QList() << true << true, true); + if(!mouseFocusTimer->isActive()){ mouseFocusTimer->start(); } +} + +void RootWindow::CloseWindow(WId win){ + for(int i=0; iid() == win){ + if(lastActiveMouse==WINDOWS[i]){ lastActiveMouse = 0; } //no longer valid + WINDOWS.takeAt(i)->clientClosed(); + break; + } + } + if(WINDOWS.isEmpty()){ mouseFocusTimer->stop(); } //no windows to look for +} + +// === PRIVATE SLOTS === + +// === PROTECTED === +void RootWindow::paintEvent(QPaintEvent *ev){ + //qDebug() << "RootWindow: PaintEvent:" << ev->rect(); //<< QDateTime::currentDateTime()->toString(QDateTime::ShortDate); + //QWidget::paintEvent(ev); + bool found = false; + QPainter painter(this); + QRect geom = ev->rect(); + geom.adjust(-100,-100,100,100); //give it a few more pixels in each direction to repaint (noticing some issues in Qt 5.7.1) + for(int i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RootSubWindow.h" + +#include +#include + +class RootWindow : public QWidget{ + Q_OBJECT +public: + enum ScaleType{ SolidColor, Stretch, Full, Fit, Center, Tile, BottomLeft, BottomRight, BottomCenter, \ + TopLeft, TopRight, TopCenter, CenterLeft, CenterRight}; + + RootWindow(); + ~RootWindow(); + + void start(); + +private: + struct screeninfo{ + QString id; + QRect area; + QString file; + ScaleType scale; + QPixmap wallpaper; //Note: This pixmap will always be the same size as "area" + }; + QTimer *autoResizeTimer, *mouseFocusTimer; + RootSubWindow *lastActiveMouse; + QPoint lastCursorPos; + + QList WALLPAPERS; + void updateScreenPixmap(screeninfo *info); //used for recalculating the wallpaper pixmap based on file/area/scale as needed + + //Window Management + QList WINDOWS; + RootSubWindow* windowForId(WId id); + void arrangeWindows(RootSubWindow *primary = 0, QString type = "", bool primaryonly = false); + + QScreen* screenUnderMouse(); + + +public slots: + void ResizeRoot(); + void ChangeWallpaper(QString id, RootWindow::ScaleType scale, QString file); + //Note: for "SingleColor" scaling the "file" variable should be "rgb(R,G,B)" or "#hexcode" + void checkMouseFocus(); + + void NewWindow(NativeWindow*); + void CloseWindow(WId); //automatically connected for any new native window + + //Window arrangement functions - defined in "RootWindow-mgmt.cpp" + void ArrangeWindows(WId primary = 0, QString type = ""); + void TileWindows(WId primary = 0, QString type = ""); + void CheckWindowPosition(WId, bool newwindow = false); //used after a "drop" to validate/snap/re-arrange window(s) as needed + +private slots: + +protected: + void paintEvent(QPaintEvent *ev); + +signals: + void RegisterVirtualRoot(WId); + void RootResized(QRect); + void NewScreens(QStringList); // [screen_id_1, screen_id_2, etc..] + void RemovedScreens(QStringList); // [screen_id_1, screen_id_2, etc..] + void WorkspaceChanged(int); + void MouseMoved(); + +}; + +#endif diff --git a/src-qt5/core/libLumina/obsolete/RootWindow.pri b/src-qt5/core/libLumina/obsolete/RootWindow.pri new file mode 100644 index 00000000..9426b6b4 --- /dev/null +++ b/src-qt5/core/libLumina/obsolete/RootWindow.pri @@ -0,0 +1,17 @@ + +# Files +SOURCES *= $${PWD}/RootWindow.cpp \ + $${PWD}/RootWindow-mgmt.cpp \ + $${PWD}/RootSubWindow.cpp \ + $${PWD}/RootSubWindow-animations.cpp + +HEADERS *= $${PWD}/RootWindow.h \ + $${PWD}/RootSubWindow.h + +INCLUDEPATH *= ${PWD} + +# include other library dependencies +include(LUtils.pri) +include(NativeWindow.pri) +include(LIconCache.pri) +include(DesktopSettings.pri) -- cgit From c1b01a5e939aa39b52d13f91ebd73fe1092c4669 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Mon, 16 Oct 2017 09:30:19 -0400 Subject: Update the backend process-running routine for Lumina (LUtils) This gives us an extra function with additional hooks (environment, working directory) It also gets rid of all that ugly QFuture stuff which never quite worked as expected anyway. --- src-qt5/core/libLumina/LUtils.cpp | 80 +++++++++++++++++++++------------------ src-qt5/core/libLumina/LUtils.h | 3 ++ 2 files changed, 47 insertions(+), 36 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp index 491778ca..820b55e8 100644 --- a/src-qt5/core/libLumina/LUtils.cpp +++ b/src-qt5/core/libLumina/LUtils.cpp @@ -14,7 +14,7 @@ #include -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 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 future = QtConcurrent::run(ProcessRun, cmd, args); + return future.result()[1].split("\n"); //Split the return message into lines*/ } QStringList LUtils::readFile(QString filepath){ 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) -- cgit From e152255ec8e2bb7c0604fbbe569d47f345678ea6 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Mon, 16 Oct 2017 11:54:07 -0400 Subject: Clean up the session file-init routine. Now the user files are scanned/created from within the start-lumina-desktop process, not the desktop process. This fixes the loading of the theme engine for the desktop process on first-run situations, and also ensures that the desktop process does not need to make any major changes to it's configs while it is still running. --- src-qt5/core/libLumina/LDesktopUtils.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index fb13a2a3..c65f6faf 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -483,10 +483,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ //Convert from the old desktop numbering system to the new one (change occured with 1.0.1) if(oldversion<=1000001){ QStringList DS = LUtils::readFile(dset); - char *tmp; - int tmpN = 0; - QApplication A(tmpN, &tmp); - QList screens = A.screens(); + QList screens = QApplication::screens(); for(int i=0; i Date: Mon, 16 Oct 2017 21:00:07 -0400 Subject: Updated how video thumbnails are loaded. Now cached to stop crash when resizing. --- src-qt5/core/libLumina/LVideoLabel.cpp | 50 +++++++++++++++++---------------- src-qt5/core/libLumina/LVideoLabel.h | 9 ++++-- src-qt5/core/libLumina/LVideoLabel.pri | 5 +++- src-qt5/core/libLumina/LuminaThemes.cpp | 6 ++++ 4 files changed, 42 insertions(+), 28 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index 20b2cad4..3b2ce468 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -1,40 +1,42 @@ #include "LVideoLabel.h" -LVideoLabel::LVideoLabel(QString file, bool video) : QLabel(){ - this->setScaledContents(true); - if(video) { - mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); - thumbnail = QPixmap(); - entered = false; - surface = new LVideoSurface(this); - mediaPlayer->setVideoOutput(surface); - mediaPlayer->setMedia(QUrl("file://" + file)); - mediaPlayer->setPlaybackRate(3); - mediaPlayer->setMuted(true); - mediaPlayer->play(); - mediaPlayer->pause(); - this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); - this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); - this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); - }else{ - thumbnail = QPixmap(file); - this->setPixmap(thumbnail); - } +LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { + this->setScaledContents(true); + mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + thumbnail = QPixmap(); + this->setPixmap(thumbnail); + entered = false; + surface = new LVideoSurface(this); + mediaPlayer->setVideoOutput(surface); + mediaPlayer->setPlaybackRate(3); + mediaPlayer->setMuted(true); + mediaPlayer->setMedia(QUrl("file://" + file)); + mediaPlayer->play(); + mediaPlayer->pause(); + + this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); + this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); + this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); } LVideoLabel::~LVideoLabel() { mediaPlayer->deleteLater(); - surface->deleteLater(); + delete surface; +} + +void LVideoLabel::setShrinkPixmap(bool shrink) { + this->shrink = shrink; } void LVideoLabel::stopVideo(QPixmap pix) { if(!entered) { + emit frameReceived(pix); if(thumbnail.isNull()) - thumbnail = QPixmap(pix.scaledToHeight(64)); - this->setPixmap(thumbnail); + thumbnail = pix; + this->setPixmap((shrink) ? thumbnail.scaledToHeight(64) : thumbnail); mediaPlayer->pause(); }else { - this->setPixmap(QPixmap(pix.scaledToHeight(64))); + this->setPixmap((shrink) ? pix.scaledToHeight(64) : pix); } } diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h index fd293200..fa590e5a 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -10,21 +10,24 @@ class LVideoLabel : public QLabel { Q_OBJECT public: - LVideoLabel(QString, bool); + LVideoLabel(QString, QWidget* parent=NULL); ~LVideoLabel(); + void setShrinkPixmap(bool); + protected: void enterEvent(QEvent*); void leaveEvent(QEvent*); signals: void rollOver(); - public slots: + void frameReceived(QPixmap); + private slots: void stopVideo(QPixmap); void setDuration(QMediaPlayer::MediaStatus); private: QMediaPlayer *mediaPlayer; LVideoSurface *surface; - QVideoWidget *videoPlayer; QPixmap thumbnail; bool entered; + bool shrink; }; #endif diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri index f609df08..384b3aae 100644 --- a/src-qt5/core/libLumina/LVideoLabel.pri +++ b/src-qt5/core/libLumina/LVideoLabel.pri @@ -1,8 +1,11 @@ QT *= multimedia HEADERS *= $${PWD}/LVideoLabel.h +HEADERS *= $${PWD}/LVideoSurface.h SOURCES *= $${PWD}/LVideoLabel.cpp +SOURCES *= $${PWD}/LVideoSurface.cpp INCLUDEPATH *= ${PWD} -include(LVideoSurface.pri) +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp index f6868651..857e604b 100644 --- a/src-qt5/core/libLumina/LuminaThemes.cpp +++ b/src-qt5/core/libLumina/LuminaThemes.cpp @@ -122,6 +122,8 @@ QStringList LTHEME::availableSystemCursors(){ //returns: [name] for each item //Save a new theme/color file bool LTHEME::saveLocalTheme(QString name, QStringList contents){ + 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); } @@ -129,6 +131,8 @@ bool LTHEME::saveLocalTheme(QString name, QStringList contents){ } bool LTHEME::saveLocalColors(QString name, QStringList contents){ + 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); } @@ -182,6 +186,8 @@ 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"); -- cgit From 7a3e9e46423d999d47e19b26e910c849028599de Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 18 Oct 2017 11:58:59 -0400 Subject: Another quick checkpoint for Lumina 2 files. Nothing too spectacular yet - still in the experimental stage for the QML usage. --- src-qt5/core/libLumina/LuminaXDG.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index ab1000ab..fdf51a11 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -664,11 +664,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 +683,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 +696,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 -- cgit From e5f8846fd775269314e5be502261284b9183205e Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 18 Oct 2017 12:10:10 -0400 Subject: Make LVideoLabel thread-safe. Couple quick fixes for the Browser class in lumina-fm too (minor cleanup). --- src-qt5/core/libLumina/LVideoLabel.cpp | 31 +++++++++++++++++-------------- src-qt5/core/libLumina/LVideoLabel.h | 11 ++++++++--- 2 files changed, 25 insertions(+), 17 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index 3b2ce468..dcc0ad58 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -1,16 +1,28 @@ #include "LVideoLabel.h" - +#include LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { this->setScaledContents(true); - mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); - thumbnail = QPixmap(); - this->setPixmap(thumbnail); + this->setPixmap(thumbnail); //blank pixmap by default entered = false; + filepath = file; + QTimer::singleShot(0, this, SLOT(initializeBackend()) ); +} + +LVideoLabel::~LVideoLabel() { + +} + +void LVideoLabel::setShrinkPixmap(bool shrink) { + this->shrink = shrink; +} + +void LVideoLabel::initializeBackend(){ + mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); surface = new LVideoSurface(this); mediaPlayer->setVideoOutput(surface); mediaPlayer->setPlaybackRate(3); mediaPlayer->setMuted(true); - mediaPlayer->setMedia(QUrl("file://" + file)); + mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); mediaPlayer->play(); mediaPlayer->pause(); @@ -19,15 +31,6 @@ LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); } -LVideoLabel::~LVideoLabel() { - mediaPlayer->deleteLater(); - delete surface; -} - -void LVideoLabel::setShrinkPixmap(bool shrink) { - this->shrink = shrink; -} - void LVideoLabel::stopVideo(QPixmap pix) { if(!entered) { emit frameReceived(pix); diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h index fa590e5a..110e3305 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -1,5 +1,5 @@ -#ifndef LVIDEOLABEL_H -#define LVIDEOLABEL_H +#ifndef LVIDEOLABEL_H +#define LVIDEOLABEL_H #include #include @@ -13,21 +13,26 @@ class LVideoLabel : public QLabel { LVideoLabel(QString, QWidget* parent=NULL); ~LVideoLabel(); void setShrinkPixmap(bool); - + protected: void enterEvent(QEvent*); void leaveEvent(QEvent*); + signals: void rollOver(); void frameReceived(QPixmap); + private slots: + void initializeBackend(); void stopVideo(QPixmap); void setDuration(QMediaPlayer::MediaStatus); + private: QMediaPlayer *mediaPlayer; LVideoSurface *surface; QPixmap thumbnail; bool entered; bool shrink; + QString filepath; }; #endif -- cgit From 3a38773ce20620610e87c84c40ebfd6d2f478203 Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Sat, 21 Oct 2017 17:48:29 -0400 Subject: Finished video thumbnails and roll over playback for lumina-fm and lumina-fileinfo --- src-qt5/core/libLumina/LVideoLabel.cpp | 25 +++++++++++++++++-------- src-qt5/core/libLumina/LVideoLabel.h | 11 ++++++----- src-qt5/core/libLumina/LVideoLabel.pri | 2 ++ src-qt5/core/libLumina/LVideoWidget.cpp | 28 ++++++++++++++++++++++++++++ src-qt5/core/libLumina/LVideoWidget.h | 21 +++++++++++++++++++++ 5 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 src-qt5/core/libLumina/LVideoWidget.cpp create mode 100644 src-qt5/core/libLumina/LVideoWidget.h (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index dcc0ad58..b90cff66 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -1,15 +1,17 @@ #include "LVideoLabel.h" -#include + LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { - this->setScaledContents(true); - this->setPixmap(thumbnail); //blank pixmap by default + thumbnail = QPixmap(); entered = false; + shrink = true; filepath = file; + QTimer::singleShot(0, this, SLOT(initializeBackend()) ); } LVideoLabel::~LVideoLabel() { - + mediaPlayer->deleteLater(); + surface->deleteLater(); } void LVideoLabel::setShrinkPixmap(bool shrink) { @@ -22,6 +24,7 @@ void LVideoLabel::initializeBackend(){ mediaPlayer->setVideoOutput(surface); mediaPlayer->setPlaybackRate(3); mediaPlayer->setMuted(true); + mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); mediaPlayer->play(); mediaPlayer->pause(); @@ -36,10 +39,10 @@ void LVideoLabel::stopVideo(QPixmap pix) { emit frameReceived(pix); if(thumbnail.isNull()) thumbnail = pix; - this->setPixmap((shrink) ? thumbnail.scaledToHeight(64) : thumbnail); + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); mediaPlayer->pause(); }else { - this->setPixmap((shrink) ? pix.scaledToHeight(64) : pix); + this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio)); } } @@ -50,17 +53,23 @@ void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { } } +void LVideoLabel::resizeEvent(QResizeEvent *event) { + if(!thumbnail.isNull()) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + QLabel::resizeEvent(event); +} + void LVideoLabel::enterEvent(QEvent *event) { entered=true; emit rollOver(); mediaPlayer->setPosition(0); mediaPlayer->play(); - QLabel::enterEvent(event); + QWidget::enterEvent(event); } void LVideoLabel::leaveEvent(QEvent *event) { entered=false; mediaPlayer->setPosition(mediaPlayer->duration() / 2); emit rollOver(); - QLabel::leaveEvent(event); + QWidget::leaveEvent(event); } diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h index 110e3305..8c544b16 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -3,11 +3,11 @@ #include #include +#include +#include #include "LVideoSurface.h" -//class LVideoSurface; - -class LVideoLabel : public QLabel { +class LVideoLabel : public QLabel{ Q_OBJECT public: LVideoLabel(QString, QWidget* parent=NULL); @@ -17,13 +17,14 @@ class LVideoLabel : public QLabel { protected: void enterEvent(QEvent*); void leaveEvent(QEvent*); + void resizeEvent(QResizeEvent*); signals: void rollOver(); void frameReceived(QPixmap); private slots: - void initializeBackend(); + void initializeBackend(); void stopVideo(QPixmap); void setDuration(QMediaPlayer::MediaStatus); @@ -33,6 +34,6 @@ class LVideoLabel : public QLabel { QPixmap thumbnail; bool entered; bool shrink; - QString filepath; + QString filepath; }; #endif diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri index 384b3aae..06395c8d 100644 --- a/src-qt5/core/libLumina/LVideoLabel.pri +++ b/src-qt5/core/libLumina/LVideoLabel.pri @@ -2,8 +2,10 @@ 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} diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp new file mode 100644 index 00000000..14490484 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.cpp @@ -0,0 +1,28 @@ +#include "LVideoWidget.h" + +LVideoWidget::LVideoWidget(QString file, QSize iconSize, QWidget *parent) : QWidget(parent) { + flag = false; + iconLabel = new LVideoLabel(file, parent); + textLabel = new QLabel(parent); + + layout = new QHBoxLayout(this); + layout->setAlignment(Qt::AlignLeft | Qt::AlignCenter); + layout->addWidget(iconLabel); + layout->addWidget(textLabel); + layout->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space + + textLabel->setText(file.section("/", -1)); + iconLabel->setFixedSize(iconSize); + iconLabel->setVisible(true); + textLabel->setVisible(true); +} + +LVideoWidget::~LVideoWidget() { + delete iconLabel; + delete textLabel; + delete layout; +} + +void LVideoWidget::setIconSize(QSize iconSize) { + iconLabel->setFixedSize(iconSize); +} diff --git a/src-qt5/core/libLumina/LVideoWidget.h b/src-qt5/core/libLumina/LVideoWidget.h new file mode 100644 index 00000000..c239a697 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.h @@ -0,0 +1,21 @@ +#ifndef LVIDEOWIDGET_H +#define LVIDEOWIDGET_H + +#include "LVideoLabel.h" +#include +#include + +class LVideoWidget : public QWidget { + Q_OBJECT + public: + LVideoWidget(QString, QSize, QWidget* parent=NULL); + ~LVideoWidget(); + void setIconSize(QSize); + + private: + bool flag; + LVideoLabel *iconLabel; + QLabel *textLabel; + QHBoxLayout *layout; +}; +#endif -- cgit From b4bb314391b9d363944b8de91ea2c660675fabc6 Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Sat, 21 Oct 2017 19:19:28 -0400 Subject: Added some testing code for issues with directories having >10 videos --- src-qt5/core/libLumina/LVideoLabel.cpp | 34 ++++++++++++++++++++++++++++++---- src-qt5/core/libLumina/LVideoLabel.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index b90cff66..af23330c 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -1,4 +1,5 @@ #include "LVideoLabel.h" +#include LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { thumbnail = QPixmap(); @@ -27,13 +28,14 @@ void LVideoLabel::initializeBackend(){ mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); mediaPlayer->play(); - mediaPlayer->pause(); 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::stopVideo(QPixmap pix) { if(!entered) { emit frameReceived(pix); @@ -46,19 +48,42 @@ void LVideoLabel::stopVideo(QPixmap pix) { } } +void LVideoLabel::stateChanged(QMediaPlayer::State state) { + //qDebug() << state; +} + void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { - if(status == QMediaPlayer::BufferedMedia) { + //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) { - if(!thumbnail.isNull()) + if(!thumbnail.isNull()) //Resize the current pixmap to match the new size this->setPixmap(thumbnail.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) { entered=true; emit rollOver(); @@ -67,6 +92,7 @@ void LVideoLabel::enterEvent(QEvent *event) { 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) { entered=false; mediaPlayer->setPosition(mediaPlayer->duration() / 2); diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h index 8c544b16..f368c1a8 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -27,6 +27,7 @@ class LVideoLabel : public QLabel{ void initializeBackend(); void stopVideo(QPixmap); void setDuration(QMediaPlayer::MediaStatus); + void stateChanged(QMediaPlayer::State); private: QMediaPlayer *mediaPlayer; -- cgit From 76eb44f51faee92476ed509b700be9bc30be08a7 Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Wed, 25 Oct 2017 17:09:02 -0400 Subject: Fixed image previews with video thumbnails --- src-qt5/core/libLumina/LVideoLabel.cpp | 34 +++++++++++++++++++++------------ src-qt5/core/libLumina/LVideoLabel.h | 5 +++-- src-qt5/core/libLumina/LVideoWidget.cpp | 8 ++++++++ src-qt5/core/libLumina/LVideoWidget.h | 2 ++ 4 files changed, 35 insertions(+), 14 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index af23330c..bc70a292 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -1,10 +1,11 @@ #include "LVideoLabel.h" +#include #include LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { thumbnail = QPixmap(); entered = false; - shrink = true; + icons = true; filepath = file; QTimer::singleShot(0, this, SLOT(initializeBackend()) ); @@ -15,10 +16,6 @@ LVideoLabel::~LVideoLabel() { surface->deleteLater(); } -void LVideoLabel::setShrinkPixmap(bool shrink) { - this->shrink = shrink; -} - void LVideoLabel::initializeBackend(){ mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); surface = new LVideoSurface(this); @@ -35,6 +32,15 @@ void LVideoLabel::initializeBackend(){ 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(LXDG::findIcon("unknown", "").pixmap(this->size())); + icons = false; +} void LVideoLabel::stopVideo(QPixmap pix) { if(!entered) { @@ -85,17 +91,21 @@ void LVideoLabel::resizeEvent(QResizeEvent *event) { //Start playing the video from the beginning when the mouse enters the label void LVideoLabel::enterEvent(QEvent *event) { - entered=true; - emit rollOver(); - mediaPlayer->setPosition(0); - mediaPlayer->play(); + 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) { - entered=false; - mediaPlayer->setPosition(mediaPlayer->duration() / 2); - emit rollOver(); + 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 index f368c1a8..3c6b304c 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -12,7 +12,8 @@ class LVideoLabel : public QLabel{ public: LVideoLabel(QString, QWidget* parent=NULL); ~LVideoLabel(); - void setShrinkPixmap(bool); + void enableIcons(); + void disableIcons(); protected: void enterEvent(QEvent*); @@ -34,7 +35,7 @@ class LVideoLabel : public QLabel{ LVideoSurface *surface; QPixmap thumbnail; bool entered; - bool shrink; + bool icons; QString filepath; }; #endif diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp index 14490484..b9660b10 100644 --- a/src-qt5/core/libLumina/LVideoWidget.cpp +++ b/src-qt5/core/libLumina/LVideoWidget.cpp @@ -26,3 +26,11 @@ LVideoWidget::~LVideoWidget() { 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 index c239a697..6743acb6 100644 --- a/src-qt5/core/libLumina/LVideoWidget.h +++ b/src-qt5/core/libLumina/LVideoWidget.h @@ -11,6 +11,8 @@ class LVideoWidget : public QWidget { LVideoWidget(QString, QSize, QWidget* parent=NULL); ~LVideoWidget(); void setIconSize(QSize); + void disableIcons(); + void enableIcons(); private: bool flag; -- cgit From 1e4bb99764f6012260adb4192604a392bd62bf0a Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Wed, 25 Oct 2017 18:23:38 -0400 Subject: Fixed issues with previews and LVideoWidget sizing --- src-qt5/core/libLumina/LVideoLabel.cpp | 23 ++++++++++++++++------- src-qt5/core/libLumina/LVideoLabel.h | 3 ++- src-qt5/core/libLumina/LVideoWidget.cpp | 12 +++++++----- src-qt5/core/libLumina/LVideoWidget.h | 3 +-- 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp index bc70a292..bddb1cba 100644 --- a/src-qt5/core/libLumina/LVideoLabel.cpp +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -2,11 +2,12 @@ #include #include -LVideoLabel::LVideoLabel(QString file, QWidget *parent) : QLabel(parent) { +LVideoLabel::LVideoLabel(QString file, bool icons, QWidget *parent) : QLabel(parent) { thumbnail = QPixmap(); entered = false; - icons = true; + this->icons = icons; filepath = file; + defaultThumbnail = LXDG::findIcon("unknown", "").pixmap(256,256); QTimer::singleShot(0, this, SLOT(initializeBackend()) ); } @@ -23,6 +24,7 @@ void LVideoLabel::initializeBackend(){ mediaPlayer->setPlaybackRate(3); mediaPlayer->setMuted(true); + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); mediaPlayer->play(); @@ -38,7 +40,7 @@ void LVideoLabel::enableIcons() { } void LVideoLabel::disableIcons() { - this->setPixmap(LXDG::findIcon("unknown", "").pixmap(this->size())); + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); icons = false; } @@ -47,10 +49,12 @@ void LVideoLabel::stopVideo(QPixmap pix) { emit frameReceived(pix); if(thumbnail.isNull()) thumbnail = pix; - this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + if(icons) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); mediaPlayer->pause(); }else { - this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio)); + if(icons) + this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio)); } } @@ -84,8 +88,13 @@ void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { } void LVideoLabel::resizeEvent(QResizeEvent *event) { - if(!thumbnail.isNull()) //Resize the current pixmap to match the new size - this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + //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); } diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h index 3c6b304c..56defb6a 100644 --- a/src-qt5/core/libLumina/LVideoLabel.h +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -10,7 +10,7 @@ class LVideoLabel : public QLabel{ Q_OBJECT public: - LVideoLabel(QString, QWidget* parent=NULL); + LVideoLabel(QString, bool, QWidget* parent=NULL); ~LVideoLabel(); void enableIcons(); void disableIcons(); @@ -34,6 +34,7 @@ class LVideoLabel : public QLabel{ QMediaPlayer *mediaPlayer; LVideoSurface *surface; QPixmap thumbnail; + QPixmap defaultThumbnail; bool entered; bool icons; QString filepath; diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp index b9660b10..f1f74414 100644 --- a/src-qt5/core/libLumina/LVideoWidget.cpp +++ b/src-qt5/core/libLumina/LVideoWidget.cpp @@ -1,20 +1,22 @@ #include "LVideoWidget.h" -LVideoWidget::LVideoWidget(QString file, QSize iconSize, QWidget *parent) : QWidget(parent) { - flag = false; - iconLabel = new LVideoLabel(file, parent); +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->addWidget(iconLabel); - layout->addWidget(textLabel); + 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() { diff --git a/src-qt5/core/libLumina/LVideoWidget.h b/src-qt5/core/libLumina/LVideoWidget.h index 6743acb6..610fd9e5 100644 --- a/src-qt5/core/libLumina/LVideoWidget.h +++ b/src-qt5/core/libLumina/LVideoWidget.h @@ -8,14 +8,13 @@ class LVideoWidget : public QWidget { Q_OBJECT public: - LVideoWidget(QString, QSize, QWidget* parent=NULL); + LVideoWidget(QString, QSize, bool icons, QWidget* parent=NULL); ~LVideoWidget(); void setIconSize(QSize); void disableIcons(); void enableIcons(); private: - bool flag; LVideoLabel *iconLabel; QLabel *textLabel; QHBoxLayout *layout; -- cgit From 76f587abe521794a71604532224b9cf7103ae50e Mon Sep 17 00:00:00 2001 From: ZackaryWelch Date: Wed, 25 Oct 2017 19:02:16 -0400 Subject: Removed debug outputs --- src-qt5/core/libLumina/LVideoSurface.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp index e3e87667..3aaa81f0 100644 --- a/src-qt5/core/libLumina/LVideoSurface.cpp +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -7,17 +7,17 @@ LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { } bool LVideoSurface::present(const QVideoFrame &frame) { - //qDebug() << surfaceFormat().pixelFormat() << frame.pixelFormat() << surfaceFormat().frameSize() << frame.size(); + //qDebug() << surfaceFormat().frameSize() << frame.size(); if(!frameImage.isNull() && !entered) { emit frameReceived(frameImage); return true; } if(frame.isValid()) { - //qDebug() << "Recording Frame" << frame.pixelFormat(); + //qDebug() << "Recording Frame"; + //qDebug() << surfaceFormat().frameSize() << frame.size(); QVideoFrame icon(frame); icon.map(QAbstractVideoBuffer::ReadOnly); - //qDebug() << icon.width() << icon.height(); QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); if((frameImage.isNull() && !entered) or entered) @@ -48,10 +48,13 @@ bool LVideoSurface::start(const QVideoSurfaceFormat &format) { const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); const QSize size = format.frameSize(); - if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) { + //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 true; - } else { - return false; - } + + return (imageFormat != QImage::Format_Invalid && !size.isEmpty()); } -- cgit From 9c5f154c2e8cc1ad388732a0bc3ee9bb42f296c6 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 26 Oct 2017 18:30:51 -0400 Subject: Fix a few places where /net/ files are still checked for existance (pauses/delays the session init) --- src-qt5/core/libLumina/LuminaXDG.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index fdf51a11..53b59165 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -631,7 +631,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 +644,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"; @@ -730,7 +731,7 @@ bool LXDG::checkExec(QString exec){ else{ QStringList paths = QString(getenv("PATH")).split(":"); for(int i=0; i Date: Fri, 27 Oct 2017 09:24:11 -0400 Subject: Ensure that "Exec" and "TryExec" strings with quotes are handled properly. --- src-qt5/core/libLumina/LUtils.cpp | 3 +++ src-qt5/core/libLumina/LuminaXDG.cpp | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp index 820b55e8..65c6ac96 100644 --- a/src-qt5/core/libLumina/LUtils.cpp +++ b/src-qt5/core/libLumina/LUtils.cpp @@ -121,6 +121,9 @@ 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); } + //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/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index 53b59165..aaca7bb1 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){ @@ -727,6 +728,8 @@ 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); } if(exec.startsWith("/")){ return QFile::exists(exec); } else{ QStringList paths = QString(getenv("PATH")).split(":"); @@ -748,7 +751,7 @@ QStringList LXDG::systemApplicationDirs(){ for(int i=0; i Date: Tue, 31 Oct 2017 09:00:24 -0400 Subject: Add an upgrade path for moving theme settings from the old format to the new theme engine. Also turn on the mouse cursor "loading" image again when launching an external process (for 3 seconds) --- src-qt5/core/libLumina/ExternalProcess.h | 4 ++-- src-qt5/core/libLumina/LDesktopUtils.cpp | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index b1e56af8..ce8ff6f5 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -31,7 +31,7 @@ private slots: void processStarting(){ if(!cursorRestored){ QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); - QTimer::singleShot(15000, this, SLOT(resetCursor()) ); + QTimer::singleShot(3000, this, SLOT(resetCursor()) ); } } void processFinished(){ @@ -62,7 +62,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 c65f6faf..db913e1b 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -505,6 +505,40 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ } 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)){ + //Need to migrate theme settings from the old location to the new one + QSettings newtheme(themefile); + 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/"; -- cgit From 4d27f401cdef77b5f2e162615ade2b92a57ae68f Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 31 Oct 2017 09:28:48 -0400 Subject: Finish up the theme engine migration path (works fine now - after some testing). Also some random whitespace cleanup --- src-qt5/core/libLumina/LDesktopUtils.cpp | 5 ++++- src-qt5/core/libLumina/LuminaOS.h | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index db913e1b..f1b3de17 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -509,8 +509,11 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ //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 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/"; 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-.cpp", and use that file in +// To port Lumina to a different operating system, just create a file +// called "LuminaOS-.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[ :::: ]; //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) -- cgit From 91134ecb1e450464acf6e9b99b17fdec26452d76 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 31 Oct 2017 09:55:21 -0400 Subject: Ensure the mouse cursor "busy" icon is used for 3 seconds when launching an external process. --- src-qt5/core/libLumina/ExternalProcess.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index ce8ff6f5..2a6f4949 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -15,6 +15,7 @@ #include #include #include +#include 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) ); + 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()) ); } -- cgit From adf9932d1a1a7a45a786753aca878ed906c25a49 Mon Sep 17 00:00:00 2001 From: q5sys Date: Tue, 31 Oct 2017 10:10:51 -0400 Subject: fix for XDG processing --- src-qt5/core/libLumina/LUtils.cpp | 1 + src-qt5/core/libLumina/LuminaXDG.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp index 65c6ac96..3d3c878a 100644 --- a/src-qt5/core/libLumina/LUtils.cpp +++ b/src-qt5/core/libLumina/LUtils.cpp @@ -123,6 +123,7 @@ 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 diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index aaca7bb1..492a296c 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -729,7 +729,8 @@ bool LFileInfo::isAVFile(){ 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); } + 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(":"); -- cgit From b38e7a9ff3343c9e2bcaec07f5e495f901e15553 Mon Sep 17 00:00:00 2001 From: q5sys Date: Tue, 31 Oct 2017 16:43:23 -0400 Subject: update LSingleApplication to use getuid instead of getlogin --- src-qt5/core/libLumina/LuminaSingleApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') 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()) ); -- cgit From a65d083fc98e36d3dd4b58052f73f44ce029b2ae Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 1 Nov 2017 12:46:48 -0400 Subject: Fix up some whitespace in luminaxdg.cpp --- src-qt5/core/libLumina/LuminaXDG.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index 492a296c..cf9e0af2 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -896,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); @@ -931,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()){ @@ -951,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", ""); } @@ -974,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. will still be caught) @@ -1067,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 -- cgit From e0c84c93d82e19b0aad62e65458fa21b1ae639f2 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Thu, 2 Nov 2017 10:45:01 -0400 Subject: Add parsing of the "/media" directory on FreeBSD to the External Device Paths LOS function. --- src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index b9346565..a1c82fc9 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[ :::: ]; ) -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,23 @@ QStringList LOS::ExternalDevicePaths(){ i--; } } + //Also add info about anything in the "/media" directory + QDir media("/media"); + QFileInfoList list = media.entryInfoList(QDir::NoDotAndDotDot, QDir::Type | QDir::Name); + for(int i=0; i Date: Thu, 2 Nov 2017 11:07:43 -0400 Subject: Finish up the /media parsing for LuminaOS-FreeBSD --- src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index a1c82fc9..6ff144d5 100644 --- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp +++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp @@ -61,8 +61,10 @@ QStringList LOS::ExternalDevicePaths(){ } //Also add info about anything in the "/media" directory QDir media("/media"); - QFileInfoList list = media.entryInfoList(QDir::NoDotAndDotDot, QDir::Type | QDir::Name); + 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 Date: Thu, 2 Nov 2017 11:24:14 -0400 Subject: A bit more cleanup on the external device reporting/usage. --- src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index 6ff144d5..29a58ec9 100644 --- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp +++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp @@ -66,7 +66,7 @@ QStringList LOS::ExternalDevicePaths(){ for(int i=0; i