- electron/preload.cjs: contextBridge 로 window.desktop.setWindowSize 노출 - main.cjs: preload 연결 + ipcMain 'window:setSize'/'getSize' 핸들러 - SettingsView: PC(window.desktop 존재 시)에서 해상도 선택 추가 (1024×720 ~ 1920×1080), 선택 시 창 크기 변경+가운데 정렬 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-1
@@ -1,7 +1,7 @@
|
|||||||
// Slim Budget 데스크톱(Electron) 메인 프로세스.
|
// Slim Budget 데스크톱(Electron) 메인 프로세스.
|
||||||
// 라이브 사이트(https://app.sblog.kr)를 직접 로드한다 → 프론트 변경이 자동 반영(재설치 불필요),
|
// 라이브 사이트(https://app.sblog.kr)를 직접 로드한다 → 프론트 변경이 자동 반영(재설치 불필요),
|
||||||
// 같은 출처라 CORS 우회도 불필요. 배포된 웹 게이트가 Electron 을 감지해 안내페이지 대신 전체 앱을 띄운다.
|
// 같은 출처라 CORS 우회도 불필요. 배포된 웹 게이트가 Electron 을 감지해 안내페이지 대신 전체 앱을 띄운다.
|
||||||
const { app, BrowserWindow, shell, session } = require('electron')
|
const { app, BrowserWindow, shell, session, ipcMain } = require('electron')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ function createWindow() {
|
|||||||
webPreferences: {
|
webPreferences: {
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
|
preload: path.join(__dirname, 'preload.cjs'),
|
||||||
// 한글 IME 첫 글자 중복 입력 방지 — Chromium 맞춤법 검사기가 조합을 방해하는 Electron 알려진 버그 회피
|
// 한글 IME 첫 글자 중복 입력 방지 — Chromium 맞춤법 검사기가 조합을 방해하는 Electron 알려진 버그 회피
|
||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
},
|
},
|
||||||
@@ -91,6 +92,20 @@ function createWindow() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 데스크톱 창 크기(해상도) 변경 — 렌더러(설정 화면)에서 호출
|
||||||
|
ipcMain.handle('window:setSize', (e, w, h) => {
|
||||||
|
const win = BrowserWindow.fromWebContents(e.sender)
|
||||||
|
if (!win) return false
|
||||||
|
if (win.isMaximized()) win.unmaximize()
|
||||||
|
win.setSize(Math.max(360, Math.round(w)), Math.max(560, Math.round(h)))
|
||||||
|
win.center()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
ipcMain.handle('window:getSize', (e) => {
|
||||||
|
const win = BrowserWindow.fromWebContents(e.sender)
|
||||||
|
return win ? win.getSize() : [0, 0]
|
||||||
|
})
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
app.whenReady().then(async () => {
|
||||||
// 시작 시 HTTP 캐시 비움 → 라이브 사이트의 최신 프론트를 항상 로드(옛 HTML 캐시로 인한 미반영 방지).
|
// 시작 시 HTTP 캐시 비움 → 라이브 사이트의 최신 프론트를 항상 로드(옛 HTML 캐시로 인한 미반영 방지).
|
||||||
// localStorage(로그인 세션)는 캐시가 아니라 영향 없음.
|
// localStorage(로그인 세션)는 캐시가 아니라 영향 없음.
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// 렌더러(웹)에서 안전하게 호출할 데스크톱 전용 API 노출 (contextIsolation 유지).
|
||||||
|
const { contextBridge, ipcRenderer } = require('electron')
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('desktop', {
|
||||||
|
// 데스크톱 창 크기(해상도) 변경
|
||||||
|
setWindowSize: (w, h) => ipcRenderer.invoke('window:setSize', w, h),
|
||||||
|
getWindowSize: () => ipcRenderer.invoke('window:getSize'),
|
||||||
|
})
|
||||||
@@ -15,6 +15,22 @@ const THEMES = [
|
|||||||
const appVersion = typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : '-'
|
const appVersion = typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : '-'
|
||||||
const clearing = ref(false)
|
const clearing = ref(false)
|
||||||
|
|
||||||
|
// PC(데스크톱) 전용: 창 해상도 변경 (Electron preload 의 window.desktop 존재 시에만)
|
||||||
|
const isDesktop = typeof window !== 'undefined' && !!window.desktop
|
||||||
|
const RESOLUTIONS = [
|
||||||
|
{ label: '1024 × 720', w: 1024, h: 720 },
|
||||||
|
{ label: '1280 × 800', w: 1280, h: 800 },
|
||||||
|
{ label: '1366 × 768', w: 1366, h: 768 },
|
||||||
|
{ label: '1600 × 900', w: 1600, h: 900 },
|
||||||
|
{ label: '1920 × 1080', w: 1920, h: 1080 },
|
||||||
|
]
|
||||||
|
function onResolution(e) {
|
||||||
|
const v = e.target.value
|
||||||
|
if (!v) return
|
||||||
|
const [w, h] = v.split('x').map(Number)
|
||||||
|
window.desktop?.setWindowSize(w, h)
|
||||||
|
}
|
||||||
|
|
||||||
async function clearAppData() {
|
async function clearAppData() {
|
||||||
if (clearing.value) return
|
if (clearing.value) return
|
||||||
const ok = await dialog.confirm(
|
const ok = await dialog.confirm(
|
||||||
@@ -62,6 +78,20 @@ async function clearAppData() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- PC(데스크톱) 전용: 창 해상도 -->
|
||||||
|
<section v-if="isDesktop" class="card">
|
||||||
|
<div class="row">
|
||||||
|
<div class="row-main">
|
||||||
|
<span class="row-label">화면 해상도</span>
|
||||||
|
<span class="row-sub">데스크톱 창 크기를 선택한 크기로 변경</span>
|
||||||
|
</div>
|
||||||
|
<select class="res-select" @change="onResolution">
|
||||||
|
<option value="">선택</option>
|
||||||
|
<option v-for="r in RESOLUTIONS" :key="r.label" :value="`${r.w}x${r.h}`">{{ r.label }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<RouterLink to="/settings/account" class="row row-link">
|
<RouterLink to="/settings/account" class="row row-link">
|
||||||
<div class="row-main">
|
<div class="row-main">
|
||||||
@@ -164,6 +194,10 @@ async function clearAppData() {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
.res-select {
|
||||||
|
flex: none;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
.seg-btn {
|
.seg-btn {
|
||||||
padding: 0.4rem 0.7rem;
|
padding: 0.4rem 0.7rem;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user