diff options
author | Ken Moore <ken@pcbsd.org> | 2015-01-05 07:54:31 -0500 |
---|---|---|
committer | Ken Moore <ken@pcbsd.org> | 2015-01-05 07:54:31 -0500 |
commit | 3004b0d22caf1985d5e9b60c7647293f10f5690a (patch) | |
tree | 9546d3788cd894cc40ced6575ab07d549a5750ff /lumina-desktop | |
parent | Add support for the LIBPREFIX qmake variable for all the project files. This ... (diff) | |
download | lumina-3004b0d22caf1985d5e9b60c7647293f10f5690a.tar.gz lumina-3004b0d22caf1985d5e9b60c7647293f10f5690a.tar.bz2 lumina-3004b0d22caf1985d5e9b60c7647293f10f5690a.zip |
Quick checkpoint of additional XCB improvements/fixes. Still having an issue with fluxbox maximizing windows underneath panels at the moment.
Diffstat (limited to 'lumina-desktop')
-rw-r--r-- | lumina-desktop/LSession.cpp | 23 | ||||
-rw-r--r-- | lumina-desktop/LSession.h | 7 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.cpp | 109 | ||||
-rw-r--r-- | lumina-desktop/LXcbEventFilter.h | 122 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp | 17 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskButton.h | 6 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.cpp | 23 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/taskmanager/LTaskManagerPlugin.h | 1 |
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: |