From 3b94de763a3121f539baf14fed5d7b6bc8fcd9b0 Mon Sep 17 00:00:00 2001 From: Alexander Drozdov Date: Fri, 13 Mar 2020 13:47:53 +0200 Subject: [PATCH] browser && auto-hide --- src/components/CheckedItem.vue | 15 +----- src/components/main-process-bindings.ts | 9 ++-- src/main/positioning.ts | 64 +++++++++++++++++++------ src/main/shortcuts.ts | 6 +-- src/main/window.ts | 2 +- src/views/Home.vue | 37 +++++++++++--- 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/components/CheckedItem.vue b/src/components/CheckedItem.vue index 5cf995b5..503236c3 100644 --- a/src/components/CheckedItem.vue +++ b/src/components/CheckedItem.vue @@ -50,25 +50,12 @@ export default { FilterName }, created () { - MainProcess.addEventListener('price-check', ({ detail: clipboard }) => { + MainProcess.addEventListener('price-check', ({ detail: { clipboard } }) => { this.item = parseClipboard(clipboard) this.itemFilters = createFilters(this.item) this.itemStats = initUiModFilters(this.item) }) - document.addEventListener('mouseenter', (e) => { - const key = e.ctrlKey ? 'Ctrl' : e.shiftKey ? 'Shift' : undefined - MainProcess.priceCheckMouse('enter', key) - }) - document.addEventListener('click', () => { MainProcess.priceCheckMouse('click') }) - document.addEventListener('mouseleave', () => { MainProcess.priceCheckMouse('leave') }) - - document.addEventListener('keyup', (e) => { - if (e.key === 'Escape') { - MainProcess.priceCheckHide() - } - }) - this.$watch(vm => [vm.itemFilters, vm.itemStats], () => { this.tradeAPI = apiToSatisfySearch(this.itemFilters, this.itemStats) diff --git a/src/components/main-process-bindings.ts b/src/components/main-process-bindings.ts index 0857ad42..3495053e 100644 --- a/src/components/main-process-bindings.ts +++ b/src/components/main-process-bindings.ts @@ -12,8 +12,8 @@ class MainProcessBinding extends EventTarget { super() if (electron) { - electron.ipcRenderer.on('price-check', (e, clipboard) => { - this.selfEmitPriceCheck(clipboard) + electron.ipcRenderer.on('price-check', (e, data) => { + this.selfEmitPriceCheck(data) }) electron.ipcRenderer.on(LEAGUE_SELECTED, (e, leagueId) => { @@ -24,9 +24,9 @@ class MainProcessBinding extends EventTarget { } } - selfEmitPriceCheck (text: string) { + selfEmitPriceCheck (data: { clipboard: string, position: string }) { this.dispatchEvent(new CustomEvent('price-check', { - detail: text + detail: data })) } @@ -65,6 +65,7 @@ class MainProcessBinding extends EventTarget { openAppBrowser (url: string) { if (electron) { electron.ipcRenderer.send(OPEN_LINK, url) + this.dispatchEvent(new Event(OPEN_LINK)) } else { window.open(url) } diff --git a/src/main/positioning.ts b/src/main/positioning.ts index f5521679..36dbbf04 100644 --- a/src/main/positioning.ts +++ b/src/main/positioning.ts @@ -1,4 +1,4 @@ -import { BrowserWindow, ipcMain, screen, Rectangle, BrowserView } from 'electron' +import { BrowserWindow, ipcMain, screen, Rectangle, BrowserView, Point } from 'electron' import ioHook from 'iohook' import { win, WIDTH, TITLE_HEIGHT } from './window' import { checkPressPosition, isPollingClipboard } from './shortcuts' @@ -14,30 +14,37 @@ const CLOSE_THRESHOLD_PX = 40 let isWindowShown = false let isWindowLocked = false let isClickedAfterLock = false +let priceCheckActualBounds : Rectangle | undefined +let isMouseInside = false let browserViewExternal: BrowserView | undefined -export function showWindow () { +export function showWindow (willLocked?: boolean) { positionWindow(win) if (isWindowShown && isWindowLocked) { logger.debug('Hide the window (was left in background)', { source: 'price-check', fn: 'showWindow' }) - hideWindow(true) + hideWindow(true, willLocked) } isWindowShown = true win.showInactive() } -function hideWindow (willShow?: boolean) { +function hideWindow (willShow?: boolean, willLocked?: boolean) { logger.verbose('Hide window', { source: 'price-check', fn: 'hideWindow', wasLocked: isWindowLocked }) isWindowShown = false - if (isWindowLocked && config.get('altTabToGame')) { + isMouseInside = false + if (isWindowLocked && config.get('altTabToGame') && !willLocked) { win.setSkipTaskbar(true) win.setAlwaysOnTop(true, 'screen-saver') + if (process.platform === 'win32' && willShow) { + win.hide() + } } if (!willShow) { win.hide() + priceCheckActualBounds = undefined } win.setIgnoreMouseEvents(true) @@ -67,7 +74,6 @@ export function lockWindow (syntheticClick = false) { win.setSkipTaskbar(false) win.setAlwaysOnTop(false) } - win.setIgnoreMouseEvents(false) } export function setupShowHide () { @@ -80,16 +86,24 @@ export function setupShowHide () { if (!isWindowLocked) { logger.debug('Clicked inside window fix', { source: 'price-check' }) lockWindow(true) + isMouseInside = true } else { isClickedAfterLock = true + isMouseInside = true logger.debug('Clicked inside window after lock', { source: 'price-check' }) } } else if (name === 'leave') { + isMouseInside = false + win.setIgnoreMouseEvents(true) + if (!isClickedAfterLock && leagues.length) { logger.debug('Mouse has left the window without a single click', { source: 'price-check' }) hideWindow() } } else if (name === 'enter') { + isMouseInside = true + win.setIgnoreMouseEvents(false) + if (isWindowLocked) return if (modifier === config.get('priceCheckKeyHold')) { @@ -109,9 +123,9 @@ export function setupShowHide () { win.setBounds(PoeWindow.bounds!) browserViewExternal.setBounds({ x: 0, - y: TITLE_HEIGHT, + y: 0, width: PoeWindow.bounds!.width - WIDTH, - height: PoeWindow.bounds!.height - TITLE_HEIGHT + height: PoeWindow.bounds!.height }) browserViewExternal.webContents.loadURL(link) }) @@ -133,31 +147,53 @@ export function setupShowHide () { if (distance > CLOSE_THRESHOLD_PX) { hideWindow() } + } else if (priceCheckActualBounds && !isMouseInside) { + if ( + e.x > priceCheckActualBounds.x && + e.x < priceCheckActualBounds.x + priceCheckActualBounds.width && + e.y > priceCheckActualBounds.y && + e.y < priceCheckActualBounds.y + priceCheckActualBounds.height + ) { + ipcMain.emit(PRICE_CHECK_MOUSE, undefined, 'enter', modifier) + } } }) } function positionWindow (tradeWindow: BrowserWindow) { - const poePos = PoeWindow.bounds! + const poeBounds = PoeWindow.bounds! - const newBounds = poePos + priceCheckActualBounds = { + x: getOffsetX(poeBounds), + y: poeBounds.y, + width: WIDTH, + height: poeBounds.height + } - logger.debug('Reposition window', { source: 'price-check', newBounds, poeBounds: poePos }) - tradeWindow.setBounds(newBounds, false) + logger.debug('Reposition window', { source: 'price-check', poeBounds }) + tradeWindow.setBounds(poeBounds, false) } function getOffsetX (poePos: Rectangle): number { - const mousePos = screen.getCursorScreenPoint() + const mousePos = checkPressPosition! if (mousePos.x > (poePos.x + poePos.width / 2)) { // inventory - return (poePos.x + poePos.width) - poeUserInterfaceWidth(poePos.height) - 460 + return (poePos.x + poePos.width) - poeUserInterfaceWidth(poePos.height) - WIDTH } else { // stash or chat return poePos.x + poeUserInterfaceWidth(poePos.height) } } +export function getPoeUiPosition (mousePos: Point) { + if (mousePos.x > (PoeWindow.bounds!.x + PoeWindow.bounds!.width / 2)) { + return 'inventory' + } else { + return 'stash' // or chat/vendor/center of screen + } +} + export function poeUserInterfaceWidth (windowHeight: number) { // sidebar is 370px at 800x600 const ratio = 370 / 600 diff --git a/src/main/shortcuts.ts b/src/main/shortcuts.ts index 4c876a35..9b0bd718 100644 --- a/src/main/shortcuts.ts +++ b/src/main/shortcuts.ts @@ -3,7 +3,7 @@ import robotjs from 'robotjs' import ioHook from 'iohook' import { pollClipboard } from './PollClipboard' import { win } from './window' -import { showWindow, lockWindow, poeUserInterfaceWidth } from './positioning' +import { showWindow, lockWindow, poeUserInterfaceWidth, getPoeUiPosition } from './positioning' import { IohookToName, KeyToElectron } from '@/components/settings/KeyToCode' import { config } from './config' import { PoeWindow } from './PoeWindow' @@ -20,8 +20,8 @@ function priceCheck (lockedMode: boolean) { isPollingClipboard = true pollClipboard(32, 500) .then(async (clipboard) => { - win.webContents.send('price-check', clipboard) - await showWindow() + win.webContents.send('price-check', { clipboard, position: getPoeUiPosition(checkPressPosition!) }) + await showWindow(lockedMode) if (lockedMode) { lockWindow(true) } diff --git a/src/main/window.ts b/src/main/window.ts index 71ee8dfa..8541461b 100644 --- a/src/main/window.ts +++ b/src/main/window.ts @@ -10,7 +10,7 @@ export const TITLE_HEIGHT = 24 export function createWindow () { win = new BrowserWindow({ - width: 460, + width: WIDTH, height: 200, icon: path.join(__static, 'icon.png'), fullscreenable: false, diff --git a/src/views/Home.vue b/src/views/Home.vue index 94573cf8..93193f02 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -1,14 +1,15 @@ @@ -71,6 +71,19 @@ export default { }, filters: { displayRounding }, created () { + document.addEventListener('keyup', (e) => { + if (e.key === 'Escape') { + MainProcess.priceCheckHide() + } + }) + MainProcess.addEventListener('price-check', ({ detail: { position } }) => { + this.clickPosition = position + this.isBrowserShown = false + }) + MainProcess.addEventListener('open-link', () => { + this.clickPosition = 'inventory' + this.isBrowserShown = true + }) window.addEventListener('resize', () => { this.updatePoeUiWidth() }) @@ -78,7 +91,9 @@ export default { }, data () { return { - poeUiWidth: '0px' + poeUiWidth: '0px', + clickPosition: 'stash', + isBrowserShown: false } }, computed: { @@ -107,6 +122,14 @@ export default { // sidebar is 370px at 800x600 const ratio = 370 / 600 this.poeUiWidth = `${Math.round(window.innerHeight * ratio)}px` + }, + handleClick () { + MainProcess.priceCheckMouse('click') + }, + handleMouseleave () { + if (!this.isBrowserShown) { + MainProcess.priceCheckMouse('leave') + } } } }