diff options
-rw-r--r-- | libLumina/LuminaX11.cpp | 153 | ||||
-rw-r--r-- | libLumina/LuminaX11.h | 9 | ||||
-rw-r--r-- | lumina-desktop/LDesktop.cpp | 15 | ||||
-rw-r--r-- | lumina-desktop/LDesktop.h | 5 | ||||
-rw-r--r-- | lumina-desktop/LPanel.cpp | 7 | ||||
-rw-r--r-- | lumina-desktop/LSession.cpp | 132 | ||||
-rw-r--r-- | lumina-desktop/LSession.h | 12 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.cpp | 23 | ||||
-rw-r--r-- | lumina-desktop/LWinInfo.h | 4 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.h | 1 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/LTBWidget.h | 1 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp | 46 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.h | 4 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp | 10 |
14 files changed, 287 insertions, 135 deletions
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 03a33dd0..2230c1ff 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -26,19 +26,6 @@ #include <xcb/xcb_ewmh.h> #include <xcb/xcb_icccm.h> -//xcb_ewmh_connection_t ewmh_handle; - -//===== Get EWMH connection handle ===== -/*xcb_ewmh_connection_t* LX11::EWMH_C(){ - static bool firstrun = true; - if(firstrun){ - qDebug() << "Init EWMH structure"; - xcb_ewmh_init_atoms(QX11Info::connection(), &ewmh_handle); - firstrun = false; - } - qDebug() << "Return EWMH structure pointer:" << &ewmh_handle; - return &ewmh_handle; -}*/ //===== WindowList() ======== QList<WId> LX11::WindowList(){ @@ -888,6 +875,19 @@ unsigned int LXCB::CurrentWorkspace(){ return wkspace; } +// === RegisterVirtualRoots() === +void LXCB::RegisterVirtualRoots(QList<WId> roots){ + //First convert the QList into the proper format + xcb_window_t *list = new xcb_window_t[ roots.length() ]; + for(int i=0; i<roots.length(); i++){ + list[i] = roots[i]; //move from the QList to the array + } + //Now set the property + xcb_ewmh_set_virtual_roots(&EWMH, 0, roots.length(), list); + //Now delete the temporary array from memory + delete list; +} + // === WindowClass() === QString LXCB::WindowClass(WId win){ QString out; @@ -912,6 +912,49 @@ unsigned int LXCB::WindowWorkspace(WId win){ return wkspace; } +// === WindowGeometry() === +QRect LXCB::WindowGeometry(WId win, bool includeFrame){ + QRect geom; + xcb_get_geometry_cookie_t cookie = xcb_get_geometry(QX11Info::connection(), win); + xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(QX11Info::connection(), cookie, NULL); + //qDebug() << "Get Window Geometry:" << reply; + if(reply != 0){ + geom = QRect(0, 0, reply->width, reply->height); //make sure to use the origin point for the window + //qDebug() << " - "<<reply->x << reply->y << reply->width << reply->height; + free(reply); + if(includeFrame){ + //Need to add/include the frame extents as well (assuming the frame info is available) + xcb_get_property_cookie_t cookie = xcb_ewmh_get_frame_extents_unchecked(&EWMH, win); + if(cookie.sequence != 0){ + xcb_ewmh_get_extents_reply_t frame; + if(1== xcb_ewmh_get_frame_extents_reply(&EWMH, cookie, &frame, NULL) ){ + //adjust the origin point to account for the frame + geom.translate(-frame.left, -frame.top); //move to the orign point for the frame + //adjust the size (include the frame sizes) + //geom.setWidth( geom.width() + frame.left + frame.right ); + //geom.setHeight( geom.height() + frame.top + frame.bottom ); + } + //qDebug() << " - Frame:" << frame.left << frame.right << frame.top << frame.bottom; + //qDebug() << " - Modified with Frame:" << geom.x() << geom.y() << geom.width() << geom.height(); + } + } + //Now need to convert this to absolute coordinates (not parent-relavitve) + xcb_translate_coordinates_cookie_t tcookie = xcb_translate_coordinates(QX11Info::connection(), win, QX11Info::appRootWindow(), geom.x(), geom.y()); + xcb_translate_coordinates_reply_t *trans = xcb_translate_coordinates_reply(QX11Info::connection(), tcookie, NULL); + if(trans!=0){ + //qDebug() << " - Got Translation:" << trans->dst_x << trans->dst_y; + //Replace the origin point with the global position (sizing remains the same) + geom.moveLeft(trans->dst_x); //adjust X coordinate (no size change) + geom.moveTop(trans->dst_y); //adjust Y coordinate (no size change) + free(trans); + } + }else{ + //Need to do another catch for this situation (probably not mapped yet) + } + + return geom; +} + // === WindowState() === LXCB::WINDOWSTATE LXCB::WindowState(WId win){ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state_unchecked(&EWMH, win); @@ -1027,6 +1070,90 @@ void LXCB::SetAsSticky(WId win){ void LXCB::CloseWindow(WId win){ xcb_ewmh_request_close_window(&EWMH, 0, win, QX11Info::getTimestamp(), XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER); } + +// === MinimizeWindow() === +void LXCB::MinimizeWindow(WId win){ //request that the window be unmapped/minimized + //Note: Fluxbox completely removes this window from the open list if unmapped manually + // xcb_unmap_window(QX11Info::connection(), win); + //xcb_flush(QX11Info::connection()); //make sure the command is sent out right away + + //Need to send a client message event for the window so the WM picks it up + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; + event.type = EWMH._NET_WM_STATE; + event.data.data32[0] = 1; //set to toggle (switch back and forth) + event.data.data32[1] = EWMH._NET_WM_STATE_HIDDEN; + event.data.data32[2] = 0; + event.data.data32[3] = 0; + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, QX11Info::appRootWindow(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); +} + +// === ActivateWindow() === +void LXCB::ActivateWindow(WId win){ //request that the window become active + //First need to get the currently active window + 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) ){ + actwin = 0; + } + if(actwin == win){ return; } //requested window is already active + +//Need to send a client message event for the window so the WM picks it up + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; //window to activate + event.type = EWMH._NET_ACTIVE_WINDOW; + event.data.data32[0] = 2; //pager/direct user interaction + event.data.data32[1] = QX11Info::getTimestamp(); //current timestamp + event.data.data32[2] = actwin; //currently active window (0 if none) + event.data.data32[3] = 0; + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, QX11Info::appRootWindow(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + +} + +// === MaximizeWindow() === +void LXCB::MaximizeWindow(WId win){ //request that the window become maximized + //Need to send a client message event for the window so the WM picks it up + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; + event.type = EWMH._NET_WM_STATE; + event.data.data32[0] = 2; //set to toggle (switch back and forth) + event.data.data32[1] = EWMH._NET_WM_STATE_MAXIMIZED_VERT; + event.data.data32[2] = EWMH._NET_WM_STATE_MAXIMIZED_HORZ; + event.data.data32[3] = 0; + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, QX11Info::appRootWindow(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + +} + +// === MoveResizeWindow() === +void LXCB::MoveResizeWindow(WId win, QRect geom){ + //NOTE: geom needs to be in root/absolute coordinates! + //qDebug() << "MoveResize Window:" << geom.x() << geom.y() << geom.width() << geom.height(); + + //Move the window + /*xcb_ewmh_request_moveresize_window(&EWMH, 0, win, XCB_GRAVITY_STATIC, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER, \ + XCB_EWMH_MOVERESIZE_WINDOW_X | XCB_EWMH_MOVERESIZE_WINDOW_Y | XCB_MOVERESIZE_WINDOW_WIDTH | XCB_MOVERESIZE_WINDOW_HEIGHT, \ + geom.x(), geom.y(), geom.width(), geom.height());*/ + + //Use the basic XCB functions instead of ewmh (Issues with combining the XCB_EWMH_MOVERESIZE _*flags) + uint32_t values[4]; + values[0] = geom.x(); values[1] = geom.y(); + values[2] = geom.width(); values[3] = geom.height(); + xcb_configure_window(QX11Info::connection(), win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); + +} + // === 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 6e229729..df32cc1c 100644 --- a/libLumina/LuminaX11.h +++ b/libLumina/LuminaX11.h @@ -126,11 +126,12 @@ public: unsigned int CurrentWorkspace(); //Session Modification - + void RegisterVirtualRoots(QList<WId> roots); //Window Information QString WindowClass(WId); - unsigned int WindowWorkspace(WId); + unsigned int WindowWorkspace(WId); //The workspace the window is on + QRect WindowGeometry(WId, bool includeFrame = true); //the geometry of the window (frame excluded) WINDOWSTATE WindowState(WId win); //Visible state of window QString WindowVisibleIconName(WId win); //_WM_VISIBLE_ICON_NAME QString WindowIconName(WId win); //_WM_ICON_NAME @@ -140,6 +141,10 @@ public: //Window Modification void SetAsSticky(WId); //Stick to all workspaces 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 + void MaximizeWindow(WId); //request that the window become maximized + void MoveResizeWindow(WId win, QRect geom); }; diff --git a/lumina-desktop/LDesktop.cpp b/lumina-desktop/LDesktop.cpp index 07225fad..16d74f9d 100644 --- a/lumina-desktop/LDesktop.cpp +++ b/lumina-desktop/LDesktop.cpp @@ -58,6 +58,20 @@ void LDesktop::hide(){ for(int i=0; i<PANELS.length(); i++){ PANELS[i]->hide(); } } +WId LDesktop::backgroundID(){ + if(bgWindow!=0){ return bgWindow->winId(); } + else{ return QX11Info::appRootWindow(); } +} + +QRect LDesktop::availableScreenGeom(){ + //Return a QRect containing the (global) screen area that is available (not under any panels) + if(bgDesktop!=0){ + return globalWorkRect; //saved from previous calculations + }else{ + return desktop->screenGeometry(desktopnumber); + } +} + void LDesktop::SystemLogout(){ LSession::handle()->systemWindow(); } @@ -419,6 +433,7 @@ void LDesktop::UpdateDesktopPluginArea(){ QRect rec = visReg.boundingRect(); //LSession::handle()->XCB->SetScreenWorkArea((unsigned int) desktopnumber, rec); //Now remove the X offset to place it on the current screen (needs widget-coords, not global) + globalWorkRect = rec; //save this for later rec.moveTopLeft( QPoint( rec.x()-desktop->screenGeometry(desktopnumber).x() , rec.y() ) ); //qDebug() << "DPlug Area:" << rec.x() << rec.y() << rec.width() << rec.height(); bgDesktop->setGeometry( rec ); diff --git a/lumina-desktop/LDesktop.h b/lumina-desktop/LDesktop.h index 65e40322..e21ca19a 100644 --- a/lumina-desktop/LDesktop.h +++ b/lumina-desktop/LDesktop.h @@ -41,6 +41,9 @@ public: void show(); void hide(); + WId backgroundID(); + QRect availableScreenGeom(); + public slots: void SystemLogout(); void SystemTerminal(); @@ -66,7 +69,7 @@ private: QList<LDPlugin*> PLUGINS; QFileSystemWatcher *watcher; QString CBG; //current background - + QRect globalWorkRect; void CreateDesktopPluginContainer(LDPlugin*); private slots: diff --git a/lumina-desktop/LPanel.cpp b/lumina-desktop/LPanel.cpp index b94534b8..5e47dd6b 100644 --- a/lumina-desktop/LPanel.cpp +++ b/lumina-desktop/LPanel.cpp @@ -31,7 +31,7 @@ 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::FramelessWindowHint ); + this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint ); this->setFocusPolicy(Qt::NoFocus); this->setWindowTitle(""); //this->setAttribute(Qt::WA_X11NetWmWindowTypeDock); //Reserve as panel/dock @@ -130,9 +130,8 @@ void LPanel::UpdatePanel(){ } } //With QT5, we need to make sure to reset window properties on occasion - LSession::handle()->XCB->SetAsSticky(this->winId()); - //LX11::SetAsPanel(this->winId()); - //LX11::SetAsSticky(this->winId()); + //LSession::handle()->XCB->SetAsSticky(this->winId()); + //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 4c8d33bb..2db26647 100644 --- a/lumina-desktop/LSession.cpp +++ b/lumina-desktop/LSession.cpp @@ -252,6 +252,8 @@ void LSession::updateDesktops(){ } } //qDebug() << " - Done Starting Desktops"; + //Make sure all the background windows are registered on the system as virtual roots + QTimer::singleShot(200,this, SLOT(registerDesktopWindows())); if(firstrun){ return; } //Done right here on first run //Now go through and make sure to delete any desktops for detached screens for(int i=0; i<DESKTOPS.length(); i++){ @@ -266,89 +268,54 @@ void LSession::updateDesktops(){ //qDebug() << " - Done Checking Desktops"; } +void LSession::registerDesktopWindows(){ + QList<WId> wins; + for(int i=0; i<DESKTOPS.length(); i++){ + wins << DESKTOPS[i]->backgroundID(); + } + XCB->RegisterVirtualRoots(wins); +} + +void LSession::adjustWindowGeom(WId win){ + //Quick hack for making sure that new windows are not located underneath any panels + // Get the window location + QRect geom = XCB->WindowGeometry(win, true); //always include the frame if possible + if(DEBUG){ qDebug() << "Adjust Window Geometry:" << XCB->WindowClass(win) << !geom.isNull(); } + if(geom.isNull()){ return; } //Could not get geometry + //Get the available geometry for the screen the window is on + QRect desk; + for(int i=0; i<DESKTOPS.length(); i++){ + if( this->desktop()->screenGeometry(DESKTOPS[i]->Screen()).contains(geom.topLeft()) ){ + //Window is on this screen + if(DEBUG){ qDebug() << " - On Screen:" << DESKTOPS[i]->Screen(); } + desk = DESKTOPS[i]->availableScreenGeom(); + break; + } + } + //Adjust the window location if necessary + if(!desk.contains(geom) ){ + if(DEBUG){ + qDebug() << "Desk:" << desk.x() << desk.y() << desk.width() << desk.height(); + qDebug() << "Geom:" << geom.x() << geom.y() << geom.width() << geom.height(); + } + //Adjust origin point for left/top margins + if(geom.y() < desk.y()){ geom.moveTop(desk.y()); } //move down to the edge (top panel) + if(geom.x() < desk.x()){ geom.moveLeft(desk.x()); } //move right to the edge (left panel) + //Adjust size for right/bottom margins (within reason, since window titles are on top normally) + if(geom.right() > desk.right() && (geom.width() > 100)){ geom.setRight(desk.right()); } + if(geom.bottom() > desk.bottom() && geom.height() > 100){ geom.setBottom(desk.bottom()); } + //Now move/resize the window + if(DEBUG){ qDebug() << "New Geom:" << geom.x() << geom.y() << geom.width() << geom.height(); } + XCB->MoveResizeWindow(win, geom); + } + +} 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) - switch(event->type){ - // ------------------------- - case PropertyNotify: - //qDebug() << "Property Event:"; - if(event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_CLIENT_LIST",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_ACTIVE_WINDOW",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_WM_NAME",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_WM_VISIBLE_NAME",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_WM_ICON_NAME",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_WM_STATE",false) \ - || event->xproperty.atom == XInternAtom(QX11Info::display(),"_NET_WM_VISIBLE_ICON_NAME",false) ){ - LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) - 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; -}*/ - //=============== // SYSTEM ACCESS //=============== @@ -407,7 +374,16 @@ void LSession::playAudioFile(QString filepath){ // ======================= void LSession::WindowPropertyEvent(){ if(DEBUG){ qDebug() << "Window Property Event"; } - LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) + QList<WId> newapps = XCB->WindowList(); + if(RunningApps.length() < newapps.length()){ + //New Window found + LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) + //Perform sanity checks on any new window geometries + for(int i=0; i<newapps.length(); i++){ + if(!RunningApps.contains(newapps[i])){ adjustWindowGeom(newapps[i]); } + } + } + RunningApps = newapps; emit WindowListEvent(); } diff --git a/lumina-desktop/LSession.h b/lumina-desktop/LSession.h index 20466b16..cc918407 100644 --- a/lumina-desktop/LSession.h +++ b/lumina-desktop/LSession.h @@ -28,7 +28,6 @@ #include "SystemWindow.h" #include "LDesktop.h" #include "WMProcess.h" -//#include "LXcbEventFilter.h" #include <LuminaX11.h> @@ -53,10 +52,6 @@ public: //Functions to be called during startup void setupSession(); - //virtual bool x11EventFilter(XEvent *event); - - //bool LoadLocale(QString); - //Public System Tray Functions QList<WId> currentTrayApps(WId visualTray); bool registerVisualTray(WId); @@ -93,7 +88,7 @@ private: WMProcess *WM; QList<LDesktop*> DESKTOPS; QFileSystemWatcher *watcher; - //XCBEventFilter *evFilter; + //Internal variable for global usage AppMenu *appmenu; SettingsMenu *settingsmenu; @@ -108,6 +103,9 @@ private: QList<WId> RunningTrayApps; bool TrayStopping; + //Task Manager Variables + QList<WId> RunningApps; + public slots: void launchStartupApps(); @@ -125,6 +123,8 @@ private slots: void checkUserFiles(); void refreshWindowManager(); void updateDesktops(); + void registerDesktopWindows(); + void adjustWindowGeom(WId win); void SessionEnding(); diff --git a/lumina-desktop/LWinInfo.cpp b/lumina-desktop/LWinInfo.cpp index 227dc2d9..25486d23 100644 --- a/lumina-desktop/LWinInfo.cpp +++ b/lumina-desktop/LWinInfo.cpp @@ -13,36 +13,33 @@ //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); } + if(nm.isEmpty()){ nm = LSession::handle()->XCB->WindowIconName(window); } + if(nm.isEmpty()){ nm = LSession::handle()->XCB->WindowVisibleName(window); } + if(nm.isEmpty()){ 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;} + if(ico.isNull()){ ico = LXDG::findIcon( this->Class().toLower(),""); } + if(ico.isNull()){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 LWinInfo::status(){ + if(window==0){ return LXCB::IGNORE; } LXCB::WINDOWSTATE ws = LSession::handle()->XCB->WindowState(window); //LX11::WINDOWSTATE ws = LX11::GetWindowState(window); - Lumina::STATES state; + /*Lumina::STATES state; switch(ws){ case LXCB::VISIBLE: state = Lumina::VISIBLE; break; @@ -54,7 +51,7 @@ Lumina::STATES LWinInfo::status(){ state = Lumina::NOTIFICATION; break; default: state = Lumina::NOSHOW; - } + }*/ //qDebug() << "Window State:" << ws << state; - return state; + return ws; }
\ No newline at end of file diff --git a/lumina-desktop/LWinInfo.h b/lumina-desktop/LWinInfo.h index 8fb70ee2..a90b82c6 100644 --- a/lumina-desktop/LWinInfo.h +++ b/lumina-desktop/LWinInfo.h @@ -18,7 +18,7 @@ #include <LuminaXDG.h> // Local includes -#include "Globals.h" //For the STATES enumeration definition +//#include "Globals.h" //For the STATES enumeration definition //#include "LSession.h" @@ -42,7 +42,7 @@ public: QString text(); QIcon icon(bool &noicon); QString Class(); - Lumina::STATES status(); + LXCB::WINDOWSTATE status(); }; #endif
\ No newline at end of file diff --git a/lumina-desktop/LXcbEventFilter.h b/lumina-desktop/LXcbEventFilter.h index 5f7e6bc8..806e6013 100644 --- a/lumina-desktop/LXcbEventFilter.h +++ b/lumina-desktop/LXcbEventFilter.h @@ -47,7 +47,6 @@ XCB_SELECTION_[CLEAR | REQUEST | NOTIFY] XCB_COLORMAP_NOTIFY XCB_CLIENT_MESSAGE -Also: it appears that the Xlib "Window" is identical to an XCB "xcb_window_t" */ //SYSTEM TRAY STANDARD DEFINITIONS diff --git a/lumina-desktop/panel-plugins/LTBWidget.h b/lumina-desktop/panel-plugins/LTBWidget.h index 7ca46d0d..d1e69b6e 100644 --- a/lumina-desktop/panel-plugins/LTBWidget.h +++ b/lumina-desktop/panel-plugins/LTBWidget.h @@ -16,6 +16,7 @@ class LTBWidget : public QToolButton{ Q_OBJECT + private: LXCB::WINDOWSTATE cstate; QString rawstyle; diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp index 3b88b537..79981754 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp @@ -7,6 +7,10 @@ #include "LTaskButton.h" #include "LSession.h" +#ifndef DEBUG +#define DEBUG 0 +#endif + LTaskButton::LTaskButton(QWidget *parent, bool smallDisplay) : LTBWidget(parent){ actMenu = new QMenu(this); winMenu = new QMenu(this); @@ -119,11 +123,14 @@ void LTaskButton::UpdateButton(){ else{ this->setText("("+QString::number(WINLIST.length())+")"); } } this->setState(showstate); //Make sure this is after the button setup so that it properly sets the margins/etc + cstate = showstate; //save this for later } void LTaskButton::UpdateMenus(){ //Action menu is very simple right now - can expand it later 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()) ); actMenu->addAction( LXDG::findIcon("window-close",""), tr("Close Window"), this, SLOT(closeWindow()) ); } @@ -139,27 +146,47 @@ void LTaskButton::buttonClicked(){ } void LTaskButton::closeWindow(){ + if(DEBUG){ qDebug() << "Close Window:" << this->text(); } if(winMenu->isVisible()){ winMenu->hide(); } LWinInfo win = currentWindow(); LSession::handle()->XCB->CloseWindow(win.windowID()); - //LX11::CloseWindow(win.windowID()); cWin = LWinInfo(); //clear the current } +void LTaskButton::maximizeWindow(){ + if(DEBUG){ qDebug() << "Maximize Window:" << this->text(); } + if(winMenu->isVisible()){ winMenu->hide(); } + LWinInfo win = currentWindow(); + LSession::handle()->XCB->MaximizeWindow(win.windowID()); + cWin = LWinInfo(); //clear the current +} + +void LTaskButton::minimizeWindow(){ + if(DEBUG){ qDebug() << "Minimize Window:" << this->text(); } + if(winMenu->isVisible()){ winMenu->hide(); } + LWinInfo win = currentWindow(); + LSession::handle()->XCB->MinimizeWindow(win.windowID()); + cWin = LWinInfo(); //clear the current +} + void LTaskButton::triggerWindow(){ LWinInfo win = currentWindow(); //Check which state the window is currently in and flip it to the other - LX11::WINDOWSTATE state = LX11::GetWindowState(win.windowID()); - if(state == LX11::ACTIVE){ - qDebug() << "Minimize Window:" << this->text(); - LX11::IconifyWindow(win.windowID()); - }else if(state == LX11::VISIBLE){ - qDebug() << "Activate Window:" << this->text(); - LX11::ActivateWindow(win.windowID()); + 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()); }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 } @@ -177,6 +204,7 @@ void LTaskButton::openActionMenu(){ QAction *act = winMenu->actionAt(QCursor::pos()); if( act != 0 && winMenu->isVisible() ){ //Get the window from the action + qDebug() << "Found Action:" << act->data().toInt(); if(act->data().toInt() < WINLIST.length()){ cWin = WINLIST[act->data().toInt()]; }else{ cWin = LWinInfo(); } //clear it diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h index 1fd81e0b..3202d676 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h @@ -48,7 +48,7 @@ private: bool noicon, showText; 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) @@ -56,6 +56,8 @@ public slots: private slots: void buttonClicked(); void closeWindow(); //send the signal to close a window + void maximizeWindow(); //send the signal to maximize/restore a window + void minimizeWindow(); //send the signal to minimize a window (iconify) void triggerWindow(); //change b/w visible and invisible void winClicked(QAction*); void openActionMenu(); diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp index b551a795..ccad7531 100644 --- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp +++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp @@ -51,14 +51,14 @@ void LTaskManagerPlugin::UpdateButtons(){ //Window was closed - remove it if(WI.length()==1){ //Remove the entire button - qDebug() << "Window Closed: Remove 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() << "Window Closed: Remove from button:" << 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--; @@ -68,7 +68,7 @@ void LTaskManagerPlugin::UpdateButtons(){ 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 } @@ -85,7 +85,7 @@ void LTaskManagerPlugin::UpdateButtons(){ if(BUTTONS[b]->classname()== ctxt && usegroups){ //This adds a window to an existing group found = true; - qDebug() << "Add Window to Button:" << b; + //qDebug() << "Add Window to Button:" << b; BUTTONS[b]->addWindow(winlist[i]); break; } @@ -93,7 +93,7 @@ void LTaskManagerPlugin::UpdateButtons(){ 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, usegroups); but->addWindow( LWinInfo(winlist[i]) ); if(this->layout()->direction()==QBoxLayout::LeftToRight){ |