PaperWM/liveAltTab.js
2021-01-31 17:57:26 +01:00

181 lines
6.2 KiB
JavaScript

var Extension;
if (imports.misc.extensionUtils.extensions) {
Extension = imports.misc.extensionUtils.extensions["paperwm@hedning:matrix.org"];
} else {
Extension = imports.ui.main.extensionManager.lookup("paperwm@hedning:matrix.org");
}
var Clutter = imports.gi.Clutter;
var Meta = imports.gi.Meta;
var AltTab = imports.ui.altTab;
var Main = imports.ui.main;
var Tweener = Extension.imports.utils.tweener;
var Gio = imports.gi.Gio;
var Scratch = Extension.imports.scratch;
var Tiling = Extension.imports.tiling;
var Keybindings = Extension.imports.keybindings;
var utils = Extension.imports.utils;
var debug = utils.debug;
var prefs = Extension.imports.settings.prefs;
var switcherSettings = new Gio.Settings({
schema_id: 'org.gnome.shell.window-switcher'
})
var LiveAltTab = utils.registerClass(
class LiveAltTab extends AltTab.WindowSwitcherPopup {
_init(reverse) {
this.reverse = reverse;
super._init();
}
_getWindowList(reverse) {
let tabList = global.display.get_tab_list(
Meta.TabList.NORMAL_ALL,
switcherSettings.get_boolean('current-workspace-only') ?
global.workspace_manager.get_active_workspace() : null)
.filter(w => !Scratch.isScratchWindow(w));
let scratch = Scratch.getScratchWindows();
if (Scratch.isScratchWindow(global.display.focus_window)) {
// Access scratch windows in mru order with shift-super-tab
return scratch.concat(this.reverse ? tabList.reverse() : tabList);
} else {
return tabList.concat(this.reverse ? scratch.reverse() : scratch);
}
}
_initialSelection(backward, actionName) {
this.space = Tiling.spaces.selectedSpace;
this.space.startAnimate();
let monitor = Tiling.spaces.selectedSpace.monitor;
let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
let fog = new Clutter.Actor({x: workArea.x, y: workArea.y,
width: workArea.width, height: workArea.height,
opacity: 0, background_color: Clutter.color_from_string("black")[1]
});
// this.blur = new Clutter.BlurEffect();
// this.space.cloneContainer.add_effect(this.blur);
this.space.setSelectionInactive();
Main.uiGroup.insert_child_above(fog, global.window_group);
Tweener.addTween(fog, {
time: prefs.animation_time,
opacity: 100,
});
this.fog = fog;
super._initialSelection(backward, actionName);
}
_keyPressHandler(keysym, mutterActionId) {
if (keysym === Clutter.KEY_Escape)
return Clutter.EVENT_PROPAGATE;
// After the first super-tab the mutterActionId we get is apparently
// SWITCH_APPLICATIONS so we need to case on those too.
switch(mutterActionId) {
case Meta.KeyBindingAction.SWITCH_APPLICATIONS:
mutterActionId = Meta.KeyBindingAction.SWITCH_WINDOWS;
break;
case Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD:
mutterActionId = Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD;
break;
case Keybindings.idOf('live-alt-tab'):
mutterActionId = Meta.KeyBindingAction.SWITCH_WINDOWS;
break;
;;
case Keybindings.idOf('live-alt-tab-backward'):
mutterActionId = Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD;
break;
;;
}
// let action = Keybindings.byId(mutterActionId);
// if (action && action.options.activeInNavigator) {
// let space = Tiling.spaces.selectedSpace;
// let metaWindow = space.selectedWindow;
// action.handler(metaWindow, space);
// return true;
// }
return super._keyPressHandler(keysym, mutterActionId);
}
_select(num) {
let from = this._switcherList.windows[this._selectedIndex];
let to = this._switcherList.windows[num];
this.clone && this.clone.destroy();
this.clone = null;
let actor = to.get_compositor_private();
actor.remove_clip();
let frame = to.get_frame_rect();
let clone = new Clutter.Clone({source: actor});
clone.position = actor.position;
let space = Tiling.spaces.spaceOfWindow(to);
if (space.indexOf(to) !== -1) {
clone.x = Tiling.ensuredX(to, space) + space.monitor.x;
clone.x -= frame.x - actor.x;
}
this.clone = clone;
Main.uiGroup.insert_child_above(clone, this.fog);
// Tiling.ensureViewport(to, space);
this._selectedIndex = num;
this._switcherList.highlight(num);
}
_finish() {
this.was_accepted = true;
super._finish();
}
_itemEnteredHandler() {
// The item-enter (mouse hover) event is triggered even after a item is
// accepted. This can cause _select to run on the item below the pointer
// ensuring the wrong window.
if(!this.was_accepted) {
super._itemEnteredHandler.apply(this, arguments);
}
}
_onDestroy() {
super._onDestroy();
debug('#preview', 'onDestroy', this.was_accepted);
Tweener.addTween(this.fog, {
time: prefs.animation_time,
opacity: 0,
onStopped: () => {
this.fog.destroy();
this.fog = null;
// this.space.cloneContainer.remove_effect(this.blur);
this.clone && this.clone.destroy();
this.clone = null;
this.space.moveDone();
}
});
let index = this.was_accepted ? this._selectedIndex : 0
let to = this._switcherList.windows[index];
Tiling.focus_handler(to);
let actor = to.get_compositor_private();
if (this.was_accepted) {
actor.x = this.clone.x;
actor.y = this.clone.y;
}
actor.set_scale(1, 1);
}
});
function liveAltTab(meta_window, space, {display, screen, binding}) {
let tabPopup = new LiveAltTab(binding.is_reversed());
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
}