Skip to content

Commit

Permalink
fix(plugin): bind values to 1:1 animation while gesture is ongoing
Browse files Browse the repository at this point in the history
Otherwise the animation feels wrong while activating with a gesture.
Now when a 1:1 gesture is ongoing, then the Overview effect will stop
animating the overviewVal/gridVal values. I implemented this by porting
to states, giving 1:1 gestures their own states, and only animating the
change between states.

BUG: 476536
  • Loading branch information
veggero authored and romangg committed Dec 12, 2023
1 parent 46d04fa commit 239f82a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 35 deletions.
5 changes: 3 additions & 2 deletions lib/render/effect/interface/effect_togglable_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void EffectTogglableState::deactivate()
void EffectTogglableState::stop()
{
setInProgress(false);
setPartialActivationFactor(0.0);
setStatus(Status::Stopped);
}

Expand Down Expand Up @@ -98,15 +99,15 @@ void EffectTogglableState::partialActivate(qreal factor)
}

setStatus(Status::Activating);
setPartialActivationFactor(factor);
setInProgress(true);
setPartialActivationFactor(factor);
}

void EffectTogglableState::partialDeactivate(qreal factor)
{
setStatus(Status::Deactivating);
setPartialActivationFactor(1.0 - factor);
setInProgress(true);
setPartialActivationFactor(1.0 - factor);
}

void EffectTogglableState::toggle()
Expand Down
6 changes: 0 additions & 6 deletions plugins/effects/overview/overvieweffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,6 @@ void OverviewEffect::activate()

void OverviewEffect::deactivate()
{
auto const screens = effects->screens();
for (auto const screen : screens) {
if (auto view = viewForScreen(screen)) {
QMetaObject::invokeMethod(view->rootItem(), "stop");
}
}
m_shutdownTimer->start(animationDuration());
m_overviewState->deactivate();
}
Expand Down
109 changes: 82 additions & 27 deletions plugins/effects/overview/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,89 @@ FocusScope {
property real overviewVal: 0
property real gridVal: 0

Behavior on overviewVal {
NumberAnimation {
duration: Kirigami.Units.shortDuration
states: [
State {
name: "initial"
PropertyChanges {
target: container
overviewVal: 0
gridVal: 0
}
},
State {
name: "grid"
PropertyChanges {
target: container
overviewVal: 0
gridVal: 1
}
},
State {
name: "overview"
PropertyChanges {
target: container
overviewVal: 1
gridVal: 0
}
},
State {
name: "partialOverview"
PropertyChanges {
target: container
overviewVal: effect.overviewPartialActivationFactor
gridVal: 0
}
},
State {
name: "partialGrid"
PropertyChanges {
target: container
overviewVal: 0
gridVal: effect.gridPartialActivationFactor
}
},
State {
name: "transition"
PropertyChanges {
target: container
overviewVal: 1 - effect.transitionPartialActivationFactor
gridVal: effect.transitionPartialActivationFactor
}
}
]
state: {
// If the effect hasn't started, we remain on the initial state
if (!organized) return "initial";

// If a gesture is ongoing, we use a partial state
if (effect.overviewGestureInProgress) return "partialOverview";
if (effect.gridGestureInProgress) return "partialGrid";
if (effect.transitionGestureInProgress) return "transition";

// If either the overview or grid gestures are completed, either
// by a touchpad/touchscreen gesture or through a shortcut, we use
// that state
if (effect.overviewPartialActivationFactor === 1) return "overview";
if (effect.gridPartialActivationFactor === 1) return "grid";

// If neither is active, we are in the initial state.
if (effect.overviewPartialActivationFactor + effect.gridPartialActivationFactor === 0) return "initial";

// If we are inbetween a state but no gesture is going on, we snap to
// the closest state
if (overviewVal >= 0.5) return "overview";
if (gridVal >= 0.5) return "grid";
return "initial";
}

Behavior on gridVal {
transitions: Transition {
to: "initial, grid, overview"
NumberAnimation {
duration: Kirigami.Units.shortDuration
properties: "gridVal, overviewVal"
easing.type: Easing.OutCubic
}
}

function start() {
animationEnabled = true;
organized = true;

overviewVal = Qt.binding(() => effect.overviewGestureInProgress ? effect.overviewPartialActivationFactor :
effect.transitionGestureInProgress ? 1 - effect.transitionPartialActivationFactor :
effect.overviewPartialActivationFactor == 1 && effect.transitionPartialActivationFactor == 0)
gridVal = Qt.binding(() => effect.transitionGestureInProgress ? effect.transitionPartialActivationFactor :
effect.gridGestureInProgress ? effect.gridPartialActivationFactor :
effect.transitionPartialActivationFactor == 1 && effect.gridPartialActivationFactor == 1)
}

function stop() {
organized = false;
}

function switchTo(desktop) {
KWinComponents.Workspace.currentDesktop = desktop;
effect.deactivate();
Expand Down Expand Up @@ -352,7 +407,7 @@ FocusScope {
color: Kirigami.Theme.highlightColor
visible: gridVal > 0 || nearCurrent
anchors.fill: parent
property bool shouldBeVisibleInOverview: !(container.organized && effect.searchText.length > 0 && current) || (heap.count !== 0 && effect.filterWindows)
property bool shouldBeVisibleInOverview: !(effect.searchText.length > 0 && current) || (heap.count !== 0 && effect.filterWindows)
opacity: 1 - overviewVal * (shouldBeVisibleInOverview ? 0 : 1)

function selectLastItem(direction) {
Expand Down Expand Up @@ -550,8 +605,8 @@ FocusScope {
focus: current
padding: Kirigami.Units.largeSpacing
animationDuration: effect.animationDuration
animationEnabled: container.animationEnabled && (gridVal !== 0 || mainBackground.current)
organized: container.organized
animationEnabled: (gridVal !== 0 || mainBackground.current) && organized
organized: container.state !== "initial"
dndManagerStore: desktopGrid.dndManagerStore
Keys.priority: Keys.AfterItem
Keys.forwardTo: [searchResults, searchField]
Expand Down Expand Up @@ -649,12 +704,12 @@ FocusScope {
Item {
width: parent.width
height: parent.height - topBar.height
visible: container.organized && effect.searchText.length > 0 && (allDesktopHeaps.currentHeap.count === 0 || !effect.filterWindows)
visible: effect.searchText.length > 0 && (allDesktopHeaps.currentHeap.count === 0 || !effect.filterWindows)
opacity: overviewVal

PlasmaExtras.PlaceholderMessage {
id: placeholderMessage
visible: container.organized && effect.searchText.length > 0 && allDesktopHeaps.currentHeap.count === 0 && effect.filterWindows
visible: effect.searchText.length > 0 && allDesktopHeaps.currentHeap.count === 0 && effect.filterWindows
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
text: i18ndc("kwin", "@info:placeholder", "No matching windows")
Expand Down Expand Up @@ -710,6 +765,6 @@ FocusScope {
// don't want the desktop bar changing screenside whilst the user is
// interacting with it, e.g. by adding desktops
container.verticalDesktopBar = container.verticalDesktopBar
start();
organized = true
}
}

0 comments on commit 239f82a

Please sign in to comment.