diff options
-rw-r--r-- | libLumina/LuminaX11.cpp | 4 | ||||
-rw-r--r-- | lumina-config/mainUI.cpp | 32 | ||||
-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 |
9 files changed, 343 insertions, 81 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 418e041f..68d54c6d 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -518,7 +518,7 @@ QPixmap LX11::WindowImage(WId win, bool useleader){ if(leader!=0 && useleader){ win = leader; } //use the leader window instead //First get the size of the window image (embedded in the window attributes) XWindowAttributes att; - if( !XGetWindowAttributes(disp, win, &att) ){ return pix; } //invalid window attributes + if( 0 == XGetWindowAttributes(disp, win, &att) ){ return pix; } //invalid window attributes //Now extract the image XImage *xim = XGetImage(disp, win, 0,0, att.width, att.height, AllPlanes, ZPixmap); if(xim!=0){ @@ -677,7 +677,7 @@ WId LX11::startSystemTray(int screen){ qWarning() << "An alternate system tray is currently in use"; return 0; } - //Create a simple window to register as the tray (not visible) + //Create a simple window to register as the tray (not visible - just off the screen) Window LuminaSessionTrayID = XCreateSimpleWindow(disp, root,-1,-1,1,1,0,0,0); //register this widget as the system tray XSetSelectionOwner(disp, _NET_SYSTEM_TRAY_S, LuminaSessionTrayID, CurrentTime); diff --git a/lumina-config/mainUI.cpp b/lumina-config/mainUI.cpp index 756fc016..e4490659 100644 --- a/lumina-config/mainUI.cpp +++ b/lumina-config/mainUI.cpp @@ -823,17 +823,23 @@ void MainUI::adjustpanel1(){ if(loading){ return; } qDebug() << "Adjust Panel 1:"; ui->toolBox_panel1->setCurrentIndex( ui->toolBox_panel2->currentIndex() ); + bool changed = false; + int newindex=0; switch(ui->combo_panel2_loc->currentIndex()){ case 0: - ui->combo_panel1_loc->setCurrentIndex(1); break; + newindex = 1; break; case 1: - ui->combo_panel1_loc->setCurrentIndex(0); break; + newindex = 0; break; case 2: - ui->combo_panel1_loc->setCurrentIndex(3); break; + newindex = 3; break; case 3: - ui->combo_panel1_loc->setCurrentIndex(2); break; + newindex = 2; break; } - if(!loading){ ui->push_save->setEnabled(true); modpan = true; } + if(newindex != ui->combo_panel1_loc->currentIndex()){ + changed = true; + ui->combo_panel1_loc->setCurrentIndex(newindex); + } + if(!loading && changed){ ui->push_save->setEnabled(true); modpan = true; } } void MainUI::adjustpanel2(){ @@ -841,17 +847,23 @@ void MainUI::adjustpanel2(){ //Adjust panel 2 to complement a panel 1 change qDebug() << "Adjust Panel 2:"; ui->toolBox_panel2->setCurrentIndex( ui->toolBox_panel1->currentIndex() ); + bool changed = false; + int newindex=0; switch(ui->combo_panel1_loc->currentIndex()){ case 0: - ui->combo_panel2_loc->setCurrentIndex(1); break; + newindex = 1; break; case 1: - ui->combo_panel2_loc->setCurrentIndex(0); break; + newindex = 0; break; case 2: - ui->combo_panel2_loc->setCurrentIndex(3); break; + newindex = 3; break; case 3: - ui->combo_panel2_loc->setCurrentIndex(2); break; + newindex = 2; break; } - if(!loading){ ui->push_save->setEnabled(true); modpan = true; } + if(newindex != ui->combo_panel2_loc->currentIndex()){ + changed = true; + ui->combo_panel2_loc->setCurrentIndex(newindex); + } + if(!loading && changed){ ui->push_save->setEnabled(true); modpan = true; } } 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 |