00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "systemtray.h"
00020
00021
00022 #include <qobject.h>
00023 #include <kiconloader.h>
00024 #include <klocale.h>
00025 #include <kwinmodule.h>
00026 #include <kmessagebox.h>
00027 #include <kdebug.h>
00028 #include <kwin.h>
00029
00030 #include <qpopupmenu.h>
00031 #include <qdragobject.h>
00032 #include <qlayout.h>
00033 #include <qstringlist.h>
00034 #include <qpixmap.h>
00035
00036 #include <X11/Xlib.h>
00037
00038 Systemtray::Systemtray(QWidget* parent)
00039 : QWidget(parent,0,0)
00040 {
00041 setBackgroundOrigin(ParentOrigin);
00042 setBackgroundMode(FixedPixmap);
00043 m_Wins.setAutoDelete(true);
00044 }
00045
00046
00047 Systemtray::~Systemtray()
00048 {
00049 m_Wins.clear();
00050 }
00051
00052 int Systemtray::getTraySize() {
00053
00054 return (int) kwin_module->systemTrayWindows().size();
00055 }
00056
00057 void Systemtray::updateBackgroundPixmap ( const QPixmap & pixmap) {
00058 QXEmbed *emb;
00059 setPaletteBackgroundPixmap (pixmap);
00060 for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
00061
00062
00063
00064 QPixmap bug = QPixmap(emb->size());
00065 bitBlt(&bug, 0, 0, &pixmap, emb->parentWidget()->x()+emb->x(), emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),Qt::CopyROP, false);
00066 emb->setPaletteBackgroundPixmap (bug);
00067
00068 }
00069
00070 QPoint topPoint = mapToGlobal(QPoint(0,0));
00071 Window hack = XCreateSimpleWindow(qt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0);
00072 XRaiseWindow(qt_xdisplay(), hack);
00073 XMapWindow(qt_xdisplay(), hack);
00074 XUnmapWindow(qt_xdisplay(), hack);
00075 XDestroyWindow(qt_xdisplay(), hack);
00076 }
00077
00078 void Systemtray::initSystray( void )
00079 {
00080 bool existing = false;
00081
00082 Display *display = qt_xdisplay();
00083 no_of_systray_windows = 0;
00084
00085 kwin_module = new KWinModule();
00086 systemTrayWindows = kwin_module->systemTrayWindows();
00087 QValueList<WId>::ConstIterator end(systemTrayWindows.end());
00088 for (QValueList<WId>::ConstIterator it = systemTrayWindows.begin(); it!=end; ++it)
00089 {
00090 no_of_systray_windows++;
00091 QXEmbed *emb;
00092
00093 emb = new QXEmbed(this);
00094 emb->setBackgroundMode(FixedPixmap);
00095
00096 emb->setAutoDelete(false);
00097
00098 connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
00099
00100 m_Wins.append(emb);
00101
00102 emb->embed(*it);
00103 emb->resize(24, 24);
00104 emb->show();
00105 existing = true;
00106 }
00107
00108 updateTrayWindows();
00109
00110 connect(kwin_module, SIGNAL(systemTrayWindowAdded(WId)), SLOT(systemTrayWindowAdded(WId)));
00111 connect(kwin_module, SIGNAL(systemTrayWindowRemoved(WId)), SLOT(systemTrayWindowRemoved(WId)));
00112
00113 QCString screenstr;
00114 screenstr.setNum(qt_xscreen());
00115 QCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr;
00116
00117 net_system_tray_selection = XInternAtom( display, trayatom, false );
00118 net_system_tray_opcode = XInternAtom( display, "_NET_SYSTEM_TRAY_OPCODE", false );
00119
00120
00121 XSetSelectionOwner( display,
00122 net_system_tray_selection,
00123 winId(),
00124 CurrentTime );
00125
00126 WId root = qt_xrootwin();
00127
00128 if (XGetSelectionOwner(display, net_system_tray_selection) == winId())
00129 {
00130 XClientMessageEvent xev;
00131
00132 xev.type = ClientMessage;
00133 xev.window = root;
00134
00135 xev.message_type = XInternAtom(display, "MANAGER", false);
00136 xev.format = 32;
00137
00138 xev.data.l[0] = CurrentTime;
00139 xev.data.l[1] = net_system_tray_selection;
00140 xev.data.l[2] = winId();
00141 xev.data.l[3] = 0;
00142 xev.data.l[4] = 0;
00143
00144 XSendEvent( display, root, false, StructureNotifyMask, (XEvent *)&xev );
00145 }
00146 }
00147
00148 void Systemtray::updateTrayWindows( void )
00149 {
00150 QXEmbed *emb;
00151
00152 emb = m_Wins.first();
00153 while ((emb = m_Wins.current()) != 0L)
00154 {
00155 WId wid = emb->embeddedWinId();
00156 if ((wid == 0) || !kwin_module->systemTrayWindows().contains(wid) )
00157 m_Wins.remove(emb);
00158 else
00159 m_Wins.next();
00160 }
00161 layoutSystray();
00162 }
00163 void Systemtray::layoutSystray()
00164 {
00165 int i = 0, a = 0;
00166
00167 QXEmbed* emb;
00168 int x = 0;
00169 int count = 0;
00170
00171
00172 int aa = width() / 24;
00173
00174 if(aa < 1)
00175 {
00176
00177
00178 aa = 1;
00179 }
00180
00181 for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
00182 x = 2+i*24;
00183
00184 emb->move(a*24, x);
00185 a++;
00186
00187 if(a+1 > aa) {
00188 a = 0;
00189 i++;
00190 }
00191
00192 count++;
00193 emb->repaint();
00194 }
00195 }
00196
00197 void Systemtray::systemTrayWindowAdded( WId w )
00198 {
00199
00200 QXEmbed *emb;
00201 no_of_systray_windows++;
00202 emit updated();
00203
00204 emb = new QXEmbed(this);
00205
00206 emb->setAutoDelete(false);
00207
00208 emb->setBackgroundMode(FixedPixmap);
00209 connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
00210 m_Wins.append(emb);
00211
00212 emb->embed(w);
00213 emb->resize(24, 24);
00214 emb->show();
00215
00216 layoutSystray();
00217 }
00218
00219 void Systemtray::systemTrayWindowRemoved(WId)
00220 {
00221 no_of_systray_windows--;
00222 emit updated();
00223 updateTrayWindows();
00224 }
00225
00226 int Systemtray::getCurrentWindowCount()
00227 {
00228 return no_of_systray_windows;
00229 }
00230
00231 #include "systemtray.moc"