aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <ken@pcbsd.org>2015-01-01 10:18:35 -0500
committerKen Moore <ken@pcbsd.org>2015-01-01 10:18:35 -0500
commit64c9ecca216ce03287908c510a7af3adff112832 (patch)
treeebfdb821a450121a8ebd9352b2c57ce0cdd3d0ef
parentMake sure that any argv[] -> QString translations from CLI input are run thro... (diff)
downloadlumina-64c9ecca216ce03287908c510a7af3adff112832.tar.gz
lumina-64c9ecca216ce03287908c510a7af3adff112832.tar.bz2
lumina-64c9ecca216ce03287908c510a7af3adff112832.zip
Large update of XLib -> XCB usage
1) Add ability for task manager to minimize/maximize window from details menu 2) Add quick check/movement of new windows to make sure they are not underneath any panels
-rw-r--r--libLumina/LuminaX11.cpp153
-rw-r--r--libLumina/LuminaX11.h9
-rw-r--r--lumina-desktop/LDesktop.cpp15
-rw-r--r--lumina-desktop/LDesktop.h5
-rw-r--r--lumina-desktop/LPanel.cpp7
-rw-r--r--lumina-desktop/LSession.cpp132
-rw-r--r--lumina-desktop/LSession.h12
-rw-r--r--lumina-desktop/LWinInfo.cpp23
-rw-r--r--lumina-desktop/LWinInfo.h4
-rw-r--r--lumina-desktop/LXcbEventFilter.h1
-rw-r--r--lumina-desktop/panel-plugins/LTBWidget.h1
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp46
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.h4
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp10
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){
bgstack15