PaperWM/liveAltTab.js
2018-11-26 17:50:56 +01:00

125 lines
4.2 KiB
JavaScript

var Extension = imports.misc.extensionUtils.extensions['paperwm@hedning:matrix.org'];
var Clutter = imports.gi.Clutter;
var Lang = imports.lang;
var Meta = imports.gi.Meta;
var AltTab = imports.ui.altTab;
var Main = imports.ui.main;
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 LiveAltTab = Lang.Class({
Name: 'LiveAltTab',
Extends: AltTab.WindowSwitcherPopup,
_getWindowList: function () {
let tabList = global.display.get_tab_list(
Meta.TabList.NORMAL_ALL,
global.workspace_manager.get_active_workspace())
.filter(w => !Scratch.isScratchWindow(w));
let scratch = Scratch.getScratchWindows();
if (Scratch.isScratchActive()) {
return scratch.concat(tabList);
} else {
// Access scratch windows in mru order with shift-super-tab
return tabList.concat(scratch.reverse());
}
},
_initialSelection: function(backward, actionName) {
this._block = Main.wm._blockAnimations;
Main.wm._blockAnimations = true;
this.parent(backward, actionName);
},
_keyPressHandler: function(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 this.parent(keysym, mutterActionId);
},
_select: function(num) {
let from = this._switcherList.windows[this._selectedIndex];
let to = this._switcherList.windows[num];
this.clone && this.clone.destroy();
// Show pseudo focused scratch windows
if (Scratch.isScratchWindow(to)) {
let actor = to.get_compositor_private();
let clone = new Clutter.Clone({source: actor});
clone.position = actor.position;
this.clone = clone;
Main.uiGroup.add_child(clone);
// Raise the switcherpopup to the top
Main.uiGroup.set_child_above_sibling(this.actor, clone);
}
let space = Tiling.spaces.spaceOfWindow(to);
Tiling.ensureViewport(to, space);
this._selectedIndex = num;
this._switcherList.highlight(num);
},
_finish: function() {
this.parent();
this.was_accepted = true;
},
_itemEnteredHandler: function() {
// 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) {
this.parent.apply(this, arguments);
}
},
_onDestroy: function() {
debug('#preview', 'onDestroy', this.was_accepted);
Main.wm._blockAnimations = this._block;
if(!this.was_accepted) {
// Select the starting window
this._select(0);
}
this.clone && this.clone.destroy();
this.parent();
}
})
function liveAltTab(meta_window, space, {display, screen, binding}) {
let tabPopup = new LiveAltTab();
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
}