UNPKG

dynamic-desktop-manager

Version:

Electron.js uygulamaları için Windows'ta dinamik masaüstü duvar kağıtları (MP4, GIF) ayarlayın. Çoklu monitör, ses ve sığdırma seçeneklerini destekler.

196 lines (171 loc) 8.42 kB
const { BrowserWindow, screen } = require('electron'); const path = require('path'); const os = require('os'); let ffi; let ref; let user32; // Aktif duvar kağıdı pencerelerini ve ayarlarını saklamak için // Key: display.id (string), Value: { window: BrowserWindow, filePath: string, type: string, options: WallpaperOptions } const activeWallpaperWindows = new Map(); function initFFI() { if (os.platform() !== 'win32' || user32) return; try { ffi = require('ffi-napi'); ref = require('ref-napi'); user32 = new ffi.Library('user32', { 'FindWindowW': ['pointer', ['string', 'string']], 'FindWindowExW': ['pointer', ['pointer', 'pointer', 'string', 'string']], 'SendMessageTimeoutW': ['uint32', ['pointer', 'uint32', 'uintptr_t', 'uintptr_t', 'uint32', 'uint32', 'pointer']], 'EnumWindows': ['bool', ['pointer', 'pointer']], 'GetParent': ['pointer', ['pointer']], 'SetParent': ['pointer', ['pointer', 'pointer']], 'GetClassNameW': ['int', ['pointer', 'pointer', 'int']], }); console.log("dynamic-desktop-manager: FFI başarıyla başlatıldı."); } catch (e) { console.error("dynamic-desktop-manager: ffi-napi veya ref-napi yüklenemedi. Windows'ta dinamik duvar kağıdı çalışmayacak.", e); ffi = null; user32 = null; } } function attachToDesktop(electronWindow) { if (os.platform() !== 'win32' || !user32) { console.warn("dynamic-desktop-manager: attachToDesktop Windows dışı platformda veya FFI başlatılmamışken çağrıldı."); return; } const progman = user32.FindWindowW(ref.allocCString('Progman', 'utf16le'), null); if (progman.isNull()) { console.error("dynamic-desktop-manager: Progman penceresi bulunamadı."); return; } let resultPtr = ref.alloc('uint64'); user32.SendMessageTimeoutW(progman, 0x052C, 0, 0, 0x0000, 1000, resultPtr); let workerW = null; const enumWindowsProc = ffi.Callback('bool', ['pointer', 'pointer'], (hwnd, lParam) => { const defView = user32.FindWindowExW(hwnd, null, ref.allocCString('SHELLDLL_DefView', 'utf16le'), null); if (!defView.isNull()) { let classNameBuf = Buffer.alloc(256 * 2); user32.GetClassNameW(hwnd, classNameBuf, 255); const className = classNameBuf.toString('utf16le').replace(/\0/g, ''); if (className === 'WorkerW') { const parent = user32.GetParent(hwnd); if (parent.equals(progman) || parent.isNull()) { workerW = hwnd; return false; } } } return true; }); user32.EnumWindows(enumWindowsProc, null); if (!workerW || workerW.isNull()) { let currentChild = user32.FindWindowExW(progman, null, ref.allocCString('WorkerW', 'utf16le'), null); while (!currentChild.isNull()) { const defView = user32.FindWindowExW(currentChild, null, ref.allocCString('SHELLDLL_DefView', 'utf16le'), null); if (!defView.isNull()) { workerW = currentChild; break; } currentChild = user32.FindWindowExW(progman, currentChild, ref.allocCString('WorkerW', 'utf16le'), null); } } if (workerW && !workerW.isNull()) { const electronWinHandle = electronWindow.getNativeWindowHandle(); user32.SetParent(electronWinHandle, workerW); console.log(`dynamic-desktop-manager: Duvar kağıdı penceresi WorkerW'ye başarıyla eklendi (Ekran: ${electronWindow.displayTargetId}, WorkerW: ${workerW.toString()})`); } else { console.error(`dynamic-desktop-manager: Uygun WorkerW penceresi bulunamadı (Ekran: ${electronWindow.displayTargetId}). Duvar kağıdı simgelerin arkasında olmayabilir.`); } } async function createOrUpdateWallpaperWindow(display, filePath, type, options) { initFFI(); // Her ihtimale karşı FFI'nin başlatıldığından emin ol const displayIdStr = display.id.toString(); if (activeWallpaperWindows.has(displayIdStr)) { const existing = activeWallpaperWindows.get(displayIdStr); // Eğer dosya ve temel ayarlar aynıysa, sadece medyayı güncelle if (existing.filePath === filePath && existing.options.objectFit === options.objectFit && existing.options.volume === options.volume && existing.options.loop === options.loop) { existing.window.webContents.send('set-media', { filePath, type, options }); existing.window.showInactive(); // Görünür olduğundan emin ol console.log(`dynamic-desktop-manager: Mevcut duvar kağıdı penceresi güncellendi (Ekran ID: ${displayIdStr})`); return existing.window; } // Aksi takdirde, eskisini kapat ve yenisini oluştur await clearWallpaperWindow(displayIdStr); } const { x, y, width, height } = display.bounds; const wallpaperWindow = new BrowserWindow({ x, y, width, height, frame: false, transparent: false, backgroundColor: '#000000', alwaysOnTop: false, skipTaskbar: true, focusable: false, show: false, webPreferences: { preload: path.join(__dirname, '..', 'preload', 'wallpaper-preload.js'), nodeIntegration: false, contextIsolation: true, devTools: process.env.NODE_ENV === 'development', webSecurity: true, // file:// URL'leri için true kalmalı }, type: 'toolbar', }); wallpaperWindow.displayTargetId = displayIdStr; // Hangi ekrana ait olduğunu takip etmek için const wallpaperHtmlPath = path.join(__dirname, '..', 'renderer', 'wallpaper.html'); await wallpaperWindow.loadFile(wallpaperHtmlPath); wallpaperWindow.webContents.on('did-finish-load', () => { wallpaperWindow.webContents.send('set-media', { filePath, type, options }); if (os.platform() === 'win32' && ffi && user32) { // FFI'nin başarılı olup olmadığını kontrol et attachToDesktop(wallpaperWindow); } wallpaperWindow.showInactive(); console.log(`dynamic-desktop-manager: Yeni duvar kağıdı penceresi oluşturuldu ve yüklendi (Ekran ID: ${displayIdStr})`); }); wallpaperWindow.on('closed', () => { activeWallpaperWindows.delete(displayIdStr); console.log(`dynamic-desktop-manager: Duvar kağıdı penceresi kapatıldı (Ekran ID: ${displayIdStr})`); }); wallpaperWindow.webContents.on('will-navigate', (event) => event.preventDefault()); wallpaperWindow.webContents.setWindowOpenHandler(() => ({ action: 'deny' })); activeWallpaperWindows.set(displayIdStr, { window: wallpaperWindow, filePath, type, options }); return wallpaperWindow; } async function clearWallpaperWindow(displayIdStr) { if (activeWallpaperWindows.has(displayIdStr)) { const entry = activeWallpaperWindows.get(displayIdStr); if (entry.window && !entry.window.isDestroyed()) { entry.window.close(); } activeWallpaperWindows.delete(displayIdStr); console.log(`dynamic-desktop-manager: Duvar kağıdı temizlendi (Ekran ID: ${displayIdStr})`); } } async function clearAllWallpaperWindows() { for (const displayIdStr of activeWallpaperWindows.keys()) { await clearWallpaperWindow(displayIdStr); } console.log("dynamic-desktop-manager: Tüm aktif duvar kağıtları temizlendi."); } function getActiveWallpapers() { const result = {}; for (const [displayId, data] of activeWallpaperWindows.entries()) { result[displayId] = { filePath: data.filePath, type: data.type, options: data.options, displayBounds: screen.getAllDisplays().find(d => d.id.toString() === displayId)?.bounds }; } return result; } module.exports = { createOrUpdateWallpaperWindow, clearWallpaperWindow, clearAllWallpaperWindows, getActiveWallpapers, initFFI // Gerekirse dışarıdan tetiklemek için };