From 3ba47e6ed45c4b1611a54b8c8b976b4de30c3bcb Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 14 Oct 2018 08:34:30 -0700 Subject: [PATCH] Ensure windows are on screen when window size changes --- js/actionCreators/windows.ts | 19 +++++++++++++++---- js/components/App.js | 35 +++++++++++++++++++++++++++++++---- js/webampLazy.js | 12 ------------ 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/js/actionCreators/windows.ts b/js/actionCreators/windows.ts index 244cc7da..7380b606 100644 --- a/js/actionCreators/windows.ts +++ b/js/actionCreators/windows.ts @@ -17,7 +17,13 @@ import { import { getPositionDiff, SizeDiff } from "../resizeUtils"; import { applyDiff } from "../snapUtils"; -import { Action, Dispatchable, WindowId, WindowPositions } from "../types"; +import { + Action, + Dispatchable, + WindowId, + WindowPositions, + Dispatch +} from "../types"; // Dispatch an action and, if needed rearrange the windows to preserve // the existing edge relationship. @@ -179,9 +185,14 @@ export function centerWindows(box: { }; } -export function browserWindowSizeChanged() { - const { height, width } = Utils.getWindowSize(); - return { type: BROWSER_WINDOW_SIZE_CHANGED, height, width }; +export function browserWindowSizeChanged(size: { + height: number; + width: number; +}) { + return (dispatch: Dispatch) => { + dispatch({ type: BROWSER_WINDOW_SIZE_CHANGED, ...size }); + dispatch(ensureWindowsAreOnScreen()); + }; } export function resetWindowSizes(): Dispatchable { diff --git a/js/components/App.js b/js/components/App.js index 5a7bb032..047f4b98 100644 --- a/js/components/App.js +++ b/js/components/App.js @@ -2,11 +2,11 @@ import React from "react"; import ReactDOM from "react-dom"; import PropTypes from "prop-types"; import { connect } from "react-redux"; -import { objectMap } from "../utils"; import Emitter from "../emitter"; import { WINDOWS, MEDIA_STATUS } from "../constants"; import { getVisualizerStyle } from "../selectors"; -import { closeWindow } from "../actionCreators"; +import * as Actions from "../actionCreators"; +import * as Utils from "../utils"; import ContextMenuWrapper from "./ContextMenuWrapper"; import MainContextMenu from "./MainWindow/MainContextMenu"; import WindowManager from "./WindowManager"; @@ -35,9 +35,13 @@ class App extends React.Component { this._webampNode.role = "application"; this._webampNode.style.zIndex = this.props.zIndex; document.body.appendChild(this._webampNode); + + this.props.browserWindowSizeChanged(Utils.getWindowSize()); + window.addEventListener("resize", this._handleWindowResize); } componentWillUnmount() { + window.removeEventListener("resize", this._handleWindowResize); document.body.removeChild(this._webampNode); } @@ -51,6 +55,27 @@ class App extends React.Component { } } + _handleWindowResize = () => { + if (this._webampNode == null) { + return; + } + // It's a bit tricky to measure the "natural" size of the browser window. + // Specifically we want to know how large the window would be without our + // own Webamp windows influencing it. To achieve this, we temporarily make + // our container `overflow: hidden;`. We then make our container full + // screen by setting the bottom/right properties to zero. This second part + // allows our Webamp windows to stay visible during the resize. After we + // measure, we set the style back so that we don't end up interfering with + // click events outside of our Webamp windows. + this._webampNode.style.right = 0; + this._webampNode.style.bottom = 0; + this._webampNode.style.overflow = "hidden"; + this.props.browserWindowSizeChanged(Utils.getWindowSize()); + this._webampNode.style.right = "default"; + this._webampNode.style.bottom = "default"; + this._webampNode.style.overflow = "visible"; + }; + _setFocus() { const binding = this._bindings[this.props.focused]; if (binding && binding.node) { @@ -93,7 +118,7 @@ class App extends React.Component { filePickers, genWindowComponents } = this.props; - return objectMap(genWindowsInfo, (w, id) => { + return Utils.objectMap(genWindowsInfo, (w, id) => { if (!w.open) { return null; } @@ -180,7 +205,9 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ - closeWindow: id => dispatch(closeWindow(id)) + closeWindow: id => dispatch(Actions.closeWindow(id)), + browserWindowSizeChanged: size => + dispatch(Actions.browserWindowSizeChanged(size)) }); export default connect( diff --git a/js/webampLazy.js b/js/webampLazy.js index 1d32c24f..50379af4 100644 --- a/js/webampLazy.js +++ b/js/webampLazy.js @@ -122,18 +122,6 @@ class Winamp { this.store.dispatch({ type: NETWORK_DISCONNECTED }) ); - this.store.dispatch(Actions.browserWindowSizeChanged()); - window.addEventListener("resize", () => { - this.store.dispatch(Actions.browserWindowSizeChanged()); - /* - Disable this for now, since we can't figure out how to safely measure - the natural size of the window when one or more of the Webamp windows - extend outside of it. - - this.store.dispatch(Actions.ensureWindowsAreOnScreen()); - */ - }); - if (initialSkin) { this.store.dispatch(Actions.setSkinFromUrl(initialSkin.url)); } else {