diff options
-rw-r--r-- | libLumina/LuminaX11.cpp | 73 | ||||
-rw-r--r-- | libLumina/LuminaX11.h | 8 | ||||
-rw-r--r-- | libLumina/LuminaXDG.cpp | 10 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.cpp | 60 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.h | 47 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.h | 10 | ||||
-rw-r--r-- | lumina-desktop/lumina-desktop.pro | 1 | ||||
-rw-r--r-- | lumina-desktop/main.cpp | 3 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp | 26 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h | 3 | ||||
-rw-r--r-- | lumina-open/main.cpp | 20 |
11 files changed, 181 insertions, 80 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 3509d262..03a33dd0 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -858,12 +858,12 @@ LXCB::~LXCB(){ // === WindowList() === QList<WId> LXCB::WindowList(bool rawlist){ QList<WId> output; - qDebug() << "Get Client list cookie"; + //qDebug() << "Get Client list cookie"; xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_unchecked( &EWMH, 0); xcb_ewmh_get_windows_reply_t winlist; - qDebug() << "Get client list"; + //qDebug() << "Get client list"; if( 1 == xcb_ewmh_get_client_list_reply( &EWMH, cookie, &winlist, NULL) ){ - qDebug() << " - Loop over items"; + //qDebug() << " - Loop over items"; unsigned int wkspace = CurrentWorkspace(); for(unsigned int i=0; i<winlist.windows_len; i++){ //Filter out the Lumina Desktop windows @@ -880,11 +880,11 @@ QList<WId> LXCB::WindowList(bool rawlist){ // === CurrentWorkspace() === unsigned int LXCB::CurrentWorkspace(){ - qDebug() << "Get Current Workspace"; + //qDebug() << "Get Current Workspace"; xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&EWMH, 0); uint32_t wkspace = 0; xcb_ewmh_get_current_desktop_reply(&EWMH, cookie, &wkspace, NULL); - qDebug() << " - done:" << wkspace; + //qDebug() << " - done:" << wkspace; return wkspace; } @@ -892,27 +892,30 @@ unsigned int LXCB::CurrentWorkspace(){ QString LXCB::WindowClass(WId win){ QString out; xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class_unchecked(QX11Info::connection(), win); + if(cookie.sequence == 0){ return out; } xcb_icccm_get_wm_class_reply_t value; if( 1== xcb_icccm_get_wm_class_reply( QX11Info::connection(), cookie, &value, NULL) ){ - out = QString(value.class_name); + out = QString::fromUtf8(value.class_name); + xcb_icccm_get_wm_class_reply_wipe(&value); } - xcb_icccm_get_wm_class_reply_wipe(&value); return out; } // === WindowWorkspace() === unsigned int LXCB::WindowWorkspace(WId win){ - qDebug() << "Get Window Workspace"; + //qDebug() << "Get Window Workspace"; uint32_t wkspace = 0; xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return wkspace; } xcb_ewmh_get_wm_desktop_reply(&EWMH, cookie, &wkspace, NULL); - qDebug() << " - done: " << wkspace; + //qDebug() << " - done: " << wkspace; return wkspace; } // === WindowState() === LXCB::WINDOWSTATE LXCB::WindowState(WId win){ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return IGNORE; } xcb_ewmh_get_atoms_reply_t states; WINDOWSTATE cstate = IGNORE; //First Check for special states (ATTENTION in particular); @@ -951,6 +954,54 @@ LXCB::WINDOWSTATE LXCB::WindowState(WId win){ return cstate; } +// === WindowVisibleIconName() === +QString LXCB::WindowVisibleIconName(WId win){ //_WM_VISIBLE_ICON_NAME + QString out; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_icon_name_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return out; } + xcb_ewmh_get_utf8_strings_reply_t data; + if( 1 == xcb_ewmh_get_wm_visible_icon_name_reply(&EWMH, cookie, &data, NULL) ){ + out = QString::fromUtf8(data.strings, data.strings_len); + } + return out; +} + +// === WindowIconName() === +QString LXCB::WindowIconName(WId win){ //_WM_ICON_NAME + QString out; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return out; } + xcb_ewmh_get_utf8_strings_reply_t data; + if( 1 == xcb_ewmh_get_wm_icon_name_reply(&EWMH, cookie, &data, NULL) ){ + out = QString::fromUtf8(data.strings, data.strings_len); + } + return out; +} + +// === WindowVisibleName() === +QString LXCB::WindowVisibleName(WId win){ //_WM_VISIBLE_NAME + QString out; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_name_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return out; } + xcb_ewmh_get_utf8_strings_reply_t data; + if( 1 == xcb_ewmh_get_wm_visible_name_reply(&EWMH, cookie, &data, NULL) ){ + out = QString::fromUtf8(data.strings, data.strings_len); + } + return out; +} + +// === WindowName() === +QString LXCB::WindowName(WId win){ //_WM_NAME + QString out; + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name_unchecked(&EWMH, win); + if(cookie.sequence == 0){ return out; } + xcb_ewmh_get_utf8_strings_reply_t data; + if( 1 == xcb_ewmh_get_wm_name_reply(&EWMH, cookie, &data, NULL) ){ + out = QString::fromUtf8(data.strings, data.strings_len); + } + return out; +} + // === SetAsSticky() === void LXCB::SetAsSticky(WId win){ //Need to send a client message event for the window so the WM picks it up @@ -972,6 +1023,10 @@ void LXCB::SetAsSticky(WId win){ xcb_flush(QX11Info::connection()); //apply it right away*/ } +// === CloseWindow() === +void LXCB::CloseWindow(WId win){ + xcb_ewmh_request_close_window(&EWMH, 0, win, QX11Info::getTimestamp(), XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER); +} // === SetScreenWorkArea() === /*void LXCB::SetScreenWorkArea(unsigned int screen, QRect rect){ //This is only useful because Fluxbox does not set the _NET_WORKAREA root atom diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h index ac232de1..6e229729 100644 --- a/libLumina/LuminaX11.h +++ b/libLumina/LuminaX11.h @@ -132,9 +132,15 @@ public: QString WindowClass(WId); unsigned int WindowWorkspace(WId); WINDOWSTATE WindowState(WId win); //Visible state of window + QString WindowVisibleIconName(WId win); //_WM_VISIBLE_ICON_NAME + QString WindowIconName(WId win); //_WM_ICON_NAME + QString WindowVisibleName(WId win); //_WM_VISIBLE_NAME + QString WindowName(WId win); //_WM_NAME //Window Modification - void SetAsSticky(WId); + void SetAsSticky(WId); //Stick to all workspaces + void CloseWindow(WId); //request that the window be closed + }; #endif
\ No newline at end of file diff --git a/libLumina/LuminaXDG.cpp b/libLumina/LuminaXDG.cpp index 84a6f665..b58f4326 100644 --- a/libLumina/LuminaXDG.cpp +++ b/libLumina/LuminaXDG.cpp @@ -272,13 +272,17 @@ void LXDG::setEnvironmentVars(){ QIcon LXDG::findIcon(QString iconName, QString fallback){ //Check if the icon is an absolute path and exists + bool DEBUG =false; + if(DEBUG){ qDebug() << "[LXDG] Find icon for:" << iconName; } if(QFile::exists(iconName) && iconName.startsWith("/")){ return QIcon(iconName); } else if(iconName.startsWith("/")){ iconName.section("/",-1); } //Invalid absolute path, just looks for the icon //Check if the icon is actually given - if(iconName.isEmpty()){ return QIcon(fallback); } + if(iconName.isEmpty()){ + if(fallback.isEmpty()){ return QIcon(); } + else{ return LXDG::findIcon(fallback, ""); } + } //Now try to find the icon from the theme - bool DEBUG = false; - if(DEBUG){ qDebug() << "[LXDG] Find icon for:" << iconName; } + if(DEBUG){ qDebug() << "[LXDG] Start search for icon"; } //Check the default theme search paths QStringList paths = QIcon::themeSearchPaths(); if(paths.isEmpty()){ diff --git a/lumina-desktop/LWinInfo.cpp b/lumina-desktop/LWinInfo.cpp new file mode 100644 index 00000000..227dc2d9 --- /dev/null +++ b/lumina-desktop/LWinInfo.cpp @@ -0,0 +1,60 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2014, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "LWinInfo.h" + +#include <LuminaX11.h> + +#include "LSession.h" + +//Information Retrieval + // Don't cache these results because they can change regularly +QString LWinInfo::text(){ + qDebug() << "Window Visible Icon Name:" << window; + if(window==0){ return ""; } + QString nm = LSession::handle()->XCB->WindowVisibleIconName(window); + if(nm.isEmpty()){ qDebug() << " - Window Icon Name"; nm = LSession::handle()->XCB->WindowIconName(window); } + if(nm.isEmpty()){ qDebug() << " - Window Visible Name";nm = LSession::handle()->XCB->WindowVisibleName(window); } + if(nm.isEmpty()){ qDebug() << " - Window Name";nm = LSession::handle()->XCB->WindowName(window); } + return nm; +} + +QIcon LWinInfo::icon(bool &noicon){ + if(window==0){ noicon = true; return QIcon();} + qDebug() << "Check for Window Icon:" << window; + noicon = false; + QIcon ico = LX11::WindowIcon(window); + //Check for a null icon, and supply one if necessary + if(ico.isNull()){ qDebug() << " - Class Icon"; ico = LXDG::findIcon( this->Class().toLower(),""); } + if(ico.isNull()){qDebug() << " - Default Icon"; ico = LXDG::findIcon("preferences-system-windows",""); noicon=true;} + return ico; +} + +QString LWinInfo::Class(){ + qDebug() << "Window Class:" << window; + return LSession::handle()->XCB->WindowClass(window); +} + +Lumina::STATES LWinInfo::status(){ + if(window==0){ return Lumina::NOSHOW; } + LXCB::WINDOWSTATE ws = LSession::handle()->XCB->WindowState(window); + //LX11::WINDOWSTATE ws = LX11::GetWindowState(window); + Lumina::STATES state; + switch(ws){ + case LXCB::VISIBLE: + state = Lumina::VISIBLE; break; + case LXCB::INVISIBLE: + state = Lumina::INVISIBLE; break; + case LXCB::ACTIVE: + state = Lumina::ACTIVE; break; + case LXCB::ATTENTION: + state = Lumina::NOTIFICATION; break; + default: + state = Lumina::NOSHOW; + } + //qDebug() << "Window State:" << ws << state; + return state; +}
\ No newline at end of file diff --git a/lumina-desktop/LWinInfo.h b/lumina-desktop/LWinInfo.h index ae67499b..8fb70ee2 100644 --- a/lumina-desktop/LWinInfo.h +++ b/lumina-desktop/LWinInfo.h @@ -39,49 +39,10 @@ public: //Information Retrieval // Don't cache these results because they can change regularly - QString text(){ - if(window==0){ return ""; } - QString nm = LX11::WindowVisibleIconName(window); - if(nm.isEmpty()){ nm = LX11::WindowIconName(window); } - if(nm.isEmpty()){ nm = LX11::WindowVisibleName(window); } - if(nm.isEmpty()){ nm = LX11::WindowName(window); } - return nm; - } - - QIcon icon(bool &noicon){ - if(window==0){ noicon = true; return QIcon();} - //qDebug() << "Check for Window Icon:" << window; - noicon = false; - QIcon ico = LX11::WindowIcon(window); - //Check for a null icon, and supply one if necessary - if(ico.isNull()){ ico = LXDG::findIcon( this->Class().toLower(),""); } - if(ico.isNull()){ ico = LXDG::findIcon("preferences-system-windows",""); noicon=true;} - return ico; - } - - QString Class(){ - return LX11::WindowClass(window); - } - - Lumina::STATES status(){ - if(window==0){ return Lumina::NOSHOW; } - LX11::WINDOWSTATE ws = LX11::GetWindowState(window); - Lumina::STATES state; - switch(ws){ - case LX11::VISIBLE: - state = Lumina::VISIBLE; break; - case LX11::INVISIBLE: - state = Lumina::INVISIBLE; break; - case LX11::ACTIVE: - state = Lumina::ACTIVE; break; - case LX11::ATTENTION: - state = Lumina::NOTIFICATION; break; - default: - state = Lumina::NOSHOW; - } - //qDebug() << "Window State:" << ws << state; - return state; - } + QString text(); + QIcon icon(bool &noicon); + QString Class(); + Lumina::STATES status(); }; #endif
\ No newline at end of file diff --git a/lumina-desktop/LXcbEventFilter.h b/lumina-desktop/LXcbEventFilter.h index 390a2c14..5f7e6bc8 100644 --- a/lumina-desktop/LXcbEventFilter.h +++ b/lumina-desktop/LXcbEventFilter.h @@ -119,28 +119,28 @@ public: case XCB_PROPERTY_NOTIFY: //qDebug() << "Property Notify Event:"; if( atoms.contains( ((xcb_property_notify_event_t*)ev)->atom) ){ - //qDebug() << " - launch session property event"; + qDebug() << " - launch session property event"; session->WindowPropertyEvent(); } break; case XCB_CLIENT_MESSAGE: - //qDebug() << "Client Message Event"; + qDebug() << "Client Message Event"; checkClientMessage( (xcb_client_message_event_t*)ev ); break; case XCB_DESTROY_NOTIFY: - //qDebug() << "Window Closed Event"; + qDebug() << "Window Closed Event"; session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window ); break; case XCB_CONFIGURE_NOTIFY: - //qDebug() << "Configure Notify Event"; + qDebug() << "Configure Notify Event"; session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window ); break; case XCB_SELECTION_CLEAR: - //qDebug() << "Selection Clear Event"; + qDebug() << "Selection Clear Event"; session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); break; diff --git a/lumina-desktop/lumina-desktop.pro b/lumina-desktop/lumina-desktop.pro index fdc12469..4b232de2 100644 --- a/lumina-desktop/lumina-desktop.pro +++ b/lumina-desktop/lumina-desktop.pro @@ -21,6 +21,7 @@ SOURCES += main.cpp \ LSession.cpp \ LDesktop.cpp \ LPanel.cpp \ + LWinInfo.cpp \ AppMenu.cpp \ SettingsMenu.cpp \ SystemWindow.cpp \ diff --git a/lumina-desktop/main.cpp b/lumina-desktop/main.cpp index 8305be60..091a1355 100644 --- a/lumina-desktop/main.cpp +++ b/lumina-desktop/main.cpp @@ -61,7 +61,8 @@ int main(int argc, char ** argv) //LSession::setGraphicsSystem("native"); //make sure to use X11 graphics system //Setup the log file qDebug() << "Lumina Log File:" << logfile.fileName(); - if(logfile.exists()){ logfile.remove(); } //remove any old one + if(QFile::exists(logfile.fileName()+".old")){ QFile::remove(logfile.fileName()+".old"); } + if(logfile.exists()){ QFile::rename(logfile.fileName(), logfile.fileName()+".old"); } //Make sure the parent directory exists if(!QFile::exists(QDir::homePath()+"/.lumina/logs")){ QDir dir; diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp index 8f131c9e..3f223a63 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp @@ -8,7 +8,6 @@ #include "../../LSession.h" LTaskManagerPlugin::LTaskManagerPlugin(QWidget *parent, QString id, bool horizontal) : LPPlugin(parent, id, horizontal){ - updating=false; timer = new QTimer(this); timer->setSingleShot(true); timer->setInterval(10); // 1/100 second @@ -27,18 +26,22 @@ LTaskManagerPlugin::~LTaskManagerPlugin(){ // PRIVATE SLOTS //============== void LTaskManagerPlugin::UpdateButtons(){ - if(updating){ timer->start(); return; } //check again in a moment - //Make sure this only runs one at a time - updating=true; + updating = QDateTime::currentDateTime(); //global time stamp + QDateTime ctime = updating; //current thread time stamp + //Get the current window list QList<WId> winlist = LSession::handle()->XCB->WindowList(); //qDebug() << "Update Buttons:" << winlist; + if(updating > ctime){ return; } //another thread kicked off already - stop this one //Now go through all the current buttons first for(int i=0; i<BUTTONS.length(); i++){ //Get the windows managed in this button QList<LWinInfo> WI = BUTTONS[i]->windows(); bool updated=false; + if(updating > ctime){ return; } //another thread kicked off already - stop this one + //Loop over all the windows for this button for(int w=0; w<WI.length(); w++){ + if(updating > ctime){ return; } //another thread kicked off already - stop this one if( winlist.contains( WI[w].windowID() ) ){ //Still current window - update it later winlist.removeAll(WI[w].windowID()); //remove this window from the list since it is done @@ -46,42 +49,48 @@ void LTaskManagerPlugin::UpdateButtons(){ //Window was closed - remove it if(WI.length()==1){ //Remove the entire button + qDebug() << "Window Closed: Remove Button" ; this->layout()->takeAt(i); //remove from the layout delete BUTTONS.takeAt(i); i--; updated = true; //prevent updating a removed button break; //break out of the button->window loop }else{ - //qDebug() << "Remove Window:" << WI[w].windowID() << "Button:" << w; + qDebug() << "Window Closed: Remove from button:" << WI[w].windowID() << "Button:" << w; BUTTONS[i]->rmWindow(WI[w]); // one of the multiple windows for the button WI.removeAt(w); //remove this window from the list w--; } updated=true; //button already changed } + if(updating > ctime){ return; } //another thread kicked off already - stop this one } if(!updated){ - //qDebug() << "Update Button:" << i; + qDebug() << "Update Button:" << i; + if(updating > ctime){ return; } //another thread kicked off already - stop this one QTimer::singleShot(1,BUTTONS[i], SLOT(UpdateButton()) ); //keep moving on } } //Now go through the remaining windows for(int i=0; i<winlist.length(); i++){ //New windows, create buttons for each (add grouping later) + if(updating > ctime){ return; } //another thread kicked off already - stop this one //Check for a button that this can just be added to QString ctxt = LX11::WindowClass(winlist[i]); bool found = false; for(int b=0; b<BUTTONS.length(); b++){ + if(updating > ctime){ return; } //another thread kicked off already - stop this one if(BUTTONS[b]->classname()== ctxt){ found = true; - //qDebug() << "Add Window to Button:" << b; + qDebug() << "Add Window to Button:" << b; BUTTONS[b]->addWindow(winlist[i]); break; } } if(!found){ + if(updating > ctime){ return; } //another thread kicked off already - stop this one //No group, create a new button - //qDebug() << "New Button"; + qDebug() << "New Button"; LTaskButton *but = new LTaskButton(this); but->addWindow( LWinInfo(winlist[i]) ); if(this->layout()->direction()==QBoxLayout::LeftToRight){ @@ -93,7 +102,6 @@ void LTaskManagerPlugin::UpdateButtons(){ BUTTONS << but; } } - updating=false; //flag that we are done updating the buttons } void LTaskManagerPlugin::checkWindows(){ diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h index ca470da6..b8867074 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h @@ -14,6 +14,7 @@ #include <QDebug> #include <QTimer> #include <QEvent> +#include <QDateTime> // libLumina includes #include <LuminaX11.h> @@ -32,7 +33,7 @@ public: private: QList<LTaskButton*> BUTTONS; //to keep track of the current buttons QTimer *timer; - bool updating; //quick flag for if it is currently working + QDateTime updating; //quick flag for if it is currently working private slots: void UpdateButtons(); diff --git a/lumina-open/main.cpp b/lumina-open/main.cpp index a92a585f..e560f0df 100644 --- a/lumina-open/main.cpp +++ b/lumina-open/main.cpp @@ -292,29 +292,33 @@ int main(int argc, char **argv){ //Now run the command (move to execvp() later?) if(cmd.isEmpty()){ return 0; } //no command to run (handled internally) if(!args.isEmpty()){ cmd.append(" \""+args+"\""); } - int retcode = system( cmd.toUtf8() ); - /* + //int retcode = system( cmd.toUtf8() ); + qDebug() << "[lumina-open] Running Cmd:" << cmd; QProcess *p = new QProcess(); p->setProcessEnvironment(QProcessEnvironment::systemEnvironment()); if(!path.isEmpty() && QFile::exists(path)){ p->setWorkingDirectory(path); } - p->start(cmd+" \""+args+"\""); + p->start(cmd); //Check the startup procedure - while(!p->waitForStarted(5000)){ + /*while(!p->waitForStarted(5000)){ if(p->state() == QProcess::NotRunning){ //bad/invalid start - qDebug() << "[lumina-open] Application did not startup properly:"<<cmd+" "+args; + qDebug() << "[lumina-open] Application did not start properly:"<<cmd; return p->exitCode(); }else if(p->state() == QProcess::Running){ //This just missed the "started" signal - continue break; } - } + }*/ //Now check up on it once every minute until it is finished while(!p->waitForFinished(60000)){ + qDebug() << "[lumina-open] process check:" << p->state(); if(p->state() != QProcess::Running){ break; } //somehow missed the finished signal } - int retcode = p->exitCode();*/ - if(retcode!=0){ + int retcode = p->exitCode(); + qDebug() << "[lumina-open] Finished Cmd:" << cmd << retcode << p->exitStatus(); + + //if(retcode!=0 ){ + if(p->exitStatus() == QProcess::CrashExit){ qDebug() << "[lumina-open] Application Error:" << retcode; //Setup the application QApplication App(argc, argv); |