Toplevel::windowType becomes a pure virtual function
The method windowType needs actually two implementations: * one for Clients * one for Unmanaged as for Clients also the window rules are checked and hacks are applied which is both not needed for Unmanaged windows. To have the Client specific behavior in windowType the function used to perform two dynamic_casts which made this method one of the most expensive during compositing, e.g. for ~1000 frames * called ~43000 times * ~85000 dynamic casts * incl. cost of method: 0.24 * self cost of method: 0.05 * incl. cost of the casts: 0.12 After the change to remove the dynamic casts we have for ~1500 frames in Client::windowType: * called ~31000 times * incl. cost of 0.06 * self cost of 0.02 Calls on Unmanaged and Deleted are so low that we do not need to consider them. BUG: 306384 FIXED-IN: 4.10 REVIEW: 106349icc-effect-5.14.5
parent
3aee94d798
commit
62d5e8124c
21
client.cpp
21
client.cpp
|
@ -2523,6 +2523,27 @@ bool Client::isClient() const
|
|||
return true;
|
||||
}
|
||||
|
||||
NET::WindowType Client::windowType(bool direct, int supportedTypes) const
|
||||
{
|
||||
// TODO: does it make sense to cache the returned window type for SUPPORTED_MANAGED_WINDOW_TYPES_MASK?
|
||||
if (supportedTypes == 0) {
|
||||
supportedTypes = SUPPORTED_MANAGED_WINDOW_TYPES_MASK;
|
||||
}
|
||||
NET::WindowType wt = info->windowType(supportedTypes);
|
||||
if (direct) {
|
||||
return wt;
|
||||
}
|
||||
NET::WindowType wt2 = client_rules.checkType(wt);
|
||||
if (wt != wt2) {
|
||||
wt = wt2;
|
||||
info->setWindowType(wt); // force hint change
|
||||
}
|
||||
// hacks here
|
||||
if (wt == NET::Unknown) // this is more or less suggested in NETWM spec
|
||||
wt = isTransient() ? NET::Dialog : NET::Normal;
|
||||
return wt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "client.moc"
|
||||
|
|
1
client.h
1
client.h
|
@ -324,6 +324,7 @@ public:
|
|||
#ifdef HAVE_XSYNC
|
||||
void syncEvent(XSyncAlarmNotifyEvent* e);
|
||||
#endif
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
|
||||
|
||||
bool manage(Window w, bool isMapped);
|
||||
void releaseWindow(bool on_shutdown = false);
|
||||
|
|
10
deleted.cpp
10
deleted.cpp
|
@ -157,6 +157,16 @@ bool Deleted::isDeleted() const
|
|||
return true;
|
||||
}
|
||||
|
||||
NET::WindowType Deleted::windowType(bool direct, int supportedTypes) const
|
||||
{
|
||||
Q_UNUSED(direct)
|
||||
// TODO: maybe retrieve the actual window type when copying to deleted?
|
||||
if (supportedTypes == 0) {
|
||||
supportedTypes = SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK;
|
||||
}
|
||||
return info->windowType(supportedTypes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "deleted.moc"
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
bool isMinimized() const {
|
||||
return m_minimized;
|
||||
}
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
|
||||
protected:
|
||||
virtual void debug(QDebug& stream) const;
|
||||
virtual bool shouldUnredirect() const;
|
||||
|
|
20
toplevel.cpp
20
toplevel.cpp
|
@ -159,26 +159,6 @@ QRect Toplevel::visibleRect() const
|
|||
return r.translated(geometry().topLeft());
|
||||
}
|
||||
|
||||
NET::WindowType Toplevel::windowType(bool direct, int supported_types) const
|
||||
{
|
||||
if (supported_types == 0)
|
||||
supported_types = dynamic_cast< const Client* >(this) != NULL
|
||||
? SUPPORTED_MANAGED_WINDOW_TYPES_MASK : SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK;
|
||||
NET::WindowType wt = info->windowType(supported_types);
|
||||
if (direct)
|
||||
return wt;
|
||||
const Client* cl = dynamic_cast< const Client* >(this);
|
||||
NET::WindowType wt2 = cl ? cl->rules()->checkType(wt) : wt;
|
||||
if (wt != wt2) {
|
||||
wt = wt2;
|
||||
info->setWindowType(wt); // force hint change
|
||||
}
|
||||
// hacks here
|
||||
if (wt == NET::Unknown && cl != NULL) // this is more or less suggested in NETWM spec
|
||||
wt = cl->isTransient() ? NET::Dialog : NET::Normal;
|
||||
return wt;
|
||||
}
|
||||
|
||||
void Toplevel::getWindowRole()
|
||||
{
|
||||
window_role = getStringProperty(window(), atoms->wm_window_role).toLower();
|
||||
|
|
|
@ -188,7 +188,7 @@ public:
|
|||
|
||||
// prefer isXXX() instead
|
||||
// 0 for supported types means default for managed/unmanaged types
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
|
||||
virtual NET::WindowType windowType(bool direct = false, int supported_types = 0) const = 0;
|
||||
bool hasNETSupport() const;
|
||||
bool isDesktop() const;
|
||||
bool isDock() const;
|
||||
|
|
|
@ -137,6 +137,17 @@ void Unmanaged::debug(QDebug& stream) const
|
|||
stream << "\'ID:" << window() << "\'";
|
||||
}
|
||||
|
||||
NET::WindowType Unmanaged::windowType(bool direct, int supportedTypes) const
|
||||
{
|
||||
// for unmanaged windows the direct does not make any difference
|
||||
// as there are no rules to check and no hacks to apply
|
||||
Q_UNUSED(direct)
|
||||
if (supportedTypes == 0) {
|
||||
supportedTypes = SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK;
|
||||
}
|
||||
return info->windowType(supportedTypes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "unmanaged.moc"
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
virtual Layer layer() const {
|
||||
return UnmanagedLayer;
|
||||
}
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
|
||||
protected:
|
||||
virtual void damageNotifyEvent(XDamageNotifyEvent* e);
|
||||
virtual void debug(QDebug& stream) const;
|
||||
|
|
Loading…
Reference in New Issue