diff options
Diffstat (limited to 'lumina-desktop/panel-plugins/systemtray')
-rw-r--r-- | lumina-desktop/panel-plugins/systemtray/LSysTray.cpp | 113 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/systemtray/LSysTray.h | 25 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp | 35 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/systemtray/TrayIcon.h | 10 |
4 files changed, 129 insertions, 54 deletions
diff --git a/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp b/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp index 27dbaee5..36f5f81d 100644 --- a/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp +++ b/lumina-desktop/panel-plugins/systemtray/LSysTray.cpp @@ -7,17 +7,17 @@ #include "LSysTray.h" #include "../../LSession.h" -#include <LuminaX11.h> +/*#include <LuminaX11.h> //X includes (these need to be last due to Qt compile issues) #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/extensions/Xrender.h> -#include <X11/extensions/Xdamage.h> +#include <X11/extensions/Xdamage.h>*/ //Static variables for damage detection (tray update notifications) -static int dmgEvent = 0; -static int dmgError = 0; +//static int dmgEvent = 0; +//static int dmgError = 0; LSysTray::LSysTray(QWidget *parent, QString id, bool horizontal) : LPPlugin(parent, id, horizontal){ frame = new QFrame(this); @@ -30,12 +30,16 @@ LSysTray::LSysTray(QWidget *parent, QString id, bool horizontal) : LPPlugin(pare LI->setContentsMargins(0,0,0,0); this->layout()->addWidget(frame); this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - TrayID=0; + //TrayID=0; upTimer = new QTimer(this); upTimer->setInterval(300000); //maximum time between refreshes is 5 minutes connect(upTimer, SIGNAL(timeout()), this, SLOT(checkAll()) ); - isRunning = false; - start(); + isRunning = false; stopping = false; + QTimer::singleShot(100, this, SLOT(start()) ); + + connect(LSession::handle(), SIGNAL(TrayListChanged()), this, SLOT(checkAll()) ); + connect(LSession::handle(), SIGNAL(TrayIconChanged(WId)), this, SLOT(UpdateTrayWindow(WId)) ); + connect(LSession::handle(), SIGNAL(VisualTrayAvailable()), this, SLOT(start()) ); } LSysTray::~LSysTray(){ @@ -45,9 +49,15 @@ LSysTray::~LSysTray(){ } void LSysTray::start(){ - if(TrayID!=0){ return; } //already running + if(isRunning || stopping){ return; } //already running + isRunning = LSession::handle()->registerVisualTray(this->winId()); + qDebug() << "Visual Tray Started:" << this->type() << isRunning; + if(isRunning){ + upTimer->start(); + QTimer::singleShot(0,this, SLOT(checkAll()) ); + } //Make sure we catch all events right away - connect(LSession::instance(),SIGNAL(aboutToQuit()),this,SLOT(closeAll()) ); + /*connect(LSession::instance(),SIGNAL(aboutToQuit()),this,SLOT(closeAll()) ); connect(LSession::instance(),SIGNAL(TrayEvent(XEvent*)), this, SLOT(checkXEvent(XEvent*)) ); isRunning = true; TrayID = LX11::startSystemTray(0); //LSession::desktop()->screenNumber(this)); @@ -61,16 +71,17 @@ void LSysTray::start(){ }else{ disconnect(this); } - isRunning = (TrayID!=0); + isRunning = (TrayID!=0);*/ } void LSysTray::stop(){ if(!isRunning){ return; } + stopping = true; upTimer->stop(); //Now close down the system tray registry - qDebug() << "Stop system Tray"; - LX11::closeSystemTray(TrayID); - TrayID = 0; + qDebug() << "Stop system Tray:" << this->type(); + //LX11::closeSystemTray(TrayID); + //TrayID = 0; disconnect(this); //remove any signals/slots isRunning = false; //Release all the tray applications and delete the containers @@ -81,13 +92,15 @@ void LSysTray::stop(){ LI->removeWidget(cont); delete cont; } + //Now let some other visual tray take over + LSession::handle()->unregisterVisualTray(this->winId()); qDebug() << "Done stopping system tray"; } // ======================== // PRIVATE FUNCTIONS // ======================== -void LSysTray::checkXEvent(XEvent *event){ +/*void LSysTray::checkXEvent(XEvent *event){ if(!isRunning){ return; } switch(event->type){ // ------------------------- @@ -151,23 +164,72 @@ void LSysTray::closeAll(){ } } - +*/ void LSysTray::checkAll(){ + if(!isRunning || stopping){ return; } //Don't check if not running at the moment + QList<WId> wins = LSession::handle()->currentTrayApps(this->winId()); + for(int i=0; i<trayIcons.length(); i++){ + int index = wins.indexOf(trayIcons[i]->appID()); + if(index < 0){ + //Tray Icon no longer exists: remove it + TrayIcon *cont = trayIcons.takeAt(i); + LI->removeWidget(cont); + delete cont; + i--; //List size changed + //Re-adjust the maximum widget size to account for what is left + if(this->layout()->direction()==QBoxLayout::LeftToRight){ + this->setMaximumSize( trayIcons.length()*this->height(), 10000); + }else{ + this->setMaximumSize(10000, trayIcons.length()*this->width()); + } + }else{ + //Tray Icon already exists: just update it + trayIcons[i]->update(); + wins.removeAt(index); //Already found - remove from the list + } + } + //Now go through any remaining windows and add them + for(int i=0; i<wins.length(); i++){ + TrayIcon *cont = new TrayIcon(this); + LSession::processEvents(); + trayIcons << cont; + LI->addWidget(cont); + //qDebug() << " - Update tray layout"; + if(this->layout()->direction()==QBoxLayout::LeftToRight){ + cont->setSizeSquare(this->height()-2*frame->frameWidth()); //horizontal tray + this->setMaximumSize( trayIcons.length()*this->height(), 10000); + }else{ + cont->setSizeSquare(this->width()-2*frame->frameWidth()); //vertical tray + this->setMaximumSize(10000, trayIcons.length()*this->width()); + } + LSession::processEvents(); + //qDebug() << " - Attach tray app"; + cont->attachApp(wins[i]); + if(cont->appID()==0){ qDebug() << "Invalid Container:"; delete cont; continue; } //could not attach window + LI->update(); //make sure there is no blank space in the layout + } +} + +void LSysTray::UpdateTrayWindow(WId win){ + if(!isRunning || stopping){ return; } for(int i=0; i<trayIcons.length(); i++){ - trayIcons[i]->update(); - } + if(trayIcons[i]->appID()==win){ + trayIcons[i]->update(); + break; + } + } } -void LSysTray::initialTrayIconDetect(){ +/*void LSysTray::initialTrayIconDetect(){ // WARNING: This is still experimental and should be disabled by default!! QList<WId> wins = LX11::findOrphanTrayWindows(); for(int i=0; i<wins.length(); i++){ //addTrayIcon(wins[i]); qDebug() << "Initial Tray Window:" << wins[i] << LX11::WindowClass(wins[i]); } -} +}*/ -void LSysTray::addTrayIcon(WId win){ +/*void LSysTray::addTrayIcon(WId win){ if(win == 0 || !isRunning){ return; } //qDebug() << "System Tray: Add Tray Icon:" << win; bool exists = false; @@ -195,9 +257,10 @@ void LSysTray::addTrayIcon(WId win){ cont->attachApp(win); LI->update(); //make sure there is no blank space } -} +}*/ -void LSysTray::removeTrayIcon(WId win){ +/*void LSysTray::removeTrayIcon(WId win){ + //This function only runs when the tray app was closed externally if(win==0 || !isRunning){ return; } for(int i=0; i<trayIcons.length(); i++){ if(trayIcons[i]->appID()==win){ @@ -218,9 +281,9 @@ void LSysTray::removeTrayIcon(WId win){ } LI->update(); //update the layout (no gaps) this->update(); //update the main widget appearance -} +}*/ -void LSysTray::updateStatus(){ +/*void LSysTray::updateStatus(){ qDebug() << "System Tray: Client Attached"; LI->update(); //make sure there is no blank space //qDebug() << " - Items:" << trayIcons.length(); @@ -246,4 +309,4 @@ void LSysTray::trayAppClosed(){ LI->update(); //update the layout (no gaps) this->update(); } - +*/ diff --git a/lumina-desktop/panel-plugins/systemtray/LSysTray.h b/lumina-desktop/panel-plugins/systemtray/LSysTray.h index 13eb0df1..7f8386fc 100644 --- a/lumina-desktop/panel-plugins/systemtray/LSysTray.h +++ b/lumina-desktop/panel-plugins/systemtray/LSysTray.h @@ -30,30 +30,31 @@ public: LSysTray(QWidget *parent = 0, QString id="systemtray", bool horizontal=true); ~LSysTray(); - void start(); - void stop(); - private: - bool isRunning; + bool isRunning, stopping; QList<TrayIcon*> trayIcons; QFrame *frame; QBoxLayout *LI; //layout items - WId TrayID; + //WId TrayID; QTimer *upTimer; //manual timer to force refresh of all items private slots: - void checkXEvent(XEvent *event); - void closeAll(); + //void checkXEvent(XEvent *event); + //void closeAll(); void checkAll(); + void UpdateTrayWindow(WId win); - void initialTrayIconDetect(); //initial scan for previously running tray apps - void addTrayIcon(WId win); - void removeTrayIcon(WId win); + //void initialTrayIconDetect(); //initial scan for previously running tray apps + //void addTrayIcon(WId win); + //void removeTrayIcon(WId win); - void updateStatus(); - void trayAppClosed(); + /*void updateStatus(); + void trayAppClosed();*/ public slots: + void start(); + void stop(); + virtual void OrientationChange(){ //make sure the internal layout has the same orientation as the main widget LI->setDirection( this->layout()->direction() ); diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp index 37970051..64c7c77d 100644 --- a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp +++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp @@ -13,7 +13,7 @@ static Damage dmgID = 0; TrayIcon::TrayIcon(QWidget *parent) : QWidget(parent){ - AID = 0; //nothing attached yet + AID = 0; //nothing yet IID = 0; } @@ -31,9 +31,21 @@ void TrayIcon::attachApp(WId id){ if(id==0){ return; } //nothing to attach else if(AID!=0){ qWarning() << "Tray Icon is already attached to a window!"; return; } AID = id; - //qDebug() << "Container:" << this->winId(); - //qDebug() << " - Tray:" << AID; - QTimer::singleShot(0,this,SLOT(slotAttach()) ); + IID = this->winId(); //embed directly into this widget + //IID = LX11::CreateWindow( this->winId(), this->rect() ); //Create an intermediate window to be the parent + if( LX11::EmbedWindow(AID, IID) ){ + LX11::RestoreWindow(AID); //make it visible + //XSelectInput(QX11Info::display(), AID, StructureNotifyMask); + dmgID = XDamageCreate( QX11Info::display(), AID, XDamageReportRawRectangles ); + updateIcon(); + qDebug() << "New System Tray App:" << AID; + QTimer::singleShot(500, this, SLOT(updateIcon()) ); + }else{ + qWarning() << "Could not Embed Tray Application:" << AID; + //LX11::DestroyWindow(IID); + IID = 0; + AID = 0; + } } void TrayIcon::setSizeSquare(int side){ @@ -58,13 +70,12 @@ void TrayIcon::detachApp(){ qDebug() << " - finished app:" << tmp; //if(IID!=this->winId()){ LX11::DestroyWindow(IID); } IID = 0; - emit AppClosed(); } // ============== // PRIVATE SLOTS // ============== -void TrayIcon::slotAttach(){ +/*void TrayIcon::slotAttach(){ IID = this->winId(); //embed directly into this widget //IID = LX11::CreateWindow( this->winId(), this->rect() ); //Create an intermediate window to be the parent if( LX11::EmbedWindow(AID, IID) ){ @@ -73,16 +84,14 @@ void TrayIcon::slotAttach(){ dmgID = XDamageCreate( QX11Info::display(), AID, XDamageReportRawRectangles ); updateIcon(); qDebug() << "New System Tray App:" << AID; - emit AppAttached(); QTimer::singleShot(500, this, SLOT(updateIcon()) ); }else{ qWarning() << "Could not Embed Tray Application:" << AID; //LX11::DestroyWindow(IID); IID = 0; AID = 0; - emit AppClosed(); } -} +}*/ void TrayIcon::updateIcon(){ if(AID==0){ return; } @@ -102,16 +111,18 @@ void TrayIcon::paintEvent(QPaintEvent *event){ //Now paint the tray app on top of the background //qDebug() << " - Draw tray:" << AID << IID << this->winId(); //qDebug() << " - - " << event->rect().x() << event->rect().y() << event->rect().width() << event->rect().height(); - //qDebug() << " - Get image"; + //qDebug() << " - Get image:" << AID; QPixmap pix = LX11::WindowImage(AID, false); if(pix.isNull()){ //Try to grab the window directly with Qt - //qDebug() << " - Grab window directly"; + //qDebug() << " - - Grab window directly"; pix = QPixmap::grabWindow(AID); } //qDebug() << " - Pix size:" << pix.size().width() << pix.size().height(); //qDebug() << " - Geom:" << this->geometry().x() << this->geometry().y() << this->geometry().width() << this->geometry().height(); - painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) ); + if(!pix.isNull()){ + painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) ); + } //qDebug() << " - Done"; } } diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.h b/lumina-desktop/panel-plugins/systemtray/TrayIcon.h index 97f2fdf5..a3cbac31 100644 --- a/lumina-desktop/panel-plugins/systemtray/TrayIcon.h +++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.h @@ -43,8 +43,8 @@ public slots: private: WId IID, AID; //icon ID and app ID -private slots: - void slotAttach(); //so that the attachment can be done in a new thread +//private slots: + //void slotAttach(); //so that the attachment can be done in a new thread protected: @@ -53,8 +53,8 @@ protected: void resizeEvent(QResizeEvent *event); //bool x11Event(XEvent *event); -signals: - void AppClosed(); - void AppAttached(); +//signals: + //void AppClosed(); + //void AppAttached(); }; #endif
\ No newline at end of file |