diff options
author | Ken Moore <ken@pcbsd.org> | 2014-10-17 08:41:49 -0400 |
---|---|---|
committer | Ken Moore <ken@pcbsd.org> | 2014-10-17 08:41:49 -0400 |
commit | 0394411a5c589b3c19fd3ecd2a6b4836f1a74a88 (patch) | |
tree | 8990178419840553011e2bf38fa079c5f50fc538 /lumina-desktop | |
parent | Add a quick "make-linux-distro.sh" script to change the linux template file u... (diff) | |
download | lumina-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')
-rw-r--r-- | lumina-desktop/LPanel.cpp | 10 | ||||
-rw-r--r-- | lumina-desktop/LSession.cpp | 160 | ||||
-rw-r--r-- | lumina-desktop/LSession.h | 35 | ||||
-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 |
7 files changed, 319 insertions, 69 deletions
diff --git a/lumina-desktop/LPanel.cpp b/lumina-desktop/LPanel.cpp index 5e7ad292..4aa0acae 100644 --- a/lumina-desktop/LPanel.cpp +++ b/lumina-desktop/LPanel.cpp @@ -14,7 +14,7 @@ LPanel::LPanel(QSettings *file, int scr, int num, QWidget *parent) : QWidget(){ bgWindow = parent; //save for later //Setup the widget overlay for the entire panel to provide transparency effects panelArea = new QWidget(this); - QBoxLayout *tmp = new QBoxLayout(QBoxLayout::LeftToRight,this); + QBoxLayout *tmp = new QBoxLayout(QBoxLayout::LeftToRight); tmp->setContentsMargins(0,0,0,0); this->setLayout(tmp); tmp->addWidget(panelArea); @@ -33,13 +33,13 @@ LPanel::LPanel(QSettings *file, int scr, int num, QWidget *parent) : QWidget(){ this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint ); this->setFocusPolicy(Qt::NoFocus); this->setWindowTitle(""); - this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); + this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); //Reserve as panel/dock this->setAttribute(Qt::WA_AlwaysShowToolTips); this->setObjectName("LuminaPanelWidget"); panelArea->setObjectName("LuminaPanelPluginWidget"); //LX11::SetAsPanel(this->winId()); //set proper type of window for a panel since Qt can't do it LX11::SetAsSticky(this->winId()); - layout = new QBoxLayout(QBoxLayout::LeftToRight, this); + layout = new QBoxLayout(QBoxLayout::LeftToRight); layout->setContentsMargins(0,0,0,0); layout->setSpacing(1); //layout->setSizeConstraint(QLayout::SetFixedSize); @@ -118,10 +118,10 @@ void LPanel::UpdatePanel(){ //Ensure this plugin has a unique ID (NOTE: this numbering does not persist between sessions) if(!plugins[i].contains("---")){ int num=1; - while( plugins.contains(plugins[i]+"---"+QString::number(this->number())+"."+QString::number(num)) ){ + while( plugins.contains(plugins[i]+"---"+QString::number(screennum)+"."+QString::number(this->number())+"."+QString::number(num)) ){ num++; } - plugins[i] = plugins[i]+"---"+QString::number(this->number())+"."+QString::number(num); + plugins[i] = plugins[i]+"---"+QString::number(screennum)+"."+QString::number(this->number())+"."+QString::number(num); } //See if this plugin is already there or in a different spot bool found = false; diff --git a/lumina-desktop/LSession.cpp b/lumina-desktop/LSession.cpp index bd7d49fb..0507f920 100644 --- a/lumina-desktop/LSession.cpp +++ b/lumina-desktop/LSession.cpp @@ -16,9 +16,9 @@ #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/extensions/Xrender.h> +#include <X11/extensions/Xdamage.h> //Private/global variables (for static function access) -//static WId LuminaSessionTrayID; static AppMenu *appmenu; static SettingsMenu *settingsmenu; static QTranslator *currTranslator; @@ -37,7 +37,9 @@ LSession::LSession(int &argc, char ** argv) : QApplication(argc, argv){ this->setEffectEnabled( Qt::UI_AnimateCombo, true); this->setEffectEnabled( Qt::UI_AnimateTooltip, true); //this->setStyle( new MenuProxyStyle); //QMenu icon size override - //LuminaSessionTrayID = 0; + SystemTrayID = 0; VisualTrayID = 0; + TrayDmgEvent = 0; + TrayDmgError = 0; } LSession::~LSession(){ @@ -68,7 +70,10 @@ void LSession::setupSession(){ qDebug() << " - Launching Fluxbox"; WM = new WMProcess(); WM->startWM(); - + + //Start the background system tray + startSystemTray(); + //Initialize the desktops updateDesktops(); @@ -233,11 +238,11 @@ void LSession::updateDesktops(){ void LSession::SessionEnding(){ audioThread->wait(3000); //wait a max of 3 seconds for the audio thread to finish + stopSystemTray(); } bool LSession::x11EventFilter(XEvent *event){ //Detect X Event types and send the appropriate signal(s) - emit TrayEvent(event); //Make sure the tray also can check this event switch(event->type){ // ------------------------- case PropertyNotify: @@ -253,7 +258,61 @@ bool LSession::x11EventFilter(XEvent *event){ emit WindowListEvent(); } break; - } + //------------------------------ + // System Tray Events + //------------------------------ + case ClientMessage: + //Only check if the client is the system tray, otherwise ignore + if(event->xany.window == SystemTrayID){ + //qDebug() << "SysTray: ClientMessage"; + switch(event->xclient.data.l[1]){ + case SYSTEM_TRAY_REQUEST_DOCK: + attachTrayWindow(event->xclient.data.l[2]); //Window ID + break; + //case SYSTEM_TRAY_BEGIN_MESSAGE: + //Let the window manager handle the pop-up messages for now + //break; + //case SYSTEM_TRAY_CANCEL_MESSAGE: + //Let the window manager handle the pop-up messages for now + //break; + } + } + break; + case SelectionClear: + if(event->xany.window == SystemTrayID){ + //qDebug() << "SysTray: Selection Clear"; + stopSystemTray(); //de-activate this system tray (release all embeds) + } + break; + case DestroyNotify: + //qDebug() << "SysTray: DestroyNotify"; + removeTrayWindow(event->xany.window); //Check for removing an icon + break; + + case ConfigureNotify: + for(int i=0; i<RunningTrayApps.length(); i++){ + if(event->xany.window==RunningTrayApps[i]){ + //qDebug() << "SysTray: Configure Event" << trayIcons[i]->appID(); + emit TrayIconChanged(RunningTrayApps[i]); //trigger a repaint event + break; + } + } + default: + if(SystemTrayID!=0){ //Only do this if the system tray is available + if(event->type == TrayDmgEvent+XDamageNotify){ + WId ID = reinterpret_cast<XDamageNotifyEvent*>(event)->drawable; + //qDebug() << "SysTray: Damage Event"; + for(int i=0; i<RunningTrayApps.length(); i++){ + if(ID==RunningTrayApps[i]){ + //qDebug() << "SysTray: Damage Event" << ID; + emit TrayIconChanged(ID); //trigger a repaint event + break; + } + } + } + } + + } //end event type switch // ----------------------- //Now continue on with the event handling (don't change it) return false; @@ -306,3 +365,94 @@ void LSession::playAudioFile(QString filepath){ audioThread->start(); } } + +//====================== +// SYSTEM TRAY FUNCTIONS +//====================== +bool LSession::registerVisualTray(WId visualTray){ + //Only one visual tray can be registered at a time + // (limitation of how tray apps are embedded) + if(VisualTrayID==0){ VisualTrayID = visualTray; return true; } + else if(VisualTrayID==visualTray){ return true; } + else{ return false; } +} + +void LSession::unregisterVisualTray(WId visualTray){ + if(VisualTrayID==visualTray){ + qDebug() << "Unregistered Visual Tray"; + VisualTrayID=0; + emit VisualTrayAvailable(); + } +} + +QList<WId> LSession::currentTrayApps(WId visualTray){ + if(visualTray==VisualTrayID){ + return RunningTrayApps; + }else if( registerVisualTray(visualTray) ){ + return RunningTrayApps; + }else{ + return QList<WId>(); + } +} + +void LSession::startSystemTray(){ + if(SystemTrayID!=0){ return; } + RunningTrayApps.clear(); //nothing running yet + SystemTrayID = LX11::startSystemTray(0); + TrayStopping = false; + if(SystemTrayID!=0){ + XSelectInput(QX11Info::display(), SystemTrayID, InputOutput); //make sure TrayID events get forwarded here + XDamageQueryExtension( QX11Info::display(), &TrayDmgEvent, &TrayDmgError); + qDebug() << "System Tray Started Successfully"; + } +} + +void LSession::stopSystemTray(bool detachall){ + TrayStopping = true; //make sure the internal list does not modified during this + //Close all the running Tray Apps + for(int i=0; i<RunningTrayApps.length(); i++){ + if(!detachall){ LX11::CloseWindow(RunningTrayApps[i]); } + } + LX11::closeSystemTray(SystemTrayID); + SystemTrayID = 0; + TrayDmgEvent = 0; + TrayDmgError = 0; + RunningTrayApps.clear(); + emit TrayListChanged(); +} + +void LSession::attachTrayWindow(WId win){ + //static int appnum = 0; + if(TrayStopping){ return; } + if(RunningTrayApps.contains(win)){ return; } //already managed + RunningTrayApps << win; + emit TrayListChanged(); + /*//Now try to embed the window into the tray + qDebug() << "Attach Tray App:" << appnum; + WId cont = LX11::CreateWindow( SystemTrayID, QRect(appnum*64, 0, 64, 64) ); + if( LX11::EmbedWindow(win, cont) ){ + appnum++; + //Successful embed, now set it up for damage report notifications + XDamageCreate( QX11Info::display(), win, XDamageReportRawRectangles ); + //LX11::ResizeWindow(win, 64, 64); //Always use 64x64 if possible (can shrink, not expand later) + LX11::RestoreWindow(win); + //Add it to the tray list + RunningTrayApps << win; + TrayAppContainers << cont; + //Emit that the list has changed + emit TrayListChanged(); + }else{ + LX11::DestroyWindow(cont); //clean up + }*/ +} + +void LSession::removeTrayWindow(WId win){ + if(TrayStopping || SystemTrayID==0){ return; } + for(int i=0; i<RunningTrayApps.length(); i++){ + if(win==RunningTrayApps[i]){ + RunningTrayApps.removeAt(i); + emit TrayListChanged(); + break; + } + } +}
\ No newline at end of file diff --git a/lumina-desktop/LSession.h b/lumina-desktop/LSession.h index cdf0cbd8..3068aac4 100644 --- a/lumina-desktop/LSession.h +++ b/lumina-desktop/LSession.h @@ -30,9 +30,9 @@ #include <LuminaX11.h> //SYSTEM TRAY STANDARD DEFINITIONS -//#define SYSTEM_TRAY_REQUEST_DOCK 0 -//#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -//#define SYSTEM_TRAY_CANCEL_MESSAGE 2 +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_BEGIN_MESSAGE 1 +#define SYSTEM_TRAY_CANCEL_MESSAGE 2 /*class MenuProxyStyle : public QProxyStyle{ public: @@ -54,7 +54,17 @@ public: bool LoadLocale(QString); + //Public System Tray Functions + QList<WId> currentTrayApps(WId visualTray); + bool registerVisualTray(WId); + void unregisterVisualTray(WId); + //System Access + //Return a pointer to the current session + static LSession* handle(){ + return static_cast<LSession*>(LSession::instance()); + } + static void LaunchApplication(QString cmd); static AppMenu* applicationMenu(); static void systemWindow(); @@ -69,6 +79,11 @@ private: WMProcess *WM; QList<LDesktop*> DESKTOPS; QFileSystemWatcher *watcher; + //System Tray Variables + WId SystemTrayID, VisualTrayID; + int TrayDmgEvent, TrayDmgError; + QList<WId> RunningTrayApps; + bool TrayStopping; public slots: void launchStartupApps(); @@ -77,6 +92,12 @@ public slots: private slots: void watcherChange(QString); + //System Tray Functions + void startSystemTray(); + void stopSystemTray(bool detachall = false); + void attachTrayWindow(WId); + void removeTrayWindow(WId); + //Internal simplification functions void checkUserFiles(); void refreshWindowManager(); @@ -85,10 +106,14 @@ private slots: void SessionEnding(); signals: - void NewSystemTrayApp(WId); //WinID - void TrayEvent(XEvent*); + //System Tray Signals + void VisualTrayAvailable(); //new Visual Tray Plugin can be registered + void TrayListChanged(); //Item added/removed from the list + void TrayIconChanged(WId); //WinID of Tray App + //Task Manager Signals void WindowListEvent(WId); void WindowListEvent(); + //General Signals void LocaleChanged(); void DesktopConfigChanged(); 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 |