gnome-compact-top-bar/compact-top-bar@metehan-ars.../extension.js

125 lines
4.7 KiB
JavaScript

import Meta from 'gi://Meta';
import St from 'gi://St';
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js'
export default class CompactTopBar extends Extension {
enable() {
this._actorSignalIds = new Map();
this._windowSignalIds = new Map();
this._actorSignalIds.set(Main.overview, [
Main.overview.connect('showing', this._updateTransparent.bind(this)),
Main.overview.connect('hiding', this._updateTransparent.bind(this))
]);
this._actorSignalIds.set(Main.sessionMode, [
Main.sessionMode.connect('updated', this._updateTransparent.bind(this))
]);
for (const metaWindowActor of global.get_window_actors()) {
this._onWindowActorAdded(metaWindowActor.get_parent(), metaWindowActor);
}
this._actorSignalIds.set(global.window_group, [
global.window_group.connect('child-added', this._onWindowActorAdded.bind(this)),
global.window_group.connect('child-removed', this._onWindowActorRemoved.bind(this))
]);
this._actorSignalIds.set(global.window_manager, [
global.window_manager.connect('switch-workspace', this._updateTransparent.bind(this))
]);
this._updateTransparent();
}
disable() {
for (const actorSignalIds of [this._actorSignalIds, this._windowSignalIds]) {
for (const [actor, signalIds] of actorSignalIds) {
for (const signalId of signalIds) {
actor.disconnect(signalId);
}
}
}
this._actorSignalIds = null;
this._windowSignalIds = null;
Main.panel.remove_style_class_name('transparent-top-bar--solid');
Main.panel.remove_style_class_name('transparent-top-bar--transparent');
}
_onWindowActorAdded(container, metaWindowActor) {
this._windowSignalIds.set(metaWindowActor, [
metaWindowActor.connect('notify::allocation', this._updateTransparent.bind(this)),
metaWindowActor.connect('notify::visible', this._updateTransparent.bind(this))
]);
}
_onWindowActorRemoved(container, metaWindowActor) {
for (const signalId of this._windowSignalIds.get(metaWindowActor)) {
metaWindowActor.disconnect(signalId);
}
this._windowSignalIds.delete(metaWindowActor);
this._updateTransparent();
}
_updateTransparent() {
if (Main.panel.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
this._setTransparent(true);
return;
}
if (!Main.layoutManager.primaryMonitor) {
return;
}
// Get all the windows in the active workspace that are visible.
const workspaceManager = global.workspace_manager;
const activeWorkspace = workspaceManager.get_active_workspace();
const windows = activeWorkspace.list_windows().filter(metaWindow => {
if (!Main.layoutManager.primaryMonitor.inFullscreen){
return metaWindow.is_on_primary_monitor()
&& metaWindow.showing_on_its_workspace()
&& !metaWindow.is_hidden()
&& !metaWindow.is_fullscreen()
&& metaWindow.get_window_type() !== Meta.WindowType.DESKTOP;
} else {
return !metaWindow.is_on_primary_monitor()
&& metaWindow.showing_on_its_workspace()
&& !metaWindow.is_hidden()
&& !metaWindow.is_fullscreen()
&& metaWindow.get_window_type() !== Meta.WindowType.DESKTOP;
}
});
// Check if at least one window is near enough to the panel.
const panelTop = Main.panel.get_transformed_position()[1];
const panelBottom = panelTop + Main.panel.get_height();
const scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
const isNearEnough = windows.some(metaWindow => {
const verticalPosition = metaWindow.get_frame_rect().y;
return verticalPosition < panelBottom + 5 * scale;
});
this._setTransparent(!isNearEnough);
}
_setTransparent(transparent) {
if (transparent) {
Main.panel.remove_style_class_name('transparent-top-bar--solid');
Main.panel.add_style_class_name('transparent-top-bar--transparent');
} else {
Main.panel.add_style_class_name('transparent-top-bar--solid');
Main.panel.remove_style_class_name('transparent-top-bar--transparent');
}
}
};
function init() {
return new Extension();
}