Move core shade code to AbstractClient
Summary: In order to allow shading wayland clients, this change moves core shade code from X11Client to AbstractClient. Test Plan: Shading still works on X11. Reviewers: #kwin, cblack Reviewed By: cblack Subscribers: cblack, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D29512
This commit is contained in:
parent
f29ca8a293
commit
44143ef7ae
7 changed files with 132 additions and 145 deletions
|
@ -545,6 +545,11 @@ QVector<uint> AbstractClient::x11DesktopIds() const
|
|||
return x11Ids;
|
||||
}
|
||||
|
||||
ShadeMode AbstractClient::shadeMode() const
|
||||
{
|
||||
return m_shadeMode;
|
||||
}
|
||||
|
||||
bool AbstractClient::isShadeable() const
|
||||
{
|
||||
return false;
|
||||
|
@ -557,12 +562,85 @@ void AbstractClient::setShade(bool set)
|
|||
|
||||
void AbstractClient::setShade(ShadeMode mode)
|
||||
{
|
||||
Q_UNUSED(mode)
|
||||
if (!isShadeable())
|
||||
return;
|
||||
if (mode == ShadeHover && isMove())
|
||||
return; // causes geometry breaks and is probably nasty
|
||||
if (isSpecialWindow() || noBorder())
|
||||
mode = ShadeNone;
|
||||
|
||||
mode = rules()->checkShade(mode);
|
||||
if (m_shadeMode == mode)
|
||||
return;
|
||||
|
||||
const bool wasShade = isShade();
|
||||
const ShadeMode previousShadeMode = shadeMode();
|
||||
m_shadeMode = mode;
|
||||
|
||||
if (wasShade == isShade()) {
|
||||
// Decoration may want to update after e.g. hover-shade changes
|
||||
emit shadeChanged();
|
||||
return; // No real change in shaded state
|
||||
}
|
||||
|
||||
Q_ASSERT(isDecorated());
|
||||
GeometryUpdatesBlocker blocker(this);
|
||||
|
||||
doSetShade(previousShadeMode);
|
||||
|
||||
discardWindowPixmap();
|
||||
updateWindowRules(Rules::Shade);
|
||||
|
||||
emit shadeChanged();
|
||||
}
|
||||
|
||||
ShadeMode AbstractClient::shadeMode() const
|
||||
void AbstractClient::doSetShade(ShadeMode previousShadeMode)
|
||||
{
|
||||
return ShadeNone;
|
||||
Q_UNUSED(previousShadeMode)
|
||||
}
|
||||
|
||||
void AbstractClient::shadeHover()
|
||||
{
|
||||
setShade(ShadeHover);
|
||||
cancelShadeHoverTimer();
|
||||
}
|
||||
|
||||
void AbstractClient::shadeUnhover()
|
||||
{
|
||||
setShade(ShadeNormal);
|
||||
cancelShadeHoverTimer();
|
||||
}
|
||||
|
||||
void AbstractClient::startShadeHoverTimer()
|
||||
{
|
||||
if (!isShade())
|
||||
return;
|
||||
m_shadeHoverTimer = new QTimer(this);
|
||||
connect(m_shadeHoverTimer, &QTimer::timeout, this, &AbstractClient::shadeHover);
|
||||
m_shadeHoverTimer->setSingleShot(true);
|
||||
m_shadeHoverTimer->start(options->shadeHoverInterval());
|
||||
}
|
||||
|
||||
void AbstractClient::startShadeUnhoverTimer()
|
||||
{
|
||||
if (m_shadeMode == ShadeHover && !isMoveResize() && !isMoveResizePointerButtonDown()) {
|
||||
m_shadeHoverTimer = new QTimer(this);
|
||||
connect(m_shadeHoverTimer, &QTimer::timeout, this, &AbstractClient::shadeUnhover);
|
||||
m_shadeHoverTimer->setSingleShot(true);
|
||||
m_shadeHoverTimer->start(options->shadeHoverInterval());
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractClient::cancelShadeHoverTimer()
|
||||
{
|
||||
delete m_shadeHoverTimer;
|
||||
m_shadeHoverTimer = nullptr;
|
||||
}
|
||||
|
||||
void AbstractClient::toggleShade()
|
||||
{
|
||||
// If the mode is ShadeHover or ShadeActive, cancel shade too.
|
||||
setShade(shadeMode() == ShadeNone ? ShadeNormal : ShadeNone);
|
||||
}
|
||||
|
||||
AbstractClient::Position AbstractClient::titlebarPosition() const
|
||||
|
@ -1745,6 +1823,18 @@ bool AbstractClient::performMouseCommand(Options::MouseCommand cmd, const QPoint
|
|||
updateCursor();
|
||||
break;
|
||||
}
|
||||
case Options::MouseShade:
|
||||
toggleShade();
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
case Options::MouseSetShade:
|
||||
setShade(ShadeNormal);
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
case Options::MouseUnsetShade:
|
||||
setShade(ShadeNone);
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
case Options::MouseNothing:
|
||||
default:
|
||||
replay = true;
|
||||
|
@ -2324,7 +2414,11 @@ void AbstractClient::setDecoratedClient(QPointer< Decoration::DecoratedClientImp
|
|||
|
||||
void AbstractClient::enterEvent(const QPoint &globalPos)
|
||||
{
|
||||
// TODO: shade hover
|
||||
if (options->isShadeHover()) {
|
||||
cancelShadeHoverTimer();
|
||||
startShadeHoverTimer();
|
||||
}
|
||||
|
||||
if (options->focusPolicy() == Options::ClickToFocus || workspace()->userActionsMenu()->isShown())
|
||||
return;
|
||||
|
||||
|
@ -2350,7 +2444,8 @@ void AbstractClient::leaveEvent()
|
|||
{
|
||||
cancelAutoRaise();
|
||||
workspace()->cancelDelayFocus();
|
||||
// TODO: shade hover
|
||||
cancelShadeHoverTimer();
|
||||
startShadeUnhoverTimer();
|
||||
// TODO: send hover leave to deco
|
||||
// TODO: handle Options::FocusStrictlyUnderMouse
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ public:
|
|||
return _shortcut;
|
||||
}
|
||||
void setShortcut(const QString &cut);
|
||||
virtual bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos);
|
||||
bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos);
|
||||
void setOnAllDesktops(bool set);
|
||||
void setDesktop(int);
|
||||
void enterDesktop(VirtualDesktop *desktop);
|
||||
|
@ -517,15 +517,11 @@ public:
|
|||
bool isShade() const {
|
||||
return shadeMode() == ShadeNormal;
|
||||
}
|
||||
/**
|
||||
* Default implementation returns @c ShadeNone
|
||||
*/
|
||||
virtual ShadeMode shadeMode() const; // Prefer isShade()
|
||||
ShadeMode shadeMode() const; // Prefer isShade()
|
||||
void setShade(bool set);
|
||||
/**
|
||||
* Default implementation does nothing
|
||||
*/
|
||||
virtual void setShade(ShadeMode mode);
|
||||
void setShade(ShadeMode mode);
|
||||
void toggleShade();
|
||||
void cancelShadeHoverTimer();
|
||||
/**
|
||||
* Whether the Client can be shaded. Default implementation returns @c false.
|
||||
*/
|
||||
|
@ -949,6 +945,13 @@ protected:
|
|||
* 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.
|
||||
|
@ -1203,6 +1206,13 @@ protected:
|
|||
|
||||
bool tabTo(AbstractClient *other, bool behind, bool activate);
|
||||
|
||||
void startShadeHoverTimer();
|
||||
void startShadeUnhoverTimer();
|
||||
|
||||
private Q_SLOTS:
|
||||
void shadeHover();
|
||||
void shadeUnhover();
|
||||
|
||||
private:
|
||||
void handlePaletteChange();
|
||||
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
|
||||
|
@ -1221,6 +1231,8 @@ private:
|
|||
bool m_demandsAttention = false;
|
||||
bool m_minimized = false;
|
||||
QTimer *m_autoRaiseTimer = nullptr;
|
||||
QTimer *m_shadeHoverTimer = nullptr;
|
||||
ShadeMode m_shadeMode = ShadeNone;
|
||||
QVector <VirtualDesktop *> m_desktops;
|
||||
|
||||
QString m_colorScheme;
|
||||
|
|
17
events.cpp
17
events.cpp
|
@ -774,16 +774,6 @@ void X11Client::enterNotifyEvent(xcb_enter_notify_event_t *e)
|
|||
#define MOUSE_DRIVEN_FOCUS (!options->focusPolicyIsReasonable() || \
|
||||
(options->focusPolicy() == Options::FocusFollowsMouse && options->isNextFocusPrefersMouse()))
|
||||
if (e->mode == XCB_NOTIFY_MODE_NORMAL || (e->mode == XCB_NOTIFY_MODE_UNGRAB && MOUSE_DRIVEN_FOCUS)) {
|
||||
|
||||
if (options->isShadeHover()) {
|
||||
cancelShadeHoverTimer();
|
||||
if (isShade()) {
|
||||
shadeHoverTimer = new QTimer(this);
|
||||
connect(shadeHoverTimer, SIGNAL(timeout()), this, SLOT(shadeHover()));
|
||||
shadeHoverTimer->setSingleShot(true);
|
||||
shadeHoverTimer->start(options->shadeHoverInterval());
|
||||
}
|
||||
}
|
||||
#undef MOUSE_DRIVEN_FOCUS
|
||||
|
||||
enterEvent(QPoint(e->root_x, e->root_y));
|
||||
|
@ -817,13 +807,6 @@ void X11Client::leaveNotifyEvent(xcb_leave_notify_event_t *e)
|
|||
}
|
||||
if (lostMouse) {
|
||||
leaveEvent();
|
||||
cancelShadeHoverTimer();
|
||||
if (shade_mode == ShadeHover && !isMoveResize() && !isMoveResizePointerButtonDown()) {
|
||||
shadeHoverTimer = new QTimer(this);
|
||||
connect(shadeHoverTimer, SIGNAL(timeout()), this, SLOT(shadeUnhover()));
|
||||
shadeHoverTimer->setSingleShot(true);
|
||||
shadeHoverTimer->start(options->shadeHoverInterval());
|
||||
}
|
||||
if (isDecorated()) {
|
||||
// sending a move instead of a leave. With leave we need to send proper coords, with move it's handled internally
|
||||
QHoverEvent leaveEvent(QEvent::HoverMove, QPointF(-1, -1), QPointF(-1, -1), Qt::NoModifier);
|
||||
|
|
|
@ -318,16 +318,12 @@ void TabBoxHandlerImpl::elevateClient(TabBoxClient *c, QWindow *tabbox, bool b)
|
|||
|
||||
void TabBoxHandlerImpl::shadeClient(TabBoxClient *c, bool b) const
|
||||
{
|
||||
X11Client *cl = dynamic_cast<X11Client *>(static_cast<TabBoxClientImpl*>(c)->client());
|
||||
if (!cl) {
|
||||
// shading is X11 specific
|
||||
return;
|
||||
}
|
||||
cl->cancelShadeHoverTimer(); // stop core shading action
|
||||
if (!b && cl->shadeMode() == ShadeNormal)
|
||||
cl->setShade(ShadeHover);
|
||||
else if (b && cl->shadeMode() == ShadeHover)
|
||||
cl->setShade(ShadeNormal);
|
||||
AbstractClient *client = static_cast<TabBoxClientImpl *>(c)->client();
|
||||
client->cancelShadeHoverTimer(); // stop core shading action
|
||||
if (!b && client->shadeMode() == ShadeNormal)
|
||||
client->setShade(ShadeHover);
|
||||
else if (b && client->shadeMode() == ShadeHover)
|
||||
client->setShade(ShadeNormal);
|
||||
}
|
||||
|
||||
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::desktopClient() const
|
||||
|
|
|
@ -1132,31 +1132,6 @@ void Workspace::performWindowOperation(AbstractClient* c, Options::WindowOperati
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a mouse command on this client (see options.h)
|
||||
*/
|
||||
bool X11Client::performMouseCommand(Options::MouseCommand command, const QPoint &globalPos)
|
||||
{
|
||||
bool replay = false;
|
||||
switch(command) {
|
||||
case Options::MouseShade :
|
||||
toggleShade();
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
case Options::MouseSetShade:
|
||||
setShade(ShadeNormal);
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
case Options::MouseUnsetShade:
|
||||
setShade(ShadeNone);
|
||||
cancelShadeHoverTimer();
|
||||
break;
|
||||
default:
|
||||
return AbstractClient::performMouseCommand(command, globalPos);
|
||||
}
|
||||
return replay;
|
||||
}
|
||||
|
||||
void Workspace::slotActivateAttentionWindow()
|
||||
{
|
||||
if (attention_chain.count() > 0)
|
||||
|
|
|
@ -120,7 +120,6 @@ X11Client::X11Client()
|
|||
, shade_below(nullptr)
|
||||
, m_motif(atoms->motif_wm_hints)
|
||||
, blocks_compositing(false)
|
||||
, shadeHoverTimer(nullptr)
|
||||
, m_colormap(XCB_COLORMAP_NONE)
|
||||
, in_group(nullptr)
|
||||
, ping_timer(nullptr)
|
||||
|
@ -147,7 +146,6 @@ X11Client::X11Client()
|
|||
|
||||
info = nullptr;
|
||||
|
||||
shade_mode = ShadeNone;
|
||||
deleting = false;
|
||||
m_fullscreenMode = FullScreenNone;
|
||||
hidden = false;
|
||||
|
@ -1468,35 +1466,8 @@ bool X11Client::isShadeable() const
|
|||
return !isSpecialWindow() && !noBorder() && (rules()->checkShade(ShadeNormal) != rules()->checkShade(ShadeNone));
|
||||
}
|
||||
|
||||
void X11Client::setShade(ShadeMode mode)
|
||||
void X11Client::doSetShade(ShadeMode previousShadeMode)
|
||||
{
|
||||
if (mode == ShadeHover && isMove())
|
||||
return; // causes geometry breaks and is probably nasty
|
||||
if (isSpecialWindow() || noBorder())
|
||||
mode = ShadeNone;
|
||||
mode = rules()->checkShade(mode);
|
||||
if (shade_mode == mode)
|
||||
return;
|
||||
bool was_shade = isShade();
|
||||
ShadeMode was_shade_mode = shade_mode;
|
||||
shade_mode = mode;
|
||||
|
||||
// Decorations may turn off some borders when shaded
|
||||
// this has to happen _before_ the tab alignment since it will restrict the minimum geometry
|
||||
#if 0
|
||||
if (decoration)
|
||||
decoration->borders(border_left, border_right, border_top, border_bottom);
|
||||
#endif
|
||||
|
||||
if (was_shade == isShade()) {
|
||||
// Decoration may want to update after e.g. hover-shade changes
|
||||
emit shadeChanged();
|
||||
return; // No real change in shaded state
|
||||
}
|
||||
|
||||
Q_ASSERT(isDecorated()); // noborder windows can't be shaded
|
||||
GeometryUpdatesBlocker blocker(this);
|
||||
|
||||
// TODO: All this unmapping, resizing etc. feels too much duplicated from elsewhere
|
||||
if (isShade()) {
|
||||
// shade_mode == ShadeNormal
|
||||
|
@ -1512,7 +1483,7 @@ void X11Client::setShade(ShadeMode mode)
|
|||
exportMappingState(XCB_ICCCM_WM_STATE_ICONIC);
|
||||
plainResize(s);
|
||||
shade_geometry_change = false;
|
||||
if (was_shade_mode == ShadeHover) {
|
||||
if (previousShadeMode == ShadeHover) {
|
||||
if (shade_below && workspace()->stackingOrder().indexOf(shade_below) > -1)
|
||||
workspace()->restack(this, shade_below, true);
|
||||
if (isActive())
|
||||
|
@ -1528,9 +1499,9 @@ void X11Client::setShade(ShadeMode mode)
|
|||
shade_geometry_change = false;
|
||||
plainResize(s);
|
||||
setGeometryRestore(frameGeometry());
|
||||
if ((shade_mode == ShadeHover || shade_mode == ShadeActivated) && rules()->checkAcceptFocus(info->input()))
|
||||
if ((shadeMode() == ShadeHover || shadeMode() == ShadeActivated) && rules()->checkAcceptFocus(info->input()))
|
||||
setActive(true);
|
||||
if (shade_mode == ShadeHover) {
|
||||
if (shadeMode() == ShadeHover) {
|
||||
QList<Toplevel *> order = workspace()->stackingOrder();
|
||||
// invalidate, since "this" could be the topmost toplevel and shade_below dangeling
|
||||
shade_below = nullptr;
|
||||
|
@ -1554,36 +1525,8 @@ void X11Client::setShade(ShadeMode mode)
|
|||
}
|
||||
info->setState(isShade() ? NET::Shaded : NET::States(), NET::Shaded);
|
||||
info->setState(isShown(false) ? NET::States() : NET::Hidden, NET::Hidden);
|
||||
discardWindowPixmap();
|
||||
updateVisibility();
|
||||
updateAllowedActions();
|
||||
updateWindowRules(Rules::Shade);
|
||||
|
||||
emit shadeChanged();
|
||||
}
|
||||
|
||||
void X11Client::shadeHover()
|
||||
{
|
||||
setShade(ShadeHover);
|
||||
cancelShadeHoverTimer();
|
||||
}
|
||||
|
||||
void X11Client::shadeUnhover()
|
||||
{
|
||||
setShade(ShadeNormal);
|
||||
cancelShadeHoverTimer();
|
||||
}
|
||||
|
||||
void X11Client::cancelShadeHoverTimer()
|
||||
{
|
||||
delete shadeHoverTimer;
|
||||
shadeHoverTimer = nullptr;
|
||||
}
|
||||
|
||||
void X11Client::toggleShade()
|
||||
{
|
||||
// If the mode is ShadeHover or ShadeActive, cancel shade too
|
||||
setShade(shade_mode == ShadeNone ? ShadeNormal : ShadeNone);
|
||||
}
|
||||
|
||||
void X11Client::updateVisibility()
|
||||
|
|
19
x11client.h
19
x11client.h
|
@ -144,10 +144,7 @@ public:
|
|||
bool isShown(bool shaded_is_shown) const override;
|
||||
bool isHiddenInternal() const override; // For compositing
|
||||
|
||||
ShadeMode shadeMode() const override; // Prefer isShade()
|
||||
void setShade(ShadeMode mode) override;
|
||||
bool isShadeable() const override;
|
||||
|
||||
bool isMaximizable() const override;
|
||||
MaximizeMode maximizeMode() const override;
|
||||
|
||||
|
@ -201,8 +198,6 @@ public:
|
|||
|
||||
bool providesContextHelp() const override;
|
||||
|
||||
bool performMouseCommand(Options::MouseCommand, const QPoint& globalPos) override;
|
||||
|
||||
QRect adjustedClientArea(const QRect& desktop, const QRect& area) const;
|
||||
|
||||
xcb_colormap_t colormap() const;
|
||||
|
@ -251,9 +246,7 @@ public:
|
|||
static bool sameAppWindowRoleMatch(const X11Client *c1, const X11Client *c2, bool active_hack);
|
||||
|
||||
void killWindow() override;
|
||||
void toggleShade();
|
||||
void showContextHelp() override;
|
||||
void cancelShadeHoverTimer();
|
||||
void checkActiveModal();
|
||||
StrutRect strutRect(StrutArea area) const;
|
||||
StrutRects strutRects() const;
|
||||
|
@ -330,10 +323,6 @@ public Q_SLOTS:
|
|||
void closeWindow() override;
|
||||
void updateCaption() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void shadeHover();
|
||||
void shadeUnhover();
|
||||
|
||||
private:
|
||||
// Handlers for X11 events
|
||||
bool mapRequestEvent(xcb_map_request_event_t *e);
|
||||
|
@ -359,6 +348,7 @@ protected:
|
|||
void doSetActive() override;
|
||||
void doSetKeepAbove() override;
|
||||
void doSetKeepBelow() override;
|
||||
void doSetShade(ShadeMode previousShadeMode) override;
|
||||
void doSetDesktop() override;
|
||||
void doMinimize() override;
|
||||
void doSetSkipPager() override;
|
||||
|
@ -503,7 +493,6 @@ private:
|
|||
void setTransient(xcb_window_t new_transient_for_id);
|
||||
xcb_window_t m_transientForId;
|
||||
xcb_window_t m_originalTransientForId;
|
||||
ShadeMode shade_mode;
|
||||
X11Client *shade_below;
|
||||
uint deleting : 1; ///< True when doing cleanup and destroying the client
|
||||
Xcb::MotifHints m_motif;
|
||||
|
@ -522,7 +511,6 @@ private:
|
|||
QRect m_bufferGeometry = QRect(0, 0, 100, 100);
|
||||
QRect m_clientGeometry = QRect(0, 0, 100, 100);
|
||||
QRect geom_fs_restore;
|
||||
QTimer* shadeHoverTimer;
|
||||
xcb_colormap_t m_colormap;
|
||||
QString cap_normal, cap_iconic, cap_suffix;
|
||||
Group* in_group;
|
||||
|
@ -607,11 +595,6 @@ inline bool X11Client::isHiddenInternal() const
|
|||
return hidden;
|
||||
}
|
||||
|
||||
inline ShadeMode X11Client::shadeMode() const
|
||||
{
|
||||
return shade_mode;
|
||||
}
|
||||
|
||||
inline MaximizeMode X11Client::maximizeMode() const
|
||||
{
|
||||
return max_mode;
|
||||
|
|
Loading…
Reference in a new issue