aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop/panel-plugins
diff options
context:
space:
mode:
authorKen Moore <ken@pcbsd.org>2014-10-17 08:41:49 -0400
committerKen Moore <ken@pcbsd.org>2014-10-17 08:41:49 -0400
commit0394411a5c589b3c19fd3ecd2a6b4836f1a74a88 (patch)
tree8990178419840553011e2bf38fa079c5f50fc538 /lumina-desktop/panel-plugins
parentAdd a quick "make-linux-distro.sh" script to change the linux template file u... (diff)
downloadlumina-0394411a5c589b3c19fd3ecd2a6b4836f1a74a88.tar.gz
lumina-0394411a5c589b3c19fd3ecd2a6b4836f1a74a88.tar.bz2
lumina-0394411a5c589b3c19fd3ecd2a6b4836f1a74a88.zip
Adjust how the backend for the system tray works:
1) Now the Lumina session registeres the system-wide tray, and just keeps track of the windows that should be visible (preventing any loss of service or apps starting up before the tray is registered). 2) The system tray plugin is now just a "visual tray" for embedding the applications in the panel. The Session only allows a single visual tray to be registered at a time, but sends out signals whenever there is an opening for a visual tray (allowing near-instant transfer of tray applications from one visual tray to another). Also fix a quick bug in lumina-config where the save button was getting activated simply by changing the appearance/plugins tab in the panel configuration (without actually changing anything).
Diffstat (limited to 'lumina-desktop/panel-plugins')
-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