From 223e28da7a0c67b5ad1e844dbbbd6f4bd7557977 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 31 Jan 2017 14:12:29 -0500 Subject: Get a lot more of Lumina2 working. Now the window embed systems are functional, with 2-way create/show/hide/close detection. Windows do not detect/resize as needed yet though. --- src-qt5/core/libLumina/ExternalProcess.h | 26 ++++++++- src-qt5/core/libLumina/RootSubWindow.cpp | 90 ++++++++++++++++++++++++++++++++ src-qt5/core/libLumina/RootSubWindow.h | 50 ++++++++++++++++++ src-qt5/core/libLumina/RootWindow.cpp | 34 +++++++++++- src-qt5/core/libLumina/RootWindow.h | 13 ++++- src-qt5/core/libLumina/RootWindow.pri | 7 ++- 6 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 src-qt5/core/libLumina/RootSubWindow.cpp create mode 100644 src-qt5/core/libLumina/RootSubWindow.h (limited to 'src-qt5/core/libLumina') diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index 1325247f..8329c361 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -13,17 +13,40 @@ #include #include +#include +#include class ExternalProcess : public QProcess{ Q_OBJECT +private: + bool cursorRestored; + private slots: + void resetCursor(){ + if(!cursorRestored){ + QApplication::restoreOverrideCursor(); + cursorRestored = true; + } + } + void processStarting(){ + if(!cursorRestored){ + QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); + QTimer::singleShot(15000, this, SLOT(resetCursor()) ); + } + } void processFinished(){ + if(!cursorRestored){ + QApplication::restoreOverrideCursor(); + cursorRestored = true; + } //Clean up this object this->deleteLater(); } + public: - ExternalProcess(QString logfile = "") : QProcess(){ + ExternalProcess(QString logfile = "", bool manageCursors = true) : QProcess(){ this->setProcessChannelMode(QProcess::MergedChannels); + cursorRestored = !manageCursors; if(logfile.isEmpty()){ this->setStandardOutputFile(QProcess::nullDevice()); }else{ @@ -32,6 +55,7 @@ public: //Setup the connection for automatic cleanup connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished()) ); } + ~ExternalProcess(){ /*if(this->state() == QProcess::Running){ this->detach(); //about to close down the QProcess - detach the other program so it can continue functioning normally. diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp new file mode 100644 index 00000000..f1d5fe61 --- /dev/null +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -0,0 +1,90 @@ +//=========================================== +// 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 + +// === PUBLIC === +RootSubWindow::RootSubWindow(QMdiArea *root, WId window, Qt::WindowFlags flags) : \ + QMdiSubWindow(0, flags){ + this->setAttribute(Qt::WA_DeleteOnClose); + //Create the QWindow and QWidget containers for the window + closing = false; + CID = window; + WIN = QWindow::fromWinId(CID); + WinWidget = QWidget::createWindowContainer( WIN, this); + this->setWidget(WinWidget); + //Hookup the signals/slots + connect(this, SIGNAL(aboutToActivate()), this, SLOT(aboutToActivate()) ); + connect(WIN, SIGNAL(windowTitleChanged(const QString&)), this, SLOT(setWindowTitle(const QString&)) ); + connect(WIN, SIGNAL(heightChanged(int)), this, SLOT(adjustHeight(int) )); + connect(WIN, SIGNAL(widthChanged(int)), this, SLOT(adjustWidth(int) )); + + qDebug() << "Initial Window Geometry:" << WIN->geometry(); + qDebug() << "Initial Widget Geometry:" << WinWidget->geometry(); + qDebug() << "Minimums:"; + qDebug() << " - Height:" << WIN->minimumHeight(); + qDebug() << " - Width:" << WIN->minimumWidth(); + + //this->resize(WinWidget->size()); + //Now add this window to the root QMdiArea + root->addSubWindow(this); +} + +RootSubWindow::~RootSubWindow(){ + +} + +WId RootSubWindow::id(){ + return CID; +} + +// === PRIVATE === + +// === PUBLIC SLOTS === +void RootSubWindow::clientClosed(){ + qDebug() << "Client Closed"; + closing = true; + this->close(); +} + +void RootSubWindow::clientHidden(){ + qDebug() << "Client Hidden"; + this->hide(); +} + +void RootSubWindow::clientShown(){ + qDebug() << "Client Shown"; + this->show(); +} + +// === PRIVATE SLOTS === +void RootSubWindow::aboutToActivate(){ + emit Activated(CID); //need to activate the subwindow - not the frame + WIN->requestActivate(); +} + +void RootSubWindow::adjustHeight(int val){ + qDebug() << "Adjust height:" << val; + WinWidget->resize(WinWidget->width(), val); +} + +void RootSubWindow::adjustWidth(int val){ + qDebug() << "Adjust Width:" << val; + WinWidget->resize(val, WinWidget->height()); +} + +// === PROTECTED === +void RootSubWindow::closeEvent(QCloseEvent *ev){ + if(!closing){ + qDebug() << "Close Window By Button:" << CID; + ev->ignore(); + WIN->destroy(); + }else{ + QMdiSubWindow::closeEvent(ev); + } + +} diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h new file mode 100644 index 00000000..d4119ccc --- /dev/null +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -0,0 +1,50 @@ +//=========================================== +// 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 + +class RootSubWindow : public QMdiSubWindow{ + Q_OBJECT +public: + RootSubWindow(QMdiArea *root, WId window, Qt::WindowFlags flags = Qt::WindowFlags()); + ~RootSubWindow(); + + WId id(); + +private: + WId CID; //client window ID + QWindow *WIN; //Embedded window container + QWidget *WinWidget; + bool closing; +public slots: + void clientClosed(); + void clientHidden(); + void clientShown(); + +private slots: + void aboutToActivate(); + void adjustHeight(int); + void adjustWidth(int); + +protected: + void closeEvent(QCloseEvent*); + +signals: + void Activated(WId); + +}; + +#endif diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index aa5957b5..57950a48 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -11,7 +11,7 @@ #include // === PUBLIC === -RootWindow::RootWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ +RootWindow::RootWindow() : QMdiArea(0){ //QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ qRegisterMetaType("WId"); autoResizeTimer = 0; } @@ -166,13 +166,43 @@ void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QStrin } +void RootWindow::NewWindow(WId win, Qt::WindowFlags flags){ + RootSubWindow *subwin = 0; + for(int i=0; iid() == win){ subwin = WINDOWS[i]; } + } + if(subwin==0){ + subwin = new RootSubWindow(this, win, flags); + WINDOWS << subwin; + } + subwin->show(); +} + +void RootWindow::ShowWindow(WId win){ + for(int i=0; iid() == win){ WINDOWS[i]->clientShown(); break; } + } +} + +void RootWindow::HideWindow(WId win){ + for(int i=0; iid() == win){ WINDOWS[i]->clientHidden(); break; } + } +} + +void RootWindow::CloseWindow(WId win){ + for(int i=0; iid() == win){ WINDOWS.takeAt(i)->clientClosed(); break; } + } +} + // === PRIVATE SLOTS === // === PROTECTED === void RootWindow::paintEvent(QPaintEvent *ev){ //qDebug() << "RootWindow: PaintEvent:" << ev->rect(); //<< QDateTime::currentDateTime()->toString(QDateTime::ShortDate); bool found = false; - QPainter painter(this); + QPainter painter(this->viewport()); for(int i=0; irect()) ){ found = true; diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/RootWindow.h index b371d239..a653d82a 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/RootWindow.h @@ -18,8 +18,11 @@ #include #include #include +#include -class RootWindow : public QWidget{ +#include "RootSubWindow.h" + +class RootWindow : public QMdiArea{ Q_OBJECT public: enum ScaleType{ SolidColor, Stretch, Full, Fit, Center, Tile, BottomLeft, BottomRight, BottomCenter, \ @@ -43,11 +46,19 @@ private: QList WALLPAPERS; void updateScreenPixmap(screeninfo *info); //used for recalculating the wallpaper pixmap based on file/area/scale as needed + //Window Management + QList WINDOWS; + 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 NewWindow(WId win, Qt::WindowFlags flags = Qt::WindowFlags()); + void ShowWindow(WId win); + void HideWindow(WId win); + void CloseWindow(WId win); + private slots: protected: diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/RootWindow.pri index 7ef3efb0..fac1992d 100644 --- a/src-qt5/core/libLumina/RootWindow.pri +++ b/src-qt5/core/libLumina/RootWindow.pri @@ -1,7 +1,10 @@ # Files -SOURCES *= $${PWD}/RootWindow.cpp -HEADERS *= $${PWD}/RootWindow.h +SOURCES *= $${PWD}/RootWindow.cpp \ + $${PWD}/RootSubWindow.cpp + +HEADERS *= $${PWD}/RootWindow.h \ + $${PWD}/RootSubWindow.h INCLUDEPATH *= ${PWD} -- cgit