aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp')
-rw-r--r--lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
new file mode 100644
index 00000000..37970051
--- /dev/null
+++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
@@ -0,0 +1,142 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2014, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "TrayIcon.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xdamage.h>
+
+static Damage dmgID = 0;
+
+TrayIcon::TrayIcon(QWidget *parent) : QWidget(parent){
+ AID = 0; //nothing attached yet
+ IID = 0;
+}
+
+TrayIcon::~TrayIcon(){
+ if(AID!=0){
+ detachApp();
+ }
+}
+
+WId TrayIcon::appID(){
+ return AID;
+}
+
+void TrayIcon::attachApp(WId id){
+ if(id==0){ return; } //nothing to attach
+ else if(AID!=0){ qWarning() << "Tray Icon is already attached to a window!"; return; }
+ AID = id;
+ //qDebug() << "Container:" << this->winId();
+ //qDebug() << " - Tray:" << AID;
+ QTimer::singleShot(0,this,SLOT(slotAttach()) );
+}
+
+void TrayIcon::setSizeSquare(int side){
+ this->setFixedSize( QSize(side, side) );
+}
+
+// ==============
+// PUBLIC SLOTS
+// ==============
+void TrayIcon::detachApp(){
+ if(AID==0){ return; } //already detached
+ qDebug() << "Detach App:" << AID;
+ //Temporarily move the AID, so that internal slots do not auto-run
+ WId tmp = AID;
+ AID = 0;
+ //Now detach the application window and clean up
+ qDebug() << " - Unembed";
+ LX11::UnembedWindow(tmp);
+ if(dmgID!=0){
+ XDamageDestroy(QX11Info::display(), dmgID);
+ }
+ qDebug() << " - finished app:" << tmp;
+ //if(IID!=this->winId()){ LX11::DestroyWindow(IID); }
+ IID = 0;
+ emit AppClosed();
+}
+
+// ==============
+// PRIVATE SLOTS
+// ==============
+void TrayIcon::slotAttach(){
+ IID = this->winId(); //embed directly into this widget
+ //IID = LX11::CreateWindow( this->winId(), this->rect() ); //Create an intermediate window to be the parent
+ if( LX11::EmbedWindow(AID, IID) ){
+ LX11::RestoreWindow(AID); //make it visible
+ //XSelectInput(QX11Info::display(), AID, StructureNotifyMask);
+ dmgID = XDamageCreate( QX11Info::display(), AID, XDamageReportRawRectangles );
+ updateIcon();
+ qDebug() << "New System Tray App:" << AID;
+ emit AppAttached();
+ QTimer::singleShot(500, this, SLOT(updateIcon()) );
+ }else{
+ qWarning() << "Could not Embed Tray Application:" << AID;
+ //LX11::DestroyWindow(IID);
+ IID = 0;
+ AID = 0;
+ emit AppClosed();
+ }
+}
+
+void TrayIcon::updateIcon(){
+ if(AID==0){ return; }
+ //Make sure the icon is square
+ QSize icosize = this->size();
+ LX11::ResizeWindow(AID, icosize.width(), icosize.height());
+}
+
+// =============
+// PROTECTED
+// =============
+void TrayIcon::paintEvent(QPaintEvent *event){
+ QWidget::paintEvent(event); //make sure the background is already painted
+ if(AID!=0){
+ //qDebug() << "Paint Tray:" << AID;
+ QPainter painter(this);
+ //Now paint the tray app on top of the background
+ //qDebug() << " - Draw tray:" << AID << IID << this->winId();
+ //qDebug() << " - - " << event->rect().x() << event->rect().y() << event->rect().width() << event->rect().height();
+ //qDebug() << " - Get image";
+ QPixmap pix = LX11::WindowImage(AID, false);
+ if(pix.isNull()){
+ //Try to grab the window directly with Qt
+ //qDebug() << " - Grab window directly";
+ pix = QPixmap::grabWindow(AID);
+ }
+ //qDebug() << " - Pix size:" << pix.size().width() << pix.size().height();
+ //qDebug() << " - Geom:" << this->geometry().x() << this->geometry().y() << this->geometry().width() << this->geometry().height();
+ painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) );
+ //qDebug() << " - Done";
+ }
+}
+
+/*void TrayIcon::moveEvent(QMoveEvent *event){
+ //Make sure the main Tray window is right underneath the widget
+ //qDebug() << "Move Event:" << event->pos().x() << event->pos().y();
+ LX11::MoveResizeWindow(AID, QRect( this->mapToGlobal(event->pos()), this->size()) );
+ QWidget::moveEvent(event);
+}*/
+
+void TrayIcon::resizeEvent(QResizeEvent *event){
+ //qDebug() << "Resize Event:" << event->size().width() << event->size().height();
+ if(AID!=0){
+ LX11::ResizeWindow(AID, event->size().width(), event->size().height());
+ }
+}
+
+/*bool TrayIcon::x11Event(XEvent *event){
+ qDebug() << "XEvent";
+ if( event->xany.window==AID || event->type==( (int)dmgID+XDamageNotify) ){
+ qDebug() << "Tray X Event:" << AID;
+ this->update(); //trigger a repaint
+ return true;
+ }else{
+ return false; //no special handling
+ }
+}*/
bgstack15