dot/.local/share/gnome-shell/extensions/transparent-window-moving@n.../extension.js

163 lines
4.6 KiB
JavaScript

const Tweener = imports.ui.tweener;
const Meta = imports.gi.Meta;
const GLib = imports.gi.GLib;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
let _settings = null;
let _WindowState;
let _on_window_grab_begin, _on_window_grab_end;
let _on_move_changed, _on_resize_changed;
let _allowed_grab_operations = [];
let _grab_moving_operations = [
Meta.GrabOp.MOVING,
Meta.GrabOp.KEYBOARD_MOVING
];
let _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
];
function init_grab_operations() {
_allowed_grab_operations = [];
if (_settings.get_boolean('transparent-on-moving')) {
_allowed_grab_operations.push(..._grab_moving_operations);
}
if (_settings.get_boolean('transparent-on-resizing')) {
_allowed_grab_operations.push(..._grab_resizing_operations);
}
}
function is_grab_operation_allowed(grab_op) {
return _allowed_grab_operations.indexOf(grab_op) > -1;
}
function set_opacity(window_actor, target_opacity, on_complete, check_if_completed) {
let transition_time = _settings.get_double('transition-time');
let window_surface = get_window_surface(window_actor);
let state = _WindowState[window_actor.meta_window.get_pid()];
let thread = Date.now();
state.thread = thread;
let complete_func = function() {
state.thread = 0;
if (on_complete) {
on_complete();
}
};
if (transition_time < 0.001) {
window_surface.opacity = target_opacity;
complete_func();
} else {
Tweener.addTween(window_surface, {
time: transition_time,
transition: 'easeOutQuad',
opacity: target_opacity,
onComplete: complete_func
});
if (check_if_completed) {
set_timeout(function() {
if (state && state.thread == thread){
window_surface.opacity = target_opacity;
complete_func();
}
}, transition_time * 1000 + 100); // repair opacity if the Tween was canceled
}
}
}
function set_timeout(func, time){
GLib.timeout_add(GLib.PRIORITY_DEFAULT, time, function() {
func();
return false;
});
}
function get_window_surface(window_actor) {
var childs = window_actor.get_children();
for (var i = 0; i < childs.length; i++) {
if (childs[i].constructor.name.indexOf('MetaSurfaceActor') > -1) {
return childs[i];
}
}
return window_actor;
}
function window_grab_begin(meta_display, meta_screen, meta_window, meta_grab_op, gpointer) {
if (!meta_window || !is_grab_operation_allowed(meta_grab_op)) {
return;
}
let window_actor = meta_window.get_compositor_private();
let pid = meta_window.get_pid();
let state = _WindowState[pid];
if (!state) {
let window_surface = get_window_surface(window_actor);
state = { thread: -1, original_opacity: window_surface.opacity }
_WindowState[pid] = state;
}
let opacity_value = _settings.get_int('window-opacity');
set_opacity(window_actor, opacity_value);
}
function window_grab_end(meta_display, meta_screen, meta_window, meta_grab_op, gpointer) {
if (!meta_window || !is_grab_operation_allowed(meta_grab_op)) {
return;
}
let window_actor = meta_window.get_compositor_private();
let pid = meta_window.get_pid();
let state = _WindowState[pid];
set_opacity(window_actor, state.original_opacity, function() { delete _WindowState[pid]; }, true);
}
function enable() {
_settings = Convenience.getSettings();
init_grab_operations();
_WindowState = {};
_on_window_grab_begin = global.display.connect('grab-op-begin', window_grab_begin);
_on_window_grab_end = global.display.connect('grab-op-end', window_grab_end);
_on_move_changed = _settings.connect('changed::transparent-on-moving', init_grab_operations);
_on_resize_changed = _settings.connect('changed::transparent-on-resizing', init_grab_operations);
}
function disable() {
global.display.disconnect(_on_window_grab_begin);
global.display.disconnect(_on_window_grab_end);
_settings.disconnect(_on_move_changed);
_settings.disconnect(_on_resize_changed);
_WindowState = {};
_settings.run_dispose();
}
function init() {
Convenience.initTranslations();
}