Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
Avoid 'flashes of white' when tabs open or close
Browse files Browse the repository at this point in the history
Remove white flash for new tab pages which use about:newtab.
Sets the frame background to the same background as the newtab page, for a smooth transition between frame creation and the tab beginning to load content.
Keeps the frame around until the next frame is ready, to avoid flash when closing tabs.

Addresses #5309
  • Loading branch information
petemill committed Nov 15, 2017
1 parent 1ff7717 commit 3bcf2c7
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 23 deletions.
18 changes: 17 additions & 1 deletion app/renderer/components/frame/frame.js
Expand Up @@ -859,12 +859,15 @@ class Frame extends React.Component {

const props = {}
// used in renderer
props.transitionState = ownProps.transitionState
props.partition = frameStateUtil.getPartition(frame)
props.isFullScreen = frame.get('isFullScreen')
props.isPreview = frame.get('key') === currentWindow.get('previewFrameKey')
props.isActive = frameStateUtil.isFrameKeyActive(currentWindow, frame.get('key'))
props.showFullScreenWarning = frame.get('showFullScreenWarning')
props.location = location
props.isDefaultNewTabLocation = location === 'about:newtab'
props.isBlankLocation = location === 'about:blank'
props.tabId = tabId
props.showMessageBox = tabMessageBoxState.hasMessageBoxDetail(state, tabId)
props.isFocused = isFocused(state)
Expand Down Expand Up @@ -906,16 +909,29 @@ class Frame extends React.Component {
return props
}

getTransitionStateClassName (stateName) {
if (!stateName) {
return null
} else {
return `is${stateName[0].toUpperCase()}${stateName.slice(1)}`
}
}

render () {
const transitionClassName = this.getTransitionStateClassName(this.props.transitionState)
return <div
data-partition={this.props.partition}
data-test-id='frameWrapper'
data-test2-id={this.props.isActive ? 'activeFrame' : null}
data-test3-id={this.props.isPreview ? 'previewFrame' : null}
className={cx({
frameWrapper: true,
[this.props.className]: this.props.className,
[transitionClassName]: transitionClassName,
isPreview: this.props.isPreview,
isActive: this.props.isActive
isActive: this.props.isActive,
isDefaultNewTabLocation: this.props.isDefaultNewTabLocation,
isBlankLocation: this.props.isBlankLocation
})}>
{
this.props.isFullScreen && this.props.showFullScreenWarning
Expand Down
23 changes: 18 additions & 5 deletions app/renderer/components/main/main.js
Expand Up @@ -17,6 +17,7 @@ const contextMenus = require('../../../../js/contextMenus')
const {getSetting} = require('../../../../js/settings')

// Components
const { Transition, TransitionGroup } = require('react-transition-group')
const Navigator = require('../navigation/navigator')
const Frame = require('../frame/frame')
const TabPages = require('../tabs/tabPages')
Expand Down Expand Up @@ -733,15 +734,27 @@ class Main extends React.Component {
}
</div>
<div className='mainContainer'>
<div className='tabContainer'>
<TransitionGroup className='tabContainer'>
{
this.props.sortedFrames.map((frameKey) =>
<Frame
frameKey={frameKey}
<Transition
key={frameKey}
/>)
// after how long (ms)
// should the state 'entering' switch to 'entered'
// and also how long should state switch from 'exiting'
// to the <Frame /> component actually being removed
timeout={150}>
{
(transitionState) =>
<Frame
frameKey={frameKey}
transitionState={transitionState}
/>
}
</Transition>
)
}
</div>
</TransitionGroup>
</div>
{
this.props.showDownloadBar
Expand Down
69 changes: 52 additions & 17 deletions less/window.less
Expand Up @@ -62,16 +62,66 @@ html,
.frameWrapper {
height: 100%;
width: 100%;
z-index: @zindexWindow;

position: absolute;
top: 0;
left: 0;

// Needed to be able to click and drag to select content in pages.
user-select: none;
// default frame background
--frame-bg: #fff;
// custom frame background(s)
&.isDefaultNewTabLocation {
// matches tab dashboard background
// will also show when about:newtab === about:blank
--frame-bg: #222;
}
// Webviews can cause flickers w/ Chrome v49 if left visible
// in the background. This also has a major benefit for background
// tabs that have video and animations in them.
visibility: hidden;
// delay frames getting hidden when new tabs show up
// in order to avoid showing 0 frames and just the window
// background
// whilst this does also affect visibility when switching tabs,
// z-index ensures the delayed-hidden tab is not visible
// Note that this value can be as large as we want, it does not
// need to match the timeout specified in the frame's <Transition /> element
// (in renderer main.js). However, there is no reason to set it higher than that.
transition: visibility 0s linear 150ms;
// 1000
z-index: @zindexWindow;
&:not(.isActive) {
// 900
z-index: @zindexWindowNotActive;
}
&.isPreview {
background: #222;
// 1100
z-index: @zindexWindowIsPreview;
}
// show frame when active or preview
&.isActive,
&.isPreview,
// keep window contents around when exiting, to allow
// time for next active frame to be shown
&.isExiting {
visibility: visible;
// show instantly
transition-delay: 0s;
}
// hide frame whilst it's figuring out which location to be
// note: that isEntering is timed-out at a value set in renderer main.js
// but isBlankLocation will change at the exact moment that the frame
// has an actual location
&.isEntering.isBlankLocation {
visibility: hidden;
transition-delay: 0s;
}

webview {
background-color: #fff;
background-color: var(--frame-bg);
border: 0;
height: 100%;
outline: none;
Expand All @@ -89,21 +139,6 @@ html,
}
}

&:not(.isActive) {
z-index: @zindexWindowNotActive;

&.isPreview {
background: gray;
z-index: @zindexWindowIsPreview;
}

// Webviews can cause flickers w/ Chrome v49 if left visible
// in the background. This also has a major benefit for background
// tabs that have video and animations in them.
&:not(.isPreview) {
visibility: hidden;
}
}
}

.hrefPreview {
Expand Down
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -120,6 +120,7 @@
"react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.5.4",
"react-select": "^0.9.1",
"react-transition-group": "^2.2.1",
"snazzy": "^7.0.0",
"string.prototype.endswith": "^0.2.0",
"string.prototype.startswith": "^0.2.0",
Expand Down

0 comments on commit 3bcf2c7

Please sign in to comment.