kwin/toplevel.h

679 lines
20 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 "virtualdesktops.h"
#include "workspace.h"
#include <X11/extensions/Xdamage.h>
#include <xcb/xfixes.h>
class NETWinInfo2;
namespace KWin
{
Improved resolving whether a window is on local machine Most windows use the hostname in WM_CLIENT_MACHINE, but there are windows using the FQDN (for example libreoffice). So instead of "foo" it is "foo.local.net" or similar. The logic so far has been unable to properly determine whether windows with FQDN are on the local system. In order to solve this problem the handling is split out into an own class which stores the information of hostname and whether it is a local machine. This is to not query multiple times. To determine whether the Client is on the local system getaddrinfo is used for the own hostname and the FQDN provided in WM_CLIENT_MACHINE. If one of the queried names matches, we know that it is on the local machine. The old logic to compare the hostname is still used and getaddrinfo is only a fallback in case hostname does not match. The problem with getaddrinfo is, that it accesses the network and by that could block. To circumvent this problem the calls are moved into threads by using QtConcurrent::run. Obviously this brings disadvantages. When trying to resolve whether a Client is on the local machine and a FQDN is used, the information is initially wrong. The new ClientMachine class emits a signal when the information that the system is local becomes available, but for some things this is just too late: * window rules are already gathered * Session Management has already taken place In both cases this is an acceptable loss. For window rules it just needs a proper matching of the machine in case of localhost (remote hosts are not affected). And the case of session management is very academic as it is unlikely that a restoring session contains remote windows. BUG: 308391 FIXED-IN: 4.11 REVIEW: 108235
2013-01-07 11:07:27 +04:00
class ClientMachine;
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(QRect visibleRect READ visibleRect)
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 NOTIFY screenChanged)
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)
/**
* Whether the window is on all desktops. That is desktop is -1.
**/
Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops)
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 NOTIFY activitiesChanged)
/**
* 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:
explicit Toplevel(Workspace *ws);
2011-01-30 17:34:42 +03:00
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
virtual NET::WindowType windowType(bool direct = false, int supported_types = 0) const = 0;
2011-01-30 17:34:42 +03:00
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;
Improved resolving whether a window is on local machine Most windows use the hostname in WM_CLIENT_MACHINE, but there are windows using the FQDN (for example libreoffice). So instead of "foo" it is "foo.local.net" or similar. The logic so far has been unable to properly determine whether windows with FQDN are on the local system. In order to solve this problem the handling is split out into an own class which stores the information of hostname and whether it is a local machine. This is to not query multiple times. To determine whether the Client is on the local system getaddrinfo is used for the own hostname and the FQDN provided in WM_CLIENT_MACHINE. If one of the queried names matches, we know that it is on the local machine. The old logic to compare the hostname is still used and getaddrinfo is only a fallback in case hostname does not match. The problem with getaddrinfo is, that it accesses the network and by that could block. To circumvent this problem the calls are moved into threads by using QtConcurrent::run. Obviously this brings disadvantages. When trying to resolve whether a Client is on the local machine and a FQDN is used, the information is initially wrong. The new ClientMachine class emits a signal when the information that the system is local becomes available, but for some things this is just too late: * window rules are already gathered * Session Management has already taken place In both cases this is an acceptable loss. For window rules it just needs a proper matching of the machine in case of localhost (remote hosts are not affected). And the case of session management is very academic as it is unlikely that a restoring session contains remote windows. BUG: 308391 FIXED-IN: 4.11 REVIEW: 108235
2013-01-07 11:07:27 +04:00
const ClientMachine *clientMachine() const;
2011-01-30 17:34:42 +03:00
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;
/**
* Resets the damage state and sends a request for the damage region.
* A call to this function must be followed by a call to getDamageRegionReply(),
* or the reply will be leaked.
*
* Returns true if the window was damaged, and false otherwise.
*/
bool resetAndFetchDamage();
/**
* Gets the reply from a previous call to resetAndFetchDamage().
* Calling this function is a no-op if there is no pending reply.
* Call damage() to return the fetched region.
*/
void getDamageRegionReply();
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 paddingChanged(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();
/**
* Emitted whenever the state changes in a way, that the Compositor should
* schedule a repaint of the scene.
**/
void needsRepaint();
void activitiesChanged(KWin::Toplevel* toplevel);
/**
* Emitted whenever the Toplevel's screen changes. This can happen either in consequence to
* a screen being removed/added or if the Toplevel's geometry changes.
* @since 4.11
**/
void screenChanged();
protected Q_SLOTS:
/**
* Checks whether the screen number for this Toplevel changed and updates if needed.
* Any method changing the geometry of the Toplevel should call this method.
**/
void checkScreen();
void setupCheckScreenConnection();
void removeCheckScreenConnection();
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);
2012-12-12 00:21:35 +04:00
xcb_pixmap_t createWindowPixmap();
2011-01-30 17:34:42 +03:00
void discardWindowPixmap();
void addDamageFull();
void getWmClientLeader();
void getWmClientMachine();
void setReadyForPainting();
/**
* @returns Whether there is a compositor and it is active.
**/
bool compositing() const;
/**
* 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;
protected:
bool m_isDamaged;
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
bool is_shape;
EffectWindowImpl* effect_window;
QByteArray resource_name;
QByteArray resource_class;
Improved resolving whether a window is on local machine Most windows use the hostname in WM_CLIENT_MACHINE, but there are windows using the FQDN (for example libreoffice). So instead of "foo" it is "foo.local.net" or similar. The logic so far has been unable to properly determine whether windows with FQDN are on the local system. In order to solve this problem the handling is split out into an own class which stores the information of hostname and whether it is a local machine. This is to not query multiple times. To determine whether the Client is on the local system getaddrinfo is used for the own hostname and the FQDN provided in WM_CLIENT_MACHINE. If one of the queried names matches, we know that it is on the local machine. The old logic to compare the hostname is still used and getaddrinfo is only a fallback in case hostname does not match. The problem with getaddrinfo is, that it accesses the network and by that could block. To circumvent this problem the calls are moved into threads by using QtConcurrent::run. Obviously this brings disadvantages. When trying to resolve whether a Client is on the local machine and a FQDN is used, the information is initially wrong. The new ClientMachine class emits a signal when the information that the system is local becomes available, but for some things this is just too late: * window rules are already gathered * Session Management has already taken place In both cases this is an acceptable loss. For window rules it just needs a proper matching of the machine in case of localhost (remote hosts are not affected). And the case of session management is very academic as it is unlikely that a restoring session contains remote windows. BUG: 308391 FIXED-IN: 4.11 REVIEW: 108235
2013-01-07 11:07:27 +04:00
ClientMachine *m_clientMachine;
2011-01-30 17:34:42 +03:00
WId wmClientLeaderWin;
QByteArray window_role;
bool unredirect;
bool unredirectSuspend; // when unredirected, but pixmap is needed temporarily
bool m_damageReplyPending;
QRegion opaque_region;
xcb_xfixes_fetch_region_cookie_t m_regionCookie;
int m_screen;
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(VirtualDesktopManager::self()->current());
2011-01-30 17:34:42 +03:00
}
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
}
Improved resolving whether a window is on local machine Most windows use the hostname in WM_CLIENT_MACHINE, but there are windows using the FQDN (for example libreoffice). So instead of "foo" it is "foo.local.net" or similar. The logic so far has been unable to properly determine whether windows with FQDN are on the local system. In order to solve this problem the handling is split out into an own class which stores the information of hostname and whether it is a local machine. This is to not query multiple times. To determine whether the Client is on the local system getaddrinfo is used for the own hostname and the FQDN provided in WM_CLIENT_MACHINE. If one of the queried names matches, we know that it is on the local machine. The old logic to compare the hostname is still used and getaddrinfo is only a fallback in case hostname does not match. The problem with getaddrinfo is, that it accesses the network and by that could block. To circumvent this problem the calls are moved into threads by using QtConcurrent::run. Obviously this brings disadvantages. When trying to resolve whether a Client is on the local machine and a FQDN is used, the information is initially wrong. The new ClientMachine class emits a signal when the information that the system is local becomes available, but for some things this is just too late: * window rules are already gathered * Session Management has already taken place In both cases this is an acceptable loss. For window rules it just needs a proper matching of the machine in case of localhost (remote hosts are not affected). And the case of session management is very academic as it is unlikely that a restoring session contains remote windows. BUG: 308391 FIXED-IN: 4.11 REVIEW: 108235
2013-01-07 11:07:27 +04:00
inline const ClientMachine *Toplevel::clientMachine() const
{
return m_clientMachine;
}
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
Q_DECLARE_METATYPE(KWin::Toplevel*)
#endif