aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop
diff options
context:
space:
mode:
authorKen Moore <ken@pcbsd.org>2015-01-05 14:31:43 -0500
committerKen Moore <ken@pcbsd.org>2015-01-05 14:31:43 -0500
commitebd5faf993fd3ea8f6e929df6f3288cfa1d4b752 (patch)
treeb6fd32a17f6a138c804884bf2cde0dde8ab09aa8 /lumina-desktop
parentQuick checkpoint of additional XCB improvements/fixes. Still having an issue ... (diff)
downloadlumina-ebd5faf993fd3ea8f6e929df6f3288cfa1d4b752.tar.gz
lumina-ebd5faf993fd3ea8f6e929df6f3288cfa1d4b752.tar.bz2
lumina-ebd5faf993fd3ea8f6e929df6f3288cfa1d4b752.zip
Clean up the Panel/Taskmanager XCB usage quite a bit. Now the panel is "seen" by fluxbox when a window is maximized, and the task manager works with the highly asynchronous XCB events.
Diffstat (limited to 'lumina-desktop')
-rw-r--r--lumina-desktop/LPanel.cpp25
-rw-r--r--lumina-desktop/LSession.cpp3
-rw-r--r--lumina-desktop/LWinInfo.cpp9
-rw-r--r--lumina-desktop/LWinInfo.h4
-rw-r--r--lumina-desktop/LXcbEventFilter.cpp32
-rw-r--r--lumina-desktop/LXcbEventFilter.h2
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp48
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.h2
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp6
9 files changed, 81 insertions, 50 deletions
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
bgstack15