1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
//===========================================
// Lumina-DE source code
// Copyright (c) 2014-2015, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
#include "TrayIcon.h"
#include <LSession.h>
#include <QScreen>
#include <LuminaX11.h>
TrayIcon::TrayIcon(QWidget *parent) : QWidget(parent){
AID = 0; //nothing yet
IID = 0;
dmgID = 0;
//this->setLayout(new QHBoxLayout);
//this->layout()->setContentsMargins(0,0,0,0);
}
TrayIcon::~TrayIcon(){
}
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;
//WIN = QWindow::fromWinId(AID);
//connect(WIN, SIGNAL(
//this->layout()->addWidget( QWidget::createWindowContainer(WIN, this) );
IID = this->winId(); //embed directly into this widget
dmgID = LSession::handle()->XCB->EmbedWindow(AID, IID);
if( dmgID != 0 ){
LSession::handle()->XCB->RestoreWindow(AID); //make it visible
qDebug() << "New System Tray App:" << AID;
QTimer::singleShot(1000, this, SLOT(updateIcon()) );
}else{
qWarning() << "Could not Embed Tray Application:" << AID;
IID = 0;
AID = 0;
}
}
void TrayIcon::setSizeSquare(int side){
//qDebug() << " Set Fixed Systray size:" << 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";
//WIN->setParent(0); //Reset parentage back to the main stack
LSession::handle()->XCB->UnembedWindow(tmp);
qDebug() << " - finished app:" << tmp;
IID = 0;
}
// ==============
// PRIVATE SLOTS
// ==============
void TrayIcon::updateIcon(){
if(AID==0){ return; }
//Make sure the icon is square
QSize icosize = this->size();
LSession::handle()->XCB->ResizeWindow(AID, icosize.width(), icosize.height());
QTimer::singleShot(500, this, SLOT(update()) ); //make sure to re-draw the window in a moment
}
// =============
// PROTECTED
// =============
void TrayIcon::paintEvent(QPaintEvent *event){
QWidget::paintEvent(event); //make sure the background is already painted
if(AID!=0){
//Update the background on the tray app
//qDebug() << "Paint Tray Background";
//LSession::handle()->XCB->SetWindowBackground(this, this->geometry(), AID);
//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:" << AID;
QPixmap pix = LSession::handle()->XCB->TrayImage(AID); //= WIN->icon().pixmap(this->size());
//if(pix.isNull()){
//qDebug() << "Null Image - use Qt grab Window";
//Try to grab the window directly with Qt instead
/*QList<QScreen*> scrnlist = QApplication::screens();
for(int i=0; i<scrnlist.length(); i++){
pix = scrnlist[i]->grabWindow(AID);
break; //stop here
}
//}
if(pix.isNull()){
qDebug() << "Null Qt Pixmap - Use XCB grab image:";
pix = LSession::handle()->XCB->TrayImage(AID);
}*/
//qDebug() << " - Pix size:" << pix.size().width() << pix.size().height();
//qDebug() << " - Geom:" << this->geometry().x() << this->geometry().y() << this->geometry().width() << this->geometry().height();
if(!pix.isNull()){
if(this->size() != pix.size()){ QTimer::singleShot(10, this, SLOT(updateIcon())); }
painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) );
}else{
qWarning() << " - - No Tray Icon/Image found!" << "ID:" << AID;
}
//qDebug() << " - Done";
}
}
void TrayIcon::resizeEvent(QResizeEvent *event){
//qDebug() << "Resize Event:" << event->size().width() << event->size().height();
if(AID!=0){
LSession::handle()->XCB->ResizeWindow(AID, event->size());
QTimer::singleShot(500, this, SLOT(update()) ); //make sure to re-draw the window in a moment
}
}
|