summaryrefslogtreecommitdiffstats
path: root/kwin/lib
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/lib')
-rw-r--r--kwin/lib/Makefile.am20
-rw-r--r--kwin/lib/kcommondecoration.cpp966
-rw-r--r--kwin/lib/kcommondecoration.h367
-rw-r--r--kwin/lib/kdecoration.cpp444
-rw-r--r--kwin/lib/kdecoration.h887
-rw-r--r--kwin/lib/kdecoration_p.cpp235
-rw-r--r--kwin/lib/kdecoration_p.h111
-rw-r--r--kwin/lib/kdecoration_plugins_p.cpp199
-rw-r--r--kwin/lib/kdecoration_plugins_p.h77
-rw-r--r--kwin/lib/kdecorationfactory.cpp85
-rw-r--r--kwin/lib/kdecorationfactory.h120
11 files changed, 3511 insertions, 0 deletions
diff --git a/kwin/lib/Makefile.am b/kwin/lib/Makefile.am
new file mode 100644
index 000000000..bb584e25a
--- /dev/null
+++ b/kwin/lib/Makefile.am
@@ -0,0 +1,20 @@
+# FRAME libkwin???
+lib_LTLIBRARIES = libkdecorations.la
+
+libkdecorations_la_SOURCES = kdecoration.cpp kdecoration_p.cpp kdecoration_plugins_p.cpp \
+ kdecorationfactory.cpp kcommondecoration.cpp
+libkdecorations_la_LIBADD = $(LIB_KDECORE)
+libkdecorations_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined
+
+# FRAME
+include_HEADERS = kdecoration.h kdecoration_p.h kdecoration_plugins_p.h \
+ kdecorationfactory.h kcommondecoration.h
+
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+include ../../admin/Doxyfile.am
+
+messages: rc.cpp
+ $(XGETTEXT) `find . -name \*.cpp` -o $(podir)/kwin_lib.pot
+ -rm rc.cpp
diff --git a/kwin/lib/kcommondecoration.cpp b/kwin/lib/kcommondecoration.cpp
new file mode 100644
index 000000000..58a95b599
--- /dev/null
+++ b/kwin/lib/kcommondecoration.cpp
@@ -0,0 +1,966 @@
+/*
+ This file is part of the KDE project.
+
+ Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#include <qapplication.h>
+#include <qcursor.h>
+#include <qdatetime.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include <qwidget.h>
+
+#include <kdebug.h>
+
+#include <kapplication.h>
+#include <kdecorationfactory.h>
+#include <klocale.h>
+
+#include "kcommondecoration.h"
+#include "kcommondecoration.moc"
+
+KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
+ : KDecoration (bridge, factory),
+ m_previewWidget(0),
+ btnHideMinWidth(200),
+ btnHideLastWidth(0),
+ closing(false)
+{
+ // sizeof(...) is calculated at compile time
+ memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
+}
+
+KCommonDecoration::~KCommonDecoration()
+{
+ for (int n=0; n<NumButtons; n++) {
+ if (m_button[n]) delete m_button[n];
+ }
+ delete m_previewWidget;
+}
+
+bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const
+{
+ switch (behaviour) {
+ case DB_MenuClose:
+ return false;
+
+ case DB_WindowMask:
+ return false;
+
+ case DB_ButtonHide:
+ return true;
+ }
+
+ return false;
+}
+
+int KCommonDecoration::layoutMetric(LayoutMetric lm, bool, const KCommonDecorationButton *) const
+{
+ switch (lm) {
+ case LM_BorderLeft:
+ case LM_BorderRight:
+ case LM_BorderBottom:
+ case LM_TitleEdgeTop:
+ case LM_TitleEdgeBottom:
+ case LM_TitleEdgeLeft:
+ case LM_TitleEdgeRight:
+ case LM_TitleBorderLeft:
+ case LM_TitleBorderRight:
+ return 5;
+
+
+ case LM_ButtonWidth:
+ case LM_ButtonHeight:
+ case LM_TitleHeight:
+ return 20;
+
+ case LM_ButtonSpacing:
+ return 5;
+
+ case LM_ButtonMarginTop:
+ return 0;
+
+ case LM_ExplicitButtonSpacer:
+ return 5;
+
+ default:
+ return 0;
+ }
+}
+
+void KCommonDecoration::init()
+{
+ createMainWidget(WNoAutoErase);
+
+ // for flicker-free redraws
+ widget()->setBackgroundMode(NoBackground);
+
+ widget()->installEventFilter( this );
+
+ resetLayout();
+
+ connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
+ connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
+
+ updateCaption();
+}
+
+void KCommonDecoration::reset( unsigned long changed )
+{
+ if (changed & SettingButtons) {
+ resetLayout();
+ widget()->update();
+ }
+}
+
+QRegion KCommonDecoration::cornerShape(WindowCorner)
+{
+ return QRegion();
+}
+
+void KCommonDecoration::updateCaption()
+{
+ // This should be reimplemented in decorations for better efficiency
+ widget()->update();
+}
+
+void KCommonDecoration::borders( int& left, int& right, int& top, int& bottom ) const
+{
+ left = layoutMetric(LM_BorderLeft);
+ right = layoutMetric(LM_BorderRight);
+ bottom = layoutMetric(LM_BorderBottom);
+ top = layoutMetric(LM_TitleHeight) +
+ layoutMetric(LM_TitleEdgeTop) +
+ layoutMetric(LM_TitleEdgeBottom);
+
+ updateLayout(); // TODO!! don't call everytime we are in ::borders
+}
+
+void KCommonDecoration::updateLayout() const
+{
+ QRect r = widget()->rect();
+ int r_x, r_y, r_x2, r_y2;
+ r.coords(&r_x, &r_y, &r_x2, &r_y2);
+
+ // layout preview widget
+ if (m_previewWidget) {
+ const int borderLeft = layoutMetric(LM_BorderLeft);
+ const int borderRight = layoutMetric(LM_BorderRight);
+ const int borderBottom = layoutMetric(LM_BorderBottom);
+ const int titleHeight = layoutMetric(LM_TitleHeight);
+ const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
+ const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
+
+ int left = r_x+borderLeft;
+ int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
+ int width = r_x2-borderRight-left+1;
+ int height = r_y2-borderBottom-top+1;
+ m_previewWidget->setGeometry(left, top, width, height);
+ moveWidget(left,top, m_previewWidget);
+ resizeWidget(width, height, m_previewWidget);
+ }
+
+ // resize buttons...
+ for (int n=0; n<NumButtons; n++) {
+ if (m_button[n]) {
+ QSize newSize = QSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
+ layoutMetric(LM_ButtonHeight, true, m_button[n]) );
+ if (newSize != m_button[n]->size() )
+ m_button[n]->setSize(newSize);
+ }
+ }
+
+ // layout buttons
+ int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
+ if (m_buttonsLeft.count() > 0) {
+ const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
+ int x = r_x + layoutMetric(LM_TitleEdgeLeft);
+ for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
+ bool elementLayouted = false;
+ if (*it) {
+ if (!(*it)->isHidden() ) {
+ moveWidget(x,y, *it);
+ x += layoutMetric(LM_ButtonWidth, true, ::qt_cast<KCommonDecorationButton*>(*it) );
+ elementLayouted = true;
+ }
+ } else {
+ x+= layoutMetric(LM_ExplicitButtonSpacer);
+ elementLayouted = true;
+ }
+ if (elementLayouted && it != m_buttonsLeft.end() )
+ x += buttonSpacing;
+ }
+ }
+
+ if (m_buttonsRight.count() > 0) {
+ const int titleEdgeRightLeft = r_x2-layoutMetric(LM_TitleEdgeRight)+1;
+
+ const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
+ int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
+ for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
+ bool elementLayouted = false;
+ if (*it) {
+ if (!(*it)->isHidden() ) {
+ moveWidget(x,y, *it);
+ x += layoutMetric(LM_ButtonWidth, true, ::qt_cast<KCommonDecorationButton*>(*it) );;
+ elementLayouted = true;
+ }
+ } else {
+ x += layoutMetric(LM_ExplicitButtonSpacer);
+ elementLayouted = true;
+ }
+ if (elementLayouted && it != m_buttonsRight.end() )
+ x += buttonSpacing;
+ }
+ }
+}
+
+void KCommonDecoration::updateButtons() const
+{
+ for (int n=0; n<NumButtons; n++)
+ if (m_button[n]) m_button[n]->update();
+}
+
+void KCommonDecoration::resetButtons() const
+{
+ for (int n=0; n<NumButtons; n++)
+ if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
+}
+
+void KCommonDecoration::resetLayout()
+{
+ for (int n=0; n<NumButtons; n++) {
+ if (m_button[n]) {
+ delete m_button[n];
+ m_button[n] = 0;
+ }
+ }
+ m_buttonsLeft.clear();
+ m_buttonsRight.clear();
+
+ delete m_previewWidget;
+ m_previewWidget = 0;
+
+ // shown instead of the window contents in decoration previews
+ if(isPreview() ) {
+ m_previewWidget = new QLabel(i18n("%1 is the name of window decoration style", "<center><b>%1 preview</b></center>").arg(visibleName() ), widget());
+ m_previewWidget->show();
+ }
+
+ addButtons(m_buttonsLeft,
+ options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
+ true);
+ addButtons(m_buttonsRight,
+ options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
+ false);
+
+ updateLayout();
+
+ const int minTitleBarWidth = 35;
+ btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,true) + buttonContainerWidth(m_buttonsRight,true) +
+ layoutMetric(LM_TitleEdgeLeft,false) + layoutMetric(LM_TitleEdgeRight,false) +
+ layoutMetric(LM_TitleBorderLeft,false) + layoutMetric(LM_TitleBorderRight,false) +
+ minTitleBarWidth;
+ btnHideLastWidth = 0;
+}
+
+int KCommonDecoration::buttonsLeftWidth() const
+{
+ return buttonContainerWidth(m_buttonsLeft);
+}
+
+int KCommonDecoration::buttonsRightWidth() const
+{
+ return buttonContainerWidth(m_buttonsRight);
+}
+
+int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
+{
+ int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
+
+ int shownElementsCount = 0;
+
+ int w = 0;
+ for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
+ if (*it) {
+ if (countHidden || !(*it)->isHidden() ) {
+ w += (*it)->width();
+ ++shownElementsCount;
+ }
+ } else {
+ w += explicitSpacer;
+ ++shownElementsCount;
+ }
+ }
+ w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
+
+ return w;
+}
+
+void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
+{
+ if (s.length() > 0) {
+ for (unsigned n=0; n < s.length(); n++) {
+ KCommonDecorationButton *btn = 0;
+ switch (s[n]) {
+ case 'M': // Menu button
+ if (!m_button[MenuButton]){
+ btn = createButton(MenuButton);
+ if (!btn) break;
+ btn->setTipText(i18n("Menu") );
+ btn->setRealizeButtons(LeftButton|RightButton);
+ connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
+ connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
+
+ m_button[MenuButton] = btn;
+ }
+ break;
+ case 'S': // OnAllDesktops button
+ if (!m_button[OnAllDesktopsButton]){
+ btn = createButton(OnAllDesktopsButton);
+ if (!btn) break;
+ const bool oad = isOnAllDesktops();
+ btn->setTipText(oad?i18n("Not on all desktops"):i18n("On all desktops") );
+ btn->setToggleButton(true);
+ btn->setOn( oad );
+ connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
+
+ m_button[OnAllDesktopsButton] = btn;
+ }
+ break;
+ case 'H': // Help button
+ if ((!m_button[HelpButton]) && providesContextHelp()){
+ btn = createButton(HelpButton);
+ if (!btn) break;
+ btn->setTipText(i18n("Help") );
+ connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
+
+ m_button[HelpButton] = btn;
+ }
+ break;
+ case 'I': // Minimize button
+ if ((!m_button[MinButton]) && isMinimizable()){
+ btn = createButton(MinButton);
+ if (!btn) break;
+ btn->setTipText(i18n("Minimize") );
+ connect(btn, SIGNAL(clicked()), SLOT(minimize()));
+
+ m_button[MinButton] = btn;
+ }
+ break;
+ case 'A': // Maximize button
+ if ((!m_button[MaxButton]) && isMaximizable()){
+ btn = createButton(MaxButton);
+ if (!btn) break;
+ btn->setRealizeButtons(LeftButton|MidButton|RightButton);
+ const bool max = maximizeMode()==MaximizeFull;
+ btn->setTipText(max?i18n("Restore"):i18n("Maximize") );
+ btn->setToggleButton(true);
+ btn->setOn( max );
+ connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
+
+ m_button[MaxButton] = btn;
+ }
+ break;
+ case 'X': // Close button
+ if ((!m_button[CloseButton]) && isCloseable()){
+ btn = createButton(CloseButton);
+ if (!btn) break;
+ btn->setTipText(i18n("Close") );
+ connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
+
+ m_button[CloseButton] = btn;
+ }
+ break;
+ case 'F': // AboveButton button
+ if (!m_button[AboveButton]){
+ btn = createButton(AboveButton);
+ if (!btn) break;
+ bool above = keepAbove();
+ btn->setTipText(above?i18n("Do not keep above others"):i18n("Keep above others") );
+ btn->setToggleButton(true);
+ btn->setOn( above );
+ connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
+
+ m_button[AboveButton] = btn;
+ }
+ break;
+ case 'B': // BelowButton button
+ if (!m_button[BelowButton]){
+ btn = createButton(BelowButton);
+ if (!btn) break;
+ bool below = keepBelow();
+ btn->setTipText(below?i18n("Do not keep below others"):i18n("Keep below others") );
+ btn->setToggleButton(true);
+ btn->setOn( below );
+ connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
+
+ m_button[BelowButton] = btn;
+ }
+ break;
+ case 'L': // Shade button
+ if ((!m_button[ShadeButton]) && isShadeable()){
+ btn = createButton(ShadeButton);
+ if (!btn) break;
+ bool shaded = isSetShade();
+ btn->setTipText(shaded?i18n("Unshade"):i18n("Shade") );
+ btn->setToggleButton(true);
+ btn->setOn( shaded );
+ connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
+
+ m_button[ShadeButton] = btn;
+ }
+ break;
+ case '_': // Spacer item
+ btnContainer.append(0);
+ }
+
+
+ if (btn) {
+ btn->setLeft(isLeft);
+ btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) );
+ btn->show();
+ btnContainer.append(btn);
+ }
+
+ }
+ }
+}
+
+void KCommonDecoration::calcHiddenButtons()
+{
+ if (width() == btnHideLastWidth)
+ return;
+
+ btnHideLastWidth = width();
+
+ //Hide buttons in the following order:
+ KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
+ m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
+ m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
+ const int buttonsCount = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
+
+ int current_width = width();
+ int count = 0;
+
+ // Hide buttons
+ while (current_width < btnHideMinWidth && count < buttonsCount)
+ {
+ if (btnArray[count] ) {
+ current_width += btnArray[count]->width();
+ if (btnArray[count]->isVisible() )
+ btnArray[count]->hide();
+ }
+ count++;
+ }
+ // Show the rest of the buttons...
+ for(int i = count; i < buttonsCount; i++)
+ {
+ if (btnArray[i] ) {
+
+ if (! btnArray[i]->isHidden() )
+ break; // all buttons shown...
+
+ btnArray[i]->show();
+ }
+ }
+}
+
+void KCommonDecoration::show()
+{
+ if (decorationBehaviour(DB_ButtonHide) )
+ calcHiddenButtons();
+ widget()->show();
+}
+
+void KCommonDecoration::resize( const QSize& s )
+{
+ widget()->resize( s );
+}
+
+QSize KCommonDecoration::minimumSize() const
+{
+ const int minWidth = QMAX(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
+ +QMAX(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
+ +layoutMetric(LM_TitleBorderLeft)+layoutMetric(LM_TitleBorderRight);
+ return QSize(minWidth,
+ layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)
+ +layoutMetric(LM_TitleEdgeBottom)
+ +layoutMetric(LM_BorderBottom) );
+}
+
+void KCommonDecoration::maximizeChange()
+{
+ if( m_button[MaxButton] ) {
+ m_button[MaxButton]->setOn( maximizeMode()==MaximizeFull);
+ m_button[MaxButton]->setTipText( (maximizeMode()!=MaximizeFull) ?
+ i18n("Maximize")
+ : i18n("Restore"));
+ m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
+ }
+ updateWindowShape();
+ widget()->update();
+}
+
+void KCommonDecoration::desktopChange()
+{
+ if ( m_button[OnAllDesktopsButton] ) {
+ m_button[OnAllDesktopsButton]->setOn( isOnAllDesktops() );
+ m_button[OnAllDesktopsButton]->setTipText( isOnAllDesktops() ?
+ i18n("Not on all desktops")
+ : i18n("On all desktops"));
+ m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
+ }
+}
+
+void KCommonDecoration::shadeChange()
+{
+ if ( m_button[ShadeButton] ) {
+ bool shaded = isSetShade();
+ m_button[ShadeButton]->setOn( shaded );
+ m_button[ShadeButton]->setTipText( shaded ?
+ i18n("Unshade")
+ : i18n("Shade"));
+ m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
+ }
+}
+
+void KCommonDecoration::iconChange()
+{
+ if (m_button[MenuButton])
+ {
+ m_button[MenuButton]->update();
+ m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
+ }
+}
+
+void KCommonDecoration::activeChange()
+{
+ updateButtons();
+ widget()->update(); // do something similar to updateCaption here
+}
+
+void KCommonDecoration::captionChange()
+{
+ updateCaption();
+}
+
+void KCommonDecoration::keepAboveChange(bool above)
+{
+ if (m_button[AboveButton])
+ {
+ m_button[AboveButton]->setOn(above);
+ m_button[AboveButton]->setTipText( above?i18n("Do not keep above others"):i18n("Keep above others") );
+ m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
+ }
+
+ if (m_button[BelowButton] && m_button[BelowButton]->isOn())
+ {
+ m_button[BelowButton]->setOn(false);
+ m_button[BelowButton]->setTipText( i18n("Keep below others") );
+ m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
+ }
+}
+
+void KCommonDecoration::keepBelowChange(bool below)
+{
+ if (m_button[BelowButton])
+ {
+ m_button[BelowButton]->setOn(below);
+ m_button[BelowButton]->setTipText( below?i18n("Do not keep below others"):i18n("Keep below others") );
+ m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
+ }
+
+ if (m_button[AboveButton] && m_button[AboveButton]->isOn())
+ {
+ m_button[AboveButton]->setOn(false);
+ m_button[AboveButton]->setTipText( i18n("Keep above others") );
+ m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
+ }
+}
+
+void KCommonDecoration::slotMaximize()
+{
+ if (m_button[MaxButton])
+ {
+ maximize(m_button[MaxButton]->lastMousePress() );
+ }
+}
+
+void KCommonDecoration::slotShade()
+{
+ setShade( !isSetShade() );
+}
+
+void KCommonDecoration::slotKeepAbove()
+{
+ setKeepAbove(!keepAbove() );
+}
+
+void KCommonDecoration::slotKeepBelow()
+{
+ setKeepBelow(!keepBelow() );
+}
+
+void KCommonDecoration::menuButtonPressed()
+{
+ static QTime* t = NULL;
+ static KCommonDecoration* lastClient = NULL;
+ if (t == NULL)
+ t = new QTime;
+ bool dbl = (lastClient==this && t->elapsed() <= QApplication::doubleClickInterval());
+ lastClient = this;
+ t->start();
+ if (!dbl || !decorationBehaviour(DB_MenuClose) ) {
+ QRect menuRect = m_button[MenuButton]->rect();
+ QPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
+ QPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+QPoint(0,2);
+ KDecorationFactory* f = factory();
+ showWindowMenu(QRect(menutop, menubottom));
+ if( !f->exists( this )) // 'this' was deleted
+ return;
+ m_button[MenuButton]->setDown(false);
+ }
+ else
+ closing = true;
+}
+
+void KCommonDecoration::menuButtonReleased()
+{
+ if(closing)
+ closeWindow();
+}
+
+void KCommonDecoration::resizeEvent(QResizeEvent */*e*/)
+{
+ if (decorationBehaviour(DB_ButtonHide) )
+ calcHiddenButtons();
+
+ updateLayout();
+
+ updateWindowShape();
+ // FIXME: don't update() here! this would result in two paintEvent()s
+ // because there is already "something" else triggering the repaint...
+// widget()->update();
+}
+
+void KCommonDecoration::moveWidget(int x, int y, QWidget *widget) const
+{
+ QPoint p = widget->pos();
+ int oldX = p.y();
+ int oldY = p.x();
+
+ if (x!=oldX || y!=oldY)
+ widget->move(x,y);
+}
+
+void KCommonDecoration::resizeWidget(int w, int h, QWidget *widget) const
+{
+ QSize s = widget->size();
+ int oldW = s.width();
+ int oldH = s.height();
+
+ if (w!=oldW || h!=oldH)
+ widget->resize(w,h);
+}
+
+void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if( e->button() != LeftButton )
+ return;
+
+ int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
+ // when shaded, react on double clicks everywhere to make it easier to unshade. otherwise
+ // react only on double clicks in the title bar region...
+ if (isSetShade() || e->pos().y() <= tb )
+ titlebarDblClickOperation();
+}
+
+void KCommonDecoration::wheelEvent(QWheelEvent *e)
+{
+ int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
+ if (isSetShade() || e->pos().y() <= tb )
+ titlebarMouseWheelOperation( e->delta());
+}
+
+KCommonDecoration::Position KCommonDecoration::mousePosition(const QPoint &point) const
+{
+ const int corner = 18+3*layoutMetric(LM_BorderBottom, false)/2;
+ Position pos = PositionCenter;
+
+ QRect r = widget()->rect();
+ int r_x, r_y, r_x2, r_y2;
+ r.coords(&r_x, &r_y, &r_x2, &r_y2);
+ int p_x = point.x();
+ int p_y = point.y();
+ const int borderLeft = layoutMetric(LM_BorderLeft);
+// const int borderRight = layoutMetric(LM_BorderRight);
+ const int borderBottom = layoutMetric(LM_BorderBottom);
+ const int titleHeight = layoutMetric(LM_TitleHeight);
+ const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
+ const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
+ const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
+ const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
+
+ const int borderBottomTop = r_y2-borderBottom+1;
+ const int borderLeftRight = r_x+borderLeft-1;
+// const int borderRightLeft = r_x2-borderRight+1;
+ const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
+ const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
+ const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
+ const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
+
+ if (p_y <= titleEdgeTopBottom) {
+ if (p_x <= r_x+corner)
+ pos = PositionTopLeft;
+ else if (p_x >= r_x2-corner)
+ pos = PositionTopRight;
+ else
+ pos = PositionTop;
+ } else if (p_y <= titleEdgeBottomBottom) {
+ if (p_x <= titleEdgeLeftRight)
+ pos = PositionTopLeft;
+ else if (p_x >= titleEdgeRightLeft)
+ pos = PositionTopRight;
+ else
+ pos = PositionCenter; // title bar
+ } else if (p_y < borderBottomTop) {
+ if (p_y < r_y2-corner) {
+ if (p_x <= borderLeftRight)
+ pos = PositionLeft;
+ else
+ pos = PositionRight;
+ } else {
+ if (p_x <= borderLeftRight)
+ pos = PositionBottomLeft;
+ else
+ pos = PositionBottomRight;
+ }
+ } else if(p_y >= borderBottomTop) {
+ if (p_x <= r_x+corner)
+ pos = PositionBottomLeft;
+ else if (p_x >= r_x2-corner)
+ pos = PositionBottomRight;
+ else
+ pos = PositionBottom;
+ }
+
+ return pos;
+}
+
+void KCommonDecoration::updateWindowShape()
+{
+ // don't mask the widget...
+ if (!decorationBehaviour(DB_WindowMask) )
+ return;
+
+ int w = widget()->width();
+ int h = widget()->height();
+
+ bool tl=true,tr=true,bl=true,br=true; // is there a transparent rounded corner in top-left? etc
+
+ QDesktopWidget *desktop=KApplication::desktop();
+ // no transparent rounded corners if this window corner lines up with a screen corner
+ for(int screen=0; screen < desktop->numScreens(); ++screen)
+ {
+ QRect fullscreen(desktop->screenGeometry(screen));
+ QRect window = geometry();
+
+ if(window.topLeft() == fullscreen.topLeft() ) tl = false;
+ if(window.topRight() == fullscreen.topRight() ) tr = false;
+ if(window.bottomLeft() == fullscreen.bottomLeft() ) bl = false;
+ if(window.bottomRight()== fullscreen.bottomRight() ) br = false;
+ }
+
+ QRegion mask(0, 0, w, h);
+
+ // Remove top-left corner.
+ if(tl)
+ {
+ mask -= cornerShape(WC_TopLeft);
+ }
+ // Remove top-right corner.
+ if(tr)
+ {
+ mask -= cornerShape(WC_TopRight);
+ }
+ // Remove top-left corner.
+ if(bl)
+ {
+ mask -= cornerShape(WC_BottomLeft);
+ }
+ // Remove top-right corner.
+ if(br)
+ {
+ mask -= cornerShape(WC_BottomRight);
+ }
+
+ setMask( mask );
+}
+
+bool KCommonDecoration::eventFilter( QObject* o, QEvent* e )
+{
+ if( o != widget())
+ return false;
+ switch( e->type())
+ {
+ case QEvent::Resize:
+ resizeEvent(static_cast<QResizeEvent*>(e) );
+ return true;
+ case QEvent::Paint:
+ paintEvent( static_cast< QPaintEvent* >( e ));
+ return true;
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
+ return true;
+ case QEvent::MouseButtonPress:
+ processMousePressEvent( static_cast< QMouseEvent* >( e ));
+ return true;
+ case QEvent::Wheel:
+ wheelEvent( static_cast< QWheelEvent* >( e ));
+ return true;
+ default:
+ return false;
+ }
+}
+
+const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
+ | NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
+ | NET::UtilityMask | NET::SplashMask;
+
+bool KCommonDecoration::isToolWindow() const
+{
+ NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
+ return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
+}
+
+QRect KCommonDecoration::titleRect() const
+{
+ int r_x, r_y, r_x2, r_y2;
+ widget()->rect().coords(&r_x, &r_y, &r_x2, &r_y2);
+ const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
+ const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
+ const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
+ const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
+ const int titleBorderLeft = layoutMetric(LM_TitleBorderLeft);
+ const int titleBorderRight = layoutMetric(LM_TitleBorderRight);
+ const int ttlHeight = layoutMetric(LM_TitleHeight);
+ const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
+ return QRect(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft, r_y+titleEdgeTop,
+ r_x2-titleEdgeRight-buttonsRightWidth()-titleBorderRight-(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft),
+ titleEdgeBottomBottom-(r_y+titleEdgeTop) );
+}
+
+
+KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent, const char *name)
+ : QButton(parent->widget(), name),
+ m_decoration(parent),
+ m_type(type),
+ m_realizeButtons(LeftButton),
+ m_lastMouse(NoButton),
+ m_isLeft(true)
+{
+ setCursor(ArrowCursor);
+}
+
+KCommonDecorationButton::~KCommonDecorationButton()
+{
+}
+
+KCommonDecoration *KCommonDecorationButton::decoration() const
+{
+ return m_decoration;
+}
+
+ButtonType KCommonDecorationButton::type() const
+{
+ return m_type;
+}
+
+bool KCommonDecorationButton::isLeft() const
+{
+ return m_isLeft;
+}
+
+void KCommonDecorationButton::setLeft(bool left)
+{
+ m_isLeft = left;
+}
+
+void KCommonDecorationButton::setRealizeButtons(int btns)
+{
+ m_realizeButtons = btns;
+}
+
+void KCommonDecorationButton::setSize(const QSize &s)
+{
+ if (!m_size.isValid() || s != size() ) {
+ m_size = s;
+
+ setFixedSize(m_size);
+ reset(SizeChange);
+ }
+}
+
+QSize KCommonDecorationButton::sizeHint() const
+{
+ return m_size;
+}
+
+void KCommonDecorationButton::setTipText(const QString &tip) {
+ QToolTip::remove(this );
+ QToolTip::add(this, tip );
+}
+
+void KCommonDecorationButton::setToggleButton(bool toggle)
+{
+ QButton::setToggleButton(toggle);
+ reset(ToggleChange);
+}
+
+void KCommonDecorationButton::setOn(bool on)
+{
+ if (on != isOn() ) {
+ QButton::setOn(on);
+ reset(StateChange);
+ }
+}
+
+void KCommonDecorationButton::mousePressEvent(QMouseEvent* e)
+{
+ m_lastMouse = e->button();
+ // pass on event after changing button to LeftButton
+ QMouseEvent me(e->type(), e->pos(), e->globalPos(),
+ (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
+
+ QButton::mousePressEvent(&me);
+}
+
+void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent* e)
+{
+ m_lastMouse = e->button();
+ // pass on event after changing button to LeftButton
+ QMouseEvent me(e->type(), e->pos(), e->globalPos(),
+ (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
+
+ QButton::mouseReleaseEvent(&me);
+}
diff --git a/kwin/lib/kcommondecoration.h b/kwin/lib/kcommondecoration.h
new file mode 100644
index 000000000..9495cf148
--- /dev/null
+++ b/kwin/lib/kcommondecoration.h
@@ -0,0 +1,367 @@
+/*
+ This file is part of the KDE project.
+
+ Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef KCOMMONDECORATION_H
+#define KCOMMONDECORATION_H
+
+#include <qbutton.h>
+#include <qvaluevector.h>
+
+#include "kdecoration.h"
+
+class KDecorationBridge;
+class KDecorationFactory;
+
+enum ButtonType {
+ HelpButton=0,
+ MaxButton,
+ MinButton,
+ CloseButton,
+ MenuButton,
+ OnAllDesktopsButton,
+ AboveButton,
+ BelowButton,
+ ShadeButton,
+ NumButtons
+};
+
+class KCommonDecorationButton;
+
+class KCommonDecorationButtonPrivate;
+class KCommonDecorationPrivate;
+
+/**
+ * This class eases development of decorations by implementing parts of KDecoration
+ * which are error prone and common for most decorations.
+ * It takes care of the window layout, button/action handling, and window mask creation.
+ */
+class KWIN_EXPORT KCommonDecoration : public KDecoration
+{
+ Q_OBJECT
+
+ public:
+ KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory);
+ virtual ~KCommonDecoration();
+
+ /**
+ * Used to calculate the decoration layout. The basic layout looks like this:
+ *
+ * Window:
+ * _______________________________________________________________
+ * | LM_TitleEdgeTop |
+ * |_______________________________________________________________|
+ * | LM_TitleEdgeLeft | [title] | LM_TitleEdgeRight |
+ * |__________________|________________________|___________________|
+ * | LM_TitleEdgeBottom |
+ * |_______________________________________________________________|
+ * | | | |
+ * | | | |
+ * | | | |
+ * |LM_BorderLeft LM_BorderRight|
+ * |_|___________________________________________________________|_|
+ * | LM_BorderBottom |
+ * |_______________________________________________________________|
+ *
+ * Title:
+ * ___________________________________________________________________________________
+ * | LM_ButtonMarginTop | | LM_ButtonMarginTop |
+ * |________________________________| |_________________________________|
+ * | [Buttons] | LM_TitleBorderLeft | LM_TitleHeight | LM_TitleBorderRight | [Buttons] |
+ * |___________|____________________|________________|_____________________|___________|
+ *
+ * Buttons:
+ * _____________________________________________________________________________________________
+ * | button | spacing | button | spacing | explicit spacer | spacing | ... | spacing | button |
+ * |________|_________|________|_________|_________________|_________|________|_________|________|
+ *
+ * @see layoutMetric()
+ */
+ enum LayoutMetric
+ {
+ LM_BorderLeft,
+ LM_BorderRight,
+ LM_BorderBottom,
+ LM_TitleHeight,
+ LM_TitleBorderLeft,
+ LM_TitleBorderRight,
+ LM_TitleEdgeLeft,
+ LM_TitleEdgeRight,
+ LM_TitleEdgeTop,
+ LM_TitleEdgeBottom,
+ LM_ButtonWidth,
+ LM_ButtonHeight,
+ LM_ButtonSpacing,
+ LM_ExplicitButtonSpacer,
+ LM_ButtonMarginTop
+ };
+
+ enum DecorationBehaviour
+ {
+ DB_MenuClose, ///< Close window on double clicking the menu
+ DB_WindowMask, ///< Set a mask on the window
+ DB_ButtonHide ///< Hide buttons when there is not enough space in the titlebar
+ };
+
+ enum WindowCorner
+ {
+ WC_TopLeft,
+ WC_TopRight,
+ WC_BottomLeft,
+ WC_BottomRight
+ };
+
+ /**
+ * The name of the decoration used in the decoration preview.
+ */
+ virtual QString visibleName() const = 0;
+ /**
+ * The default title button order on the left.
+ * @see KDecoration::titleButtonsLeft()
+ * @see KDecoration::titleButtonsRight()
+ */
+ virtual QString defaultButtonsLeft() const = 0;
+ /**
+ * The default title button order on the left.
+ * @see KDecoration::titleButtonsLeft()
+ * @see KDecoration::titleButtonsRight()
+ */
+ virtual QString defaultButtonsRight() const = 0;
+
+ /**
+ * This controls whether some specific behaviour should be enabled or not.
+ * @see DecorationBehaviour
+ */
+ virtual bool decorationBehaviour(DecorationBehaviour behaviour) const;
+
+ /**
+ * This controls the layout of the decoration in various ways. It is
+ * possible to have a different layout for different window states.
+ * @param lm The layout element.
+ * @param respectWindowState Whether window states should be taken into account or a "default" state should be assumed.
+ * @param button For LM_ButtonWidth and LM_ButtonHeight, the button.
+ */
+ virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton *button = 0) const;
+
+ /**
+ * Create a new title bar button. KCommonDecoration takes care of memory management.
+ * @return a pointer to the button, or 0 if the button should not be created.
+ */
+ virtual KCommonDecorationButton *createButton(ButtonType type) = 0;
+
+ /**
+ * @return the mask for the specific window corner.
+ */
+ virtual QRegion cornerShape(WindowCorner corner);
+
+ /**
+ * This updates the window mask using the information provided by
+ * cornerShape(). Edges which are aligned to screen corners are not
+ * shaped for better usability (remember to paint these areas in paintEvent(), too).
+ * You normally don't want/need to reimplement updateWindowShape().
+ * @see cornerShape()
+ */
+ virtual void updateWindowShape();
+
+ /**
+ * Draw the window decoration.
+ */
+ virtual void paintEvent(QPaintEvent *e) = 0;
+
+ /**
+ * This is used to update the painting of the title bar after the caption has been changed.
+ * Reimplement for a more efficient implementation (default calls update() on the whole decoration).
+ */
+ virtual void updateCaption();
+
+ int buttonsLeftWidth() const;
+ int buttonsRightWidth() const;
+
+ /**
+ * TODO: remove?
+ */
+ void updateLayout() const;
+ /**
+ * Makes sure all buttons are repainted.
+ */
+ void updateButtons() const;
+ /**
+ * Manually call reset() on each button.
+ */
+ void resetButtons() const;
+
+ /**
+ * Convenience method.
+ * @returns true if the window type is NET::Toolbar, NET::Utility, or NET::Menu
+ */
+ bool isToolWindow() const;
+ /**
+ * Convenience method.
+ * @returns the title rect.
+ */
+ QRect titleRect() const;
+
+ public:
+ /**
+ * Handles widget and layout creation, call the base implementation when subclassing this member.
+ */
+ virtual void init();
+ /**
+ * Handles SettingButtons, call the base implementation when subclassing this member.
+ */
+ virtual void reset( unsigned long changed );
+ virtual void borders( int& left, int& right, int& top, int& bottom ) const;
+ virtual void show();
+ virtual void resize(const QSize& s);
+ virtual QSize minimumSize() const;
+ virtual void maximizeChange();
+ virtual void desktopChange();
+ virtual void shadeChange();
+ virtual void iconChange();
+ virtual void activeChange();
+ virtual void captionChange();
+ public slots:
+ void keepAboveChange(bool above);
+ void keepBelowChange(bool below);
+ void slotMaximize();
+ void slotShade();
+ void slotKeepAbove();
+ void slotKeepBelow();
+ void menuButtonPressed();
+ void menuButtonReleased();
+ public:
+ virtual Position mousePosition(const QPoint &point) const;
+
+ virtual bool eventFilter( QObject* o, QEvent* e );
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void wheelEvent(QWheelEvent *e);
+
+ private:
+ void resetLayout();
+
+ void moveWidget(int x, int y, QWidget *widget) const;
+ void resizeWidget(int w, int h, QWidget *widget) const;
+
+ typedef QValueVector <KCommonDecorationButton*> ButtonContainer; ///< If the entry is 0, it's a spacer.
+ int buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden = false) const;
+ void addButtons(ButtonContainer &btnContainer, const QString& buttons, bool isLeft);
+
+ KCommonDecorationButton *m_button[NumButtons];
+
+ ButtonContainer m_buttonsLeft;
+ ButtonContainer m_buttonsRight;
+
+ QWidget *m_previewWidget;
+
+ // button hiding for small windows
+ void calcHiddenButtons();
+ int btnHideMinWidth;
+ int btnHideLastWidth;
+
+ bool closing; // for menu doubleclick closing...
+
+ KCommonDecorationPrivate *d;
+};
+
+/**
+ * Title bar buttons of KCommonDecoration need to inherit this class.
+ */
+class KWIN_EXPORT KCommonDecorationButton : public QButton
+{
+ friend class KCommonDecoration;
+
+ public:
+ KCommonDecorationButton(ButtonType type, KCommonDecoration *parent, const char *name);
+ virtual ~KCommonDecorationButton();
+
+ /**
+ * These flags specify what has changed, e.g. the reason for a reset().
+ */
+ enum
+ {
+ ManualReset = 1 << 0, ///< The button might want to do a full reset for some reason...
+ SizeChange = 1 << 1, ///< The button size changed @see setSize()
+ ToggleChange = 1 << 2, ///< The button toggle state has changed @see setToggleButton()
+ StateChange = 1 << 3, ///< The button has been set pressed or not... @see setOn()
+ IconChange = 1 << 4, ///< The window icon has been changed
+ DecorationReset = 1 << 5 ///< E.g. when decoration colors have changed
+ };
+ /**
+ * Initialize the button after size change etc.
+ */
+ virtual void reset(unsigned long changed) = 0;
+ /**
+ * @returns the KCommonDecoration the button belongs to.
+ */
+ KCommonDecoration *decoration() const;
+ /**
+ * @returns the button type.
+ * @see ButtonType
+ */
+ ButtonType type() const;
+
+ /**
+ * Whether the button is left of the titlebar or not.
+ */
+ bool isLeft() const;
+
+ /**
+ * Set which mouse buttons the button should honor. Used e.g. to prevent accidental right mouse clicks.
+ */
+ void setRealizeButtons(int btns);
+ /**
+ * Set the button size.
+ */
+ void setSize(const QSize &s);
+ /**
+ * Set/update the button's tool tip
+ */
+ void setTipText(const QString &tip);
+ /**
+ * The mouse button that has been clicked last time.
+ */
+ ButtonState lastMousePress() const { return m_lastMouse; }
+
+ QSize sizeHint() const;
+
+ protected:
+ void setToggleButton(bool toggle);
+ void setOn(bool on);
+ void setLeft(bool left);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+ private:
+ KCommonDecoration *m_decoration;
+ ButtonType m_type;
+ int m_realizeButtons;
+ QSize m_size;
+ ButtonState m_lastMouse;
+
+ bool m_isLeft;
+
+ KCommonDecorationButtonPrivate *d;
+};
+
+#endif // KCOMMONDECORATION_H
diff --git a/kwin/lib/kdecoration.cpp b/kwin/lib/kdecoration.cpp
new file mode 100644
index 000000000..c7b3d6929
--- /dev/null
+++ b/kwin/lib/kdecoration.cpp
@@ -0,0 +1,444 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#include "kdecoration.h"
+
+#include <kdebug.h>
+#include <qapplication.h>
+#include <kglobal.h>
+#include <assert.h>
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#endif
+
+#include "kdecoration_p.h"
+#include "kdecorationfactory.h"
+
+KDecorationOptions* KDecoration::options_;
+
+KDecoration::KDecoration( KDecorationBridge* bridge, KDecorationFactory* factory )
+ : bridge_( bridge ),
+ w_( NULL ),
+ factory_( factory )
+ {
+ factory->addDecoration( this );
+ }
+
+KDecoration::~KDecoration()
+ {
+ factory()->removeDecoration( this );
+ delete w_;
+ }
+
+const KDecorationOptions* KDecoration::options()
+ {
+ return options_;
+ }
+
+void KDecoration::createMainWidget( WFlags flags )
+ {
+ // FRAME check flags?
+ setMainWidget( new QWidget( initialParentWidget(), "decoration widget", initialWFlags() | flags ));
+ }
+
+void KDecoration::setMainWidget( QWidget* w )
+ {
+ assert( w_ == NULL );
+ w_ = w;
+ w->setMouseTracking( true );
+ widget()->resize( geometry().size());
+ }
+
+QWidget* KDecoration::initialParentWidget() const
+ {
+ return bridge_->initialParentWidget();
+ }
+
+Qt::WFlags KDecoration::initialWFlags() const
+ {
+ return bridge_->initialWFlags();
+ }
+
+bool KDecoration::isActive() const
+ {
+ return bridge_->isActive();
+ }
+
+bool KDecoration::isCloseable() const
+ {
+ return bridge_->isCloseable();
+ }
+
+bool KDecoration::isMaximizable() const
+ {
+ return bridge_->isMaximizable();
+ }
+
+KDecoration::MaximizeMode KDecoration::maximizeMode() const
+ {
+ return bridge_->maximizeMode();
+ }
+
+bool KDecoration::isMinimizable() const
+ {
+ return bridge_->isMinimizable();
+ }
+
+bool KDecoration::providesContextHelp() const
+ {
+ return bridge_->providesContextHelp();
+ }
+
+int KDecoration::desktop() const
+ {
+ return bridge_->desktop();
+ }
+
+bool KDecoration::isModal() const
+ {
+ return bridge_->isModal();
+ }
+
+bool KDecoration::isShadeable() const
+ {
+ return bridge_->isShadeable();
+ }
+
+bool KDecoration::isShade() const
+ {
+ return bridge_->isShade();
+ }
+
+bool KDecoration::isSetShade() const
+ {
+ return bridge_->isSetShade();
+ }
+
+bool KDecoration::keepAbove() const
+ {
+ return bridge_->keepAbove();
+ }
+
+bool KDecoration::keepBelow() const
+ {
+ return bridge_->keepBelow();
+ }
+
+bool KDecoration::isMovable() const
+ {
+ return bridge_->isMovable();
+ }
+
+bool KDecoration::isResizable() const
+ {
+ return bridge_->isResizable();
+ }
+
+NET::WindowType KDecoration::windowType( unsigned long supported_types ) const
+ { // this one is also duplicated in KDecorationFactory
+ return bridge_->windowType( supported_types );
+ }
+
+QIconSet KDecoration::icon() const
+ {
+ return bridge_->icon();
+ }
+
+QString KDecoration::caption() const
+ {
+ return bridge_->caption();
+ }
+
+void KDecoration::processMousePressEvent( QMouseEvent* e )
+ {
+ return bridge_->processMousePressEvent( e );
+ }
+
+void KDecoration::showWindowMenu( const QRect &pos )
+ {
+ bridge_->showWindowMenu( pos );
+ }
+
+void KDecoration::showWindowMenu( QPoint pos )
+ {
+ bridge_->showWindowMenu( pos );
+ }
+
+void KDecoration::performWindowOperation( WindowOperation op )
+ {
+ bridge_->performWindowOperation( op );
+ }
+
+void KDecoration::setMask( const QRegion& reg, int mode )
+ {
+ bridge_->setMask( reg, mode );
+ }
+
+void KDecoration::clearMask()
+ {
+ bridge_->setMask( QRegion(), 0 );
+ }
+
+bool KDecoration::isPreview() const
+ {
+ return bridge_->isPreview();
+ }
+
+QRect KDecoration::geometry() const
+ {
+ return bridge_->geometry();
+ }
+
+QRect KDecoration::iconGeometry() const
+ {
+ return bridge_->iconGeometry();
+ }
+
+QRegion KDecoration::unobscuredRegion( const QRegion& r ) const
+ {
+ return bridge_->unobscuredRegion( r );
+ }
+
+QWidget* KDecoration::workspaceWidget() const
+ {
+ return bridge_->workspaceWidget();
+ }
+
+WId KDecoration::windowId() const
+ {
+ return bridge_->windowId();
+ }
+
+void KDecoration::closeWindow()
+ {
+ bridge_->closeWindow();
+ }
+
+void KDecoration::maximize( ButtonState button )
+ {
+ performWindowOperation( options()->operationMaxButtonClick( button ));
+ }
+
+void KDecoration::maximize( MaximizeMode mode )
+ {
+ bridge_->maximize( mode );
+ }
+
+void KDecoration::minimize()
+ {
+ bridge_->minimize();
+ }
+
+void KDecoration::showContextHelp()
+ {
+ bridge_->showContextHelp();
+ }
+
+void KDecoration::setDesktop( int desktop )
+ {
+ bridge_->setDesktop( desktop );
+ }
+
+void KDecoration::toggleOnAllDesktops()
+ {
+ if( isOnAllDesktops())
+ setDesktop( bridge_->currentDesktop());
+ else
+ setDesktop( NET::OnAllDesktops );
+ }
+
+void KDecoration::titlebarDblClickOperation()
+ {
+ bridge_->titlebarDblClickOperation();
+ }
+
+void KDecoration::titlebarMouseWheelOperation( int delta )
+ {
+ bridge_->titlebarMouseWheelOperation( delta );
+ }
+
+void KDecoration::setShade( bool set )
+ {
+ bridge_->setShade( set );
+ }
+
+void KDecoration::setKeepAbove( bool set )
+ {
+ bridge_->setKeepAbove( set );
+ }
+
+void KDecoration::setKeepBelow( bool set )
+ {
+ bridge_->setKeepBelow( set );
+ }
+
+bool KDecoration::drawbound( const QRect&, bool )
+ {
+ return false;
+ }
+
+bool KDecoration::animateMinimize( bool )
+ {
+ return false;
+ }
+
+bool KDecoration::windowDocked( Position )
+ {
+ return false;
+ }
+
+void KDecoration::helperShowHide( bool show )
+ {
+ bridge_->helperShowHide( show );
+ }
+
+void KDecoration::reset( unsigned long )
+ {
+ }
+
+void KDecoration::grabXServer()
+ {
+ bridge_->grabXServer( true );
+ }
+
+void KDecoration::ungrabXServer()
+ {
+ bridge_->grabXServer( false );
+ }
+
+KDecoration::Position KDecoration::mousePosition( const QPoint& p ) const
+{
+ const int range = 16;
+ int bleft, bright, btop, bbottom;
+ borders( bleft, bright, btop, bbottom );
+ btop = KMIN( btop, 4 ); // otherwise whole titlebar would have resize cursor
+
+ Position m = PositionCenter;
+
+ if ( ( p.x() > bleft && p.x() < widget()->width() - bright )
+ && ( p.y() > btop && p.y() < widget()->height() - bbottom ) )
+ return PositionCenter;
+
+ if ( p.y() <= KMAX( range, btop ) && p.x() <= KMAX( range, bleft ))
+ m = PositionTopLeft;
+ else if ( p.y() >= widget()->height()- KMAX( range, bbottom )
+ && p.x() >= widget()->width()- KMAX( range, bright ))
+ m = PositionBottomRight;
+ else if ( p.y() >= widget()->height()- KMAX( range, bbottom ) && p.x() <= KMAX( range, bleft ))
+ m = PositionBottomLeft;
+ else if ( p.y() <= KMAX( range, btop ) && p.x() >= widget()->width()- KMAX( range, bright ))
+ m = PositionTopRight;
+ else if ( p.y() <= btop )
+ m = PositionTop;
+ else if ( p.y() >= widget()->height()-bbottom )
+ m = PositionBottom;
+ else if ( p.x() <= bleft )
+ m = PositionLeft;
+ else if ( p.x() >= widget()->width()-bright )
+ m = PositionRight;
+ else
+ m = PositionCenter;
+ return m;
+}
+
+KDecorationOptions::KDecorationOptions()
+ {
+ assert( KDecoration::options_ == NULL );
+ KDecoration::options_ = this;
+ }
+
+KDecorationOptions::~KDecorationOptions()
+ {
+ assert( KDecoration::options_ == this );
+ KDecoration::options_ = NULL;
+ }
+
+const QColor& KDecorationOptions::color(ColorType type, bool active) const
+{
+ return(d->colors[type + (active ? 0 : NUM_COLORS)]);
+}
+
+const QFont& KDecorationOptions::font(bool active, bool small) const
+{
+ if ( small )
+ return(active ? d->activeFontSmall : d->inactiveFontSmall);
+ else
+ return(active ? d->activeFont : d->inactiveFont);
+}
+
+const QColorGroup& KDecorationOptions::colorGroup(ColorType type, bool active) const
+{
+ int idx = type + (active ? 0 : NUM_COLORS);
+ if(d->cg[idx])
+ return(*d->cg[idx]);
+ d->cg[idx] = new QColorGroup(Qt::black, d->colors[idx], d->colors[idx].light(150),
+ d->colors[idx].dark(), d->colors[idx].dark(120),
+ Qt::black, QApplication::palette().active().
+ base());
+ return(*d->cg[idx]);
+}
+
+bool KDecorationOptions::customButtonPositions() const
+{
+ return d->custom_button_positions;
+}
+
+QString KDecorationOptions::titleButtonsLeft() const
+{
+ return d->title_buttons_left;
+}
+
+QString KDecorationOptions::titleButtonsRight() const
+{
+ return d->title_buttons_right;
+}
+
+bool KDecorationOptions::showTooltips() const
+{
+ return d->show_tooltips;
+}
+
+KDecorationOptions::BorderSize KDecorationOptions::preferredBorderSize( KDecorationFactory* factory ) const
+{
+ assert( factory != NULL );
+ if( d->cached_border_size == BordersCount ) // invalid
+ d->cached_border_size = d->findPreferredBorderSize( d->border_size,
+ factory->borderSizes());
+ return d->cached_border_size;
+}
+
+bool KDecorationOptions::moveResizeMaximizedWindows() const
+{
+ return d->move_resize_maximized_windows;
+}
+
+KDecorationDefines::WindowOperation KDecorationOptions::operationMaxButtonClick( Qt::ButtonState button ) const
+ {
+ return button == Qt::RightButton? d->OpMaxButtonRightClick :
+ button == Qt::MidButton? d->OpMaxButtonMiddleClick :
+ d->OpMaxButtonLeftClick;
+ }
+
+#include "kdecoration.moc"
diff --git a/kwin/lib/kdecoration.h b/kwin/lib/kdecoration.h
new file mode 100644
index 000000000..2fd1fc451
--- /dev/null
+++ b/kwin/lib/kdecoration.h
@@ -0,0 +1,887 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#ifndef KDECORATION_H
+#define KDECORATION_H
+
+#include <qcolor.h>
+#include <qfont.h>
+#include <qobject.h>
+#include <qiconset.h>
+#include <netwm_def.h>
+#include <kdeversion.h>
+
+class KDecorationOptionsPrivate;
+class KDecorationBridge;
+class KDecorationPrivate;
+class KDecorationFactory;
+
+#define KWIN_EXPORT KDE_EXPORT
+
+/**
+ * This class provides a namespace for all decoration related classes.
+ * All shared types are defined here.
+ * @since 3.2
+ */
+class KWIN_EXPORT KDecorationDefines
+{
+public:
+ /**
+ * These values represent positions inside an area
+ */
+ enum Position
+ { // without prefix, they'd conflict with Qt::TopLeft etc. :(
+ PositionCenter = 0x00,
+ PositionLeft = 0x01,
+ PositionRight = 0x02,
+ PositionTop = 0x04,
+ PositionBottom = 0x08,
+ PositionTopLeft = PositionLeft | PositionTop,
+ PositionTopRight = PositionRight | PositionTop,
+ PositionBottomLeft = PositionLeft | PositionBottom,
+ PositionBottomRight = PositionRight | PositionBottom
+ };
+ /**
+ * Maximize mode. These values specify how a window is maximized.
+ */
+ // these values are written to session files, don't change the order
+ enum MaximizeMode
+ {
+ MaximizeRestore = 0, ///< The window is not maximized in any direction.
+ MaximizeVertical = 1, ///< The window is maximized vertically.
+ MaximizeHorizontal = 2, ///< The window is maximized horizontally.
+ /// Equal to @p MaximizeVertical | @p MaximizeHorizontal
+ MaximizeFull = MaximizeVertical | MaximizeHorizontal
+ };
+
+ enum WindowOperation
+ {
+ MaximizeOp = 5000,
+ RestoreOp,
+ MinimizeOp,
+ MoveOp,
+ UnrestrictedMoveOp,
+ ResizeOp,
+ UnrestrictedResizeOp,
+ CloseOp,
+ OnAllDesktopsOp,
+ ShadeOp,
+ KeepAboveOp,
+ KeepBelowOp,
+ OperationsOp,
+ WindowRulesOp,
+ ToggleStoreSettingsOp = WindowRulesOp, ///< @obsolete
+ HMaximizeOp,
+ VMaximizeOp,
+ LowerOp,
+ FullScreenOp,
+ NoBorderOp,
+ NoOp,
+ SetupWindowShortcutOp,
+ ApplicationRulesOp ///< @since 3.5
+ };
+ /**
+ * Basic color types that should be recognized by all decoration styles.
+ * Decorations are not required to implement all the colors, but for the ones that
+ * are implemented the color setting for them should be obeyed.
+ */
+ enum ColorType
+ {
+ ColorTitleBar, ///< The color for the titlebar
+ ColorTitleBlend, ///< The blend color for the titlebar
+ ColorFont, ///< The titlebar text color
+ ColorButtonBg, ///< The color to use for the titlebar buttons
+ ColorFrame, ///< The color for the window frame (border)
+ ColorHandle, ///< The color for the resize handle
+ NUM_COLORS
+ };
+
+ /**
+ * These flags specify which settings changed when rereading settings.
+ * Each setting in class KDecorationOptions specifies its matching flag.
+ */
+ enum
+ {
+ SettingDecoration = 1 << 0, ///< The decoration was changed
+ SettingColors = 1 << 1, ///< The color palette was changed
+ SettingFont = 1 << 2, ///< The titlebar font was changed
+ SettingButtons = 1 << 3, ///< The button layout was changed
+ SettingTooltips = 1 << 4, ///< The tooltip setting was changed
+ SettingBorder = 1 << 5 ///< The border size setting was changed
+ };
+
+ /**
+ * Border size. KDecorationOptions::preferredBorderSize() returns
+ * one of these values.
+ */
+ enum BorderSize
+ {
+ BorderTiny, ///< Minimal borders
+ BorderNormal, ///< Standard size borders, the default setting
+ BorderLarge, ///< Larger borders
+ BorderVeryLarge, ///< Very large borders
+ BorderHuge, ///< Huge borders
+ BorderVeryHuge, ///< Very huge borders
+ BorderOversized, ///< Oversized borders
+ BordersCount ///< @internal
+ };
+
+ /**
+ * Used to find out which features the decoration supports.
+ * @see KDecorationFactory::supports()
+ */
+ enum Ability
+ {
+ AbilityAnnounceButtons = 0, ///< decoration supports AbilityButton* values (always use)
+ AbilityButtonMenu = 1000, ///< decoration supports the menu button
+ AbilityButtonOnAllDesktops = 1001, ///< decoration supports the on all desktops button
+ AbilityButtonSpacer = 1002, ///< decoration supports inserting spacers between buttons
+ AbilityButtonHelp = 1003, ///< decoration supports what's this help button
+ AbilityButtonMinimize = 1004, ///< decoration supports a minimize button
+ AbilityButtonMaximize = 1005, ///< decoration supports a maximize button
+ AbilityButtonClose = 1006, ///< decoration supports a close button
+ AbilityButtonAboveOthers = 1007, ///< decoration supports an above button
+ AbilityButtonBelowOthers = 1008, ///< decoration supports a below button
+ AbilityButtonShade = 1009, ///< decoration supports a shade button
+ AbilityButtonResize = 1010, ///< decoration supports a resize button
+ ABILITY_DUMMY = 10000000
+ };
+
+ enum Requirement { REQUIREMENT_DUMMY = 1000000 };
+};
+
+class KDecorationProvides
+ : public KDecorationDefines
+ {
+ public:
+ virtual bool provides( Requirement req ) = 0;
+ };
+
+/**
+ * This class holds various configuration settings for the decoration.
+ * It is accessible from the decorations either as KDecoration::options()
+ * or KDecorationFactory::options().
+ * @since 3.2
+ */
+class KWIN_EXPORT KDecorationOptions : public KDecorationDefines
+ {
+public:
+ KDecorationOptions();
+ virtual ~KDecorationOptions();
+ /**
+ * Returns the color that should be used for the given part of the decoration.
+ * The changed flags for this setting is SettingColors.
+ *
+ * @param type The requested color type.
+ * @param active Whether the color should be for active or inactive windows.
+ */
+ const QColor& color(ColorType type, bool active=true) const;
+ /**
+ * Returns a colorgroup using the given decoration color as the background.
+ * The changed flags for this setting is SettingColors.
+ *
+ * @param type The requested color type.
+ * @param active Whether to return the color for active or inactive windows.
+ */
+ const QColorGroup& colorGroup(ColorType type, bool active=true) const;
+ /**
+ * Returns the active or inactive decoration font.
+ * The changed flags for this setting is SettingFont.
+ *
+ * @param active Whether to return the color for active or inactive windows.
+ * @param small If @a true, returns a font that's suitable for tool windows.
+ */
+ const QFont& font(bool active=true, bool small = false) const;
+ /**
+ * Returns @a true if the style should use custom button positions
+ * The changed flags for this setting is SettingButtons.
+ *
+ * @see titleButtonsLeft
+ * @see titleButtonsRight
+ */
+ bool customButtonPositions() const;
+ /**
+ * If customButtonPositions() returns true, titleButtonsLeft
+ * returns which buttons should be on the left side of the titlebar from left
+ * to right. Characters in the returned string have this meaning :
+ * @li 'M' menu button
+ * @li 'S' on_all_desktops button
+ * @li 'H' quickhelp button
+ * @li 'I' minimize ( iconify ) button
+ * @li 'A' maximize button
+ * @li 'X' close button
+ * @li 'F' keep_above_others button
+ * @li 'B' keep_below_others button
+ * @li 'L' shade button
+ * @li 'R' resize button
+ * @li '_' spacer
+ *
+ * The default ( which is also returned if customButtonPositions returns false )
+ * is "MS".
+ * Unknown buttons in the returned string must be ignored.
+ * The changed flags for this setting is SettingButtons.
+ */
+ QString titleButtonsLeft() const;
+ /**
+ * If customButtonPositions() returns true, titleButtonsRight
+ * returns which buttons should be on the right side of the titlebar from left
+ * to right. Characters in the return string have the same meaning like
+ * in titleButtonsLeft().
+ *
+ * The default ( which is also returned if customButtonPositions returns false )
+ * is "HIAX".
+ * Unknown buttons in the returned string must be ignored.
+ * The changed flags for this setting is SettingButtons.
+ */
+ QString titleButtonsRight() const;
+
+ /**
+ * @returns true if the style should use tooltips for window buttons
+ * The changed flags for this setting is SettingTooltips.
+ */
+ bool showTooltips() const;
+
+ /**
+ * The preferred border size selected by the user, e.g. for accessibility
+ * reasons, or when using high resolution displays. It's up to the decoration
+ * to decide which borders or if any borders at all will obey this setting.
+ * It is guaranteed that the returned value will be one of those
+ * returned by KDecorationFactory::borderSizes(), so if that one hasn't been
+ * reimplemented, BorderNormal is always returned.
+ * The changed flags for this setting is SettingBorder.
+ * @param factory the decoration factory used
+ */
+ BorderSize preferredBorderSize( KDecorationFactory* factory ) const;
+
+ /*
+ * When this functions returns false, moving and resizing of maximized windows
+ * is not allowed, and therefore the decoration is allowed to turn off (some of)
+ * its borders.
+ * The changed flags for this setting is SettingButtons.
+ */
+ bool moveResizeMaximizedWindows() const;
+
+ /**
+ * @internal
+ */
+ WindowOperation operationMaxButtonClick( Qt::ButtonState button ) const;
+
+ /**
+ * @internal
+ */
+ virtual unsigned long updateSettings() = 0; // returns SettingXYZ mask
+
+protected:
+ /**
+ * @internal
+ */
+ KDecorationOptionsPrivate* d;
+ };
+
+
+/**
+ * This is the base class for a decoration object. It provides functions
+ * that give various information about the decorated window, and also
+ * provides pure virtual functions for controlling the decoration that
+ * every decoration should implement.
+ * @since 3.2
+ */
+class KWIN_EXPORT KDecoration
+ : public QObject, public KDecorationDefines
+ {
+ Q_OBJECT
+ public:
+ /**
+ * Constructs a KDecoration object. Both the arguments are passed from
+ * KDecorationFactory. Note that the initialization code of the decoration
+ * should be done in the init() method.
+ */
+ KDecoration( KDecorationBridge* bridge, KDecorationFactory* factory );
+ /**
+ * Destroys the KDecoration.
+ */
+ virtual ~KDecoration();
+
+ // requests from decoration
+
+ /**
+ * Returns the KDecorationOptions object, which is used to access
+ * configuration settings for the decoration.
+ */
+ static const KDecorationOptions* options();
+ /**
+ * Returns @a true if the decorated window is currently active.
+ */
+ bool isActive() const;
+ /**
+ * Returns @a true if the decoration window can be closed by the user.
+ */
+ bool isCloseable() const;
+ /**
+ * Returns @a true if the decorated window can be maximized.
+ */
+ bool isMaximizable() const;
+ /**
+ * Returns the current maximization mode of the decorated window.
+ * Note that only fully maximized windows should be treated
+ * as "maximized" (e.g. if the maximize button has only two states).
+ */
+ MaximizeMode maximizeMode() const;
+ /**
+ * Returns @a true if the decorated window can be minimized by the user.
+ */
+ bool isMinimizable() const;
+ /**
+ * Return @a true if the decorated window can show context help
+ * (i.e. the decoration should provide the context help button).
+ */
+ bool providesContextHelp() const;
+ /**
+ * Returns the number of the virtual desktop the decorated window
+ * is currently on (including NET::OnAllDesktops for being on all
+ * desktops).
+ */
+ int desktop() const;
+ /**
+ * Convenience function that returns @a true if the window is on all
+ * virtual desktops.
+ */
+ bool isOnAllDesktops() const; // convenience
+ /**
+ * Returns @a true if the decoration window is modal (usually a modal dialog).
+ */
+ bool isModal() const;
+ /**
+ * Returns @a true if the decorated window can be shaded.
+ */
+ bool isShadeable() const;
+ /**
+ * Returns @a true if the decorated window is currently shaded.
+ * If the window is e.g. hover unshaded, it's not considered to be shaded.
+ * This function should not be used for the shade titlebar button, use
+ * @ref isSetShade() instead.
+ *
+ * @see isSetShade
+ */
+ bool isShade() const;
+ /**
+ * Returns @a true if the decorated window was set to be shaded. This function
+ * returns also true if the window is e.g. hover unshaded, so it doesn't
+ * always correspond to the actual window state.
+ *
+ * @see isShade
+ */
+ bool isSetShade() const;
+ /**
+ * Returns @a true if the decorated window should be kept above other windows.
+ */
+ bool keepAbove() const;
+ /**
+ * Returns @a true if the decorated window should be kept below other windows.
+ */
+ bool keepBelow() const;
+ /**
+ * Returns @a true if the decorated window can be moved by the user.
+ */
+ bool isMovable() const;
+ /**
+ * Returns @a true if the decorated window can be resized by the user.
+ */
+ bool isResizable() const;
+ /**
+ * This function returns the window type of the decorated window.
+ * The argument to this function is a mask of all window types
+ * the decoration knows about (as the list of valid window types
+ * is extended over time, and fallback types are specified in order
+ * to support older code). For a description of all window types,
+ * see the definition of the NET::WindowType type. Note that
+ * some window types never have decorated windows.
+ *
+ * An example of usage:
+ * @code
+ * const unsigned long supported_types = NET::NormalMask | NET::DesktopMask
+ * | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
+ * | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask;
+ *
+ * NET::WindowType type = windowType( supported_types );
+ *
+ * if( type == NET::Utility || type == NET::Menu || type == NET::Toolbar )
+ * // ... use smaller decorations for tool window types
+ * else
+ * // ... use normal decorations
+ * @endcode
+ */
+ NET::WindowType windowType( unsigned long supported_types ) const;
+ /**
+ * Returns an icon set with the decorated window's icon.
+ */
+ QIconSet icon() const;
+ /**
+ * Returns the decorated window's caption that should be shown in the titlebar.
+ */
+ QString caption() const;
+ /**
+ * This function invokes the window operations menu.
+ * \param pos specifies the place on the screen where the menu should
+ * show up. The menu pops up at the bottom-left corner of the specified
+ * rectangle, unless there is no space, in which case the menu is
+ * displayed above the rectangle.
+ *
+ * \note Decorations that enable a double-click operation for the menu
+ * button must ensure to call \a showWindowMenu() with the \a pos
+ * rectangle set to the menu button geometry.
+ * IMPORTANT: As a result of this function, the decoration object that
+ * called it may be destroyed after the function returns. This means
+ * that the decoration object must either return immediately after
+ * calling showWindowMenu(), or it must use
+ * KDecorationFactory::exists() to check it's still valid. For example,
+ * the code handling clicks on the menu button should look similarly
+ * like this:
+ *
+ * \code
+ * KDecorationFactory* f = factory(); // needs to be saved before
+ * showWindowMenu( button[MenuButton]->mapToGlobal( menuPoint ));
+ * if( !f->exists( this )) // destroyed, return immediately
+ * return;
+ * button[MenuButton]->setDown(false);
+ * \endcode
+ */
+ void showWindowMenu( const QRect &pos );
+
+ /**
+ * Overloaded version of the above.
+ */
+ void showWindowMenu( QPoint pos );
+ /**
+ * This function performs the given window operation. This function may destroy
+ * the current decoration object, just like showWindowMenu().
+ */
+ void performWindowOperation( WindowOperation op );
+ /**
+ * If the decoration is non-rectangular, this function needs to be called
+ * to set the shape of the decoration.
+ *
+ * @param reg The shape of the decoration.
+ * @param mode The X11 values Unsorted, YSorted, YXSorted and YXBanded that specify
+ * the sorting of the rectangles, default value is Unsorted.
+ */
+ void setMask( const QRegion& reg, int mode = 0 );
+ /**
+ * This convenience function resets the shape mask.
+ */
+ void clearMask(); // convenience
+ /**
+ * If this function returns @a true, the decorated window is used as a preview
+ * e.g. in the configuration module. In such case, the decoration can e.g.
+ * show some information in the window area.
+ */
+ bool isPreview() const;
+ /**
+ * Returns the geometry of the decoration.
+ */
+ QRect geometry() const;
+ /**
+ * Returns the icon geometry for the window, i.e. the geometry of the taskbar
+ * entry. This is used mainly for window minimize animations. Note that
+ * the geometry may be null.
+ */
+ QRect iconGeometry() const;
+ /**
+ * Returns the intersection of the given region with the region left
+ * unobscured by the windows stacked above the current one. You can use
+ * this function to, for example, try to keep the titlebar visible if
+ * there is a hole available. The region returned is in the coordinate
+ * space of the decoration.
+ * @param r The region you want to check for holes
+ */
+ QRegion unobscuredRegion( const QRegion& r ) const;
+ /**
+ * Returns the main workspace widget. The main purpose of this function is to
+ * allow painting the minimize animation or the transparent move bound on it.
+ */
+ QWidget* workspaceWidget() const;
+ /**
+ * Returns the handle of the window that is being decorated. It is possible
+ * the returned value will be 0.
+ * IMPORTANT: This function is meant for special purposes, and it
+ * usually should not be used. The main purpose is finding out additional
+ * information about the window's state. Also note that different kinds
+ * of windows are decorated: Toplevel windows managed by the window manager,
+ * test window in the window manager decoration module, and possibly also
+ * other cases.
+ * Careless abuse of this function will usually sooner or later lead
+ * to problems.
+ * @since 3.4
+ */
+ WId windowId() const;
+ /**
+ * Convenience function that returns the width of the decoration.
+ */
+ int width() const; // convenience
+ /**
+ * Convenience function that returns the height of the decoration.
+ */
+ int height() const; // convenience
+ /**
+ * This function is the default handler for mouse events. All mouse events
+ * that are not handled by the decoration itself should be passed to it
+ * in order to make work operations like window resizing by dragging borders etc.
+ */
+ void processMousePressEvent( QMouseEvent* e );
+
+ // requests to decoration
+
+ /**
+ * This function is called immediately after the decoration object is created.
+ * Due to some technical reasons, initialization should be done here
+ * instead of in the constructor.
+ */
+ virtual void init() = 0; // called once right after created
+
+ /**
+ * This function should return mouse cursor position in the decoration.
+ * Positions at the edge will result in window resizing with mouse button
+ * pressed, center position will result in moving.
+ */
+ virtual Position mousePosition( const QPoint& p ) const = 0;
+
+ /**
+ * This function should return the distance from each window side to the inner
+ * window. The sizes may depend on the state of the decorated window, such as
+ * whether it's shaded. Decorations often turn off their bottom border when the
+ * window is shaded, and turn off their left/right/bottom borders when
+ * the window is maximized and moving and resizing of maximized windows is disabled.
+ * This function mustn't do any repaints or resizes. Also, if the sizes returned
+ * by this function don't match the real values, this may result in drawing errors
+ * or other problems.
+ *
+ * @see KDecorationOptions::moveResizeMaximizedWindows()
+ */
+ // mustn't do any repaints, resizes or anything like that
+ virtual void borders( int& left, int& right, int& top, int& bottom ) const = 0;
+ /**
+ * This method is called by kwin when the style should resize the decoration window.
+ * The usual implementation is to resize the main widget of the decoration to the
+ * given size.
+ *
+ * @param s Specifies the new size of the decoration window.
+ */
+ virtual void resize( const QSize& s ) = 0;
+ /**
+ * This function should return the minimum required size for the decoration.
+ * Note that the returned size shouldn't be too large, because it will be
+ * used to keep the decorated window at least as large.
+ */
+ virtual QSize minimumSize() const = 0;
+ /**
+ * This function is called whenever the window either becomes or stops being active.
+ * Use isActive() to find out the current state.
+ */
+ virtual void activeChange() = 0;
+ /**
+ * This function is called whenever the caption changes. Use caption() to get it.
+ */
+ virtual void captionChange() = 0;
+ /**
+ * This function is called whenever the window icon changes. Use icon() to get it.
+ */
+ virtual void iconChange() = 0;
+ /**
+ * This function is called whenever the maximalization state of the window changes.
+ * Use maximizeMode() to get the current state.
+ */
+ virtual void maximizeChange() = 0;
+ /**
+ * This function is called whenever the desktop for the window changes. Use
+ * desktop() or isOnAllDesktops() to find out the current desktop
+ * on which the window is.
+ */
+ virtual void desktopChange() = 0;
+ /**
+ * This function is called whenever the window is shaded or unshaded. Use
+ * isShade() to get the current state.
+ */
+ virtual void shadeChange() = 0;
+#if KDE_IS_VERSION( 3, 90, 0 )
+#warning Redo all the XYZChange() virtuals as signals.
+#endif
+ signals:
+ /**
+ * This signal is emitted whenever the window's keep-above state changes.
+ * @since 3.3
+ */
+ void keepAboveChanged( bool );
+ /**
+ * This signal is emitted whenever the window's keep-below state changes.
+ * @since 3.3
+ */
+ void keepBelowChanged( bool );
+ public:
+ /**
+ * This function may be reimplemented to provide custom bound drawing
+ * for transparent moving or resizing of the window.
+ * @a False should be returned if the default implementation should be used.
+ * Note that if you e.g. paint the outline using a 5 pixels wide line,
+ * you should compensate for the 2 pixels that would make the window
+ * look larger.
+ *
+ * @param geom The geometry at this the bound should be drawn
+ * @param clear @a true if the bound should be cleared
+ *
+ * @see workspaceWidget() and geometry().
+ */
+ virtual bool drawbound( const QRect& geom, bool clear );
+ /**
+ * This function may be reimplemented to provide custom minimize/restore animations
+ * The reimplementation is allowed to perform X server grabs if necessary
+ * (only using the functions provided by this API, no direct Xlib calls), but no
+ * futher event processing is allowed (i.e. no kapp->processEvents()).
+ * @a False should be returned if the default implementation should be used.
+ * Note that you should not use this function to force disabling of the animation.
+ *
+ * @see workspaceWidget(), geometry() and helperShowHide().
+ */
+ virtual bool animateMinimize( bool minimize );
+ /**
+ * @internal Reserved.
+ */
+ // TODO position will need also values for top+left+bottom etc. docking ?
+ virtual bool windowDocked( Position side );
+ /**
+ * This function is called to reset the decoration on settings changes.
+ * It is usually invoked by calling KDecorationFactory::resetDecorations().
+ *
+ * @param changed Specifies which settings were changed, given by the SettingXXX masks
+ */
+ virtual void reset( unsigned long changed );
+
+ // special
+
+ /**
+ * This should be the first function called in init() to specify
+ * the main widget of the decoration. The widget should be created
+ * with parent specified by initialParentWidget() and flags
+ * specified by initialWFlags().
+ */
+ void setMainWidget( QWidget* );
+ /**
+ * Convenience functions that creates and sets a main widget as necessary.
+ * In such case, it's usually needed to install an event filter
+ * on the main widget to receive important events on it.
+ *
+ * @param flags Additional widget flags for the main widget. Note that only
+ * flags that affect widget drawing are allowed. Window type flags
+ * like WX11BypassWM or WStyle_NoBorder are forbidden.
+ */
+ void createMainWidget( WFlags flags = 0 );
+ /**
+ * The parent widget that should be used for the main widget.
+ */
+ QWidget* initialParentWidget() const;
+ /**
+ * The flags that should be used when creating the main widget.
+ * It is possible to add more flags when creating the main widget, but only flags
+ * that affect widget drawing are allowed. Window type flags like WX11BypassWM
+ * or WStyle_NoBorder are forbidden.
+ */
+ WFlags initialWFlags() const;
+ /**
+ * This function is only allowed to be called once from animateMinimize().
+ * It can be used if the window should be shown or hidden at a specific
+ * time during the animation. It is forbidden to use this function
+ * for other purposes.
+ */
+ void helperShowHide( bool show );
+ /**
+ * Returns the main widget for the decoration.
+ */
+ QWidget* widget();
+ /**
+ * Returns the main widget for the decoration.
+ */
+ const QWidget* widget() const;
+ /**
+ * Returns the factory that created this decoration.
+ */
+ KDecorationFactory* factory() const;
+ /**
+ * Performs X server grab. It is safe to call it several times in a row.
+ */
+ void grabXServer();
+ /**
+ * Ungrabs X server (if the number of ungrab attempts matches the number of grab attempts).
+ */
+ void ungrabXServer();
+ public slots:
+ // requests from decoration
+
+ /**
+ * This function can be called by the decoration to request
+ * closing of the decorated window. Note that closing the window
+ * also involves destroying the decoration.
+ * IMPORTANT: This function may destroy the current decoration object,
+ * just like showWindowMenu().
+ */
+ void closeWindow();
+ /*
+ * Changes the maximize mode of the decorated window. This function should
+ * be preferred to the other maximize() overload for reacting on clicks
+ * on the maximize titlebar button.
+ * NOTE: This function is new in KDE3.3. In order to support also KDE3.2,
+ * it is recommended to use code like this:
+ * \code
+ * ButtonState button = ... ;
+ * #if KDE_IS_VERSION( 3, 3, 0 )
+ * maximize( button );
+ * #else
+ * if( button == MidButton )
+ * maximize( maximizeMode() ^ MaximizeVertical );
+ * else if( button == RightButton )
+ * maximize( maximizeMode() ^ MaximizeHorizontal );
+ * else
+ * maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );
+ * #endif
+ * \endcode
+ * @since 3.3
+ */
+#if KDE_IS_VERSION( 3, 90, 0 )
+#warning Update the docs.
+#endif
+ void maximize( ButtonState button );
+ /**
+ * Set the maximize mode of the decorated window.
+ * @param mode The maximization mode to be set.
+ */
+ void maximize( MaximizeMode mode );
+ /**
+ * Minimize the decorated window.
+ */
+ void minimize();
+ /**
+ * Start showing context help in the window (i.e. the mouse will enter
+ * the what's this mode).
+ */
+ void showContextHelp();
+ /**
+ * Moves the window to the given desktop. Use NET::OnAllDesktops for making
+ * the window appear on all desktops.
+ */
+ void setDesktop( int desktop );
+ /**
+ * This function toggles the on-all-desktops state of the decorated window.
+ */
+ void toggleOnAllDesktops(); // convenience
+ /**
+ * This function performs the operation configured as titlebar double click
+ * operation.
+ */
+ void titlebarDblClickOperation();
+ /**
+ * This function performs the operation configured as titlebar wheel mouse
+ * operation.
+ * @param delta the mouse wheel delta
+ * @since 3.5
+ */
+ void titlebarMouseWheelOperation( int delta );
+ /**
+ * Shades or unshades the decorated window.
+ * @param set Whether the window should be shaded
+ */
+ void setShade( bool set );
+ /**
+ * Sets or reset keeping this window above others.
+ * @param set Whether to keep the window above others
+ */
+ void setKeepAbove( bool set );
+ /**
+ * Sets or reset keeping this window below others.
+ * @param set Whether to keep the window below others
+ */
+ void setKeepBelow( bool set );
+ /**
+ * @internal
+ */
+ void emitKeepAboveChanged( bool above ) { emit keepAboveChanged( above ); }
+ /**
+ * @internal
+ */
+ void emitKeepBelowChanged( bool below ) { emit keepBelowChanged( below ); }
+ private:
+ KDecorationBridge* bridge_;
+ QWidget* w_;
+ KDecorationFactory* factory_;
+ friend class KDecorationOptions; // for options_
+ static KDecorationOptions* options_;
+ KDecorationPrivate* d;
+ };
+
+inline
+KDecorationDefines::MaximizeMode operator^( KDecorationDefines::MaximizeMode m1, KDecorationDefines::MaximizeMode m2 )
+ {
+ return KDecorationDefines::MaximizeMode( int(m1) ^ int(m2) );
+ }
+
+inline
+KDecorationDefines::MaximizeMode operator&( KDecorationDefines::MaximizeMode m1, KDecorationDefines::MaximizeMode m2 )
+ {
+ return KDecorationDefines::MaximizeMode( int(m1) & int(m2) );
+ }
+
+inline
+KDecorationDefines::MaximizeMode operator|( KDecorationDefines::MaximizeMode m1, KDecorationDefines::MaximizeMode m2 )
+ {
+ return KDecorationDefines::MaximizeMode( int(m1) | int(m2) );
+ }
+
+inline QWidget* KDecoration::widget()
+ {
+ return w_;
+ }
+
+inline const QWidget* KDecoration::widget() const
+ {
+ return w_;
+ }
+
+inline KDecorationFactory* KDecoration::factory() const
+ {
+ return factory_;
+ }
+
+inline bool KDecoration::isOnAllDesktops() const
+ {
+ return desktop() == NET::OnAllDesktops;
+ }
+
+inline int KDecoration::width() const
+ {
+ return geometry().width();
+ }
+
+inline int KDecoration::height() const
+ {
+ return geometry().height();
+ }
+
+#endif
diff --git a/kwin/lib/kdecoration_p.cpp b/kwin/lib/kdecoration_p.cpp
new file mode 100644
index 000000000..0117e4ec4
--- /dev/null
+++ b/kwin/lib/kdecoration_p.cpp
@@ -0,0 +1,235 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#include "kdecoration_p.h"
+
+#include <kconfig.h>
+#include <kglobalsettings.h>
+#include <qpalette.h>
+#include <qapplication.h>
+#include <assert.h>
+
+KDecorationOptionsPrivate::KDecorationOptionsPrivate()
+ {
+ for(int i=0; i < NUM_COLORS*2; ++i)
+ cg[i] = NULL;
+ }
+
+KDecorationOptionsPrivate::~KDecorationOptionsPrivate()
+ {
+ int i;
+ for(i=0; i < NUM_COLORS*2; ++i)
+ {
+ if(cg[i])
+ {
+ delete cg[i];
+ cg[i] = NULL;
+ }
+ }
+ }
+
+void KDecorationOptionsPrivate::defaultKWinSettings()
+ {
+ title_buttons_left = "MS";
+ title_buttons_right = "HIAX";
+ custom_button_positions = false;
+ show_tooltips = true;
+ border_size = BorderNormal;
+ cached_border_size = BordersCount; // invalid
+ move_resize_maximized_windows = true;
+ OpMaxButtonRightClick = MaximizeOp;
+ OpMaxButtonMiddleClick = VMaximizeOp;
+ OpMaxButtonLeftClick = HMaximizeOp;
+ }
+
+unsigned long KDecorationOptionsPrivate::updateKWinSettings( KConfig* config )
+ {
+ unsigned long changed = 0;
+ QString old_group = config->group();
+ config->setGroup( "WM" );
+
+// SettingColors
+ QColor old_colors[NUM_COLORS*2];
+ for( int i = 0;
+ i < NUM_COLORS*2;
+ ++i )
+ old_colors[ i ] = colors[ i ];
+
+ QPalette pal = QApplication::palette();
+ // normal colors
+ colors[ColorFrame] = pal.active().background();
+ colors[ColorFrame] = config->readColorEntry("frame", &colors[ColorFrame]);
+ colors[ColorHandle] = colors[ColorFrame];
+ colors[ColorHandle] = config->readColorEntry("handle", &colors[ColorHandle]);
+
+ // full button configuration (background, blend, and foreground
+ if(QPixmap::defaultDepth() > 8)
+ colors[ColorButtonBg] = colors[ColorFrame].light(130);
+ else
+ colors[ColorButtonBg] = colors[ColorFrame];
+ colors[ColorButtonBg] = config->readColorEntry("activeTitleBtnBg",
+ &colors[ColorFrame]);
+ colors[ColorTitleBar] = pal.active().highlight();
+ colors[ColorTitleBar] = config->readColorEntry("activeBackground",
+ &colors[ColorTitleBar]);
+ if(QPixmap::defaultDepth() > 8)
+ colors[ColorTitleBlend] = colors[ ColorTitleBar ].dark(110);
+ else
+ colors[ColorTitleBlend] = colors[ ColorTitleBar ];
+ colors[ColorTitleBlend] = config->readColorEntry("activeBlend",
+ &colors[ColorTitleBlend]);
+
+ colors[ColorFont] = pal.active().highlightedText();
+ colors[ColorFont] = config->readColorEntry("activeForeground", &colors[ColorFont]);
+
+ // inactive
+ colors[ColorFrame+NUM_COLORS] = config->readColorEntry("inactiveFrame",
+ &colors[ColorFrame]);
+ colors[ColorTitleBar+NUM_COLORS] = colors[ColorFrame];
+ colors[ColorTitleBar+NUM_COLORS] = config->
+ readColorEntry("inactiveBackground", &colors[ColorTitleBar+NUM_COLORS]);
+
+ if(QPixmap::defaultDepth() > 8)
+ colors[ColorTitleBlend+NUM_COLORS] = colors[ ColorTitleBar+NUM_COLORS ].dark(110);
+ else
+ colors[ColorTitleBlend+NUM_COLORS] = colors[ ColorTitleBar+NUM_COLORS ];
+ colors[ColorTitleBlend+NUM_COLORS] =
+ config->readColorEntry("inactiveBlend", &colors[ColorTitleBlend+NUM_COLORS]);
+
+ // full button configuration
+ if(QPixmap::defaultDepth() > 8)
+ colors[ColorButtonBg+NUM_COLORS] = colors[ColorFrame+NUM_COLORS].light(130);
+ else
+ colors[ColorButtonBg+NUM_COLORS] = colors[ColorFrame+NUM_COLORS];
+ colors[ColorButtonBg+NUM_COLORS] =
+ config->readColorEntry("inactiveTitleBtnBg",
+ &colors[ColorButtonBg]);
+
+ colors[ColorHandle+NUM_COLORS] =
+ config->readColorEntry("inactiveHandle", &colors[ColorHandle]);
+
+ colors[ColorFont+NUM_COLORS] = colors[ColorFrame].dark();
+ colors[ColorFont+NUM_COLORS] = config->readColorEntry("inactiveForeground",
+ &colors[ColorFont+NUM_COLORS]);
+
+ for( int i = 0;
+ i < NUM_COLORS*2;
+ ++i )
+ if( old_colors[ i ] != colors[ i ] )
+ changed |= SettingColors;
+
+// SettingFont
+ QFont old_activeFont = activeFont;
+ QFont old_inactiveFont = inactiveFont;
+ QFont old_activeFontSmall = activeFontSmall;
+ QFont old_inactiveFontSmall = inactiveFontSmall;
+
+ QFont activeFontGuess = KGlobalSettings::windowTitleFont();
+
+ activeFont = config->readFontEntry("activeFont", &activeFontGuess);
+ inactiveFont = config->readFontEntry("inactiveFont", &activeFont);
+
+ activeFontSmall = activeFont;
+ activeFontSmall.setPointSize(activeFont.pointSize() - 2);
+ activeFontSmall = config->readFontEntry("activeFontSmall", &activeFontSmall);
+ inactiveFontSmall = config->readFontEntry("inactiveFontSmall", &activeFontSmall);
+
+ if( old_activeFont != activeFont
+ || old_inactiveFont != inactiveFont
+ || old_activeFontSmall != activeFontSmall
+ || old_inactiveFontSmall != inactiveFontSmall )
+ changed |= SettingFont;
+
+ config->setGroup( "Style" );
+// SettingsButtons
+ QString old_title_buttons_left = title_buttons_left;
+ QString old_title_buttons_right = title_buttons_right;
+ bool old_custom_button_positions = custom_button_positions;
+ custom_button_positions = config->readBoolEntry("CustomButtonPositions", false);
+ if (custom_button_positions)
+ {
+ title_buttons_left = config->readEntry("ButtonsOnLeft", "MS");
+ title_buttons_right = config->readEntry("ButtonsOnRight", "HIAX");
+ }
+ else
+ {
+ title_buttons_left = "MS";
+ title_buttons_right = "HIAX";
+ }
+ if( old_custom_button_positions != custom_button_positions
+ || ( custom_button_positions &&
+ ( old_title_buttons_left != title_buttons_left
+ || old_title_buttons_right != title_buttons_right )))
+ changed |= SettingButtons;
+
+// SettingTooltips
+ bool old_show_tooltips = show_tooltips;
+ show_tooltips = config->readBoolEntry("ShowToolTips", true);
+ if( old_show_tooltips != show_tooltips )
+ changed |= SettingTooltips;
+
+// SettingBorder
+
+ BorderSize old_border_size = border_size;
+ int border_size_num = config->readNumEntry( "BorderSize", BorderNormal );
+ if( border_size_num >= 0 && border_size_num < BordersCount )
+ border_size = static_cast< BorderSize >( border_size_num );
+ else
+ border_size = BorderNormal;
+ if( old_border_size != border_size )
+ changed |= SettingBorder;
+ cached_border_size = BordersCount; // invalid
+
+ config->setGroup( "Windows" );
+ bool old_move_resize_maximized_windows = move_resize_maximized_windows;
+ move_resize_maximized_windows = config->readBoolEntry( "MoveResizeMaximizedWindows", false );
+ if( old_move_resize_maximized_windows != move_resize_maximized_windows )
+ changed |= SettingBorder;
+
+// destroy cached values
+ int i;
+ for(i=0; i < NUM_COLORS*2; ++i)
+ {
+ if(cg[i])
+ {
+ delete cg[i];
+ cg[i] = NULL;
+ }
+ }
+
+ config->setGroup( old_group );
+
+ return changed;
+ }
+
+KDecorationDefines::BorderSize KDecorationOptionsPrivate::findPreferredBorderSize( BorderSize size,
+ QValueList< BorderSize > sizes ) const
+ {
+ for( QValueList< BorderSize >::ConstIterator it = sizes.begin();
+ it != sizes.end();
+ ++it )
+ if( size <= *it ) // size is either a supported size, or *it is the closest larger supported
+ return *it;
+ return sizes.last(); // size is larger than all supported ones, return largest
+ }
diff --git a/kwin/lib/kdecoration_p.h b/kwin/lib/kdecoration_p.h
new file mode 100644
index 000000000..8d0e5e15a
--- /dev/null
+++ b/kwin/lib/kdecoration_p.h
@@ -0,0 +1,111 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#ifndef KDECORATION_P_H
+#define KDECORATION_P_H
+
+//
+// This header file is internal. I mean it.
+//
+
+#include "kdecoration.h"
+#include <qwidget.h>
+#include <qvaluelist.h>
+
+class KConfig;
+
+class KWIN_EXPORT KDecorationOptionsPrivate : public KDecorationDefines
+ {
+ public:
+ KDecorationOptionsPrivate();
+ virtual ~KDecorationOptionsPrivate();
+ void defaultKWinSettings(); // shared implementation
+ unsigned long updateKWinSettings( KConfig* ); // shared implementation
+ BorderSize findPreferredBorderSize( BorderSize size, QValueList< BorderSize > ) const; // shared implementation
+
+ QColor colors[NUM_COLORS*2];
+ QColorGroup *cg[NUM_COLORS*2];
+ QFont activeFont, inactiveFont, activeFontSmall, inactiveFontSmall;
+ QString title_buttons_left;
+ QString title_buttons_right;
+ bool custom_button_positions;
+ bool show_tooltips;
+ BorderSize border_size, cached_border_size;
+ bool move_resize_maximized_windows;
+ WindowOperation OpMaxButtonRightClick;
+ WindowOperation OpMaxButtonMiddleClick;
+ WindowOperation OpMaxButtonLeftClick;
+ };
+
+class KDecorationBridge : public KDecorationDefines
+ {
+ public:
+ virtual bool isActive() const = 0;
+ virtual bool isCloseable() const = 0;
+ virtual bool isMaximizable() const = 0;
+ virtual MaximizeMode maximizeMode() const = 0;
+ virtual bool isMinimizable() const = 0;
+ virtual bool providesContextHelp() const = 0;
+ virtual int desktop() const = 0;
+ virtual bool isModal() const = 0;
+ virtual bool isShadeable() const = 0;
+ virtual bool isShade() const = 0;
+ virtual bool isSetShade() const = 0;
+ virtual bool keepAbove() const = 0;
+ virtual bool keepBelow() const = 0;
+ virtual bool isMovable() const = 0;
+ virtual bool isResizable() const = 0;
+ virtual NET::WindowType windowType( unsigned long supported_types ) const = 0;
+ virtual QIconSet icon() const = 0;
+ virtual QString caption() const = 0;
+ virtual void processMousePressEvent( QMouseEvent* ) = 0;
+ virtual void showWindowMenu( const QRect &) = 0;
+ virtual void showWindowMenu( QPoint ) = 0;
+ virtual void performWindowOperation( WindowOperation ) = 0;
+ virtual void setMask( const QRegion&, int ) = 0;
+ virtual bool isPreview() const = 0;
+ virtual QRect geometry() const = 0;
+ virtual QRect iconGeometry() const = 0;
+ virtual QRegion unobscuredRegion( const QRegion& r ) const = 0;
+ virtual QWidget* workspaceWidget() const = 0;
+ virtual WId windowId() const = 0;
+ virtual void closeWindow() = 0;
+ virtual void maximize( MaximizeMode mode ) = 0;
+ virtual void minimize() = 0;
+ virtual void showContextHelp() = 0;
+ virtual void setDesktop( int desktop ) = 0;
+ virtual void titlebarDblClickOperation() = 0;
+ virtual void titlebarMouseWheelOperation( int delta ) = 0;
+ virtual void setShade( bool set ) = 0;
+ virtual void setKeepAbove( bool ) = 0;
+ virtual void setKeepBelow( bool ) = 0;
+ // not part of public API
+ virtual int currentDesktop() const = 0;
+ virtual QWidget* initialParentWidget() const = 0;
+ virtual Qt::WFlags initialWFlags() const = 0;
+ virtual void helperShowHide( bool ) = 0;
+ virtual void grabXServer( bool grab ) = 0;
+ };
+
+#endif
diff --git a/kwin/lib/kdecoration_plugins_p.cpp b/kwin/lib/kdecoration_plugins_p.cpp
new file mode 100644
index 000000000..85d496105
--- /dev/null
+++ b/kwin/lib/kdecoration_plugins_p.cpp
@@ -0,0 +1,199 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 1999, 2000 Daniel M. Duley <mosfet@kde.org>
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#include "kdecoration_plugins_p.h"
+
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <klibloader.h>
+#include <assert.h>
+
+#include <qdir.h>
+#include <qfile.h>
+
+#include "kdecorationfactory.h"
+
+KDecorationPlugins::KDecorationPlugins( KConfig* cfg )
+ : create_ptr( NULL ),
+ library( NULL ),
+ fact( NULL ),
+ old_library( NULL ),
+ old_fact( NULL ),
+ pluginStr( "kwin3_undefined " ),
+ config( cfg )
+ {
+ }
+
+KDecorationPlugins::~KDecorationPlugins()
+ {
+ if(library)
+ {
+ assert( fact != NULL );
+ delete fact;
+ library->unload();
+ }
+ if(old_library)
+ {
+ assert( old_fact != NULL );
+ delete old_fact;
+ old_library->unload();
+ }
+ }
+
+bool KDecorationPlugins::reset( unsigned long changed )
+ {
+ QString oldPlugin = pluginStr;
+ config->reparseConfiguration();
+ bool ret = false;
+ if(( !loadPlugin( "" ) && library ) // "" = read the one in cfg file
+ || oldPlugin == pluginStr )
+ { // no new plugin loaded, reset the old one
+ assert( fact != NULL );
+ ret = fact->reset( changed );
+ }
+ return ret || oldPlugin != pluginStr;
+ }
+
+KDecorationFactory* KDecorationPlugins::factory()
+ {
+ return fact;
+ }
+
+// convenience
+KDecoration* KDecorationPlugins::createDecoration( KDecorationBridge* bridge )
+ {
+ if( fact != NULL )
+ return fact->createDecoration( bridge );
+ return NULL;
+ }
+
+// returns true if plugin was loaded successfully
+bool KDecorationPlugins::loadPlugin( QString nameStr )
+ {
+ if( nameStr.isEmpty())
+ {
+ KConfigGroupSaver saver( config, "Style" );
+ nameStr = config->readEntry("PluginLib", defaultPlugin );
+ }
+ // make sure people can switch between HEAD and kwin_iii branch
+ if( nameStr.startsWith( "kwin_" ))
+ nameStr = "kwin3_" + nameStr.mid( 5 );
+
+ KLibrary *oldLibrary = library;
+ KDecorationFactory* oldFactory = fact;
+
+ QString path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
+
+ // If the plugin was not found, try to find the default
+ if (path.isEmpty())
+ {
+ nameStr = defaultPlugin;
+ path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
+ }
+
+ // If no library was found, exit kwin with an error message
+ if (path.isEmpty())
+ {
+ error( i18n("No window decoration plugin library was found." ));
+ return false;
+ }
+
+ // Check if this library is not already loaded.
+ if(pluginStr == nameStr)
+ return true;
+
+ // Try loading the requested plugin
+ library = KLibLoader::self()->library(QFile::encodeName(path));
+
+ // If that fails, fall back to the default plugin
+ if (!library)
+ {
+ kdDebug() << " could not load library, try default plugin again" << endl;
+ nameStr = defaultPlugin;
+ if ( pluginStr == nameStr )
+ return true;
+ path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
+ if (!path.isEmpty())
+ library = KLibLoader::self()->library(QFile::encodeName(path));
+ }
+
+ if (!library)
+ {
+ error( i18n("The default decoration plugin is corrupt "
+ "and could not be loaded." ));
+ return false;
+ }
+
+ create_ptr = NULL;
+ if( library->hasSymbol("create_factory"))
+ {
+ void* create_func = library->symbol("create_factory");
+ if(create_func)
+ create_ptr = (KDecorationFactory* (*)())create_func;
+ }
+ if(!create_ptr)
+ {
+ error( i18n( "The library %1 is not a KWin plugin." ).arg( path ));
+ library->unload();
+ return false;
+ }
+ fact = create_ptr();
+ fact->checkRequirements( this ); // let it check what is supported
+
+ pluginStr = nameStr;
+
+ // For clients in kdeartwork
+ QString catalogue = nameStr;
+ catalogue.replace( "kwin3_", "kwin_" );
+ KGlobal::locale()->insertCatalogue( catalogue );
+ // For KCommonDecoration based clients
+ KGlobal::locale()->insertCatalogue( "kwin_lib" );
+ // For clients in kdebase
+ KGlobal::locale()->insertCatalogue( "kwin_clients" );
+ // For clients in kdeartwork
+ KGlobal::locale()->insertCatalogue( "kwin_art_clients" );
+
+ old_library = oldLibrary; // save for delayed destroying
+ old_fact = oldFactory;
+
+ return true;
+}
+
+void KDecorationPlugins::destroyPreviousPlugin()
+{
+ // Destroy the old plugin
+ if(old_library)
+ {
+ delete old_fact;
+ old_fact = NULL;
+ old_library->unload();
+ old_library = NULL;
+ }
+}
+
+void KDecorationPlugins::error( const QString& )
+ {
+ }
diff --git a/kwin/lib/kdecoration_plugins_p.h b/kwin/lib/kdecoration_plugins_p.h
new file mode 100644
index 000000000..b82f7f914
--- /dev/null
+++ b/kwin/lib/kdecoration_plugins_p.h
@@ -0,0 +1,77 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 1999, 2000 Daniel M. Duley <mosfet@kde.org>
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#ifndef KDECORATION_PLUGINS_H
+#define KDECORATION_PLUGINS_H
+
+//
+// This header file is internal. I mean it.
+//
+
+#include <qcstring.h>
+#include <qstring.h>
+#include <qwidget.h>
+
+#include "kdecoration.h"
+
+class KLibrary;
+class KConfig;
+class KDecoration;
+class KDecorationBridge;
+class KDecorationFactory;
+
+class KWIN_EXPORT KDecorationPlugins
+ : public KDecorationProvides
+ {
+ public:
+ KDecorationPlugins( KConfig* cfg );
+ virtual ~KDecorationPlugins();
+ bool loadPlugin( QString name );
+ void destroyPreviousPlugin();
+ KDecorationFactory* factory();
+ KDecoration* createDecoration( KDecorationBridge* );
+ QString currentPlugin() { return pluginStr; }
+ bool reset( unsigned long changed ); // returns true if decorations need to be recreated
+ protected:
+ virtual void error( const QString& error_msg );
+ QCString defaultPlugin; // FRAME normalne protected?
+ private:
+ KDecorationFactory* (*create_ptr)();
+ KLibrary *library;
+ KDecorationFactory* fact;
+ KLibrary *old_library;
+ KDecorationFactory* old_fact;
+ QString pluginStr;
+ KConfig* config;
+ };
+
+/*
+
+ Plugins API:
+ KDecorationFactory* create_factory(); - called once after loading
+
+*/
+
+#endif
diff --git a/kwin/lib/kdecorationfactory.cpp b/kwin/lib/kdecorationfactory.cpp
new file mode 100644
index 000000000..74508501b
--- /dev/null
+++ b/kwin/lib/kdecorationfactory.cpp
@@ -0,0 +1,85 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#include "kdecorationfactory.h"
+
+#include <assert.h>
+
+#include "kdecoration_p.h"
+
+KDecorationFactory::KDecorationFactory()
+ {
+ }
+
+KDecorationFactory::~KDecorationFactory()
+ {
+ assert( _decorations.count() == 0 );
+ }
+
+bool KDecorationFactory::reset( unsigned long )
+ {
+ return false;
+ }
+
+bool KDecorationFactory::supports( Ability )
+ {
+ return false;
+ }
+
+void KDecorationFactory::checkRequirements( KDecorationProvides* )
+ {
+ }
+
+QValueList< KDecorationDefines::BorderSize > KDecorationFactory::borderSizes() const
+ {
+ return QValueList< BorderSize >() << BorderNormal;
+ }
+
+bool KDecorationFactory::exists( const KDecoration* deco ) const
+ {
+ return _decorations.contains( const_cast< KDecoration* >( deco ));
+ }
+
+void KDecorationFactory::addDecoration( KDecoration* deco )
+ {
+ _decorations.append( deco );
+ }
+
+void KDecorationFactory::removeDecoration( KDecoration* deco )
+ {
+ _decorations.remove( deco );
+ }
+
+void KDecorationFactory::resetDecorations( unsigned long changed )
+ {
+ for( QValueList< KDecoration* >::ConstIterator it = _decorations.begin();
+ it != _decorations.end();
+ ++it )
+ (*it)->reset( changed );
+ }
+
+NET::WindowType KDecorationFactory::windowType( unsigned long supported_types, KDecorationBridge* bridge ) const
+ {
+ return bridge->windowType( supported_types );
+ }
diff --git a/kwin/lib/kdecorationfactory.h b/kwin/lib/kdecorationfactory.h
new file mode 100644
index 000000000..08e733c8b
--- /dev/null
+++ b/kwin/lib/kdecorationfactory.h
@@ -0,0 +1,120 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#ifndef KDECORATIONFACTORY_H
+#define KDECORATIONFACTORY_H
+
+#include "kdecoration.h"
+
+class KDecoration;
+class KDecorationBridge;
+class KDecorationFactoryPrivate;
+
+class KWIN_EXPORT KDecorationFactory
+ : public KDecorationDefines
+ {
+ public:
+ /**
+ * Constructor. Called after loading the decoration plugin. All global
+ * initialization of the plugin should be done in the factory constructor.
+ */
+ KDecorationFactory();
+ /**
+ * Destructor. Called before unloading the decoration plugin. All global
+ * cleanup of the plugin should be done in the factory destructor.
+ */
+ virtual ~KDecorationFactory();
+ /**
+ * This function must be reimplemented to create decoration objects.
+ * The argument should be passed to the KDecoration constructor, the second
+ * KDecoration argument should be this factory object.
+ */
+ virtual KDecoration* createDecoration( KDecorationBridge* bridge ) = 0;
+ /**
+ * This function is called when the configuration settings changed.
+ * The argument specifies what has changed, using the SettingXXX masks.
+ * It should be determined whether the decorations need to be completely
+ * remade, in which case true should be returned, or whether only e.g.
+ * a repaint will be sufficient, in which case false should be returned,
+ * and resetDecorations() can be called to reset all decoration objects.
+ * Note that true should be returned only when really necessary.
+ */
+ virtual bool reset( unsigned long changed ); // returns true if the decoration needs to be recreated
+
+ /**
+ * Reimplement this function if your decoration supports more border sizes than
+ * the default one (BorderNormal). The returned list must contain all supported
+ * sizes, ordered from the smallest to the largest one. By default, only
+ * BorderNormal is returned.
+ */
+ virtual QValueList< BorderSize > borderSizes() const;
+
+ virtual bool supports( Ability ability );
+
+ virtual void checkRequirements( KDecorationProvides* provides );
+ /**
+ * Returns the KDecorationOptions object, which is used to access
+ * configuration settings for the decoration.
+ */
+ const KDecorationOptions* options(); // convenience
+ /**
+ * Returns true if the given decoration object still exists. This is necessary
+ * e.g. when calling KDecoration::showWindowMenu(), which may cause the decoration
+ * to be destroyed. Note that this function is reliable only if called immediately
+ * after such actions.
+ */
+ bool exists( const KDecoration* deco ) const;
+ /**
+ * @internal
+ */
+ void addDecoration( KDecoration* );
+ /**
+ * @internal
+ */
+ void removeDecoration( KDecoration* );
+ protected:
+ /**
+ * Convenience function that calls KDecoration::reset() for all decoration
+ * objects.
+ */
+ void resetDecorations( unsigned long changed ); // convenience
+ /**
+ * This function has the same functionality like KDecoration::windowType().
+ * It can be used in createDecoration() to return different KDecoration
+ * inherited classes depending on the window type, as at that time
+ * KDecoration::windowType() is not available yet. The additional argument
+ * is the one passed to createDecoration().
+ */
+ NET::WindowType windowType( unsigned long supported_types, KDecorationBridge* bridge ) const;
+ private:
+ QValueList< KDecoration* > _decorations;
+ KDecorationFactoryPrivate* d;
+ };
+
+inline const KDecorationOptions* KDecorationFactory::options()
+ {
+ return KDecoration::options();
+ }
+
+#endif