#include "xosd.h" #include #include #include #include #include #include #include #include #include #include #include xosd::xosd(QWidget *parent, const char *name) : QWidget(parent, name, WStyle_Customize | WRepaintNoErase | WStyle_NoBorder | WDestructiveClose | WResizeNoErase | WMouseNoMask | WStyle_StaysOnTop | WX11BypassWM) { info = new NETWinInfo( qt_xdisplay(), winId(), qt_xrootwin(), NET::WMState); info->setDesktop( NETWinInfo::OnAllDesktops ); hide(); KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager); setCaption("kooldock xosd window"); } xosd::~xosd() { } void xosd::setColor(QString color) { fontColor=color; } void xosd::setShadowColor(QString color) { shadowColor=color; } void xosd::setOrientation(int orientation, int w, int mh) { fOrientation=orientation; dw=w; rdh=mh; if (fCleaner==1) { //font is set, so program can get its height to prepare background buffer QFontMetrics *metrics = new QFontMetrics(f); h = metrics->height(); bgBuffer = QPixmap(dw, h); maskBuffer = QPixmap(dw, h, true); bgBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, 0, dw, h); lastX=0; lastY=0; } } //Enables/disables dynamic background void xosd::setClear(int nClean) { fCleaner = nClean; } void xosd::setShadowOffset(int off) { shadowOffset=off; } void xosd::setText(QString t) { //setMask(QRegion(0,0,0,0)); // NOTICE: it appears that with WX11BypassWM, resize() doesn't flick the widget anymore :) // so, setMask() is no more needed. // -- Matias resize(0,0); text = t; QFontMetrics *metrics = new QFontMetrics(f); w = metrics->width(text); w = w + shadowOffset + 5; // 5 pixels more h = metrics->height(); yOffset = metrics->height()-metrics->descent(); update(); } void xosd::setFont(QString font) { f.setFamily(font); } void xosd::setItalic() { f.setItalic(TRUE); } void xosd::setBold() { f.setBold(TRUE); } void xosd::setSize(int size) { f.setPointSize(size); fontSize = size; } /*int xosd::w() { QFontMetrics *metrics = new QFontMetrics(f); return (metrics->width(text) + shadowOffset + 5); } int xosd::h() { QFontMetrics *metrics = new QFontMetrics(f); return metrics->height(); }*/ void xosd::paintEvent(QPaintEvent *) { int i, j; resize(w,h); QPixmap pm(size()); QBitmap bm(size()); QPainter p; //Drawing text p.begin(&pm, this); if (fCleaner==1) { //Dynamic background - look cleaner bitBlt(&pm, 0, 0, &bgBuffer, lastX, 0, w, h); } else { //One colour background - work faster p.fillRect (rect(), QColor(shadowColor)); } p.setPen( QColor(shadowColor) ); p.setFont(f); p.drawText(shadowOffset, yOffset + shadowOffset, text, AlignCenter); // draw shadow text // now, draw normal text p.setPen( QColor(fontColor) ); p.drawText(1, yOffset, text, AlignCenter); // draw front text p.end(); //Drawing mask p.begin(&bm, this); // now we must draw the text with black color for making the mask p.setPen( Qt::white ); p.fillRect (rect(), Qt::black); p.setFont(f); for (i=-fCleaner;i<=fCleaner;i++) { for (j=-fCleaner;j<=fCleaner;j++) { p.drawText(shadowOffset+i, yOffset + shadowOffset+j, text, AlignCenter); // shadow p.drawText(1+i, yOffset+j, text, AlignCenter); // front } } p.end(); bitBlt(this, 0, 0, &pm); // update the widget if (fCleaner==1) bitBlt(&maskBuffer, 0, 0, &bm); info->setState(NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager, NETWinInfo::SkipTaskbar | NETWinInfo::SkipPager); setMask(bm); } void xosd::move2(int x, int y) { //bit block transfer don't work propertly with too less cursor position changes if (abs(lastY-y)>2 || abs(lastX-x)>2) { if (fCleaner==1) { QPixmap tmpBuffer; //window is not hidden if (y!=rdh) { tmpBuffer = QPixmap::grabWindow(qt_xrootwin(), 0, y, dw, h); if (lastY!=rdh) { //fill background covered with the text with cached version if (fOrientation==0 ) //horizontal { bitBlt(&tmpBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::AndROP);//copying part, which hides only the text bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP);//so the background won't be covered by bitBlt(&tmpBuffer, lastX, 0, &bgBuffer, lastX, 0, w, h, Qt::OrROP);//currently visible text. } if (fOrientation==1) //vertical { if (ylastY) { bitBlt(&tmpBuffer, lastX, lastY-y, &maskBuffer, 0, 0, w, h, Qt::AndROP); bitBlt(&bgBuffer, lastX, 0, &maskBuffer, 0, 0, w, h, Qt::NotAndROP); bitBlt(&tmpBuffer, lastX, lastY-y, &bgBuffer, lastX, 0, w, h, Qt::OrROP); } if (y>lastY && (y-lastY)