1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-10 21:18:19 +03:00

improve smoothness of animations during startup

--This new approach paints all docks and panels during
starup offscreen. This way especially under x11 not a lot of
visual glitches are appearing all over the place.
After startup time has ended docks and panels are
moved at their original and valid placement and slide in
animations are triggered.
This commit is contained in:
Michail Vourlakos 2021-12-12 03:13:35 +02:00
parent 6a66dd0000
commit aeb934d0fb
8 changed files with 102 additions and 30 deletions

View File

@ -107,6 +107,7 @@ void Positioner::init()
connect(this, &Positioner::hidingForRelocationStarted, this, &Positioner::updateInRelocationAnimation); connect(this, &Positioner::hidingForRelocationStarted, this, &Positioner::updateInRelocationAnimation);
connect(this, &Positioner::showingAfterRelocationFinished, this, &Positioner::updateInRelocationAnimation); connect(this, &Positioner::showingAfterRelocationFinished, this, &Positioner::updateInRelocationAnimation);
connect(this, &Positioner::showingAfterRelocationFinished, this, &Positioner::syncLatteViews); connect(this, &Positioner::showingAfterRelocationFinished, this, &Positioner::syncLatteViews);
connect(this, &Positioner::startupFinished, this, &Positioner::onStartupFinished);
connect(m_view, &Latte::View::onPrimaryChanged, this, &Positioner::syncLatteViews); connect(m_view, &Latte::View::onPrimaryChanged, this, &Positioner::syncLatteViews);
@ -336,6 +337,14 @@ void Positioner::slideInDuringStartup()
m_corona->wm()->slideWindow(*m_view, slideLocation(m_view->containment()->location())); m_corona->wm()->slideWindow(*m_view, slideLocation(m_view->containment()->location()));
} }
void Positioner::onStartupFinished()
{
if (m_inStartup) {
m_inStartup = false;
syncGeometry();
}
}
void Positioner::onCurrentLayoutIsSwitching(const QString &layoutName) void Positioner::onCurrentLayoutIsSwitching(const QString &layoutName)
{ {
if (!m_view || !m_view->layout() || m_view->layout()->name() != layoutName || !m_view->isVisible()) { if (!m_view || !m_view->layout() || m_view->layout()->name() != layoutName || !m_view->isVisible()) {
@ -509,7 +518,14 @@ void Positioner::immediateSyncGeometry()
//! instead of two times (both inside the resizeWindow and the updatePosition) //! instead of two times (both inside the resizeWindow and the updatePosition)
QRegion freeRegion;; QRegion freeRegion;;
QRect maximumRect; QRect maximumRect;
QRect availableScreenRect{m_view->screen()->geometry()}; QRect availableScreenRect = m_view->screen()->geometry();
if (m_inStartup) {
//! paint out-of-screen
availableScreenRect = QRect(-9999, -9999, m_view->screen()->geometry().width(), m_view->screen()->geometry().height());
}
qDebug() << " ------------>> " << m_view->location() << " ___ " << availableScreenRect;
if (m_view->formFactor() == Plasma::Types::Vertical) { if (m_view->formFactor() == Plasma::Types::Vertical) {
QString layoutName = m_view->layout() ? m_view->layout()->name() : QString(); QString layoutName = m_view->layout() ? m_view->layout()->name() : QString();
@ -538,7 +554,12 @@ void Positioner::immediateSyncGeometry()
} }
QString activityid = m_view->layout() ? m_view->layout()->lastUsedActivity() : QString(); QString activityid = m_view->layout() ? m_view->layout()->lastUsedActivity() : QString();
freeRegion = latteCorona->availableScreenRegionWithCriteria(fixedScreen, activityid, ignoreModes, ignoreEdges); if (m_inStartup) {
//! paint out-of-screen
freeRegion = availableScreenRect;
} else {
freeRegion = latteCorona->availableScreenRegionWithCriteria(fixedScreen, activityid, ignoreModes, ignoreEdges);
}
maximumRect = maximumNormalGeometry(); maximumRect = maximumNormalGeometry();
QRegion availableRegion = freeRegion.intersected(maximumRect); QRegion availableRegion = freeRegion.intersected(maximumRect);
@ -871,6 +892,10 @@ void Positioner::resizeWindow(QRect availableScreenRect)
} }
} }
//! protect from invalid window size under wayland
size.setWidth(qMax(1, size.width()));
size.setHeight(qMax(1, size.height()));
m_validGeometry.setSize(size); m_validGeometry.setSize(size);
m_view->setMinimumSize(size); m_view->setMinimumSize(size);

View File

@ -89,6 +89,7 @@ public:
public slots: public slots:
Q_INVOKABLE void setNextLocation(const QString layoutName, const QString screenId, int edge, int alignment); Q_INVOKABLE void setNextLocation(const QString layoutName, const QString screenId, int edge, int alignment);
Q_INVOKABLE void slideInDuringStartup();
void syncGeometry(); void syncGeometry();
@ -96,7 +97,6 @@ public slots:
//! that might prevent them. It must be called with care. //! that might prevent them. It must be called with care.
void immediateSyncGeometry(); void immediateSyncGeometry();
void slideInDuringStartup();
void slideOutDuringExit(Plasma::Types::Location location = Plasma::Types::Floating); void slideOutDuringExit(Plasma::Types::Location location = Plasma::Types::Floating);
void initDelayedSignals(); void initDelayedSignals();
@ -118,6 +118,8 @@ signals:
void hidingForRelocationFinished(); void hidingForRelocationFinished();
void showingAfterRelocationFinished(); void showingAfterRelocationFinished();
void startupFinished(); //called from containment qml end of startup sequence
void onHideWindowsForSlidingOut(); void onHideWindowsForSlidingOut();
void inRelocationAnimationChanged(); void inRelocationAnimationChanged();
void inRelocationShowingChanged(); void inRelocationShowingChanged();
@ -129,6 +131,7 @@ private slots:
void onScreenChanged(QScreen *screen); void onScreenChanged(QScreen *screen);
void onCurrentLayoutIsSwitching(const QString &layoutName); void onCurrentLayoutIsSwitching(const QString &layoutName);
void onLastRepositionApplyEvent(); void onLastRepositionApplyEvent();
void onStartupFinished();
void validateDockGeometry(); void validateDockGeometry();
void updateInRelocationAnimation(); void updateInRelocationAnimation();
@ -160,6 +163,7 @@ private:
bool m_inRelocationAnimation{false}; bool m_inRelocationAnimation{false};
bool m_inRelocationShowing{false}; bool m_inRelocationShowing{false};
bool m_inSlideAnimation{false}; bool m_inSlideAnimation{false};
bool m_inStartup{true};
bool m_isStickedOnTopEdge{false}; bool m_isStickedOnTopEdge{false};
bool m_isStickedOnBottomEdge{false}; bool m_isStickedOnBottomEdge{false};

View File

@ -172,10 +172,6 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassX11WM)
if (m_positioner) { if (m_positioner) {
//! immediateSyncGeometry helps avoiding binding loops from containment qml side //! immediateSyncGeometry helps avoiding binding loops from containment qml side
m_positioner->immediateSyncGeometry(); m_positioner->immediateSyncGeometry();
if (m_inStartup) {
m_inStartup = false;
m_positioner->slideInDuringStartup();
}
} }
connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus))); connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus)));

View File

@ -391,7 +391,6 @@ private:
bool m_containsDrag{false}; bool m_containsDrag{false};
bool m_containsMouse{false}; bool m_containsMouse{false};
bool m_inDelete{false}; bool m_inDelete{false};
bool m_inStartup{true};
bool m_isPreferredForShortcuts{false}; bool m_isPreferredForShortcuts{false};
bool m_onPrimary{true}; bool m_onPrimary{true};
bool m_screenEdgeMarginEnabled{false}; bool m_screenEdgeMarginEnabled{false};

View File

@ -79,16 +79,6 @@ VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view)
connect(m_latteView, &Latte::View::inEditModeChanged, this, &VisibilityManager::initViewFlags); connect(m_latteView, &Latte::View::inEditModeChanged, this, &VisibilityManager::initViewFlags);
// disabling this call because it was creating too many struts calls and
// could create reduced responsiveness for DynamicStruts Scenario(for example
// when dragging active window from a floating dock/panel)
/*
connect(m_latteView, &Latte::View::absoluteGeometryChanged, this, [&]() {
if (m_mode == Types::AlwaysVisible) {
updateStrutsBasedOnLayoutsAndActivities();
}
});*/
//! Frame Extents //! Frame Extents
connect(m_latteView, &Latte::View::headThicknessGapChanged, this, &VisibilityManager::onHeadThicknessChanged); connect(m_latteView, &Latte::View::headThicknessGapChanged, this, &VisibilityManager::onHeadThicknessChanged);
connect(m_latteView, &Latte::View::locationChanged, this, [&]() { connect(m_latteView, &Latte::View::locationChanged, this, [&]() {
@ -267,23 +257,20 @@ void VisibilityManager::setMode(Latte::Types::Visibility mode)
updateStrutsBasedOnLayoutsAndActivities(); updateStrutsBasedOnLayoutsAndActivities();
} }
m_connections[base] = connect(this, &VisibilityManager::strutsThicknessChanged, this, [&]() { m_connections[base] = connect(this, &VisibilityManager::strutsThicknessChanged, &VisibilityManager::updateStrutsAfterTimer);
bool execute = !m_timerBlockStrutsUpdate.isActive();
m_timerBlockStrutsUpdate.start(); // disabling this call because it was creating too many struts calls and ???
// could create reduced responsiveness for DynamicStruts Scenario(for example ??
// when dragging active window from a floating dock/panel) ???
m_connections[base+1] = connect(m_latteView, &Latte::View::absoluteGeometryChanged, this, &VisibilityManager::updateStrutsAfterTimer);
if (execute) { m_connections[base+2] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() {
updateStrutsBasedOnLayoutsAndActivities();
}
});
m_connections[base+1] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() {
if (m_corona && m_corona->layoutsManager()->memoryUsage() == MemoryUsage::MultipleLayouts) { if (m_corona && m_corona->layoutsManager()->memoryUsage() == MemoryUsage::MultipleLayouts) {
updateStrutsBasedOnLayoutsAndActivities(true); updateStrutsBasedOnLayoutsAndActivities(true);
} }
}); });
m_connections[base+2] = connect(m_latteView, &Latte::View::activitiesChanged, this, [&]() { m_connections[base+3] = connect(m_latteView, &Latte::View::activitiesChanged, this, [&]() {
updateStrutsBasedOnLayoutsAndActivities(true); updateStrutsBasedOnLayoutsAndActivities(true);
}); });
@ -382,6 +369,17 @@ void VisibilityManager::setMode(Latte::Types::Visibility mode)
emit modeChanged(); emit modeChanged();
} }
void VisibilityManager::updateStrutsAfterTimer()
{
bool execute = !m_timerBlockStrutsUpdate.isActive();
m_timerBlockStrutsUpdate.start();
if (execute) {
updateStrutsBasedOnLayoutsAndActivities();
}
}
void VisibilityManager::updateSidebarState() void VisibilityManager::updateSidebarState()
{ {
bool cursidebarstate = ((m_mode == Types::SidebarOnDemand) bool cursidebarstate = ((m_mode == Types::SidebarOnDemand)

View File

@ -204,6 +204,8 @@ private slots:
void dodgeMaximized(); void dodgeMaximized();
void updateHiddenState(); void updateHiddenState();
void updateStrutsAfterTimer();
bool isValidMode() const; bool isValidMode() const;
private: private:

View File

@ -166,6 +166,11 @@ Item{
} }
function slotMustBeShown() { function slotMustBeShown() {
if (root.inStartup) {
slidingAnimationAutoHiddenIn.init();
return;
}
//! WindowsCanCover case //! WindowsCanCover case
if (latteView && latteView.visibility.mode === LatteCore.Types.WindowsCanCover) { if (latteView && latteView.visibility.mode === LatteCore.Types.WindowsCanCover) {
latteView.visibility.setViewOnFrontLayer(); latteView.visibility.setViewOnFrontLayer();
@ -190,6 +195,11 @@ Item{
} }
function slotMustBeHide() { function slotMustBeHide() {
if (root.inStartup) {
slidingAnimationAutoHiddenOut.init();
return;
}
if (inSlidingIn && !inRelocationHiding) { if (inSlidingIn && !inRelocationHiding) {
/*consider hiding after sliding in has finished*/ /*consider hiding after sliding in has finished*/
return; return;
@ -468,10 +478,18 @@ Item{
latteView.visibility.slideOutFinished(); latteView.visibility.slideOutFinished();
manager.updateInputGeometry(); manager.updateInputGeometry();
if (root.inStartup) {
//! when view is first created slide-outs when that animation ends then
//! it flags that startup has ended and first slide-in can be started
//! this is important because if it is removed then some views
//! wont slide-in after startup.
root.inStartup = false;
}
} }
function init() { function init() {
if (manager.inRelocationAnimation || !latteView.visibility.blockHiding) { if (manager.inRelocationAnimation || root.inStartup/*used from recreating views*/ || !latteView.visibility.blockHiding) {
start(); start();
} }
} }

View File

@ -180,7 +180,7 @@ Item {
property bool dragActiveWindowEnabled: plasmoid.configuration.dragActiveWindowEnabled property bool dragActiveWindowEnabled: plasmoid.configuration.dragActiveWindowEnabled
property bool immutable: plasmoid.immutable property bool immutable: plasmoid.immutable
property bool inFullJustify: (plasmoid.configuration.alignment === LatteCore.Types.Justify) && (maxLengthPerCentage===100) property bool inFullJustify: (plasmoid.configuration.alignment === LatteCore.Types.Justify) && (maxLengthPerCentage===100)
property bool inStartup: !fastLayoutManager.hasRestoredApplets property bool inStartup: true
property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal
property bool isVertical: !isHorizontal property bool isVertical: !isHorizontal
@ -1045,6 +1045,12 @@ Item {
onViewChanged: { onViewChanged: {
if (view) { if (view) {
view.interfacesGraphicObj = _interfaces; view.interfacesGraphicObj = _interfaces;
if (!root.inStartup) {
//! used from recreating views
root.inStartup = true;
startupDelayer.start();
}
} }
} }
} }
@ -1056,10 +1062,34 @@ Item {
//! It is used in order to slide-in the latteView on startup //! It is used in order to slide-in the latteView on startup
onInStartupChanged: { onInStartupChanged: {
if (!inStartup) { if (!inStartup) {
latteView.positioner.startupFinished();
latteView.positioner.slideInDuringStartup();
visibilityManager.slotMustBeShown(); visibilityManager.slotMustBeShown();
} }
} }
Connections {
target:fastLayoutManager
onHasRestoredAppletsChanged: {
if (fastLayoutManager.hasRestoredApplets) {
startupDelayer.start();
}
}
}
Timer {
//! Give a little more time to layouter and applets to load and be positioned properly during startup when
//! the view is drawn out-of-screen and afterwards trigger the startup animation sequence:
//! 1.slide-out when out-of-screen //slotMustBeHide()
//! 2.be positioned properly at correct screen //slideInDuringStartup(), triggers Positioner::syncGeometry()
//! 3.slide-in properly in correct screen //slotMustBeShown();
id: startupDelayer
interval: 1000
onTriggered: {
visibilityManager.slotMustBeHide();
}
}
///////////////END TIMER elements ///////////////END TIMER elements
Loader{ Loader{