diff options
-rw-r--r-- | libLumina/LuminaX11.cpp | 91 | ||||
-rw-r--r-- | libLumina/LuminaX11.h | 2 | ||||
-rw-r--r-- | lumina-desktop/LPanel.cpp | 25 | ||||
-rw-r--r-- | lumina-desktop/LSession.cpp | 3 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.cpp | 9 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.h | 4 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.cpp | 32 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.h | 2 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp | 48 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.h | 2 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp | 6 |
11 files changed, 174 insertions, 50 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index cb0655e2..e73f124c 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -875,6 +875,17 @@ unsigned int LXCB::CurrentWorkspace(){ return wkspace; } +// === ActiveWindow() === +WId LXCB::ActiveWindow(){ + xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window_unchecked(&EWMH, 0); + xcb_window_t actwin; + if(1 == xcb_ewmh_get_active_window_reply(&EWMH, cookie, &actwin, NULL) ){ + return actwin; + }else{ + return 0; //invalid ID/failure + } +} + // === RegisterVirtualRoots() === void LXCB::RegisterVirtualRoots(QList<WId> roots){ //First convert the QList into the proper format @@ -1084,6 +1095,86 @@ void LXCB::SetAsSticky(WId win){ xcb_flush(QX11Info::connection()); //apply it right away*/ } +// === SetAsPanel() === +void LXCB::SetAsPanel(WId win){ + //Disable Input focus (panel activation ruins task manager window detection routines) + // - Disable Input flag in WM_HINTS + xcb_icccm_wm_hints_t hints; + qDebug() << " - Disable WM_HINTS input flag"; + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(QX11Info::connection(), win); + qDebug() << " -- got cookie"; + if(1 == xcb_icccm_get_wm_hints_reply(QX11Info::connection(), cookie, &hints, NULL) ){ + qDebug() << " -- Set no inputs flag"; + xcb_icccm_wm_hints_set_input(&hints, False); //set no input focus + xcb_icccm_set_wm_hints(QX11Info::connection(), win, &hints); //save hints back to window + qDebug() << " -- Free the hints structure"; + free(&hints); //free up hints structure + } + // - Remove WM_TAKE_FOCUS from the WM_PROTOCOLS for the window + // - - Generate the necessary atoms + qDebug() << " - Generate WM_PROTOCOLS and WM_TAKE_FOCUS atoms"; + xcb_atom_t WM_PROTOCOLS, WM_TAKE_FOCUS; //the two atoms needed + xcb_intern_atom_reply_t *preply = xcb_intern_atom_reply(QX11Info::connection(), \ + xcb_intern_atom(QX11Info::connection(), 0, 12, "WM_PROTOCOLS"), NULL); + xcb_intern_atom_reply_t *freply = xcb_intern_atom_reply(QX11Info::connection(), \ + xcb_intern_atom(QX11Info::connection(), 0, 13, "WM_TAKE_FOCUS"), NULL); + bool gotatoms = false; + if(preply && freply){ + WM_PROTOCOLS = preply->atom; + WM_TAKE_FOCUS = freply->atom; + free(preply); + free(freply); + gotatoms = true; + qDebug() << " -- success"; + } + // - - Now update the protocols for the window + if(gotatoms){ //requires the atoms + qDebug() << " - Get WM_PROTOCOLS"; + xcb_icccm_get_wm_protocols_reply_t proto; + if( 1 == xcb_icccm_get_wm_protocols_reply(QX11Info::connection(), \ + xcb_icccm_get_wm_protocols_unchecked(QX11Info::connection(), win, WM_PROTOCOLS), \ + &proto, NULL) ){ + + //Found the current protocols, see if it has the focus atom set + //remove the take focus atom and re-save them + bool needremove = false; + //Note: This first loop is required so that we can initialize the modified list with a valid size + qDebug() << " -- Check current protocols"; + for(unsigned int i=0; i<proto.atoms_len; i++){ + if(proto.atoms[i] == WM_TAKE_FOCUS){ needremove = true; break;} + } + if(needremove){ + qDebug() << " -- Remove WM_TAKE_FOCUS protocol"; + xcb_atom_t *protolist = new xcb_atom_t[proto.atoms_len-1]; + int num = 0; + for(unsigned int i=0; i<proto.atoms_len; i++){ + if(proto.atoms[i] != WM_TAKE_FOCUS){ + protolist[num] = proto.atoms[i]; + num++; + } + } + qDebug() << " -- Re-save modified protocols"; + xcb_icccm_set_wm_protocols(QX11Info::connection(), win, WM_PROTOCOLS, num, protolist); + } + qDebug() << " -- Clear protocols reply"; + xcb_icccm_get_wm_protocols_reply_wipe(&proto); + }//end of get protocols check + } //end of gotatoms check + //Make sure it has the "dock" window type + // - get the current window types (Not necessary, only 1 type of window needed) + + // - set the adjusted window type(s) + qDebug() << " - Adjust window type"; + xcb_atom_t list[1]; + list[0] = EWMH._NET_WM_WINDOW_TYPE_DOCK; + xcb_ewmh_set_wm_window_type(&EWMH, win, 1, list); + + //Make sure it is on all workspaces + qDebug() << " - Set window as sticky"; + SetAsSticky(win); + +} + // === CloseWindow() === void LXCB::CloseWindow(WId win){ xcb_ewmh_request_close_window(&EWMH, 0, win, QX11Info::getTimestamp(), XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER); diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h index 4c2ada21..ef6fa676 100644 --- a/libLumina/LuminaX11.h +++ b/libLumina/LuminaX11.h @@ -123,6 +123,7 @@ public: // General Information QList<WId> WindowList(bool rawlist = false); //list all non-Lumina windows (rawlist -> all workspaces) unsigned int CurrentWorkspace(); + WId ActiveWindow(); //fetch the ID for the currently active window //Session Modification void RegisterVirtualRoots(QList<WId> roots); @@ -140,6 +141,7 @@ public: //Window Modification void SetAsSticky(WId); //Stick to all workspaces + void SetAsPanel(WId); //Adjust all the window flags for a proper panel (cannot be done through Qt) void CloseWindow(WId); //request that the window be closed void MinimizeWindow(WId); //request that the window be unmapped/minimized void ActivateWindow(WId); //request that the window become active diff --git a/lumina-desktop/LPanel.cpp b/lumina-desktop/LPanel.cpp index 5e47dd6b..8caaa8e9 100644 --- a/lumina-desktop/LPanel.cpp +++ b/lumina-desktop/LPanel.cpp @@ -31,21 +31,26 @@ LPanel::LPanel(QSettings *file, int scr, int num, QWidget *parent) : QWidget(){ qDebug() << " -- Setup Panel"; this->setContentsMargins(0,0,0,0); this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint ); - this->setFocusPolicy(Qt::NoFocus); + this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint ); + this->setWindowTitle(""); - //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 - LSession::handle()->XCB->SetAsSticky(this->winId()); - //LX11::SetAsSticky(this->winId()); layout = new QBoxLayout(QBoxLayout::LeftToRight); layout->setContentsMargins(0,0,0,0); layout->setSpacing(1); //layout->setSizeConstraint(QLayout::SetFixedSize); panelArea->setLayout(layout); + //Set special window flags on the panel for proper usage + this->show(); + this->setFocusPolicy(Qt::NoFocus); + //panels cannot get keyboard focus otherwise it upsets the task manager window detection + this->setAttribute(Qt::WA_X11DoNotAcceptFocus); + this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); + this->setAttribute(Qt::WA_AlwaysShowToolTips); + LSession::handle()->XCB->SetAsSticky(this->winId()); + //LSession::handle()->XCB->SetAsPanel(this->winId()); //make sure this happens after Qt creates the window first + QTimer::singleShot(1,this, SLOT(UpdatePanel()) ); //start this in a new thread connect(screen, SIGNAL(resized(int)), this, SLOT(UpdatePanel()) ); //in case the screen resolution changes } @@ -131,7 +136,11 @@ void LPanel::UpdatePanel(){ } //With QT5, we need to make sure to reset window properties on occasion //LSession::handle()->XCB->SetAsSticky(this->winId()); - + //First test/update all the window attributes as necessary + //if(!this->testAttribute(Qt::WA_X11DoNotAcceptFocus)){ this->setAttribute(Qt::WA_X11DoNotAcceptFocus); } + //if(!this->testAttribute(Qt::WA_X11NetWmWindowTypeDock)){ this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); } + //if(!this->testAttribute(Qt::WA_AlwaysShowToolTips)){ this->setAttribute(Qt::WA_AlwaysShowToolTips); } + //Now update the appearance of the toolbar QString color = settings->value(PPREFIX+"color", "rgba(255,255,255,160)").toString(); QString style = "QWidget#LuminaPanelPluginWidget{ background: %1; border-radius: 3px; border: 1px solid %1; }"; diff --git a/lumina-desktop/LSession.cpp b/lumina-desktop/LSession.cpp index 398f2a5c..034aad6e 100644 --- a/lumina-desktop/LSession.cpp +++ b/lumina-desktop/LSession.cpp @@ -392,9 +392,10 @@ void LSession::WindowPropertyEvent(){ void LSession::WindowPropertyEvent(WId win){ //Emit the single-app signal if the window in question is one used by the task manager + qDebug() << "Single-Property event"; if(RunningApps.contains(win)){ if(DEBUG){ qDebug() << "Single-window property event"; } - emit WindowListEvent(win); + emit WindowListEvent(); } } diff --git a/lumina-desktop/LWinInfo.cpp b/lumina-desktop/LWinInfo.cpp index 25486d23..d46bef92 100644 --- a/lumina-desktop/LWinInfo.cpp +++ b/lumina-desktop/LWinInfo.cpp @@ -35,9 +35,12 @@ QString LWinInfo::Class(){ return LSession::handle()->XCB->WindowClass(window); } -LXCB::WINDOWSTATE LWinInfo::status(){ +LXCB::WINDOWSTATE LWinInfo::status(bool update){ if(window==0){ return LXCB::IGNORE; } - LXCB::WINDOWSTATE ws = LSession::handle()->XCB->WindowState(window); + if(update || cstate == LXCB::IGNORE){ + cstate = LSession::handle()->XCB->WindowState(window); + } + return cstate; //LX11::WINDOWSTATE ws = LX11::GetWindowState(window); /*Lumina::STATES state; switch(ws){ @@ -53,5 +56,5 @@ LXCB::WINDOWSTATE LWinInfo::status(){ state = Lumina::NOSHOW; }*/ //qDebug() << "Window State:" << ws << state; - return ws; + //return ws; }
\ No newline at end of file diff --git a/lumina-desktop/LWinInfo.h b/lumina-desktop/LWinInfo.h index a90b82c6..b483e87e 100644 --- a/lumina-desktop/LWinInfo.h +++ b/lumina-desktop/LWinInfo.h @@ -25,10 +25,12 @@ class LWinInfo{ private: WId window; + LXCB::WINDOWSTATE cstate; //current window state public: LWinInfo(WId id = 0){ window = id; + cstate = LXCB::IGNORE; //make sure this gets updates with the first "status" call } ~LWinInfo(){}; @@ -42,7 +44,7 @@ public: QString text(); QIcon icon(bool &noicon); QString Class(); - LXCB::WINDOWSTATE status(); + LXCB::WINDOWSTATE status(bool update = false); }; #endif
\ No newline at end of file diff --git a/lumina-desktop/LXcbEventFilter.cpp b/lumina-desktop/LXcbEventFilter.cpp index eb56cb89..84948084 100644 --- a/lumina-desktop/LXcbEventFilter.cpp +++ b/lumina-desktop/LXcbEventFilter.cpp @@ -35,21 +35,15 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag switch( ev->response_type & ~0x80){ //============================== case XCB_PROPERTY_NOTIFY: - qDebug() << "Property Notify Event:"; - qDebug() << " - Root Window:" << QX11Info::appRootWindow(); - qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; - //System-wide property change + //qDebug() << "Property Notify Event:"; + //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); + //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; + //System-specific proprty change if( SysNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Update the status/list of all running windows session->WindowPropertyEvent(); - } + //window-specific property change - if( ((xcb_property_notify_event_t*)ev)->atom == session->XCB->EWMH._NET_WM_STATE ){ - if( session->XCB->WindowIsMaximized( ((xcb_property_notify_event_t*)ev)->window ) ){ - //Quick fix for maximized windows (since Fluxbox is not doing the STRUT detection properly) - session->adjustWindowGeom( ((xcb_property_notify_event_t*)ev)->window ); - } - session->WindowPropertyEvent( ((xcb_property_notify_event_t*)ev)->window ); }else if( WinNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Ping only that window session->WindowPropertyEvent( ((xcb_property_notify_event_t*)ev)->window ); @@ -57,9 +51,9 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_CLIENT_MESSAGE: - qDebug() << "Client Message Event"; - qDebug() << " - Root Window:" << QX11Info::appRootWindow(); - qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; + //qDebug() << "Client Message Event"; + //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); + //qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; if( ((xcb_client_message_event_t*)ev)->type == _NET_SYSTEM_TRAY_OPCODE && ((xcb_client_message_event_t*)ev)->format == 32){ //data32[0] is timestamp, [1] is opcode, [2] is window handle if(SYSTEM_TRAY_REQUEST_DOCK == ((xcb_client_message_event_t*)ev)->data.data32[1]){ @@ -68,12 +62,12 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag //Ignore the System Tray messages at the moment (let the WM handle it) //window-specific property changes - }else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){ + /*}else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){ if( session->XCB->WindowIsMaximized( ((xcb_client_message_event_t*)ev)->window ) ){ //Quick fix for maximized windows (since Fluxbox is not doing the STRUT detection properly) session->adjustWindowGeom( ((xcb_client_message_event_t*)ev)->window ); } - session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window ); + session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window );*/ }else if( WinNotifyAtoms.contains( ((xcb_client_message_event_t*)ev)->type ) ){ //Ping only that window session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window ); @@ -81,17 +75,17 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag 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/LXcbEventFilter.h b/lumina-desktop/LXcbEventFilter.h index cdbed042..dafb3212 100644 --- a/lumina-desktop/LXcbEventFilter.h +++ b/lumina-desktop/LXcbEventFilter.h @@ -77,8 +77,8 @@ private: SysNotifyAtoms << session->XCB->EWMH._NET_CLIENT_LIST \ << session->XCB->EWMH._NET_CLIENT_LIST_STACKING \ << session->XCB->EWMH._NET_CURRENT_DESKTOP \ - << session->XCB->EWMH._NET_ACTIVE_WINDOW \ << session->XCB->EWMH._NET_WM_STATE \ + << session->XCB->EWMH._NET_ACTIVE_WINDOW \ << session->XCB->EWMH._NET_WM_ICON \ << session->XCB->EWMH._NET_WM_ICON_GEOMETRY; //_NET_SYSTEM_TRAY_OPCODE diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp index 53ab3a09..7c24dc3d 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp @@ -19,6 +19,7 @@ LTaskButton::LTaskButton(QWidget *parent, bool smallDisplay) : LTBWidget(parent) this->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); this->setAutoRaise(false); //make sure these always look like buttons this->setContextMenuPolicy(Qt::CustomContextMenu); + this->setFocusPolicy(Qt::NoFocus); winMenu->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openActionMenu()) ); connect(this, SIGNAL(clicked()), this, SLOT(buttonClicked()) ); @@ -45,6 +46,10 @@ QString LTaskButton::classname(){ return cname; } +bool LTaskButton::isActive(){ + return cstate == LXCB::ACTIVE; +} + void LTaskButton::addWindow(WId win){ WINLIST << LWinInfo(win); UpdateButton(); @@ -76,7 +81,7 @@ LWinInfo LTaskButton::currentWindow(){ //============= void LTaskButton::UpdateButton(){ if(winMenu->isVisible()){ return; } //skip this if the window menu is currently visible for now - bool statusOnly = WINLIST.length() == LWINLIST.length(); + bool statusOnly = (WINLIST.length() == LWINLIST.length()); LWINLIST = WINLIST; winMenu->clear(); @@ -101,7 +106,7 @@ void LTaskButton::UpdateButton(){ bool junk; QAction *tmp = winMenu->addAction( WINLIST[i].icon(junk), WINLIST[i].text() ); tmp->setData(i); //save which number in the WINLIST this entry is for - LXCB::WINDOWSTATE stat = LSession::handle()->XCB->WindowState(WINLIST[i].windowID()); + LXCB::WINDOWSTATE stat = WINLIST[i].status(true); //update the saved state for the window if(stat==LXCB::ATTENTION){ showstate = stat; } //highest priority else if( stat==LXCB::ACTIVE && showstate != LXCB::ATTENTION){ showstate = stat; } //next priority else if( stat==LXCB::VISIBLE && showstate != LXCB::ATTENTION && showstate != LXCB::ACTIVE){ showstate = stat; } @@ -131,10 +136,19 @@ void LTaskButton::UpdateButton(){ } void LTaskButton::UpdateMenus(){ - //Action menu is very simple right now - can expand it later + //Action menu should be auto-created for the state of the current window (cWin/cstate) actMenu->clear(); - actMenu->addAction( LXDG::findIcon("view-close",""), tr("Minimize Window"), this, SLOT(minimizeWindow()) ); - actMenu->addAction( LXDG::findIcon("view-fullscreen",""), tr("Maximize Window"), this, SLOT(maximizeWindow()) ); + if(cstate!=LXCB::ACTIVE){ + actMenu->addAction( LXDG::findIcon("edit-select",""), tr("Activate Window"), this, SLOT(triggerWindow()) ); + } + if(cstate!=LXCB::INVISIBLE){ + actMenu->addAction( LXDG::findIcon("view-close",""), tr("Minimize Window"), this, SLOT(minimizeWindow()) ); + if(LSession::handle()->XCB->WindowIsMaximized(cWin.windowID()) ){ + actMenu->addAction( LXDG::findIcon("view-restore",""), tr("Restore Window"), this, SLOT(maximizeWindow()) ); + }else{ + actMenu->addAction( LXDG::findIcon("view-fullscreen",""), tr("Maximize Window"), this, SLOT(maximizeWindow()) ); + } + } actMenu->addAction( LXDG::findIcon("window-close",""), tr("Close Window"), this, SLOT(closeWindow()) ); } @@ -171,27 +185,23 @@ void LTaskButton::minimizeWindow(){ if(winMenu->isVisible()){ winMenu->hide(); } LWinInfo win = currentWindow(); LSession::handle()->XCB->MinimizeWindow(win.windowID()); - cWin = LWinInfo(); //clear the current + cWin = LWinInfo(); //clear the current + QTimer::singleShot(100, this, SLOT(UpdateButton()) ); //make sure to update this button if losing active status } void LTaskButton::triggerWindow(){ LWinInfo win = currentWindow(); //Check which state the window is currently in and flip it to the other LXCB::WINDOWSTATE state = cstate; - //if(WINLIST[0].windowID() != win.windowID()){ state = LSession::handle()->XCB->WindowState(win.windowID()); } //need to fetch the state of the window - state = LSession::handle()->XCB->WindowState(win.windowID()); if(DEBUG){ qDebug() << "Window State: " << state; } if(state == LXCB::ACTIVE){ if(DEBUG){ qDebug() << "Minimize Window:" << this->text(); } LSession::handle()->XCB->MinimizeWindow(win.windowID()); + QTimer::singleShot(100, this, SLOT(UpdateButton()) ); //make sure to update this button if losing active status }else{ if(DEBUG){ qDebug() << "Activate Window:" << this->text(); } LSession::handle()->XCB->ActivateWindow(win.windowID()); - }/*else{ - qDebug() << "Restore Window:" << this->text(); - LSession::handle()->XCB->MinimizeWindow(win.windowID()); - LX11::RestoreWindow(win.windowID()); - }*/ + } cWin = LWinInfo(); //clear the current } @@ -199,6 +209,7 @@ void LTaskButton::winClicked(QAction* act){ //Get the window from the action if(act->data().toInt() < WINLIST.length()){ cWin = WINLIST[act->data().toInt()]; + cstate = cWin.status(); }else{ cWin = LWinInfo(); } //clear it //Now trigger the window triggerWindow(); @@ -206,14 +217,19 @@ void LTaskButton::winClicked(QAction* act){ void LTaskButton::openActionMenu(){ //Get the Window the mouse is currently over - QAction *act = winMenu->actionAt(QCursor::pos()); + QPoint curpos = QCursor::pos(); + QAction *act = winMenu->actionAt(winMenu->mapFromGlobal(curpos)); + //qDebug() << "Button Context Menu:" << curpos.x() << curpos.y() << winMenu->geometry().x() << winMenu->geometry().y() << winMenu->geometry().width() << winMenu->geometry().height(); + cWin = WINLIST[0]; //default to the first window if( act != 0 && winMenu->isVisible() ){ //Get the window from the action - qDebug() << "Found Action:" << act->data().toInt(); + //qDebug() << "Found Action:" << act->data().toInt(); if(act->data().toInt() < WINLIST.length()){ cWin = WINLIST[act->data().toInt()]; - }else{ cWin = LWinInfo(); } //clear it + } } + cstate = cWin.status(); //Now show the action menu + UpdateMenus(); actMenu->popup(QCursor::pos()); } diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h index 8ee60b01..b980071e 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h @@ -33,6 +33,7 @@ public: //Window Information QList<WId> windows(); QString classname(); + bool isActive(); //Window Management void addWindow(WId win); //Add a window to this button @@ -49,6 +50,7 @@ private: LWinInfo currentWindow(); //For getting the currently-active window LXCB::WINDOWSTATE cstate; //current state of the button + public slots: void UpdateButton(); //re-sync the current window infomation void UpdateMenus(); //re-create the menus (text + icons) diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp index 67378c68..1785c681 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp @@ -34,6 +34,8 @@ void LTaskManagerPlugin::UpdateButtons(){ //Get the current window list QList<WId> winlist = LSession::handle()->XCB->WindowList(); + //Do not change the status of the previously active window if it just changed to a non-visible window + bool skipActive = !winlist.contains( LSession::handle()->XCB->ActiveWindow() ); //qDebug() << "Update Buttons:" << winlist; if(updating > ctime){ return; } //another thread kicked off already - stop this one //Now go through all the current buttons first @@ -71,7 +73,9 @@ void LTaskManagerPlugin::UpdateButtons(){ if(!updated){ //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 + if(!skipActive || !BUTTONS[i]->isActive()){ + QTimer::singleShot(1,BUTTONS[i], SLOT(UpdateButton()) ); //keep moving on + } } } //Now go through the remaining windows |