kde-workspace/kstyles/oxygen/oxygenwindowmanager.h

319 lines
8.8 KiB
C++

#ifndef OXYGENWINDOWMANAGER_H
#define OXYGENWINDOWMANAGER_H
//////////////////////////////////////////////////////////////////////////////
// oxygenwindowmanager.h
// pass some window mouse press/release/move event actions to window manager
// -------------------
//
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
//
// Largely inspired from BeSpin style
// Copyright (C) 2007 Thomas Luebking <thomas.luebking@web.de>
//
// 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 <QtCore/QEvent>
#include <QtCore/QBasicTimer>
#include <QtCore/QObject>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtCore/qsharedpointer.h>
#include <QtGui/QWidget>
namespace Oxygen
{
class WindowManager: public QObject
{
Q_OBJECT
public:
//! constructor
explicit WindowManager( QObject* );
//! destructor
virtual ~WindowManager( void )
{}
//! initialize
/*! read relevant options from OxygenStyleConfigData */
void initialize( void );
//! register widget
void registerWidget( QWidget* );
//! unregister widget
void unregisterWidget( QWidget* );
//! event filter [reimplemented]
virtual bool eventFilter( QObject*, QEvent* );
protected:
//! timer event,
/*! used to start drag if button is pressed for a long enough time */
void timerEvent( QTimerEvent* );
//! mouse press event
bool mousePressEvent( QObject*, QEvent* );
//! mouse move event
bool mouseMoveEvent( QObject*, QEvent* );
//! mouse release event
bool mouseReleaseEvent( QObject*, QEvent* );
//!@name configuration
//@{
//! enable state
bool enabled( void ) const
{ return _enabled; }
//! enable state
void setEnabled( bool value )
{ _enabled = value; }
//! returns true if window manager is used for moving
bool useWMMoveResize( void ) const
{ return supportWMMoveResize() && _useWMMoveResize; }
//! use window manager for moving, when available
void setUseWMMoveResize( bool value )
{ _useWMMoveResize = value; }
//! drag mode
int dragMode( void ) const
{ return _dragMode; }
//! drag mode
void setDragMode( int value )
{ _dragMode = value; }
//! drag distance (pixels)
void setDragDistance( int value )
{ _dragDistance = value; }
//! drag delay (msec)
void setDragDelay( int value )
{ _dragDelay = value; }
//! set list of whiteListed widgets
/*!
white list is read from options and is used to adjust
per-app window dragging issues
*/
void initializeWhiteList();
//! set list of blackListed widgets
/*!
black list is read from options and is used to adjust
per-app window dragging issues
*/
void initializeBlackList( void );
//@}
//! returns true if widget is dragable
bool isDragable( QWidget* );
//! returns true if widget is dragable
bool isBlackListed( QWidget* );
//! returns true if widget is dragable
bool isWhiteListed( QWidget* ) const;
//! returns true if drag can be started from current widget
bool canDrag( QWidget* );
//! returns true if drag can be started from current widget and position
/*! child at given position is passed as second argument */
bool canDrag( QWidget*, QWidget*, const QPoint& );
//! reset drag
void resetDrag( void );
//! start drag
void startDrag( QWidget*, const QPoint& );
//! returns true if window manager is used for moving
/*! right now this is true only for X11 */
bool supportWMMoveResize( void ) const;
//! utility function
bool isDockWidgetTitle( const QWidget* ) const;
//!@name lock
//@{
void setLocked( bool value )
{ _locked = value; }
//! lock
bool isLocked( void ) const
{ return _locked; }
//@}
//! returns first widget matching given class, or 0L if none
template<typename T> T findParent( const QWidget* ) const;
private:
//! enability
bool _enabled;
//! use WM moveResize
bool _useWMMoveResize;
//! drag mode
int _dragMode;
//! drag distance
/*! this is copied from kwin::geometry */
int _dragDistance;
//! drag delay
/*! this is copied from kwin::geometry */
int _dragDelay;
//! wrapper for exception id
class ExceptionId: public QPair<QString, QString>
{
public:
//! constructor
explicit ExceptionId( const QString& value )
{
const QStringList args( value.split( "@" ) );
if( args.isEmpty() ) return;
second = args[0].trimmed();
if( args.size()>1 ) first = args[1].trimmed();
}
const QString& appName( void ) const
{ return first; }
const QString& className( void ) const
{ return second; }
};
//! exception set
typedef QSet<ExceptionId> ExceptionSet;
//! list of white listed special widgets
/*!
it is read from options and is used to adjust
per-app window dragging issues
*/
ExceptionSet _whiteList;
//! list of black listed special widgets
/*!
it is read from options and is used to adjust
per-app window dragging issues
*/
ExceptionSet _blackList;
//! drag point
QPoint _dragPoint;
QPoint _globalDragPoint;
//! drag timer
QBasicTimer _dragTimer;
//! target being dragged
/*! QWeakPointer is used in case the target gets deleted while drag is in progress */
QWeakPointer<QWidget> _target;
//! true if drag is about to start
bool _dragAboutToStart;
//! true if drag is in progress
bool _dragInProgress;
//! true if drag is locked
bool _locked;
//! cursor override
/*! used to keep track of application cursor being overridden when dragging in non-WM mode */
bool _cursorOverride;
//! provide application-wise event filter
/*!
it us used to unlock dragging and make sure event look is properly restored
after a drag has occurred
*/
class AppEventFilter: public QObject
{
public:
//! constructor
explicit AppEventFilter( WindowManager* parent ):
QObject( parent ),
_parent( parent )
{}
//! event filter
virtual bool eventFilter( QObject*, QEvent* );
protected:
//! application-wise event.
/*! needed to catch end of XMoveResize events */
bool appMouseEvent( QObject*, QEvent* );
private:
//! parent
WindowManager* _parent;
};
//! application event filter
AppEventFilter* _appEventFilter;
//! allow access of all private members to the app event filter
friend class AppEventFilter;
};
//____________________________________________________________________
template<typename T>
T WindowManager::findParent( const QWidget* widget ) const
{
if( !widget ) return 0L;
for( QWidget* parent = widget->parentWidget(); parent; parent = parent->parentWidget() )
{ if( T cast = qobject_cast<T>(parent) ) return cast; }
return 0L;
}
}
#endif