UNPKG

nwm

Version:

Dynamic window manager for X11

256 lines (236 loc) 7.68 kB
module.exports = function(dependencies) { // modules var NWM = dependencies.NWM, XK = dependencies.keysymdef, Xh = dependencies.Xh, child_process = require('child_process'), which = dependencies.which; // instantiate nwm and configure it var nwm = new NWM(); // resolved using node-which from a preset list, see bottom of the file var bestAvailableTerm = 'xterm'; // load layouts var layouts = dependencies.layouts; nwm.addLayout('tile', layouts.tile); nwm.addLayout('monocle', layouts.monocle); nwm.addLayout('wide', layouts.wide); nwm.addLayout('grid', layouts.grid); // convinience functions for writing the keyboard shortcuts function currentMonitor() { return nwm.monitors.get(nwm.monitors.current); } function moveToMonitor(window, currentMonitor, otherMonitorId) { if (window) { window.monitor = otherMonitorId; // set the workspace to the current workspace on that monitor var otherMonitor = nwm.monitors.get(otherMonitorId); window.workspace = otherMonitor.workspaces.current; // rearrange both monitors currentMonitor.workspaces.get(currentMonitor.workspaces.current).rearrange(); otherMonitor.workspaces.get(otherMonitor.workspaces.current).rearrange(); } } function resizeWorkspace(increment) { var workspace = currentMonitor().currentWorkspace(); workspace.setMainWindowScale(workspace.getMainWindowScale() + increment); workspace.rearrange(); } // KEYBOARD SHORTCUTS // Change the base modifier to your liking e.g. Xh.Mod4Mask if you just want to use the meta key without Ctrl var baseModifier = Xh.Mod4Mask; // Win key if (process.argv.indexOf('--xephyr') > -1) { baseModifier = Xh.Mod4Mask | Xh.ControlMask; // Win + Ctrl } var envWithLang = JSON.parse(JSON.stringify(process.env)); envWithLang.LANGUAGE = 'en_US.utf8'; envWithLang.LANG = 'en_US.utf8'; envWithLang.LC_ALL = 'en_US.utf8'; function exec(command, onErr) { var term = child_process.spawn(command, [], { env: envWithLang }); term.stderr.setEncoding('utf8'); term.stderr.on('data', function(data) { if (/^execvp\(\)/.test(data)) { if (onErr) { onErr(); } } }); } var keyboard_shortcuts = [ { key: [1, 2, 3, 4, 5, 6, 7, 8, 9], // number keys are used to move between screens callback: function(event) { currentMonitor().go(String.fromCharCode(event.keysym)); } }, { key: [1, 2, 3, 4, 5, 6, 7, 8, 9], // with shift, move windows between workspaces modifier: ['shift'], callback: function(event) { var monitor = currentMonitor(); monitor.windowTo(monitor.focused_window, String.fromCharCode(event.keysym)); } }, { key: 'Return', // enter key launches xterm modifier: ['shift'], callback: function(event) { exec(bestAvailableTerm); } }, { key: 'c', // c key closes the current window modifier: ['shift'], callback: function(event) { var monitor = currentMonitor(); if (monitor.focused_window) { nwm.wm.killWindow(monitor.focused_window); } } }, { key: 'space', // space switches between layout modes callback: function(event) { var monitor = currentMonitor(); var workspace = monitor.currentWorkspace(); workspace.layout = nwm.nextLayout(workspace.layout); // monocle hides windows in the current workspace, so unhide them monitor.go(monitor.workspaces.current); workspace.rearrange(); } }, { key: ['h', 'F10'], // shrink master area callback: function(event) { resizeWorkspace(-5); } }, { key: ['l', 'F11'], // grow master area callback: function(event) { resizeWorkspace(+5); } }, { key: 'Tab', // tab makes the current window the main window callback: function(event) { var monitor = currentMonitor(); var workspace = monitor.currentWorkspace(); workspace.mainWindow = monitor.focused_window; workspace.rearrange(); } }, { key: 'comma', // moving windows between monitors modifier: ['shift'], callback: function(event) { var monitor = currentMonitor(); var window = nwm.windows.get(monitor.focused_window); if (window) { // empty if no windows moveToMonitor(window, monitor, nwm.monitors.next(window.monitor)); } } }, { key: 'period', // moving windows between monitors modifier: ['shift'], callback: function(event) { var monitor = currentMonitor(); var window = nwm.windows.get(monitor.focused_window); if (window) { // empty if no windows moveToMonitor(window, monitor, nwm.monitors.prev(window.monitor)); } } }, { key: 'j', // moving focus callback: function() { var monitor = currentMonitor(); if (monitor.focused_window && nwm.windows.exists(monitor.focused_window)) { var window = nwm.windows.get(monitor.focused_window); do { var previous = nwm.windows.prev(window.id); window = nwm.windows.get(previous); } while (window.workspace != monitor.workspaces.current); console.log('Current', monitor.focused_window, 'previous', window.id); monitor.focused_window = window.id; nwm.wm.focusWindow(window.id); } } }, { key: 'k', // moving focus callback: function() { var monitor = currentMonitor(); if (monitor.focused_window && nwm.windows.exists(monitor.focused_window)) { var window = nwm.windows.get(monitor.focused_window); do { var next = nwm.windows.next(window.id); window = nwm.windows.get(next); } while (window.workspace != monitor.workspaces.current); console.log('Current', monitor.focused_window, 'next', window.id); monitor.focused_window = window.id; nwm.wm.focusWindow(monitor.focused_window); } } }, { key: 'q', // quit modifier: ['shift'], callback: function() { process.exit(); } }, { key: 'BackSpace', callback: function() { currentMonitor().goBack(); } } ]; // take each of the keyboard shortcuts above and make add a key using nwm.addKey keyboard_shortcuts.forEach(function(shortcut) { var callback = shortcut.callback; var modifier = baseModifier; // translate the modifier array to a X11 modifier if (shortcut.modifier) { if (shortcut.modifier.indexOf('shift') > -1) { modifier = modifier | Xh.ShiftMask; } if (shortcut.modifier.indexOf('ctrl') > -1) { modifier = modifier | Xh.ControlMask; } } // add shortcuts if (Array.isArray(shortcut.key)) { shortcut.key.forEach(function(key) { nwm.addKey({ key: XK[key], modifier: modifier }, callback); }); } else { nwm.addKey({ key: XK[shortcut.key], modifier: modifier }, callback); } }); // START var terms = [ 'sakura', 'rxvt', 'urxvt', 'xterm' ]; function findTerm(onDone) { var name = terms.shift(); which(name, function(err, filepath) { if (err || !filepath) { findTerm(onDone); } else { onDone(null, name); } }); } findTerm(function(err, term) { bestAvailableTerm = term; nwm.start(function() {}); }); };