keyboard: Animate focus window using position instead of translation-y

Commit 8526776b4a changed the OSK to use
the translation-y property of the MetaWindowActor when animating a focus
window, which broke two things:

1) It's not compatible with the obscured region culling we do for
windows in mutter. That's because MetaCullable strictly operates in
integer coordinates and thus has to ignore any transformations
(translation-y is a transformation). Because of this, during the
animation and gesture, window damage is now tracked incorrectly,
introducing painting issues. The best fix for this would probably be
factoring in transformations when tracking damage in MetaCullable, but
that's not feasible right now.

2) It broke the shifting up of maximized and tiled windows, likely that
is because they are positioned using constraints internally, and mutter
enforces those constraints every time meta_window_move_frame() is
called, not allowing the window to move somewhere else.

To fix both issues, go back to the old way of shifting the window for
now, using the fixed y position of the ClutterActor. To make sure the
drag-up gesture still works, store the initial y1 position of the window
and then use that as a reference point for all our animations.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1760>
This commit is contained in:
Jonas Dreßler 2021-02-20 12:55:58 +01:00 committed by Marge Bot
parent 2cf8b93a7b
commit 7b990daee2

View File

@ -1265,6 +1265,7 @@ var Keyboard = GObject.registerClass({
this._languagePopup = null; this._languagePopup = null;
this._focusWindow = null; this._focusWindow = null;
this._focusWindowStartY = null;
this._latched = false; // current level is latched this._latched = false; // current level is latched
@ -1890,10 +1891,9 @@ var Keyboard = GObject.registerClass({
let progress = Math.min(delta, this.height) / this.height; let progress = Math.min(delta, this.height) / this.height;
this.translation_y = -this.height * progress; this.translation_y = -this.height * progress;
this.opacity = 255 * progress; this.opacity = 255 * progress;
if (this._focusWindow) { const windowActor = this._focusWindow?.get_compositor_private();
const windowActor = this._focusWindow.get_compositor_private(); if (windowActor)
windowActor.translation_y = -this.height * progress; windowActor.y = this._focusWindowStartY - (this.height * progress);
}
} }
gestureActivate() { gestureActivate() {
@ -1926,54 +1926,50 @@ var Keyboard = GObject.registerClass({
this._showIdleId = 0; this._showIdleId = 0;
} }
_windowSlideAnimationComplete(window, delta) { _windowSlideAnimationComplete(window, finalY) {
// Synchronize window positions again. // Synchronize window positions again.
const windowActor = window.get_compositor_private(); const frameRect = window.get_frame_rect();
if (windowActor) const bufferRect = window.get_buffer_rect();
windowActor.translation_y = 0;
let frameRect = window.get_frame_rect(); finalY += frameRect.y - bufferRect.y;
frameRect.y += delta;
frameRect.y = finalY;
window.move_frame(true, frameRect.x, frameRect.y); window.move_frame(true, frameRect.x, frameRect.y);
} }
_animateWindow(window, show) { _animateWindow(window, show) {
let windowActor = window.get_compositor_private(); let windowActor = window.get_compositor_private();
let deltaY = Main.layoutManager.keyboardBox.height;
if (!windowActor) if (!windowActor)
return; return;
if (show) { const finalY = show
windowActor.ease({ ? this._focusWindowStartY - Main.layoutManager.keyboardBox.height
translation_y: -deltaY, : this._focusWindowStartY;
duration: KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, windowActor.ease({
onComplete: () => { y: finalY,
this._windowSlideAnimationComplete(window, -deltaY); duration: KEYBOARD_ANIMATION_TIME,
}, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
}); onStopped: () => {
} else { windowActor.y = finalY;
windowActor.ease({ this._windowSlideAnimationComplete(window, finalY);
translation_y: deltaY, },
duration: KEYBOARD_ANIMATION_TIME, });
mode: Clutter.AnimationMode.EASE_IN_QUAD,
onComplete: () => {
this._windowSlideAnimationComplete(window, deltaY);
},
});
}
} }
_setFocusWindow(window) { _setFocusWindow(window) {
if (this._focusWindow === window) if (this._focusWindow === window)
return; return;
if (this._keyboardVisible) { if (this._keyboardVisible && this._focusWindow)
if (this._focusWindow) this._animateWindow(this._focusWindow, false);
this._animateWindow(this._focusWindow, false);
if (window) const windowActor = window?.get_compositor_private();
this._animateWindow(window, true); windowActor?.remove_transition('y');
} this._focusWindowStartY = windowActor ? windowActor.y : null;
if (this._keyboardVisible && window)
this._animateWindow(window, true);
this._focusWindow = window; this._focusWindow = window;
} }