155 lines
4.4 KiB
JavaScript
155 lines
4.4 KiB
JavaScript
import Clutter from 'gi://Clutter';
|
|
import Meta from 'gi://Meta';
|
|
|
|
import { Extension, gettext as _ }
|
|
from 'resource:///org/gnome/shell/extensions/extension.js';
|
|
|
|
const _grab_moving_operations = [
|
|
Meta.GrabOp.MOVING,
|
|
Meta.GrabOp.KEYBOARD_MOVING,
|
|
Meta.GrabOp.MOVING_UNCONSTRAINED
|
|
];
|
|
|
|
const _grab_resizing_operations = [
|
|
Meta.GrabOp.RESIZING_NW,
|
|
Meta.GrabOp.RESIZING_N,
|
|
Meta.GrabOp.RESIZING_NE,
|
|
Meta.GrabOp.RESIZING_E,
|
|
Meta.GrabOp.RESIZING_SW,
|
|
Meta.GrabOp.RESIZING_S,
|
|
Meta.GrabOp.RESIZING_SE,
|
|
Meta.GrabOp.RESIZING_W,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_UNKNOWN,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_NW,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_N,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_NE,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_E,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_SW,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_S,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_SE,
|
|
Meta.GrabOp.KEYBOARD_RESIZING_W
|
|
];
|
|
|
|
export default class TransparentWindowMoving extends Extension {
|
|
init_grab_operations() {
|
|
this._allowed_grab_operations = [];
|
|
if (this._settings.get_boolean('transparent-on-moving')) {
|
|
this._allowed_grab_operations.push(..._grab_moving_operations);
|
|
}
|
|
|
|
if (this._settings.get_boolean('transparent-on-resizing')) {
|
|
this._allowed_grab_operations.push(..._grab_resizing_operations);
|
|
}
|
|
}
|
|
|
|
is_grab_operation_allowed(grab_op) {
|
|
return this._allowed_grab_operations.indexOf(grab_op) > -1;
|
|
}
|
|
|
|
set_opacity(window_surfaces, target_opacity, on_complete) {
|
|
const complete_func = function() {
|
|
if (on_complete) {
|
|
on_complete();
|
|
}
|
|
};
|
|
|
|
const transition_time = this._settings.get_double('transition-time');
|
|
if (transition_time < 0.001) {
|
|
window_surfaces.forEach(surface => {
|
|
surface.opacity = target_opacity;
|
|
});
|
|
complete_func();
|
|
} else {
|
|
window_surfaces.forEach(surface => {
|
|
surface.ease({
|
|
duration: transition_time * 1000,
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
opacity: target_opacity,
|
|
onComplete: complete_func
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
get_window_surfaces(meta_window) {
|
|
const window_actor = meta_window.get_compositor_private();
|
|
const surfaces = this.find_meta_surface_actors(window_actor);
|
|
if (surfaces.length > 0) {
|
|
return surfaces;
|
|
}
|
|
|
|
return [window_actor];
|
|
}
|
|
|
|
find_meta_surface_actors(meta_actor) {
|
|
if (meta_actor.constructor.name.indexOf('MetaSurfaceActor') > -1) {
|
|
return [meta_actor];
|
|
}
|
|
|
|
const surfaces = [];
|
|
for (const child of meta_actor.get_children()) {
|
|
const result = this.find_meta_surface_actors(child);
|
|
if (result.length > 0) {
|
|
surfaces.push(...result);
|
|
}
|
|
}
|
|
|
|
return surfaces;
|
|
}
|
|
|
|
window_grab_begin(meta_display, meta_window, meta_grab_op, gpointer) {
|
|
if (!meta_window || !this.is_grab_operation_allowed(meta_grab_op)) {
|
|
return;
|
|
}
|
|
|
|
const window_surfaces = this.get_window_surfaces(meta_window);
|
|
const pid = meta_window.get_pid();
|
|
if (!this._window_opacity[pid]) {
|
|
this._window_opacity[pid] = window_surfaces[0].opacity;
|
|
}
|
|
|
|
const opacity_value = this._settings.get_int('window-opacity');
|
|
this.set_opacity(window_surfaces, opacity_value);
|
|
}
|
|
|
|
window_grab_end(meta_display, meta_window, meta_grab_op, gpointer) {
|
|
if (!meta_window || !this.is_grab_operation_allowed(meta_grab_op)) {
|
|
return;
|
|
}
|
|
|
|
const window_surfaces = this.get_window_surfaces(meta_window);
|
|
const pid = meta_window.get_pid();
|
|
|
|
const complete_func = function() {
|
|
delete this._window_opacity[pid];
|
|
};
|
|
|
|
this.set_opacity(window_surfaces, this._window_opacity[pid], complete_func.bind(this));
|
|
}
|
|
|
|
enable() {
|
|
this._settings = this.getSettings();
|
|
this.init_grab_operations();
|
|
this._window_opacity = {};
|
|
this._on_window_grab_begin = global.display.connect('grab-op-begin', this.window_grab_begin.bind(this));
|
|
this._on_window_grab_end = global.display.connect('grab-op-end', this.window_grab_end.bind(this));
|
|
this._on_move_changed = this._settings.connect('changed::transparent-on-moving', this.init_grab_operations.bind(this));
|
|
this._on_resize_changed = this._settings.connect('changed::transparent-on-resizing', this.init_grab_operations.bind(this));
|
|
}
|
|
|
|
disable() {
|
|
global.display.disconnect(this._on_window_grab_begin);
|
|
global.display.disconnect(this._on_window_grab_end);
|
|
this._settings.disconnect(this._on_move_changed);
|
|
this._settings.disconnect(this._on_resize_changed);
|
|
|
|
delete this._window_opacity;
|
|
delete this._allowed_grab_operations;
|
|
delete this._settings;
|
|
delete this._on_window_grab_begin;
|
|
delete this._on_window_grab_end;
|
|
delete this._on_move_changed;
|
|
delete this._on_resize_changed;
|
|
}
|
|
}
|