Applets
systemtraywidget.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "systemtraywidget.h"
00025 #include "systemtraycontainer.h"
00026
00027
00028 #include <QX11Info>
00029
00030
00031 #include <X11/Xlib.h>
00032
00033 namespace
00034 {
00035 enum
00036 {
00037 SYSTEM_TRAY_REQUEST_DOCK,
00038 SYSTEM_TRAY_BEGIN_MESSAGE,
00039 SYSTEM_TRAY_CANCEL_MESSAGE
00040 };
00041 }
00042
00043 SystemTrayWidget::SystemTrayWidget(QWidget *parent)
00044 : QWidget(parent),
00045 m_orientation(Qt::Horizontal),
00046 m_maxCount(0),
00047 m_nextRow(0),
00048 m_nextColumn(0)
00049 {
00050 m_mainLayout = new QGridLayout(this);
00051
00052
00053 m_mainLayout->setContentsMargins(0, 0, 0, 0);
00054 m_mainLayout->setSpacing(4);
00055 }
00056
00057 void SystemTrayWidget::init()
00058 {
00059 Display *display = QX11Info::display();
00060
00061 m_selectionAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_S" + QByteArray::number(QX11Info::appScreen()), false);
00062 m_opcodeAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", false);
00063 XSetSelectionOwner(display, m_selectionAtom, winId(), CurrentTime);
00064
00065 if (XGetSelectionOwner(display, m_selectionAtom) == winId()) {
00066 WId root = QX11Info::appRootWindow();
00067 XClientMessageEvent xev;
00068
00069 xev.type = ClientMessage;
00070 xev.window = root;
00071 xev.message_type = XInternAtom(display, "MANAGER", false);
00072 xev.format = 32;
00073 xev.data.l[0] = CurrentTime;
00074 xev.data.l[1] = m_selectionAtom;
00075 xev.data.l[2] = winId();
00076 xev.data.l[3] = 0;
00077 xev.data.l[4] = 0;
00078
00079 XSendEvent(display, root, false, StructureNotifyMask, (XEvent*)&xev);
00080 }
00081 }
00082
00083 bool SystemTrayWidget::x11Event(XEvent *event)
00084 {
00085 if (event->type == ClientMessage) {
00086 if (event->xclient.message_type == m_opcodeAtom &&
00087 event->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
00088 const WId systemTrayClientId = (WId)event->xclient.data.l[2];
00089 if (systemTrayClientId == 0) {
00090 return true;
00091 }
00092 foreach(SystemTrayContainer *c, findChildren<SystemTrayContainer*>()) {
00093 if (c->clientWinId() == systemTrayClientId) {
00094 return true;
00095 }
00096 }
00097
00098
00099 SystemTrayContainer *container = new SystemTrayContainer(this);
00100 connect(container, SIGNAL(destroyed(QObject *)), this, SLOT(relayoutContainers(QObject *)));
00101 connect(container, SIGNAL(clientIsEmbedded()), this, SIGNAL(sizeShouldChange()));
00102 addWidgetToLayout(container);
00103
00104 container->embedSystemTrayClient(systemTrayClientId);
00105 return true;
00106 }
00107 }
00108 return QWidget::x11Event(event);
00109 }
00110
00111 void SystemTrayWidget::setOrientation(Qt::Orientation orientation)
00112 {
00113 if (orientation != m_orientation) {
00114 m_orientation = orientation;
00115 relayoutContainers();
00116 }
00117 }
00118
00119 void SystemTrayWidget::setMaximumSize(QSize s)
00120 {
00121 bool doLayout = (m_orientation == Qt::Horizontal && s.height() != maximumHeight());
00122 doLayout |= (m_orientation == Qt::Vertical && s.width() != maximumWidth());
00123
00124 QWidget::setMaximumSize(s);
00125 if (doLayout) {
00126 relayoutContainers();
00127 }
00128 }
00129
00130 void SystemTrayWidget::addWidgetToLayout(QWidget *widget)
00131 {
00132
00133 m_mainLayout->setRowMinimumHeight(m_nextRow, 22);
00134 m_mainLayout->setColumnMinimumWidth(m_nextColumn, 22);
00135 widget->resize(22,22);
00136 m_mainLayout->addWidget(widget, m_nextRow, m_nextColumn, 1, 1, Qt::AlignCenter);
00137
00138
00139 if (m_orientation == Qt::Horizontal) {
00140
00141 m_maxCount = (maximumHeight() + m_mainLayout->spacing()) / (widget->height() + m_mainLayout->spacing()) -1;
00142
00143 setMinimumSize(QSize(22 * (m_nextColumn + 1) + m_mainLayout->spacing() * m_nextColumn,
00144 22 * (m_maxCount + 1) + m_mainLayout->spacing() * m_maxCount));
00145
00146
00147 m_nextRow++;
00148 if (m_nextRow > m_maxCount){
00149 m_nextColumn++;
00150 m_nextRow = 0;
00151 }
00152 } else {
00153
00154 m_maxCount = (maximumWidth() + m_mainLayout->spacing()) / (widget->width() + m_mainLayout->spacing()) -1;
00155
00156 setMinimumSize(QSize(22 * (m_maxCount + 1) + m_mainLayout->spacing() * m_maxCount,
00157 22 * (m_nextRow + 1) + m_mainLayout->spacing() * m_nextRow));
00158
00159
00160 m_nextColumn++;
00161 if (m_nextColumn > m_maxCount) {
00162 m_nextRow++;
00163 m_nextColumn = 0;
00164 }
00165 }
00166 }
00167
00168 void SystemTrayWidget::relayoutContainers(QObject *removeContainer)
00169 {
00170
00171
00172 QList<QWidget *> remainingWidgets;
00173 while (QLayoutItem* item = m_mainLayout->takeAt(0)) {
00174 if (item->widget() && item->widget() != removeContainer) {
00175 remainingWidgets.append(item->widget());
00176 }
00177 delete item;
00178 }
00179
00180
00181
00182
00183 for (int row = 0; row < m_mainLayout->rowCount(); row++) {
00184 m_mainLayout->setRowMinimumHeight(row, 0);
00185 }
00186 for (int column = 0; column < m_mainLayout->columnCount(); column++) {
00187 m_mainLayout->setColumnMinimumWidth(column, 0);
00188 }
00189
00190
00191 m_maxCount = 0;
00192 m_nextRow = 0;
00193 m_nextColumn = 0;
00194 foreach (QWidget *widget, remainingWidgets) {
00195 addWidgetToLayout(widget);
00196 }
00197
00198 emit sizeShouldChange();
00199 }
00200
00201 #include "systemtraywidget.moc"