2009-09-13 15:36:45 +04:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
2013-03-12 16:17:53 +04:00
|
|
|
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
|
2009-09-13 15:36:45 +04:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
#ifndef TABBOXHANDLER_H
|
|
|
|
#define TABBOXHANDLER_H
|
|
|
|
|
|
|
|
#include "tabboxconfig.h"
|
|
|
|
|
|
|
|
#include <QModelIndex>
|
|
|
|
#include <QPixmap>
|
|
|
|
#include <QString>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <fixx11h.h>
|
2013-01-28 17:17:12 +04:00
|
|
|
#include <xcb/xcb.h>
|
2009-09-13 15:36:45 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* This file contains the classes which hide KWin core from tabbox.
|
|
|
|
* It defines the pure virtual classes TabBoxHandler and TabBoxClient.
|
|
|
|
* The classes have to be implemented in KWin Core.
|
|
|
|
*
|
2013-03-12 16:17:53 +04:00
|
|
|
* @author Martin Gräßlin <mgraesslin@kde.org>
|
2009-09-13 15:36:45 +04:00
|
|
|
* @since 4.4
|
|
|
|
*/
|
|
|
|
|
|
|
|
class QKeyEvent;
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* The TabBox is a model based view for displaying a list while switching windows or desktops.
|
|
|
|
* This functionality is mostly referred as Alt+Tab. TabBox itself does not provide support for
|
|
|
|
* switching windows or desktops. This has to be done outside of TabBox inside an independent controller.
|
|
|
|
*
|
|
|
|
* The main entrance point to TabBox is the class TabBoxHandler, which has to be subclassed and implemented.
|
|
|
|
* The class TabBoxClient, which represents a window client inside TabBox, has to be implemented as well.
|
|
|
|
*
|
|
|
|
* The behavior of the TabBox is defined by the TabBoxConfig and has to be set in the TabBoxHandler.
|
|
|
|
* If the TabBox should be used to switch desktops as well as clients it is sufficient to just provide
|
|
|
|
* different TabBoxConfig objects instead of creating an own handler for each mode.
|
|
|
|
*
|
|
|
|
* In order to use the TabBox the TabBoxConfig has to be set. This defines if the model for desktops or for
|
|
|
|
* clients will be used. The model has to be initialized by calling TabBoxHandler::createModel(), as the
|
|
|
|
* model is undefined when the TabBox is not active. The TabBox is activated by TabBoxHandler::show().
|
2013-04-24 10:27:31 +04:00
|
|
|
* Depending on the current set TabBoxConfig it is possible that the
|
2009-09-13 15:36:45 +04:00
|
|
|
* highlight windows effect activated and that the view is not displayed at all. As already mentioned
|
|
|
|
* the TabBox does not handle any updating of the selected item. This has to be done by invoking
|
|
|
|
* TabBoxHandler::setCurrentIndex(). Nevertheless the TabBoxHandler provides methods to query for the
|
|
|
|
* model index or the next or previous item, for a cursor position or for a given item (that is
|
2013-04-24 10:27:31 +04:00
|
|
|
* TabBoxClient or desktop). By invoking TabBoxHandler::hide() the view, the
|
2009-09-13 15:36:45 +04:00
|
|
|
* optional highlight windows effect are removed. The model is invalidated immediately. So if it is
|
|
|
|
* necessary to retrieve the last selected item this has to be done before calling the hide method.
|
|
|
|
*
|
|
|
|
* The layout of the TabBox View and the items is completely customizable. Therefore TabBox provides
|
|
|
|
* a widget LayoutConfig which includes a live preview (in kcmkwin/kwintabbox). The layout of items
|
|
|
|
* can be defined by an xml document. That way the user is able to define own custom layouts. The view
|
|
|
|
* itself is made up of two widgets: one to show the complete list and one to show only the selected
|
|
|
|
* item. This way it is possible to have a view which shows for example a list containing only small
|
|
|
|
* icons and nevertheless show the title of the currently selected client.
|
|
|
|
*/
|
|
|
|
namespace TabBox
|
|
|
|
{
|
|
|
|
class DesktopModel;
|
|
|
|
class ClientModel;
|
|
|
|
class TabBoxConfig;
|
|
|
|
class TabBoxClient;
|
|
|
|
class TabBoxHandlerPrivate;
|
2012-05-20 17:52:24 +04:00
|
|
|
typedef QList< QWeakPointer< TabBoxClient > > TabBoxClientList;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class is a wrapper around KWin Workspace. It is used for accessing the
|
|
|
|
* required core methods from inside TabBox and has to be implemented in KWin core.
|
|
|
|
*
|
2013-03-12 16:17:53 +04:00
|
|
|
* @author Martin Gräßlin <mgraesslin@kde.org>
|
2009-09-13 15:36:45 +04:00
|
|
|
* @since 4.4
|
|
|
|
*/
|
|
|
|
class TabBoxHandler : public QObject
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2009-09-13 15:36:45 +04:00
|
|
|
Q_OBJECT
|
2011-01-30 17:34:42 +03:00
|
|
|
public:
|
2014-05-27 12:10:07 +04:00
|
|
|
TabBoxHandler(QObject *parent);
|
2011-01-30 17:34:42 +03:00
|
|
|
virtual ~TabBoxHandler();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return The id of the active screen
|
|
|
|
*/
|
|
|
|
virtual int activeScreen() const = 0;
|
|
|
|
/**
|
|
|
|
* @return The current active TabBoxClient or NULL
|
|
|
|
* if there is no active client.
|
|
|
|
*/
|
2012-05-20 17:52:24 +04:00
|
|
|
virtual QWeakPointer<TabBoxClient> activeClient() const = 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @param client The client which is starting point to find the next client
|
|
|
|
* @return The next TabBoxClient in focus chain
|
|
|
|
*/
|
2012-05-20 17:52:24 +04:00
|
|
|
virtual QWeakPointer<TabBoxClient> nextClientFocusChain(TabBoxClient* client) const = 0;
|
2012-08-19 21:32:56 +04:00
|
|
|
/**
|
|
|
|
* This method is used by the ClientModel to find an entrance into the focus chain in case
|
|
|
|
* there is no active Client.
|
|
|
|
*
|
|
|
|
* @return The first Client of the focus chain
|
|
|
|
* @since 4.9.1
|
|
|
|
**/
|
|
|
|
virtual QWeakPointer<TabBoxClient> firstClientFocusChain() const = 0;
|
2012-09-05 22:55:07 +04:00
|
|
|
/**
|
|
|
|
* Checks whether the given @p client is part of the focus chain at all.
|
|
|
|
* This is useful to figure out whether the currently active Client can be used
|
|
|
|
* as a starting point to construct the recently used list.
|
|
|
|
*
|
|
|
|
* In case the @p client is not in the focus chain it is recommended to use the
|
|
|
|
* Client returned by @link firstClientFocusChain.
|
|
|
|
*
|
|
|
|
* The method accepts a @c null Client and in that case @c false is returned.
|
|
|
|
* @param client The Client to check whether it is in the Focus Chain
|
|
|
|
* @return @c true in case the Client is part of the focus chain, @c false otherwise.
|
|
|
|
* @since 4.9.2
|
|
|
|
**/
|
|
|
|
virtual bool isInFocusChain(TabBoxClient* client) const = 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @param client The client whose desktop name should be retrieved
|
|
|
|
* @return The desktop name of the given TabBoxClient. If the client is
|
|
|
|
* on all desktops the name of current desktop will be returned.
|
|
|
|
*/
|
|
|
|
virtual QString desktopName(TabBoxClient* client) const = 0;
|
|
|
|
/**
|
|
|
|
* @param desktop The desktop whose name should be retrieved
|
|
|
|
* @return The desktop name of given desktop
|
|
|
|
*/
|
|
|
|
virtual QString desktopName(int desktop) const = 0;
|
|
|
|
/**
|
|
|
|
* @return The number of current desktop
|
|
|
|
*/
|
|
|
|
virtual int currentDesktop() const = 0;
|
|
|
|
/**
|
|
|
|
* @return The number of virtual desktops
|
|
|
|
*/
|
|
|
|
virtual int numberOfDesktops() const = 0;
|
|
|
|
/**
|
|
|
|
* @param desktop The desktop which is the starting point to find the next desktop
|
|
|
|
* @return The next desktop in the current focus chain.
|
|
|
|
*/
|
|
|
|
virtual int nextDesktopFocusChain(int desktop) const = 0;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2013-04-12 22:15:31 +04:00
|
|
|
/**
|
|
|
|
* whether KWin is currently compositing and it's related features (elevating) can be used
|
|
|
|
*/
|
|
|
|
virtual bool isKWinCompositing() const = 0;
|
|
|
|
|
2012-04-11 03:19:15 +04:00
|
|
|
/**
|
|
|
|
* De-/Elevate a client using the compositor (if enabled)
|
|
|
|
*/
|
2016-03-04 11:44:24 +03:00
|
|
|
virtual void elevateClient(TabBoxClient* c, QWindow *tabbox, bool elevate) const = 0;
|
2012-04-11 03:19:15 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Raise a client (w/o activating it)
|
|
|
|
*/
|
|
|
|
virtual void raiseClient(TabBoxClient* c) const = 0;
|
2010-10-17 23:49:07 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @param c The client to be restacked
|
|
|
|
* @param under The client the other one will be placed below
|
|
|
|
*/
|
|
|
|
virtual void restack(TabBoxClient *c, TabBoxClient *under) = 0;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2015-02-07 01:10:59 +03:00
|
|
|
/**
|
|
|
|
* Toggle between ShadeHover and ShadeNormal - not shaded windows are unaffected
|
|
|
|
* @param c The client to be shaded
|
|
|
|
* @param b Whether to un- or shade
|
|
|
|
*/
|
|
|
|
virtual void shadeClient(TabBoxClient *c, bool b) const = 0;
|
|
|
|
|
2016-08-30 16:50:31 +03:00
|
|
|
virtual void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) = 0;
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return The current stacking order of TabBoxClients
|
|
|
|
*/
|
|
|
|
virtual TabBoxClientList stackingOrder() const = 0;
|
|
|
|
/**
|
|
|
|
* Determines if given client will be added to the list:
|
|
|
|
* <UL>
|
|
|
|
* <LI>Depends on desktop</LI>
|
|
|
|
* <LI>if the client wants to have tab focus.</LI>
|
|
|
|
* <LI>The client won't be added if it has modal dialogs</LI>
|
|
|
|
* <LI>In that case the modal dialog will be returned if it isn't already
|
|
|
|
* included</LI>
|
|
|
|
* <LI>Won't be added if it isn't on active screen when using separate
|
|
|
|
* screen focus</LI>
|
|
|
|
* </UL>
|
|
|
|
* @param client The client to be checked for inclusion
|
|
|
|
* @param desktop The desktop the client should be on. This is irrelevant if allDesktops is set
|
|
|
|
* @param allDesktops Add clients from all desktops or only from current
|
|
|
|
* @return The client to be included in the list or NULL if it isn't to be included
|
|
|
|
*/
|
2012-05-20 17:52:24 +04:00
|
|
|
virtual QWeakPointer<TabBoxClient> clientToAddToList(TabBoxClient* client, int desktop) const = 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return The first desktop window in the stacking order.
|
|
|
|
*/
|
2012-05-20 17:52:24 +04:00
|
|
|
virtual QWeakPointer<TabBoxClient> desktopClient() const = 0;
|
2011-11-27 20:03:35 +04:00
|
|
|
/**
|
|
|
|
* Activates the currently selected client and closes the TabBox.
|
|
|
|
**/
|
|
|
|
virtual void activateAndClose() = 0;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return The currently used TabBoxConfig
|
|
|
|
*/
|
|
|
|
const TabBoxConfig& config() const;
|
|
|
|
/**
|
|
|
|
* Call this method when you want to change the currently used TabBoxConfig.
|
|
|
|
* It fires the signal configChanged.
|
|
|
|
* @param config Updates the currently used TabBoxConfig to config
|
|
|
|
*/
|
|
|
|
void setConfig(const TabBoxConfig& config);
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Call this method to show the TabBoxView. Depending on current
|
|
|
|
* configuration this method might not do anything.
|
|
|
|
* If highlight windows effect is to be used it will be activated.
|
|
|
|
* Highlight windows and outline are not shown if
|
|
|
|
* TabBoxConfig::TabBoxMode is TabBoxConfig::DesktopTabBox.
|
|
|
|
* @see TabBoxConfig::isShowTabBox
|
|
|
|
* @see TabBoxConfig::isHighlightWindows
|
|
|
|
*/
|
|
|
|
void show();
|
|
|
|
/**
|
|
|
|
* Hides the TabBoxView if shown.
|
|
|
|
* Deactivates highlight windows effect if active.
|
|
|
|
* @see show
|
|
|
|
*/
|
|
|
|
void hide(bool abort = false);
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Sets the current model index in the view and updates
|
2013-04-24 10:27:31 +04:00
|
|
|
* highlight windows if active.
|
2011-01-30 17:34:42 +03:00
|
|
|
* @param index The current Model index
|
|
|
|
*/
|
|
|
|
void setCurrentIndex(const QModelIndex& index);
|
2011-10-31 17:34:37 +04:00
|
|
|
/**
|
|
|
|
* @returns the current index
|
|
|
|
**/
|
|
|
|
const QModelIndex ¤tIndex() const;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Retrieves the next or previous item of the current item.
|
|
|
|
* @param forward next or previous item
|
|
|
|
* @return The next or previous item. If there is no matching item
|
|
|
|
* the current item will be returned.
|
|
|
|
*/
|
|
|
|
QModelIndex nextPrev(bool forward) const;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Initializes the model based on the current config.
|
|
|
|
* This method has to be invoked before showing the TabBox.
|
|
|
|
* It can also be invoked when clients are added or removed.
|
|
|
|
* In that case partialReset has to be true.
|
|
|
|
*
|
|
|
|
* @param partialReset Keep the currently selected item or regenerate everything
|
|
|
|
*/
|
|
|
|
void createModel(bool partialReset = false);
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @param desktop The desktop whose index should be retrieved
|
|
|
|
* @return The model index of given desktop. If TabBoxMode is not
|
|
|
|
* TabBoxConfig::DesktopTabBox an invalid model index will be returned.
|
|
|
|
*/
|
|
|
|
QModelIndex desktopIndex(int desktop) const;
|
|
|
|
/**
|
|
|
|
* @return The current list of desktops.
|
|
|
|
* If TabBoxMode is not TabBoxConfig::DesktopTabBox an empty list will
|
|
|
|
* be returned.
|
|
|
|
* @see DesktopModel::desktopList
|
|
|
|
*/
|
|
|
|
QList< int > desktopList() const;
|
|
|
|
/**
|
|
|
|
* @return The desktop for given model index. If the index is not valid
|
|
|
|
* or TabBoxMode is not TabBoxConfig::DesktopTabBox -1 will be returned.
|
|
|
|
* @see DesktopModel::desktopIndex
|
|
|
|
*/
|
|
|
|
int desktop(const QModelIndex& index) const;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* Handles additional grabbed key events by the TabBox controller.
|
|
|
|
* @param event The key event which has been grabbed
|
|
|
|
*/
|
2012-03-20 23:01:46 +04:00
|
|
|
virtual void grabbedKeyEvent(QKeyEvent* event) const;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @param pos The position to be tested in global coordinates
|
|
|
|
* @return True if the view contains the point, otherwise false.
|
|
|
|
*/
|
|
|
|
bool containsPos(const QPoint& pos) const;
|
|
|
|
/**
|
|
|
|
* @param client The TabBoxClient whose index should be returned
|
|
|
|
* @return Returns the ModelIndex of given TabBoxClient or an invalid ModelIndex
|
|
|
|
* if the model does not contain the given TabBoxClient.
|
|
|
|
* @see ClientModel::index
|
|
|
|
*/
|
2012-05-20 17:52:24 +04:00
|
|
|
QModelIndex index(QWeakPointer<TabBoxClient> client) const;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return Returns the current list of TabBoxClients.
|
|
|
|
* If TabBoxMode is not TabBoxConfig::ClientTabBox an empty list will
|
|
|
|
* be returned.
|
|
|
|
* @see ClientModel::clientList
|
|
|
|
*/
|
|
|
|
TabBoxClientList clientList() const;
|
|
|
|
/**
|
|
|
|
* @param index The index of the client to be returned
|
|
|
|
* @return Returns the TabBoxClient at given model index. If
|
|
|
|
* the index is invalid, does not point to a Client or the list
|
|
|
|
* is empty, NULL will be returned.
|
|
|
|
*/
|
|
|
|
TabBoxClient* client(const QModelIndex& index) const;
|
|
|
|
/**
|
|
|
|
* @return The first model index. That is the model index at position 0, 0.
|
|
|
|
* It is valid, as desktop has at least one desktop and if there are no
|
|
|
|
* clients an empty item is created.
|
|
|
|
*/
|
|
|
|
QModelIndex first() const;
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2016-10-06 09:06:25 +03:00
|
|
|
bool eventFilter(QObject *watcher, QEvent *event) override;
|
|
|
|
|
2017-04-12 19:14:37 +03:00
|
|
|
/**
|
|
|
|
* @returns whether the TabBox operates in a no modifier grab mode.
|
|
|
|
* In this mode a click on an item should directly accept and close the tabbox.
|
|
|
|
**/
|
|
|
|
virtual bool noModifierGrab() const = 0;
|
|
|
|
|
2013-07-22 18:07:39 +04:00
|
|
|
Q_SIGNALS:
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* This signal is fired when the TabBoxConfig changes
|
|
|
|
* @see setConfig
|
|
|
|
*/
|
|
|
|
void configChanged();
|
2011-12-02 13:48:04 +04:00
|
|
|
void selectedIndexChanged();
|
2011-01-30 17:34:42 +03:00
|
|
|
|
2013-07-22 18:07:39 +04:00
|
|
|
private Q_SLOTS:
|
2015-02-07 01:10:59 +03:00
|
|
|
void initHighlightWindows();
|
2012-05-04 03:08:28 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
private:
|
2011-04-28 13:16:27 +04:00
|
|
|
friend class TabBoxHandlerPrivate;
|
2011-01-30 17:34:42 +03:00
|
|
|
TabBoxHandlerPrivate* d;
|
|
|
|
};
|
2009-09-13 15:36:45 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class is a wrapper around a KWin Client. It is used for accessing the
|
|
|
|
* required client methods from inside TabBox and has to be implemented in KWin core.
|
|
|
|
*
|
2013-03-12 16:17:53 +04:00
|
|
|
* @author Martin Gräßlin <mgraesslin@kde.org>
|
2009-09-13 15:36:45 +04:00
|
|
|
* @since 4.4
|
|
|
|
*/
|
|
|
|
class TabBoxClient
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
TabBoxClient();
|
|
|
|
virtual ~TabBoxClient();
|
2009-09-13 15:36:45 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return The caption of the client
|
|
|
|
*/
|
|
|
|
virtual QString caption() const = 0;
|
|
|
|
/**
|
|
|
|
* @param size Requested size of the icon
|
|
|
|
* @return The icon of the client
|
|
|
|
*/
|
2013-12-06 17:41:23 +04:00
|
|
|
virtual QIcon icon() const = 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
/**
|
|
|
|
* @return The window Id of the client
|
|
|
|
*/
|
|
|
|
virtual WId window() const = 0;
|
|
|
|
/**
|
|
|
|
* @return Minimized state of the client
|
|
|
|
*/
|
|
|
|
virtual bool isMinimized() const = 0;
|
|
|
|
virtual int x() const = 0;
|
|
|
|
virtual int y() const = 0;
|
|
|
|
virtual int width() const = 0;
|
|
|
|
virtual int height() const = 0;
|
2011-11-27 17:15:49 +04:00
|
|
|
virtual bool isCloseable() const = 0;
|
2011-11-27 18:00:09 +04:00
|
|
|
virtual void close() = 0;
|
2011-12-01 16:15:11 +04:00
|
|
|
virtual bool isFirstInTabBox() const = 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
};
|
2009-09-13 15:36:45 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Pointer to the global TabBoxHandler object.
|
|
|
|
**/
|
|
|
|
extern TabBoxHandler* tabBox;
|
|
|
|
|
|
|
|
} // namespace TabBox
|
|
|
|
} // namespace KWin
|
|
|
|
|
|
|
|
#endif // TABBOXHANDLER_H
|