350cd296fa
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>
137 lines
3.7 KiB
JavaScript
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);
|
|
});
|
|
}
|
|
}
|