var Extension = imports.misc.extensionUtils.getCurrentExtension(); var Keybindings = Extension.imports.keybindings; var Main = imports.ui.main; var Tiling = Extension.imports.tiling; var Scratch = Extension.imports.scratch; /** To use an example as-is ("gotoByIndex" for instance) add the following to the `init` function in "user.js": Extension.imports.examples.keybindings.gotoByIndex(); */ function gotoByIndex() { function goto(k) { return () => { let space = Tiling.spaces.get(global.workspace_manager.get_active_workspace()); let metaWindow = space.getWindow(k, 0) if (!metaWindow) return; if (metaWindow.has_focus()) { // Can happen when navigator is open Tiling.ensureViewport(metaWindow); } else { Main.activateWindow(metaWindow); } } } for(let k = 1; k <= 9; k++) { Keybindings.bindkey(`${k}`, `goto-coloumn-${k}`, goto(k-1), {activeInNavigator: true}) } } function windowMarks() { const Meta = imports.gi.Meta; var marks = {} function setMark(k) { return (mw) => marks[k] = mw } function gotoMark(k) { return (metaWindow, space, options) => { let mark = marks[k]; if (!mark) return; if (mark.has_focus()) { // Can happen when navigator is open Tiling.ensureViewport(mark); if (!options.navigator) { let mru = global.display.get_tab_list( Meta.TabList.NORMAL_ALL, null); let nextWindow = mru[1]; if (!nextWindow) return; Main.activateWindow(nextWindow); if (Scratch.isScratchWindow(mark) && !Scratch.isScratchWindow(nextWindow)) { Scratch.hide(); } } } else { Main.activateWindow(mark); } } } for(let k = 0; k <= 9; k++) { Keybindings.bindkey(`${k}`, `goto-mark-${k}`, gotoMark(k), {activeInNavigator: true}) Keybindings.bindkey(`${k}`, `set-mark-${k}`, setMark(k), {activeInNavigator: true}) } } function swapNeighbours(binding = "y") { var Tiling = Extension.imports.tiling; var Meta = imports.gi.Meta; Keybindings.bindkey(binding, "swap-neighbours", (mw) => { let space = Tiling.spaces.spaceOfWindow(mw) let i = space.indexOf(mw); if (space[i+1]) { space.swap(Meta.MotionDirection.RIGHT, space[i+1][0]) } }, {activeInNavigator: true}) } function cycleMonitor(binding = "d") { var Tiling = Extension.imports.tiling; var Main = imports.ui.main; Keybindings.bindkey(binding, "cycle-monitor", () => { let curMonitor = Tiling.spaces.selectedSpace.monitor let monitors = Main.layoutManager.monitors; let nextMonitorI = (curMonitor.index + 1) % monitors.length; let nextMonitor = monitors[nextMonitorI]; let nextSpace = Tiling.spaces.monitors.get(nextMonitor); if (nextSpace) { nextSpace.workspace.activate(global.get_current_time()); } }); } /** Cycle the workspace settings bound to the current workspace. (among the unused settings) NB: Only relevant when using dynamic workspaces. */ function cycleWorkspaceSettings(binding = "q") { var Tiling = Extension.imports.tiling; var Settings = Extension.imports.settings; var Utils = Extension.imports.utils; Keybindings.bindkey( binding, "next-space-setting", mw => Tiling.cycleWorkspaceSettings(-1), { activeInNavigator: true } ); Keybindings.bindkey( ""+binding, "prev-space-setting", mw => Tiling.cycleWorkspaceSettings(1), { activeInNavigator: true } ); } function showNavigator(binding = "j") { Keybindings.bindkey(binding, "show-minimap", () => null, { opensMinimap: true }) } // listFreeBindings("").join("\n") function listFreeBindings(modifierString) { let free = []; const chars = "abcdefghijklmnopqrstuvxyz1234567890".split("") const symbols = ["minus", "comma", "period", "plus"] return [].concat(chars, symbols).filter( key => Keybindings.getBoundActionId(modifierString+key) === 0 ).map(key => modifierString+key) } function moveSpaceToMonitor(basebinding = '') { let Meta = imports.gi.Meta; let display = global.display; function moveTo(direction) { let Navigator = Extension.imports.navigator; let spaces = Tiling.spaces; let currentSpace = spaces.selectedSpace; let monitor = currentSpace.monitor; let i = display.get_monitor_neighbor_index(monitor.index, direction); let opposite; switch (direction) { case Meta.DisplayDirection.RIGHT: opposite = Meta.DisplayDirection.LEFT; break; case Meta.DisplayDirection.LEFT: opposite = Meta.DisplayDirection.RIGHT; break; case Meta.DisplayDirection.UP: opposite = Meta.DisplayDirection.DOWN; break; case Meta.DisplayDirection.DOWN: opposite = Meta.DisplayDirection.UP; break; } let n = i; if (i === -1) { let i = monitor.index; while (i !== -1) { n = i; i = display.get_monitor_neighbor_index(n, opposite); } } let next = spaces.monitors.get(Main.layoutManager.monitors[n]); currentSpace.setMonitor(next.monitor); spaces.monitors.set(next.monitor, currentSpace); next.setMonitor(monitor); spaces.monitors.set(monitor, next); // This is pretty hacky spaces.switchWorkspace(null, currentSpace.workspace.index(), currentSpace.workspace.index()); } for (let arrow of ['Down', 'Left', 'Up', 'Right']) { Keybindings.bindkey(`${basebinding}${arrow}`, `move-space-monitor-${arrow}`, () => { moveTo(Meta.DisplayDirection[arrow.toUpperCase()]); }); } } /** "KP_Add" and "KP_Subtract" to use the numpad keys */ function adjustWidth(incBinding="plus", decBinding="minus", increment=50) { function adjuster(delta) { return mw => { if (!mw) return; const f = mw.get_frame_rect(); mw.move_resize_frame(true, f.x, f.y, f.width + delta, f.height); } } Keybindings.bindkey(incBinding, "inc-width", adjuster(increment)); Keybindings.bindkey(decBinding, "dec-width", adjuster(-increment)); } function tileInto(leftBinding="less", rightBinding="less") { // less: '<' let Tiling = Extension.imports.tiling; const tileIntoDirection = (dir=-1) => (metaWindow) => { let space = Tiling.spaces.spaceOfWindow(metaWindow); let jFrom = space.indexOf(metaWindow); let jTo = jFrom + dir; if (jTo < 0 || jTo >= space.length) return; space[jFrom].splice(space.rowOf(metaWindow), 1); space[jTo].push(metaWindow); if (space[jFrom].length === 0) { space.splice(jFrom, 1); } space.layout(true, { customAllocators: { [space.indexOf(metaWindow)]: Tiling.allocateEqualHeight } }); space.emit("full-layout"); } let options = { activeInNavigator: true }; if (leftBinding) Keybindings.bindkey(leftBinding, "tile-into-left-column", tileIntoDirection(-1), options); if (rightBinding) Keybindings.bindkey(rightBinding, "tile-into-right-column", tileIntoDirection(1), options); }