Use KWin's TaskbarThumbnail effect to show window previews in tooltips.
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=756513
This commit is contained in:
parent
ecbe57e4ea
commit
89ab030a89
@ -24,8 +24,13 @@
|
|||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
|
#include <QX11Info>
|
||||||
|
|
||||||
#include <kglobal.h>
|
#include <kglobal.h>
|
||||||
|
#include <kwindowsystem.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <fixx11h.h>
|
||||||
|
|
||||||
namespace Plasma {
|
namespace Plasma {
|
||||||
|
|
||||||
@ -35,6 +40,8 @@ class ToolTip::Private
|
|||||||
Private()
|
Private()
|
||||||
: label(0)
|
: label(0)
|
||||||
, imageLabel(0)
|
, imageLabel(0)
|
||||||
|
, preview(0)
|
||||||
|
, windowToPreview(0)
|
||||||
, currentWidget(0)
|
, currentWidget(0)
|
||||||
, isShown(false)
|
, isShown(false)
|
||||||
, showTimer(0)
|
, showTimer(0)
|
||||||
@ -43,6 +50,8 @@ class ToolTip::Private
|
|||||||
|
|
||||||
QLabel *label;
|
QLabel *label;
|
||||||
QLabel *imageLabel;
|
QLabel *imageLabel;
|
||||||
|
WindowPreview *preview;
|
||||||
|
WId windowToPreview;
|
||||||
Plasma::Widget *currentWidget;
|
Plasma::Widget *currentWidget;
|
||||||
bool isShown;
|
bool isShown;
|
||||||
QTimer *showTimer;
|
QTimer *showTimer;
|
||||||
@ -112,18 +121,30 @@ void ToolTip::slotResetTimer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToolTip::showEvent( QShowEvent* e )
|
||||||
|
{
|
||||||
|
QWidget::showEvent( e );
|
||||||
|
if( d->windowToPreview != 0 ) { //show or hide the window preview area
|
||||||
|
d->preview->show();
|
||||||
|
d->preview->setInfo();
|
||||||
|
} else
|
||||||
|
d->preview->hide();
|
||||||
|
}
|
||||||
|
|
||||||
ToolTip::ToolTip()
|
ToolTip::ToolTip()
|
||||||
: QWidget(0)
|
: QWidget(0)
|
||||||
, d( new Private )
|
, d( new Private )
|
||||||
{
|
{
|
||||||
setWindowFlags(Qt::ToolTip);
|
setWindowFlags(Qt::ToolTip);
|
||||||
QHBoxLayout *l = new QHBoxLayout;
|
QGridLayout *l = new QGridLayout;
|
||||||
|
d->preview = new WindowPreview;
|
||||||
d->label = new QLabel;
|
d->label = new QLabel;
|
||||||
d->label->setWordWrap(true);
|
d->label->setWordWrap(true);
|
||||||
d->imageLabel = new QLabel;
|
d->imageLabel = new QLabel;
|
||||||
d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
l->addWidget(d->imageLabel);
|
l->addWidget(d->preview, 0, 0, 1, 2);
|
||||||
l->addWidget(d->label);
|
l->addWidget(d->imageLabel, 1, 0);
|
||||||
|
l->addWidget(d->label, 1, 1);
|
||||||
setLayout(l);
|
setLayout(l);
|
||||||
|
|
||||||
d->showTimer = new QTimer(this);
|
d->showTimer = new QTimer(this);
|
||||||
@ -140,6 +161,7 @@ void ToolTip::setData(const Plasma::ToolTipData &data)
|
|||||||
d->label->setText("<qt><h3>" + data.mainText + "</h3><p>" +
|
d->label->setText("<qt><h3>" + data.mainText + "</h3><p>" +
|
||||||
data.subText + "</p></qt>");
|
data.subText + "</p></qt>");
|
||||||
d->imageLabel->setPixmap(data.image);
|
d->imageLabel->setPixmap(data.image);
|
||||||
|
d->preview->setWindowId( data.windowToPreview );
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip::~ToolTip()
|
ToolTip::~ToolTip()
|
||||||
@ -147,5 +169,80 @@ ToolTip::~ToolTip()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// A widget which reserves area for window preview and sets hints on the toplevel
|
||||||
|
// tooltip widget that tells KWin to render the preview in this area. This depends
|
||||||
|
// on KWin's TaskbarThumbnail compositing effect (which is here detected).
|
||||||
|
|
||||||
|
void WindowPreview::setWindowId( WId w )
|
||||||
|
{
|
||||||
|
if( !previewsAvailable()) {
|
||||||
|
id = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
id = w;
|
||||||
|
windowSize = QSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowPreview::previewsAvailable() const
|
||||||
|
{
|
||||||
|
if( !KWindowSystem::compositingActive())
|
||||||
|
return false;
|
||||||
|
// hackish way to find out if KWin has the effect enabled,
|
||||||
|
// TODO provide proper support
|
||||||
|
Display* dpy = QX11Info::display();
|
||||||
|
Atom atom = XInternAtom( dpy, "_KDE_WINDOW_PREVIEW", False );
|
||||||
|
int cnt;
|
||||||
|
Atom* list = XListProperties( dpy, DefaultRootWindow( dpy ), &cnt );
|
||||||
|
if( list != NULL ) {
|
||||||
|
bool ret = ( qFind( list, list + cnt, atom ) != list + cnt );
|
||||||
|
XFree( list );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize WindowPreview::sizeHint() const
|
||||||
|
{
|
||||||
|
if( id == 0 )
|
||||||
|
return QSize();
|
||||||
|
if( !windowSize.isValid())
|
||||||
|
readWindowSize();
|
||||||
|
QSize s = windowSize;
|
||||||
|
s.scale( 200, 150, Qt::KeepAspectRatio );
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowPreview::readWindowSize() const
|
||||||
|
{
|
||||||
|
Window r;
|
||||||
|
int x, y;
|
||||||
|
unsigned int w, h, b, d;
|
||||||
|
if( XGetGeometry( QX11Info::display(), id, &r, &x, &y, &w, &h, &b, &d ))
|
||||||
|
windowSize = QSize( w, h );
|
||||||
|
else
|
||||||
|
windowSize = QSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowPreview::setInfo()
|
||||||
|
{
|
||||||
|
Display* dpy = QX11Info::display();
|
||||||
|
Atom atom = XInternAtom( dpy, "_KDE_WINDOW_PREVIEW", False );
|
||||||
|
if( id == 0 ) {
|
||||||
|
XDeleteProperty( dpy, winId(), atom );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( !windowSize.isValid())
|
||||||
|
readWindowSize();
|
||||||
|
if( !windowSize.isValid()) {
|
||||||
|
XDeleteProperty( dpy, winId(), atom );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_ASSERT( parentWidget()->isWindow()); // parent must be toplevel
|
||||||
|
long data[] = { 1, 5, id, x(), y(), width(), height() };
|
||||||
|
XChangeProperty( dpy, parentWidget()->winId(), atom, atom, 32, PropModeReplace,
|
||||||
|
reinterpret_cast< unsigned char* >( data ), sizeof( data ) / sizeof( data[ 0 ] ));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#include "tooltip_p.moc"
|
#include "tooltip_p.moc"
|
||||||
|
@ -49,6 +49,9 @@ public:
|
|||||||
|
|
||||||
Plasma::Widget *currentWidget() const;
|
Plasma::Widget *currentWidget() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void showEvent( QShowEvent* );
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotResetTimer();
|
void slotResetTimer();
|
||||||
void slotShowToolTip();
|
void slotShowToolTip();
|
||||||
@ -60,6 +63,20 @@ private:
|
|||||||
Private *const d;
|
Private *const d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WindowPreview : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
void setWindowId( WId w );
|
||||||
|
void setInfo();
|
||||||
|
virtual QSize sizeHint() const;
|
||||||
|
bool previewsAvailable() const;
|
||||||
|
private:
|
||||||
|
void readWindowSize() const;
|
||||||
|
WId id;
|
||||||
|
mutable QSize windowSize;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,9 +40,11 @@ namespace Plasma
|
|||||||
|
|
||||||
struct PLASMA_EXPORT ToolTipData
|
struct PLASMA_EXPORT ToolTipData
|
||||||
{
|
{
|
||||||
|
ToolTipData() : windowToPreview( 0 ) {}
|
||||||
QString mainText; //Important information
|
QString mainText; //Important information
|
||||||
QString subText; //Elaborates on the Main Text
|
QString subText; //Elaborates on the Main Text
|
||||||
QPixmap image; // Icon to show;
|
QPixmap image; // Icon to show;
|
||||||
|
WId windowToPreview; // Id of window to show preview
|
||||||
};
|
};
|
||||||
|
|
||||||
class Layout;
|
class Layout;
|
||||||
|
Loading…
Reference in New Issue
Block a user