aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop/panel-plugins/systemtray
diff options
context:
space:
mode:
Diffstat (limited to 'lumina-desktop/panel-plugins/systemtray')
-rw-r--r--lumina-desktop/panel-plugins/systemtray/LSysTray.cpp113
-rw-r--r--lumina-desktop/panel-plugins/systemtray/LSysTray.h25
-rw-r--r--lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp35
-rw-r--r--lumina-desktop/panel-plugins/systemtray/TrayIcon.h10
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
bgstack15