summaryrefslogtreecommitdiffstats
path: root/kwin-styles/smooth-blend/client/smoothblend.cc
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit8b2aa1b5301ab60368a03e36df4ff5216726e87d (patch)
tree36163d4ee667c23b5cf232df2f3004cd0a76202a /kwin-styles/smooth-blend/client/smoothblend.cc
downloadtdeartwork-8b2aa1b5301ab60368a03e36df4ff5216726e87d.tar.gz
tdeartwork-8b2aa1b5301ab60368a03e36df4ff5216726e87d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeartwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kwin-styles/smooth-blend/client/smoothblend.cc')
-rw-r--r--kwin-styles/smooth-blend/client/smoothblend.cc1396
1 files changed, 1396 insertions, 0 deletions
diff --git a/kwin-styles/smooth-blend/client/smoothblend.cc b/kwin-styles/smooth-blend/client/smoothblend.cc
new file mode 100644
index 00000000..9adb60ac
--- /dev/null
+++ b/kwin-styles/smooth-blend/client/smoothblend.cc
@@ -0,0 +1,1396 @@
+//////////////////////////////////////////////////////////////////////////////
+// smoothblend.cc
+// -------------------
+// Smooth Blend window decoration for KDE
+// -------------------
+// Copyright (c) 2005 Ryan Nickell
+// Please see the header file for copyright and license information.
+//////////////////////////////////////////////////////////////////////////////
+
+#include <kconfig.h>
+#include <kdeversion.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <klocale.h>
+#include <kpixmap.h>
+#include <kimageeffect.h>
+#include <kpixmapeffect.h>
+#include <kpixmap.h>
+
+#include <qbitmap.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+#include <qapplication.h>
+
+#include "smoothblend.h"
+#include "buttons.h"
+
+using namespace smoothblend;
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendFactory Class
+//////////////////////////////////////////////////////////////////////////////
+smoothblendFactory* factory=NULL;
+
+bool smoothblendFactory::initialized_ = false;
+Qt::AlignmentFlags smoothblendFactory::titlealign_ = Qt::AlignHCenter;
+bool smoothblendFactory::cornerflags_ = true;
+int smoothblendFactory::titlesize_ = 30;
+int smoothblendFactory::buttonsize_ = 26;
+int smoothblendFactory::framesize_ = 4;
+int smoothblendFactory::roundsize_ = 50;
+bool smoothblendFactory::titleshadow_ = true;
+bool smoothblendFactory::animatebuttons = true;
+int smoothblendFactory::btnComboBox = 0;
+bool smoothblendFactory::menuClose = false;
+
+// global constants
+static const int TOPMARGIN = 4; // do not change
+static const int DECOHEIGHT = 4; // do not change
+static const int SIDETITLEMARGIN = 2;
+// Default button layout
+const char default_left[] = "M";
+const char default_right[] = "HIAX";
+
+static const uint TIMERINTERVAL = 50; // msec
+static const uint ANIMATIONSTEPS = 4;
+
+extern "C" KDecorationFactory* create_factory() {
+ return new smoothblend::smoothblendFactory();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendFactory()
+// ----------------
+// Constructor
+
+smoothblendFactory::smoothblendFactory() {
+ readConfig();
+ initialized_ = true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ~smoothblendFactory()
+// -----------------
+// Destructor
+
+smoothblendFactory::~smoothblendFactory() {
+ initialized_ = false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// createDecoration()
+// -----------------
+// Create the decoration
+
+KDecoration* smoothblendFactory::createDecoration(KDecorationBridge* b) {
+ return new smoothblendClient(b, this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// reset()
+// -------
+// Reset the handler. Returns true if decorations need to be remade, false if
+// only a repaint is necessary
+
+bool smoothblendFactory::reset(unsigned long changed) {
+ // read in the configuration
+ initialized_ = false;
+ bool confchange = readConfig();
+ initialized_ = true;
+
+ if (confchange ||
+ (changed & (SettingDecoration | SettingButtons | SettingBorder))) {
+ return true;
+ } else {
+ resetDecorations(changed);
+ return false;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// readConfig()
+// ------------
+// Read in the configuration file
+
+bool smoothblendFactory::readConfig() {
+ // create a config object
+ KConfig config("kwinsmoothblendrc");
+ config.setGroup("General");
+
+ // grab settings
+ QString value = config.readEntry("TitleAlignment", "AlignHCenter");
+ if (value == "AlignLeft")
+ titlealign_ = Qt::AlignLeft;
+ else if (value == "AlignHCenter")
+ titlealign_ = Qt::AlignHCenter;
+ else if (value == "AlignRight")
+ titlealign_ = Qt::AlignRight;
+
+ cornerflags_ = config.readBoolEntry("RoundCorners", true);
+ titlesize_ = config.readNumEntry("TitleSize",30);
+ buttonsize_ = config.readNumEntry("ButtonSize",26);
+ framesize_ = config.readNumEntry("FrameSize",4);
+ roundsize_ = config.readNumEntry("RoundPercent",50);
+ titleshadow_ = config.readBoolEntry("TitleShadow", true);
+ animatebuttons = config.readBoolEntry("AnimateButtons", true);
+ btnComboBox = config.readNumEntry("ButtonComboBox", 0);
+ menuClose = config.readBoolEntry("CloseOnMenuDoubleClick");
+
+ if(buttonsize_ > titlesize_ - framesize_)
+ {
+ buttonsize_ = titlesize_-framesize_;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendButton Class
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendButton()
+// ---------------
+// Constructor
+smoothblendButton::smoothblendButton(smoothblendClient *parent, const char *name, const QString& tip, ButtonType type, int button_size, bool toggle): QButton(parent->widget(), name),
+ client_(parent),
+ type_(type),
+ size_(button_size),
+ deco_(0),
+ lastmouse_(NoButton),
+ hover_(false)
+{
+ setBackgroundMode(NoBackground);
+ setFixedSize( ::factory->buttonSize(), ::factory->buttonSize());
+ setCursor(arrowCursor);
+ QToolTip::add(this, tip);
+ setToggleButton(toggle);
+ //button animation setup
+ animTmr = new QTimer(this);
+ connect(animTmr, SIGNAL(timeout() ), this, SLOT(animate() ) );
+ connect(this, SIGNAL(pressed() ), this, SLOT(buttonClicked() ) );
+ connect(this, SIGNAL(released() ), this, SLOT(buttonReleased() ) );
+ animProgress = 0;
+ m_clicked=false;
+}
+
+smoothblendButton::~smoothblendButton() {
+ if ( deco_ )
+ delete deco_;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// sizeHint()
+// ----------
+// Return size hint
+
+QSize smoothblendButton::sizeHint() const {
+ return QSize(::factory->buttonSize(), ::factory->buttonSize());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// buttonClicked()
+// ----------
+// Button animation progress reset so we don't get any leave event animation
+// when the mouse is still pressed
+void smoothblendButton::buttonClicked() {
+ m_clicked=true;
+ animProgress=0;
+}
+void smoothblendButton::buttonReleased() {
+ //This doesn't work b/c a released() signal is thrown when a leaveEvent occurs
+ //m_clicked=false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// animate()
+// ----------
+// Button animation timing
+void smoothblendButton::animate() {
+ animTmr->stop();
+
+ if(hover_) {
+ if(animProgress < ANIMATIONSTEPS) {
+ if (::factory->animateButtons() ) {
+ animProgress++;
+ } else {
+ animProgress = ANIMATIONSTEPS;
+ }
+ animTmr->start(TIMERINTERVAL, true); // single-shot
+ }
+ } else {
+ if(animProgress > 0) {
+ if (::factory->animateButtons() ) {
+ animProgress--;
+ } else {
+ animProgress = 0;
+ }
+ animTmr->start(TIMERINTERVAL, true); // single-shot
+ }
+ }
+ repaint(false);
+}
+//////////////////////////////////////////////////////////////////////////////
+// enterEvent()
+// ------------
+// Mouse has entered the button
+
+void smoothblendButton::enterEvent(QEvent *e) {
+ // we wanted to pass on the event
+ QButton::enterEvent(e);
+ // we want to do mouseovers, so keep track of it here
+ hover_=true;
+ if(!m_clicked)
+ {
+ animate();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// leaveEvent()
+// ------------
+// Mouse has left the button
+
+void smoothblendButton::leaveEvent(QEvent *e) {
+ // we wanted to pass on the event
+ QButton::leaveEvent(e);
+ // we want to do mouseovers, so keep track of it here
+ hover_=false;
+ if(!m_clicked)
+ {
+ animate();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mousePressEvent()
+// -----------------
+// Button has been pressed
+
+void smoothblendButton::mousePressEvent(QMouseEvent* e) {
+ lastmouse_ = e->button();
+
+ // translate and pass on mouse event
+ int button = LeftButton;
+ if ((type_ != ButtonMax) && (e->button() != LeftButton)) {
+ button = NoButton; // middle & right buttons inappropriate
+ }
+ QMouseEvent me(e->type(), e->pos(), e->globalPos(),
+ button, e->state());
+ QButton::mousePressEvent(&me);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mouseReleaseEvent()
+// -----------------
+// Button has been released
+
+void smoothblendButton::mouseReleaseEvent(QMouseEvent* e) {
+ lastmouse_ = e->button();
+
+ // translate and pass on mouse event
+ int button = LeftButton;
+ if ((type_ != ButtonMax) && (e->button() != LeftButton)) {
+ button = NoButton; // middle & right buttons inappropriate
+ }
+ QMouseEvent me(e->type(), e->pos(), e->globalPos(), button, e->state());
+ QButton::mouseReleaseEvent(&me);
+ if(m_clicked)
+ {
+ m_clicked=false;
+ }
+}
+
+void smoothblendButton::setOn(bool on)
+{
+ QButton::setOn(on);
+}
+
+void smoothblendButton::setDown(bool on)
+{
+ QButton::setDown(on);
+}
+
+//////////////////////////////////////////////////////////
+// getButtonImage()
+// ----------------
+// get the button QImage based on type and window mode
+QImage smoothblendButton::getButtonImage(ButtonType type)
+{
+ QImage finalImage;
+ switch(type) {
+ case ButtonClose:
+ finalImage = uic_findImage( "close.png" );
+ break;
+ case ButtonHelp:
+ finalImage = uic_findImage( "help.png" );
+ break;
+ case ButtonMin:
+ finalImage = uic_findImage( "minimize.png" );
+ break;
+ case ButtonMax:
+ if(client_->maximizeMode() == KDecorationDefines::MaximizeFull)
+ {
+ finalImage = uic_findImage( "restore.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "maximize.png" );
+ }
+ break;
+ case ButtonSticky:
+ if(client_->isOnAllDesktops())
+ {
+ finalImage = uic_findImage( "splat.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "circle.png" );
+ }
+ break;
+ case ButtonShade:
+ if(client_->isShade())
+ {
+ finalImage = uic_findImage( "shade.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "shade.png" );
+ }
+ break;
+ case ButtonAbove:
+ if(client_->keepAbove())
+ {
+ finalImage = uic_findImage( "keep_above_lit.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "keep_above.png" );
+ }
+ break;
+ case ButtonBelow:
+ if(client_->keepBelow())
+ {
+ finalImage = uic_findImage( "keep_below_lit.png" );
+ }
+ else
+ {
+ finalImage = uic_findImage( "keep_below.png" );
+ }
+ break;
+ default:
+ finalImage = uic_findImage( "splat.png" );
+ break;
+ }
+ return finalImage;
+}
+
+//////////////////////////////////////////////////////////
+// drawButton()
+// -------------------------
+// draw the pixmap button
+
+void smoothblendButton::drawButton( QPainter *painter ) {
+ if ( !smoothblendFactory::initialized() )
+ return ;
+
+ int newWidth = width() - 2;
+ int newHeight = height() - 2;
+ int dx = (width() - newWidth) / 2;
+ int dy = (height() - newHeight) / 2;
+ QImage tmpResult;
+ QColorGroup group;
+ QColor redColor(red);
+ bool active = client_->isActive();
+ QPixmap backgroundTile = client_->getTitleBarTile(active);
+ group = KDecoration::options()->colorGroup(KDecoration::ColorTitleBar, active);
+
+ //draw the titlebar behind the buttons and app icons
+ if ((client_->maximizeMode()==client_->MaximizeFull) && !KDecoration::options()->moveResizeMaximizedWindows())
+ {
+ painter->drawTiledPixmap(0, 0, width(), height(), backgroundTile);
+ }
+ else
+ {
+ painter->drawTiledPixmap(0, 0, width(), height(), backgroundTile, 0, y()-::factory->frameSize());
+ }
+
+ QImage buttonImage = getButtonImage(type_).smoothScale( width(),height());
+ buttonImage = KImageEffect::blend( group.background(), buttonImage, .50);
+ if (type_ == ButtonMenu) {
+ //slight movement to show the menu button is depressed
+ if (isDown()) {
+ dx++;
+ dy++;
+ }
+ QPixmap menuButtonPixmap(client_->icon().pixmap(QIconSet::Large, QIconSet::Normal));
+ QImage menuButtonImage(menuButtonPixmap.convertToImage());
+ //draw the menu button the same size as the other buttons
+ //using QIconSet::Large gives us a 32x32 icon to resize, resizing larger than
+ //that may produce pixilation of the image
+ painter->drawImage( dx, dy, menuButtonImage.smoothScale(newWidth, newHeight) );
+ } else {
+ //highlight on a mouse over repaint
+ double factor = animProgress * 0.13;
+
+ if(!isDown())
+ {
+ switch(::factory->getBtnComboBox())
+ {
+ case 0:
+ tmpResult = KImageEffect::intensity( buttonImage, factor);
+ break;
+ case 1:
+ tmpResult = KImageEffect::fade( buttonImage, factor, group.background());
+ break;
+ }
+ }
+ else
+ {
+ tmpResult = buttonImage;
+ }
+ painter->drawPixmap( 0, 0, QPixmap( tmpResult ) );
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendClient Class
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// smoothblendClient()
+// ---------------
+// Constructor
+
+smoothblendClient::smoothblendClient(KDecorationBridge *b, KDecorationFactory *f)
+ : KDecoration(b, f),
+ mainLayout_(0),
+ titleLayout_(0),
+ topSpacer_(0),
+ titleSpacer_(0),
+ leftTitleSpacer_(0), rightTitleSpacer_(0),
+ decoSpacer_(0),
+ leftSpacer_(0), rightSpacer_(0),
+ bottomSpacer_(0), windowSpacer_(0),
+ aCaptionBuffer(0), iCaptionBuffer(0),
+ aTitleBarTile(0), iTitleBarTile(0), aTitleBarTopTile(0), iTitleBarTopTile(0),
+ pixmaps_created(false),
+ //captionBufferDirty(true),
+ s_titleHeight(0),
+ s_titleFont(QFont()),
+ closing(false)
+ {
+ aCaptionBuffer = new QPixmap();
+ iCaptionBuffer = new QPixmap();
+ //s_titleFont = isTool()?smoothblendFactory::titleFontTool():smoothblendFactory::titleFont();
+ s_titleFont = options()->font();
+ s_titleHeight = smoothblendFactory::titleSize();
+ }
+//////////////////////////////////////////////////////////////////////////////////
+// ~smoothblendClient()
+// --------------------
+// Destructor
+smoothblendClient::~smoothblendClient() {
+ delete aCaptionBuffer;
+ delete iCaptionBuffer;
+}
+
+void smoothblendClient::create_pixmaps() {
+ if(pixmaps_created)
+ return;
+ KPixmap tempPixmap;
+ QPainter painter;
+ QColorGroup group,widgetGroup;
+ int FRAMESIZE = ::factory->frameSize();
+ // Get the color groups we need for the gradients
+ group = options()->colorGroup(KDecoration::ColorTitleBar, true);
+ widgetGroup = widget()->colorGroup();
+
+ // active top title bar tile
+ tempPixmap.resize(1, TOPMARGIN);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ -100);
+ aTitleBarTopTile = new QPixmap(1, TOPMARGIN);
+ painter.begin(aTitleBarTopTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // inactive top title bar tile
+ group = options()->colorGroup(KDecoration::ColorTitleBar, false);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ -100);
+ iTitleBarTopTile = new QPixmap(1, TOPMARGIN);
+ painter.begin(iTitleBarTopTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // active title bar tile
+ tempPixmap.resize(1, s_titleHeight+FRAMESIZE);
+ group = options()->colorGroup(KDecoration::ColorTitleBar, true);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ 200);
+ aTitleBarTile = new QPixmap(1, s_titleHeight+FRAMESIZE);
+ painter.begin(aTitleBarTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ // inactive title bar tile
+ group = options()->colorGroup(KDecoration::ColorTitleBar, false);
+ tempPixmap = KPixmapEffect::unbalancedGradient(tempPixmap,
+ group.background(),
+ widgetGroup.background(),
+ KPixmapEffect::VerticalGradient,
+ 100,
+ 200);
+ iTitleBarTile = new QPixmap(1, s_titleHeight+FRAMESIZE);
+ painter.begin(iTitleBarTile);
+ painter.drawPixmap(0, 0, tempPixmap);
+ painter.end();
+
+ pixmaps_created = true;
+}
+
+void smoothblendClient::delete_pixmaps() {
+ delete aTitleBarTopTile;
+ aTitleBarTopTile = 0;
+
+ delete iTitleBarTopTile;
+ iTitleBarTopTile = 0;
+
+ delete aTitleBarTile;
+ aTitleBarTile = 0;
+
+ delete iTitleBarTile;
+ iTitleBarTile = 0;
+
+ pixmaps_created = false;
+}
+//////////////////////////////////////////////////////////////////////////////
+// init()
+// ------
+// Actual initializer for class
+
+void smoothblendClient::init() {
+ createMainWidget(WResizeNoErase | WRepaintNoErase);
+ widget()->installEventFilter(this);
+ handlebar = ::factory->frameSize() < 4 ? 4 - ::factory->frameSize() : 0;
+ // for flicker-free redraws
+ widget()->setBackgroundMode(NoBackground);
+
+ _resetLayout();
+
+ create_pixmaps();
+}
+void smoothblendClient::_resetLayout()
+{
+ // basic layout:
+ // _______________________________________________________________
+ // | topSpacer |
+ // |_______________________________________________________________|
+ // | leftTitleSpacer | btns | titlebar | bts | rightTitleSpacer |
+ // |_________________|______|_____________|_____|__________________|
+ // | decoSpacer |
+ // |_______________________________________________________________|
+ // | | | |
+ // | | windowWrapper | |
+ // | | | |
+ // |leftSpacer rightSpacer|
+ // |_|___________________________________________________________|_|
+ // | bottomSpacer |
+ // |_______________________________________________________________|
+ //
+ if (!::factory->initialized()) return;
+
+ delete mainLayout_;
+ delete titleLayout_;
+ delete topSpacer_;
+ delete titleSpacer_;
+ delete leftTitleSpacer_;
+ delete rightTitleSpacer_;
+ delete decoSpacer_;
+ delete leftSpacer_;
+ delete rightSpacer_;
+ delete bottomSpacer_;
+ delete windowSpacer_;
+
+ mainLayout_ = new QVBoxLayout(widget());
+ // title
+ titleLayout_ = new QHBoxLayout();
+ QHBoxLayout *windowLayout_ = new QHBoxLayout();
+ int FRAMESIZE = ::factory->frameSize();
+
+ topSpacer_ = new QSpacerItem(1, FRAMESIZE, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ titlebar_ = new QSpacerItem(1, ::factory->buttonSize(),
+ QSizePolicy::Expanding, QSizePolicy::Fixed);
+ leftTitleSpacer_ = new QSpacerItem(FRAMESIZE, s_titleHeight,
+ QSizePolicy::Fixed, QSizePolicy::Fixed);
+ rightTitleSpacer_ = new QSpacerItem(FRAMESIZE, s_titleHeight,
+ QSizePolicy::Fixed, QSizePolicy::Fixed);
+ decoSpacer_ = new QSpacerItem(1, FRAMESIZE, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ leftSpacer_ = new QSpacerItem(::factory->frameSize(), 1,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ rightSpacer_ = new QSpacerItem(::factory->frameSize(), 1,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ bottomSpacer_ = new QSpacerItem(1, ::factory->frameSize(),
+ QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ // sizeof(...) is calculated at compile time
+ memset(button, 0, sizeof(smoothblendButton *) * ButtonTypeCount);
+
+ // message in preview widget
+ if (isPreview()) {
+ windowLayout_->addWidget(
+ new QLabel( i18n("<b><center>Smooth Blend</center></b>"), widget() ), 1 );
+ } else {
+ windowLayout_->addItem(new QSpacerItem(0, 0));
+ }
+
+ // setup titlebar buttons
+ for (int n=0; n<ButtonTypeCount; n++)
+ button[n] = 0;
+ //Deal with the title and buttons
+ titleLayout_->addItem(leftTitleSpacer_);
+ addButtons(titleLayout_,
+ options()->customButtonPositions() ? options()->titleButtonsLeft() : QString(default_left),
+ ::factory->titleSize()-1);
+ titleLayout_->addItem(titlebar_);
+ addButtons(titleLayout_,
+ options()->customButtonPositions() ? options()->titleButtonsRight() : QString(default_right),
+ ::factory->titleSize()-1);
+ titleLayout_->addItem(rightTitleSpacer_);
+
+ //Mid - left side, middle contents and right side
+ QHBoxLayout * midLayout_ = new QHBoxLayout();
+ midLayout_->addItem(leftSpacer_);
+ midLayout_->addLayout(windowLayout_);
+ midLayout_->addItem(rightSpacer_);
+
+ //Layout order
+ mainLayout_->addItem( topSpacer_ );
+ mainLayout_->addLayout( titleLayout_ );
+ mainLayout_->addItem( decoSpacer_ );
+ mainLayout_->addLayout( midLayout_ );
+ mainLayout_->addItem( bottomSpacer_ );
+
+ // connections
+ connect(this, SIGNAL(keepAboveChanged(bool)), SLOT(keepAboveChange(bool)));
+ connect(this, SIGNAL(keepBelowChanged(bool)), SLOT(keepBelowChange(bool)));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// addButtons()
+// ------------
+// Add buttons to title layout
+
+void smoothblendClient::addButtons(QBoxLayout *layout, const QString& s, int button_size) {
+ QString tip;
+ if (s.length() > 0) {
+ for (unsigned n=0; n < s.length(); n++) {
+ switch (s[n]) {
+ case 'M': // Menu button
+ if (!button[ButtonMenu]) {
+ button[ButtonMenu] =
+ new smoothblendButton(this, "splat.png", i18n("Menu"),ButtonMenu,button_size);
+ connect(button[ButtonMenu], SIGNAL(pressed()), this, SLOT(menuButtonPressed()));
+ connect(button[ButtonMenu], SIGNAL(released()), this, SLOT(menuButtonReleased()));
+ layout->addWidget(button[ButtonMenu]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'S': // Sticky button
+ if (!button[ButtonSticky]) {
+ if (isOnAllDesktops()) {
+ tip = i18n("Un-Sticky");
+ } else {
+ tip = i18n("Sticky");
+ }
+ button[ButtonSticky] =
+ new smoothblendButton(this, "circle.png", tip, ButtonSticky, button_size, true);
+ connect(button[ButtonSticky], SIGNAL(clicked()),
+ this, SLOT(toggleOnAllDesktops()));
+ layout->addWidget(button[ButtonSticky]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'H': // Help button
+ if ((!button[ButtonHelp]) && providesContextHelp()) {
+ button[ButtonHelp] =
+ new smoothblendButton(this, "help.png", i18n("Help"), ButtonHelp, button_size);
+ connect(button[ButtonHelp], SIGNAL(clicked()),
+ this, SLOT(showContextHelp()));
+ layout->addWidget(button[ButtonHelp]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'I': // Minimize button
+ if ((!button[ButtonMin]) && isMinimizable()) {
+ button[ButtonMin] =
+ new smoothblendButton(this, "minimize.png", i18n("Minimize"), ButtonMin, button_size);
+ connect(button[ButtonMin], SIGNAL(clicked()),
+ this, SLOT(minimize()));
+ layout->addWidget(button[ButtonMin]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'A': // Maximize button
+ if ((!button[ButtonMax]) && isMaximizable()) {
+ if (maximizeMode() == MaximizeFull) {
+ tip = i18n("Restore");
+ } else {
+ tip = i18n("Maximize");
+ }
+ button[ButtonMax] =
+ new smoothblendButton(this, "maximize.png", tip, ButtonMax, button_size, true);
+ connect(button[ButtonMax], SIGNAL(clicked()),
+ this, SLOT(maxButtonPressed()));
+ layout->addWidget(button[ButtonMax]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'X': // Close button
+ if ((!button[ButtonClose]) && isCloseable()) {
+ button[ButtonClose] =
+ new smoothblendButton(this, "close.png", i18n("Close"), ButtonClose, button_size);
+ connect(button[ButtonClose], SIGNAL(clicked()),
+ this, SLOT(closeWindow()));
+ layout->addWidget(button[ButtonClose]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'F': // Above button
+ if ((!button[ButtonAbove])) {
+ button[ButtonAbove] =
+ new smoothblendButton(this, "keep_above.png",
+ i18n("Keep Above Others"), ButtonAbove, button_size, true);
+ connect(button[ButtonAbove], SIGNAL(clicked()),
+ this, SLOT(aboveButtonPressed()));
+ layout->addWidget(button[ButtonAbove]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'B': // Below button
+ if ((!button[ButtonBelow])) {
+ button[ButtonBelow] =
+ new smoothblendButton(this, "keep_below.png",
+ i18n("Keep Below Others"), ButtonBelow, button_size, true);
+ connect(button[ButtonBelow], SIGNAL(clicked()),
+ this, SLOT(belowButtonPressed()));
+ layout->addWidget(button[ButtonBelow]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case 'L': // Shade button
+ if ((!button[ButtonShade]) && isShadeable()) {
+ if ( isSetShade()) {
+ tip = i18n("Unshade");
+ } else {
+ tip = i18n("Shade");
+ }
+ button[ButtonShade] =
+ new smoothblendButton(this, "shade.png", tip, ButtonShade, button_size, true);
+ connect(button[ButtonShade], SIGNAL(clicked()),
+ this, SLOT(shadeButtonPressed()));
+ layout->addWidget(button[ButtonShade]);
+ if (n < s.length()-1) layout->addSpacing(1);
+ }
+ break;
+
+ case '_': // Spacer item
+ layout->addSpacing(::factory->frameSize());
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// activeChange()
+// --------------
+// window active state has changed
+
+void smoothblendClient::activeChange() {
+ for (int n=0; n<ButtonTypeCount; n++)
+ if (button[n])
+ button[n]->reset();
+ widget()->repaint(false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// captionChange()
+// ---------------
+// The title has changed
+
+void smoothblendClient::captionChange() {
+ widget()->repaint(titlebar_->geometry(), false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// desktopChange()
+// ---------------
+// Called when desktop/sticky changes
+
+void smoothblendClient::desktopChange() {
+ bool d = isOnAllDesktops();
+ if (button[ButtonSticky]) {
+ QToolTip::remove(button[ButtonSticky]);
+ QToolTip::add(button[ButtonSticky], d ? i18n("Un-Sticky") : i18n("Sticky"));
+ button[ButtonSticky]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// iconChange()
+// ------------
+// The title has changed
+
+void smoothblendClient::iconChange() {
+ if (button[ButtonMenu]) {
+ button[ButtonMenu]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// maximizeChange()
+// ----------------
+// Maximized state has changed
+
+void smoothblendClient::maximizeChange() {
+ bool m = (maximizeMode() == MaximizeFull);
+ if (button[ButtonMax]) {
+ QToolTip::remove(button[ButtonMax]);
+ QToolTip::add(button[ButtonMax], m ? i18n("Restore") : i18n("Maximize"));
+ button[ButtonMax]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// shadeChange()
+// -------------
+// Called when window shading changes
+
+void smoothblendClient::shadeChange() {
+ bool s = isSetShade();
+ if (button[ButtonShade]) {
+ QToolTip::remove(button[ButtonShade]);
+ QToolTip::add(button[ButtonShade], s ? i18n("Unshade") : i18n("Shade"));
+ button[ButtonShade]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// keepAboveChange()
+// ------------
+// The above state has changed
+
+void smoothblendClient::keepAboveChange(bool a) {
+ if (button[ButtonAbove]) {
+ button[ButtonAbove]->setOn(a);
+ button[ButtonAbove]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// keepBelowChange()
+// ------------
+// The below state has changed
+
+void smoothblendClient::keepBelowChange(bool b) {
+ if (button[ButtonBelow]) {
+ button[ButtonBelow]->setOn(b);
+ button[ButtonBelow]->repaint(false);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// borders()
+// ----------
+// Get the size of the borders
+
+void smoothblendClient::borders(int &left, int &right, int &top, int &bottom) const {
+ int FRAMESIZE = ::factory->frameSize();
+
+ if ((maximizeMode()==MaximizeFull) && !options()->moveResizeMaximizedWindows()) {
+ left = right = bottom = 0;
+ top = ::factory->buttonSize();
+
+ // update layout etc.
+ topSpacer_->changeSize(1, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ decoSpacer_->changeSize(1, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ leftSpacer_->changeSize(left, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
+ leftTitleSpacer_->changeSize(left, top, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ rightSpacer_->changeSize(right, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
+ rightTitleSpacer_->changeSize(right, top, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ bottomSpacer_->changeSize(1, bottom, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ } else {
+ left = right = bottom = ::factory->frameSize();
+ top = ::factory->titleSize() + (FRAMESIZE*2);
+
+ // update layout etc.
+ topSpacer_->changeSize(1, FRAMESIZE, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ decoSpacer_->changeSize(1, FRAMESIZE, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ leftSpacer_->changeSize(left, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
+ leftTitleSpacer_->changeSize(left, s_titleHeight, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ rightSpacer_->changeSize(right, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
+ rightTitleSpacer_->changeSize(right,s_titleHeight,QSizePolicy::Fixed, QSizePolicy::Fixed);
+ bottomSpacer_->changeSize(1, bottom, QSizePolicy::Expanding, QSizePolicy::Fixed);
+ }
+ widget()->layout()->activate();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// resize()
+// --------
+// Called to resize the window
+
+void smoothblendClient::resize(const QSize &size) {
+ widget()->resize(size);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// minimumSize()
+// -------------
+// Return the minimum allowable size for this window
+
+QSize smoothblendClient::minimumSize() const {
+ return widget()->minimumSize();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mousePosition()
+// ---------------
+// Return logical mouse position
+
+KDecoration::Position smoothblendClient::mousePosition(const QPoint &point) const {
+ const int corner = 24;
+ Position pos;
+ int fs = ::factory->frameSize() + handlebar;
+ //int fs = ::factory->frameSize();
+
+ if (point.y() <= fs) {
+ // inside top frame
+ if (point.x() <= corner)
+ pos = PositionTopLeft;
+ else if (point.x() >= (width()-corner))
+ pos = PositionTopRight;
+ else
+ pos = PositionTop;
+ } else if (point.y() >= (height()-fs*2)) {
+ // inside handle
+ if (point.x() <= corner)
+ pos = PositionBottomLeft;
+ else if (point.x() >= (width()-corner))
+ pos = PositionBottomRight;
+ else
+ pos = PositionBottom;
+ } else if (point.x() <= fs ) {
+ // on left frame
+ if (point.y() <= corner)
+ pos = PositionTopLeft;
+ else if (point.y() >= (height()-corner))
+ pos = PositionBottomLeft;
+ else
+ pos = PositionLeft;
+ } else if (point.x() >= width()-fs) {
+ // on right frame
+ if (point.y() <= corner)
+ pos = PositionTopRight;
+ else if (point.y() >= (height()-corner))
+ pos = PositionBottomRight;
+ else
+ pos = PositionRight;
+ } else {
+ // inside the frame
+ pos = PositionCenter;
+ }
+ return pos;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eventFilter()
+// -------------
+// Event filter
+
+bool smoothblendClient::eventFilter(QObject *obj, QEvent *e) {
+ if (obj != widget())
+ return false;
+
+ switch (e->type()) {
+ case QEvent::MouseButtonDblClick: {
+ mouseDoubleClickEvent(static_cast<QMouseEvent *>(e));
+ return true;
+ }
+ case QEvent::MouseButtonPress: {
+ processMousePressEvent(static_cast<QMouseEvent *>(e));
+ return true;
+ }
+ case QEvent::Paint: {
+ paintEvent(static_cast<QPaintEvent *>(e));
+ return true;
+ }
+ case QEvent::Resize: {
+ resizeEvent(static_cast<QResizeEvent *>(e));
+ return true;
+ }
+ case QEvent::Show: {
+ showEvent(static_cast<QShowEvent *>(e));
+ return true;
+ }
+ case QEvent::Wheel: {
+ wheelEvent( static_cast< QWheelEvent* >( e ));
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// mouseDoubleClickEvent()
+// -----------------------
+// Doubleclick on title
+
+void smoothblendClient::mouseDoubleClickEvent(QMouseEvent *e) {
+ if (titlebar_->geometry().contains(e->pos()))
+ titlebarDblClickOperation();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// wheelEvent()
+// ------------
+// Mouse wheel on titlebar
+
+void smoothblendClient::wheelEvent(QWheelEvent *e)
+{
+ if (titleLayout_->geometry().contains(e->pos()) )
+ titlebarMouseWheelOperation( e->delta());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// paintEvent()
+// ------------
+// Repaint the window
+
+void smoothblendClient::paintEvent(QPaintEvent*) {
+ if (!::factory->initialized())
+ {
+ return;
+ }
+
+ //int FRAMESIZE = ::factory->frameSize();
+ const uint maxCaptionLength = 300; // truncate captions longer than this!
+ QString captionText(caption());
+ if (captionText.length() > maxCaptionLength) {
+ captionText.truncate(maxCaptionLength);
+ captionText.append(" [...]");
+ }
+
+ QColor blackColor(black);
+ QColor redColor(red);
+ QColorGroup group,widgetGroup;
+ QPainter painter(widget());
+ bool active = isActive();
+ //get group information first
+ group = options()->colorGroup(KDecoration::ColorTitleBar, isActive());
+ widgetGroup = widget()->colorGroup();
+
+ QRect topRect( topSpacer_->geometry() );
+ QRect titleRect( titleLayout_->geometry() );
+ QRect textRect( titlebar_->geometry() );
+ QRect Rltitle( leftTitleSpacer_->geometry() );
+ QRect Rrtitle( rightTitleSpacer_->geometry() );
+ QRect Rdeco( decoSpacer_->geometry() );
+ QRect Rleft( leftSpacer_->geometry() );
+ QRect Rright( rightSpacer_->geometry() );
+ QRect Rbottom( bottomSpacer_->geometry() );
+ QRect tempRect;
+
+
+ /*
+ if(active)
+ {
+ qDebug("paintEvent() topRect.y() = %i\tbottom() = %i",topRect.top(),topRect.bottom());
+ qDebug("paintEvent() titleRect.y() = %i\tbottom() = %i",titleRect.top(),titleRect.bottom());
+ qDebug("paintEvent() textRect.y() = %i\tbottom() = %i",textRect.top(),textRect.bottom());
+ qDebug("paintEvent() Rltitle.y() = %i\tbottom() = %i",Rltitle.top(),Rltitle.bottom());
+ qDebug("paintEvent() Rrtitle.y() = %i\tbottom() = %i",Rrtitle.top(),Rrtitle.bottom());
+ qDebug("paintEvent() Rdeco.y() = %i\tbottom() = %i",Rdeco.top(),Rdeco.bottom());
+ qDebug("paintEvent() Rleft.y() = %i\tbottom() = %i",Rleft.top(),Rleft.bottom());
+ qDebug("paintEvent() Rright.y() = %i\tbottom() = %i",Rright.top(),Rright.bottom());
+ qDebug("paintEvent() Rbottom.y() = %i\tbottom() = %i",Rbottom.top(),Rbottom.bottom());
+ }
+ */
+
+ // top
+ painter.drawTiledPixmap(topRect, active ? *aTitleBarTopTile:*iTitleBarTopTile);
+ painter.drawTiledPixmap(titleRect.x(),
+ titleRect.y(),
+ titleRect.width(),
+ titleRect.height() + Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+
+ textRect.setRect(textRect.x()+SIDETITLEMARGIN,
+ textRect.y(),
+ textRect.width()-SIDETITLEMARGIN*2,
+ textRect.height());
+ QRect shadowRect(textRect.x()+1,textRect.y()+1,textRect.width(),textRect.height());
+ //if we are shadowing title bar text
+ if(::factory->titleShadow())
+ {
+ //shadow text
+ painter.setFont(options()->font(isActive(), false));
+ painter.setPen(blackColor);
+ painter.drawText(shadowRect,
+ ::factory->titleAlign() | AlignVCenter | Qt::SingleLine,
+ captionText);
+ }
+ // draw title text
+ painter.setFont(options()->font(isActive(), false));
+ painter.setPen(options()->color(KDecoration::ColorFont, isActive()));
+ painter.drawText(textRect,
+ ::factory->titleAlign() | AlignVCenter | Qt::SingleLine,
+ captionText);
+
+ //left of buttons and title
+ painter.drawTiledPixmap(Rltitle.x(),
+ Rltitle.y(),
+ Rltitle.width(),
+ Rltitle.height()+Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+ // left mid layout
+ painter.fillRect(Rleft,widgetGroup.background());
+
+ // right of buttons and title
+ painter.drawTiledPixmap(Rrtitle.x(),
+ Rrtitle.y(),
+ Rrtitle.width(),
+ Rrtitle.height()+Rdeco.height(),
+ active ? *aTitleBarTile:*iTitleBarTile);
+ // right mid layout
+ painter.fillRect(Rright,widgetGroup.background());
+
+ // bottom
+ /*
+ if(isShade())
+ {
+ frame.setRect(0,::factory->titleSize()+FRAMESIZE, width(), FRAMESIZE);
+ }
+ else
+ {
+ frame.setRect(0, height() - (FRAMESIZE*2), width(), (FRAMESIZE*2));
+ }
+ */
+ painter.fillRect(Rbottom, widgetGroup.background());
+
+ //draw a line between title bar and window contents
+ painter.setPen(group.background());
+
+ // outline outside the frame but not the corners if they are rounded
+ tempRect = widget()->rect();
+ painter.drawRect(tempRect);
+
+ bool cornersFlag = ::factory->roundedCorners();
+ if(cornersFlag) {
+ // local temp right and bottom
+ int r(width());
+ painter.setPen(group.background());
+ painter.drawPoint(4, 1);
+ painter.drawPoint(3, 1);
+ painter.drawPoint(2, 2);
+ painter.drawPoint(1, 3);
+ painter.drawPoint(1, 4);
+ painter.drawPoint(r - 5, 1);
+ painter.drawPoint(r - 4, 1);
+ painter.drawPoint(r - 3, 2);
+ painter.drawPoint(r - 2, 3);
+ painter.drawPoint(r - 2, 4);
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// updateMask()
+// ------------
+// update the frame mask
+void smoothblendClient::updateMask() {
+ bool cornersFlag = ::factory->roundedCorners();
+ if ( (!options()->moveResizeMaximizedWindows() && maximizeMode() == MaximizeFull ) )
+ {
+ setMask(QRegion(widget()->rect()));
+ return;
+ }
+
+ int r(width());
+ int b(height());
+ QRegion mask;
+
+ mask=QRegion(widget()->rect());
+
+ // Remove top-left corner.
+ if(cornersFlag) {
+ mask -= QRegion(0, 0, 5, 1);
+ mask -= QRegion(0, 1, 3, 1);
+ mask -= QRegion(0, 2, 2, 1);
+ mask -= QRegion(0, 3, 1, 2);
+ mask -= QRegion(r - 5, 0, 5, 1);
+ mask -= QRegion(r - 3, 1, 3, 1);
+ mask -= QRegion(r - 2, 2, 2, 1);
+ mask -= QRegion(r - 1, 3, 1, 2);
+ }
+ //always remove one corner pixel so it simulates a soft corner like plastik
+ mask -= QRegion(0,0,1,1);
+ mask -= QRegion(r-1,0,1,1);
+ mask -= QRegion(0, b-1, 1,1);
+ mask -= QRegion(r-1,b-1,1,1);
+
+ setMask(mask);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// resizeEvent()
+// -------------
+// Window is being resized
+
+void smoothblendClient::resizeEvent(QResizeEvent *) {
+ if (widget()->isShown()) {
+ QRegion region = widget()->rect();
+ region = region.subtract(titlebar_->geometry());
+ widget()->erase(region);
+ updateMask();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// showEvent()
+// -----------
+// Window is being shown
+
+void smoothblendClient::showEvent(QShowEvent *) {
+ updateMask();
+ widget()->repaint();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// maxButtonPressed()
+// -----------------
+// Max button was pressed
+
+void smoothblendClient::maxButtonPressed() {
+ if (button[ButtonMax]) {
+#if KDE_IS_VERSION(3, 3, 0)
+ maximize(button[ButtonMax]->lastMousePress());
+#else
+
+ switch (button[ButtonMax]->lastMousePress()) {
+ case MidButton:
+ maximize(maximizeMode() ^ MaximizeVertical);
+ break;
+ case RightButton:
+ maximize(maximizeMode() ^ MaximizeHorizontal);
+ break;
+ default:
+ (maximizeMode() == MaximizeFull) ? maximize(MaximizeRestore)
+ : maximize(MaximizeFull);
+ }
+#endif
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// shadeButtonPressed()
+// -----------------
+// Shade button was pressed
+
+void smoothblendClient::shadeButtonPressed() {
+ if (button[ButtonShade]) {
+ setShade( !isSetShade());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// aboveButtonPressed()
+// -----------------
+// Above button was pressed
+
+void smoothblendClient::aboveButtonPressed() {
+ if (button[ButtonAbove]) {
+ setKeepAbove( !keepAbove());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// belowButtonPressed()
+// -----------------
+// Below button was pressed
+
+void smoothblendClient::belowButtonPressed() {
+ if (button[ButtonBelow]) {
+ setKeepBelow( !keepBelow());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// menuButtonPressed()
+// -------------------
+// Menu button was pressed (popup the menu)
+
+void smoothblendClient::menuButtonPressed() {
+ static QTime* t = NULL;
+ static smoothblendClient* lastClient = NULL;
+ if (t == NULL)
+ t = new QTime;
+ bool dbl = (lastClient==this && t->elapsed() <= QApplication::doubleClickInterval());
+ lastClient = this;
+ t->start();
+ //if (button[ButtonMenu] && !dbl && !::factory->menuClosed()) {
+ if ( !dbl || !::factory->menuClosed()) {
+ QPoint p(button[ButtonMenu]->rect().bottomLeft().x(),
+ button[ButtonMenu]->rect().bottomLeft().y());
+ KDecorationFactory* f = factory();
+ showWindowMenu(button[ButtonMenu]->mapToGlobal(p));
+ if (!f->exists(this))
+ return; // decoration was destroyed
+ button[ButtonMenu]->setDown(false);
+ }
+ else
+ {
+ closing = true;
+ }
+}
+
+void smoothblendClient::menuButtonReleased()
+{
+ if(closing)
+ {
+ closeWindow();
+ }
+}
+
+#include "smoothblend.moc"