Separate KCommonDecoration from KDecoration, in order to allow

greater possibilities in extending KDecoration. KCommonDecoration
now does not inherit KDecoration, only wraps it (i.e. it's source
compatible). Added comments on how to extend KDecoration
in the future by subclassing to KDecoration2, added PORTING
document with all API changes in KDE4.
CCMAIL: kwin@kde.org


svn path=/trunk/KDE/kdebase/workspace/; revision=742976
This commit is contained in:
Luboš Luňák 2007-11-29 14:11:02 +00:00
parent fe90101935
commit 0170623a9c
15 changed files with 553 additions and 16 deletions

25
clients/PORTING Normal file
View file

@ -0,0 +1,25 @@
This document lists changed needed for porting KWin decoration clients from KDE3 to KDE4:
- the client needs to be ported to KDE4/Qt4 (obviously)
- KCommonDecoration no longer inherits KDecoration, it only has the same API (it is
source-compatible) - this means that generally there should not be any changes related
to this needed, with the exception of converting from KCommonDecoration* to KDecoration*
(most notably in createDecoration()) - call decoration() to do the conversion;
for example, change
"
KDecoration* YourClientHandler::createDecoration( KDecorationBridge* bridge )
{
return new YourClientClient( bridge, this );
}
"
to
"
KDecoration* YourClientHandler::createDecoration( KDecorationBridge* bridge )
{
return ( new YourClientClient( bridge, this ))->decoration();
}
"
- KDecoration::workspaceWidget() has been removed, for drawing outlines in drawbound(),
use code similar to example in the documentation for KDecoration::drawbound()
- KDecoration::animateMinimize() and KDecoration::helperShowHide() have been removed,
animations are now implemented only by KWin's compositing code

View file

@ -187,7 +187,7 @@ KDE2Handler::~KDE2Handler()
KDecoration* KDE2Handler::createDecoration( KDecorationBridge* b )
{
return new KDE2Client( b, this );
return ( new KDE2Client( b, this ))->decoration();
}
bool KDE2Handler::reset( unsigned long changed )

View file

@ -683,7 +683,7 @@ LaptopClientFactory::~LaptopClientFactory()
KDecoration *LaptopClientFactory::createDecoration(KDecorationBridge *b)
{
findPreferredHandleSize();
return new Laptop::LaptopClient(b, this);
return (new Laptop::LaptopClient(b, this))->decoration();
}
bool LaptopClientFactory::reset(unsigned long changed)

View file

@ -758,7 +758,7 @@ ModernSysFactory::~ModernSysFactory()
KDecoration* ModernSysFactory::createDecoration( KDecorationBridge* b )
{
return(new ModernSys(b, this));
return(new ModernSys(b, this))->decoration();
}
bool ModernSysFactory::reset( unsigned long changed )

View file

@ -71,7 +71,7 @@ OxygenFactory::~OxygenFactory() { initialized_ = false; }
KDecoration* OxygenFactory::createDecoration(KDecorationBridge* b)
{
return new OxygenClient(b, this);
return (new OxygenClient(b, this))->decoration();
}
//////////////////////////////////////////////////////////////////////////////

View file

@ -133,7 +133,7 @@ bool PlastikHandler::reset(unsigned long changed)
KDecoration* PlastikHandler::createDecoration( KDecorationBridge* bridge )
{
return new PlastikClient( bridge, this );
return ( new PlastikClient( bridge, this ))->decoration();
}
bool PlastikHandler::supports( Ability ability ) const

View file

@ -163,7 +163,7 @@ QuartzHandler::~QuartzHandler()
KDecoration* QuartzHandler::createDecoration( KDecorationBridge* bridge )
{
return new QuartzClient( bridge, this );
return ( new QuartzClient( bridge, this ))->decoration();
}

View file

@ -640,7 +640,7 @@ RedmondDecoFactory::~RedmondDecoFactory()
KDecoration *RedmondDecoFactory::createDecoration( KDecorationBridge *b )
{
return new RedmondDeco(b, this);
return (new RedmondDeco(b, this))->decoration();
}
bool RedmondDecoFactory::reset( unsigned long changed )

View file

@ -334,7 +334,7 @@ void WebClient::updateWindowShape()
KDecoration* WebFactory::createDecoration( KDecorationBridge* b )
{
return(new WebClient(b, this));
return(new WebClient(b, this))->decoration();
}
bool WebFactory::reset(unsigned long changed)

View file

@ -8,7 +8,8 @@ set(kdecorations_LIB_SRCS
kdecoration_p.cpp
kdecoration_plugins_p.cpp
kdecorationfactory.cpp
kcommondecoration.cpp )
kcommondecoration.cpp
kcommondecoration_p.cpp )
kde4_add_library(kdecorations SHARED ${kdecorations_LIB_SRCS})
@ -21,7 +22,7 @@ install(TARGETS kdecorations DESTINATION ${LIB_INSTALL_DIR} )
########### install files ###############
install( FILES kdecoration.h kdecoration_p.h kdecoration_plugins_p.h kdecorationfactory.h kcommondecoration.h DESTINATION ${INCLUDE_INSTALL_DIR})
install( FILES kdecoration.h kdecorationfactory.h kcommondecoration.h DESTINATION ${INCLUDE_INSTALL_DIR})
### effects lib ###
set(kwin_EFFECTSLIB_SRCS

View file

@ -22,6 +22,8 @@
DEALINGS IN THE SOFTWARE.
*/
#include "kcommondecoration.h"
#include <QApplication>
#include <QCursor>
#include <QDateTime>
@ -36,18 +38,22 @@
#include <klocale.h>
#include <QDesktopWidget>
#include "kcommondecoration.h"
#include "kcommondecoration_p.h"
#include "kcommondecoration.moc"
KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
: KDecoration (bridge, factory),
m_previewWidget(0),
: m_previewWidget(0),
btnHideMinWidth(200),
btnHideLastWidth(0),
closing(false)
closing(false),
wrapper( new KCommonDecorationWrapper( this, bridge, factory ))
{
// sizeof(...) is calculated at compile time
memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
connect( wrapper, SIGNAL( keepAboveChanged( bool )), this, SIGNAL( keepAboveChanged( bool )));
connect( wrapper, SIGNAL( keepBelowChanged( bool )), this, SIGNAL( keepBelowChanged( bool )));
}
KCommonDecoration::~KCommonDecoration()
@ -56,6 +62,7 @@ KCommonDecoration::~KCommonDecoration()
if (m_button[n]) delete m_button[n];
}
delete m_previewWidget;
// delete wrapper; - do not do this, this object is actually owned and deleted by the wrapper
}
QString KCommonDecoration::defaultButtonsLeft() const
@ -648,7 +655,7 @@ void KCommonDecoration::menuButtonPressed()
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
if( !f->exists( decoration())) // 'this' was deleted
return;
m_button[MenuButton]->setDown(false);
}
@ -974,5 +981,243 @@ void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent* e)
QAbstractButton::mouseReleaseEvent(&me);
}
// *** wrap everything from KDecoration *** //
bool KCommonDecoration::drawbound( const QRect&, bool )
{
return false;
}
bool KCommonDecoration::windowDocked( Position )
{
return false;
}
const KDecorationOptions* KCommonDecoration::options()
{
return KDecoration::options();
}
bool KCommonDecoration::isActive() const
{
return wrapper->isActive();
}
bool KCommonDecoration::isCloseable() const
{
return wrapper->isCloseable();
}
bool KCommonDecoration::isMaximizable() const
{
return wrapper->isMaximizable();
}
KCommonDecoration::MaximizeMode KCommonDecoration::maximizeMode() const
{
return wrapper->maximizeMode();
}
bool KCommonDecoration::isMinimizable() const
{
return wrapper->isMinimizable();
}
bool KCommonDecoration::providesContextHelp() const
{
return wrapper->providesContextHelp();
}
int KCommonDecoration::desktop() const
{
return wrapper->desktop();
}
bool KCommonDecoration::isOnAllDesktops() const
{
return wrapper->isOnAllDesktops();
}
bool KCommonDecoration::isModal() const
{
return wrapper->isModal();
}
bool KCommonDecoration::isShadeable() const
{
return wrapper->isShadeable();
}
bool KCommonDecoration::isShade() const
{
return wrapper->isShade();
}
bool KCommonDecoration::isSetShade() const
{
return wrapper->isSetShade();
}
bool KCommonDecoration::keepAbove() const
{
return wrapper->keepAbove();
}
bool KCommonDecoration::keepBelow() const
{
return wrapper->keepBelow();
}
bool KCommonDecoration::isMovable() const
{
return wrapper->isMovable();
}
bool KCommonDecoration::isResizable() const
{
return wrapper->isResizable();
}
NET::WindowType KCommonDecoration::windowType( unsigned long supported_types ) const
{
return wrapper->windowType( supported_types );
}
QIcon KCommonDecoration::icon() const
{
return wrapper->icon();
}
QString KCommonDecoration::caption() const
{
return wrapper->caption();
}
void KCommonDecoration::showWindowMenu( const QRect &pos )
{
return wrapper->showWindowMenu( pos );
}
void KCommonDecoration::showWindowMenu( QPoint pos )
{
return wrapper->showWindowMenu( pos );
}
void KCommonDecoration::performWindowOperation( WindowOperation op )
{
return wrapper->performWindowOperation( op );
}
void KCommonDecoration::setMask( const QRegion& reg, int mode )
{
return wrapper->setMask( reg, mode );
}
void KCommonDecoration::clearMask()
{
return wrapper->clearMask();
}
bool KCommonDecoration::isPreview() const
{
return wrapper->isPreview();
}
QRect KCommonDecoration::geometry() const
{
return wrapper->geometry();
}
QRect KCommonDecoration::iconGeometry() const
{
return wrapper->iconGeometry();
}
QRegion KCommonDecoration::unobscuredRegion( const QRegion& r ) const
{
return wrapper->unobscuredRegion( r );
}
WId KCommonDecoration::windowId() const
{
return wrapper->windowId();
}
int KCommonDecoration::width() const
{
return wrapper->width();
}
int KCommonDecoration::height() const
{
return wrapper->height();
}
void KCommonDecoration::processMousePressEvent( QMouseEvent* e )
{
return wrapper->processMousePressEvent( e );
}
void KCommonDecoration::setMainWidget( QWidget* w )
{
return wrapper->setMainWidget( w );
}
void KCommonDecoration::createMainWidget( Qt::WFlags flags )
{
return wrapper->createMainWidget( flags );
}
QWidget* KCommonDecoration::initialParentWidget() const
{
return wrapper->initialParentWidget();
}
Qt::WFlags KCommonDecoration::initialWFlags() const
{
return wrapper->initialWFlags();
}
QWidget* KCommonDecoration::widget()
{
return wrapper->widget();
}
const QWidget* KCommonDecoration::widget() const
{
return wrapper->widget();
}
KDecorationFactory* KCommonDecoration::factory() const
{
return wrapper->factory();
}
void KCommonDecoration::grabXServer()
{
return wrapper->grabXServer();
}
void KCommonDecoration::ungrabXServer()
{
return wrapper->ungrabXServer();
}
void KCommonDecoration::closeWindow()
{
return wrapper->closeWindow();
}
void KCommonDecoration::maximize( Qt::MouseButtons button )
{
return wrapper->maximize( button );
}
void KCommonDecoration::maximize( MaximizeMode mode )
{
return wrapper->maximize( mode );
}
void KCommonDecoration::minimize()
{
return wrapper->minimize();
}
void KCommonDecoration::showContextHelp()
{
return wrapper->showContextHelp();
}
void KCommonDecoration::setDesktop( int desktop )
{
return wrapper->setDesktop( desktop );
}
void KCommonDecoration::toggleOnAllDesktops()
{
return wrapper->toggleOnAllDesktops();
}
void KCommonDecoration::titlebarDblClickOperation()
{
return wrapper->titlebarDblClickOperation();
}
void KCommonDecoration::titlebarMouseWheelOperation( int delta )
{
return wrapper->titlebarMouseWheelOperation( delta );
}
void KCommonDecoration::setShade( bool set )
{
return wrapper->setShade( set );
}
void KCommonDecoration::setKeepAbove( bool set )
{
return wrapper->setKeepAbove( set );
}
void KCommonDecoration::setKeepBelow( bool set )
{
return wrapper->setKeepBelow( set );
}
// *** end of wrapping of everything from KDecoration *** //
const KDecoration* KCommonDecoration::decoration() const
{
return wrapper;
}
KDecoration* KCommonDecoration::decoration()
{
return wrapper;
}
// kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;

View file

@ -48,13 +48,18 @@ class KCommonDecorationButton;
class KCommonDecorationButtonPrivate;
class KCommonDecorationPrivate;
class KCommonDecorationWrapper;
/**
* 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.
* Note that for technical reasons KCommonDecoration does not inherit KDecoration but
* only provides the same API. If in rare cases you need to convert to KDecoration,
* use the decoration() function.
* See KDecoration documentation for all the wrapped functions.
*/
class KWIN_EXPORT KCommonDecoration : public KDecoration
class KWIN_EXPORT KCommonDecoration : public QObject, public KDecorationDefines
{
Q_OBJECT
@ -255,6 +260,76 @@ class KWIN_EXPORT KCommonDecoration : public KDecoration
virtual void mouseDoubleClickEvent(QMouseEvent *e);
virtual void wheelEvent(QWheelEvent *e);
// *** wrap everything from KDecoration *** //
// reimplementing from KDecoration (wrapped)
virtual bool drawbound( const QRect& geom, bool clear );
virtual bool windowDocked( Position side );
// wrap everything KDecoration provides
static const KDecorationOptions* options();
bool isActive() const;
bool isCloseable() const;
bool isMaximizable() const;
MaximizeMode maximizeMode() const;
bool isMinimizable() const;
bool providesContextHelp() const;
int desktop() const;
bool isOnAllDesktops() const; // convenience
bool isModal() const;
bool isShadeable() const;
bool isShade() const;
bool isSetShade() const;
bool keepAbove() const;
bool keepBelow() const;
bool isMovable() const;
bool isResizable() const;
NET::WindowType windowType( unsigned long supported_types ) const;
QIcon icon() const;
QString caption() const;
void showWindowMenu( const QRect &pos );
void showWindowMenu( QPoint pos );
void performWindowOperation( WindowOperation op );
void setMask( const QRegion& reg, int mode = 0 );
void clearMask(); // convenience
bool isPreview() const;
QRect geometry() const;
QRect iconGeometry() const;
QRegion unobscuredRegion( const QRegion& r ) const;
WId windowId() const;
int width() const; // convenience
int height() const; // convenience
void processMousePressEvent( QMouseEvent* e );
Q_SIGNALS:
void keepAboveChanged( bool );
void keepBelowChanged( bool );
public:
void setMainWidget( QWidget* );
void createMainWidget( Qt::WFlags flags = 0 );
QWidget* initialParentWidget() const;
Qt::WFlags initialWFlags() const;
QWidget* widget();
const QWidget* widget() const;
KDecorationFactory* factory() const;
void grabXServer();
void ungrabXServer();
public Q_SLOTS:
void closeWindow();
void maximize( Qt::MouseButtons button );
void maximize( MaximizeMode mode );
void minimize();
void showContextHelp();
void setDesktop( int desktop );
void toggleOnAllDesktops(); // convenience
void titlebarDblClickOperation();
void titlebarMouseWheelOperation( int delta );
void setShade( bool set );
void setKeepAbove( bool set );
void setKeepBelow( bool set );
// *** end of wrapping of everything from KDecoration *** //
public:
// access the KDecoration wrapper
const KDecoration* decoration() const;
KDecoration* decoration();
private:
void resetLayout();
@ -279,6 +354,8 @@ class KWIN_EXPORT KCommonDecoration : public KDecoration
bool closing; // for menu doubleclick closing...
KCommonDecorationWrapper* wrapper;
KCommonDecorationPrivate *d;
};

111
lib/kcommondecoration_p.cpp Normal file
View file

@ -0,0 +1,111 @@
/*
This file is part of the KDE project.
Copyright (C) 2007 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 "kcommondecoration_p.h"
#include "kcommondecoration.h"
#include "kcommondecoration_p.moc"
KCommonDecorationWrapper::KCommonDecorationWrapper( KCommonDecoration* deco, KDecorationBridge* bridge, KDecorationFactory* factory )
: KDecoration( bridge, factory )
, decoration( deco )
{
}
KCommonDecorationWrapper::~KCommonDecorationWrapper()
{
// the wrapper actually owns KCommonDecoration, since the wrapper is what KWin core uses
delete decoration;
}
void KCommonDecorationWrapper::init()
{
return decoration->init();
}
KCommonDecorationWrapper::Position KCommonDecorationWrapper::mousePosition( const QPoint& p ) const
{
return decoration->mousePosition( p );
}
void KCommonDecorationWrapper::borders( int& left, int& right, int& top, int& bottom ) const
{
return decoration->borders( left, right, top, bottom );
}
void KCommonDecorationWrapper::resize( const QSize& s )
{
return decoration->resize( s );
}
QSize KCommonDecorationWrapper::minimumSize() const
{
return decoration->minimumSize();
}
void KCommonDecorationWrapper::activeChange()
{
return decoration->activeChange();
}
void KCommonDecorationWrapper::captionChange()
{
return decoration->captionChange();
}
void KCommonDecorationWrapper::iconChange()
{
return decoration->iconChange();
}
void KCommonDecorationWrapper::maximizeChange()
{
return decoration->maximizeChange();
}
void KCommonDecorationWrapper::desktopChange()
{
return decoration->desktopChange();
}
void KCommonDecorationWrapper::shadeChange()
{
return decoration->shadeChange();
}
bool KCommonDecorationWrapper::drawbound( const QRect& geom, bool clear )
{
return decoration->drawbound( geom, clear );
}
bool KCommonDecorationWrapper::windowDocked( Position side )
{
return decoration->windowDocked( side );
}
void KCommonDecorationWrapper::reset( unsigned long changed )
{
return decoration->reset( changed );
}

60
lib/kcommondecoration_p.h Normal file
View file

@ -0,0 +1,60 @@
/*
This file is part of the KDE project.
Copyright (C) 2007 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 KCOMMONDECORATION_P_H
#define KCOMMONDECORATION_P_H
#include "kdecoration.h"
class KCommonDecoration;
class KDecorationBridge;
class KDecorationFactory;
// wrapper all functionality that needs reimplementing in KDecoration and forward it to KCommonDecoration
class KCommonDecorationWrapper
: public KDecoration
{
Q_OBJECT
public:
KCommonDecorationWrapper( KCommonDecoration* deco, KDecorationBridge* bridge, KDecorationFactory* factory );
virtual ~KCommonDecorationWrapper();
virtual void init();
virtual Position mousePosition( const QPoint& p ) const;
virtual void borders( int& left, int& right, int& top, int& bottom ) const;
virtual void resize( const QSize& s );
virtual QSize minimumSize() const;
virtual void activeChange();
virtual void captionChange();
virtual void iconChange();
virtual void maximizeChange();
virtual void desktopChange();
virtual void shadeChange();
virtual bool drawbound( const QRect& geom, bool clear );
virtual bool windowDocked( Position side );
virtual void reset( unsigned long changed );
private:
KCommonDecoration* decoration;
};
#endif // KCOMMONDECORATION_P_H

View file

@ -37,6 +37,24 @@ DEALINGS IN THE SOFTWARE.
#include "kdecoration_p.h"
#include "kdecorationfactory.h"
/*
Extending KDecoration:
======================
If KDecoration will ever need to be extended in a way that'd break binary compatibility
(i.e. adding new virtual methods most probably), new class KDecoration2 should be
inherited from KDecoration and those methods added there. Code that would depend
on the new functionality could then dynamic_cast<> to KDecoration2 to check whether
it is available and use it.
KCommonDecoration would have to be extended the same way, adding KCommonDecoration2
inheriting KCommonDecoration and adding the new API matching KDecoration2.
*/
KDecorationOptions* KDecoration::options_;
KDecoration::KDecoration( KDecorationBridge* bridge, KDecorationFactory* factory )