dot/.local/share/gnome-shell/extensions/floatingDock@sun.wxg@gmail.com/windowPreview.js

173 lines
5.4 KiB
JavaScript
Raw Normal View History

2020-05-11 09:16:27 +00:00
const { Gtk, Clutter, GObject, Shell, St } = imports.gi;
const PopupMenu = imports.ui.popupMenu;
const Main = imports.ui.main;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;
const Extension = Me.imports.extension;
const CreateNumberIcon = Me.imports.numberIcon.createNumberIcon;
const NUMBER_TO_CHAR = Me.imports.util.NUMBER_TO_CHAR;
const DIRECTION = 'floating-dock-direction';
const PREVIEW_MAX_WIDTH = 250;
const PREVIEW_MAX_HEIGHT = 150;
var WindowPreviewMenu = class WindowPreviewMenu extends PopupMenu.PopupMenu {
constructor(source, iconSize) {
let direction, style;
[direction, style] = getDirectionStyle(source);
super(source, 0.5, direction);
this.actor.set_style(style);
this.iconSize = iconSize;
this._source = source;
this._source.connect('destroy', () => {
this.destroy();
});
if (source.vimMode) {
this.sourceActor.disconnect(this._keyPressId);
this._keyPressId = 0;
}
this.actor.hide();
Main.uiGroup.add_actor(this.actor);
}
_redisplay() {
this.removeAll();
this._menuSection = new WindowPreviewMenuSection();
this.addMenuItem(this._menuSection);
let windows = this._source.app.get_windows();
windows = windows.filter( (window) => {
return Util.windowInActiveWorkspace(window);
});
let k = 0;
for (let i in windows) {
let menuItem = new WindowPreviewMenuItem(windows[i], this._source, k++, this.iconSize);
this._menuSection.addMenuItem(menuItem);
}
}
popup() {
this._redisplay();
this.open();
}
};
var WindowPreviewMenuSection = class WindowPreviewMenuSection extends PopupMenu.PopupMenuSection {
constructor() {
super();
let scroll = new St.ScrollView({ hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
enable_mouse_scrolling: true });
this.actor = scroll;
this.actor.add_actor(this.box);
this.actor._delegate = this;
}
};
var WindowPreviewMenuItem = GObject.registerClass(
class WindowPreviewMenuItem extends PopupMenu.PopupBaseMenuItem {
_init(window, button, number, iconSize) {
super._init({});
this._window = window;
this._button = button;
this._number = number;
this.iconSize = iconSize;
if (button.vimMode) {
this.setSensitive(false);
}
this._cloneBin = new St.Bin();
this._cloneBin.set_size(PREVIEW_MAX_WIDTH, PREVIEW_MAX_HEIGHT);
this.add_child(this._cloneBin);
this._cloneWindow(window);
this.connect('destroy', () => { this._onDestroy(); });
}
_cloneWindow(window) {
let mutterWindow = window.get_compositor_private();
let [width, height] = mutterWindow.get_size();
let scale = Math.min(1.0, PREVIEW_MAX_WIDTH/width, PREVIEW_MAX_HEIGHT/height);
let clone = new Clutter.Clone ({ source: mutterWindow,
reactive: true,
width: width * scale,
height: height * scale });
this._clone = clone;
this._cloneBox = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._cloneBox.destroy_all_children();
this._cloneBox.add_child(this._clone);
if (this._button.vimMode)
this._cloneBox.add_child(CreateNumberIcon(this._number, this.iconSize));
this._cloneBin.set_child(this._cloneBox);
this._mutterWindow = mutterWindow;
this._mutterWindowId = this._mutterWindow.connect('destroy', () => {
this.destroy();
this._mutterWindowId = 0;
});
}
vfunc_button_press_event() {
this._getTopMenu().close();
this._button.activateWindow(this._window);
return Clutter.EVENT_PROPAGATE;
}
_onDestroy() {
if (this._mutterWindowId) {
this._mutterWindow.disconnect(this._mutterWindowId);
this._mutterWindowId = 0;
}
}
});
function getDirectionStyle(source) {
let sourceAllocation = Shell.util_get_transformed_allocation(source);
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
// -arrow-base + -arrow-border-radius*2 + -arrow-border-width*2
let arrowHeight = (24 + 9 * 2 + 2);
let style = '';
let direction;
switch (Util.getPosition(Extension.gsettings.get_string(DIRECTION))) {
case St.Side.TOP:
case St.Side.BOTTOM:
if (sourceAllocation.x1 > (workArea.x + workArea.width / 2)) {
direction = St.Side.RIGHT;
} else {
direction = St.Side.LEFT;
}
style = 'max-height: %spx;'.format(workArea.height - arrowHeight);
break;
case St.Side.LEFT:
case St.Side.RIGHT:
if (sourceAllocation.y1 > (workArea.y + workArea.height / 2)) {
direction = St.Side.BOTTOM;
style = 'max-height: %spx;'.format(sourceAllocation.y1 - workArea.y);
} else {
direction = St.Side.TOP;
style = 'max-height: %spx;'.format(workArea.y + workArea.height - sourceAllocation.y2);
}
break;
default:
break;
}
return [direction, style];
}