Files
system-taskbar/ding/gnomeShellOverride.js

191 lines
6.2 KiB
JavaScript

/* eslint-disable no-invalid-this */
/* eslint-disable no-undef */
/* The above is for use of global in this file as Shell.global */
/* Gnome Shell Override
*
* Copyright (C) 2023 Sundeep Mediratta (smedius@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* exported GnomeShellOverride */
const {Meta, Clutter, GObject} = imports.gi;
// Show desktop windows on workspace thumbnails
const SHOW_ON_WORKSPACE_THUMBNAILS = true;
const SHOW_ICONS_ON_OVERVIEW = false;
const ANIMATION_MULTIPLE = 1;
import {WorkspaceBackground} from 'resource:///org/gnome/shell/ui/workspace.js';
import {InjectionManager} from
'resource:///org/gnome/shell/extensions/extension.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as Util from 'resource:///org/gnome/shell/misc/util.js';
export {GnomeShellOverride};
var GnomeShellOverride = class {
constructor() {
this._injectionManager = new InjectionManager();
}
enable() {
const Background = WorkspaceBackground;
this._injectionManager.overrideMethod(Background.prototype, '_init',
this._newBackgroundInit.bind(this));
}
disable() {
this._injectionManager.clear();
}
_newBackgroundInit(origninalMethod) {
return function (...args) {
origninalMethod.call(this, ...args);
/** @enum {number} */
const ControlsState = {
HIDDEN: 0,
WINDOW_PICKER: 1,
APP_GRID: 2,
};
const opaque = 255;
const transparent = 0;
const adjustment =
Main.overview._overview._controls._stateAdjustment
function _windowIsOnThisMonitor(metawindow, monitorIndex) {
const geometry =
global.display.get_monitor_geometry(monitorIndex);
const [intersects] =
metawindow.get_frame_rect().intersect(geometry);
return intersects;
}
function _modifyTransparency(value) {
const {initialState, finalState, } =
adjustment.getStateTransitionParams();
if ((initialState == ControlsState.HIDDEN ||
finalState == ControlsState.HIDDEN) &&
(Math.abs(initialState - finalState) == 1))
return _setTransparency(value);
return transparent;
}
function _setTransparency(value) {
if (SHOW_ICONS_ON_OVERVIEW)
return opaque;
return Util.lerp(opaque, transparent,
Math.min(ANIMATION_MULTIPLE * value, 1.0));
}
const desktopWindows = global.get_window_actors().filter(a =>
a.meta_window.get_window_type() === Meta.WindowType.DESKTOP &&
_windowIsOnThisMonitor(a.meta_window, this._monitorIndex));
if (desktopWindows.length) {
const desktopLayer = new Clutter.Actor({
layout_manager: new DesktopLayout(),
clip_to_allocation: true,
});
for (let windowActor of desktopWindows) {
const clone = new Clutter.Clone({
source: windowActor,
});
desktopLayer.add_child(clone);
windowActor.connectObject('destroy', () => {
clone.destroy();
}, this);
}
const offset = 0;
const syncAll = Clutter.BindConstraint.new(
this._bgManager.backgroundActor,
Clutter.BindCoordinate.ALL,
offset);
desktopLayer.add_constraint(syncAll);
desktopLayer.opacity = _setTransparency(opaque);
this._stateAdjustment.connectObject('notify::value',
(stAdjustment) => {
if (SHOW_ON_WORKSPACE_THUMBNAILS)
desktopLayer.opacity =
_setTransparency(this._stateAdjustment.value);
else
desktopLayer.opacity =
_modifyTransparency(stAdjustment.value);
},
this
);
this._backgroundGroup.insert_child_above(
desktopLayer,
this._bgManager.backgroundActor
);
}
};
}
};
class DesktopLayout extends Clutter.LayoutManager {
static {
GObject.registerClass(this);
}
vfunc_get_preferred_width() {
return [0, 0];
}
vfunc_get_preferred_height() {
return [0, 0];
}
vfunc_allocate(container, box) {
const monitorIndex = Main.layoutManager.findIndexForActor(container);
const monitor = Main.layoutManager.monitors[monitorIndex];
const hscale = box.get_width() / monitor.width;
const vscale = box.get_height() / monitor.height;
for (const child of container) {
const childBox = new Clutter.ActorBox();
const frameRect = child.get_source()?.metaWindow.get_frame_rect();
childBox.set_size(
Math.round(frameRect.width * hscale),
Math.round(frameRect.height * vscale)
);
childBox.set_origin(
Math.round((frameRect.x - monitor.x) * hscale),
Math.round((frameRect.y - monitor.y) * vscale)
);
child.allocate(childBox);
}
}
}