251 lines
7.2 KiB
JavaScript
251 lines
7.2 KiB
JavaScript
|
const { Clutter, GObject, Shell, St } = imports.gi;
|
||
|
|
||
|
const PopupMenu = imports.ui.popupMenu;
|
||
|
const AppDisplay = imports.ui.appDisplay;
|
||
|
const IconGrid = imports.ui.iconGrid;
|
||
|
const Main = imports.ui.main;
|
||
|
const Meta = imports.gi.Meta;
|
||
|
|
||
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||
|
const Me = ExtensionUtils.getCurrentExtension();
|
||
|
const NUMBER_TO_CHAR = Me.imports.util.NUMBER_TO_CHAR;
|
||
|
const Util = Me.imports.util;
|
||
|
const WindowPreview = Me.imports.windowPreview;
|
||
|
const CreateNumberIcon = Me.imports.numberIcon.createNumberIcon;
|
||
|
const Indicator = Me.imports.indicator;
|
||
|
|
||
|
var MyAppIcon = GObject.registerClass({
|
||
|
}, class MyAppIcon extends St.Widget {
|
||
|
_init(app, vimMode, number, iconSize) {
|
||
|
super._init();
|
||
|
|
||
|
this.app = app;
|
||
|
this.iconSize = iconSize;
|
||
|
|
||
|
this._icon = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||
|
this._icon.destroy_all_children();
|
||
|
this.add_child(this._icon);
|
||
|
|
||
|
let appicon = this.app.create_icon_texture(this.iconSize);
|
||
|
this._icon.add_child(appicon);
|
||
|
|
||
|
if (vimMode)
|
||
|
this._icon.add_child(CreateNumberIcon(number, this.iconSize));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var MyAppButton = GObject.registerClass({
|
||
|
Signals: {
|
||
|
'activate-window': {},
|
||
|
'in-preview': { param_types: [GObject.TYPE_BOOLEAN] },
|
||
|
},
|
||
|
}, class MyAppButton extends St.Button {
|
||
|
_init(app, vimMode, number, iconSize) {
|
||
|
super._init({ label: app.get_name(),
|
||
|
style_class: 'app-button',
|
||
|
y_align: Clutter.ActorAlign.CENTER,
|
||
|
reactive: vimMode ? false : true,
|
||
|
});
|
||
|
|
||
|
this.set_child(new MyAppIcon(app, vimMode, number, iconSize));
|
||
|
this.app = app;
|
||
|
this.iconSize = iconSize;
|
||
|
this.vimMode = vimMode;
|
||
|
this.time = 0;
|
||
|
|
||
|
this.set_pivot_point(0.5, 0.5);
|
||
|
this.connect('notify::hover', this._onHover.bind(this));
|
||
|
|
||
|
this._previewMenuManager = new PopupMenu.PopupMenuManager(this);
|
||
|
this._previewMenu = null;
|
||
|
|
||
|
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
||
|
this._menu = null;
|
||
|
}
|
||
|
|
||
|
vfunc_button_press_event(buttonEvent) {
|
||
|
if (buttonEvent.button == 3) {
|
||
|
if (this._previewMenu && this._previewMenu.isOpen)
|
||
|
return Clutter.EVENT_PROPAGATE;
|
||
|
|
||
|
this._popupMenu();
|
||
|
} else if (buttonEvent.button == 1) {
|
||
|
this.leftButtonClicked();
|
||
|
}
|
||
|
|
||
|
return Clutter.EVENT_STOP;
|
||
|
}
|
||
|
|
||
|
vfunc_scroll_event(scrollEvent) {
|
||
|
let gap = scrollEvent.time - this.time;
|
||
|
if (gap < 500 && gap >= 0)
|
||
|
return;
|
||
|
|
||
|
this.time = scrollEvent.time;
|
||
|
this._switchWindows();
|
||
|
|
||
|
return Clutter.EVENT_STOP;
|
||
|
}
|
||
|
|
||
|
_switchWindows() {
|
||
|
let currentWorkspace = global.workspace_manager.get_active_workspace();
|
||
|
|
||
|
let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL, currentWorkspace);
|
||
|
windows.map(w => {
|
||
|
return w.is_attached_dialog() ? w.get_transient_for() : w;
|
||
|
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
|
||
|
|
||
|
if (windows.length <= 1)
|
||
|
return;
|
||
|
|
||
|
windows[windows.length - 1].activate(global.get_current_time());
|
||
|
}
|
||
|
|
||
|
leftButtonClicked() {
|
||
|
let openNewWindow = this.app.can_open_new_window() &&
|
||
|
!Util.appInActiveWorkspace(this.app);
|
||
|
let windows = Util.windowsInActiveWorkspace(this.app);
|
||
|
|
||
|
if (openNewWindow) {
|
||
|
this.app.open_new_window(-1);
|
||
|
this.emit('activate-window');
|
||
|
} else if (windows.length == 1) {
|
||
|
this.activateWindow(windows[0]);
|
||
|
} else {
|
||
|
this._showPreviews();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_showPreviews() {
|
||
|
if (!this._previewMenu) {
|
||
|
this._previewMenu = new WindowPreview.WindowPreviewMenu(this, this.iconSize);
|
||
|
this._previewMenu.connect('open-state-changed',
|
||
|
(menu, state) => { this.emit('in-preview', state); });
|
||
|
|
||
|
this._previewMenuManager.addMenu(this._previewMenu, St.Side.LEFT);
|
||
|
}
|
||
|
|
||
|
if (this._previewMenu.isOpen) {
|
||
|
this._previewMenu.close();
|
||
|
} else {
|
||
|
this._previewMenu.popup();
|
||
|
this._previewMenuManager.ignoreRelease();
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
_onHover() {
|
||
|
let scale;
|
||
|
if (this.hover) {
|
||
|
scale = 0.8;
|
||
|
} else {
|
||
|
scale = 1;
|
||
|
}
|
||
|
|
||
|
this.ease({
|
||
|
scale_x: scale,
|
||
|
scale_y: scale,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
_popupMenu() {
|
||
|
if (!this._menu) {
|
||
|
this._menu = new AppDisplay.AppIconMenu(this);
|
||
|
this._menu.connect('activate-window', (menu, window) => {
|
||
|
this.activateWindow(window); });
|
||
|
|
||
|
this._menuManager.addMenu(this._menu);
|
||
|
}
|
||
|
|
||
|
this._menu.popup();
|
||
|
this._menuManager.ignoreRelease();
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
findPreviewMenu(number) {
|
||
|
if (this._previewMenu == null)
|
||
|
return null;
|
||
|
|
||
|
let items = this._previewMenu._menuSection._getMenuItems();
|
||
|
let menuItem = items.find( (element) => {
|
||
|
return element._number == number; });
|
||
|
|
||
|
if (menuItem)
|
||
|
return menuItem._window;
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
activateWindow(metaWindow) {
|
||
|
if (metaWindow) {
|
||
|
let focusWindow = global.display.get_focus_window();
|
||
|
if (metaWindow == focusWindow)
|
||
|
metaWindow.minimize();
|
||
|
else
|
||
|
Main.activateWindow(metaWindow);
|
||
|
}
|
||
|
|
||
|
this.emit('activate-window');
|
||
|
}
|
||
|
|
||
|
animateLaunch() {
|
||
|
//Used for Icon button right click
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var ItemContainer = GObject.registerClass(
|
||
|
class ItemContainer extends St.Widget {
|
||
|
_init(app, vimMode, number, iconSize, indicator) {
|
||
|
super._init({ layout_manager: new Clutter.BinLayout(), });
|
||
|
|
||
|
let buttonBox = new St.Widget({ style_class: 'button-box',
|
||
|
layout_manager: new Clutter.BinLayout(),
|
||
|
x_expand: true,
|
||
|
y_expand: true,
|
||
|
reactive: vimMode ? false : true,
|
||
|
track_hover: vimMode ? false : true,
|
||
|
});
|
||
|
this.add_child(buttonBox);
|
||
|
|
||
|
this.app = app;
|
||
|
this.number = number;
|
||
|
|
||
|
let button = new MyAppButton(app, vimMode, number, iconSize);
|
||
|
this.button = button;
|
||
|
buttonBox.add_child(button);
|
||
|
|
||
|
switch (indicator) {
|
||
|
case 'dash':
|
||
|
this._indicator = new Indicator.Dash(iconSize);
|
||
|
break;
|
||
|
case 'dot':
|
||
|
this._indicator = new Indicator.Dot(iconSize);
|
||
|
break;
|
||
|
}
|
||
|
this.add_child(this._indicator);
|
||
|
this._indicator.show();
|
||
|
|
||
|
this._stateChangedId = this.app.connect('windows-changed', () => {
|
||
|
this._updateRunningStyle();
|
||
|
});
|
||
|
this._updateRunningStyle();
|
||
|
|
||
|
this.connect('destroy', this._onDestroy.bind(this));
|
||
|
}
|
||
|
|
||
|
_updateRunningStyle() {
|
||
|
let windows = this.app.get_windows();
|
||
|
windows = windows.filter( (window) => {
|
||
|
return Util.windowInActiveWorkspace(window);
|
||
|
});
|
||
|
this._indicator.value = windows.length;
|
||
|
}
|
||
|
|
||
|
_onDestroy() {
|
||
|
if (this._stateChangedId > 0)
|
||
|
this.app.disconnect(this._stateChangedId);
|
||
|
}
|
||
|
});
|