Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Windows support and first-class Linux support #946

Merged
merged 32 commits into from Nov 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3384442
`child_pty` => `pty.js`
matheuss Oct 27, 2016
3230ce4
Create a frameless window on Windows and Linux
matheuss Oct 28, 2016
f8a8da6
Add a brand new UI for Linux and Windows :nail_care:
matheuss Oct 30, 2016
0a35ddc
[Windows] Fix plugin installation
matheuss Oct 31, 2016
541edf1
[Windows] Fix the `build` script
matheuss Oct 31, 2016
3bf5a83
[Windows] Add a bigger `icon.ico`
matheuss Oct 31, 2016
dfc6876
[Mac] Add `WebKitAppRegion: drag` when running on macOS
matheuss Oct 31, 2016
4bf6797
Fix code style :thinking:
matheuss Oct 31, 2016
3030b13
Add `appveyor.yml`
matheuss Oct 31, 2016
4fd3275
Fix code style (again)
matheuss Oct 31, 2016
17084ff
[Windows] Fix AppVeyor's `install` script
matheuss Oct 31, 2016
0e3025b
[Windows] Try a new AppVeyor config
matheuss Oct 31, 2016
28d15df
[Windows] Set the binary path so Spectron can run the tests
matheuss Oct 31, 2016
0ff0d1b
[Windows] Try to build on x64
matheuss Oct 31, 2016
a31a20f
Try again to build on x64
matheuss Oct 31, 2016
d46a54d
Try one more time :weary:
matheuss Oct 31, 2016
99bb5e0
Throw an error to indicate that `pty.js` was built incorrectly
matheuss Oct 31, 2016
b9f945f
[Win/Linux] Add `display: hidden` to <Tabs /> if tabs.length === 1
matheuss Nov 1, 2016
a221aad
[Win/Linux] Reorganize SVGs – via @CodeTheory
matheuss Nov 5, 2016
5dae33f
[Win/Linux] Fix the hamburger menu height
matheuss Nov 7, 2016
f3314bb
Make the SVGs look better with `shape-rendering: crispEdges;`
matheuss Nov 7, 2016
325b90b
[Win/Linux] Add config options for the window controls and the :hambu…
matheuss Nov 9, 2016
316831c
Add `electron-squirrel-startup` dependency
matheuss Nov 9, 2016
117410f
[Win] Handle Squirrel commands
matheuss Nov 9, 2016
8e7ef2c
[Win/Linux] Fix default color for the :hamburger: and window controls…
matheuss Nov 9, 2016
8b944fa
[Win/Linux] Add some padding - via @CodeTheory
matheuss Nov 9, 2016
82bd606
[Win/Linux] Add hover states – via @CodeTheory
matheuss Nov 9, 2016
4055924
[Win] Fix empty window/tab titles
matheuss Nov 9, 2016
285b884
[Win] Fix opening Preferences (#978)
Nov 9, 2016
efe582f
[Win] Add dependency instructions to the README.md [skip ci]
matheuss Nov 9, 2016
8d68618
Fix code style
matheuss Nov 9, 2016
9e4bc96
[Win/Linux] Check the number of open windows before quitting the app
matheuss Nov 10, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -20,7 +20,9 @@ $ brew cask install hyper

## Contribute

1. If you are running Linux, install "icnsutils", "graphicsmagick" and "xz-utils"
1. Install the dependencies
* If you are running Linux, install `icnsutils`, `graphicsmagick` and `xz-utils`
* If you are running Windows, install [VC++ Build Tools Technical Preview](http://go.microsoft.com/fwlink/?LinkId=691126) using the **Default Install option**; Install Python 2.7 and add it to your `%PATH%`; Run `npm config set msvs_version 2015 --global`
2. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
3. Install the dependencies: `npm install`
4. Build the code, watch for changes and run the app: `npm start`
Expand Down
10 changes: 10 additions & 0 deletions app/config-default.js
Expand Up @@ -27,6 +27,16 @@ module.exports = {
// custom css to embed in the terminal window
termCSS: '',

// set to `true` if you're using a Linux set up
// that doesn't shows native menus
// default: `false` on Linux, `true` on Windows (ignored on macOS)
showHamburgerMenu: '',

// set to `false` if you want to hide the minimize, maximize and close buttons
// additionally, set to `'left'` if you want them on the left, like in Ubuntu
// default: `true` on windows and Linux (ignored on macOS)
showWindowControls: '',

// custom padding (css format, i.e.: `top right bottom left`)
padding: '12px 14px',

Expand Down
20 changes: 18 additions & 2 deletions app/index.js
@@ -1,3 +1,5 @@
// eslint-disable-next-line curly, unicorn/no-process-exit
if (require('electron-squirrel-startup')) process.exit();
// Native
const {resolve} = require('path');

Expand Down Expand Up @@ -108,9 +110,11 @@ app.on('ready', () => installDevExtensions(isDev).then(() => {
height,
minHeight: 190,
minWidth: 370,
titleBarStyle: 'hidden-inset',
titleBarStyle: 'hidden-inset', // macOS only
title: 'Hyper.app',
backgroundColor: toElectronBackgroundColor(cfg.backgroundColor || '#000'),
// we want to go frameless on windows and linux
frame: process.platform === 'darwin',
transparent: true,
icon: resolve(__dirname, 'static/icon.png'),
// we only want to show when the prompt is ready for user input
Expand Down Expand Up @@ -235,6 +239,18 @@ app.on('ready', () => installDevExtensions(isDev).then(() => {
rpc.emit('move');
});

rpc.on('open hamburger menu', ({x, y}) => {
Menu.getApplicationMenu().popup(x, y);
});

rpc.on('minimize', () => {
win.minimize();
});

rpc.on('close', () => {
win.close();
});

const deleteSessions = () => {
sessions.forEach((session, key) => {
session.removeAllListeners();
Expand Down Expand Up @@ -305,7 +321,7 @@ app.on('ready', () => installDevExtensions(isDev).then(() => {
});

win.on('closed', () => {
if (process.platform !== 'darwin') {
if (process.platform !== 'darwin' && windowSet.size === 0) {
app.quit();
}
});
Expand Down
3 changes: 2 additions & 1 deletion app/package.json
Expand Up @@ -11,18 +11,19 @@
"repository": "zeit/hyper",
"xo": false,
"dependencies": {
"child_pty": "3.0.1",
"color": "0.11.3",
"convert-css-color-name-to-hex": "0.1.1",
"default-shell": "1.0.1",
"electron-config": "0.2.1",
"electron-is-dev": "0.1.1",
"electron-squirrel-startup": "1.0.0",
"file-uri-to-path": "0.0.2",
"gaze": "1.1.2",
"git-describe": "3.0.2",
"mkdirp": "0.5.1",
"ms": "0.7.1",
"node-fetch": "1.6.3",
"pty.js": "https://github.com/Tyriar/pty.js/tarball/c75c2dcb6dcad83b0cb3ef2ae42d0448fb912642",
"semver": "5.3.0",
"shell-env": "0.2.0",
"uuid": "2.0.2"
Expand Down
2 changes: 1 addition & 1 deletion app/plugins.js
Expand Up @@ -236,7 +236,7 @@ function install(fn) {
env.npm_config_target = '1.3.0';
env.npm_config_disturl = 'https://atom.io/download/atom-shell';
/* eslint-enable camelcase */
exec('npm prune; npm install --production', {
exec('npm prune && npm install --production', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work with fish shell 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and ; don't work on Windows 😩

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add this as a script in package.json?, then && works (even in fish)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or run them with .then after each other

exec('npm prune').then(() => exec('npm install'))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, you wouldn't have to use && in package.json.

"pretarget": "npm prune",
"target": "npm install",

cwd: path,
env,
shell
Expand Down
37 changes: 21 additions & 16 deletions app/session.js
Expand Up @@ -8,16 +8,13 @@ const {getDecoratedEnv} = require('./plugins');
const {productName, version} = require('./package');
const config = require('./config');

const createPtyJsError = () => new Error('`pty.js` failed to load. Typically this means that it was built incorrectly. Please check the `README.me` to more info.');

let spawn;
try {
spawn = require('child_pty').spawn;
spawn = require('pty.js').spawn;
} catch (err) {
console.error(
'A native module failed to load. Typically this means ' +
'you installed the modules incorrectly.\n Use `scripts/install.sh` ' +
'to trigger the installation.\n ' +
'More information: https://github.com/zeit/hyper/issues/72'
);
throw createPtyJsError();
}

const envFromConfig = config.getConfig().env || {};
Expand All @@ -37,12 +34,20 @@ module.exports = class Session extends EventEmitter {

const defaultShellArgs = ['--login'];

this.pty = spawn(shell || defaultShell, shellArgs || defaultShellArgs, {
columns,
rows,
cwd,
env: getDecoratedEnv(baseEnv)
});
try {
this.pty = spawn(shell || defaultShell, shellArgs || defaultShellArgs, {
columns,
rows,
cwd,
env: getDecoratedEnv(baseEnv)
});
} catch (err) {
if (/is not a function/.test(err.message)) {
throw createPtyJsError();
} else {
throw err;
}
}

this.pty.stdout.on('data', data => {
if (this.ended) {
Expand All @@ -69,17 +74,17 @@ module.exports = class Session extends EventEmitter {
this.pty.stdin.write(data);
}

resize({cols: columns, rows}) {
resize({cols, rows}) {
try {
this.pty.stdout.resize({columns, rows});
this.pty.stdout.resize(cols, rows);
} catch (err) {
console.error(err.stack);
}
}

destroy() {
try {
this.pty.kill('SIGHUP');
this.pty.kill();
} catch (err) {
console.error('exit error', err.stack);
}
Expand Down
31 changes: 31 additions & 0 deletions appveyor.yml
@@ -0,0 +1,31 @@
# https://github.com/sindresorhus/appveyor-node/blob/master/appveyor.yml

environment:
matrix:
- platform: x64

image: Visual Studio 2015
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matheuss are you sure you need this, VS Code's appveyor.yml doesn't have anything like it? Having said that, I don't know much about how images are used in appveyor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tyriar looks like Install-Product node 6 x64 is enough 😅 I'll try to remove it later. Thanks for your concern!


init:
- npm config set msvs_version 2015 # we need this to build `pty.js`

cache:
- node_modules

install:
- ps: Install-Product node 6 x64
- set CI=true
- npm -g install npm@latest
- npm install

build: off

shallow_clone: true

test_script:
- node --version
- npm --version
- npm run test

on_success:
- npm run dist
44 changes: 42 additions & 2 deletions assets/icons.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified build/icon.ico
Binary file not shown.
35 changes: 34 additions & 1 deletion lib/actions/header.js
@@ -1,5 +1,5 @@
import {CLOSE_TAB, CHANGE_TAB} from '../constants/tabs';
import {UI_WINDOW_MAXIMIZE, UI_WINDOW_UNMAXIMIZE} from '../constants/ui';
import {UI_WINDOW_MAXIMIZE, UI_WINDOW_UNMAXIMIZE, UI_OPEN_HAMBURGER_MENU, UI_WINDOW_MINIMIZE, UI_WINDOW_CLOSE} from '../constants/ui';
import rpc from '../rpc';
import {userExitTermGroup, setActiveGroup} from './term-groups';

Expand Down Expand Up @@ -48,3 +48,36 @@ export function unmaximize() {
});
};
}

export function openHamburgerMenu(coordinates) {
return dispatch => {
dispatch({
type: UI_OPEN_HAMBURGER_MENU,
effect() {
rpc.emit('open hamburger menu', coordinates);
}
});
};
}

export function minimize() {
return dispatch => {
dispatch({
type: UI_WINDOW_MINIMIZE,
effect() {
rpc.emit('minimize');
}
});
};
}

export function close() {
return dispatch => {
dispatch({
type: UI_WINDOW_CLOSE,
effect() {
rpc.emit('close');
}
});
};
}
19 changes: 12 additions & 7 deletions lib/actions/ui.js
Expand Up @@ -201,7 +201,12 @@ export function moveTo(i) {
}

export function showPreferences() {
const editorFallback = process.platform === 'win32' ? 'notepad' : 'nano';
// eslint-disable-next-line no-template-curly-in-string
const command = process.platform === 'win32' ? ' start notepad "%userprofile%\\.hyper.js"' : ' bash -c \'exec env ${EDITOR:=nano} ~/.hyper.js\'';
const message = process.platform === 'win32' ?
' echo Attempting to open ^%userprofile^%\\.hyper.js with notepad' :
' echo Attempting to open ~/.hyper.js with your \$EDITOR'; // eslint-disable-line no-useless-escape

return dispatch => {
dispatch({
type: UI_SHOW_PREFERENCES,
Expand All @@ -212,12 +217,12 @@ export function showPreferences() {
rpc.once('session data', () => {
dispatch(sendSessionData(
uid,
// Leading space prevents command to be stored in shell history
[' echo Attempting to open ~/.hyper.js with your \$EDITOR', // eslint-disable-line no-useless-escape
' echo If it fails, open it manually with your favorite editor!',
' bash -c \'exec env ${EDITOR:=' + editorFallback + '} ~/.hyper.js\'',
''
].join('\n')
[ // Leading space prevents command to be stored in shell history
' echo Attempting to open ~/.hyper.js with your \$EDITOR', // eslint-disable-line no-useless-escape
message,
command,
''
].join('\n\r')
));
});
});
Expand Down