1
0
mirror of https://github.com/KDE/latte-dock.git synced 2024-12-23 01:33:50 +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::showingAfterRelocationFinished, this, &Positioner::updateInRelocationAnimation);
connect(this, &Positioner::showingAfterRelocationFinished, this, &Positioner::syncLatteViews);
connect(this, &Positioner::startupFinished, this, &Positioner::onStartupFinished);
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()));
}
void Positioner::onStartupFinished()
{
if (m_inStartup) {
m_inStartup = false;
syncGeometry();
}
}
void Positioner::onCurrentLayoutIsSwitching(const QString &layoutName)
{
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)
QRegion freeRegion;;
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) {
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();
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();
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_view->setMinimumSize(size);

View File

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

View File

@ -172,10 +172,6 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassX11WM)
if (m_positioner) {
//! immediateSyncGeometry helps avoiding binding loops from containment qml side
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)));

View File

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

View File

@ -79,16 +79,6 @@ VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view)
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
connect(m_latteView, &Latte::View::headThicknessGapChanged, this, &VisibilityManager::onHeadThicknessChanged);
connect(m_latteView, &Latte::View::locationChanged, this, [&]() {
@ -267,23 +257,20 @@ void VisibilityManager::setMode(Latte::Types::Visibility mode)
updateStrutsBasedOnLayoutsAndActivities();
}
m_connections[base] = connect(this, &VisibilityManager::strutsThicknessChanged, this, [&]() {
bool execute = !m_timerBlockStrutsUpdate.isActive();
m_connections[base] = connect(this, &VisibilityManager::strutsThicknessChanged, &VisibilityManager::updateStrutsAfterTimer);
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) {
updateStrutsBasedOnLayoutsAndActivities();
}
});
m_connections[base+1] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() {
m_connections[base+2] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() {
if (m_corona && m_corona->layoutsManager()->memoryUsage() == MemoryUsage::MultipleLayouts) {
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);
});
@ -382,6 +369,17 @@ void VisibilityManager::setMode(Latte::Types::Visibility mode)
emit modeChanged();
}
void VisibilityManager::updateStrutsAfterTimer()
{
bool execute = !m_timerBlockStrutsUpdate.isActive();
m_timerBlockStrutsUpdate.start();
if (execute) {
updateStrutsBasedOnLayoutsAndActivities();
}
}
void VisibilityManager::updateSidebarState()
{
bool cursidebarstate = ((m_mode == Types::SidebarOnDemand)

View File

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

View File

@ -166,6 +166,11 @@ Item{
}
function slotMustBeShown() {
if (root.inStartup) {
slidingAnimationAutoHiddenIn.init();
return;
}
//! WindowsCanCover case
if (latteView && latteView.visibility.mode === LatteCore.Types.WindowsCanCover) {
latteView.visibility.setViewOnFrontLayer();
@ -190,6 +195,11 @@ Item{
}
function slotMustBeHide() {
if (root.inStartup) {
slidingAnimationAutoHiddenOut.init();
return;
}
if (inSlidingIn && !inRelocationHiding) {
/*consider hiding after sliding in has finished*/
return;
@ -468,10 +478,18 @@ Item{
latteView.visibility.slideOutFinished();
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() {
if (manager.inRelocationAnimation || !latteView.visibility.blockHiding) {
if (manager.inRelocationAnimation || root.inStartup/*used from recreating views*/ || !latteView.visibility.blockHiding) {
start();
}
}

View File

@ -180,7 +180,7 @@ Item {
property bool dragActiveWindowEnabled: plasmoid.configuration.dragActiveWindowEnabled
property bool immutable: plasmoid.immutable
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 isVertical: !isHorizontal
@ -1045,6 +1045,12 @@ Item {
onViewChanged: {
if (view) {
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
onInStartupChanged: {
if (!inStartup) {
latteView.positioner.startupFinished();
latteView.positioner.slideInDuringStartup();
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
Loader{