Skip to content

Commit

Permalink
Added MacOS support (#403)
Browse files Browse the repository at this point in the history
  • Loading branch information
hsource authored Dec 7, 2023
1 parent 18d079b commit 588b801
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 19 deletions.
43 changes: 43 additions & 0 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# How this works

There are 2 main parts of the app:

1. renderer: this is the HTML/Javascript-based UI rendered within the Electron container. This runs Vue.js, a React-like Javascript framework for rendering front-end.
2. main: includes the main app (written in Electron). Handles keyboard shortcuts, brings up the UI and overlays.

Note that these 2 both depend on each other, and one cannot run without the other.

# How to develop

The most up-to-date instructions can always be derived from CI:

[.github/workflows/main.yml](https://github.com/SnosMe/awakened-poe-trade/blob/master/.github/workflows/main.yml)

Here's what that looks like as of 2023-12-03.

```shell
cd renderer
yarn install
yarn make-index-files
yarn dev

# In a second shell
cd main
yarn install
yarn dev
```

# How to build

```shell
cd renderer
yarn install
yarn make-index-files
yarn build

cd ../main
yarn build
# We want to sign with a distribution certificate to ensure other users can
# install without errors
CSC_NAME="Certificate name in Keychain" yarn package
```
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

### Development

Follow instructions similar to CI [.github/workflows/main.yml](https://github.com/SnosMe/awakened-poe-trade/blob/master/.github/workflows/main.yml)
See [DEVELOPING.md](./DEVELOPING.md)

### Acknowledgments

Expand Down
4 changes: 3 additions & 1 deletion ipc/KeyToCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ export const KeyToElectron = {
Backslash: '\\',
BracketRight: ']',
Quote: "'",
Ctrl: 'CmdOrCtrl',
// Do not change Ctrl to CmdOrCtrl. It causes registered shortcuts to
// often not work on Mac for unknown reasons.
Ctrl: 'Ctrl',
Alt: 'Alt',
Shift: 'Shift'
}
Expand Down
7 changes: 7 additions & 0 deletions main/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ win:
linux:
target:
- "AppImage"
mac:
target:
- target: default
arch:
- universal
# MacOS apps can only be run on other systems if signed
forceCodeSigning: true
appImage:
executableArgs:
- "--sandbox"
16 changes: 14 additions & 2 deletions main/src/AppTray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,21 @@ export class AppTray {
serverPort = 0

constructor (server: ServerEvents) {
this.tray = new Tray(
nativeImage.createFromPath(path.join(__dirname, process.env.STATIC!, process.platform === 'win32' ? 'icon.ico' : 'icon.png'))
let trayImage = nativeImage.createFromPath(
path.join(
__dirname,
process.env.STATIC!,
process.platform === "win32" ? "icon.ico" : "icon.png"
)
)

if (process.platform === 'darwin') {
// Mac image size needs to be smaller, or else it looks huge. Size
// guideline is from https://iconhandbook.co.uk/reference/chart/osx/
trayImage = trayImage.resize({ width: 22, height: 22 })
}

this.tray = new Tray(trayImage)
this.tray.setToolTip(`Awakened PoE Trade v${app.getVersion()}`)
this.rebuildMenu()

Expand Down
8 changes: 7 additions & 1 deletion main/src/host-files/GameConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs/promises'
import path from 'path'
import ini from 'ini'
import { app } from 'electron'
import process from 'process';
import { hotkeyToString, CodeToKey } from '../../../ipc/KeyToCode'
import type { Logger } from '../RemoteLogger'
import type { ServerEvents } from '../server'
Expand All @@ -21,7 +22,12 @@ export class GameConfig {
if (this.filePath === filePath) return

if (!filePath) {
filePath = path.join(app.getPath('documents'), 'My Games', 'Path of Exile', 'production_Config.ini')
if (process.platform === 'darwin') {
filePath = path.join(app.getPath('appData'), 'Path of Exile', 'Preferences', 'production_Config.ini')
} else {
filePath = path.join(app.getPath('documents'), 'My Games', 'Path of Exile', 'production_Config.ini')
}

try {
await fs.access(filePath)
// this.server.sendEventTo('any', {
Expand Down
22 changes: 15 additions & 7 deletions main/src/host-files/GameLogWatcher.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { promises as fs, watchFile, unwatchFile } from 'fs'
import { app } from 'electron';
import { ServerEvents } from '../server'
import { Logger } from '../RemoteLogger'

const COMMON_PATH = [
'C:\\Program Files (x86)\\Grinding Gear Games\\Path of Exile\\logs\\Client.txt',
'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Path of Exile\\logs\\Client.txt'
]

export class GameLogWatcher {
private offset = 0
private filePath?: string
Expand All @@ -22,8 +18,20 @@ export class GameLogWatcher {
async restart (logFile: string | null) {
if (this.filePath === logFile) return

if (!logFile && process.platform === 'win32') {
for (const filePath of COMMON_PATH) {
if (!logFile) {
let possiblePaths: string[] = []
if (process.platform === 'win32') {
possiblePaths = [
'C:\\Program Files (x86)\\Grinding Gear Games\\Path of Exile\\logs\\Client.txt',
'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Path of Exile\\logs\\Client.txt'
]
} else if (process.platform === 'darwin') {
possiblePaths = [
`${app.getPath('home')}/Library/Caches/com.GGG.PathOfExile/Logs/Client.txt`
]
}

for (const filePath of possiblePaths) {
try {
await fs.access(filePath)
// this.server.sendEventTo('any', {
Expand Down
11 changes: 10 additions & 1 deletion main/src/shortcuts/Shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,16 @@ export class Shortcuts {

function pressKeysToCopyItemText (pressedModKeys: string[] = [], showModsKey: string) {
let keys = mergeTwoHotkeys('Ctrl + C', showModsKey).split(' + ')
keys = keys.filter(key => key !== 'C' && !pressedModKeys.includes(key))
keys = keys.filter(key => key !== 'C')
if (process.platform !== 'darwin') {
// On non-Mac platforms, don't toggle keys that are already being pressed.
//
// For unknown reasons, we need to toggle pressed keys on Mac for advanced
// mod descriptions to be copied. You can test this by setting the shortcut
// to "Alt + any letter". They'll work with this line, but not if it's
// commented out.
keys = keys.filter(key => !pressedModKeys.includes(key))
}

for (const key of keys) {
uIOhook.keyToggle(UiohookKey[key as UiohookKeyT], 'down')
Expand Down
13 changes: 8 additions & 5 deletions main/src/shortcuts/text-box.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { uIOhook, UiohookKey as Key } from 'uiohook-napi'
import process from 'process';
import type { HostClipboard } from './HostClipboard'
import type { OverlayWindow } from '../windowing/OverlayWindow'

Expand All @@ -14,14 +15,16 @@ const AUTO_CLEAR = [

export function typeInChat (text: string, send: boolean, clipboard: HostClipboard) {
clipboard.restoreShortly((clipboard) => {
const modifiers = process.platform === 'darwin' ? [Key.Meta] : [Key.Ctrl]

if (text.startsWith(PLACEHOLDER_LAST)) {
text = text.slice(`${PLACEHOLDER_LAST} `.length)
clipboard.writeText(text)
uIOhook.keyTap(Key.Enter, [Key.Ctrl])
uIOhook.keyTap(Key.Enter, modifiers)
} else if (text.endsWith(PLACEHOLDER_LAST)) {
text = text.slice(0, -PLACEHOLDER_LAST.length)
clipboard.writeText(text)
uIOhook.keyTap(Key.Enter, [Key.Ctrl])
uIOhook.keyTap(Key.Enter, modifiers)
uIOhook.keyTap(Key.Home)
// press twice to focus input when using controller
uIOhook.keyTap(Key.Home)
Expand All @@ -30,11 +33,11 @@ export function typeInChat (text: string, send: boolean, clipboard: HostClipboar
clipboard.writeText(text)
uIOhook.keyTap(Key.Enter)
if (!AUTO_CLEAR.includes(text[0])) {
uIOhook.keyTap(Key.A, [Key.Ctrl])
uIOhook.keyTap(Key.A, modifiers)
}
}

uIOhook.keyTap(Key.V, [Key.Ctrl])
uIOhook.keyTap(Key.V, modifiers)

if (send) {
uIOhook.keyTap(Key.Enter)
Expand All @@ -56,7 +59,7 @@ export function stashSearch (
overlay.assertGameActive()
clipboard.writeText(text)
uIOhook.keyTap(Key.F, [Key.Ctrl])
uIOhook.keyTap(Key.V, [Key.Ctrl])
uIOhook.keyTap(Key.V, [process.platform === 'darwin' ? Key.Meta : Key.Ctrl])
uIOhook.keyTap(Key.Enter)
})
}
2 changes: 1 addition & 1 deletion main/src/windowing/GameWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class GameWindow extends EventEmitter {
if (!this._isTracking) {
OverlayController.events.on('focus', () => { this.isActive = true })
OverlayController.events.on('blur', () => { this.isActive = false })
OverlayController.attachByTitle(window, title)
OverlayController.attachByTitle(window, title, { hasTitleBarOnMac: true })
this._isTracking = true
}
}
Expand Down

0 comments on commit 588b801

Please sign in to comment.