Dynamically change the font-smoothing pref (#205)

* Dynamically change the `font-smoothing` pref

By default, hterm defaults to `font-smoothing: 'antialiased'`, which
works really well on retina displays. On non-retina displays, however,
the type looks very thin and is hard to read.

This will look at the devicePixelRatio of the device anytime the term
prefs are set, and change between `antialiased` and
`subpixel-antialiased` dynamically.

* Refactor to add the font smoothing override into state

This also subscribes to the electron `move` event to control when this
piece of state gets updated.

* Add UI_WINDOW_MOVE action with a side effect for font smoothing
This commit is contained in:
Mike 2016-07-19 12:30:57 -06:00 committed by Guillermo Rauch
parent 961a39e8f3
commit b76e004309
8 changed files with 54 additions and 2 deletions

View file

@ -11,10 +11,12 @@ import {
UI_FONT_SIZE_INCR, UI_FONT_SIZE_INCR,
UI_FONT_SIZE_DECR, UI_FONT_SIZE_DECR,
UI_FONT_SIZE_RESET, UI_FONT_SIZE_RESET,
UI_FONT_SMOOTHING_SET,
UI_MOVE_LEFT, UI_MOVE_LEFT,
UI_MOVE_RIGHT, UI_MOVE_RIGHT,
UI_MOVE_TO, UI_MOVE_TO,
UI_SHOW_PREFERENCES UI_SHOW_PREFERENCES,
UI_WINDOW_MOVE
} from '../constants/ui'; } from '../constants/ui';
export function increaseFontSize () { export function increaseFontSize () {
@ -57,6 +59,18 @@ export function resetFontSize () {
}; };
} }
export function setFontSmoothing () {
const devicePixelRatio = window.devicePixelRatio;
const fontSmoothing = devicePixelRatio < 2
? 'subpixel-antialiased'
: 'antialiased';
return {
type: UI_FONT_SMOOTHING_SET,
fontSmoothing
};
}
export function moveLeft () { export function moveLeft () {
return (dispatch, getState) => { return (dispatch, getState) => {
dispatch({ dispatch({
@ -141,3 +155,14 @@ export function showPreferences () {
}); });
}; };
} }
export function windowMove () {
return (dispatch) => {
dispatch({
type: UI_WINDOW_MOVE,
effect () {
dispatch(setFontSmoothing());
}
});
};
}

View file

@ -25,6 +25,7 @@ export default class Term extends Component {
this.term.prefs_.set('font-family', props.fontFamily); this.term.prefs_.set('font-family', props.fontFamily);
this.term.prefs_.set('font-size', props.fontSize); this.term.prefs_.set('font-size', props.fontSize);
this.term.prefs_.set('font-smoothing', props.fontSmoothing);
this.term.prefs_.set('cursor-color', props.cursorColor); this.term.prefs_.set('cursor-color', props.cursorColor);
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);
@ -175,6 +176,10 @@ export default class Term extends Component {
this.term.prefs_.set('font-family', nextProps.fontFamily); this.term.prefs_.set('font-family', nextProps.fontFamily);
} }
if (this.props.fontSmoothing !== nextProps.fontSmoothing) {
this.term.prefs_.set('font-smoothing', props.fontSmoothing);
}
if (this.props.cursorColor !== nextProps.cursorColor) { if (this.props.cursorColor !== nextProps.cursorColor) {
this.term.prefs_.set('cursor-color', nextProps.cursorColor); this.term.prefs_.set('cursor-color', nextProps.cursorColor);
} }

View file

@ -129,6 +129,7 @@ export default class Terms extends Component {
fontSize: this.props.fontSize, fontSize: this.props.fontSize,
cursorColor: this.props.cursorColor, cursorColor: this.props.cursorColor,
fontFamily: this.props.fontFamily, fontFamily: this.props.fontFamily,
fontSmoothing: this.props.fontSmoothing,
foregroundColor: this.props.foregroundColor, foregroundColor: this.props.foregroundColor,
backgroundColor: this.props.backgroundColor, backgroundColor: this.props.backgroundColor,
colors: this.props.colors, colors: this.props.colors,

View file

@ -2,7 +2,9 @@ export const UI_FONT_SIZE_SET = 'UI_FONT_SIZE_SET';
export const UI_FONT_SIZE_INCR = 'UI_FONT_SIZE_INCR'; export const UI_FONT_SIZE_INCR = 'UI_FONT_SIZE_INCR';
export const UI_FONT_SIZE_DECR = 'UI_FONT_SIZE_DECR'; export const UI_FONT_SIZE_DECR = 'UI_FONT_SIZE_DECR';
export const UI_FONT_SIZE_RESET = 'UI_FONT_SIZE_RESET'; export const UI_FONT_SIZE_RESET = 'UI_FONT_SIZE_RESET';
export const UI_FONT_SMOOTHING_SET = 'UI_FONT_SMOOTHING_SET';
export const UI_MOVE_LEFT = 'UI_MOVE_LEFT'; export const UI_MOVE_LEFT = 'UI_MOVE_LEFT';
export const UI_MOVE_RIGHT = 'UI_MOVE_RIGHT'; export const UI_MOVE_RIGHT = 'UI_MOVE_RIGHT';
export const UI_MOVE_TO = 'UI_MOVE_TO'; export const UI_MOVE_TO = 'UI_MOVE_TO';
export const UI_SHOW_PREFERENCES = 'UI_SHOW_PREFERENCES'; export const UI_SHOW_PREFERENCES = 'UI_SHOW_PREFERENCES';
export const UI_WINDOW_MOVE = 'UI_WINDOW_MOVE';

View file

@ -23,6 +23,7 @@ const TermsContainer = connect(
? state.ui.fontSizeOverride ? state.ui.fontSizeOverride
: state.ui.fontSize, : state.ui.fontSize,
fontFamily: state.ui.fontFamily, fontFamily: state.ui.fontFamily,
fontSmoothing: state.ui.fontSmoothingOverride,
padding: state.ui.padding, padding: state.ui.padding,
cursorColor: state.ui.cursorColor, cursorColor: state.ui.cursorColor,
borderColor: state.ui.borderColor, borderColor: state.ui.borderColor,

View file

@ -41,6 +41,7 @@ config.subscribe(() => {
// and subscribe to all user intents for example from menus // and subscribe to all user intents for example from menus
rpc.on('ready', () => { rpc.on('ready', () => {
store_.dispatch(init()); store_.dispatch(init());
store_.dispatch(uiActions.setFontSmoothing());
}); });
rpc.on('session add', ({ uid, shell, pid }) => { rpc.on('session add', ({ uid, shell, pid }) => {
@ -99,6 +100,10 @@ rpc.on('update available', ({ releaseName, releaseNotes }) => {
store_.dispatch(updaterActions.updateAvailable(releaseName, releaseNotes)); store_.dispatch(updaterActions.updateAvailable(releaseName, releaseNotes));
}); });
rpc.on('move', () => {
store_.dispatch(uiActions.windowMove());
});
const app = render( const app = render(
<Provider store={ store_ }> <Provider store={ store_ }>
<HyperTermContainer /> <HyperTermContainer />

View file

@ -1,7 +1,11 @@
import Immutable from 'seamless-immutable'; import Immutable from 'seamless-immutable';
import { decorateUIReducer } from '../utils/plugins'; import { decorateUIReducer } from '../utils/plugins';
import { CONFIG_LOAD, CONFIG_RELOAD } from '../constants/config'; import { CONFIG_LOAD, CONFIG_RELOAD } from '../constants/config';
import { UI_FONT_SIZE_SET, UI_FONT_SIZE_RESET } from '../constants/ui'; import {
UI_FONT_SIZE_SET,
UI_FONT_SIZE_RESET,
UI_FONT_SMOOTHING_SET
} from '../constants/ui';
import { NOTIFICATION_DISMISS } from '../constants/notifications'; import { NOTIFICATION_DISMISS } from '../constants/notifications';
import { import {
SESSION_ADD, SESSION_ADD,
@ -24,6 +28,7 @@ const initial = Immutable({
padding: '12px 14px', padding: '12px 14px',
fontFamily: 'Menlo, "DejaVu Sans Mono", "Lucida Console", monospace', fontFamily: 'Menlo, "DejaVu Sans Mono", "Lucida Console", monospace',
fontSizeOverride: null, fontSizeOverride: null,
fontSmoothingOverride: 'antialiased',
css: '', css: '',
termCSS: '', termCSS: '',
openAt: {}, openAt: {},
@ -195,6 +200,10 @@ const reducer = (state = initial, action) => {
state_ = state.set('fontSizeOverride', null); state_ = state.set('fontSizeOverride', null);
break; break;
case UI_FONT_SMOOTHING_SET:
state_ = state.set('fontSmoothingOverride', action.fontSmoothing);
break;
case NOTIFICATION_DISMISS: case NOTIFICATION_DISMISS:
state_ = state.merge({ state_ = state.merge({
notifications: { notifications: {

View file

@ -160,6 +160,10 @@ app.on('ready', () => {
shell.openExternal(url); shell.openExternal(url);
}); });
rpc.win.on('move', () => {
rpc.emit('move');
});
const deleteSessions = () => { const deleteSessions = () => {
sessions.forEach((session, key) => { sessions.forEach((session, key) => {
session.removeAllListeners(); session.removeAllListeners();