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
129
130
131
|
//===========================================
// 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;
badpaints = 0;
if("1" == QString(getenv("QT_AUTO_SCREEN_SCALE_FACTOR")) ){
scalefactor = 2; //Auto-adjust this later to the physicalDotsPerInch of the current screen
}else{ scalefactor = 1; }
//this->setLayout(new QHBoxLayout);
//this->layout()->setContentsMargins(0,0,0,0);
}
TrayIcon::~TrayIcon(){
}
void TrayIcon::cleanup(){
AID = IID = 0;
}
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()*scalefactor, icosize.height()*scalefactor);
QTimer::singleShot(500, this, SLOT(repaint()) ); //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());
//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()*scalefactor) != pix.size()){ QTimer::singleShot(10, this, SLOT(updateIcon())); return; }
painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) );
badpaints = 0; //good paint
}else{
badpaints++;
if(badpaints>5){
qWarning() << " - - No Tray Icon/Image found!" << "ID:" << AID;
AID = 0; //reset back to nothing
IID = 0;
emit BadIcon(); //removed/destroyed in some non-valid way?
}
}
//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
}
}
|