Commit 7d51838e authored by Martin Flöser's avatar Martin Flöser

Implement AbstractClient::isActive and ::setActive

Moves the implmentation to AbstractClient. Methods are no longer virtual,
setActive calls a virtual protected method which is implemented in Client
for Client specific activation code.
parent 3527f1d4
......@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
#include "workspace.h"
namespace KWin
{
......@@ -109,4 +110,31 @@ void AbstractClient::setIcon(const QIcon &icon)
emit iconChanged();
}
void AbstractClient::setActive(bool act)
{
if (m_active == act) {
return;
}
m_active = act;
const int ruledOpacity = m_active
? rules()->checkOpacityActive(qRound(opacity() * 100.0))
: rules()->checkOpacityInactive(qRound(opacity() * 100.0));
setOpacity(ruledOpacity / 100.0);
workspace()->setActiveClient(act ? this : NULL);
if (!m_active)
cancelAutoRaise();
if (!m_active && shadeMode() == ShadeActivated)
setShade(ShadeNormal);
doSetActive();
emit activeChanged();
updateMouseGrab();
}
void AbstractClient::doSetActive()
{
}
}
......@@ -42,6 +42,11 @@ class AbstractClient : public Toplevel
* For change connect to the visibleChanged signal on the Client's Group.
**/
Q_PROPERTY(bool isCurrentTab READ isCurrentTab)
/**
* 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)
/**
* Whether the Client should be excluded from window switching effects.
**/
......@@ -70,6 +75,21 @@ public:
return m_icon;
}
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);
virtual void updateMouseGrab();
virtual QString caption(bool full = true, bool stripped = false) const = 0;
virtual bool isMinimized() const = 0;
......@@ -89,8 +109,6 @@ public:
* false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
*/
virtual bool isSpecialWindow() const = 0;
virtual bool isActive() const = 0;
virtual void setActive(bool) =0;
virtual void sendToScreen(int screen) = 0;
virtual const QKeySequence &shortcut() const = 0;
virtual void setShortcut(const QString &cut) = 0;
......@@ -185,6 +203,7 @@ public Q_SLOTS:
Q_SIGNALS:
void skipSwitcherChanged();
void iconChanged();
void activeChanged();
protected:
AbstractClient();
......@@ -192,6 +211,13 @@ protected:
m_firstInTabBox = enable;
}
void setIcon(const QIcon &icon);
/**
* Called from ::setActive once the active value got updated, but before the changed signal
* is emitted.
*
* Default implementation does nothing.
**/
virtual void doSetActive();
// TODO: remove boolean trap
virtual bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const = 0;
......@@ -200,6 +226,7 @@ private:
bool m_firstInTabBox = false;
bool m_skipSwitcher = false;
QIcon m_icon;
bool m_active = false;
};
}
......
......@@ -778,34 +778,8 @@ xcb_timestamp_t Client::userTime() const
return time;
}
/*!
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 Client::setActive(bool act)
void Client::doSetActive()
{
if (active == act)
return;
active = act;
const int ruledOpacity = active
? rules()->checkOpacityActive(qRound(opacity() * 100.0))
: rules()->checkOpacityInactive(qRound(opacity() * 100.0));
setOpacity(ruledOpacity / 100.0);
workspace()->setActiveClient(act ? this : NULL);
if (!active)
cancelAutoRaise();
if (!active && shade_mode == ShadeActivated)
setShade(ShadeNormal);
StackingUpdatesBlocker blocker(workspace());
workspace()->updateClientLayer(this); // active windows may get different layer
ClientList mainclients = mainClients();
......@@ -814,8 +788,7 @@ void Client::setActive(bool act)
++it)
if ((*it)->isFullScreen()) // fullscreens go high even if their transient is active
workspace()->updateClientLayer(*it);
emit activeChanged();
updateMouseGrab();
updateUrgency(); // demand attention again if it's still urgent
}
......
......@@ -157,7 +157,6 @@ Client::Client()
info = NULL;
shade_mode = ShadeNone;
active = false;
deleting = false;
keep_above = false;
keep_below = false;
......
......@@ -76,11 +76,6 @@ class Client
: public AbstractClient
{
Q_OBJECT
/**
* 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 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.
......@@ -334,9 +329,6 @@ public:
QSize adjustedSize(const QSize&, Sizemode mode = SizemodeAny) const;
QSize adjustedSize() const;
bool isActive() const override;
void setActive(bool) override;
virtual int desktop() const;
void setDesktop(int) override;
void setOnAllDesktops(bool set) override;
......@@ -663,6 +655,7 @@ protected:
virtual bool shouldUnredirect() const;
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;
void doSetActive() override;
private Q_SLOTS:
void delayedSetShortcut();
......@@ -682,7 +675,6 @@ Q_SIGNALS:
void clientStartUserMovedResized(KWin::Client*);
void clientStepUserMovedResized(KWin::Client *, const QRect&);
void clientFinishUserMovedResized(KWin::Client*);
void activeChanged();
void captionChanged();
void desktopChanged();
void desktopPresenceChanged(KWin::Client*, int); // to be forwarded by Workspace
......@@ -879,7 +871,6 @@ private:
ClientList transients_list; // SELI TODO: Make this ordered in stacking order?
ShadeMode shade_mode;
Client *shade_below;
uint active : 1;
uint deleting : 1; ///< True when doing cleanup and destroying the client
uint keep_above : 1; ///< NET::KeepAbove (was stays_on_top)
uint skip_taskbar : 1;
......@@ -1052,11 +1043,6 @@ inline bool Client::isMinimized() const
return minimized;
}
inline bool Client::isActive() const
{
return active;
}
inline bool Client::isShown(bool shaded_is_shown) const
{
return !isMinimized() && (!isShade() || shaded_is_shown) && !hidden &&
......
......@@ -458,7 +458,7 @@ Client* Workspace::createClient(xcb_window_t w, bool is_mapped)
StackingUpdatesBlocker blocker(this);
Client* c = new Client();
connect(c, SIGNAL(needsRepaint()), m_compositor, SLOT(scheduleRepaint()));
connect(c, SIGNAL(activeChanged()), m_compositor, SLOT(checkUnredirect()));
connect(c, &Client::activeChanged, m_compositor, static_cast<void (Compositor::*)()>(&Compositor::checkUnredirect));
connect(c, SIGNAL(fullScreenChanged()), m_compositor, SLOT(checkUnredirect()));
connect(c, SIGNAL(geometryChanged()), m_compositor, SLOT(checkUnredirect()));
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), m_compositor, SLOT(checkUnredirect()));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment