gnome-shell/js/ui/pointerA11yTimeout.js
Zander Brown 350cd296fa js: Stop using ClutterContainer API
These have been long deprecated over in clutter, and (via several
vtables) simply forward the call to the equivalent ClutterActor methods

Save ourselves the hassle and just use ClutterActor methods directly

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3010>
2023-11-10 20:19:13 +00:00

137 lines
3.7 KiB
JavaScript

import Clutter from 'gi://Clutter';
import GObject from 'gi://GObject';
import Meta from 'gi://Meta';
import St from 'gi://St';
import * as Main from './main.js';
import Cairo from 'gi://cairo';
const SUCCESS_ZOOM_OUT_DURATION = 150;
const PieTimer = GObject.registerClass({
Properties: {
'angle': GObject.ParamSpec.double(
'angle', 'angle', 'angle',
GObject.ParamFlags.READWRITE,
0, 2 * Math.PI, 0),
},
}, class PieTimer extends St.DrawingArea {
_init() {
this._angle = 0;
super._init({
style_class: 'pie-timer',
opacity: 0,
visible: false,
can_focus: false,
reactive: false,
});
this.set_pivot_point(0.5, 0.5);
}
get angle() {
return this._angle;
}
set angle(angle) {
if (this._angle === angle)
return;
this._angle = angle;
this.notify('angle');
this.queue_repaint();
}
vfunc_repaint() {
let node = this.get_theme_node();
let backgroundColor = node.get_color('-pie-background-color');
let borderColor = node.get_color('-pie-border-color');
let borderWidth = node.get_length('-pie-border-width');
let [width, height] = this.get_surface_size();
let radius = Math.min(width / 2, height / 2);
let startAngle = 3 * Math.PI / 2;
let endAngle = startAngle + this._angle;
let cr = this.get_context();
cr.setLineCap(Cairo.LineCap.ROUND);
cr.setLineJoin(Cairo.LineJoin.ROUND);
cr.translate(width / 2, height / 2);
if (this._angle < 2 * Math.PI)
cr.moveTo(0, 0);
cr.arc(0, 0, radius - borderWidth, startAngle, endAngle);
if (this._angle < 2 * Math.PI)
cr.lineTo(0, 0);
cr.closePath();
cr.setLineWidth(0);
cr.setSourceColor(backgroundColor);
cr.fillPreserve();
cr.setLineWidth(borderWidth);
cr.setSourceColor(borderColor);
cr.stroke();
cr.$dispose();
}
start(x, y, duration) {
this.x = x - this.width / 2;
this.y = y - this.height / 2;
this.show();
this.ease({
opacity: 255,
duration: duration / 4,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
});
this.ease_property('angle', 2 * Math.PI, {
duration,
mode: Clutter.AnimationMode.LINEAR,
onComplete: this._onTransitionComplete.bind(this),
});
}
_onTransitionComplete() {
this.ease({
scale_x: 2,
scale_y: 2,
opacity: 0,
duration: SUCCESS_ZOOM_OUT_DURATION,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onStopped: () => this.destroy(),
});
}
});
export class PointerA11yTimeout {
constructor() {
let seat = Clutter.get_default_backend().get_default_seat();
seat.connect('ptr-a11y-timeout-started', (o, device, type, timeout) => {
let [x, y] = global.get_pointer();
this._pieTimer = new PieTimer();
Main.uiGroup.add_child(this._pieTimer);
Main.uiGroup.set_child_above_sibling(this._pieTimer, null);
this._pieTimer.start(x, y, timeout);
if (type === Clutter.PointerA11yTimeoutType.GESTURE)
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
});
seat.connect('ptr-a11y-timeout-stopped', (o, device, type, clicked) => {
if (!clicked)
this._pieTimer.destroy();
if (type === Clutter.PointerA11yTimeoutType.GESTURE)
global.display.set_cursor(Meta.Cursor.DEFAULT);
});
}
}