KDEUI
ksystemeventfilter.cpp
Go to the documentation of this file.
00001 00021 #include "ksystemeventfilter.h" 00022 00023 #include <QObject> 00024 #include <QWidget> 00025 #include <QWeakPointer> 00026 #include <QSet> 00027 #include <QAbstractEventDispatcher> 00028 #include <kglobal.h> 00029 00030 // Our global event-filter which will pass events to all registered 00031 // widget filters. 00032 bool _k_eventFilter(void *message); 00033 00037 class KEventHackWidget : public QWidget 00038 { 00039 public: 00040 #if defined(Q_WS_X11) 00041 bool publicX11Event(XEvent *e) 00042 { 00043 return x11Event(e); 00044 } 00045 #elif defined(Q_WS_MAC) 00046 bool publicMacEvent(EventHandlerCallRef caller, EventRef event) 00047 { 00048 return macEvent(caller, event); 00049 } 00050 #elif defined(Q_WS_WIN) 00051 bool publicWinEvent(MSG *message, long *result) 00052 { 00053 return winEvent(message, result); 00054 } 00055 #endif 00056 }; 00057 00058 class KSystemEventFilterPrivate : public QObject 00059 { 00060 Q_OBJECT 00061 00062 public Q_SLOTS: 00063 void filterWidgetDestroyed(QObject *widget) 00064 { 00065 KSystemEventFilter::removeEventFilter(qobject_cast<QWidget*>(widget)); 00066 } 00067 00068 public: 00069 KSystemEventFilterPrivate() 00070 { 00071 // install our event-filter. note that this will only happen when this 00072 // object is constructed (which is when the global static is first 00073 // accessed. 00074 m_nextFilter = QAbstractEventDispatcher::instance()->setEventFilter(_k_eventFilter); 00075 } 00076 00077 bool filterEvent(void *message); 00078 00079 // the installed event filters 00080 QList< QWeakPointer<QWidget> > m_filters; 00081 // if an event filter had already been previously installed, it is 00082 // stored here so we can call it if none of our event filters consumes 00083 // the event 00084 QAbstractEventDispatcher::EventFilter m_nextFilter; 00085 }; 00086 00087 K_GLOBAL_STATIC(KSystemEventFilterPrivate, kSystemEventFilter) 00088 00089 bool _k_eventFilter(void *message) 00090 { 00091 return kSystemEventFilter->filterEvent(message); 00092 } 00093 00094 bool KSystemEventFilterPrivate::filterEvent(void *message) 00095 { 00096 if (!m_filters.isEmpty()) { 00097 #if defined(Q_WS_X11) 00098 XEvent *xevt = static_cast<XEvent*>(message); 00099 // pass the event as long as it's not consumed 00100 Q_FOREACH (const QWeakPointer<QWidget> &wp, m_filters) { 00101 if (QWidget *w = wp.data()) { 00102 if (static_cast<KEventHackWidget*>(w)->publicX11Event(xevt)) { 00103 return true; 00104 } 00105 } 00106 } 00107 #elif defined(Q_WS_MAC) 00108 // FIXME: untested 00109 00110 /* NSEvent *nsevt = static_cast<NSEvent*>(message); 00111 // pass the event as long as it's not consumed 00112 Q_FOREACH (const QWeakPointer<QWidget> &wp, m_filters) { 00113 if (QWidget *w = wp.data()) { 00114 if (static_cast<KEventHackWidget*>(w)->publicMacEvent(0, nsevt->eventRef)) { 00115 return true; 00116 } 00117 } 00118 }*/ 00119 #elif defined(Q_WS_WIN) 00120 // FIXME: untested 00121 00122 /* MSG *msg = static_cast<MSG*>(message); 00123 long ret; // widget filter returns are discarded! 00124 // pass the event as long as it's not consumed 00125 Q_FOREACH (const QWeakPointer<QWidget> &wp, m_filters) { 00126 if (QWidget *w = wp.data()) { 00127 if (static_cast<KEventHackWidget*>(w)->publicWinEvent(msg, &ret)) { 00128 return true; 00129 } 00130 } 00131 }*/ 00132 #endif 00133 } 00134 00135 // call next filter if we have one 00136 if (m_nextFilter) { 00137 return m_nextFilter(message); 00138 } else { 00139 return false; 00140 } 00141 } 00142 00143 namespace KSystemEventFilter 00144 { 00145 00146 void installEventFilter(QWidget *filter) 00147 { 00148 kSystemEventFilter->m_filters.append(filter); 00149 kSystemEventFilter->connect(filter, SIGNAL(destroyed(QObject*)), 00150 SLOT(filterWidgetDestroyed(QObject*))); 00151 } 00152 00153 void removeEventFilter(const QWidget *filter) 00154 { 00155 QMutableListIterator< QWeakPointer<QWidget> > it(kSystemEventFilter->m_filters); 00156 while (it.hasNext()) { 00157 QWidget *w = it.next().data(); 00158 if (w == filter || w == 0) { 00159 it.remove(); 00160 } 00161 } 00162 } 00163 00164 } 00165 00166 #include "ksystemeventfilter.moc"
KDE 4.6 API Reference