aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop
diff options
context:
space:
mode:
Diffstat (limited to 'lumina-desktop')
-rw-r--r--lumina-desktop/LSession.cpp23
-rw-r--r--lumina-desktop/LSession.h7
-rw-r--r--lumina-desktop/LXcbEventFilter.cpp109
-rw-r--r--lumina-desktop/LXcbEventFilter.h122
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp17
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.h6
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp23
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h1
8 files changed, 195 insertions, 113 deletions
diff --git a/lumina-desktop/LSession.cpp b/lumina-desktop/LSession.cpp
index 2db26647..398f2a5c 100644
--- a/lumina-desktop/LSession.cpp
+++ b/lumina-desktop/LSession.cpp
@@ -28,7 +28,7 @@ XCBEventFilter *evFilter = 0;
LSession::LSession(int &argc, char ** argv) : QApplication(argc, argv){
this->setApplicationName("Lumina Desktop Environment");
- this->setApplicationVersion("0.7.2");
+ this->setApplicationVersion("0.8.0");
this->setOrganizationName("LuminaDesktopEnvironment");
this->setQuitOnLastWindowClosed(false); //since the LDesktop's are not necessarily "window"s
//Enabled a few of the simple effects by default
@@ -39,7 +39,7 @@ LSession::LSession(int &argc, char ** argv) : QApplication(argc, argv){
SystemTrayID = 0; VisualTrayID = 0;
TrayDmgEvent = 0;
TrayDmgError = 0;
- XCB = 0;
+ XCB = new LXCB(); //need access to XCB data/functions right away
//initialize the empty internal pointers to 0
appmenu = 0;
settingsmenu = 0;
@@ -70,8 +70,6 @@ void LSession::setupSession(){
qDebug() << "Initializing Session";
QTime* timer = 0;
if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();}
- //Initialize the XCB interface backend
- XCB = new LXCB();
//Seed random number generator (if needed)
qsrand( QTime::currentTime().msec() );
//Setup the QSettings default paths
@@ -276,7 +274,7 @@ void LSession::registerDesktopWindows(){
XCB->RegisterVirtualRoots(wins);
}
-void LSession::adjustWindowGeom(WId win){
+void LSession::adjustWindowGeom(WId win, bool maximize){
//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
@@ -293,7 +291,12 @@ void LSession::adjustWindowGeom(WId win){
}
}
//Adjust the window location if necessary
- if(!desk.contains(geom) ){
+ if(maximize){
+ geom = desk; //Use the full screen
+ XCB->MoveResizeWindow(win, geom);
+ XCB->MaximizeWindow(win, true); //directly set the appropriate "maximized" flags (bypassing WM)
+
+ }else 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();
@@ -387,6 +390,14 @@ void LSession::WindowPropertyEvent(){
emit WindowListEvent();
}
+void LSession::WindowPropertyEvent(WId win){
+ //Emit the single-app signal if the window in question is one used by the task manager
+ if(RunningApps.contains(win)){
+ if(DEBUG){ qDebug() << "Single-window property event"; }
+ emit WindowListEvent(win);
+ }
+}
+
void LSession::SysTrayDockRequest(WId win){
attachTrayWindow(win); //Check to see if the window is already registered
}
diff --git a/lumina-desktop/LSession.h b/lumina-desktop/LSession.h
index cc918407..6dd99b55 100644
--- a/lumina-desktop/LSession.h
+++ b/lumina-desktop/LSession.h
@@ -60,6 +60,7 @@ public:
//Special functions for XCB event filter parsing only
// (DO NOT USE MANUALLY)
void WindowPropertyEvent();
+ void WindowPropertyEvent(WId);
void SysTrayDockRequest(WId);
void WindowClosedEvent(WId);
void WindowConfigureEvent(WId);
@@ -83,7 +84,9 @@ public:
//Play System Audio
void playAudioFile(QString filepath);
-
+ //Window Adjustment Routine (due to Fluxbox not respecting _NET_WM_STRUT)
+ void adjustWindowGeom(WId win, bool maximize = false);
+
private:
WMProcess *WM;
QList<LDesktop*> DESKTOPS;
@@ -124,7 +127,7 @@ private slots:
void refreshWindowManager();
void updateDesktops();
void registerDesktopWindows();
- void adjustWindowGeom(WId win);
+
void SessionEnding();
diff --git a/lumina-desktop/LXcbEventFilter.cpp b/lumina-desktop/LXcbEventFilter.cpp
new file mode 100644
index 00000000..eb56cb89
--- /dev/null
+++ b/lumina-desktop/LXcbEventFilter.cpp
@@ -0,0 +1,109 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2012, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "LXcbEventFilter.h"
+
+//For all the XCB interactions and atoms
+// is accessed via
+// session->XCB->EWMH.(atom name)
+// session->XCB->(do something)
+#include <LuminaX11.h>
+#include <QDebug>
+
+XCBEventFilter::XCBEventFilter(LSession *sessionhandle) : QAbstractNativeEventFilter(){
+ session = sessionhandle; //save this for interaction with the session later
+ TrayDmgFlag = 0;
+ InitAtoms();
+}
+
+void XCBEventFilter::setTrayDamageFlag(int flag){
+ //Special flag for system tray damage events
+ TrayDmgFlag = flag + XCB_DAMAGE_NOTIFY; //save the whole flag (no calculations later)
+}
+
+//This function format taken directly from the Qt5.3 documentation
+bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
+{
+ //qDebug() << "New Event";
+ if(eventType=="xcb_generic_event_t"){
+ //Convert to known event type (for X11 systems)
+ xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
+ //Now parse the event and emit signals as necessary
+ 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
+ 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 );
+ }
+ break;
+//==============================
+ case XCB_CLIENT_MESSAGE:
+ 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]){
+ session->SysTrayDockRequest( ((xcb_client_message_event_t*)ev)->data.data32[2] );
+ }
+ //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 ){
+ 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 );
+ }else if( WinNotifyAtoms.contains( ((xcb_client_message_event_t*)ev)->type ) ){
+ //Ping only that window
+ session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window );
+ }
+ break;
+//==============================
+ case XCB_DESTROY_NOTIFY:
+ qDebug() << "Window Closed Event";
+ session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window );
+ break;
+//==============================
+ case XCB_CONFIGURE_NOTIFY:
+ qDebug() << "Configure Notify Event";
+ session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window );
+ break;
+//==============================
+ case XCB_SELECTION_CLEAR:
+ qDebug() << "Selection Clear Event";
+ session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner );
+ break;
+//==============================
+ default:
+ if( (ev->response_type & ~0x80)==TrayDmgFlag){
+ session->WindowDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable );
+ }/*else{
+ qDebug() << "Default Event:" << (ev->response_type & ~0x80);
+ }*/
+//==============================
+ }
+ }
+ //qDebug() << " - finished event";
+ return false; //make sure the handling keeps going (transparent watching of events)
+}
diff --git a/lumina-desktop/LXcbEventFilter.h b/lumina-desktop/LXcbEventFilter.h
index 806e6013..cdbed042 100644
--- a/lumina-desktop/LXcbEventFilter.h
+++ b/lumina-desktop/LXcbEventFilter.h
@@ -12,7 +12,8 @@
#include <QAbstractNativeEventFilter>
#include <QList>
#include <QStringList>
-#include <QDebug>
+#include <QX11Info>
+
#include <xcb/xcb.h>
#include <xcb/xproto.h>
#include <xcb/damage.h>
@@ -57,103 +58,44 @@ XCB_CLIENT_MESSAGE
class XCBEventFilter : public QAbstractNativeEventFilter{
private:
LSession *session;
- QList<xcb_atom_t> atoms;
xcb_atom_t _NET_SYSTEM_TRAY_OPCODE;
+ QList<xcb_atom_t> WinNotifyAtoms, SysNotifyAtoms;
int TrayDmgFlag; //internal damage event offset value for the system tray
-
- void checkClientMessage(xcb_client_message_event_t* event){
- if(event->type == _NET_SYSTEM_TRAY_OPCODE && event->format == 32){
- //data32[0] is timestamp, [1] is opcode, [2] is window handle
- uint32_t opcode = event->data.data32[1];
- if(opcode==SYSTEM_TRAY_REQUEST_DOCK){
- session->SysTrayDockRequest(event->data.data32[2]);
- }
- //Ignore the System Tray messages at the moment (let the WM handle it)
- }
- }
void InitAtoms(){
- atoms.clear();
- QStringList names;
- //List all the atoms that we want to detect for proprty changes
- names << "_NET_CLIENT_LIST" << "_NET_ACTIVE_WINDOW" << "_NET_WM_NAME" << "_NET_WM_VISIBLE_NAME" \
- << "_NET_WM_ICON_NAME" << "_NET_WM_VISIBLE_ICON_NAME" << "_NET_WM_STATE";
-
- xcb_connection_t *c = xcb_connect (NULL, NULL);
- xcb_intern_atom_cookie_t *cs = (xcb_intern_atom_cookie_t *) malloc (names.length() * sizeof(xcb_intern_atom_cookie_t));
- for(int i = 0; i < names.length(); ++i)
- cs[i] = xcb_intern_atom (c, 0, names[i].length(), names[i].toStdString().c_str());
-
- for(int i = 0; i < names.length(); ++i) {
- xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(c, cs[i], 0);
- if(r){ atoms << r->atom; }
- free(r);
- }
- //Also need the _net_system_tray_opcode atom as well
- xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, 0, 23,"_NET_SYSTEM_TRAY_OPCODE");
- xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(c, cookie, 0);
- if(r){ _NET_SYSTEM_TRAY_OPCODE = r->atom; }
- free(r);
+ //Initialize any special atoms that we need to save/use regularly
+ //NOTE: All the EWMH atoms are already saved in session->XCB->EWMH
+ WinNotifyAtoms.clear();
+ WinNotifyAtoms << session->XCB->EWMH._NET_WM_NAME \
+ << session->XCB->EWMH._NET_WM_VISIBLE_NAME \
+ << session->XCB->EWMH._NET_WM_ICON_NAME \
+ << session->XCB->EWMH._NET_WM_VISIBLE_ICON_NAME \
+ << session->XCB->EWMH._NET_WM_ICON \
+ << session->XCB->EWMH._NET_WM_ICON_GEOMETRY;
+
+ SysNotifyAtoms.clear();
+ 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_WM_ICON \
+ << session->XCB->EWMH._NET_WM_ICON_GEOMETRY;
+ //_NET_SYSTEM_TRAY_OPCODE
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), 0, 23,"_NET_SYSTEM_TRAY_OPCODE");
+ xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(QX11Info::connection(), cookie, NULL);
+ if(r){
+ _NET_SYSTEM_TRAY_OPCODE = r->atom;
+ free(r);
+ }
}
public:
- XCBEventFilter(LSession *sessionhandle = 0) : QAbstractNativeEventFilter(){
- session = sessionhandle; //save this for interaction with the session later
- TrayDmgFlag = 0;
- InitAtoms();
- }
- void setTrayDamageFlag(int flag){
- //Special flag for system tray damage events
- TrayDmgFlag = flag + XCB_DAMAGE_NOTIFY; //save the whole flag (no calculations later)
- }
+ XCBEventFilter(LSession *sessionhandle);
+ void setTrayDamageFlag(int flag);
+
//This function format taken directly from the Qt5.3 documentation
- virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
- {
- //qDebug() << "New Event";
- if(eventType=="xcb_generic_event_t"){
- //Convert to known event type (for X11 systems)
- xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
- //Now parse the event and emit signals as necessary
- switch( ev->response_type & ~0x80){
- case XCB_PROPERTY_NOTIFY:
- //qDebug() << "Property Notify Event:";
- if( atoms.contains( ((xcb_property_notify_event_t*)ev)->atom) ){
- qDebug() << " - launch session property event";
- session->WindowPropertyEvent();
- }
- break;
-
- case XCB_CLIENT_MESSAGE:
- qDebug() << "Client Message Event";
- checkClientMessage( (xcb_client_message_event_t*)ev );
- break;
-
- case XCB_DESTROY_NOTIFY:
- qDebug() << "Window Closed Event";
- session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window );
- break;
-
- case XCB_CONFIGURE_NOTIFY:
- qDebug() << "Configure Notify Event";
- session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window );
- break;
-
- case XCB_SELECTION_CLEAR:
- qDebug() << "Selection Clear Event";
- session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner );
- break;
-
- default:
- if( (ev->response_type & ~0x80)==TrayDmgFlag){
- session->WindowDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable );
- }/*else{
- qDebug() << "Default Event:" << (ev->response_type & ~0x80);
- }*/
- }
- }
- //qDebug() << " - finished event";
- return false; //make sure the handling keeps going (transparent watching of events)
- }
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
};
diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
index 79981754..53ab3a09 100644
--- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
+++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
@@ -33,22 +33,26 @@ LTaskButton::~LTaskButton(){
//===========
// PUBLIC
//===========
-QList<LWinInfo> LTaskButton::windows(){
- return WINLIST;
+QList<WId> LTaskButton::windows(){
+ QList<WId> list;
+ for(int i=0; i<WINLIST.length(); i++){
+ list << WINLIST[i].windowID();
+ }
+ return list;
}
QString LTaskButton::classname(){
return cname;
}
-void LTaskButton::addWindow(LWinInfo win){
- WINLIST << win;
+void LTaskButton::addWindow(WId win){
+ WINLIST << LWinInfo(win);
UpdateButton();
}
-void LTaskButton::rmWindow(LWinInfo win){
+void LTaskButton::rmWindow(WId win){
for(int i=0; i<WINLIST.length(); i++){
- if(WINLIST[i].windowID() == win.windowID()){
+ if(WINLIST[i].windowID() == win){
WINLIST.removeAt(i);
break;
}
@@ -158,6 +162,7 @@ void LTaskButton::maximizeWindow(){
if(winMenu->isVisible()){ winMenu->hide(); }
LWinInfo win = currentWindow();
LSession::handle()->XCB->MaximizeWindow(win.windowID());
+ //LSession::handle()->adjustWindowGeom(win.windowID(), true); //run this for now until the WM works properly
cWin = LWinInfo(); //clear the current
}
diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
index 3202d676..8ee60b01 100644
--- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
+++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.h
@@ -31,12 +31,12 @@ public:
~LTaskButton();
//Window Information
- QList<LWinInfo> windows();
+ QList<WId> windows();
QString classname();
//Window Management
- void addWindow(LWinInfo win); //Add a window to this button
- void rmWindow(LWinInfo win); //Remove a window from this button
+ void addWindow(WId win); //Add a window to this button
+ void rmWindow(WId win); //Remove a window from this button
private:
QList<LWinInfo> WINLIST;
diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp
index ccad7531..67378c68 100644
--- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp
+++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp
@@ -14,7 +14,8 @@ LTaskManagerPlugin::LTaskManagerPlugin(QWidget *parent, QString id, bool horizon
connect(timer, SIGNAL(timeout()), this, SLOT(UpdateButtons()) );
usegroups = true; //backwards-compatible default value
if(id.contains("-nogroups")){ usegroups = false; }
- connect(LSession::instance(), SIGNAL(WindowListEvent()), this, SLOT(checkWindows()) );
+ connect(LSession::handle(), SIGNAL(WindowListEvent()), this, SLOT(checkWindows()) );
+ connect(LSession::handle(), SIGNAL(WindowListEvent(WId)), this, SLOT(UpdateButton(WId)) );
this->layout()->setContentsMargins(0,0,0,0);
QTimer::singleShot(0,this, SLOT(UpdateButtons()) ); //perform an initial sync
//QTimer::singleShot(100,this, SLOT(OrientationChange()) ); //perform an initial sync
@@ -38,15 +39,15 @@ void LTaskManagerPlugin::UpdateButtons(){
//Now go through all the current buttons first
for(int i=0; i<BUTTONS.length(); i++){
//Get the windows managed in this button
- QList<LWinInfo> WI = BUTTONS[i]->windows();
+ QList<WId> WI = BUTTONS[i]->windows();
bool updated=false;
if(updating > ctime){ return; } //another thread kicked off already - stop this one
//Loop over all the windows for this button
for(int w=0; w<WI.length(); w++){
if(updating > ctime){ return; } //another thread kicked off already - stop this one
- if( winlist.contains( WI[w].windowID() ) ){
+ if( winlist.contains( WI[w] ) ){
//Still current window - update it later
- winlist.removeAll(WI[w].windowID()); //remove this window from the list since it is done
+ winlist.removeAll(WI[w] ); //remove this window from the list since it is done
}else{
//Window was closed - remove it
if(WI.length()==1){
@@ -95,7 +96,7 @@ void LTaskManagerPlugin::UpdateButtons(){
//No group, create a new button
//qDebug() << "New Button";
LTaskButton *but = new LTaskButton(this, usegroups);
- but->addWindow( LWinInfo(winlist[i]) );
+ but->addWindow( winlist[i] );
if(this->layout()->direction()==QBoxLayout::LeftToRight){
but->setIconSize(QSize(this->height(), this->height()));
}else{
@@ -107,6 +108,16 @@ void LTaskManagerPlugin::UpdateButtons(){
}
}
+void LTaskManagerPlugin::UpdateButton(WId win){
+ for(int i=0; i<BUTTONS.length(); i++){
+ if(BUTTONS[i]->windows().contains(win)){
+ qDebug() << "Update Task Manager Button (single window ping)";
+ QTimer::singleShot(0,BUTTONS[i], SLOT(UpdateButton()) );
+ break;
+ }
+ }
+}
+
void LTaskManagerPlugin::checkWindows(){
timer->start();
-} \ No newline at end of file
+}
diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h
index 6aebcb17..e6371f34 100644
--- a/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h
+++ b/lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h
@@ -38,6 +38,7 @@ private:
private slots:
void UpdateButtons();
+ void UpdateButton(WId win);
void checkWindows();
public slots:
bgstack15