kwin/toplevel.h

622 lines
18 KiB
C
Raw Normal View History

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
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 KWIN_TOPLEVEL_H
#define KWIN_TOPLEVEL_H
#include <config-X11.h>
#include <assert.h>
#include <QObject>
#include <kdecoration.h>
#include <kdebug.h>
#include "utils.h"
#include "workspace.h"
#include <X11/extensions/Xdamage.h>
class NETWinInfo2;
namespace KWin
{
class Workspace;
class EffectWindowImpl;
class Shadow;
class Toplevel
: public QObject, public KDecorationDefines
2011-01-30 17:34:42 +03:00
{
Q_OBJECT
Q_PROPERTY(bool alpha READ hasAlpha CONSTANT)
Q_PROPERTY(qulonglong frameId READ frameId)
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
Q_PROPERTY(int height READ height)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
Q_PROPERTY(QPoint pos READ pos)
Q_PROPERTY(int screen READ screen)
Q_PROPERTY(QSize size READ size)
Q_PROPERTY(int width READ width)
Q_PROPERTY(qulonglong windowId READ window CONSTANT)
Q_PROPERTY(int x READ x)
Q_PROPERTY(int y READ y)
Q_PROPERTY(int desktop READ desktop)
Q_PROPERTY(QRect rect READ rect)
Q_PROPERTY(QPoint clientPos READ clientPos)
Q_PROPERTY(QSize clientSize READ clientSize)
Q_PROPERTY(QByteArray resourceName READ resourceName)
Q_PROPERTY(QByteArray resourceClass READ resourceClass)
Q_PROPERTY(QByteArray windowRole READ windowRole)
/**
* Returns whether the window is a desktop background window (the one with wallpaper).
* See _NET_WM_WINDOW_TYPE_DESKTOP at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool desktopWindow READ isDesktop)
/**
* Returns whether the window is a dock (i.e. a panel).
* See _NET_WM_WINDOW_TYPE_DOCK at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dock READ isDock)
/**
* Returns whether the window is a standalone (detached) toolbar window.
* See _NET_WM_WINDOW_TYPE_TOOLBAR at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool toolbar READ isToolbar)
/**
* Returns whether the window is a torn-off menu.
* See _NET_WM_WINDOW_TYPE_MENU at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool menu READ isMenu)
/**
* Returns whether the window is a "normal" window, i.e. an application or any other window
* for which none of the specialized window types fit.
* See _NET_WM_WINDOW_TYPE_NORMAL at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool normalWindow READ isNormalWindow)
/**
* Returns whether the window is a dialog window.
* See _NET_WM_WINDOW_TYPE_DIALOG at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dialog READ isDialog)
/**
* Returns whether the window is a splashscreen. Note that many (especially older) applications
* do not support marking their splash windows with this type.
* See _NET_WM_WINDOW_TYPE_SPLASH at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool splash READ isSplash)
/**
* Returns whether the window is a utility window, such as a tool window.
* See _NET_WM_WINDOW_TYPE_UTILITY at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool utility READ isUtility)
/**
* Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
* from the applications menubar).
* See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dropdownMenu READ isDropdownMenu)
/**
* Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
* See _NET_WM_WINDOW_TYPE_POPUP_MENU at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool popupMenu READ isPopupMenu)
/**
* Returns whether the window is a tooltip.
* See _NET_WM_WINDOW_TYPE_TOOLTIP at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool tooltip READ isTooltip)
/**
* Returns whether the window is a window with a notification.
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool notification READ isNotification)
/**
* Returns whether the window is a combobox popup.
* See _NET_WM_WINDOW_TYPE_COMBO at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool comboBox READ isComboBox)
/**
* Returns whether the window is a Drag&Drop icon.
* See _NET_WM_WINDOW_TYPE_DND at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dndIcon READ isDNDIcon)
/**
* Returns the NETWM window type
* See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(int windowType READ windowType)
Q_PROPERTY(QStringList activities READ activities)
/**
* Whether this Toplevel is managed by KWin (it has control over its placement and other
* aspects, as opposed to override-redirect windows that are entirely handled by the application).
**/
Q_PROPERTY(bool managed READ isClient CONSTANT)
/**
* Whether this Toplevel represents an already deleted window and only kept for the compositor for animations.
**/
Q_PROPERTY(bool deleted READ isDeleted CONSTANT)
/**
* Whether the window has an own shape
**/
Q_PROPERTY(bool shaped READ shape NOTIFY shapedChanged)
2011-01-30 17:34:42 +03:00
public:
Toplevel(Workspace *ws);
Window frameId() const;
Window window() const;
Workspace* workspace() const;
QRect geometry() const;
QSize size() const;
QPoint pos() const;
QRect rect() const;
int x() const;
int y() const;
int width() const;
int height() const;
bool isOnScreen(int screen) const; // true if it's at least partially there
int screen() const; // the screen where the center is
virtual QPoint clientPos() const = 0; // inside of geometry()
virtual QSize clientSize() const = 0;
virtual QRect visibleRect() const; // the area the window occupies on the screen
virtual QRect decorationRect() const; // rect including the decoration shadows
virtual QRect transparentRect() const = 0;
virtual QRegion decorationPendingRegion() const; // decoration region that needs to be repainted
virtual bool isClient() const;
virtual bool isDeleted() const;
2011-01-30 17:34:42 +03:00
// prefer isXXX() instead
// 0 for supported types means default for managed/unmanaged types
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
bool hasNETSupport() const;
bool isDesktop() const;
bool isDock() const;
bool isToolbar() const;
bool isMenu() const;
bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
bool isDialog() const;
bool isSplash() const;
bool isUtility() const;
bool isDropdownMenu() const;
bool isPopupMenu() const; // a context popup, not dropdown, not torn-off
bool isTooltip() const;
bool isNotification() const;
bool isComboBox() const;
bool isDNDIcon() const;
virtual int desktop() const = 0;
virtual QStringList activities() const = 0;
bool isOnDesktop(int d) const;
bool isOnActivity(const QString &activity) const;
bool isOnCurrentDesktop() const;
bool isOnCurrentActivity() const;
bool isOnAllDesktops() const;
bool isOnAllActivities() const;
QByteArray windowRole() const;
QByteArray sessionId() const;
2011-01-30 17:34:42 +03:00
QByteArray resourceName() const;
QByteArray resourceClass() const;
QByteArray wmCommand();
QByteArray wmClientMachine(bool use_localhost) const;
Window wmClientLeader() const;
pid_t pid() const;
static bool resourceMatch(const Toplevel* c1, const Toplevel* c2);
Pixmap windowPixmap(bool allow_create = true); // may return None (e.g. at a bad moment while resizing)
bool readyForPainting() const; // true if the window has been already painted its contents
Visual* visual() const;
bool shape() const;
void setOpacity(double opacity);
double opacity() const;
int depth() const;
bool hasAlpha() const;
virtual bool setupCompositing();
2011-01-30 17:34:42 +03:00
virtual void finishCompositing();
bool updateUnredirectedState();
bool unredirected() const;
void suspendUnredirect(bool suspend);
Q_INVOKABLE void addRepaint(const QRect& r);
Q_INVOKABLE void addRepaint(const QRegion& r);
Q_INVOKABLE void addRepaint(int x, int y, int w, int h);
Q_INVOKABLE void addLayerRepaint(const QRect& r);
Q_INVOKABLE void addLayerRepaint(const QRegion& r);
Q_INVOKABLE void addLayerRepaint(int x, int y, int w, int h);
Q_INVOKABLE virtual void addRepaintFull();
2011-01-30 17:34:42 +03:00
// these call workspace->addRepaint(), but first transform the damage if needed
void addWorkspaceRepaint(const QRect& r);
void addWorkspaceRepaint(int x, int y, int w, int h);
QRegion repaints() const;
void resetRepaints();
2011-01-30 17:34:42 +03:00
QRegion damage() const;
void resetDamage(const QRect& r);
EffectWindowImpl* effectWindow();
const EffectWindowImpl* effectWindow() const;
2011-01-30 17:34:42 +03:00
/**
* @returns Whether the Toplevel has a Shadow or not
* @see shadow
**/
bool hasShadow() const;
/**
* Returns the pointer to the Toplevel's Shadow. A Shadow
* is only available if Compositing is enabled and the corresponding X window
* has the Shadow property set.
* If a shadow is available @link hasShadow returns @c true.
* @returns The Shadow belonging to this Toplevel, may be @c NULL.
* @see hasShadow
**/
const Shadow *shadow() const;
Shadow *shadow();
/**
* Updates the Shadow associated with this Toplevel from X11 Property.
* Call this method when the Property changes or Compositing is started.
**/
void getShadow();
/**
* This method returns the area that the Toplevel window reports to be opaque.
2012-01-01 12:26:27 +04:00
* It is supposed to only provide valuable information if @link hasAlpha is @c true .
* @see hasAlpha
**/
const QRegion& opaqueRegion() const;
virtual Layer layer() const = 0;
2011-03-06 12:30:23 +03:00
signals:
void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
2011-03-12 17:04:22 +03:00
void damaged(KWin::Toplevel* toplevel, const QRect& damage);
2011-03-12 21:18:19 +03:00
void propertyNotify(KWin::Toplevel* toplevel, long a);
void geometryChanged();
void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old);
void windowClosed(KWin::Toplevel* toplevel, KWin::Deleted* deleted);
void windowShown(KWin::Toplevel* toplevel);
/**
* Signal emitted when the window's shape state changed. That is if it did not have a shape
* and received one or if the shape was withdrawn. Think of Chromium enabling/disabling KWin's
* decoration.
**/
void shapedChanged();
2011-03-06 12:30:23 +03:00
2011-01-30 17:34:42 +03:00
protected:
virtual ~Toplevel();
void setWindowHandles(Window client, Window frame);
void detectShape(Window id);
virtual void propertyNotifyEvent(XPropertyEvent* e);
virtual void damageNotifyEvent(XDamageNotifyEvent* e);
Pixmap createWindowPixmap();
void discardWindowPixmap();
void addDamage(const QRect& r);
void addDamage(int x, int y, int w, int h);
void addDamageFull();
void getWmClientLeader();
void getWmClientMachine();
void setReadyForPainting();
/**
* This function fetches the opaque region from this Toplevel.
* Will only be called on corresponding property changes and for initialization.
**/
void getWmOpaqueRegion();
2011-01-30 17:34:42 +03:00
void getResourceClass();
void getWindowRole();
virtual void debug(QDebug& stream) const = 0;
void copyToDeleted(Toplevel* c);
void disownDataPassedToDeleted();
friend QDebug& operator<<(QDebug& stream, const Toplevel*);
void deleteEffectWindow();
virtual bool shouldUnredirect() const = 0;
QRect geom;
Visual* vis;
int bit_depth;
NETWinInfo2* info;
bool ready_for_painting;
QRegion repaints_region; // updating, repaint just requires repaint of that area
QRegion layer_repaints_region;
2011-01-30 17:34:42 +03:00
private:
static QByteArray staticWindowRole(WId);
static QByteArray staticSessionId(WId);
static QByteArray staticWmCommand(WId);
static QByteArray staticWmClientMachine(WId);
static Window staticWmClientLeader(WId);
// when adding new data members, check also copyToDeleted()
Window client;
Window frame;
Workspace* wspace;
Pixmap window_pix;
Damage damage_handle;
QRegion damage_region; // damage is really damaged window (XDamage) and texture needs
float damageRatio;
2011-01-30 17:34:42 +03:00
bool is_shape;
EffectWindowImpl* effect_window;
QByteArray resource_name;
QByteArray resource_class;
QByteArray client_machine;
WId wmClientLeaderWin;
QByteArray window_role;
bool unredirect;
bool unredirectSuspend; // when unredirected, but pixmap is needed temporarily
QRegion opaque_region;
2011-01-30 17:34:42 +03:00
// when adding new data members, check also copyToDeleted()
};
inline Window Toplevel::window() const
2011-01-30 17:34:42 +03:00
{
return client;
2011-01-30 17:34:42 +03:00
}
inline Window Toplevel::frameId() const
2011-01-30 17:34:42 +03:00
{
return frame;
2011-01-30 17:34:42 +03:00
}
2011-01-30 17:34:42 +03:00
inline void Toplevel::setWindowHandles(Window w, Window f)
{
assert(client == None && w != None);
client = w;
2011-01-30 17:34:42 +03:00
assert(frame == None && f != None);
frame = f;
2011-01-30 17:34:42 +03:00
}
inline Workspace* Toplevel::workspace() const
2011-01-30 17:34:42 +03:00
{
return wspace;
2011-01-30 17:34:42 +03:00
}
inline QRect Toplevel::geometry() const
2011-01-30 17:34:42 +03:00
{
return geom;
2011-01-30 17:34:42 +03:00
}
inline QSize Toplevel::size() const
2011-01-30 17:34:42 +03:00
{
return geom.size();
2011-01-30 17:34:42 +03:00
}
inline QPoint Toplevel::pos() const
2011-01-30 17:34:42 +03:00
{
return geom.topLeft();
2011-01-30 17:34:42 +03:00
}
inline int Toplevel::x() const
2011-01-30 17:34:42 +03:00
{
return geom.x();
2011-01-30 17:34:42 +03:00
}
inline int Toplevel::y() const
2011-01-30 17:34:42 +03:00
{
return geom.y();
2011-01-30 17:34:42 +03:00
}
inline int Toplevel::width() const
2011-01-30 17:34:42 +03:00
{
return geom.width();
2011-01-30 17:34:42 +03:00
}
inline int Toplevel::height() const
2011-01-30 17:34:42 +03:00
{
return geom.height();
2011-01-30 17:34:42 +03:00
}
inline QRect Toplevel::rect() const
2011-01-30 17:34:42 +03:00
{
return QRect(0, 0, width(), height());
}
inline QRegion Toplevel::decorationPendingRegion() const
2011-01-30 17:34:42 +03:00
{
return QRegion();
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::readyForPainting() const
2011-01-30 17:34:42 +03:00
{
return ready_for_painting;
2011-01-30 17:34:42 +03:00
}
inline Visual* Toplevel::visual() const
2011-01-30 17:34:42 +03:00
{
return vis;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isDesktop() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Desktop;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isDock() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Dock;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isMenu() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Menu;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isToolbar() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Toolbar;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isSplash() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Splash;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isUtility() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Utility;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isDialog() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Dialog;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isNormalWindow() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Normal;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isDropdownMenu() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::DropdownMenu;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isPopupMenu() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::PopupMenu;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isTooltip() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Tooltip;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isNotification() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::Notification;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isComboBox() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::ComboBox;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isDNDIcon() const
2011-01-30 17:34:42 +03:00
{
return windowType() == NET::DNDIcon;
2011-01-30 17:34:42 +03:00
}
2011-01-30 17:34:42 +03:00
inline Pixmap Toplevel::windowPixmap(bool allow_create)
{
if (window_pix == None && allow_create)
window_pix = createWindowPixmap();
return window_pix;
2011-01-30 17:34:42 +03:00
}
inline QRegion Toplevel::damage() const
2011-01-30 17:34:42 +03:00
{
return damage_region;
2011-01-30 17:34:42 +03:00
}
inline QRegion Toplevel::repaints() const
2011-01-30 17:34:42 +03:00
{
return repaints_region.translated(pos()) | layer_repaints_region;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::shape() const
2011-01-30 17:34:42 +03:00
{
return is_shape;
2011-01-30 17:34:42 +03:00
}
inline int Toplevel::depth() const
2011-01-30 17:34:42 +03:00
{
return bit_depth;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::hasAlpha() const
2011-01-30 17:34:42 +03:00
{
return depth() == 32;
2011-01-30 17:34:42 +03:00
}
inline const QRegion& Toplevel::opaqueRegion() const
{
return opaque_region;
}
inline
EffectWindowImpl* Toplevel::effectWindow()
2011-01-30 17:34:42 +03:00
{
return effect_window;
2011-01-30 17:34:42 +03:00
}
inline
const EffectWindowImpl* Toplevel::effectWindow() const
{
return effect_window;
}
inline bool Toplevel::isOnAllDesktops() const
2011-01-30 17:34:42 +03:00
{
return desktop() == NET::OnAllDesktops;
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isOnAllActivities() const
2011-01-30 17:34:42 +03:00
{
return activities().isEmpty();
2011-01-30 17:34:42 +03:00
}
2011-01-30 17:34:42 +03:00
inline bool Toplevel::isOnDesktop(int d) const
{
return desktop() == d || /*desk == 0 ||*/ isOnAllDesktops();
2011-01-30 17:34:42 +03:00
}
2011-01-30 17:34:42 +03:00
inline bool Toplevel::isOnActivity(const QString &activity) const
{
return activities().isEmpty() || activities().contains(activity);
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::isOnCurrentDesktop() const
2011-01-30 17:34:42 +03:00
{
return isOnDesktop(workspace()->currentDesktop());
}
inline bool Toplevel::isOnCurrentActivity() const
2011-01-30 17:34:42 +03:00
{
return isOnActivity(Workspace::self()->currentActivity());
}
inline QByteArray Toplevel::resourceName() const
2011-01-30 17:34:42 +03:00
{
return resource_name; // it is always lowercase
2011-01-30 17:34:42 +03:00
}
inline QByteArray Toplevel::resourceClass() const
2011-01-30 17:34:42 +03:00
{
return resource_class; // it is always lowercase
2011-01-30 17:34:42 +03:00
}
inline QByteArray Toplevel::windowRole() const
2011-01-30 17:34:42 +03:00
{
return window_role;
2011-01-30 17:34:42 +03:00
}
inline pid_t Toplevel::pid() const
2011-01-30 17:34:42 +03:00
{
return info->pid();
2011-01-30 17:34:42 +03:00
}
inline bool Toplevel::unredirected() const
2011-01-30 17:34:42 +03:00
{
return unredirect;
2011-01-30 17:34:42 +03:00
}
2011-01-30 17:34:42 +03:00
QDebug& operator<<(QDebug& stream, const Toplevel*);
QDebug& operator<<(QDebug& stream, const ToplevelList&);
QDebug& operator<<(QDebug& stream, const ConstToplevelList&);
2011-01-30 17:34:42 +03:00
KWIN_COMPARE_PREDICATE(WindowMatchPredicate, Toplevel, Window, cl->window() == value);
KWIN_COMPARE_PREDICATE(FrameIdMatchPredicate, Toplevel, Window, cl->frameId() == value);
} // namespace
#endif