slidingpopups: Support animating show/hide of input method panel
This adds support for animating showing/hiding of the input method panel to the sliding popup effect, if the input panel is of type "Toplevel". This is mainly intended to animate showing the virtual keyboard and has been primarily tested with Maliit. It replaces the client-side animation that Maliit would do, instead doing the animation on the KWin side which provides a significantly smoother experience.
This commit is contained in:
parent
13f28d7d6d
commit
844c451156
7 changed files with 71 additions and 0 deletions
|
@ -43,6 +43,9 @@
|
||||||
#include "kwinglutils.h"
|
#include "kwinglutils.h"
|
||||||
#include "kwinoffscreenquickview.h"
|
#include "kwinoffscreenquickview.h"
|
||||||
|
|
||||||
|
#include "inputmethod.h"
|
||||||
|
#include "inputpanelv1client.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
@ -266,6 +269,8 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
|
||||||
slotOutputEnabled(output);
|
slotOutputEnabled(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(InputMethod::self(), &InputMethod::panelChanged, this, &EffectsHandlerImpl::inputPanelChanged);
|
||||||
|
|
||||||
reconfigure();
|
reconfigure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1807,6 +1812,24 @@ qreal EffectsHandlerImpl::renderTargetScale() const
|
||||||
return m_scene->renderTargetScale();
|
return m_scene->renderTargetScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KWin::EffectWindow *EffectsHandlerImpl::inputPanel() const
|
||||||
|
{
|
||||||
|
auto panel = InputMethod::self()->panel();
|
||||||
|
if (panel) {
|
||||||
|
return panel->effectWindow();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EffectsHandlerImpl::isInputPanelOverlay() const
|
||||||
|
{
|
||||||
|
auto panel = InputMethod::self()->panel();
|
||||||
|
if (panel) {
|
||||||
|
return panel->mode() == InputPanelV1Client::Overlay;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// EffectScreenImpl
|
// EffectScreenImpl
|
||||||
//****************************************
|
//****************************************
|
||||||
|
|
|
@ -277,6 +277,9 @@ public:
|
||||||
QRect renderTargetRect() const override;
|
QRect renderTargetRect() const override;
|
||||||
qreal renderTargetScale() const override;
|
qreal renderTargetScale() const override;
|
||||||
|
|
||||||
|
KWin::EffectWindow *inputPanel() const override;
|
||||||
|
bool isInputPanelOverlay() const override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
|
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
|
||||||
void slotTabAdded(EffectWindow* from, EffectWindow* to);
|
void slotTabAdded(EffectWindow* from, EffectWindow* to);
|
||||||
|
|
|
@ -67,6 +67,7 @@ SlidingPopupsEffect::SlidingPopupsEffect()
|
||||||
this, &SlidingPopupsEffect::stopAnimations);
|
this, &SlidingPopupsEffect::stopAnimations);
|
||||||
connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
|
connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
|
||||||
this, &SlidingPopupsEffect::stopAnimations);
|
this, &SlidingPopupsEffect::stopAnimations);
|
||||||
|
connect(effects, &EffectsHandler::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged);
|
||||||
|
|
||||||
reconfigure(ReconfigureAll);
|
reconfigure(ReconfigureAll);
|
||||||
|
|
||||||
|
@ -319,6 +320,13 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom)
|
||||||
setupAnimData(w);
|
setupAnimData(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SlidingPopupsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const QRect &)
|
||||||
|
{
|
||||||
|
if (w == effects->inputPanel()) {
|
||||||
|
setupInputPanelSlide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SlidingPopupsEffect::setupAnimData(EffectWindow *w)
|
void SlidingPopupsEffect::setupAnimData(EffectWindow *w)
|
||||||
{
|
{
|
||||||
const QRect screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
const QRect screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
||||||
|
@ -454,6 +462,26 @@ void SlidingPopupsEffect::setupInternalWindowSlide(EffectWindow *w)
|
||||||
setupAnimData(w);
|
setupAnimData(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SlidingPopupsEffect::setupInputPanelSlide()
|
||||||
|
{
|
||||||
|
auto w = effects->inputPanel();
|
||||||
|
|
||||||
|
if (!w || effects->isInputPanelOverlay()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationData &animData = m_animationsData[w];
|
||||||
|
animData.location = Location::Bottom;
|
||||||
|
animData.offset = 0;
|
||||||
|
animData.slideLength = 0;
|
||||||
|
animData.slideInDuration = m_slideInDuration;
|
||||||
|
animData.slideOutDuration = m_slideOutDuration;
|
||||||
|
|
||||||
|
setupAnimData(w);
|
||||||
|
|
||||||
|
slideIn(w);
|
||||||
|
}
|
||||||
|
|
||||||
bool SlidingPopupsEffect::eventFilter(QObject *watched, QEvent *event)
|
bool SlidingPopupsEffect::eventFilter(QObject *watched, QEvent *event)
|
||||||
{
|
{
|
||||||
auto internal = qobject_cast<QWindow*>(watched);
|
auto internal = qobject_cast<QWindow*>(watched);
|
||||||
|
|
|
@ -51,6 +51,7 @@ private Q_SLOTS:
|
||||||
void slotWindowDeleted(EffectWindow *w);
|
void slotWindowDeleted(EffectWindow *w);
|
||||||
void slotPropertyNotify(EffectWindow *w, long atom);
|
void slotPropertyNotify(EffectWindow *w, long atom);
|
||||||
void slotWaylandSlideOnShowChanged(EffectWindow *w);
|
void slotWaylandSlideOnShowChanged(EffectWindow *w);
|
||||||
|
void slotWindowFrameGeometryChanged(EffectWindow *w, const QRect &);
|
||||||
|
|
||||||
void slideIn(EffectWindow *w);
|
void slideIn(EffectWindow *w);
|
||||||
void slideOut(EffectWindow *w);
|
void slideOut(EffectWindow *w);
|
||||||
|
@ -60,6 +61,7 @@ private:
|
||||||
void setupAnimData(EffectWindow *w);
|
void setupAnimData(EffectWindow *w);
|
||||||
void setupInternalWindowSlide(EffectWindow *w);
|
void setupInternalWindowSlide(EffectWindow *w);
|
||||||
void setupSlideData(EffectWindow *w);
|
void setupSlideData(EffectWindow *w);
|
||||||
|
void setupInputPanelSlide();
|
||||||
|
|
||||||
static KWaylandServer::SlideManagerInterface *s_slideManager;
|
static KWaylandServer::SlideManagerInterface *s_slideManager;
|
||||||
static QTimer *s_slideManagerRemoveTimer;
|
static QTimer *s_slideManagerRemoveTimer;
|
||||||
|
|
|
@ -159,6 +159,11 @@ void InputMethod::setActive(bool active)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputPanelV1Client *InputMethod::panel() const
|
||||||
|
{
|
||||||
|
return m_inputClient;
|
||||||
|
}
|
||||||
|
|
||||||
void InputMethod::setPanel(InputPanelV1Client *client)
|
void InputMethod::setPanel(InputPanelV1Client *client)
|
||||||
{
|
{
|
||||||
Q_ASSERT(client->isInputMethod());
|
Q_ASSERT(client->isInputMethod());
|
||||||
|
@ -182,6 +187,7 @@ void InputMethod::setPanel(InputPanelV1Client *client)
|
||||||
connect(m_inputClient, &AbstractClient::windowClosed, this, &InputMethod::visibleChanged);
|
connect(m_inputClient, &AbstractClient::windowClosed, this, &InputMethod::visibleChanged);
|
||||||
Q_EMIT visibleChanged();
|
Q_EMIT visibleChanged();
|
||||||
updateInputPanelState();
|
updateInputPanelState();
|
||||||
|
Q_EMIT panelChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputMethod::setTrackedClient(AbstractClient* trackedClient)
|
void InputMethod::setTrackedClient(AbstractClient* trackedClient)
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
bool isAvailable() const;
|
bool isAvailable() const;
|
||||||
|
|
||||||
|
InputPanelV1Client *panel() const;
|
||||||
void setPanel(InputPanelV1Client* client);
|
void setPanel(InputPanelV1Client* client);
|
||||||
void setInputMethodCommand(const QString &path);
|
void setInputMethodCommand(const QString &path);
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ public:
|
||||||
void forwardModifiers(ForwardModifiersForce force);
|
void forwardModifiers(ForwardModifiersForce force);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void panelChanged();
|
||||||
void activeChanged(bool active);
|
void activeChanged(bool active);
|
||||||
void enabledChanged(bool enabled);
|
void enabledChanged(bool enabled);
|
||||||
void visibleChanged();
|
void visibleChanged();
|
||||||
|
|
|
@ -871,6 +871,8 @@ class KWINEFFECTS_EXPORT EffectsHandler : public QObject
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
|
Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(KWin::EffectWindow *inputPanel READ inputPanel NOTIFY inputPanelChanged)
|
||||||
|
|
||||||
friend class Effect;
|
friend class Effect;
|
||||||
public:
|
public:
|
||||||
explicit EffectsHandler(CompositingType type);
|
explicit EffectsHandler(CompositingType type);
|
||||||
|
@ -1453,6 +1455,9 @@ public:
|
||||||
*/
|
*/
|
||||||
QRegion mapToRenderTarget(const QRegion ®ion) const;
|
QRegion mapToRenderTarget(const QRegion ®ion) const;
|
||||||
|
|
||||||
|
virtual KWin::EffectWindow *inputPanel() const = 0;
|
||||||
|
virtual bool isInputPanelOverlay() const = 0;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted whenever a new @a screen is added to the system.
|
* This signal is emitted whenever a new @a screen is added to the system.
|
||||||
|
@ -1906,6 +1911,8 @@ Q_SIGNALS:
|
||||||
void startupChanged(const QString &id, const QIcon &icon);
|
void startupChanged(const QString &id, const QIcon &icon);
|
||||||
void startupRemoved(const QString &id);
|
void startupRemoved(const QString &id);
|
||||||
|
|
||||||
|
void inputPanelChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVector< EffectPair > loaded_effects;
|
QVector< EffectPair > loaded_effects;
|
||||||
//QHash< QString, EffectFactory* > effect_factories;
|
//QHash< QString, EffectFactory* > effect_factories;
|
||||||
|
|
Loading…
Reference in a new issue