diff options
29 files changed, 413 insertions, 329 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index ed4d644b..69c42c73 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -7,9 +7,8 @@ #include "LSession.h" #include "global-objects.h" -#include "src-desktop/ContextMenu.h" - #include "BootSplash.h" + #ifndef DEBUG #define DEBUG 1 #endif @@ -27,8 +26,8 @@ DesktopManager* Lumina::DESKMAN = 0; LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop-unified"){ //Initialize the global objects to null pointers qRegisterMetaType< Qt::Key >("Qt::Key"); - qRegisterMetaType< NativeWindow::Property >("NativeWindow::Property"); - qRegisterMetaType< QList< NativeWindow::Property > >("QList<NativeWindow::Property>"); + qRegisterMetaType< NativeWindowObject::Property >("NativeWindowObject::Property"); + qRegisterMetaType< QList< NativeWindowObject::Property > >("QList<NativeWindowObject::Property>"); qRegisterMetaType< NativeWindowSystem::MouseButton >("NativeWindowSystem::MouseButton"); mediaObj = 0; //private object used for playing login/logout chimes @@ -113,7 +112,7 @@ void LSession::setupSession(){ Lumina::DESKMAN->start(); Lumina::ROOTWIN->start(); //Initialize the internal variables - //DESKTOPS.clear(); + //Start the background system tray splash.showScreen("systray"); @@ -122,50 +121,18 @@ void LSession::setupSession(){ splash.showScreen("apps"); if(DEBUG){ qDebug() << " - Populate App List:" << timer->elapsed();} Lumina::APPLIST->updateList(); - //appmenu = new AppMenu(); + splash.showScreen("menus"); - //if(DEBUG){ qDebug() << " - Init SettingsMenu:" << timer->elapsed();} - //settingsmenu = new SettingsMenu(); - //if(DEBUG){ qDebug() << " - Init SystemWindow:" << timer->elapsed();} - //sysWindow = new SystemWindow(); + //Initialize the desktops splash.showScreen("desktop"); - /*if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed(); } - QList<QScreen*> scrns= QApplication::screens(); - for(int i=0; i<scrns.length(); i++){ - qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name(); - RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() ); - }*/ - - if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; } - - /*DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); - connect(cmenu, SIGNAL(showLeaveDialog()), this, SLOT(StartLogout()) ); - cmenu->start();*/ - //desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst); - //updateDesktops(); //for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running //Now setup the system watcher for changes splash.showScreen("final"); - //if(DEBUG){ qDebug() << " - Init QFileSystemWatcher:" << timer->elapsed();} - /*watcher = new QFileSystemWatcher(this); - QString confdir = sessionsettings->fileName().section("/",0,-2); - watcherChange(sessionsettings->fileName() ); - watcherChange( confdir+"/desktopsettings.conf" ); - watcherChange( confdir+"/fluxbox-init" ); - watcherChange( confdir+"/fluxbox-keys" ); - watcherChange( confdir+"/favorites.list" ); - //Try to watch the localized desktop folder too - if(QFile::exists(QDir::homePath()+"/"+tr("Desktop"))){ watcherChange( QDir::homePath()+"/"+tr("Desktop") ); } - watcherChange( QDir::homePath()+"/Desktop" );*/ - - //connect internal signals/slots - //connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherChange(QString)) ); - //connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherChange(QString)) ); - //connect(this, SIGNAL(aboutToQuit()), this, SLOT(SessionEnding()) ); + if(DEBUG){ qDebug() << " - Start Screen Saver:" << timer->elapsed();} Lumina::SS->start(); @@ -236,16 +203,17 @@ void LSession::setupGlobalConnections(){ connect(RootDesktopObject::instance(), SIGNAL(mouseMoved()), Lumina::SS, SLOT(newInputEvent()) ); connect(RootDesktopObject::instance(), SIGNAL(startLogout()), this, SLOT(StartLogout()) ); connect(RootDesktopObject::instance(), SIGNAL(lockScreen()), Lumina::SS, SLOT(LockScreenNow()) ); + connect(RootDesktopObject::instance(), SIGNAL(launchApplication(QString)), this, SLOT(LaunchStandardApplication(QString)) ); //Native Window Class connections connect(Lumina::NEF, SIGNAL(WindowCreated(WId)), Lumina::NWS, SLOT(NewWindowDetected(WId))); connect(Lumina::NEF, SIGNAL(WindowDestroyed(WId)), Lumina::NWS, SLOT(WindowCloseDetected(WId))); - connect(Lumina::NEF, SIGNAL(WindowPropertyChanged(WId, NativeWindow::Property)), Lumina::NWS, SLOT(WindowPropertyChanged(WId, NativeWindow::Property))); - connect(Lumina::NEF, SIGNAL(WindowPropertiesChanged(WId, QList<NativeWindow::Property>)), Lumina::NWS, SLOT(WindowPropertiesChanged(WId, QList<NativeWindow::Property>)) ); - connect(Lumina::NEF, SIGNAL(WindowPropertyChanged(WId, NativeWindow::Property, QVariant)), Lumina::NWS, SLOT(WindowPropertyChanged(WId, NativeWindow::Property, QVariant))); - connect(Lumina::NEF, SIGNAL(WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>)), Lumina::NWS, SLOT(WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>)) ); - connect(Lumina::NEF, SIGNAL(RequestWindowPropertyChange(WId, NativeWindow::Property, QVariant)), Lumina::NWS, SLOT(RequestPropertyChange(WId, NativeWindow::Property, QVariant))); - connect(Lumina::NEF, SIGNAL(RequestWindowPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>)), Lumina::NWS, SLOT(RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>))); + connect(Lumina::NEF, SIGNAL(WindowPropertyChanged(WId, NativeWindowObject::Property)), Lumina::NWS, SLOT(WindowPropertyChanged(WId, NativeWindowObject::Property))); + connect(Lumina::NEF, SIGNAL(WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>)), Lumina::NWS, SLOT(WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>)) ); + connect(Lumina::NEF, SIGNAL(WindowPropertyChanged(WId, NativeWindowObject::Property, QVariant)), Lumina::NWS, SLOT(WindowPropertyChanged(WId, NativeWindowObject::Property, QVariant))); + connect(Lumina::NEF, SIGNAL(WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>, QList<QVariant>)), Lumina::NWS, SLOT(WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>, QList<QVariant>)) ); + connect(Lumina::NEF, SIGNAL(RequestWindowPropertyChange(WId, NativeWindowObject::Property, QVariant)), Lumina::NWS, SLOT(RequestPropertyChange(WId, NativeWindowObject::Property, QVariant))); + connect(Lumina::NEF, SIGNAL(RequestWindowPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>)), Lumina::NWS, SLOT(RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>))); connect(Lumina::NEF, SIGNAL(TrayWindowCreated(WId)), Lumina::NWS, SLOT(NewTrayWindowDetected(WId))); connect(Lumina::NEF, SIGNAL(TrayWindowDestroyed(WId)), Lumina::NWS, SLOT(WindowCloseDetected(WId))); connect(Lumina::NEF, SIGNAL(PossibleDamageEvent(WId)), Lumina::NWS, SLOT(CheckDamageID(WId))); @@ -273,7 +241,11 @@ void LSession::setupGlobalConnections(){ connect(Lumina::NWS, SIGNAL(MouseReleaseDetected(WId, NativeWindowSystem::MouseButton)), Lumina::SHORTCUTS, SLOT(MouseRelease(WId, NativeWindowSystem::MouseButton)) ); //NWS Events to the window system - connect(Lumina::NWS, SIGNAL(NewWindowAvailable(NativeWindow*)), Lumina::ROOTWIN, SLOT(NewWindow(NativeWindow*)) ); + connect(Lumina::NWS, SIGNAL(NewWindowAvailable(NativeWindowObject*)), Lumina::DESKMAN, SLOT(NewWindowAvailable(NativeWindowObject*)) ); + connect(Lumina::NWS, SIGNAL(WindowClosed()), Lumina::DESKMAN, SLOT(syncWindowList()) ); + connect(Lumina::NWS, SIGNAL(NewTrayWindowAvailable(NativeWindowObject*)), Lumina::DESKMAN, SLOT(NewTrayWindowAvailable(NativeWindowObject*)) ); + connect(Lumina::NWS, SIGNAL(TrayWindowClosed()), Lumina::DESKMAN, SLOT(syncTrayWindowList()) ); + } //================= diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index fbc3c4f7..2ca8af15 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -69,15 +69,12 @@ #include <LuminaSingleApplication.h> #include <DesktopSettings.h> #include <ExternalProcess.h> -#include <NativeWindow.h> -#include <NativeWindowSystem.h> -#include <NativeEventFilter.h> #include <XDGMime.h> #include <LIconCache.h> #include <LFileInfo.h> // C++ Backend classes for QML interface -#include <RootDesktopObject.h> +#include <NativeWindowObject.h> #include <ScreenObject.h> //Setup any global defines (no classes or global objects: use "global-objects.h" for that) diff --git a/src-qt5/core/lumina-desktop-unified/global-objects.h b/src-qt5/core/lumina-desktop-unified/global-objects.h index 4cea60c2..bba55b84 100644 --- a/src-qt5/core/lumina-desktop-unified/global-objects.h +++ b/src-qt5/core/lumina-desktop-unified/global-objects.h @@ -21,10 +21,14 @@ //#ifndef USE_WAYLAND //#include "src-events/LXcbEventFilter.h" //#endif + +#include "src-events/NativeWindowSystem.h" +#include "src-events/NativeEventFilter.h" +#include "src-desktop/src-cpp/RootDesktopObject.h" + #include "src-events/LShortcutEvents.h" #include "src-desktop/DesktopManager.h" #include "src-screensaver/LScreenSaver.h" -//#include "src-WM/LWindowManager.h" #include <RootWindow.h> #include "LSession.h" diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index bb987e25..07781770 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -1,11 +1,11 @@ include($${PWD}/../../OS-detect.pri) lessThan(QT_MAJOR_VERSION, 5) { - message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") + message("[ERROR] Qt 5.7+ is required to use the Lumina Desktop!") exit } -lessThan(QT_MINOR_VERSION, 4){ - message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") +lessThan(QT_MINOR_VERSION, 7){ + message("[ERROR] Qt 5.7+ is required to use the Lumina Desktop!") exit } @@ -21,14 +21,13 @@ include(../libLumina/LuminaXDG.pri) include(../libLumina/LuminaSingleApplication.pri) include(../libLumina/DesktopSettings.pri) include(../libLumina/ExternalProcess.pri) -include(../../src-cpp/NativeWindow.pri) include(../libLumina/XDGMime.pri) include(../../src-cpp/plugins-base.pri) #include all the main individual source groups -include(src-screensaver/screensaver.pri) include(src-events/events.pri) +include(src-screensaver/screensaver.pri) include(src-desktop/desktop.pri) TEMPLATE = app @@ -44,12 +43,6 @@ HEADERS += global-includes.h \ FORMS += BootSplash.ui - - -#Now include all the files for the various plugins -#include(panel-plugins/panel-plugins.pri) -#include(desktop-plugins/desktop-plugins.pri) - # Install all the various files for the desktop itself desktop.path = $${L_SESSDIR} desktop.files = lumina-desktop.desktop 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 d6d06be9..b9ea3078 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp @@ -76,7 +76,7 @@ void DesktopManager::updateWallpaper(QString screen_id, int wkspace){ } //Now go ahead and set the wallpaper in the screen object if(wpaper.isEmpty() || wpaper=="default"){ wpaper = LOS::LuminaShare()+"desktop-background.jpg"; } //failover image - qDebug() << "Updating Wallpaper:" << screen_id << wpaper; + //qDebug() << "Updating Wallpaper:" << screen_id << wpaper; RootDesktopObject::instance()->ChangeWallpaper(screen_id,QUrl::fromLocalFile(wpaper).toString() ); } @@ -91,7 +91,7 @@ void DesktopManager::updatePlugins(QString plugin_id){ // === PUBLIC SLOTS === void DesktopManager::workspaceChanged(int wknum){ qDebug() << "Got Workspace Changed:" << wknum; - + syncWindowList(); } void DesktopManager::settingsChanged(DesktopSettings::File type){ @@ -112,6 +112,35 @@ void DesktopManager::settingsChanged(DesktopSettings::File type){ } } +void DesktopManager::NewWindowAvailable(NativeWindowObject* win){ + //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncWindowList()) ); + syncWindowList(); +} + +void DesktopManager::NewTrayWindowAvailable(NativeWindowObject* win){ + //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncTrayWindowList()) ); + syncTrayWindowList(); +} + +void DesktopManager::syncWindowList(){ + QList<NativeWindowObject*> allWins = Lumina::NWS->currentWindows(); + //Filter out all the windows not in the current workspace + QList<NativeWindowObject*> current; + QList<NativeWindowObject*> currentStacked; + int wkspace = Lumina::NWS->currentWorkspace(); + for(int i=0; i<allWins.length(); i++){ + if(allWins[i]->isSticky() || (allWins[i]->workspace() == wkspace)){ + current << allWins[i]; + } + } + //qDebug() << "Synced Window List:" << current.length(); + RootDesktopObject::instance()->setWindows(current); +} + +void DesktopManager::syncTrayWindowList(){ + +} + // === PRIVATE SLOTS === void DesktopManager::updateDesktopSettings(){ qDebug() << "Update Desktop Settings..."; @@ -136,4 +165,3 @@ void DesktopManager::updateMenuSettings(){ void DesktopManager::updateAnimationSettings(){ } - diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h index df681afa..d4a0cf79 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h @@ -30,6 +30,12 @@ public slots: void workspaceChanged(int); void settingsChanged(DesktopSettings::File); + void NewWindowAvailable(NativeWindowObject*); + void NewTrayWindowAvailable(NativeWindowObject*); + + void syncWindowList(); + void syncTrayWindowList(); + private slots: void updateDesktopSettings(); void updatePanelSettings(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp index 47f0e3d7..47f0e3d7 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h index 78756e8c..78756e8c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h 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 ba489465..9cf42f3c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h @@ -7,6 +7,7 @@ #ifndef _LUMINA_DESKTOP_ROOT_WINDOW_H #define _LUMINA_DESKTOP_ROOT_WINDOW_H #include <global-includes.h> +#include "src-cpp/RootDesktopObject.h" class RootWindow : public QObject{ Q_OBJECT diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp index a1b8dbbb..dcfd23b0 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp @@ -7,6 +7,7 @@ #include "NativeWindowObject.h" #include <QQmlEngine> #include <QDebug> +#include <QBuffer> // == QML Type Registration == void NativeWindowObject::RegisterType(){ @@ -60,6 +61,16 @@ QVariant NativeWindowObject::property(NativeWindowObject::Property prop){ void NativeWindowObject::setProperty(NativeWindowObject::Property prop, QVariant val, bool force){ if(prop == NativeWindowObject::RelatedWindows){ relatedTo = val.value< QList<WId> >(); } else if(prop == NativeWindowObject::None || (!force && hash.value(prop)==val)){ return; } + else if(prop == NativeWindowObject::WinImage){ + //special case - QImage is passed in, but QString is passed out (needed for QML) + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + val.value<QImage>().save(&buffer, "PNG"); + QString img("data:image/png:base64,"); + img.append(QString::fromLatin1(ba.toBase64().data())); + hash.insert(prop, img); //save the string instead + } else{ hash.insert(prop, val); } emitSinglePropChanged(prop); emit PropertiesChanged(QList<NativeWindowObject::Property>() << prop, QList<QVariant>() << val); @@ -68,8 +79,20 @@ void NativeWindowObject::setProperty(NativeWindowObject::Property prop, QVariant void NativeWindowObject::setProperties(QList<NativeWindowObject::Property> props, QList<QVariant> vals, bool force){ for(int i=0; i<props.length(); i++){ if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindowObject::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]); + if(props[i] == NativeWindowObject::None || (!force && (hash.value(props[i]) == vals[i])) ){ + props.removeAt(i); vals.removeAt(i); i--; continue; //Invalid property or identical value + }else if(props[i] == NativeWindowObject::WinImage){ + //special case - QImage is passed in, but QString is passed out (needed for QML) + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + vals[i].value<QImage>().save(&buffer, "PNG"); + QString img("data:image/png:base64,"); + img.append(QString::fromLatin1(ba.toBase64().data())); + hash.insert(props[i], img); //save the string instead + }else{ + hash.insert(props[i], vals[i]); + } emitSinglePropChanged(props[i]); } emit PropertiesChanged(props, vals); @@ -117,8 +140,8 @@ QRect NativeWindowObject::geometry(){ } // QML ACCESS FUNCTIONS (shortcuts for particular properties in a format QML can use) -QImage NativeWindowObject::winImage(){ - return this->property(NativeWindowObject::WinImage).value<QImage>(); +QString NativeWindowObject::winImage(){ + return this->property(NativeWindowObject::WinImage).toString(); } QString NativeWindowObject::name(){ @@ -130,7 +153,10 @@ QString NativeWindowObject::title(){ } QString NativeWindowObject::shortTitle(){ - return this->property(NativeWindowObject::ShortTitle).toString(); + QString tmp = this->property(NativeWindowObject::ShortTitle).toString(); + if(tmp.isEmpty()){ tmp = title(); } + if(tmp.isEmpty()){ tmp = name(); } + return tmp; } QIcon NativeWindowObject::icon(){ @@ -215,6 +241,10 @@ bool NativeWindowObject::isSticky(){ return (this->property(NativeWindowObject::Workspace).toInt()<0 || this->property(NativeWindowObject::States).value<QList<NativeWindowObject::State> >().contains(NativeWindowObject::S_STICKY) ); } +int NativeWindowObject::workspace(){ + return this->property(NativeWindowObject::Workspace).toInt(); +} + //QML Geometry reporting QRect NativeWindowObject::frameGeometry(){ return geometry(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h index 8a8504aa..e4f9d41e 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h @@ -17,7 +17,7 @@ class NativeWindowObject : public QObject{ Q_OBJECT // QML-ACCESSIBLE PROPERTIES - Q_PROPERTY( QImage winImage READ winImage NOTIFY winImageChanged) + Q_PROPERTY( QString winImage READ winImage NOTIFY winImageChanged) Q_PROPERTY( QString name READ name NOTIFY nameChanged) Q_PROPERTY( QString title READ title NOTIFY titleChanged) Q_PROPERTY( QString shortTitle READ shortTitle NOTIFY shortTitleChanged) @@ -92,7 +92,7 @@ public: Q_INVOKABLE QRect geometry(); //this returns the "full" geometry of the window (window + frame) // QML ACCESS FUNCTIONS (shortcuts for particular properties in a format QML can use) - Q_INVOKABLE QImage winImage(); + Q_INVOKABLE QString winImage(); Q_INVOKABLE QString name(); Q_INVOKABLE QString title(); Q_INVOKABLE QString shortTitle(); @@ -106,6 +106,7 @@ public: Q_INVOKABLE bool showWindowFrame(); //QML Window States Q_INVOKABLE bool isSticky(); + Q_INVOKABLE int workspace(); //QML Geometry reporting Q_INVOKABLE QRect frameGeometry(); 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 4b01fa0d..39dc30c1 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 @@ -27,6 +27,7 @@ void RootDesktopObject::RegisterType(){ qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject"); //Also register any types that are needed by this class ScreenObject::RegisterType(); + NativeWindowObject::RegisterType(); } RootDesktopObject* RootDesktopObject::instance(){ @@ -36,14 +37,14 @@ RootDesktopObject* RootDesktopObject::instance(){ //QML Read Functions QStringList RootDesktopObject::screens(){ - qDebug() << "Request Screens:" << s_objects.length(); + //qDebug() << "Request Screens:" << s_objects.length(); QStringList names; for(int i=0; i<s_objects.length(); i++){ names << s_objects[i]->name(); } return names; } ScreenObject* RootDesktopObject::screen(QString id){ - qDebug() << "Got Screen Request:" << id; + //qDebug() << "Got Screen Request:" << id; for(int i=0; i<s_objects.length(); i++){ if(s_objects[i]->name()==id){ return s_objects[i]; } } @@ -72,7 +73,7 @@ QStringList RootDesktopObject::windows(){ return names; } -NativeWindow* RootDesktopObject::window(QString id){ +NativeWindowObject* RootDesktopObject::window(QString id){ //qDebug() << "Got Panel Request:" << id; WId chk = id.toInt(); //numerical ID's in this case for(int i=0; i<window_objects.length(); i++){ @@ -86,7 +87,7 @@ void RootDesktopObject::setPanels(QList<PanelObject*> list){ emit panelsChanged(); } -void RootDesktopObject::setWindows(QList<NativeWindow*> list){ +void RootDesktopObject::setWindows(QList<NativeWindowObject*> list){ window_objects = list; emit windowsChanged(); } @@ -103,6 +104,10 @@ void RootDesktopObject::mousePositionChanged(){ emit mouseMoved(); } +void RootDesktopObject::launchApp(QString appOrPath){ + emit launchApplication(appOrPath); +} + // === 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 7d5182c4..a4236596 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 @@ -8,11 +8,8 @@ //=========================================== #ifndef _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H #define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H -#include <QObject> -#include <QList> #include <global-includes.h> - -#include "ScreenObject.h" +#include <ScreenObject.h> class RootDesktopObject : public QObject{ Q_OBJECT @@ -37,26 +34,27 @@ public: Q_INVOKABLE QStringList panels(); Q_INVOKABLE PanelObject* panel(QString id); Q_INVOKABLE QStringList windows(); - Q_INVOKABLE NativeWindow* window(QString id); - - void setPanels(QList<PanelObject*> list); - void setWindows(QList<NativeWindow*> list); + Q_INVOKABLE NativeWindowObject* window(QString id); //QML Access Functions Q_INVOKABLE void logout(); Q_INVOKABLE void lockscreen(); Q_INVOKABLE void mousePositionChanged(); + Q_INVOKABLE void launchApp(QString appOrPath); private: QList<ScreenObject*> s_objects; QList<PanelObject*> panel_objects; - QList<NativeWindow*> window_objects; + QList<NativeWindowObject*> window_objects; public slots: void updateScreens(); //rescan/update screen objects void ChangeWallpaper(QString screen, QString); QString CurrentWallpaper(QString screen); + void setPanels(QList<PanelObject*> list); + void setWindows(QList<NativeWindowObject*> list); + private slots: signals: @@ -67,6 +65,6 @@ signals: void startLogout(); void mouseMoved(); void lockScreen(); - + void launchApplication(QString); }; #endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp index 82622403..1b22c450 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -22,7 +22,7 @@ void ScreenObject::RegisterType(){ } QString ScreenObject::name(){ return bg_screen->name(); } -QString ScreenObject::background(){ qDebug() << "Got Background:" << bg_screen->name() << bg << bg_screen->geometry(); return bg; } +QString ScreenObject::background(){ return bg; } int ScreenObject::x(){ return bg_screen->geometry().x(); } int ScreenObject::y(){ return bg_screen->geometry().y(); } int ScreenObject::width(){ return bg_screen->geometry().width(); } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml index 4ab8e156..778d7568 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml @@ -13,6 +13,21 @@ import Lumina.Backend.RootDesktopObject 2.0 Menu { id: contextMenu MenuItem { + text: "Launch Terminal" + iconName: "utilities-terminal" + onTriggered: { + RootObject.launchApp("application/terminal") + } + } + MenuItem { + text: "Launch File Browser" + iconName: "user-home" + onTriggered: { + RootObject.launchApp("inode/directory") + } + } + + MenuItem { text: "Lock Screen" iconName: "system-lock-screen" onTriggered: { diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WindowFrame.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/NativeWindow.qml index b1765001..90818ca8 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WindowFrame.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/NativeWindow.qml @@ -4,17 +4,20 @@ import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -Rectangle { - id: background - color: "grey" +import Lumina.Backend.NativeWindowObject 2.0 Rectangle { + property NativeWindowObject object + property string window_id + id: windowFrame border.width: 5 - border.color: "black" - color: "white" - width: 400 - height: 300 + border.color: palette.window + color: palette.window + x: object.frameGeometry.x + y: object.frameGeometry.y + width: object.frameGeometry.width + height: object.frameGeometry.height MouseArea { id: resizeArea @@ -98,7 +101,7 @@ Rectangle { Rectangle { id: titleBar border.width: 2 - color: "black" + color: palette.window height: 25 anchors.top: windowFrame.top anchors.right: windowFrame.right @@ -107,49 +110,59 @@ Rectangle { width: parent.width RowLayout { - anchors.right: parent.right + anchors.fill: titleBar spacing: 0 + Button { + id: otherButton + anchors.left: parent.left + Layout.fillHeight: true + iconSource: windowFrame.object.icon + + } + Text { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: palette.windowText + text: windowFrame.object.shortTitle + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + //onClicked: contextMenu.open() + } + } + Button { + id: minButton + Layout.fillHeight: true iconName: "window-minimize" - //action: + onClicked: { windowFrame.object.toggleVisibility() } } Button { + id: maxButton + Layout.fillHeight: true iconName: "window-maximize" - //action: + //onClicked: { windowFrame.object.toggleMaximize() } } Button { + id: closeButton + Layout.fillHeight: true iconName: "document-close" - //action: + onClicked: { windowFrame.object.requestClose() } } } - - Button { - iconName: "emblem-synchronized" - anchors.left: parent.left - } - - Text { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - color: "white" - text: "zwelch@trueos~8905:~/lumina/src-qt5/src-qml/test" - font.pixelSize: 10 - } - - MouseArea { - acceptedButtons: Qt.RightButton - anchors.fill: parent - //onClicked: contextMenu.open() - } } Image { id: frameContents -// source: "balloon.png" + source: windowFrame.object.winImage anchors.top: titleBar.bottom anchors.bottom: parent.bottom anchors.left: windowFrame.left @@ -161,12 +174,11 @@ Rectangle { height: parent.height MouseArea { - width: parent.width; - height: parent.height; - anchors.fill: frameContents; + width: parent.width; + height: parent.height + anchors.fill: frameContents onClicked: { console.log(parent.mapToGlobal(mouse.x, mouse.y)); } } } } -} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml index c564ee42..9122ce5b 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml @@ -23,6 +23,7 @@ import "." as QML import Lumina.Backend.RootDesktopObject 2.0 import Lumina.Backend.ScreenObject 2.0 +import Lumina.Backend.NativeWindowObject 2.0 Rectangle { id: rootCanvas @@ -55,4 +56,14 @@ Rectangle { z: 0+index } } + + //Setup the windows + Repeater{ + model: RootObject.windows + QML.NativeWindow{ + window_id: modelData + object: RootObject.window(modelData) + z: 100+index + } + } } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri index ad07902a..79941b82 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri @@ -3,7 +3,8 @@ lupdate_only{ SOURCES *= $${PWD}/RootDesktop.qml \ $${PWD}/ContextMenu.qml \ $${PWD}/Screen.qml \ - $${PWD}/Panel.qml + $${PWD}/Panel.qml \ + $${PWD}/NativeWindow.qml } RESOURCES *= $${PWD}/src-qml.qrc diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc index b0c66e20..a4dc414f 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc @@ -4,5 +4,6 @@ <file>ContextMenu.qml</file> <file>Screen.qml</file> <file>Panel.qml</file> + <file>NativeWindow.qml</file> </qresource> </RCC> diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h index 4560cb1f..8017060f 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h @@ -10,7 +10,8 @@ #ifndef _LUMINA_KEY_SEQUENCE_DETECTION_H #define _LUMINA_KEY_SEQUENCE_DETECTION_H -#include "../global-includes.h" +#include <global-includes.h> +#include "NativeWindowSystem.h" class LShortcutEvents : public QObject{ Q_OBJECT diff --git a/src-qt5/src-cpp/NativeEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/NativeEventFilter.cpp index c13c1fc8..507bcb9a 100644 --- a/src-qt5/src-cpp/NativeEventFilter.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeEventFilter.cpp @@ -66,45 +66,48 @@ 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; + NativeWindowObject::Property prop = NativeWindowObject::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; } + if(ev->atom == EWMH._NET_WM_NAME){ prop = NativeWindowObject::Title; } + else if(ev->atom == EWMH._NET_WM_ICON){ prop = NativeWindowObject::Icon; } + else if(ev->atom == EWMH._NET_WM_ICON_NAME){ prop = NativeWindowObject::ShortTitle; } + else if(ev->atom == EWMH._NET_WM_DESKTOP){ prop = NativeWindowObject::Workspace; } + else if(ev->atom == EWMH._NET_WM_WINDOW_TYPE ){ prop = NativeWindowObject::WinTypes; } + else if( ev->atom == EWMH._NET_WM_STATE){ prop = NativeWindowObject::States; } //Send out the signal if necessary - if(prop!=NativeWindow::None){ + if(prop!=NativeWindowObject::None){ //if(DEBUG){ //qDebug() << "Detected Property Change:" << ev->window << prop; //} obj->emit WindowPropertyChanged(ev->window, prop); }else{ //Quick re-check of the simple properties (nothing like the icon or other graphics) - obj->emit WindowPropertiesChanged(ev->window, QList<NativeWindow::Property>() << NativeWindow::Title - << NativeWindow::ShortTitle << NativeWindow::Workspace ); + obj->emit WindowPropertiesChanged(ev->window, QList<NativeWindowObject::Property>() << NativeWindowObject::Title + << NativeWindowObject::ShortTitle << NativeWindowObject::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; + NativeWindowObject::Property prop = NativeWindowObject::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; } + if(ev->type==EWMH._NET_WM_NAME){ prop = NativeWindowObject::Title; } + else if(ev->type==EWMH._NET_WM_ICON){ prop = NativeWindowObject::Icon; } + else if(ev->type==EWMH._NET_WM_ICON_NAME){ prop = NativeWindowObject::ShortTitle; } else if(ev->type==EWMH._NET_WM_DESKTOP){ - prop = NativeWindow::Workspace; + prop = NativeWindowObject::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; } + }else if(ev->type==EWMH._NET_WM_WINDOW_TYPE){ prop = NativeWindowObject::WinTypes; } + else if(ev->type==EWMH._NET_WM_STATE){ prop = NativeWindowObject::States; } - if(prop!=NativeWindow::None){ - //if(DEBUG){ - qDebug() << "Detected Property Change Request:" << ev->window << prop; //} + if(prop!=NativeWindowObject::None){ + if(DEBUG){ qDebug() << "Detected Property Change Request:" << ev->window << prop << val; } if(val.isNull()){ obj->emit WindowPropertyChanged(ev->window, prop); } else{ obj->emit RequestWindowPropertyChange(ev->window, prop, val); } + }else{ + //Quick re-check of the simple properties (nothing like the icon or other graphics) + obj->emit WindowPropertiesChanged(ev->window, QList<NativeWindowObject::Property>() << NativeWindowObject::Title + << NativeWindowObject::ShortTitle << NativeWindowObject::Workspace ); } } @@ -204,7 +207,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== 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); + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindowObject::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"; @@ -217,7 +220,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, //============================== 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); + obj->emit WindowPropertyChanged( ((xcb_map_notify_event_t *)ev)->window, NativeWindowObject::Visible, false); break; //============================== case XCB_DESTROY_NOTIFY: @@ -256,17 +259,17 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, case XCB_CONFIGURE_NOTIFY: //qDebug() << "Configure Notify Event"; /*obj->emit WindowPropertiesChanged( ((xcb_configure_notify_event_t*)ev)->window, - QList<NativeWindow::Property>() << NativeWindow::GlobalPos << NativeWindow::Size, + QList<NativeWindowObject::Property>() << NativeWindowObject::GlobalPos << NativeWindowObject::Size, QList<QVariant>() << QPoint(((xcb_configure_notify_event_t*)ev)->x, ((xcb_configure_notify_event_t*)ev)->y) << QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) );*/ - obj->emit WindowPropertyChanged( ((xcb_configure_notify_event_t*)ev)->window, NativeWindow::Size, + obj->emit WindowPropertyChanged( ((xcb_configure_notify_event_t*)ev)->window, NativeWindowObject::Size, QSize(((xcb_configure_notify_event_t*)ev)->width, ((xcb_configure_notify_event_t*)ev)->height) ); break; //============================== case XCB_CONFIGURE_REQUEST: //qDebug() << "Configure Request Event"; obj->emit RequestWindowPropertiesChange( ((xcb_configure_request_event_t*)ev)->window, - QList<NativeWindow::Property>() << NativeWindow::GlobalPos << NativeWindow::Size, + QList<NativeWindowObject::Property>() << NativeWindowObject::GlobalPos << NativeWindowObject::Size, QList<QVariant>() << QPoint(((xcb_configure_request_event_t*)ev)->x, ((xcb_configure_request_event_t*)ev)->y) << QSize(((xcb_configure_request_event_t*)ev)->width, ((xcb_configure_request_event_t*)ev)->height) ); break; @@ -274,7 +277,7 @@ bool EventFilter::nativeEventFilter(const QByteArray &eventType, void *message, 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) ); + NativeWindowObject::Size, QSize(((xcb_resize_request_event_t*)ev)->width, ((xcb_resize_request_event_t*)ev)->height) ); break; //============================== case XCB_SELECTION_CLEAR: diff --git a/src-qt5/src-cpp/NativeEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/NativeEventFilter.h index a3be3ef1..e4500cac 100644 --- a/src-qt5/src-cpp/NativeEventFilter.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeEventFilter.h @@ -13,7 +13,7 @@ #include <QObject> #include <QByteArray> -#include "NativeWindow.h" +#include <NativeWindowObject.h> class NativeEventFilter : public QObject{ @@ -33,12 +33,12 @@ signals: //Window Signals void WindowCreated(WId); void WindowDestroyed(WId); - void WindowPropertyChanged(WId, NativeWindow::Property); - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>); - void RequestWindowPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestWindowPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); + void WindowPropertyChanged(WId, NativeWindowObject::Property); + void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>); + void WindowPropertyChanged(WId, NativeWindowObject::Property, QVariant); + void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>, QList<QVariant>); + void RequestWindowPropertyChange(WId, NativeWindowObject::Property, QVariant); + void RequestWindowPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>); //System Tray Signals void TrayWindowCreated(WId); diff --git a/src-qt5/src-cpp/NativeKeyToQt.cpp b/src-qt5/core/lumina-desktop-unified/src-events/NativeKeyToQt.cpp index 06056be7..9b639496 100644 --- a/src-qt5/src-cpp/NativeKeyToQt.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeKeyToQt.cpp @@ -1,5 +1,5 @@ -#include <NativeWindowSystem.h> +#include "NativeWindowSystem.h" #include <QKeySequence> #include <QX11Info> diff --git a/src-qt5/src-cpp/NativeWindowSystem.cpp b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp index e8e9655a..4b56f2a9 100644 --- a/src-qt5/src-cpp/NativeWindowSystem.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.cpp @@ -8,15 +8,7 @@ // used for interacting with the X11 display system on BSD/Linux/Unix systems //=========================================== #include "NativeWindowSystem.h" - -//Additional Qt includes -#include <QX11Info> -#include <QDebug> -#include <QApplication> -#include <QScreen> -#include <QFont> -#include <QFontMetrics> -#include <QKeySequence> +#include <global-objects.h> //XCB Library includes @@ -282,7 +274,7 @@ void NativeWindowSystem::stop(){ } // === PRIVATE === -NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ +NativeWindowObject* NativeWindowSystem::findWindow(WId id, bool checkRelated){ //qDebug() << "Find Window:" << id; for(int i=0; i<NWindows.length(); i++){ if(id==NWindows[i]->id() ){ return NWindows[i]; } @@ -299,16 +291,16 @@ NativeWindow* NativeWindowSystem::findWindow(WId id, bool checkRelated){ return 0; } -NativeWindow* NativeWindowSystem::findTrayWindow(WId id){ +NativeWindowObject* NativeWindowSystem::findTrayWindow(WId id){ for(int i=0; i<TWindows.length(); i++){ if(TWindows[i]->isRelatedTo(id)){ return TWindows[i]; } } return 0; } -void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props){ +void NativeWindowSystem::UpdateWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props){ //Put the properties in logical groups as appropriate (some XCB calls return multiple properties) - if(props.contains(NativeWindow::Title)){ + if(props.contains(NativeWindowObject::Title)){ //Try the EWMH standards first // _NET_WM_NAME QString name; @@ -338,10 +330,10 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native xcb_icccm_get_text_property_reply_wipe(&reply); } } - win->setProperty(NativeWindow::Title, name); + win->setProperty(NativeWindowObject::Title, name); } //end TITLE property - if(props.contains(NativeWindow::ShortTitle)){ + if(props.contains(NativeWindowObject::ShortTitle)){ //Try the EWMH standards first // _NET_WM_ICON_NAME QString name; @@ -371,10 +363,10 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native xcb_icccm_get_text_property_reply_wipe(&reply); } } - win->setProperty(NativeWindow::ShortTitle, name); + win->setProperty(NativeWindowObject::ShortTitle, name); } //end SHORTTITLE property - if(props.contains(NativeWindow::Icon)){ + if(props.contains(NativeWindowObject::Icon)){ //See if this is a tray icon first (different routine - entire app window is the icon) QIcon icon; if(win == findTrayWindow(win->id())){ @@ -414,11 +406,11 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native xcb_ewmh_get_wm_icon_reply_wipe(&reply); } } //end type of window - win->setProperty(NativeWindow::Icon, icon); + win->setProperty(NativeWindowObject::Icon, icon); } //end ICON property - if(props.contains(NativeWindow::MinSize) || props.contains(NativeWindow::MaxSize) - || props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ + if(props.contains(NativeWindowObject::MinSize) || props.contains(NativeWindowObject::MaxSize) + || props.contains(NativeWindowObject::Size) || props.contains(NativeWindowObject::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; @@ -430,32 +422,32 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native 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)); } + bool initsize = win->property(NativeWindowObject::Size).isNull(); //initial window size + if( (reply.flags&XCB_ICCCM_SIZE_HINT_US_POSITION)==XCB_ICCCM_SIZE_HINT_US_POSITION ){ win->setProperty(NativeWindowObject::GlobalPos, QPoint(reply.x,reply.y)); } + if( (reply.flags&XCB_ICCCM_SIZE_HINT_US_SIZE)==XCB_ICCCM_SIZE_HINT_US_SIZE ){ win->setProperty(NativeWindowObject::Size, QSize(reply.width, reply.height)); } + if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_POSITION)==XCB_ICCCM_SIZE_HINT_P_POSITION ){ win->setProperty(NativeWindowObject::GlobalPos, QPoint(reply.x,reply.y)); } + if( (reply.flags&XCB_ICCCM_SIZE_HINT_P_SIZE)==XCB_ICCCM_SIZE_HINT_P_SIZE ){ win->setProperty(NativeWindowObject::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(NativeWindowObject::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(NativeWindowObject::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(NativeWindowObject::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)){ + if(props.contains(NativeWindowObject::Name)){ //Put the app/class name here (much more static than the "Title" properties xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class_unchecked(QX11Info::connection(), win->id()); xcb_icccm_get_wm_class_reply_t reply; if(1 == xcb_icccm_get_wm_class_reply(QX11Info::connection(), cookie, &reply, NULL) ){ //Returns: "<instance name>::::<class name>" - win->setProperty(NativeWindow::Name, ( QString::fromLocal8Bit(reply.instance_name)+"::::"+QString::fromLocal8Bit(reply.class_name) )); + win->setProperty(NativeWindowObject::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)){ + if(props.contains(NativeWindowObject::Workspace)){ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop_unchecked(&obj->EWMH, win->id()); uint32_t num = 0; int wkspace = -1; @@ -466,13 +458,13 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native // - put it on the current screen out = WM_Get_Current_Desktop(); }*/ - win->setProperty(NativeWindow::Workspace, wkspace); + win->setProperty(NativeWindowObject::Workspace, wkspace); } - if(props.contains(NativeWindow::FrameExtents)){ + if(props.contains(NativeWindowObject::FrameExtents)){ //Just assign default values to this - need to automate it later - //win->setProperty(NativeWindow::FrameExtents, QVariant::fromValue<QList<int> >(QList<int>() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); + //win->setProperty(NativeWindowObject::FrameExtents, QVariant::fromValue<QList<int> >(QList<int>() << 5 << 5 << 5+QFontMetrics(QFont()).height() << 5) ); } - if(props.contains(NativeWindow::RelatedWindows)){ + if(props.contains(NativeWindowObject::RelatedWindows)){ WId orig = win->id(); WId tid = obj->getTransientFor(orig); QList<WId> list; @@ -481,90 +473,90 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native orig = tid; tid = obj->getTransientFor(orig); } - win->setProperty(NativeWindow::RelatedWindows, QVariant::fromValue(list)); + win->setProperty(NativeWindowObject::RelatedWindows, QVariant::fromValue(list)); } - if(props.contains(NativeWindow::Visible)){ + if(props.contains(NativeWindowObject::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); + win->setProperty(NativeWindowObject::Visible, attr->map_state == XCB_MAP_STATE_VIEWABLE); free(attr); } } - if(props.contains(NativeWindow::WinTypes)){ - QList< NativeWindow::Type> types; + if(props.contains(NativeWindowObject::WinTypes)){ + QList< NativeWindowObject::Type> types; xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type_unchecked(&obj->EWMH, win->id()); xcb_ewmh_get_atoms_reply_t reply; if(1==xcb_ewmh_get_wm_window_type_reply(&obj->EWMH, cookie, &reply, NULL) ){ for(unsigned int i=0; i<reply.atoms_len; i++){ - if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ types << NativeWindow::T_DESKTOP; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DOCK){ types << NativeWindow::T_DOCK; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ types << NativeWindow::T_TOOLBAR; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_MENU){ types << NativeWindow::T_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY){ types << NativeWindow::T_UTILITY; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH){ types << NativeWindow::T_SPLASH; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG){ types << NativeWindow::T_DIALOG; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ types << NativeWindow::T_DROPDOWN_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ types << NativeWindow::T_POPUP_MENU; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ types << NativeWindow::T_TOOLTIP; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ types << NativeWindow::T_NOTIFICATION; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_COMBO){ types << NativeWindow::T_COMBO; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DND){ types << NativeWindow::T_DND; } - else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL){ types << NativeWindow::T_NORMAL; } + if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ types << NativeWindowObject::T_DESKTOP; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DOCK){ types << NativeWindowObject::T_DOCK; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ types << NativeWindowObject::T_TOOLBAR; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_MENU){ types << NativeWindowObject::T_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY){ types << NativeWindowObject::T_UTILITY; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH){ types << NativeWindowObject::T_SPLASH; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG){ types << NativeWindowObject::T_DIALOG; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ types << NativeWindowObject::T_DROPDOWN_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ types << NativeWindowObject::T_POPUP_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ types << NativeWindowObject::T_TOOLTIP; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ types << NativeWindowObject::T_NOTIFICATION; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_COMBO){ types << NativeWindowObject::T_COMBO; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DND){ types << NativeWindowObject::T_DND; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL){ types << NativeWindowObject::T_NORMAL; } } } - if(types.isEmpty()){ types << NativeWindow::T_NORMAL; } - win->setProperty(NativeWindow::WinTypes, QVariant::fromValue< QList<NativeWindow::Type> >(types) ); + if(types.isEmpty()){ types << NativeWindowObject::T_NORMAL; } + win->setProperty(NativeWindowObject::WinTypes, QVariant::fromValue< QList<NativeWindowObject::Type> >(types) ); } } -void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList<QVariant> vals){ +void NativeWindowSystem::ChangeWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props, QList<QVariant> vals){ if(props.length() == 0 || vals.length()!=props.length() || win ==0 ){ return; } //qDebug() << "Change Window Properties:" << props << vals; - if(props.contains(NativeWindow::Title)){ + if(props.contains(NativeWindowObject::Title)){ } - if(props.contains(NativeWindow::ShortTitle)){ + if(props.contains(NativeWindowObject::ShortTitle)){ } - if(props.contains(NativeWindow::Icon)){ + if(props.contains(NativeWindowObject::Icon)){ } - if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ + if(props.contains(NativeWindowObject::Size) || props.contains(NativeWindowObject::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(); + QSize sz = win->property(NativeWindowObject::Size).toSize(); + if(props.contains(NativeWindowObject::Size)){ + sz = vals[ props.indexOf(NativeWindowObject::Size) ] .toSize(); } valList.width = sz.width(); valList.height = sz.height(); - if(props.contains(NativeWindow::GlobalPos)){ - QPoint pt = vals[ props.indexOf(NativeWindow::GlobalPos) ] .toPoint(); + if(props.contains(NativeWindowObject::GlobalPos)){ + QPoint pt = vals[ props.indexOf(NativeWindowObject::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(); + valList.x = win->property(NativeWindowObject::GlobalPos).toPoint().x(); + valList.y = win->property(NativeWindowObject::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(NativeWindowObject::Name)){ } - if(props.contains(NativeWindow::Workspace)){ - int num = vals[ props.indexOf(NativeWindow::Workspace) ].toInt(); + if(props.contains(NativeWindowObject::Workspace)){ + int num = vals[ props.indexOf(NativeWindowObject::Workspace) ].toInt(); xcb_ewmh_set_wm_desktop(&obj->EWMH, win->id(), (num<0 ? 0xFFFFFFFF : qAbs(num) ) ); } - if(props.contains(NativeWindow::RelatedWindows)){ + if(props.contains(NativeWindowObject::RelatedWindows)){ } - if(props.contains(NativeWindow::Visible)){ - //qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindow::Visible) ]; - if( vals[ props.indexOf(NativeWindow::Visible) ].toBool() ){ + if(props.contains(NativeWindowObject::Visible)){ + //qDebug() << "Check Window Visibility:" << vals[ props.indexOf(NativeWindowObject::Visible) ]; + if( vals[ props.indexOf(NativeWindowObject::Visible) ].toBool() ){ //qDebug() << " - Map it!"; xcb_map_window(QX11Info::connection(), win->id()); }else{ @@ -572,9 +564,9 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native xcb_unmap_window(QX11Info::connection(), win->id()); } } - if(props.contains(NativeWindow::Active)){ + if(props.contains(NativeWindowObject::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() ){ + if(vals[props.indexOf(NativeWindowObject::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, @@ -721,25 +713,25 @@ int NativeWindowSystem::currentWorkspace(){ //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 + if(findWindow(id, false) != 0){ findWindow(id,false)->setProperty(NativeWindowObject::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); + NativeWindowObject *win = new NativeWindowObject(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(); + UpdateWindowProperties(win, NativeWindowObject::allProperties()); + qDebug() << "New Window [& associated ID's]:" << win->id() << win->property(NativeWindowObject::Name).toString(); //Now setup the connections with this window connect(win, SIGNAL(RequestClose(WId)), this, SLOT(RequestClose(WId)) ); connect(win, SIGNAL(RequestKill(WId)), this, SLOT(RequestKill(WId)) ); connect(win, SIGNAL(RequestPing(WId)), this, SLOT(RequestPing(WId)) ); connect(win, SIGNAL(RequestReparent(WId, WId, QPoint)), this, SLOT(RequestReparent(WId, WId, QPoint)) ); - connect(win, SIGNAL(RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>)), this, SLOT(RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>)) ); + connect(win, SIGNAL(RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>)), this, SLOT(RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>)) ); emit NewWindowAvailable(win); } @@ -765,14 +757,14 @@ void NativeWindowSystem::NewTrayWindowDetected(WId id){ 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); + NativeWindowObject *win = new NativeWindowObject(id); TWindows << win; - UpdateWindowProperties(win, NativeWindow::allProperties()); + UpdateWindowProperties(win, NativeWindowObject::allProperties()); emit NewTrayWindowAvailable(win); } void NativeWindowSystem::WindowCloseDetected(WId id){ - NativeWindow *win = findWindow(id, false); + NativeWindowObject *win = findWindow(id, false); //qDebug() << "Got Window Closed" << id << win; //qDebug() << "Old Window List:" << NWindows.length(); if(win!=0){ @@ -781,35 +773,37 @@ void NativeWindowSystem::WindowCloseDetected(WId id){ win->emit WindowClosed(id); //qDebug() << "Visible Window Closed!!!"; //win->deleteLater(); + emit WindowClosed(); }else{ win = findTrayWindow(id); if(win!=0){ TWindows.removeAll(win); win->emit WindowClosed(id); win->deleteLater(); + emit TrayWindowClosed(); } } //qDebug() << " - Now:" << NWindows.length(); } -void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop){ +void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindowObject::Property prop){ //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves - NativeWindow *win = findWindow(id, prop!=NativeWindow::Visible); + NativeWindowObject *win = findWindow(id, prop!=NativeWindowObject::Visible); if(win==0){ win = findTrayWindow(id); } if(win!=0){ - UpdateWindowProperties(win, QList<NativeWindow::Property>() << prop); + UpdateWindowProperties(win, QList<NativeWindowObject::Property>() << prop); }else if(prop != 0){ //Could not find the window for a specific property with an undefined value // - update this property for all the windows just in case for(int i=0; i<NWindows.length(); i++){ - UpdateWindowProperties( NWindows[i], QList<NativeWindow::Property>() << prop); + UpdateWindowProperties( NWindows[i], QList<NativeWindowObject::Property>() << prop); } } } -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindow::Property> props){ +void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindowObject::Property> props){ //NOTE: This is triggered by the NativeEventFilter - not by changes to the NativeWindow objects themselves - NativeWindow *win = findWindow(id); + NativeWindowObject *win = findWindow(id); if(win==0){ win = findTrayWindow(id); } if(win!=0){ UpdateWindowProperties(win, props); @@ -822,31 +816,31 @@ void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindow::Pro } } -void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindow::Property prop, QVariant val){ - NativeWindow *win = findWindow(id,prop!=NativeWindow::Visible); +void NativeWindowSystem::WindowPropertyChanged(WId id, NativeWindowObject::Property prop, QVariant val){ + NativeWindowObject *win = findWindow(id,prop!=NativeWindowObject::Visible); if(win==0){ win = findTrayWindow(id); } if(win!=0){ win->setProperty(prop, val); } } -void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindow::Property> props, QList<QVariant> vals){ - NativeWindow *win = findWindow(id); +void NativeWindowSystem::WindowPropertiesChanged(WId id, QList<NativeWindowObject::Property> props, QList<QVariant> vals){ + NativeWindowObject *win = findWindow(id); if(win==0){ win = findTrayWindow(id); } if(win!=0){ for(int i=0; i<props.length() && i<vals.length(); i++){ win->setProperty(props[i], vals[i]); } } } -void NativeWindowSystem::RequestPropertyChange(WId id, NativeWindow::Property prop, QVariant val){ +void NativeWindowSystem::RequestPropertyChange(WId id, NativeWindowObject::Property prop, QVariant val){ //This is just a simplified version of the multiple-property function - RequestPropertiesChange(id, QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); + RequestPropertiesChange(id, QList<NativeWindowObject::Property>() << prop, QList<QVariant>() << val); } -void NativeWindowSystem::RequestPropertiesChange(WId win, QList<NativeWindow::Property> props, QList<QVariant> vals){ +void NativeWindowSystem::RequestPropertiesChange(WId win, QList<NativeWindowObject::Property> props, QList<QVariant> vals){ //Find the window object associated with this id bool istraywin = false; //just in case we care later if it is a tray window or a regular window - NativeWindow *WIN = findWindow(win); + NativeWindowObject *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 @@ -894,9 +888,9 @@ void NativeWindowSystem::CheckDamageID(WId win){ return; } } - NativeWindow *WIN = findTrayWindow(win); + NativeWindowObject *WIN = findTrayWindow(win); if(WIN!=0){ - UpdateWindowProperties(WIN, QList<NativeWindow::Property>() << NativeWindow::Icon); + UpdateWindowProperties(WIN, QList<NativeWindowObject::Property>() << NativeWindowObject::Icon); } } @@ -936,7 +930,7 @@ void NativeWindowSystem::RequestPing(WId win){ } void NativeWindowSystem::RequestReparent(WId win, WId container, QPoint relorigin){ - NativeWindow *WIN = findWindow(win); + NativeWindowObject *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()); diff --git a/src-qt5/src-cpp/NativeWindowSystem.h b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h index b67ecc94..e1614b75 100644 --- a/src-qt5/src-cpp/NativeWindowSystem.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/NativeWindowSystem.h @@ -1,31 +1,32 @@ //=========================================== // Lumina-DE 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 //=========================================== // 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 +// the "NativeWindowObject" class for passing information around //=========================================== -#ifndef _LUMINA_NATIVE_WINDOW_SYSTEM_H -#define _LUMINA_NATIVE_WINDOW_SYSTEM_H +#ifndef _LUMINA_DESKTOP_NATIVE_WINDOW_SYSTEM_H +#define _LUMINA_DESKTOP_NATIVE_WINDOW_SYSTEM_H -#include "NativeWindow.h" -#include <QDateTime> +#include <NativeWindowObject.h> +#include <QObject> +#include <QHash> #include <QTimer> -#include <QDebug> + class NativeWindowSystem : public QObject{ Q_OBJECT private: - QList<NativeWindow*> NWindows; - QList<NativeWindow*> TWindows; + QList<NativeWindowObject*> NWindows; + QList<NativeWindowObject*> TWindows; //Simplifications to find an already-created window object - NativeWindow* findWindow(WId id, bool checkRelated = true); + NativeWindowObject* findWindow(WId id, bool checkRelated = true); - NativeWindow* findTrayWindow(WId id); + NativeWindowObject* 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 @@ -35,6 +36,7 @@ private: //Internal timers/variables for managing pings QTimer *pingTimer; QHash<WId, QDateTime> waitingForPong; + void checkPings(){ QDateTime cur = QDateTime::currentDateTime(); QList<WId> waiting = waitingForPong.keys(); @@ -42,7 +44,7 @@ private: if(waitingForPong.value(waiting[i]) < cur){ waitingForPong.remove(waiting[i]); //Timeout on this window if(waitingForPong.isEmpty() && pingTimer!=0){ pingTimer->stop(); } - NativeWindow *win = findWindow(waiting[i]); + NativeWindowObject *win = findWindow(waiting[i]); if(win==0){ win = findTrayWindow(waiting[i]); } if(win!=0){ win->emit WindowNotResponding(waiting[i]); } } @@ -51,8 +53,8 @@ private: // Since some properties may be easier to update in bulk // let the native system interaction do them in whatever logical groups are best - void UpdateWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props); - void ChangeWindowProperties(NativeWindow* win, QList< NativeWindow::Property > props, QList<QVariant> vals); + void UpdateWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props); + void ChangeWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props, QList<QVariant> vals); //Generic private variables bool screenLocked; @@ -69,8 +71,8 @@ public: void stop(); //General-purpose listing functions - QList<NativeWindow*> currentWindows(){ return NWindows; } - QList<NativeWindow*> currentTrayWindows(){ return TWindows; } + QList<NativeWindowObject*> currentWindows(){ return NWindows; } + QList<NativeWindowObject*> currentTrayWindows(){ return TWindows; } //Small simplification functions static Qt::Key KeycodeToQt(int keycode); @@ -104,12 +106,12 @@ public slots: void NewWindowDetected(WId); //will automatically create the new NativeWindow object void NewTrayWindowDetected(WId); //will automatically create the new NativeWindow object void WindowCloseDetected(WId); //will update the lists and make changes if needed - void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>); - void WindowPropertyChanged(WId, NativeWindow::Property, QVariant); //will save that property/value to the right object - void WindowPropertiesChanged(WId, QList<NativeWindow::Property>, QList<QVariant>); - void RequestPropertyChange(WId, NativeWindow::Property, QVariant); - void RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); + void WindowPropertyChanged(WId, NativeWindowObject::Property); //will rescan the window and update the object as needed + void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>); + void WindowPropertyChanged(WId, NativeWindowObject::Property, QVariant); //will save that property/value to the right object + void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>, QList<QVariant>); + void RequestPropertyChange(WId, NativeWindowObject::Property, QVariant); + void RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>); void GotPong(WId); void NewKeyPress(int keycode, WId win = 0); @@ -126,8 +128,10 @@ private slots: void RequestReparent(WId, WId, QPoint); //client, parent, relative origin point in parent signals: - void NewWindowAvailable(NativeWindow*); - void NewTrayWindowAvailable(NativeWindow*); + void NewWindowAvailable(NativeWindowObject*); + void WindowClosed(); + void NewTrayWindowAvailable(NativeWindowObject*); + void TrayWindowClosed(); 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 diff --git a/src-qt5/core/lumina-desktop-unified/src-events/events.pri b/src-qt5/core/lumina-desktop-unified/src-events/events.pri index 48d500ed..3f89fdf2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/events.pri +++ b/src-qt5/core/lumina-desktop-unified/src-events/events.pri @@ -1,10 +1,16 @@ -#SOURCES *= $${PWD}/LXcbEventFilter.cpp +# Files +QT *= x11extras +LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage -#HEADERS *= $${PWD}/LXcbEventFilter.h +SOURCES *= $${PWD}/LShortcutEvents.cpp \ + $${PWD}/NativeEventFilter.cpp \ + $${PWD}/NativeKeyToQt.cpp \ + $${PWD}/NativeWindowSystem.cpp -#Shortcut event files -SOURCES *= $${PWD}/LShortcutEvents.cpp -HEADERS *= $${PWD}/LShortcutEvents.h -#update the includepath so we can just (#include <LXcbEventFilter.h>) as needed without paths +HEADERS *= $${PWD}/LShortcutEvents.h \ + $${PWD}/NativeEventFilter.h \ + $${PWD}/NativeWindowSystem.h + +#update the includepath so we can just (#include <NativeEventFilter.h>) as needed without paths INCLUDEPATH *= ${PWD} diff --git a/src-qt5/src-cpp/plugins-base.h b/src-qt5/src-cpp/plugins-base.h index 26b0eacc..eb54e40d 100644 --- a/src-qt5/src-cpp/plugins-base.h +++ b/src-qt5/src-cpp/plugins-base.h @@ -35,12 +35,12 @@ public: virtual void loadFile(QString path); bool isLoaded() { return !data.isEmpty(); }; - bool containsDefault(QString obj) { return data.value(obj).toObject().contains("default"); } + bool containsDefault(QString obj) { return data.value(obj).toObject().contains("default"); } /** * Check if the plugin is valid as long as the JSON is not empty, * it contains at least a "name", "qml", and "description" object, - * and the "name" and "description" objects contain a "default" key. + * and the "name" and "description" objects contain a "default" key. **/ virtual bool isValid() = 0; @@ -48,7 +48,7 @@ public: virtual QUrl scriptURL(); QJsonObject data; //Hazardous to manually modify - QString relDir; + QString relDir; }; class PluginSystem{ diff --git a/src-qt5/src-cpp/plugins-desktop.cpp b/src-qt5/src-cpp/plugins-desktop.cpp index edad2723..19c49942 100644 --- a/src-qt5/src-cpp/plugins-desktop.cpp +++ b/src-qt5/src-cpp/plugins-desktop.cpp @@ -12,13 +12,9 @@ // DT PLUGIN // ============ DTPlugin::DTPlugin(){ - pluginIcon = QIcon(); - gridSize = QSize(1,1); - panelPossible = false; } DTPlugin::~DTPlugin(){ - } bool DTPlugin::isValid(){ @@ -28,30 +24,8 @@ bool DTPlugin::isValid(){ ok &= containsDefault("description"); ok &= containsDefault("data"); if(ok) { - QJsonObject tmp = data.value("data").toObject(); - - QString possibleS = tmp.value("panel_possible").toString(); - if(!possibleS.isEmpty() and (possibleS == "yes" or possibleS == "true")) - panelPossible = true; - - QString gridS = tmp.value("grid_size").toString(); - if(!gridS.isEmpty()) { - QStringList gridList = gridS.split("x"); - if(gridList.size() == 2) { - int width = gridList[0].toInt(); - int height = gridList[1].toInt(); - if(width != 0 and height != 0) - gridSize = QSize(width, height); - } - } + QJsonObject tmp = data.value("qml").toObject(); - QString iconS = tmp.value("plugin_icon").toString(); - if(!iconS.isEmpty()) { - pluginIcon = LXDG::findIcon(iconS,""); - } - - tmp = data.value("qml").toObject(); - QStringList mustexist; QString exec = tmp.value("exec").toString(); if(exec.isEmpty() || !exec.endsWith(".qml")){ return false; } @@ -66,3 +40,33 @@ bool DTPlugin::isValid(){ } return ok; } + +QSize DTPlugin::getSize(){ + QString gridS = data.value("data").toObject().value("grid_size").toString(); + QSize gridSize(0,0); + if(!gridS.isEmpty()) { + QStringList gridList = gridS.split("x"); + if(gridList.size() == 2) { + int width = gridList[0].toInt(); + int height = gridList[1].toInt(); + if(width > 0 && height > 0) + gridSize = QSize(width, height); + } + } + return gridSize; +} + +bool DTPlugin::supportsPanel(){ + QString possibleS = data.value("data").toObject().value("panel_possible").toString().toLower(); + bool panelPossible = false; + if(!possibleS.isEmpty() && (possibleS == "yes" || possibleS == "true")){ + panelPossible = true; + } + return panelPossible; +} + +QString DTPlugin::getIcon(){ + QString iconS = data.value("data").toObject().value("plugin_icon").toString(); + if(iconS.isEmpty()){ iconS = "preferences-plugin"; } + return iconS; +} diff --git a/src-qt5/src-cpp/plugins-desktop.h b/src-qt5/src-cpp/plugins-desktop.h index 4d34f188..260f9070 100644 --- a/src-qt5/src-cpp/plugins-desktop.h +++ b/src-qt5/src-cpp/plugins-desktop.h @@ -20,19 +20,16 @@ #include <QIcon> class DTPlugin : public BasePlugin{ -private: - QSize gridSize; - bool panelPossible; - QIcon pluginIcon; + public: DTPlugin(); ~DTPlugin(); virtual bool isValid() Q_DECL_OVERRIDE; - QSize getSize { return gridSize; } - bool getPanelable { return panelPossible; } - QIcon getIcon { return pluginIcon; } + QSize getSize(); + bool supportsPanel(); + QString getIcon(); }; #endif |