/*************************************************************************** copyright (C) 2003 Adam Geitgey 2003 Sven Leiber 2000-2001 Matthias Ettrich 2000-2001 Matthias Elter 2001 Carsten Pfeiffer 2001 Martijn Klingens ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "systemtray.h" #include #include #include #include #include #include #include #include #include #include #include #include #include Systemtray::Systemtray(TQWidget* parent) : TQWidget(parent,0,0) { setBackgroundOrigin(ParentOrigin); setBackgroundMode(FixedPixmap); m_Wins.setAutoDelete(true); } Systemtray::~Systemtray() { m_Wins.clear(); } int Systemtray::getTraySize() { return (int) twin_module->systemTrayWindows().size(); } void Systemtray::updateBackgroundPixmap ( const TQPixmap & pixmap) { QXEmbed *emb; setPaletteBackgroundPixmap (pixmap); for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) { //Stupid stupid stupid work around for annoying bug //QXEmbed ignores setBackgroundOrigin(AncestorOrigin).... TQPixmap bug = TQPixmap(emb->size()); bitBlt(TQT_TQPAINTDEVICE(&bug), 0, 0, TQT_TQPAINTDEVICE(const_cast(&pixmap)), emb->parentWidget()->x()+emb->x(), emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),TQt::CopyROP, false); emb->setPaletteBackgroundPixmap (bug); } TQPoint topPoint = mapToGlobal(TQPoint(0,0)); Window hack = XCreateSimpleWindow(tqt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0); XRaiseWindow(tqt_xdisplay(), hack); XMapWindow(tqt_xdisplay(), hack); XUnmapWindow(tqt_xdisplay(), hack); XDestroyWindow(tqt_xdisplay(), hack); } void Systemtray::initSystray( void ) { bool existing = false; //bool content = false; Display *display = tqt_xdisplay(); no_of_systray_windows = 0; twin_module = new KWinModule(); systemTrayWindows = twin_module->systemTrayWindows(); TQValueList::ConstIterator end(systemTrayWindows.end()); for (TQValueList::ConstIterator it = systemTrayWindows.begin(); it!=end; ++it) { no_of_systray_windows++; QXEmbed *emb; emb = new QXEmbed(this); emb->setBackgroundMode(FixedPixmap); emb->setAutoDelete(false); connect(emb, TQT_SIGNAL(embeddedWindowDestroyed()), TQT_SLOT(updateTrayWindows())); m_Wins.append(emb); emb->embed(*it); emb->resize(24, 24); emb->show(); existing = true; } updateTrayWindows(); connect(twin_module, TQT_SIGNAL(systemTrayWindowAdded(WId)), TQT_SLOT(systemTrayWindowAdded(WId))); connect(twin_module, TQT_SIGNAL(systemTrayWindowRemoved(WId)), TQT_SLOT(systemTrayWindowRemoved(WId))); TQCString screenstr; screenstr.setNum(tqt_xscreen()); TQCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr; net_system_tray_selection = XInternAtom( display, trayatom, false ); net_system_tray_opcode = XInternAtom( display, "_NET_SYSTEM_TRAY_OPCODE", false ); // Acquire system tray XSetSelectionOwner( display, net_system_tray_selection, winId(), CurrentTime ); WId root = tqt_xrootwin(); if (XGetSelectionOwner(display, net_system_tray_selection) == winId()) { XClientMessageEvent xev; xev.type = ClientMessage; xev.window = root; xev.message_type = XInternAtom(display, "MANAGER", false); xev.format = 32; xev.data.l[0] = CurrentTime; xev.data.l[1] = net_system_tray_selection; xev.data.l[2] = winId(); xev.data.l[3] = 0; /* Manager specific data */ xev.data.l[4] = 0; /* Manager specific data */ XSendEvent( display, root, false, StructureNotifyMask, (XEvent *)&xev ); } } void Systemtray::updateTrayWindows( void ) { QXEmbed *emb; emb = m_Wins.first(); while ((emb = m_Wins.current()) != 0L) { WId wid = emb->embeddedWinId(); if ((wid == 0) || !twin_module->systemTrayWindows().contains(wid) ) m_Wins.remove(emb); else m_Wins.next(); } layoutSystray(); } void Systemtray::layoutSystray() { int i = 0, a = 0; QXEmbed* emb; int x = 0; int count = 0; //How many systray icons can fit on a line? int aa = width() / 24; if(aa < 1) { /* The place is to small to display a icon we make than one line with icons that we display at the top */ aa = 1; } for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) { x = 2+i*24; emb->move(a*24, x); a++; if(a+1 > aa) { a = 0; i++; } count++; emb->repaint(); } } void Systemtray::systemTrayWindowAdded( WId w ) { //bool content = false; QXEmbed *emb; no_of_systray_windows++; emit updated(); emb = new QXEmbed(this); emb->setAutoDelete(false); //emb->setBackgroundMode(X11ParentRelative); emb->setBackgroundMode(FixedPixmap); connect(emb, TQT_SIGNAL(embeddedWindowDestroyed()), TQT_SLOT(updateTrayWindows())); m_Wins.append(emb); emb->embed(w); emb->resize(24, 24); emb->show(); layoutSystray(); } void Systemtray::systemTrayWindowRemoved(WId) { no_of_systray_windows--; emit updated(); updateTrayWindows(); } int Systemtray::getCurrentWindowCount() { return no_of_systray_windows; } #include "systemtray.moc"