/* KWin - the KDE window manager This file is part of the KDE project. SPDX-FileCopyrightText: 2015 Martin Gräßlin SPDX-FileCopyrightText: 2019 Vlad Zahorodnii SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef KWIN_ABSTRACT_CLIENT_H #define KWIN_ABSTRACT_CLIENT_H #include "cursor.h" #include "options.h" #include "rules.h" #include "utils/common.h" #include "utils/xcbutils.h" #include #include #include #include #include #include #include #include #include #include #include class QMouseEvent; class QOpenGLFramebufferObject; namespace KWaylandServer { class PlasmaWindowInterface; class SurfaceInterface; } namespace KDecoration2 { class Decoration; } namespace KWin { class Group; class Output; class ClientMachine; class Deleted; class EffectWindowImpl; class Shadow; class SurfaceItem; class VirtualDesktop; class WindowItem; /** * Enum to describe the reason why a AbstractClient has to be released. */ enum class ReleaseReason { Release, ///< Normal Release after e.g. an Unmap notify event (window still valid) Destroyed, ///< Release after an Destroy notify event (window no longer valid) KWinShutsDown ///< Release on KWin Shutdown (window still valid) }; namespace TabBox { class TabBoxClientImpl; } namespace Decoration { class DecoratedClientImpl; class DecorationPalette; } class KWIN_EXPORT AbstractClient : public QObject { Q_OBJECT Q_PROPERTY(bool alpha READ hasAlpha NOTIFY hasAlphaChanged) Q_PROPERTY(qulonglong frameId READ frameId) /** * This property holds rectangle that the pixmap or buffer of this AbstractClient * occupies on the screen. This rectangle includes invisible portions of the * client, e.g. client-side drop shadows, etc. */ Q_PROPERTY(QRect bufferGeometry READ bufferGeometry) /** * This property holds the position of the AbstractClient's frame geometry. */ Q_PROPERTY(QPoint pos READ pos) /** * This property holds the size of the AbstractClient's frame geometry. */ Q_PROPERTY(QSize size READ size) /** * This property holds the x position of the AbstractClient's frame geometry. */ Q_PROPERTY(int x READ x NOTIFY frameGeometryChanged) /** * This property holds the y position of the AbstractClient's frame geometry. */ Q_PROPERTY(int y READ y NOTIFY frameGeometryChanged) /** * This property holds the width of the AbstractClient's frame geometry. */ Q_PROPERTY(int width READ width NOTIFY frameGeometryChanged) /** * This property holds the height of the AbstractClient's frame geometry. */ Q_PROPERTY(int height READ height NOTIFY frameGeometryChanged) Q_PROPERTY(QRect visibleRect READ visibleGeometry) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged) Q_PROPERTY(int screen READ screen NOTIFY screenChanged) Q_PROPERTY(qulonglong windowId READ window CONSTANT) Q_PROPERTY(QRect rect READ rect) Q_PROPERTY(QPoint clientPos READ clientPos) Q_PROPERTY(QSize clientSize READ clientSize) Q_PROPERTY(QByteArray resourceName READ resourceName NOTIFY windowClassChanged) Q_PROPERTY(QByteArray resourceClass READ resourceClass NOTIFY windowClassChanged) Q_PROPERTY(QByteArray windowRole READ windowRole NOTIFY windowRoleChanged) /** * Returns whether the window is a desktop background window (the one with wallpaper). * See _NET_WM_WINDOW_TYPE_DESKTOP at https://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 https://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 https://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 https://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 https://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 https://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 https://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 https://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 https://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 https://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 https://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 https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ Q_PROPERTY(bool notification READ isNotification) /** * Returns whether the window is a window with a critical notification. */ Q_PROPERTY(bool criticalNotification READ isCriticalNotification) /** * Returns whether the window is an On Screen Display. */ Q_PROPERTY(bool onScreenDisplay READ isOnScreenDisplay) /** * Returns whether the window is a combobox popup. * See _NET_WM_WINDOW_TYPE_COMBO at https://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 https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ Q_PROPERTY(bool dndIcon READ isDNDIcon) /** * Returns the NETWM window type * See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ Q_PROPERTY(int windowType READ windowType) /** * Whether this AbstractClient 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 AbstractClient 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) /** * Whether the window does not want to be animated on window close. * There are legit reasons for this like a screenshot application which does not want it's * window being captured. */ Q_PROPERTY(bool skipsCloseAnimation READ skipsCloseAnimation WRITE setSkipCloseAnimation NOTIFY skipCloseAnimationChanged) /** * Interface to the Wayland Surface. * Relevant only in Wayland, in X11 it will be nullptr */ Q_PROPERTY(KWaylandServer::SurfaceInterface *surface READ surface) /** * Whether the window is a popup. */ Q_PROPERTY(bool popupWindow READ isPopupWindow) /** * Whether this AbstractClient represents the outline. * * @note It's always @c false if compositing is turned off. */ Q_PROPERTY(bool outline READ isOutline) /** * This property holds a UUID to uniquely identify this AbstractClient. */ Q_PROPERTY(QUuid internalId READ internalId CONSTANT) /** * The pid of the process owning this window. * * @since 5.20 */ Q_PROPERTY(int pid READ pid CONSTANT) /** * The position of this window within Workspace's window stack. */ Q_PROPERTY(int stackingOrder READ stackingOrder NOTIFY stackingOrderChanged) /** * Whether this Client is fullScreen. A Client might either be fullScreen due to the _NET_WM property * or through a legacy support hack. The fullScreen state can only be changed if the Client does not * use the legacy hack. To be sure whether the state changed, connect to the notify signal. */ Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged) /** * Whether the Client can be set to fullScreen. The property is evaluated each time it is invoked. * Because of that there is no notify signal. */ Q_PROPERTY(bool fullScreenable READ isFullScreenable) /** * Whether this Client is active or not. Use Workspace::activateClient() to activate a Client. * @see Workspace::activateClient */ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged) /** * The desktop this Client is on. If the Client is on all desktops the property has value -1. * This is a legacy property, use x11DesktopIds instead * * @deprecated Use the desktops property instead. */ Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged) /** * The virtual desktops this client is on. If it's on all desktops, the list is empty. */ Q_PROPERTY(QVector desktops READ desktops WRITE setDesktops NOTIFY desktopChanged) /** * Whether the Client is on all desktops. That is desktop is -1. */ Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops WRITE setOnAllDesktops NOTIFY desktopChanged) /** * The activities this client is on. If it's on all activities the property is empty. */ Q_PROPERTY(QStringList activities READ activities WRITE setOnActivities NOTIFY activitiesChanged) /** * The x11 ids for all desktops this client is in. On X11 this list will always have a length of 1 * * @deprecated prefer using apis that use VirtualDesktop objects */ Q_PROPERTY(QVector x11DesktopIds READ x11DesktopIds NOTIFY x11DesktopIdsChanged) /** * Indicates that the window should not be included on a taskbar. */ Q_PROPERTY(bool skipTaskbar READ skipTaskbar WRITE setSkipTaskbar NOTIFY skipTaskbarChanged) /** * Indicates that the window should not be included on a Pager. */ Q_PROPERTY(bool skipPager READ skipPager WRITE setSkipPager NOTIFY skipPagerChanged) /** * Whether the Client should be excluded from window switching effects. */ Q_PROPERTY(bool skipSwitcher READ skipSwitcher WRITE setSkipSwitcher NOTIFY skipSwitcherChanged) /** * Whether the window can be closed by the user. */ Q_PROPERTY(bool closeable READ isCloseable NOTIFY closeableChanged) Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) /** * Whether the Client is set to be kept above other windows. */ Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged) /** * Whether the Client is set to be kept below other windows. */ Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged) /** * Whether the Client can be shaded. The property is evaluated each time it is invoked. * Because of that there is no notify signal. */ Q_PROPERTY(bool shadeable READ isShadeable) /** * Whether the Client is shaded. */ Q_PROPERTY(bool shade READ isShade WRITE setShade NOTIFY shadeChanged) /** * Whether the Client can be minimized. The property is evaluated each time it is invoked. * Because of that there is no notify signal. */ Q_PROPERTY(bool minimizable READ isMinimizable) /** * Whether the Client is minimized. */ Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized NOTIFY minimizedChanged) /** * The optional geometry representing the minimized Client in e.g a taskbar. * See _NET_WM_ICON_GEOMETRY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . * The value is evaluated each time the getter is called. * Because of that no changed signal is provided. */ Q_PROPERTY(QRect iconGeometry READ iconGeometry) /** * Returns whether the window is any of special windows types (desktop, dock, splash, ...), * i.e. window types that usually don't have a window frame and the user does not use window * management (moving, raising,...) on them. * The value is evaluated each time the getter is called. * Because of that no changed signal is provided. */ Q_PROPERTY(bool specialWindow READ isSpecialWindow) /** * Whether window state _NET_WM_STATE_DEMANDS_ATTENTION is set. This state indicates that some * action in or with the window happened. For example, it may be set by the Window Manager if * the window requested activation but the Window Manager refused it, or the application may set * it if it finished some work. This state may be set by both the Client and the Window Manager. * It should be unset by the Window Manager when it decides the window got the required attention * (usually, that it got activated). */ Q_PROPERTY(bool demandsAttention READ isDemandingAttention WRITE demandAttention NOTIFY demandsAttentionChanged) /** * The Caption of the Client. Read from WM_NAME property together with a suffix for hostname and shortcut. * To read only the caption as provided by WM_NAME, use the getter with an additional @c false value. */ Q_PROPERTY(QString caption READ caption NOTIFY captionChanged) /** * Minimum size as specified in WM_NORMAL_HINTS */ Q_PROPERTY(QSize minSize READ minSize) /** * Maximum size as specified in WM_NORMAL_HINTS */ Q_PROPERTY(QSize maxSize READ maxSize) /** * Whether the Client can accept keyboard focus. * The value is evaluated each time the getter is called. * Because of that no changed signal is provided. */ Q_PROPERTY(bool wantsInput READ wantsInput) /** * Whether the Client is a transient Window to another Window. * @see transientFor */ Q_PROPERTY(bool transient READ isTransient NOTIFY transientChanged) /** * The Client to which this Client is a transient if any. */ Q_PROPERTY(KWin::AbstractClient *transientFor READ transientFor NOTIFY transientChanged) /** * Whether the Client represents a modal window. */ Q_PROPERTY(bool modal READ isModal NOTIFY modalChanged) /** * The geometry of this Client. Be aware that depending on resize mode the frameGeometryChanged * signal might be emitted at each resize step or only at the end of the resize operation. * * @deprecated Use frameGeometry */ Q_PROPERTY(QRect geometry READ frameGeometry WRITE moveResize NOTIFY frameGeometryChanged) /** * The geometry of this Client. Be aware that depending on resize mode the frameGeometryChanged * signal might be emitted at each resize step or only at the end of the resize operation. */ Q_PROPERTY(QRect frameGeometry READ frameGeometry WRITE moveResize NOTIFY frameGeometryChanged) /** * Whether the Client is currently being moved by the user. * Notify signal is emitted when the Client starts or ends move/resize mode. */ Q_PROPERTY(bool move READ isInteractiveMove NOTIFY moveResizedChanged) /** * Whether the Client is currently being resized by the user. * Notify signal is emitted when the Client starts or ends move/resize mode. */ Q_PROPERTY(bool resize READ isInteractiveResize NOTIFY moveResizedChanged) /** * Whether the decoration is currently using an alpha channel. */ Q_PROPERTY(bool decorationHasAlpha READ decorationHasAlpha) /** * Whether the window has a decoration or not. * This property is not allowed to be set by applications themselves. * The decision whether a window has a border or not belongs to the window manager. * If this property gets abused by application developers, it will be removed again. */ Q_PROPERTY(bool noBorder READ noBorder WRITE setNoBorder) /** * Whether the Client provides context help. Mostly needed by decorations to decide whether to * show the help button or not. */ Q_PROPERTY(bool providesContextHelp READ providesContextHelp CONSTANT) /** * Whether the Client can be maximized both horizontally and vertically. * The property is evaluated each time it is invoked. * Because of that there is no notify signal. */ Q_PROPERTY(bool maximizable READ isMaximizable) /** * Whether the Client is moveable. Even if it is not moveable, it might be possible to move * it to another screen. The property is evaluated each time it is invoked. * Because of that there is no notify signal. * @see moveableAcrossScreens */ Q_PROPERTY(bool moveable READ isMovable) /** * Whether the Client can be moved to another screen. The property is evaluated each time it is invoked. * Because of that there is no notify signal. * @see moveable */ Q_PROPERTY(bool moveableAcrossScreens READ isMovableAcrossScreens) /** * Whether the Client can be resized. The property is evaluated each time it is invoked. * Because of that there is no notify signal. */ Q_PROPERTY(bool resizeable READ isResizable) /** * The desktop file name of the application this AbstractClient belongs to. * * This is either the base name without full path and without file extension of the * desktop file for the window's application (e.g. "org.kde.foo"). * * The application's desktop file name can also be the full path to the desktop file * (e.g. "/opt/kde/share/org.kde.foo.desktop") in case it's not in a standard location. */ Q_PROPERTY(QByteArray desktopFileName READ desktopFileName NOTIFY desktopFileNameChanged) /** * Whether an application menu is available for this Client */ Q_PROPERTY(bool hasApplicationMenu READ hasApplicationMenu NOTIFY hasApplicationMenuChanged) /** * Whether the application menu for this Client is currently opened */ Q_PROPERTY(bool applicationMenuActive READ applicationMenuActive NOTIFY applicationMenuActiveChanged) /** * Whether this client is unresponsive. * * When an application failed to react on a ping request in time, it is * considered unresponsive. This usually indicates that the application froze or crashed. */ Q_PROPERTY(bool unresponsive READ unresponsive NOTIFY unresponsiveChanged) /** * The color scheme set on this client * Absolute file path, or name of palette in the user's config directory following KColorSchemes format. * An empty string indicates the default palette from kdeglobals is used. * @note this indicates the colour scheme requested, which might differ from the theme applied if the colorScheme cannot be found */ Q_PROPERTY(QString colorScheme READ colorScheme NOTIFY colorSchemeChanged) Q_PROPERTY(KWin::Layer layer READ layer) /** * Whether this client is hidden. It's usually the case with auto-hide panels. */ Q_PROPERTY(bool hidden READ isHiddenInternal NOTIFY hiddenChanged) public: ~AbstractClient() override; virtual xcb_window_t frameId() const; xcb_window_t window() const; /** * Returns the geometry of the pixmap or buffer attached to this AbstractClient. * * For X11 clients, this method returns server-side geometry of the AbstractClient. * * For Wayland clients, this method returns rectangle that the main surface * occupies on the screen, in global screen coordinates. */ QRect bufferGeometry() const; /** * Returns the geometry of the AbstractClient, excluding invisible portions, e.g. * server-side and client-side drop shadows, etc. */ QRect frameGeometry() const; /** * Returns the geometry of the client window, in global screen coordinates. */ QRect clientGeometry() const; /** * Returns the extents of the server-side decoration. * * Note that the returned margins object will have all margins set to 0 if * the client doesn't have a server-side decoration. * * Default implementation returns a margins object with all margins set to 0. */ virtual QMargins frameMargins() const; /** * The geometry of the AbstractClient which accepts input events. This might be larger * than the actual geometry, e.g. to support resizing outside the window. * * Default implementation returns same as geometry. */ virtual QRect inputGeometry() const; QSize size() const; QPoint pos() const; QRect rect() const; int x() const; int y() const; int width() const; int height() const; bool isOnOutput(Output *output) const; bool isOnActiveOutput() const; int screen() const; // the screen where the center is Output *output() const; void setOutput(Output *output); virtual QPoint clientPos() const { return QPoint(borderLeft(), borderTop()); }; // inside of geometry() QSize clientSize() const; /** * Returns a rectangle that the window occupies on the screen, including drop-shadows. */ QRect visibleGeometry() const; virtual bool isClient() const; virtual bool isDeleted() const; /** * Maps the specified @a point from the global screen coordinates to the frame coordinates. */ QPoint mapToFrame(const QPoint &point) const; /** * Maps the specified @a point from the global screen coordinates to the surface-local * coordinates of the main surface. For X11 clients, this function maps the specified point * from the global screen coordinates to the buffer-local coordinates. */ QPoint mapToLocal(const QPoint &point) const; QPointF mapToLocal(const QPointF &point) const; QPointF mapFromLocal(const QPointF &point) const; // prefer isXXX() instead // 0 for supported types means default for managed/unmanaged types virtual NET::WindowType windowType(bool direct = false, int supported_types = 0) const = 0; 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 isCriticalNotification() const; bool isOnScreenDisplay() const; bool isComboBox() const; bool isDNDIcon() const; virtual bool isLockScreen() const; virtual bool isInputMethod() const; virtual bool isOutline() const; virtual bool isInternal() const; /** * Returns the virtual desktop within the workspace() the client window * is located in, 0 if it isn't located on any special desktop (not mapped yet), * or NET::OnAllDesktops. Do not use desktop() directly, use * isOnDesktop() instead. */ virtual int desktop() const; virtual QVector desktops() const; virtual QStringList activities() const; bool isOnDesktop(VirtualDesktop *desktop) const; bool isOnDesktop(int d) const; bool isOnActivity(const QString &activity) const; bool isOnCurrentDesktop() const; bool isOnCurrentActivity() const; bool isOnAllDesktops() const; bool isOnAllActivities() const; virtual QByteArray windowRole() const; QByteArray sessionId() const; QByteArray resourceName() const; QByteArray resourceClass() const; QByteArray wmCommand(); QByteArray wmClientMachine(bool use_localhost) const; const ClientMachine *clientMachine() const; virtual bool isLocalhost() const; xcb_window_t wmClientLeader() const; virtual pid_t pid() const; static bool resourceMatch(const AbstractClient *c1, const AbstractClient *c2); bool readyForPainting() const; // true if the window has been already painted its contents xcb_visualid_t visual() const; bool shape() const; QRegion inputShape() const; void setOpacity(qreal opacity); qreal opacity() const; int depth() const; bool hasAlpha() const; virtual bool setupCompositing(); virtual void finishCompositing(ReleaseReason releaseReason = ReleaseReason::Release); 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(); // 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); void addWorkspaceRepaint(const QRegion ®ion); EffectWindowImpl *effectWindow(); const EffectWindowImpl *effectWindow() const; SurfaceItem *surfaceItem() const; WindowItem *windowItem() const; /** * Window will be temporarily painted as if being at the top of the stack. * Only available if Compositor is active, if not active, this method is a no-op. */ void elevate(bool elevate); /** * Returns the Shadow associated with this AbstractClient or @c null if it has no shadow. */ Shadow *shadow() const; /** * Updates the Shadow associated with this AbstractClient from X11 Property. * Call this method when the Property changes or Compositing is started. */ void updateShadow(); /** * Whether the AbstractClient currently wants the shadow to be rendered. Default * implementation always returns @c true. */ virtual bool wantsShadowToBeRendered() const; /** * This method returns the area that the AbstractClient window reports to be opaque. * It is supposed to only provide valuable information if hasAlpha is @c true . * @see hasAlpha */ const QRegion &opaqueRegion() const; QRegion shapeRegion() const; bool skipsCloseAnimation() const; void setSkipCloseAnimation(bool set); quint32 pendingSurfaceId() const; KWaylandServer::SurfaceInterface *surface() const; void setSurface(KWaylandServer::SurfaceInterface *surface); const QSharedPointer &internalFramebufferObject() const; QImage internalImageObject() const; /** * @returns Transformation to map from global to window coordinates. * * Default implementation returns a translation on negative pos(). * @see pos */ virtual QMatrix4x4 inputTransformation() const; /** * Returns @c true if the toplevel can accept input at the specified position @a point. */ virtual bool hitTest(const QPoint &point) const; /** * The window has a popup grab. This means that when it got mapped the * parent window had an implicit (pointer) grab. * * Normally this is only relevant for transient windows. * * Once the popup grab ends (e.g. pointer press outside of any AbstractClient of * the client), the method popupDone should be invoked. * * The default implementation returns @c false. * @see popupDone * @since 5.10 */ virtual bool hasPopupGrab() const { return false; } /** * This method should be invoked for Toplevels with a popup grab when * the grab ends. * * The default implementation does nothing. * @see hasPopupGrab * @since 5.10 */ virtual void popupDone(){}; /** * @brief Finds the AbstractClient matching the condition expressed in @p func in @p list. * * The method is templated to operate on either a list of Toplevels or on a list of * a subclass type of AbstractClient. * @param list The list to search in * @param func The condition function (compare std::find_if) * @return T* The found AbstractClient or @c null if there is no matching AbstractClient */ template static T *findInList(const QList &list, std::function func); /** * Whether the window is a popup. * * Popups can be used to implement popup menus, tooltips, combo boxes, etc. * * @since 5.15 */ virtual bool isPopupWindow() const; /** * A UUID to uniquely identify this AbstractClient independent of windowing system. */ QUuid internalId() const { return m_internalId; } int stackingOrder() const; void setStackingOrder(int order); ///< @internal QWeakPointer tabBoxClient() const { return m_tabBoxClient.toWeakRef(); } bool isFirstInTabBox() const { return m_firstInTabBox; } bool skipSwitcher() const { return m_skipSwitcher; } void setSkipSwitcher(bool set); bool skipTaskbar() const { return m_skipTaskbar; } void setSkipTaskbar(bool set); void setOriginalSkipTaskbar(bool set); bool originalSkipTaskbar() const { return m_originalSkipTaskbar; } bool skipPager() const { return m_skipPager; } void setSkipPager(bool set); const QIcon &icon() const { return m_icon; } bool isZombie() const; bool isActive() const { return m_active; } /** * Sets the client's active state to \a act. * * This function does only change the visual appearance of the client, * it does not change the focus setting. Use * Workspace::activateClient() or Workspace::requestFocus() instead. * * If a client receives or looses the focus, it calls setActive() on * its own. */ void setActive(bool); bool keepAbove() const { return m_keepAbove; } void setKeepAbove(bool); bool keepBelow() const { return m_keepBelow; } void setKeepBelow(bool); void demandAttention(bool set = true); bool isDemandingAttention() const { return m_demandsAttention; } void cancelAutoRaise(); bool wantsTabFocus() const; virtual void updateMouseGrab(); /** * @returns The caption consisting of captionNormal and captionSuffix * @see captionNormal * @see captionSuffix */ QString caption() const; /** * @returns The caption as set by the AbstractClient without any suffix. * @see caption * @see captionSuffix */ virtual QString captionNormal() const = 0; /** * @returns The suffix added to the caption (e.g. shortcut, machine name, etc.) * @see caption * @see captionNormal */ virtual QString captionSuffix() const = 0; virtual bool isPlaceable() const; virtual bool isCloseable() const = 0; virtual bool isShown() const = 0; virtual bool isHiddenInternal() const = 0; virtual void hideClient() = 0; virtual void showClient() = 0; virtual bool isFullScreenable() const; virtual bool isFullScreen() const; virtual bool isRequestedFullScreen() const; // TODO: remove boolean trap virtual AbstractClient *findModal(bool allow_itself = false) = 0; virtual bool isTransient() const; /** * @returns Whether there is a hint available to place the AbstractClient on it's parent, default @c false. * @see transientPlacementHint */ virtual bool hasTransientPlacementHint() const; /** * Only valid id hasTransientPlacementHint is true * @returns The position the transient wishes to position itself */ virtual QRect transientPlacement(const QRect &bounds) const; const AbstractClient *transientFor() const; AbstractClient *transientFor(); /** * @returns @c true if c is the transient_for window for this client, * or recursively the transient_for window * @todo: remove boolean trap */ virtual bool hasTransient(const AbstractClient *c, bool indirect) const; const QList &transients() const; // Is not indirect virtual void addTransient(AbstractClient *client); virtual void removeTransient(AbstractClient *cl); virtual QList mainClients() const; // Call once before loop , is not indirect QList allMainClients() const; // Call once before loop , is indirect /** * Returns true for "special" windows and false for windows which are "normal" * (normal=window which has a border, can be moved by the user, can be closed, etc.) * true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now) * false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO */ bool isSpecialWindow() const; void sendToOutput(Output *output); void updateGeometryRestoresForFullscreen(Output *output); const QKeySequence &shortcut() const { return _shortcut; } void setShortcut(const QString &cut); bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos); void setOnAllDesktops(bool set); void setDesktop(int); void enterDesktop(VirtualDesktop *desktop); void leaveDesktop(VirtualDesktop *desktop); /** * Set the window as being on the attached list of desktops * On X11 it will be set to the last entry */ void setDesktops(QVector desktops); QVector x11DesktopIds() const; QStringList desktopIds() const; void setMinimized(bool set); /** * Minimizes this client plus its transients */ void minimize(bool avoid_animation = false); void unminimize(bool avoid_animation = false); bool isMinimized() const { return m_minimized; } virtual void setFullScreen(bool set, bool user = true); virtual void setClientShown(bool shown); QRect geometryRestore() const; virtual MaximizeMode maximizeMode() const; virtual MaximizeMode requestedMaximizeMode() const; void maximize(MaximizeMode); /** * Sets the maximization according to @p vertically and @p horizontally. */ Q_INVOKABLE void setMaximize(bool vertically, bool horizontally); virtual bool noBorder() const; virtual void setNoBorder(bool set); QPalette palette() const; const Decoration::DecorationPalette *decorationPalette() const; /** * Returns whether the window is resizable or has a fixed size. */ virtual bool isResizable() const = 0; /** * Returns whether the window is moveable or has a fixed position. */ virtual bool isMovable() const = 0; /** * Returns whether the window can be moved to another screen. */ virtual bool isMovableAcrossScreens() const = 0; /** * Returns @c true if the window is shaded and shadeMode is @c ShadeNormal; otherwise returns @c false. */ virtual bool isShade() const { return shadeMode() == ShadeNormal; } ShadeMode shadeMode() const; // Prefer isShade() void setShade(bool set); void setShade(ShadeMode mode); void toggleShade(); void cancelShadeHoverTimer(); /** * Whether the Client can be shaded. Default implementation returns @c false. */ virtual bool isShadeable() const; virtual bool isMaximizable() const; virtual bool isMinimizable() const; virtual QRect iconGeometry() const; virtual bool userCanSetFullScreen() const; virtual bool userCanSetNoBorder() const; virtual void checkNoBorder(); void setOnActivity(const QString &activity, bool enable); void setOnActivities(const QStringList &newActivitiesList); void setOnAllActivities(bool all); virtual void updateActivities(bool includeTransients); void blockActivityUpdates(bool b = true); const WindowRules *rules() const { return &m_rules; } void removeRule(Rules *r); void setupWindowRules(bool ignore_temporary); void evaluateWindowRules(); virtual void applyWindowRules(); virtual bool takeFocus() = 0; virtual bool wantsInput() const = 0; /** * Whether a dock window wants input. * * By default KWin doesn't pass focus to a dock window unless a force activate * request is provided. * * This method allows to have dock windows take focus also through flags set on * the window. * * The default implementation returns @c false. */ virtual bool dockWantsInput() const; void checkWorkspacePosition(QRect oldGeometry = QRect(), const VirtualDesktop *oldDesktop = nullptr); virtual xcb_timestamp_t userTime() const; virtual void updateWindowRules(Rules::Types selection); void growHorizontal(); void shrinkHorizontal(); void growVertical(); void shrinkVertical(); void updateInteractiveMoveResize(const QPointF ¤tGlobalCursor); /** * Ends move resize when all pointer buttons are up again. */ void endInteractiveMoveResize(); void keyPressEvent(uint key_code); virtual void pointerEnterEvent(const QPoint &globalPos); virtual void pointerLeaveEvent(); Qt::Edge titlebarPosition() const; bool titlebarPositionUnderMouse() const; // a helper for the workspace window packing. tests for screen validity and updates since in maximization case as with normal moving void packTo(int left, int top); /** * Sets the quick tile mode ("snap") of this window. * This will also handle preserving and restoring of window geometry as necessary. * @param mode The tile mode (left/right) to give this window. * @param keyboard Defines whether to take keyboard cursor into account. */ void setQuickTileMode(QuickTileMode mode, bool keyboard = false); QuickTileMode quickTileMode() const { return QuickTileMode(m_quickTileMode); } virtual Layer layer() const; void updateLayer(); void move(const QPoint &point); void resize(const QSize &size); void moveResize(const QRect &rect); virtual void resizeWithChecks(const QSize &s) = 0; void keepInArea(QRect area, bool partial = false); virtual QSize minSize() const; virtual QSize maxSize() const; /** * How to resize the window in order to obey constraints (mainly aspect ratios). */ enum SizeMode { SizeModeAny, SizeModeFixedW, ///< Try not to affect width SizeModeFixedH, ///< Try not to affect height SizeModeMax ///< Try not to make it larger in either direction }; virtual QSize constrainClientSize(const QSize &size, SizeMode mode = SizeModeAny) const; QSize constrainFrameSize(const QSize &size, SizeMode mode = SizeModeAny) const; QSize implicitSize() const; /** * Calculates the matching client position for the given frame position @p point. */ virtual QPoint framePosToClientPos(const QPoint &point) const; /** * Calculates the matching frame position for the given client position @p point. */ virtual QPoint clientPosToFramePos(const QPoint &point) const; /** * Calculates the matching client size for the given frame size @p size. * * Notice that size constraints won't be applied. * * Default implementation returns the frame size with frame margins being excluded. */ virtual QSize frameSizeToClientSize(const QSize &size) const; /** * Calculates the matching frame size for the given client size @p size. * * Notice that size constraints won't be applied. * * Default implementation returns the client size with frame margins being included. */ virtual QSize clientSizeToFrameSize(const QSize &size) const; /** * Calculates the matching client rect for the given frame rect @p rect. * * Notice that size constraints won't be applied. */ QRect frameRectToClientRect(const QRect &rect) const; /** * Calculates the matching frame rect for the given client rect @p rect. * * Notice that size constraints won't be applied. */ QRect clientRectToFrameRect(const QRect &rect) const; /** * Returns the last requested geometry. The returned value indicates the bounding * geometry, meaning that the client can commit smaller window geometry if the window * is resized. * * The main difference between the frame geometry and the move-resize geometry is * that the former specifies the current geometry while the latter specifies the next * geometry. */ QRect moveResizeGeometry() const; /** * Returns @c true if the Client is being interactively moved; otherwise @c false. */ bool isInteractiveMove() const { return isInteractiveMoveResize() && interactiveMoveResizeGravity() == Gravity::None; } /** * Returns @c true if the Client is being interactively resized; otherwise @c false. */ bool isInteractiveResize() const { return isInteractiveMoveResize() && interactiveMoveResizeGravity() != Gravity::None; } /** * Cursor shape for move/resize mode. */ CursorShape cursor() const { return m_interactiveMoveResize.cursor; } virtual StrutRect strutRect(StrutArea area) const; StrutRects strutRects() const; virtual bool hasStrut() const; void setModal(bool modal); bool isModal() const; /** * Determines the mouse command for the given @p button in the current state. * * The @p handled argument specifies whether the button was handled or not. * This value should be used to determine whether the mouse button should be * passed to the AbstractClient or being filtered out. */ Options::MouseCommand getMouseCommand(Qt::MouseButton button, bool *handled) const; Options::MouseCommand getWheelCommand(Qt::Orientation orientation, bool *handled) const; // decoration related KDecoration2::Decoration *decoration() { return m_decoration.decoration.data(); } const KDecoration2::Decoration *decoration() const { return m_decoration.decoration.data(); } bool isDecorated() const { return m_decoration.decoration != nullptr; } QPointer decoratedClient() const; void setDecoratedClient(QPointer client); bool decorationHasAlpha() const; void triggerDecorationRepaint(); virtual void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const; void processDecorationMove(const QPoint &localPos, const QPoint &globalPos); bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false); void processDecorationButtonRelease(QMouseEvent *event); virtual void invalidateDecoration(); /** * Returns whether the window provides context help or not. If it does, * you should show a help menu item or a help button like '?' and call * contextHelp() if this is invoked. * * Default implementation returns @c false. * @see showContextHelp; */ virtual bool providesContextHelp() const; /** * Invokes context help on the window. Only works if the window * actually provides context help. * * Default implementation does nothing. * * @see providesContextHelp() */ virtual void showContextHelp(); /** * @returns the geometry of the virtual keyboard * This geometry is in global coordinates */ QRect virtualKeyboardGeometry() const; /** * Sets the geometry of the virtual keyboard, The window may resize itself in order to make space for the keybaord * This geometry is in global coordinates */ virtual void setVirtualKeyboardGeometry(const QRect &geo); /** * Restores the AbstractClient after it had been hidden due to show on screen edge functionality. * The AbstractClient also gets raised (e.g. Panel mode windows can cover) and the AbstractClient * gets informed in a window specific way that it is shown and raised again. */ virtual void showOnScreenEdge(); QByteArray desktopFileName() const { return m_desktopFileName; } /** * Tries to terminate the process of this AbstractClient. * * Implementing subclasses can perform a windowing system solution for terminating. */ virtual void killWindow() = 0; virtual void destroyClient() = 0; enum class SameApplicationCheck { RelaxedForActive = 1 << 0, AllowCrossProcesses = 1 << 1 }; Q_DECLARE_FLAGS(SameApplicationChecks, SameApplicationCheck) static bool belongToSameApplication(const AbstractClient *c1, const AbstractClient *c2, SameApplicationChecks checks = SameApplicationChecks()); bool hasApplicationMenu() const; bool applicationMenuActive() const { return m_applicationMenuActive; } void setApplicationMenuActive(bool applicationMenuActive); QString applicationMenuServiceName() const { return m_applicationMenuServiceName; } QString applicationMenuObjectPath() const { return m_applicationMenuObjectPath; } virtual QString preferredColorScheme() const; QString colorScheme() const; void setColorScheme(const QString &colorScheme); /** * Request showing the application menu bar * @param actionId The DBus menu ID of the action that should be highlighted, 0 for the root menu */ void showApplicationMenu(int actionId); bool unresponsive() const; /** * Default implementation returns @c null. * Mostly intended for X11 clients, from EWMH: * @verbatim * If the WM_TRANSIENT_FOR property is set to None or Root window, the window should be * treated as a transient for all other windows in the same group. It has been noted that this * is a slight ICCCM violation, but as this behavior is pretty standard for many toolkits and * window managers, and is extremely unlikely to break anything, it seems reasonable to document * it as standard. * @endverbatim */ virtual bool groupTransient() const; /** * Default implementation returns @c null. * * Mostly for X11 clients, holds the client group */ virtual const Group *group() const; /** * Default implementation returns @c null. * * Mostly for X11 clients, holds the client group */ virtual Group *group(); /** * Returns whether window rules can be applied to this client. * * Default implementation returns @c false. */ virtual bool supportsWindowRules() const; /** * Return window management interface */ KWaylandServer::PlasmaWindowInterface *windowManagementInterface() const { return m_windowManagementInterface; } QRect fullscreenGeometryRestore() const; /** * Helper function to compute the icon out of an application id defined by @p fileName * * @returns an icon name that can be used with QIcon::fromTheme() */ static QString iconFromDesktopFile(const QString &fileName); public Q_SLOTS: virtual void closeWindow() = 0; protected Q_SLOTS: void setReadyForPainting(); Q_SIGNALS: void stackingOrderChanged(); void shadeChanged(); void opacityChanged(KWin::AbstractClient *toplevel, qreal oldOpacity); void damaged(KWin::AbstractClient *toplevel, const QRegion &damage); void inputTransformationChanged(); /** * This signal is emitted when the AbstractClient's frame geometry changes. * @deprecated since 5.19, use frameGeometryChanged instead */ void geometryChanged(); void geometryShapeChanged(KWin::AbstractClient *toplevel, const QRect &old); void windowClosed(KWin::AbstractClient *toplevel, KWin::Deleted *deleted); void windowShown(KWin::AbstractClient *toplevel); void windowHidden(KWin::AbstractClient *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(); /** * Emitted whenever the AbstractClient's screen changes. This can happen either in consequence to * a screen being removed/added or if the AbstractClient's geometry changes. * @since 4.11 */ void screenChanged(); void skipCloseAnimationChanged(); /** * Emitted whenever the window role of the window changes. * @since 5.0 */ void windowRoleChanged(); /** * Emitted whenever the window class name or resource name of the window changes. * @since 5.0 */ void windowClassChanged(); /** * @since 5.4 */ void hasAlphaChanged(); /** * Emitted whenever the Surface for this AbstractClient changes. */ void surfaceChanged(); /** * Emitted whenever the client's shadow changes. * @since 5.15 */ void shadowChanged(); /** * This signal is emitted when the AbstractClient's buffer geometry changes. */ void bufferGeometryChanged(KWin::AbstractClient *toplevel, const QRect &oldGeometry); /** * This signal is emitted when the AbstractClient's frame geometry changes. */ void frameGeometryChanged(KWin::AbstractClient *toplevel, const QRect &oldGeometry); /** * This signal is emitted when the AbstractClient's client geometry has changed. */ void clientGeometryChanged(KWin::AbstractClient *toplevel, const QRect &oldGeometry); /** * This signal is emitted when the visible geometry has changed. */ void visibleGeometryChanged(); void fullScreenChanged(); void skipTaskbarChanged(); void skipPagerChanged(); void skipSwitcherChanged(); void iconChanged(); void activeChanged(); void keepAboveChanged(bool); void keepBelowChanged(bool); /** * Emitted whenever the demands attention state changes. */ void demandsAttentionChanged(); void desktopPresenceChanged(KWin::AbstractClient *, int); // to be forwarded by Workspace void desktopChanged(); void activitiesChanged(KWin::AbstractClient *client); void x11DesktopIdsChanged(); void minimizedChanged(); void clientMinimized(KWin::AbstractClient *client, bool animate); void clientUnminimized(KWin::AbstractClient *client, bool animate); void paletteChanged(const QPalette &p); void colorSchemeChanged(); void captionChanged(); void clientMaximizedStateChanged(KWin::AbstractClient *, MaximizeMode); void clientMaximizedStateChanged(KWin::AbstractClient *c, bool h, bool v); void transientChanged(); void modalChanged(); void quickTileModeChanged(); void moveResizedChanged(); void moveResizeCursorChanged(CursorShape); void clientStartUserMovedResized(KWin::AbstractClient *); void clientStepUserMovedResized(KWin::AbstractClient *, const QRect &); void clientFinishUserMovedResized(KWin::AbstractClient *); void closeableChanged(bool); void minimizeableChanged(bool); void shadeableChanged(bool); void maximizeableChanged(bool); void desktopFileNameChanged(); void applicationMenuChanged(); void hasApplicationMenuChanged(bool); void applicationMenuActiveChanged(bool); void unresponsiveChanged(bool); void decorationChanged(); void hiddenChanged(); protected: void setWindowHandles(xcb_window_t client); void detectShape(xcb_window_t id); virtual void propertyNotifyEvent(xcb_property_notify_event_t *e); virtual void clientMessageEvent(xcb_client_message_event_t *e); Xcb::Property fetchWmClientLeader() const; void readWmClientLeader(Xcb::Property &p); void getWmClientLeader(); void getWmClientMachine(); /** * This function fetches the opaque region from this AbstractClient. * Will only be called on corresponding property changes and for initialization. */ void getWmOpaqueRegion(); void discardShapeRegion(); void getResourceClass(); void setResourceClass(const QByteArray &name, const QByteArray &className = QByteArray()); Xcb::Property fetchSkipCloseAnimation() const; void readSkipCloseAnimation(Xcb::Property &prop); void getSkipCloseAnimation(); void copyToDeleted(AbstractClient *c); void disownDataPassedToDeleted(); void deleteShadow(); void deleteEffectWindow(); void setDepth(int depth); Output *m_output = nullptr; QRect m_frameGeometry; QRect m_clientGeometry; QRect m_bufferGeometry; xcb_visualid_t m_visual; int bit_depth; NETWinInfo *info; bool ready_for_painting; /** * An FBO object KWin internal windows might render to. */ QSharedPointer m_internalFBO; QImage m_internalImage; protected: AbstractClient(); void setFirstInTabBox(bool enable) { m_firstInTabBox = enable; } void setIcon(const QIcon &icon); void startAutoRaise(); void autoRaise(); bool isMostRecentlyRaised() const; void markAsZombie(); /** * Whether the window accepts focus. * The difference to wantsInput is that the implementation should not check rules and return * what the window effectively supports. */ virtual bool acceptsFocus() const = 0; /** * Called from setActive once the active value got updated, but before the changed signal * is emitted. * * Default implementation does nothing. */ virtual void doSetActive(); /** * Called from setKeepAbove once the keepBelow value got updated, but before the changed signal * is emitted. * * Default implementation does nothing. */ virtual void doSetKeepAbove(); /** * Called from setKeepBelow once the keepBelow value got updated, but before the changed signal * is emitted. * * Default implementation does nothing. */ virtual void doSetKeepBelow(); /** * Called from setShade() once the shadeMode value got updated, but before the changed signal * is emitted. * * Default implementation does nothing. */ virtual void doSetShade(ShadeMode previousShadeMode); /** * Called from setDeskop once the desktop value got updated, but before the changed signal * is emitted. * * Default implementation does nothing. */ virtual void doSetDesktop(); /** * Called from @ref setOnActivities just after the activity list member has been updated, but before * @ref updateActivities is called. * * @param activityList the new list of activities set on that client * * Default implementation does nothing */ virtual void doSetOnActivities(const QStringList &activityList); /** * Called from @ref minimize and @ref unminimize once the minimized value got updated, but before the * changed signal is emitted. * * Default implementation does nothig. */ virtual void doMinimize(); virtual bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const = 0; virtual void doSetSkipTaskbar(); virtual void doSetSkipPager(); virtual void doSetSkipSwitcher(); virtual void doSetDemandsAttention(); virtual void doSetQuickTileMode(); void setupWindowManagementInterface(); void updateColorScheme(); void setTransientFor(AbstractClient *transientFor); /** * Just removes the @p cl from the transients without any further checks. */ void removeTransientFromList(AbstractClient *cl); virtual Layer belongsToLayer() const; virtual bool belongsToDesktop() const; void invalidateLayer(); bool isActiveFullScreen() const; virtual Layer layerForDock() const; // electric border / quick tiling void setElectricBorderMode(QuickTileMode mode); QuickTileMode electricBorderMode() const { return m_electricMode; } void setElectricBorderMaximizing(bool maximizing); bool isElectricBorderMaximizing() const { return m_electricMaximizing; } void updateElectricGeometryRestore(); QRect quickTileGeometryRestore() const; QRect quickTileGeometry(QuickTileMode mode, const QPoint &pos) const; void updateQuickTileMode(QuickTileMode newMode) { m_quickTileMode = newMode; } // geometry handling void checkOffscreenPosition(QRect *geom, const QRect &screenArea); int borderLeft() const; int borderRight() const; int borderTop() const; int borderBottom() const; virtual void changeMaximize(bool horizontal, bool vertical, bool adjust); void setGeometryRestore(const QRect &rect); void blockGeometryUpdates(bool block); void blockGeometryUpdates(); void unblockGeometryUpdates(); bool areGeometryUpdatesBlocked() const; enum class MoveResizeMode : uint { None, Move = 0x1, Resize = 0x2, MoveResize = Move | Resize, }; MoveResizeMode pendingMoveResizeMode() const; void setPendingMoveResizeMode(MoveResizeMode mode); virtual void moveResizeInternal(const QRect &rect, MoveResizeMode mode) = 0; /** * @returns whether the Client is currently in move resize mode */ bool isInteractiveMoveResize() const { return m_interactiveMoveResize.enabled; } /** * Sets whether the Client is in move resize mode to @p enabled. */ void setInteractiveMoveResize(bool enabled) { m_interactiveMoveResize.enabled = enabled; } /** * @returns whether the move resize mode is unrestricted. */ bool isUnrestrictedInteractiveMoveResize() const { return m_interactiveMoveResize.unrestricted; } /** * Sets whether move resize mode is unrestricted to @p set. */ void setUnrestrictedInteractiveMoveResize(bool set) { m_interactiveMoveResize.unrestricted = set; } QPoint interactiveMoveOffset() const { return m_interactiveMoveResize.offset; } void setInteractiveMoveOffset(const QPoint &offset) { m_interactiveMoveResize.offset = offset; } QPoint invertedInteractiveMoveOffset() const { return m_interactiveMoveResize.invertedOffset; } void setInvertedInteractiveMoveOffset(const QPoint &offset) { m_interactiveMoveResize.invertedOffset = offset; } QRect initialInteractiveMoveResizeGeometry() const { return m_interactiveMoveResize.initialGeometry; } /** * Sets the initial move resize geometry to the current geometry. */ void updateInitialMoveResizeGeometry(); void setMoveResizeGeometry(const QRect &geo); Gravity interactiveMoveResizeGravity() const { return m_interactiveMoveResize.gravity; } void setInteractiveMoveResizeGravity(Gravity gravity) { m_interactiveMoveResize.gravity = gravity; } bool isInteractiveMoveResizePointerButtonDown() const { return m_interactiveMoveResize.buttonDown; } void setInteractiveMoveResizePointerButtonDown(bool down) { m_interactiveMoveResize.buttonDown = down; } Output *interactiveMoveResizeStartOutput() const { return m_interactiveMoveResize.startOutput; } void checkUnrestrictedInteractiveMoveResize(); /** * Sets an appropriate cursor shape for the logical mouse position. */ void updateCursor(); void startDelayedInteractiveMoveResize(); void stopDelayedInteractiveMoveResize(); bool startInteractiveMoveResize(); /** * Called from startMoveResize. * * Implementing classes should return @c false if starting move resize should * get aborted. In that case startMoveResize will also return @c false. * * Base implementation returns @c true. */ virtual bool doStartInteractiveMoveResize(); virtual void doFinishInteractiveMoveResize(); void finishInteractiveMoveResize(bool cancel); /** * Leaves the move resize mode. * * Inheriting classes must invoke the base implementation which * ensures that the internal mode is properly ended. */ virtual void leaveInteractiveMoveResize(); /* * Checks if the mouse cursor is near the edge of the screen and if so * activates quick tiling or maximization */ void checkQuickTilingMaximizationZones(int xroot, int yroot); /** * Whether a sync request is still pending. * Default implementation returns @c false. */ virtual bool isWaitingForInteractiveMoveResizeSync() const; /** * Called during handling a resize. Implementing subclasses can use this * method to perform windowing system specific syncing. * * Default implementation does nothing. */ virtual void doInteractiveResizeSync(); void handleInteractiveMoveResize(int x, int y, int x_root, int y_root); void handleInteractiveMoveResize(const QPoint &local, const QPoint &global); void dontInteractiveMoveResize(); virtual QSize resizeIncrements() const; /** * Returns the interactive move resize gravity depending on the Decoration's section * under mouse. If no decoration it returns Gravity::None. */ Gravity mouseGravity() const; void setDecoration(QSharedPointer decoration); void startDecorationDoubleClickTimer(); void invalidateDecorationDoubleClickTimer(); void updateDecorationInputShape(); void setDesktopFileName(QByteArray name); QString iconFromDesktopFile() const; void updateApplicationMenuServiceName(const QString &serviceName); void updateApplicationMenuObjectPath(const QString &objectPath); void setUnresponsive(bool unresponsive); virtual void setShortcutInternal(); QString shortcutCaptionSuffix() const; virtual void updateCaption() = 0; /** * Looks for another AbstractClient with same captionNormal and captionSuffix. * If no such AbstractClient exists @c nullptr is returned. */ AbstractClient *findClientWithSameCaption() const; void finishWindowRules(); void discardTemporaryRules(); bool tabTo(AbstractClient *other, bool behind, bool activate); void startShadeHoverTimer(); void startShadeUnhoverTimer(); // The geometry that the client should be restored when the virtual keyboard closes QRect keyboardGeometryRestore() const; void setKeyboardGeometryRestore(const QRect &geom); QRect m_virtualKeyboardGeometry; void setFullscreenGeometryRestore(const QRect &geom); void cleanTabBox(); QStringList m_activityList; private Q_SLOTS: void shadeHover(); void shadeUnhover(); private: // when adding new data members, check also copyToDeleted() QUuid m_internalId; Xcb::Window m_client; bool is_shape; EffectWindowImpl *effect_window; Shadow *m_shadow = nullptr; QByteArray resource_name; QByteArray resource_class; ClientMachine *m_clientMachine; xcb_window_t m_wmClientLeader; QRegion opaque_region; mutable QRegion m_shapeRegion; mutable bool m_shapeRegionIsValid = false; bool m_skipCloseAnimation; quint32 m_pendingSurfaceId = 0; QPointer m_surface; // when adding new data members, check also copyToDeleted() qreal m_opacity = 1.0; int m_stackingOrder = 0; private: void handlePaletteChange(); QSharedPointer m_tabBoxClient; bool m_firstInTabBox = false; bool m_skipTaskbar = false; /** * Unaffected by KWin */ bool m_originalSkipTaskbar = false; bool m_skipPager = false; bool m_skipSwitcher = false; QIcon m_icon; bool m_active = false; bool m_zombie = false; bool m_keepAbove = false; bool m_keepBelow = false; bool m_demandsAttention = false; bool m_minimized = false; QTimer *m_autoRaiseTimer = nullptr; QTimer *m_shadeHoverTimer = nullptr; ShadeMode m_shadeMode = ShadeNone; QVector m_desktops; int m_activityUpdatesBlocked = 0; bool m_blockedActivityUpdatesRequireTransients = false; QString m_colorScheme; std::shared_ptr m_palette; static QHash> s_palettes; static std::shared_ptr s_defaultPalette; KWaylandServer::PlasmaWindowInterface *m_windowManagementInterface = nullptr; AbstractClient *m_transientFor = nullptr; QList m_transients; bool m_modal = false; Layer m_layer = UnknownLayer; // electric border/quick tiling QuickTileMode m_electricMode = QuickTileFlag::None; QRect m_electricGeometryRestore; bool m_electricMaximizing = false; // The quick tile mode of this window. int m_quickTileMode = int(QuickTileFlag::None); QTimer *m_electricMaximizingDelay = nullptr; // geometry int m_blockGeometryUpdates = 0; // > 0 = New geometry is remembered, but not actually set MoveResizeMode m_pendingMoveResizeMode = MoveResizeMode::None; friend class GeometryUpdatesBlocker; QRect m_moveResizeGeometry; QRect m_keyboardGeometryRestore; QRect m_maximizeGeometryRestore; QRect m_fullscreenGeometryRestore; struct { bool enabled = false; bool unrestricted = false; QPoint offset; QPoint invertedOffset; QRect initialGeometry; Gravity gravity = Gravity::None; bool buttonDown = false; CursorShape cursor = Qt::ArrowCursor; Output *startOutput = nullptr; QTimer *delayedTimer = nullptr; } m_interactiveMoveResize; struct { QSharedPointer decoration; QPointer client; QElapsedTimer doubleClickTimer; QRegion inputRegion; } m_decoration; QByteArray m_desktopFileName; bool m_applicationMenuActive = false; QString m_applicationMenuServiceName; QString m_applicationMenuObjectPath; bool m_unresponsive = false; QKeySequence _shortcut; WindowRules m_rules; }; /** * Helper for AbstractClient::blockGeometryUpdates() being called in pairs (true/false) */ class GeometryUpdatesBlocker { public: explicit GeometryUpdatesBlocker(AbstractClient *c) : cl(c) { cl->blockGeometryUpdates(true); } ~GeometryUpdatesBlocker() { cl->blockGeometryUpdates(false); } private: AbstractClient *cl; }; inline xcb_window_t AbstractClient::window() const { return m_client; } inline void AbstractClient::setWindowHandles(xcb_window_t w) { Q_ASSERT(!m_client.isValid() && w != XCB_WINDOW_NONE); m_client.reset(w, false); } inline QRect AbstractClient::bufferGeometry() const { return m_bufferGeometry; } inline QRect AbstractClient::clientGeometry() const { return m_clientGeometry; } inline QSize AbstractClient::clientSize() const { return m_clientGeometry.size(); } inline QRect AbstractClient::frameGeometry() const { return m_frameGeometry; } inline QSize AbstractClient::size() const { return m_frameGeometry.size(); } inline QPoint AbstractClient::pos() const { return m_frameGeometry.topLeft(); } inline int AbstractClient::x() const { return m_frameGeometry.x(); } inline int AbstractClient::y() const { return m_frameGeometry.y(); } inline int AbstractClient::width() const { return m_frameGeometry.width(); } inline int AbstractClient::height() const { return m_frameGeometry.height(); } inline QRect AbstractClient::rect() const { return QRect(0, 0, width(), height()); } inline bool AbstractClient::readyForPainting() const { return ready_for_painting; } inline xcb_visualid_t AbstractClient::visual() const { return m_visual; } inline bool AbstractClient::isDesktop() const { return windowType() == NET::Desktop; } inline bool AbstractClient::isDock() const { return windowType() == NET::Dock; } inline bool AbstractClient::isMenu() const { return windowType() == NET::Menu; } inline bool AbstractClient::isToolbar() const { return windowType() == NET::Toolbar; } inline bool AbstractClient::isSplash() const { return windowType() == NET::Splash; } inline bool AbstractClient::isUtility() const { return windowType() == NET::Utility; } inline bool AbstractClient::isDialog() const { return windowType() == NET::Dialog; } inline bool AbstractClient::isNormalWindow() const { return windowType() == NET::Normal; } inline bool AbstractClient::isDropdownMenu() const { return windowType() == NET::DropdownMenu; } inline bool AbstractClient::isPopupMenu() const { return windowType() == NET::PopupMenu; } inline bool AbstractClient::isTooltip() const { return windowType() == NET::Tooltip; } inline bool AbstractClient::isNotification() const { return windowType() == NET::Notification; } inline bool AbstractClient::isCriticalNotification() const { return windowType() == NET::CriticalNotification; } inline bool AbstractClient::isOnScreenDisplay() const { return windowType() == NET::OnScreenDisplay; } inline bool AbstractClient::isComboBox() const { return windowType() == NET::ComboBox; } inline bool AbstractClient::isDNDIcon() const { return windowType() == NET::DNDIcon; } inline bool AbstractClient::isLockScreen() const { return false; } inline bool AbstractClient::isInputMethod() const { return false; } inline bool AbstractClient::isOutline() const { return false; } inline bool AbstractClient::isInternal() const { return false; } inline bool AbstractClient::shape() const { return is_shape; } inline int AbstractClient::depth() const { return bit_depth; } inline bool AbstractClient::hasAlpha() const { return depth() == 32; } inline const QRegion &AbstractClient::opaqueRegion() const { return opaque_region; } inline EffectWindowImpl *AbstractClient::effectWindow() { return effect_window; } inline const EffectWindowImpl *AbstractClient::effectWindow() const { return effect_window; } inline bool AbstractClient::isOnAllDesktops() const { return desktops().isEmpty(); } inline bool AbstractClient::isOnAllActivities() const { return activities().isEmpty(); } inline bool AbstractClient::isOnActivity(const QString &activity) const { return activities().isEmpty() || activities().contains(activity); } inline QByteArray AbstractClient::resourceName() const { return resource_name; // it is always lowercase } inline QByteArray AbstractClient::resourceClass() const { return resource_class; // it is always lowercase } inline const ClientMachine *AbstractClient::clientMachine() const { return m_clientMachine; } inline quint32 AbstractClient::pendingSurfaceId() const { return m_pendingSurfaceId; } inline const QSharedPointer &AbstractClient::internalFramebufferObject() const { return m_internalFBO; } inline QImage AbstractClient::internalImageObject() const { return m_internalImage; } template inline T *AbstractClient::findInList(const QList &list, std::function func) { static_assert(std::is_base_of::value, "U must be derived from T"); const auto it = std::find_if(list.begin(), list.end(), func); if (it == list.end()) { return nullptr; } return *it; } inline bool AbstractClient::isPopupWindow() const { switch (windowType()) { case NET::ComboBox: case NET::DropdownMenu: case NET::PopupMenu: case NET::Tooltip: return true; default: return false; } } inline const QList &AbstractClient::transients() const { return m_transients; } inline bool AbstractClient::areGeometryUpdatesBlocked() const { return m_blockGeometryUpdates != 0; } inline void AbstractClient::blockGeometryUpdates() { m_blockGeometryUpdates++; } inline void AbstractClient::unblockGeometryUpdates() { m_blockGeometryUpdates--; } inline AbstractClient::MoveResizeMode AbstractClient::pendingMoveResizeMode() const { return m_pendingMoveResizeMode; } inline void AbstractClient::setPendingMoveResizeMode(MoveResizeMode mode) { m_pendingMoveResizeMode = MoveResizeMode(uint(m_pendingMoveResizeMode) | uint(mode)); } KWIN_EXPORT QDebug operator<<(QDebug debug, const AbstractClient *toplevel); } // namespace KWin Q_DECLARE_METATYPE(KWin::AbstractClient *) Q_DECLARE_METATYPE(QList) Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::AbstractClient::SameApplicationChecks) #endif