kwin/rules.h

378 lines
12 KiB
C
Raw Normal View History

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2004 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_RULES_H
#define KWIN_RULES_H
#include <netwm_def.h>
#include <QRect>
#include <kconfiggroup.h>
#include <kdebug.h>
#include "placement.h"
#include <kdecoration.h>
#include "options.h"
#include "utils.h"
class KConfig;
class KXMessages;
namespace KWin
{
class Client;
class Rules;
#ifndef KCMRULES // only for kwin core
class WindowRules
: public KDecorationDefines
2011-01-30 14:34:42 +00:00
{
public:
explicit WindowRules(const QVector< Rules* >& rules);
2011-01-30 14:34:42 +00:00
WindowRules();
void update(Client*, int selection);
2011-01-30 14:34:42 +00:00
void discardTemporary();
bool contains(const Rules* rule) const;
void remove(Rules* rule);
Placement::Policy checkPlacement(Placement::Policy placement) const;
QRect checkGeometry(QRect rect, bool init = false) const;
// use 'invalidPoint' with checkPosition, unlike QSize() and QRect(), QPoint() is a valid point
QPoint checkPosition(QPoint pos, bool init = false) const;
QSize checkSize(QSize s, bool init = false) const;
QSize checkMinSize(QSize s) const;
QSize checkMaxSize(QSize s) const;
int checkOpacityActive(int s) const;
int checkOpacityInactive(int s) const;
bool checkIgnoreGeometry(bool ignore, bool init = false) const;
2011-01-30 14:34:42 +00:00
int checkDesktop(int desktop, bool init = false) const;
2012-08-24 16:48:50 +00:00
int checkScreen(int screen, bool init = false) const;
QString checkActivity(QString activity, bool init = false) const;
2011-01-30 14:34:42 +00:00
NET::WindowType checkType(NET::WindowType type) const;
MaximizeMode checkMaximize(MaximizeMode mode, bool init = false) const;
bool checkMinimize(bool minimized, bool init = false) const;
ShadeMode checkShade(ShadeMode shade, bool init = false) const;
bool checkSkipTaskbar(bool skip, bool init = false) const;
bool checkSkipPager(bool skip, bool init = false) const;
bool checkSkipSwitcher(bool skip, bool init = false) const;
bool checkKeepAbove(bool above, bool init = false) const;
bool checkKeepBelow(bool below, bool init = false) const;
bool checkFullScreen(bool fs, bool init = false) const;
bool checkNoBorder(bool noborder, bool init = false) const;
bool checkBlockCompositing(bool block) const;
2011-01-30 14:34:42 +00:00
int checkFSP(int fsp) const;
bool checkAcceptFocus(bool focus) const;
bool checkCloseable(bool closeable) const;
bool checkAutogrouping(bool autogroup) const;
bool checkAutogroupInForeground(bool fg) const;
QString checkAutogroupById(QString id) const;
bool checkStrictGeometry(bool strict) const;
QString checkShortcut(QString s, bool init = false) const;
bool checkDisableGlobalShortcuts(bool disable) const;
private:
MaximizeMode checkMaximizeVert(MaximizeMode mode, bool init) const;
MaximizeMode checkMaximizeHoriz(MaximizeMode mode, bool init) const;
QVector< Rules* > rules;
};
#endif
class Rules
: public KDecorationDefines
2011-01-30 14:34:42 +00:00
{
public:
Rules();
explicit Rules(const KConfigGroup&);
2011-01-30 14:34:42 +00:00
Rules(const QString&, bool temporary);
enum Type {
Position = 1<<0, Size = 1<<1, Desktop = 1<<2,
MaximizeVert = 1<<3, MaximizeHoriz = 1<<4, Minimize = 1<<5,
Shade = 1<<6, SkipTaskbar = 1<<7, SkipPager = 1<<8,
SkipSwitcher = 1<<9, Above = 1<<10, Below = 1<<11, Fullscreen = 1<<12,
NoBorder = 1<<13, OpacityActive = 1<<14, OpacityInactive = 1<<15,
2012-08-24 16:48:50 +00:00
Activity = 1<<16, Screen = 1<<17, All = 0xffffffff
};
Q_DECLARE_FLAGS(Types, Type)
2011-01-30 14:34:42 +00:00
void write(KConfigGroup&) const;
bool isEmpty() const;
#ifndef KCMRULES
2011-01-30 14:34:42 +00:00
void discardUsed(bool withdrawn);
bool match(const Client* c) const;
bool update(Client*, int selection);
2011-01-30 14:34:42 +00:00
bool isTemporary() const;
bool discardTemporary(bool force); // removes if temporary and forced or too old
bool applyPlacement(Placement::Policy& placement) const;
bool applyGeometry(QRect& rect, bool init) const;
// use 'invalidPoint' with applyPosition, unlike QSize() and QRect(), QPoint() is a valid point
bool applyPosition(QPoint& pos, bool init) const;
bool applySize(QSize& s, bool init) const;
bool applyMinSize(QSize& s) const;
bool applyMaxSize(QSize& s) const;
bool applyOpacityActive(int& s) const;
bool applyOpacityInactive(int& s) const;
bool applyIgnoreGeometry(bool& ignore, bool init) const;
2011-01-30 14:34:42 +00:00
bool applyDesktop(int& desktop, bool init) const;
2012-08-24 16:48:50 +00:00
bool applyScreen(int& desktop, bool init) const;
bool applyActivity(QString& activity, bool init) const;
2011-01-30 14:34:42 +00:00
bool applyType(NET::WindowType& type) const;
bool applyMaximizeVert(MaximizeMode& mode, bool init) const;
bool applyMaximizeHoriz(MaximizeMode& mode, bool init) const;
bool applyMinimize(bool& minimized, bool init) const;
bool applyShade(ShadeMode& shade, bool init) const;
bool applySkipTaskbar(bool& skip, bool init) const;
bool applySkipPager(bool& skip, bool init) const;
bool applySkipSwitcher(bool& skip, bool init) const;
bool applyKeepAbove(bool& above, bool init) const;
bool applyKeepBelow(bool& below, bool init) const;
bool applyFullScreen(bool& fs, bool init) const;
bool applyNoBorder(bool& noborder, bool init) const;
bool applyBlockCompositing(bool& block) const;
2011-01-30 14:34:42 +00:00
bool applyFSP(int& fsp) const;
bool applyAcceptFocus(bool& focus) const;
bool applyCloseable(bool& closeable) const;
bool applyAutogrouping(bool& autogroup) const;
bool applyAutogroupInForeground(bool& fg) const;
bool applyAutogroupById(QString& id) const;
bool applyStrictGeometry(bool& strict) const;
bool applyShortcut(QString& shortcut, bool init) const;
bool applyDisableGlobalShortcuts(bool& disable) const;
private:
#endif
2011-01-30 14:34:42 +00:00
bool matchType(NET::WindowType match_type) const;
bool matchWMClass(const QByteArray& match_class, const QByteArray& match_name) const;
bool matchRole(const QByteArray& match_role) const;
bool matchTitle(const QString& match_title) 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 07:07:27 +00:00
bool matchClientMachine(const QByteArray& match_machine, bool local) const;
2011-01-30 14:34:42 +00:00
// All these values are saved to the cfg file, and are also used in kstart!
enum {
Unused = 0,
DontAffect, // use the default value
Force, // force the given value
Apply, // apply only after initial mapping
Remember, // like apply, and remember the value when the window is withdrawn
ApplyNow, // apply immediatelly, then forget the setting
ForceTemporarily // apply and force until the window is withdrawn
};
enum SetRule {
UnusedSetRule = Unused,
SetRuleDummy = 256 // so that it's at least short int
};
enum ForceRule {
UnusedForceRule = Unused,
ForceRuleDummy = 256 // so that it's at least short int
};
enum StringMatch {
FirstStringMatch,
UnimportantMatch = FirstStringMatch,
ExactMatch,
SubstringMatch,
RegExpMatch,
LastStringMatch = RegExpMatch
};
void readFromCfg(const KConfigGroup& cfg);
static SetRule readSetRule(const KConfigGroup&, const QString& key);
static ForceRule readForceRule(const KConfigGroup&, const QString& key);
static NET::WindowType readType(const KConfigGroup&, const QString& key);
#ifndef KCMRULES
2011-01-30 14:34:42 +00:00
static bool checkSetRule(SetRule rule, bool init);
static bool checkForceRule(ForceRule rule);
static bool checkSetStop(SetRule rule);
static bool checkForceStop(ForceRule rule);
#endif
2011-01-30 14:34:42 +00:00
int temporary_state; // e.g. for kstart
QString description;
QByteArray wmclass;
StringMatch wmclassmatch;
bool wmclasscomplete;
QByteArray windowrole;
StringMatch windowrolematch;
QString title;
StringMatch titlematch;
QByteArray clientmachine;
StringMatch clientmachinematch;
unsigned long types; // types for matching
Placement::Policy placement;
ForceRule placementrule;
QPoint position;
SetRule positionrule;
QSize size;
SetRule sizerule;
QSize minsize;
ForceRule minsizerule;
QSize maxsize;
ForceRule maxsizerule;
int opacityactive;
ForceRule opacityactiverule;
int opacityinactive;
ForceRule opacityinactiverule;
bool ignoregeometry;
SetRule ignoregeometryrule;
2011-01-30 14:34:42 +00:00
int desktop;
SetRule desktoprule;
2012-08-24 16:48:50 +00:00
int screen;
SetRule screenrule;
QString activity;
SetRule activityrule;
2011-01-30 14:34:42 +00:00
NET::WindowType type; // type for setting
ForceRule typerule;
bool maximizevert;
SetRule maximizevertrule;
bool maximizehoriz;
SetRule maximizehorizrule;
bool minimize;
SetRule minimizerule;
bool shade;
SetRule shaderule;
bool skiptaskbar;
SetRule skiptaskbarrule;
bool skippager;
SetRule skippagerrule;
bool skipswitcher;
SetRule skipswitcherrule;
bool above;
SetRule aboverule;
bool below;
SetRule belowrule;
bool fullscreen;
SetRule fullscreenrule;
bool noborder;
SetRule noborderrule;
bool blockcompositing;
ForceRule blockcompositingrule;
2011-01-30 14:34:42 +00:00
int fsplevel;
ForceRule fsplevelrule;
bool acceptfocus;
ForceRule acceptfocusrule;
bool closeable;
ForceRule closeablerule;
bool autogroup;
ForceRule autogrouprule;
bool autogroupfg;
ForceRule autogroupfgrule;
QString autogroupid;
ForceRule autogroupidrule;
bool strictgeometry;
ForceRule strictgeometryrule;
QString shortcut;
SetRule shortcutrule;
bool disableglobalshortcuts;
ForceRule disableglobalshortcutsrule;
friend QDebug& operator<<(QDebug& stream, const Rules*);
};
#ifndef KCMRULES
class RuleBook : public QObject
{
Q_OBJECT
public:
virtual ~RuleBook();
WindowRules find(const Client*, bool);
void discardUsed(Client* c, bool withdraw);
void setUpdatesDisabled(bool disable);
bool areUpdatesDisabled() const;
void load();
void edit(Client* c, bool whole_app);
void requestDiskStorage();
private Q_SLOTS:
void temporaryRulesMessage(const QString&);
void cleanupTemporaryRules();
void save();
private:
void deleteAll();
QTimer *m_updateTimer;
bool m_updatesDisabled;
QList<Rules*> m_rules;
QScopedPointer<KXMessages> m_temporaryRulesMessages;
KWIN_SINGLETON(RuleBook)
};
inline
bool RuleBook::areUpdatesDisabled() const
{
return m_updatesDisabled;
}
inline
2011-01-30 14:34:42 +00:00
bool Rules::checkSetRule(SetRule rule, bool init)
{
if (rule > (SetRule)DontAffect) { // Unused or DontAffect
if (rule == (SetRule)Force || rule == (SetRule) ApplyNow
|| rule == (SetRule) ForceTemporarily || init)
return true;
}
2011-01-30 14:34:42 +00:00
return false;
}
inline
2011-01-30 14:34:42 +00:00
bool Rules::checkForceRule(ForceRule rule)
{
return rule == (ForceRule)Force || rule == (ForceRule) ForceTemporarily;
}
inline
2011-01-30 14:34:42 +00:00
bool Rules::checkSetStop(SetRule rule)
{
return rule != UnusedSetRule;
2011-01-30 14:34:42 +00:00
}
inline
2011-01-30 14:34:42 +00:00
bool Rules::checkForceStop(ForceRule rule)
{
return rule != UnusedForceRule;
2011-01-30 14:34:42 +00:00
}
inline
2011-01-30 14:34:42 +00:00
WindowRules::WindowRules(const QVector< Rules* >& r)
: rules(r)
{
}
inline
WindowRules::WindowRules()
2011-01-30 14:34:42 +00:00
{
}
inline
2011-01-30 14:34:42 +00:00
bool WindowRules::contains(const Rules* rule) const
{
return qFind(rules.begin(), rules.end(), rule) != rules.end();
}
inline
2011-01-30 14:34:42 +00:00
void WindowRules::remove(Rules* rule)
{
QVector< Rules* >::Iterator pos = qFind(rules.begin(), rules.end(), rule);
if (pos != rules.end())
rules.erase(pos);
}
#endif
2011-01-30 14:34:42 +00:00
QDebug& operator<<(QDebug& stream, const Rules*);
} // namespace
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::Rules::Types)
#endif