Blame style/adwaitawindowmanager.h

Packit 8e9c33
#ifndef adwaitawindowmanager_h
Packit 8e9c33
#define adwaitawindowmanager_h
Packit 8e9c33
Packit 8e9c33
/*************************************************************************
Packit 8e9c33
 * Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr>    *
Packit 8e9c33
 *                                                                       *
Packit 8e9c33
 * This program is free software; you can redistribute it and/or modify  *
Packit 8e9c33
 * it under the terms of the GNU General Public License as published by  *
Packit 8e9c33
 * the Free Software Foundation; either version 2 of the License, or     *
Packit 8e9c33
 * (at your option) any later version.                                   *
Packit 8e9c33
 *                                                                       *
Packit 8e9c33
 * This program is distributed in the hope that it will be useful,       *
Packit 8e9c33
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
Packit 8e9c33
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
Packit 8e9c33
 * GNU General Public License for more details.                          *
Packit 8e9c33
 *                                                                       *
Packit 8e9c33
 * You should have received a copy of the GNU General Public License     *
Packit 8e9c33
 * along with this program; if not, write to the                         *
Packit 8e9c33
 * Free Software Foundation, Inc.,                                       *
Packit 8e9c33
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
Packit 8e9c33
 *************************************************************************/
Packit 8e9c33
Packit 8e9c33
#include "adwaita.h"
Packit 8e9c33
#include "config-adwaita.h"
Packit 8e9c33
Packit 8e9c33
#include <QEvent>
Packit 8e9c33
Packit 8e9c33
#include <QBasicTimer>
Packit 8e9c33
#include <QObject>
Packit 8e9c33
#include <QSet>
Packit 8e9c33
#include <QString>
Packit 8e9c33
#include <QWidget>
Packit 8e9c33
Packit 8e9c33
#if ADWAITA_HAVE_KWAYLAND
Packit 8e9c33
namespace KWayland
Packit 8e9c33
{
Packit 8e9c33
namespace Client
Packit 8e9c33
{
Packit 8e9c33
    class Pointer;
Packit 8e9c33
    class Seat;
Packit 8e9c33
}
Packit 8e9c33
}
Packit 8e9c33
#endif
Packit 8e9c33
Packit 8e9c33
namespace Adwaita
Packit 8e9c33
{
Packit 8e9c33
Packit 8e9c33
    class WindowManager: public QObject
Packit 8e9c33
    {
Packit 8e9c33
Packit 8e9c33
        Q_OBJECT
Packit 8e9c33
Packit 8e9c33
        public:
Packit 8e9c33
Packit 8e9c33
        //* constructor
Packit 8e9c33
        explicit WindowManager( QObject* );
Packit 8e9c33
Packit 8e9c33
        //* destructor
Packit 8e9c33
        virtual ~WindowManager( void )
Packit 8e9c33
        {}
Packit 8e9c33
Packit 8e9c33
        //* initialize
Packit 8e9c33
        /** read relevant options from config */
Packit 8e9c33
        void initialize( void );
Packit 8e9c33
Packit 8e9c33
        //* register widget
Packit 8e9c33
        void registerWidget( QWidget* );
Packit 8e9c33
Packit 8e9c33
        //* unregister widget
Packit 8e9c33
        void unregisterWidget( QWidget* );
Packit 8e9c33
Packit 8e9c33
        //* event filter [reimplemented]
Packit 8e9c33
        virtual bool eventFilter( QObject*, QEvent* );
Packit 8e9c33
Packit 8e9c33
        protected:
Packit 8e9c33
Packit 8e9c33
        //* timer event,
Packit 8e9c33
        /** used to start drag if button is pressed for a long enough time */
Packit 8e9c33
        void timerEvent( QTimerEvent* );
Packit 8e9c33
Packit 8e9c33
        //* mouse press event
Packit 8e9c33
        bool mousePressEvent( QObject*, QEvent* );
Packit 8e9c33
Packit 8e9c33
        //* mouse move event
Packit 8e9c33
        bool mouseMoveEvent( QObject*, QEvent* );
Packit 8e9c33
Packit 8e9c33
        //* mouse release event
Packit 8e9c33
        bool mouseReleaseEvent( QObject*, QEvent* );
Packit 8e9c33
Packit 8e9c33
        //*@name configuration
Packit 8e9c33
        //@{
Packit 8e9c33
Packit 8e9c33
        //* enable state
Packit 8e9c33
        bool enabled( void ) const
Packit 8e9c33
        { return _enabled; }
Packit 8e9c33
Packit 8e9c33
        //* enable state
Packit 8e9c33
        void setEnabled( bool value )
Packit 8e9c33
        { _enabled = value; }
Packit 8e9c33
Packit 8e9c33
        //* returns true if window manager is used for moving
Packit 8e9c33
        bool useWMMoveResize( void ) const
Packit 8e9c33
        { return supportWMMoveResize() && _useWMMoveResize; }
Packit 8e9c33
Packit 8e9c33
        //* use window manager for moving, when available
Packit 8e9c33
        void setUseWMMoveResize( bool value )
Packit 8e9c33
        { _useWMMoveResize = value; }
Packit 8e9c33
Packit 8e9c33
        //* drag mode
Packit 8e9c33
        int dragMode( void ) const
Packit 8e9c33
        { return _dragMode; }
Packit 8e9c33
Packit 8e9c33
        //* drag mode
Packit 8e9c33
        void setDragMode( int value )
Packit 8e9c33
        { _dragMode = value; }
Packit 8e9c33
Packit 8e9c33
        //* drag distance (pixels)
Packit 8e9c33
        void setDragDistance( int value )
Packit 8e9c33
        { _dragDistance = value; }
Packit 8e9c33
Packit 8e9c33
        //* drag delay (msec)
Packit 8e9c33
        void setDragDelay( int value )
Packit 8e9c33
        { _dragDelay = value; }
Packit 8e9c33
Packit 8e9c33
        //* set list of whiteListed widgets
Packit 8e9c33
        /**
Packit 8e9c33
        white list is read from options and is used to adjust
Packit 8e9c33
        per-app window dragging issues
Packit 8e9c33
        */
Packit 8e9c33
        void initializeWhiteList();
Packit 8e9c33
Packit 8e9c33
        //* set list of blackListed widgets
Packit 8e9c33
        /**
Packit 8e9c33
        black list is read from options and is used to adjust
Packit 8e9c33
        per-app window dragging issues
Packit 8e9c33
        */
Packit 8e9c33
        void initializeBlackList( void );
Packit 8e9c33
Packit 8e9c33
        //* initializes the Wayland specific parts
Packit 8e9c33
        void initializeWayland();
Packit 8e9c33
Packit 8e9c33
        //* The Wayland Seat's hasPointer property changed
Packit 8e9c33
        void waylandHasPointerChanged(bool hasPointer);
Packit 8e9c33
Packit 8e9c33
        //@}
Packit 8e9c33
Packit 8e9c33
        //* returns true if widget is dragable
Packit 8e9c33
        bool isDragable( QWidget* );
Packit 8e9c33
Packit 8e9c33
        //* returns true if widget is dragable
Packit 8e9c33
        bool isBlackListed( QWidget* );
Packit 8e9c33
Packit 8e9c33
        //* returns true if widget is dragable
Packit 8e9c33
        bool isWhiteListed( QWidget* ) const;
Packit 8e9c33
Packit 8e9c33
        //* returns true if drag can be started from current widget
Packit 8e9c33
        bool canDrag( QWidget* );
Packit 8e9c33
Packit 8e9c33
        //* returns true if drag can be started from current widget and position
Packit 8e9c33
        /** child at given position is passed as second argument */
Packit 8e9c33
        bool canDrag( QWidget*, QWidget*, const QPoint& );
Packit 8e9c33
Packit 8e9c33
        //* reset drag
Packit 8e9c33
        void resetDrag( void );
Packit 8e9c33
Packit 8e9c33
        //* start drag
Packit 8e9c33
        void startDrag( QWidget*, const QPoint& );
Packit 8e9c33
Packit 8e9c33
        //* X11 specific implementation for startDrag
Packit 8e9c33
        void startDragX11( QWidget*, const QPoint& );
Packit 8e9c33
Packit 8e9c33
        //* Wayland specific implementation for startDrag
Packit 8e9c33
        void startDragWayland( QWidget*, const QPoint& );
Packit 8e9c33
Packit 8e9c33
        //* returns true if window manager is used for moving
Packit 8e9c33
        /** right now this is true only for X11 */
Packit 8e9c33
        bool supportWMMoveResize( void ) const;
Packit 8e9c33
Packit 8e9c33
        //* utility function
Packit 8e9c33
        bool isDockWidgetTitle( const QWidget* ) const;
Packit 8e9c33
Packit 8e9c33
        //*@name lock
Packit 8e9c33
        //@{
Packit 8e9c33
Packit 8e9c33
        void setLocked( bool value )
Packit 8e9c33
        { _locked = value; }
Packit 8e9c33
Packit 8e9c33
        //* lock
Packit 8e9c33
        bool isLocked( void ) const
Packit 8e9c33
        { return _locked; }
Packit 8e9c33
Packit 8e9c33
        //@}
Packit 8e9c33
Packit 8e9c33
        //* returns first widget matching given class, or 0L if none
Packit 8e9c33
        template<typename T> T findParent( const QWidget* ) const;
Packit 8e9c33
Packit 8e9c33
        private:
Packit 8e9c33
Packit 8e9c33
        //* enability
Packit 8e9c33
        bool _enabled;
Packit 8e9c33
Packit 8e9c33
        //* use WM moveResize
Packit 8e9c33
        bool _useWMMoveResize;
Packit 8e9c33
Packit 8e9c33
        //* drag mode
Packit 8e9c33
        int _dragMode;
Packit 8e9c33
Packit 8e9c33
        //* drag distance
Packit 8e9c33
        /** this is copied from kwin::geometry */
Packit 8e9c33
        int _dragDistance;
Packit 8e9c33
Packit 8e9c33
        //* drag delay
Packit 8e9c33
        /** this is copied from kwin::geometry */
Packit 8e9c33
        int _dragDelay;
Packit 8e9c33
Packit 8e9c33
        //* wrapper for exception id
Packit 8e9c33
        class ExceptionId: public QPair<QString, QString>
Packit 8e9c33
        {
Packit 8e9c33
            public:
Packit 8e9c33
Packit 8e9c33
            //* constructor
Packit 8e9c33
            explicit ExceptionId( const QString& value )
Packit 8e9c33
            {
Packit 8e9c33
                const QStringList args( value.split( QChar::fromLatin1( '@' ) ) );
Packit 8e9c33
                if( args.isEmpty() ) return;
Packit 8e9c33
                second = args[0].trimmed();
Packit 8e9c33
                if( args.size()>1 ) first = args[1].trimmed();
Packit 8e9c33
            }
Packit 8e9c33
Packit 8e9c33
            const QString& appName( void ) const
Packit 8e9c33
            { return first; }
Packit 8e9c33
Packit 8e9c33
            const QString& className( void ) const
Packit 8e9c33
            { return second; }
Packit 8e9c33
Packit 8e9c33
        };
Packit 8e9c33
Packit 8e9c33
        //* exception set
Packit 8e9c33
        using ExceptionSet = QSet<ExceptionId>;
Packit 8e9c33
Packit 8e9c33
        //* list of white listed special widgets
Packit 8e9c33
        /**
Packit 8e9c33
        it is read from options and is used to adjust
Packit 8e9c33
        per-app window dragging issues
Packit 8e9c33
        */
Packit 8e9c33
        ExceptionSet _whiteList;
Packit 8e9c33
Packit 8e9c33
        //* list of black listed special widgets
Packit 8e9c33
        /**
Packit 8e9c33
        it is read from options and is used to adjust
Packit 8e9c33
        per-app window dragging issues
Packit 8e9c33
        */
Packit 8e9c33
        ExceptionSet _blackList;
Packit 8e9c33
Packit 8e9c33
        //* drag point
Packit 8e9c33
        QPoint _dragPoint;
Packit 8e9c33
        QPoint _globalDragPoint;
Packit 8e9c33
Packit 8e9c33
        //* drag timer
Packit 8e9c33
        QBasicTimer _dragTimer;
Packit 8e9c33
Packit 8e9c33
        //* target being dragged
Packit 8e9c33
        /** Weak pointer is used in case the target gets deleted while drag is in progress */
Packit 8e9c33
        WeakPointer<QWidget> _target;
Packit 8e9c33
Packit 8e9c33
        //* true if drag is about to start
Packit 8e9c33
        bool _dragAboutToStart;
Packit 8e9c33
Packit 8e9c33
        //* true if drag is in progress
Packit 8e9c33
        bool _dragInProgress;
Packit 8e9c33
Packit 8e9c33
        //* true if drag is locked
Packit 8e9c33
        bool _locked;
Packit 8e9c33
Packit 8e9c33
        //* cursor override
Packit 8e9c33
        /** used to keep track of application cursor being overridden when dragging in non-WM mode */
Packit 8e9c33
        bool _cursorOverride;
Packit 8e9c33
Packit 8e9c33
        //* application event filter
Packit 8e9c33
        QObject* _appEventFilter;
Packit 8e9c33
Packit 8e9c33
        #if ADWAITA_HAVE_KWAYLAND
Packit 8e9c33
        //* The Wayland seat object which needs to be passed to move requests.
Packit 8e9c33
        KWayland::Client::Seat* _seat;
Packit 8e9c33
        //* The Wayland pointer object where we get pointer events on.
Packit 8e9c33
        KWayland::Client::Pointer* _pointer;
Packit 8e9c33
        //* latest searial which needs to be passed to the move requests.
Packit 8e9c33
        quint32 _waylandSerial;
Packit 8e9c33
        #endif
Packit 8e9c33
Packit 8e9c33
        //* allow access of all private members to the app event filter
Packit 8e9c33
        friend class AppEventFilter;
Packit 8e9c33
Packit 8e9c33
    };
Packit 8e9c33
Packit 8e9c33
    //____________________________________________________________________
Packit 8e9c33
    template<typename T>
Packit 8e9c33
        T WindowManager::findParent( const QWidget* widget ) const
Packit 8e9c33
    {
Packit 8e9c33
Packit 8e9c33
        if( !widget ) return 0L;
Packit 8e9c33
        for( QWidget* parent = widget->parentWidget(); parent; parent = parent->parentWidget() )
Packit 8e9c33
        { if( T cast = qobject_cast<T>(parent) ) return cast; }
Packit 8e9c33
Packit 8e9c33
        return 0L;
Packit 8e9c33
    }
Packit 8e9c33
Packit 8e9c33
}
Packit 8e9c33
Packit 8e9c33
#endif