1 //=========================================== 2 // Lumina-DE source code 3 // Copyright (c) 2012, Ken Moore 4 // Available under the 3-clause BSD license 5 // See the LICENSE file for full details 6 //=========================================== 7 #include "LXcbEventFilter.h" 8 9 //For all the XCB interactions and atoms 10 // is accessed via 11 // session->XCB->EWMH.(atom name) 12 // session->XCB->(do something) 13 #include <LuminaX11.h> 14 #include <QDebug> 15 XCBEventFilter(LSession * sessionhandle)16XCBEventFilter::XCBEventFilter(LSession *sessionhandle) : QAbstractNativeEventFilter(){ 17 session = sessionhandle; //save this for interaction with the session later 18 TrayDmgFlag = 0; 19 stopping = false; 20 session->XCB->SelectInput(QX11Info::appRootWindow()); //make sure we get root window events 21 InitAtoms(); 22 } 23 setTrayDamageFlag(int flag)24void XCBEventFilter::setTrayDamageFlag(int flag){ 25 //Special flag for system tray damage events 26 TrayDmgFlag = flag + XCB_DAMAGE_NOTIFY; //save the whole flag (no calculations later) 27 } 28 29 //This function format taken directly from the Qt5.3 documentation nativeEventFilter(const QByteArray & eventType,void * message,long *)30bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *){ 31 if(stopping){ return false; } //don't do any parsing 32 //qDebug() << "New Event"; 33 if(eventType=="xcb_generic_event_t"){ 34 //qDebug() << " - XCB event"; 35 //Convert to known event type (for X11 systems) 36 xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); 37 //Now parse the event and emit signals as necessary 38 switch( ev->response_type & ~0x80){ 39 //============================== 40 case XCB_PROPERTY_NOTIFY: 41 //qDebug() << "Property Notify Event:"; 42 //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); 43 //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; 44 //System-specific property change 45 if( ((xcb_property_notify_event_t*)ev)->window == QX11Info::appRootWindow() \ 46 && ( ( ((xcb_property_notify_event_t*)ev)->atom == session->XCB->EWMH._NET_DESKTOP_GEOMETRY) \ 47 || (((xcb_property_notify_event_t*)ev)->atom == session->XCB->EWMH._NET_WORKAREA) )){ 48 session->RootSizeChange(); 49 }else if( ((xcb_property_notify_event_t*)ev)->window == QX11Info::appRootWindow() \ 50 && ( ( ((xcb_property_notify_event_t*)ev)->atom == session->XCB->EWMH._NET_CURRENT_DESKTOP) )){ 51 //qDebug() << "Got Workspace Change"; 52 session->emit WorkspaceChanged(); 53 session->WindowPropertyEvent(); //make sure we update the lists again - some windows are now hidden 54 }else if( SysNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ 55 //Update the status/list of all running windows 56 session->WindowPropertyEvent(); 57 58 //window-specific property change 59 }else if( WinNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ 60 //Ping only that window 61 //session->WindowPropertyEvent( ((xcb_property_notify_event_t*)ev)->window ); 62 session->WindowPropertyEvent(); 63 } 64 break; 65 //============================== 66 case XCB_CLIENT_MESSAGE: 67 //qDebug() << "Client Message Event"; 68 //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); 69 //qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; 70 if( TrayDmgFlag!=0 && ((xcb_client_message_event_t*)ev)->type == _NET_SYSTEM_TRAY_OPCODE && ((xcb_client_message_event_t*)ev)->format == 32){ 71 //data32[0] is timestamp, [1] is opcode, [2] is window handle 72 if(SYSTEM_TRAY_REQUEST_DOCK == ((xcb_client_message_event_t*)ev)->data.data32[1]){ 73 session->SysTrayDockRequest( ((xcb_client_message_event_t*)ev)->data.data32[2] ); 74 } 75 //Ignore the System Tray messages at the moment (let the WM handle it) 76 77 //window-specific property changes 78 /*}else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){ 79 if( session->XCB->WindowIsMaximized( ((xcb_client_message_event_t*)ev)->window ) ){ 80 //Quick fix for maximized windows (since Fluxbox is not doing the STRUT detection properly) 81 session->adjustWindowGeom( ((xcb_client_message_event_t*)ev)->window ); 82 } 83 session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window );*/ 84 }else if( WinNotifyAtoms.contains( ((xcb_client_message_event_t*)ev)->type ) ){ 85 //Ping only that window 86 //session->WindowPropertyEvent( ((xcb_client_message_event_t*)ev)->window ); 87 session->WindowPropertyEvent(); 88 } 89 break; 90 //============================== 91 case XCB_DESTROY_NOTIFY: 92 //qDebug() << "Window Closed Event"; 93 session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window ); 94 break; 95 //============================== 96 case XCB_CONFIGURE_NOTIFY: 97 //qDebug() << "Configure Notify Event"; 98 session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window ); 99 break; 100 //============================== 101 case XCB_SELECTION_CLEAR: 102 //qDebug() << "Selection Clear Event"; 103 session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); 104 break; 105 //============================== 106 default: 107 if(TrayDmgFlag!=0){ 108 //if( (ev->response_type & ~0x80)==TrayDmgFlag){ 109 session->WindowDamageEvent( ((xcb_damage_notify_event_t*)ev)->drawable ); 110 //} 111 }/*else{ 112 qDebug() << "Default Event:" << (ev->response_type & ~0x80); 113 }*/ 114 //============================== 115 } 116 } 117 //qDebug() << " - finished event"; 118 return false; //make sure the handling keeps going (transparent watching of events) 119 } 120