diff options
author | Ken Moore <ken@ixsystems.com> | 2018-03-07 15:10:49 -0500 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2018-03-07 15:10:49 -0500 |
commit | 78fa2f5368ce789f8f1fe63d3de5f43bbb4a9308 (patch) | |
tree | 7e93b470d3a489b7e22abd994c07cb7e8cdf4c18 /src-qt5/core/lumina-desktop-unified/src-desktop | |
parent | Fix a missing library dependency for libXCursor (diff) | |
download | lumina-78fa2f5368ce789f8f1fe63d3de5f43bbb4a9308.tar.gz lumina-78fa2f5368ce789f8f1fe63d3de5f43bbb4a9308.tar.bz2 lumina-78fa2f5368ce789f8f1fe63d3de5f43bbb4a9308.zip |
Split the Lumina 2 backend:
Based on a qmake flag, have it use QtWidgets or QML for the front-end renderer.
This will allow us to import/use all the Lumina 1.x interface elements (in Widget form) for now, but switch over to QML interface later without losing all the improvements to the underling events/communication systems.
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified/src-desktop')
12 files changed, 286 insertions, 30 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp index 73cd6645..b94a241d 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp @@ -41,16 +41,20 @@ void DesktopManager::updateWallpaper(QString screen_id, int wkspace){ QStringList wpaperList = DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id+"_wk_"+QString::number(wkspace), QStringList()).toStringList(); //Next look for a list that matches this exact workspace if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default_wk_"+QString::number(wkspace), QStringList()).toStringList(); } + wpaperList.removeAll(""); //Next look for a list that matches this exact screen if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id, QStringList()).toStringList(); } + wpaperList.removeAll(""); //Now look for a list that matches any screen/workspace if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default", QStringList()).toStringList(); } + wpaperList.removeAll(""); //Now use the failover wallpaper directory if(wpaperList.isEmpty()){ QString def = LOS::LuminaShare().section("/",0,-3)+"/wallpapers/lumina-nature"; //Note: LuminaShare() ends with an extra "/" //qDebug() << "Default Wallpaper:" << def; if(QFile::exists(def)){ wpaperList << def; } } + //qDebug() << "Got wallpaper list:" << screen_id << wkspace << wpaperList; //Wallpaper selection/randomization if(wpaperList.count()==1 && wpaperList.first()==current){ return; } //nothing to do - just the same image QString wpaper; @@ -60,6 +64,7 @@ void DesktopManager::updateWallpaper(QString screen_id, int wkspace){ if(!wpaper.isEmpty()){ //Got a directory - update the list of files and re-randomize the selection QStringList imgs = LUtils::imageExtensions(true); + //qDebug() << " - Got Dir: " << imgs; QDir tdir(wpaper); prefix=wpaper+"/"; bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name); @@ -91,7 +96,7 @@ void DesktopManager::updatePlugins(QString plugin_id){ // === PUBLIC SLOTS === void DesktopManager::workspaceChanged(int wknum){ - qDebug() << "Got Workspace Changed:" << wknum; + //qDebug() << "Got Workspace Changed:" << wknum; syncWindowList(); } @@ -117,6 +122,9 @@ void DesktopManager::settingsChanged(DesktopSettings::File type){ void DesktopManager::NewWindowAvailable(NativeWindowObject* win){ //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncWindowList()) ); +#ifdef USE_WIDGETS + qDebug() << "Got New Widget Window:" << win->name(); +#endif syncWindowList(); } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow-QML.cpp index 9664e506..8619544b 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow-QML.cpp @@ -1,6 +1,6 @@ //=========================================== // Lumina-desktop source code -// Copyright (c) 2017, Ken Moore +// Copyright (c) 2017-2018, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== @@ -8,6 +8,8 @@ #include "QMLImageProvider.h" #include <QQmlImageProviderBase> +QQuickView *root_view; + RootWindow::RootWindow() : QObject(){ root_win = QWindow::fromWinId( QX11Info::appRootWindow() ); root_view = new QQuickView(); //make it a child of the root window @@ -35,6 +37,11 @@ void RootWindow::start(){ root_view->show(); } +WId RootWindow::viewID(){ + if(root_view->parent()!=0){ return root_view->parent()->winId(); } + return root_view->winId(); +} + void RootWindow::syncRootSize(){ //qDebug() << "Sync Root Size:" << root_win->width() << root_win->height() << root_view->geometry(); QList<QScreen*> screens = QApplication::screens(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow-Widgets.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow-Widgets.cpp new file mode 100644 index 00000000..6a4c4cb0 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow-Widgets.cpp @@ -0,0 +1,53 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017-2018, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootWindow.h" + +//include the Widgets-based classes we need +#include "RootDesktop.h" + +RootDesktop *root_view; + +RootWindow::RootWindow() : QObject(){ + root_win = QWindow::fromWinId( QX11Info::appRootWindow() ); + root_view = new RootDesktop(root_win); //make it a child of the root window + root_obj = RootDesktopObject::instance(); + syncRootSize(); + connect(root_win, SIGNAL(widthChanged(int)), this, SLOT(syncRootSize()) ); + connect(root_win, SIGNAL(heightChanged(int)),this, SLOT(syncRootSize()) ); +} + +RootWindow::~RootWindow(){ + root_view->deleteLater(); + root_obj->deleteLater(); +} + +void RootWindow::start(){ + root_win->show(); + //if(root_view->parent()!=0){ root_view->parent()->show(); } + root_view->show(); + root_view->start(); + QTimer::singleShot(1000, this, SLOT(syncRootSize()) ); //just in case something changed during init routines +} + +WId RootWindow::viewID(){ + //if(root_view->parent()!=0){ return root_view->parent()->winId(); } + return root_view->winId(); +} + +void RootWindow::syncRootSize(){ + //qDebug() << "Sync Root Size:" << root_win->width() << root_win->height() << root_view->geometry(); + QList<QScreen*> screens = QApplication::screens(); + QRect unif; + for(int i=0; i<screens.length(); i++){ unif = unif.united(screens[i]->geometry()); } + if(unif.width() != root_view->width() || unif.height() != root_view->height()){ + //if(root_view->parent()!=0){ root_view->parent()->setGeometry(0,0,unif.width(), unif.height()); } + root_view->setGeometry(0, 0, unif.width(), unif.height() ); + emit RootResized(root_view->geometry()); + } + root_obj->updateScreens(); + //qDebug() << " - after:" << root_view->geometry(); +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h index 41c75a46..3c7414f2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h @@ -1,6 +1,6 @@ //=========================================== // Lumina-desktop source code -// Copyright (c) 2017, Ken Moore +// Copyright (c) 2017-2018, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== @@ -13,7 +13,6 @@ class RootWindow : public QObject{ Q_OBJECT private: QWindow *root_win; - QQuickView *root_view; RootDesktopObject *root_obj; public: @@ -22,10 +21,7 @@ public: void start(); - WId viewID(){ - if(root_view->parent()!=0){ return root_view->parent()->winId(); } - return root_view->winId(); - } + WId viewID(); public slots: void syncRootSize(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri index ee5ada62..89542e23 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri @@ -1,15 +1,32 @@ -QT *= gui widgets qml quick +QT *= gui widgets -SOURCES *= $${PWD}/RootWindow.cpp \ - $${PWD}/Desktopmanager.cpp \ +#update the includepath so we can just #include as needed without paths +INCLUDEPATH *= $${PWD} + +SOURCES *= $${PWD}/Desktopmanager.cpp \ $${PWD}/QMLImageProvider.cpp HEADERS *= $${PWD}/RootWindow.h \ - $${PWD}/DesktopManager.h \ - $${PWD}/QMLImageProvider.h - -#update the includepath so we can just #include as needed without paths -INCLUDEPATH *= $${PWD} + $${PWD}/DesktopManager.h +#include the base objects include($${PWD}/src-cpp/src-cpp.pri) -include($${PWD}/src-qml/src-qml.pri) + +#Now do the QML/Widgets interface switch +isEmpty(USE_QML){ + #Widgets-based interface + DEFINES += USE_WIDGETS="true" + + SOURCES *= $${PWD}/RootWindow-Widgets.cpp + + include($${PWD}/src-widgets/src-widgets.pri) + +}else{ + #QML-based interface + QT *= qml quick + DEFINES += USE_QML="true" + SOURCES *= $${PWD}/RootWindow-QML.cpp + HEADERS *= $${PWD}/QMLImageProvider.h + + include($${PWD}/src-qml/src-qml.pri) +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp index 5891028c..d9a81f54 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -237,6 +237,11 @@ void RootDesktopObject::launchApp(QString appOrPath){ emit launchApplication(appOrPath); } +//C++ Access Functions (simplifications for the QML ones) +QList<NativeWindowObject*> RootDesktopObject::windowObjects(){ + return window_objects; +} + // === PUBLIC SLOTS === void RootDesktopObject::updateScreens(){ QList<QScreen*> scrns = QApplication::screens(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h index a6a4a236..3c525848 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -55,6 +55,9 @@ public: Q_INVOKABLE void mousePositionChanged(bool lowerall = false); Q_INVOKABLE void launchApp(QString appOrPath); + //C++ Access Functions (simplifications for the QML ones) + QList<NativeWindowObject*> windowObjects(); + private: QList<ScreenObject*> s_objects; QList<PanelObject*> panel_objects; diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp index 47f0e3d7..139eee89 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.cpp @@ -7,6 +7,7 @@ #include "ContextMenu.h" #include <global-objects.h> #include <JsonMenu.h> +#include <LIconCache.h> void DesktopContextMenu::SettingsChanged(DesktopSettings::File file){ if(file == DesktopSettings::ContextMenu){ UpdateMenu(false); } @@ -78,11 +79,11 @@ void DesktopContextMenu::UpdateMenu(bool fast){ } // === PRIVATE === -void DesktopContextMenu::AddWindowToMenu(NativeWindow *win){ - QString label = win->property(NativeWindow::ShortTitle).toString(); - if(label.isEmpty()){ label = win->property(NativeWindow::Title).toString(); } - if(label.isEmpty()){ label = win->property(NativeWindow::Name).toString(); } - QAction *tmp = winMenu->addAction( win->property(NativeWindow::Icon).value<QIcon>(), label, win, SLOT(toggleVisibility()) ); +void DesktopContextMenu::AddWindowToMenu(NativeWindowObject *win){ + QString label = win->property(NativeWindowObject::ShortTitle).toString(); + if(label.isEmpty()){ label = win->property(NativeWindowObject::Title).toString(); } + if(label.isEmpty()){ label = win->property(NativeWindowObject::Name).toString(); } + QAction *tmp = winMenu->addAction( win->property(NativeWindowObject::Icon).value<QIcon>(), label, win, SLOT(toggleVisibility()) ); //Need to change the visual somehow to indicate whether it is visible or not //bool visible = win->property(NativeWindow::Visible).toBool(); // TODO @@ -176,14 +177,8 @@ void DesktopContextMenu::updateWinMenu(){ LIconCache::instance()->loadIcon( winMenu, "preferences-system-windows"); } winMenu->clear(); - QList<NativeWindow*> wins = Lumina::NWS->currentWindows(); - unsigned int wkspace = Lumina::NWS->currentWorkspace(); + QList<NativeWindowObject*> wins = RootDesktopObject::instance()->windowObjects(); for(int i=0; i<wins.length(); i++){ - //First check if this window is in the current workspace (or is "sticky") - if(wins.at(i)->property(NativeWindow::Workspace).toUInt() != wkspace - && wins.at(i)->property(NativeWindow::States).value< QList<NativeWindow::State> >().contains(NativeWindow::S_STICKY) ){ - continue; - } AddWindowToMenu(wins.at(i)); } } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h index 78756e8c..b20087ef 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/ContextMenu.h @@ -21,7 +21,7 @@ private: QMenu *appMenu, *winMenu; bool usewinmenu; - void AddWindowToMenu(NativeWindow*); + void AddWindowToMenu(NativeWindowObject*); public: DesktopContextMenu(QWidget *parent = 0); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp new file mode 100644 index 00000000..9e22a143 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.cpp @@ -0,0 +1,120 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2018, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include <global-objects.h> +#include "RootDesktop.h" + +// === PUBLIC === +RootDesktop::RootDesktop(QWindow *) : QWidget(0, Qt::Widget | Qt::FramelessWindowHint | Qt::WindowStaysOnBottomHint){ + +} + +RootDesktop::~RootDesktop(){ + +} + +void RootDesktop::start(){ + //qDebug() << "Starting RootDesktop" << this->geometry() << this->isVisible(); + bgTimer = new QTimer(this); + bgTimer->setInterval(50); + bgTimer->setSingleShot(true); + connect(bgTimer, SIGNAL(timeout()), this, SLOT(bgTimerUpdate()) ); + + cmenu = new DesktopContextMenu(this); + + //Setup the connections to the main objects + connect(RootDesktopObject::instance(), SIGNAL(screensChanged()), this, SLOT(on_screensChanged()) ); + connect(RootDesktopObject::instance(), SIGNAL(panelsChanged()), this, SLOT(on_panelsChanged()) ); + connect(RootDesktopObject::instance(), SIGNAL(windowsChanged()), this, SLOT(on_windowsChanged()) ); + connect(RootDesktopObject::instance(), SIGNAL(trayWindowsChanged()), this, SLOT(on_trayWindowsChanged()) ); + + connect(cmenu, SIGNAL(LockSession()), RootDesktopObject::instance(), SIGNAL(lockScreen()) ); + connect(cmenu, SIGNAL(showLeaveDialog()), RootDesktopObject::instance(), SIGNAL(startLogout()) ); + connect(cmenu, SIGNAL(LaunchStandardApplication(QString)), RootDesktopObject::instance(), SIGNAL(launchApplication(QString)) ); + connect(cmenu, SIGNAL(LaunchApplication(QString)), RootDesktopObject::instance(), SIGNAL(launchApplication(QString)) ); + + on_screensChanged(); //make sure this is setup right away (sets up connections + QTimer::singleShot(0, this, SLOT(on_panelsChanged()) ); + QTimer::singleShot(2, this, SLOT(on_windowsChanged()) ); + QTimer::singleShot(4, this, SLOT(on_trayWindowsChanged()) ); + + //Now start the first-run of the background change system + cmenu->start(); + bgTimer->start(); + this->show(); +} + +// === PRIVATE === +//QImage bgimage; + + +// === PRIVATE SLOTS === +//RootDesktopObject connections +void RootDesktop::on_screensChanged(){ + QStringList screens = RootDesktopObject::instance()->screens(); + //qDebug() << "Screens Changed:" << lastscreens << screens; + for(int i=0; i<screens.length(); i++){ + if(!lastscreens.contains(screens[i])){ + connect(RootDesktopObject::instance()->screen(screens[i]), SIGNAL(backgroundChanged()), this, SLOT(on_screen_bg_changed()) ); + } + } + on_screen_bg_changed(); //start the timer to update the backgrounds now + lastscreens = screens; //save this for later +} + +void RootDesktop::on_panelsChanged(){ + +} + +void RootDesktop::on_windowsChanged(){ + +} + +void RootDesktop::on_trayWindowsChanged(){ + +} + +void RootDesktop::on_screen_bg_changed(){ + if(!bgTimer->isActive()){ bgTimer->start(); } +} + +//Internal use +void RootDesktop::bgTimerUpdate(){ + //qDebug() << "bgTimerUpdate"; + //QtConcurrent::run(this, &RootDesktop::updateBG, this); + updateBG(this); +} + +void RootDesktop::updateBG(RootDesktop* obj){ + + QImage tmp(obj->size(), QImage::Format_ARGB32_Premultiplied); + QStringList scr = RootDesktopObject::instance()->screens(); + //qDebug() << "updateBG" << scr << tmp.size() << obj->geometry(); + QPainter imgpaint(&tmp); + for(int i=0; i<scr.length(); i++){ + ScreenObject * screen = RootDesktopObject::instance()->screen(scr[i]); + QString file = screen->background(); //in URL format + //qDebug() << "Got BG File:" << file << QUrl(file).toLocalFile(); + QImage img(QUrl(file).toLocalFile()); + //qDebug() << " - BG File is null:" << img.isNull(); + imgpaint.drawImage(screen->geometry(), img, QRect(0,0,img.width(), img.height()) ); + } + bgimage = tmp; + //QTimer::singleShot(0, obj, SLOT(update()) ); + obj->update(); +} + +// === PROTECTED === +void RootDesktop::paintEvent(QPaintEvent *ev){ + //qDebug() << "Paint Event:" << bgimage.isNull(); + if (!bgimage.isNull()) { + //qDebug() << "Wallpaper paint Event:" << ev->rect(); + QPainter painter(this); + painter.drawImage(ev->rect(), bgimage, ev->rect()); + }else{ + QWidget::paintEvent(ev); + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h new file mode 100644 index 00000000..16ce0e47 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/RootDesktop.h @@ -0,0 +1,44 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2018, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_WIDGETS_ROOT_DESKTOP_H +#define _LUMINA_DESKTOP_WIDGETS_ROOT_DESKTOP_H + +#include <global-includes.h> +#include "ContextMenu.h" + +class RootDesktop : public QWidget{ + Q_OBJECT +public: + RootDesktop(QWindow *root); + ~RootDesktop(); + + void start(); + +private: + QImage bgimage; + QStringList lastscreens; + QTimer *bgTimer; + DesktopContextMenu *cmenu; + +private slots: + //RootDesktopObject connections + void on_screensChanged(); + void on_panelsChanged(); + void on_windowsChanged(); + void on_trayWindowsChanged(); + void on_screen_bg_changed(); + + //Internal use + void bgTimerUpdate(); + void updateBG(RootDesktop* obj); //designed to be run in a background thread + +protected: + virtual void paintEvent(QPaintEvent *ev); + +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri new file mode 100644 index 00000000..7994bb93 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-widgets/src-widgets.pri @@ -0,0 +1,8 @@ +#update the includepath so we can just #include as needed without paths +INCLUDEPATH *= $${PWD} + +SOURCES *= $${PWD}/RootDesktop.cpp \ + $${PWD}/ContextMenu.cpp + +HEADERS *= $${PWD}/RootDesktop.h \ + $${PWD}/ContextMenu.h |