From b76e0043091cedd4b30ef8d10dbc724c9578a2b3 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 19 Jul 2016 12:30:57 -0600 Subject: [PATCH] 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 --- app/lib/actions/ui.js | 27 ++++++++++++++++++++++++++- app/lib/components/term.js | 5 +++++ app/lib/components/terms.js | 1 + app/lib/constants/ui.js | 2 ++ app/lib/containers/terms.js | 1 + app/lib/index.js | 5 +++++ app/lib/reducers/ui.js | 11 ++++++++++- index.js | 4 ++++ 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/lib/actions/ui.js b/app/lib/actions/ui.js index a2cc3cb8..901884f0 100644 --- a/app/lib/actions/ui.js +++ b/app/lib/actions/ui.js @@ -11,10 +11,12 @@ import { UI_FONT_SIZE_INCR, UI_FONT_SIZE_DECR, UI_FONT_SIZE_RESET, + UI_FONT_SMOOTHING_SET, UI_MOVE_LEFT, UI_MOVE_RIGHT, UI_MOVE_TO, - UI_SHOW_PREFERENCES + UI_SHOW_PREFERENCES, + UI_WINDOW_MOVE } from '../constants/ui'; 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 () { return (dispatch, getState) => { dispatch({ @@ -141,3 +155,14 @@ export function showPreferences () { }); }; } + +export function windowMove () { + return (dispatch) => { + dispatch({ + type: UI_WINDOW_MOVE, + effect () { + dispatch(setFontSmoothing()); + } + }); + }; +} diff --git a/app/lib/components/term.js b/app/lib/components/term.js index 4cd0c2d5..dadc7754 100644 --- a/app/lib/components/term.js +++ b/app/lib/components/term.js @@ -25,6 +25,7 @@ export default class Term extends Component { this.term.prefs_.set('font-family', props.fontFamily); 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('enable-clipboard-notice', false); 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); } + if (this.props.fontSmoothing !== nextProps.fontSmoothing) { + this.term.prefs_.set('font-smoothing', props.fontSmoothing); + } + if (this.props.cursorColor !== nextProps.cursorColor) { this.term.prefs_.set('cursor-color', nextProps.cursorColor); } diff --git a/app/lib/components/terms.js b/app/lib/components/terms.js index 15844828..7307284e 100644 --- a/app/lib/components/terms.js +++ b/app/lib/components/terms.js @@ -129,6 +129,7 @@ export default class Terms extends Component { fontSize: this.props.fontSize, cursorColor: this.props.cursorColor, fontFamily: this.props.fontFamily, + fontSmoothing: this.props.fontSmoothing, foregroundColor: this.props.foregroundColor, backgroundColor: this.props.backgroundColor, colors: this.props.colors, diff --git a/app/lib/constants/ui.js b/app/lib/constants/ui.js index 2f902513..24814f7c 100644 --- a/app/lib/constants/ui.js +++ b/app/lib/constants/ui.js @@ -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_DECR = 'UI_FONT_SIZE_DECR'; 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_RIGHT = 'UI_MOVE_RIGHT'; export const UI_MOVE_TO = 'UI_MOVE_TO'; export const UI_SHOW_PREFERENCES = 'UI_SHOW_PREFERENCES'; +export const UI_WINDOW_MOVE = 'UI_WINDOW_MOVE'; diff --git a/app/lib/containers/terms.js b/app/lib/containers/terms.js index 40d52197..aa86e9f8 100644 --- a/app/lib/containers/terms.js +++ b/app/lib/containers/terms.js @@ -23,6 +23,7 @@ const TermsContainer = connect( ? state.ui.fontSizeOverride : state.ui.fontSize, fontFamily: state.ui.fontFamily, + fontSmoothing: state.ui.fontSmoothingOverride, padding: state.ui.padding, cursorColor: state.ui.cursorColor, borderColor: state.ui.borderColor, diff --git a/app/lib/index.js b/app/lib/index.js index c780b46a..4bddb0cd 100644 --- a/app/lib/index.js +++ b/app/lib/index.js @@ -41,6 +41,7 @@ config.subscribe(() => { // and subscribe to all user intents for example from menus rpc.on('ready', () => { store_.dispatch(init()); + store_.dispatch(uiActions.setFontSmoothing()); }); rpc.on('session add', ({ uid, shell, pid }) => { @@ -99,6 +100,10 @@ rpc.on('update available', ({ releaseName, releaseNotes }) => { store_.dispatch(updaterActions.updateAvailable(releaseName, releaseNotes)); }); +rpc.on('move', () => { + store_.dispatch(uiActions.windowMove()); +}); + const app = render( diff --git a/app/lib/reducers/ui.js b/app/lib/reducers/ui.js index f1f8f364..770f874a 100644 --- a/app/lib/reducers/ui.js +++ b/app/lib/reducers/ui.js @@ -1,7 +1,11 @@ import Immutable from 'seamless-immutable'; import { decorateUIReducer } from '../utils/plugins'; 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 { SESSION_ADD, @@ -24,6 +28,7 @@ const initial = Immutable({ padding: '12px 14px', fontFamily: 'Menlo, "DejaVu Sans Mono", "Lucida Console", monospace', fontSizeOverride: null, + fontSmoothingOverride: 'antialiased', css: '', termCSS: '', openAt: {}, @@ -195,6 +200,10 @@ const reducer = (state = initial, action) => { state_ = state.set('fontSizeOverride', null); break; + case UI_FONT_SMOOTHING_SET: + state_ = state.set('fontSmoothingOverride', action.fontSmoothing); + break; + case NOTIFICATION_DISMISS: state_ = state.merge({ notifications: { diff --git a/index.js b/index.js index 0a7d8bbb..82218e93 100644 --- a/index.js +++ b/index.js @@ -160,6 +160,10 @@ app.on('ready', () => { shell.openExternal(url); }); + rpc.win.on('move', () => { + rpc.emit('move'); + }); + const deleteSessions = () => { sessions.forEach((session, key) => { session.removeAllListeners();