Add window bgcolor updates (#524)

* transparent + reactive background colors

* refactor header to not set its own background color

* make terms not set background color

* dramatically improve tab borders

* remove background color from electron windows

* Revert "remove background color from electron windows"

This reverts commit ca4de3c5dc28095f1a598f7ac79d4dff4b66ccd5.

* put alpha first for electron

* remove initial bg color setting, but maintain reactive one

* fix
This commit is contained in:
Guillermo Rauch 2016-09-19 08:47:33 +02:00 committed by GitHub
parent 61f9c587ad
commit 8a01f8a48b
8 changed files with 59 additions and 37 deletions

View file

@ -7,7 +7,7 @@ const { parse: parseUrl } = require('url');
const fileUriToPath = require('file-uri-to-path'); const fileUriToPath = require('file-uri-to-path');
const isDev = require('electron-is-dev'); const isDev = require('electron-is-dev');
const AutoUpdater = require('./auto-updater'); const AutoUpdater = require('./auto-updater');
const toHex = require('convert-css-color-name-to-hex'); const toElectronBackgroundColor = require('./utils/to-electron-background-color');
const notify = require('./notify'); const notify = require('./notify');
app.commandLine.appendSwitch('js-flags', '--harmony'); app.commandLine.appendSwitch('js-flags', '--harmony');
@ -87,7 +87,7 @@ app.on('ready', () => {
minWidth: 370, minWidth: 370,
titleBarStyle: 'hidden-inset', titleBarStyle: 'hidden-inset',
title: 'HyperTerm', title: 'HyperTerm',
backgroundColor: toHex(cfg.backgroundColor || '#000'), backgroundColor: toElectronBackgroundColor(cfg.backgroundColor || '#000'),
transparent: true, transparent: true,
icon: resolve(__dirname, 'static/icon.png'), icon: resolve(__dirname, 'static/icon.png'),
// we only want to show when the prompt // we only want to show when the prompt
@ -110,8 +110,10 @@ app.on('ready', () => {
const cfgUnsubscribe = config.subscribe(() => { const cfgUnsubscribe = config.subscribe(() => {
const cfg_ = plugins.getDecoratedConfig(); const cfg_ = plugins.getDecoratedConfig();
// notify renderer
win.webContents.send('config change'); win.webContents.send('config change');
// notify user that shell changes require new sessions
if (cfg_.shell !== cfg.shell || cfg_.shellArgs !== cfg.shellArgs) { if (cfg_.shell !== cfg.shell || cfg_.shellArgs !== cfg.shellArgs) {
notify( notify(
'Shell configuration changed!', 'Shell configuration changed!',
@ -119,6 +121,9 @@ app.on('ready', () => {
); );
} }
// update background color if necessary
win.setBackgroundColor(toElectronBackgroundColor(cfg_.backgroundColor || '#000'));
cfg = cfg_; cfg = cfg_;
}); });

View file

@ -0,0 +1,14 @@
const Color = require('color');
// returns a background color that's in hex
// format including the alpha channel (e.g.: `#00000050`)
// input can be any css value (rgb, hsl, string…)
module.exports = function toElectronBackgroundColor (bgColor) {
const color = Color(bgColor);
if (1 !== color.alpha()) {
// (╯°□°)╯︵ ┻━┻
return '#' + Math.floor(color.alpha() * 100) + color.hexString().substr(1);
} else {
return color.hexString();
}
};

View file

@ -65,7 +65,7 @@ export default class Header extends Component {
} }
template (css) { template (css) {
const { isMac, backgroundColor } = this.props; const { isMac } = this.props;
const props = getTabsProps(this.props, { const props = getTabsProps(this.props, {
tabs: this.props.tabs, tabs: this.props.tabs,
borderColor: this.props.borderColor, borderColor: this.props.borderColor,
@ -73,7 +73,6 @@ export default class Header extends Component {
onChange: this.onChangeIntent onChange: this.onChangeIntent
}); });
return <header return <header
style={{ backgroundColor }}
className={ css('header', isMac && 'headerRounded') } className={ css('header', isMac && 'headerRounded') }
onClick={ this.onHeaderClick } onClick={ this.onHeaderClick }
onMouseDown={ this.onHeaderMouseDown }> onMouseDown={ this.onHeaderMouseDown }>
@ -90,7 +89,6 @@ export default class Header extends Component {
top: '1px', top: '1px',
left: '1px', left: '1px',
right: '1px', right: '1px',
background: '#000',
zIndex: '100' zIndex: '100'
}, },

View file

@ -44,6 +44,7 @@ export default class Tab extends Component {
'tab', 'tab',
isFirst && 'first', isFirst && 'first',
isActive && 'active', isActive && 'active',
isFirst && isActive && 'firstActive',
hasActivity && 'hasActivity' hasActivity && 'hasActivity'
) }> ) }>
{ this.props.customChildrenBefore } { this.props.customChildrenBefore }
@ -76,6 +77,11 @@ export default class Tab extends Component {
return { return {
tab: { tab: {
color: '#ccc', color: '#ccc',
borderColor: '#ccc',
borderBottomWidth: 1,
borderBottomStyle: 'solid',
borderLeftWidth: 1,
borderLeftStyle: 'solid',
listStyleType: 'none', listStyleType: 'none',
flexGrow: 1, flexGrow: 1,
position: 'relative', position: 'relative',
@ -85,20 +91,18 @@ export default class Tab extends Component {
}, },
first: { first: {
marginLeft: process.platform === 'darwin' ? 76 : 0 borderLeftWidth: 0,
paddingLeft: 1
},
firstActive: {
borderLeftWidth: 1,
paddingLeft: 0
}, },
active: { active: {
color: '#fff', color: '#fff',
':before': { borderBottomWidth: 0,
position: 'absolute',
content: '" "',
borderBottom: '1px solid #000',
display: 'block',
left: '0px',
right: '0px',
bottom: '-1px'
},
':hover': { ':hover': {
color: '#fff' color: '#fff'
} }
@ -117,8 +121,6 @@ export default class Tab extends Component {
display: 'block', display: 'block',
width: '100%', width: '100%',
position: 'relative', position: 'relative',
borderLeft: '1px solid transparent',
borderRight: '1px solid transparent',
overflow: 'hidden' overflow: 'hidden'
}, },
@ -131,14 +133,6 @@ export default class Tab extends Component {
textAlign: 'center' textAlign: 'center'
}, },
textLast: {
borderRightWidth: 0
},
textActive: {
borderColor: 'inherit'
},
icon: { icon: {
transition: `opacity .2s ease, color .2s ease, transition: `opacity .2s ease, color .2s ease,
transform .25s ease, background-color .1s ease`, transform .25s ease, background-color .1s ease`,

View file

@ -4,6 +4,7 @@ import Component from '../component';
import { decorate, getTabProps } from '../utils/plugins'; import { decorate, getTabProps } from '../utils/plugins';
const Tab = decorate(Tab_, 'Tab'); const Tab = decorate(Tab_, 'Tab');
const isMac = /Mac/.test(navigator.userAgent);
export default class Tabs extends Component { export default class Tabs extends Component {
@ -21,8 +22,8 @@ export default class Tabs extends Component {
tabs.length tabs.length
? 1 === tabs.length ? 1 === tabs.length
? <div className={ css('title') }>{ tabs[0].title }</div> ? <div className={ css('title') }>{ tabs[0].title }</div>
: <ul : [
style={{ borderColor }} <ul
className={ css('list') }> className={ css('list') }>
{ {
tabs.map((tab, i) => { tabs.map((tab, i) => {
@ -40,7 +41,11 @@ export default class Tabs extends Component {
return <Tab key={`tab-${uid}`} {...props} />; return <Tab key={`tab-${uid}`} {...props} />;
}) })
} }
</ul> </ul>,
isMac && <div
style={{ borderColor }}
className={ css('borderShim') }></div>
]
: null : null
} }
{ this.props.customChildren } { this.props.customChildren }
@ -60,6 +65,7 @@ export default class Tabs extends Component {
verticalAlign: 'middle', verticalAlign: 'middle',
color: '#9B9B9B', color: '#9B9B9B',
cursor: 'default', cursor: 'default',
position: 'relative',
WebkitUserSelect: 'none', WebkitUserSelect: 'none',
WebkitAppRegion: 'drag' WebkitAppRegion: 'drag'
}, },
@ -70,10 +76,19 @@ export default class Tabs extends Component {
}, },
list: { list: {
borderBottom: '1px solid #333',
maxHeight: '34px', maxHeight: '34px',
display: 'flex', display: 'flex',
flexFlow: 'row' flexFlow: 'row',
marginLeft: isMac ? 76 : 0
},
borderShim: {
position: 'absolute',
width: '76px',
bottom: 0,
borderColor: '#ccc',
borderBottomStyle: 'solid',
borderBottomWidth: '1px'
} }
}; };
} }

View file

@ -32,7 +32,7 @@ export default class Term extends Component {
this.term.prefs_.set('cursor-color', this.validateColor(props.cursorColor, 'rgba(255,255,255,0.5)')); this.term.prefs_.set('cursor-color', this.validateColor(props.cursorColor, 'rgba(255,255,255,0.5)'));
this.term.prefs_.set('enable-clipboard-notice', false); this.term.prefs_.set('enable-clipboard-notice', false);
this.term.prefs_.set('foreground-color', props.foregroundColor); this.term.prefs_.set('foreground-color', props.foregroundColor);
this.term.prefs_.set('background-color', props.backgroundColor); this.term.prefs_.set('background-color', 'transparent');
this.term.prefs_.set('color-palette-overrides', getColorList(props.colors)); this.term.prefs_.set('color-palette-overrides', getColorList(props.colors));
this.term.prefs_.set('user-css', this.getStylesheet(props.customCSS)); this.term.prefs_.set('user-css', this.getStylesheet(props.customCSS));
this.term.prefs_.set('scrollbar-visible', false); this.term.prefs_.set('scrollbar-visible', false);
@ -202,10 +202,6 @@ export default class Term extends Component {
this.term.prefs_.set('foreground-color', nextProps.foregroundColor); this.term.prefs_.set('foreground-color', nextProps.foregroundColor);
} }
if (this.props.backgroundColor !== nextProps.backgroundColor) {
this.term.prefs_.set('background-color', nextProps.backgroundColor);
}
if (this.props.fontFamily !== nextProps.fontFamily) { if (this.props.fontFamily !== nextProps.fontFamily) {
this.term.prefs_.set('font-family', nextProps.fontFamily); this.term.prefs_.set('font-family', nextProps.fontFamily);
} }

View file

@ -136,7 +136,6 @@ export default class Terms extends Component {
fontFamily: this.props.fontFamily, fontFamily: this.props.fontFamily,
fontSmoothing: this.props.fontSmoothing, fontSmoothing: this.props.fontSmoothing,
foregroundColor: this.props.foregroundColor, foregroundColor: this.props.foregroundColor,
backgroundColor: this.props.backgroundColor,
colors: this.props.colors, colors: this.props.colors,
url: session.url, url: session.url,
cleared: session.cleared, cleared: session.cleared,

View file

@ -13,12 +13,13 @@ class HyperTerm extends Component {
constructor (props) { constructor (props) {
super(props); super(props);
this.focusActive = this.focusActive.bind(this); this.focusActive = this.focusActive.bind(this);
document.body.style.backgroundColor = props.backgroundColor;
this.onTermsRef = this.onTermsRef.bind(this); this.onTermsRef = this.onTermsRef.bind(this);
} }
componentWillReceiveProps (next) { componentWillReceiveProps (next) {
if (this.props.backgroundColor !== next.backgroundColor) { if (this.props.backgroundColor !== next.backgroundColor) {
// this can be removed when `setBackgroundColor` in electron
// starts working again
document.body.style.backgroundColor = next.backgroundColor; document.body.style.backgroundColor = next.backgroundColor;
} }
} }