summaryrefslogtreecommitdiffstats
path: root/superkaramba/src/systemtray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'superkaramba/src/systemtray.cpp')
-rw-r--r--superkaramba/src/systemtray.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/superkaramba/src/systemtray.cpp b/superkaramba/src/systemtray.cpp
new file mode 100644
index 0000000..312fe59
--- /dev/null
+++ b/superkaramba/src/systemtray.cpp
@@ -0,0 +1,231 @@
+/***************************************************************************
+ copyright (C) 2003 Adam Geitgey <adam@rootnode.org>
+ 2003 Sven Leiber <s.leiber@web.de>
+ 2000-2001 Matthias Ettrich <ettrich@kde.org>
+ 2000-2001 Matthias Elter <elter@kde.org>
+ 2001 Carsten Pfeiffer <pfeiffer@kde.org>
+ 2001 Martijn Klingens <mklingens@yahoo.com>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qobject.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kwinmodule.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kwin.h>
+
+#include <qpopupmenu.h>
+#include <qdragobject.h>
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+
+#include <X11/Xlib.h>
+
+Systemtray::Systemtray(QWidget* parent)
+ : QWidget(parent,0,0)
+{
+ setBackgroundOrigin(ParentOrigin);
+ setBackgroundMode(FixedPixmap);
+ m_Wins.setAutoDelete(true);
+}
+
+
+Systemtray::~Systemtray()
+{
+ m_Wins.clear();
+}
+
+int Systemtray::getTraySize() {
+
+ return (int) kwin_module->systemTrayWindows().size();
+}
+
+void Systemtray::updateBackgroundPixmap ( const QPixmap & 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)....
+ QPixmap bug = QPixmap(emb->size());
+ bitBlt(&bug, 0, 0, &pixmap, emb->parentWidget()->x()+emb->x(), emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),Qt::CopyROP, false);
+ emb->setPaletteBackgroundPixmap (bug);
+
+ }
+
+ QPoint topPoint = mapToGlobal(QPoint(0,0));
+ Window hack = XCreateSimpleWindow(qt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0);
+ XRaiseWindow(qt_xdisplay(), hack);
+ XMapWindow(qt_xdisplay(), hack);
+ XUnmapWindow(qt_xdisplay(), hack);
+ XDestroyWindow(qt_xdisplay(), hack);
+}
+
+void Systemtray::initSystray( void )
+{
+ bool existing = false;
+ //bool content = false;
+ Display *display = qt_xdisplay();
+ no_of_systray_windows = 0;
+
+ kwin_module = new KWinModule();
+ systemTrayWindows = kwin_module->systemTrayWindows();
+ QValueList<WId>::ConstIterator end(systemTrayWindows.end());
+ for (QValueList<WId>::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, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
+
+ m_Wins.append(emb);
+
+ emb->embed(*it);
+ emb->resize(24, 24);
+ emb->show();
+ existing = true;
+ }
+
+ updateTrayWindows();
+
+ connect(kwin_module, SIGNAL(systemTrayWindowAdded(WId)), SLOT(systemTrayWindowAdded(WId)));
+ connect(kwin_module, SIGNAL(systemTrayWindowRemoved(WId)), SLOT(systemTrayWindowRemoved(WId)));
+
+ QCString screenstr;
+ screenstr.setNum(qt_xscreen());
+ QCString 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 = qt_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) || !kwin_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, SIGNAL(embeddedWindowDestroyed()), 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"