From ffd4eb46e3923061be6549796f00d437fa0aaa0f Mon Sep 17 00:00:00 2001 From: Vassiliy Shvetsov Date: Wed, 6 May 2020 12:04:14 -0700 Subject: [PATCH] add web-link activation modifier --- app/config/config-default.js | 4 ++++ lib/components/term-group.tsx | 1 + lib/components/term.tsx | 20 +++++++++++++++++--- lib/components/terms.tsx | 1 + lib/config.d.ts | 1 + lib/containers/terms.ts | 1 + lib/hyper.d.ts | 3 +++ lib/reducers/ui.ts | 5 +++++ 8 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/config/config-default.js b/app/config/config-default.js index 9ed1e733..4b34cbb3 100644 --- a/app/config/config-default.js +++ b/app/config/config-default.js @@ -154,6 +154,10 @@ module.exports = { // rendering (slower, but supports transparent backgrounds) webGLRenderer: true, + // keypress required for weblink activation: [ctrl|alt|meta|shift] + // todo: does not pick up config changes automatically, need to restart terminal :/ + webLinksActivationKey: '', + // if `true` (without backticks and without quotes), Hyper will ignore ligatures provided by some fonts disableLigatures: false, diff --git a/lib/components/term-group.tsx b/lib/components/term-group.tsx index 7be1d6a9..65d37b85 100644 --- a/lib/components/term-group.tsx +++ b/lib/components/term-group.tsx @@ -102,6 +102,7 @@ class TermGroup_ extends React.PureComponent { selectionColor: this.props.selectionColor, quickEdit: this.props.quickEdit, webGLRenderer: this.props.webGLRenderer, + webLinksActivationKey: this.props.webLinksActivationKey, macOptionSelectionMode: this.props.macOptionSelectionMode, disableLigatures: this.props.disableLigatures, uid diff --git a/lib/components/term.tsx b/lib/components/term.tsx index 5a26ea33..5b690a75 100644 --- a/lib/components/term.tsx +++ b/lib/components/term.tsx @@ -148,13 +148,27 @@ export default class Term extends React.PureComponent { } Term.reportRenderer(props.uid, useWebGL ? 'WebGL' : 'Canvas'); + const shallActivateWebLink = (event: Record | undefined) => { + return event && (!props.webLinksActivationKey || event[`${props.webLinksActivationKey}Key`]); + }; + this.term.attachCustomKeyEventHandler(this.keyboardHandler); this.term.loadAddon(this.fitAddon); this.term.loadAddon(this.searchAddon); this.term.loadAddon( - new WebLinksAddon((event, uri) => { - shell.openExternal(uri); - }) + new WebLinksAddon( + (event: MouseEvent | undefined, uri: string) => { + if (shallActivateWebLink(event)) shell.openExternal(uri); + }, + { + // prevent default electron link handling to allow selection, e.g. via double-click + willLinkActivate: (event: MouseEvent | undefined) => { + event?.preventDefault(); + return shallActivateWebLink(event); + }, + priority: Date.now() + } + ) ); this.term.open(this.termRef); if (useWebGL) { diff --git a/lib/components/terms.tsx b/lib/components/terms.tsx index fac1a09f..5ce8daf3 100644 --- a/lib/components/terms.tsx +++ b/lib/components/terms.tsx @@ -113,6 +113,7 @@ export default class Terms extends React.Component { onContextMenu: this.props.onContextMenu, quickEdit: this.props.quickEdit, webGLRenderer: this.props.webGLRenderer, + webLinksActivationKey: this.props.webLinksActivationKey, macOptionSelectionMode: this.props.macOptionSelectionMode, disableLigatures: this.props.disableLigatures, parentProps: this.props diff --git a/lib/config.d.ts b/lib/config.d.ts index 4c0170ec..807b463e 100644 --- a/lib/config.d.ts +++ b/lib/config.d.ts @@ -59,6 +59,7 @@ export type configOptions = { updateChannel: 'stable' | 'canary'; useConpty: boolean; webGLRenderer: boolean; + webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift'; windowSize: [number, number]; }; diff --git a/lib/containers/terms.ts b/lib/containers/terms.ts index c749a186..3c289a67 100644 --- a/lib/containers/terms.ts +++ b/lib/containers/terms.ts @@ -43,6 +43,7 @@ const mapStateToProps = (state: HyperState) => { modifierKeys: state.ui.modifierKeys, quickEdit: state.ui.quickEdit, webGLRenderer: state.ui.webGLRenderer, + webLinksActivationKey: state.ui.webLinksActivationKey, macOptionSelectionMode: state.ui.macOptionSelectionMode, disableLigatures: state.ui.disableLigatures }; diff --git a/lib/hyper.d.ts b/lib/hyper.d.ts index f4565d8d..a494b90f 100644 --- a/lib/hyper.d.ts +++ b/lib/hyper.d.ts @@ -105,6 +105,7 @@ export type uiState = { updateReleaseUrl: string | null; updateVersion: string | null; webGLRenderer: boolean; + webLinksActivationKey: string; }; export type session = { @@ -308,6 +309,7 @@ export type TermGroupOwnProps = { | 'toggleSearch' | 'uiFontFamily' | 'webGLRenderer' + | 'webLinksActivationKey' >; import {TermGroupConnectedProps} from './components/term-group'; @@ -368,6 +370,7 @@ export type TermProps = { uiFontFamily: string; url: string | null; webGLRenderer: boolean; + webLinksActivationKey: string; } & extensionProps & {ref_?: any}; export type Assignable = {[k in keyof U]: k extends keyof T ? T[k] : U[k]} & Partial; diff --git a/lib/reducers/ui.ts b/lib/reducers/ui.ts index 2e80cd6a..46ca3f1e 100644 --- a/lib/reducers/ui.ts +++ b/lib/reducers/ui.ts @@ -108,6 +108,7 @@ const initial: ImmutableType = Immutable({ showWindowControls: '', quickEdit: false, webGLRenderer: true, + webLinksActivationKey: '', macOptionSelectionMode: 'vertical', disableLigatures: false }); @@ -256,6 +257,10 @@ const reducer = (state = initial, action: HyperActions) => { ret.webGLRenderer = config.webGLRenderer; } + if (config.webLinksActivationKey !== undefined) { + ret.webLinksActivationKey = config.webLinksActivationKey; + } + if (config.macOptionSelectionMode) { ret.macOptionSelectionMode = config.macOptionSelectionMode; }