From 8a204f3449670cfaf969d8d88a8e1c5e940acfee Mon Sep 17 00:00:00 2001 From: JoseMoreville <18040006@utculiacan.edu.mx> Date: Sat, 7 May 2022 11:18:07 -0600 Subject: [PATCH 1/7] feat: :construction: External screens now work This is a work in progress, i'm still making a UI and way to make every screen to be a different background instance, to have the posibility to have different background on each screen --- packages/main/src/changeBackgroundWindow.ts | 2 +- packages/main/src/externalScreenWindow.ts | 89 +++++++++++++++++++++ packages/main/src/index.ts | 77 ++++++++++++------ packages/main/src/uploadBackroundWindow.ts | 4 +- packages/renderer/src/App.vue | 7 ++ 5 files changed, 153 insertions(+), 26 deletions(-) create mode 100644 packages/main/src/externalScreenWindow.ts diff --git a/packages/main/src/changeBackgroundWindow.ts b/packages/main/src/changeBackgroundWindow.ts index 1bc3b63..e3133aa 100644 --- a/packages/main/src/changeBackgroundWindow.ts +++ b/packages/main/src/changeBackgroundWindow.ts @@ -89,7 +89,7 @@ async function createChangeBackgroundWindow() { let window = BrowserWindow.getAllWindows().find(w => !w.isDestroyed()); window?.webContents.session.clearCache(); - if (BrowserWindow.getAllWindows().length === 1) { + if (BrowserWindow.getAllWindows().length === 1 || BrowserWindow.getAllWindows().length === screen.getAllDisplays().length) { window = await createChangeBackgroundWindow(); } else{ window = BrowserWindow.getAllWindows().filter(w => w.isMinimized())[0]; diff --git a/packages/main/src/externalScreenWindow.ts b/packages/main/src/externalScreenWindow.ts new file mode 100644 index 0000000..bffdaeb --- /dev/null +++ b/packages/main/src/externalScreenWindow.ts @@ -0,0 +1,89 @@ +import {BrowserWindow, app, screen, ipcMain} from 'electron'; +import {join} from 'path'; +import {URL} from 'url'; +const fs = require('fs'); +const Store = require('electron-store'); +const store = new Store(); + +let browserWindow: BrowserWindow; + +export async function createExternalScreenWindow(position: {x: number, y: number}, size: {width: number, height: number}) { + browserWindow = new BrowserWindow({ + type: 'desktop', + x: position.x, + y: position.y, + movable: false, + autoHideMenuBar: true, + enableLargerThanScreen: true, + skipTaskbar: true, + roundedCorners: false, + titleBarStyle: 'hidden', + resizable: false, + hasShadow: false, + show: false, // Use 'ready-to-show' event to show window + height: size.height + 5, + width: size.width, + webPreferences: { + nativeWindowOpen: true, + webviewTag: false, // The webview tag is not recommended. Consider alternatives like iframe or Electron's BrowserView. https://www.electronjs.org/docs/latest/api/webview-tag#warning + preload: join(__dirname, '../../preload/dist/index.cjs'), + webSecurity: false, + }, + }); + if(!store.get('frameRate')) { + store.set('frameRate', 30); + browserWindow?.webContents.setFrameRate(30); // might make it depend on electron store value to change between 30 and 60 with tray submenu + }else{ + browserWindow?.webContents.setFrameRate(store.get('frameRate')); + } + /** + * If you install `show: true` then it can cause issues when trying to close the window. + * Use `show: false` and listener events `ready-to-show` to fix these issues. + * + * @see https://github.com/electron/electron/issues/25012 + */ + browserWindow.on('ready-to-show', () => { + browserWindow?.show(); + if (import.meta.env.DEV) { + browserWindow?.webContents.openDevTools(); + } + }); + + /** + * URL for main window. + * Vite dev server for development. + * `file://../renderer/index.html` for production and test + */ + const pageUrl = import.meta.env.DEV && import.meta.env.VITE_DEV_SERVER_URL !== undefined + ? import.meta.env.VITE_DEV_SERVER_URL + : new URL('../renderer/dist/index.html', 'file://' + __dirname).toString(); + + let data = ''; + fs.readdir(`${app.getPath('userData')}/backgrounds`, async (err:Error, files: Array) => { + if (err){ + console.error(err); + return; + } + files = files.filter( file => + file.endsWith('.mp4') || + file.endsWith('.webm') || + file.endsWith('.png') || + file.endsWith('.jpg') || + file.endsWith('.jpeg')); + + for (const video of files) { + if(video == store.get('currentBackground')){ + data = `${app.getPath('userData')}/backgrounds/${video}`; + break; + } + } + }); + browserWindow.loadFile(data); + await browserWindow.loadURL(pageUrl); + //console.log('first', screen.getDisplayMatching(browserWindow.getBounds()).id); + return browserWindow; +} + +ipcMain.handle('instanceId', () => { + return screen.getDisplayMatching(browserWindow.getBounds()).id; +}); \ No newline at end of file diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index 35f6bbf..b3d7a09 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -1,11 +1,13 @@ - /* eslint-disable */ -import {app, Menu, Tray, nativeImage, BrowserWindow, ipcMain} from 'electron'; +/* eslint-disable semi */ + +import {app, Menu, Tray, nativeImage, BrowserWindow, screen} from 'electron'; import './security-restrictions'; import {restoreOrCreateWindow} from '/@/mainWindow'; import {restoreOrCreateUploadWindow} from './uploadBackroundWindow'; import {restoreOrCreateChangeBackgroundWindow} from './changeBackgroundWindow'; import useHandlers, {store} from './Handlers'; import {join} from 'path'; +import {createExternalScreenWindow} from './externalScreenWindow'; const fs = require('fs'); let tray = null; @@ -19,9 +21,9 @@ app.on('ready', () => { if (process.platform !== 'darwin') { app.quit(); } - console.log(store.get('enableAudio')) + //console.log(store.get('enableAudio')); if(!store.get('enableAudio')){ - store.set('enableAudio', false) + store.set('enableAudio', false); } }); @@ -104,24 +106,26 @@ app.whenReady().then(() => { const contextMenu = Menu.buildFromTemplate([ { label: 'Change background', type: 'normal', click: () => { try{ + // TODO: CHECK WHY THIS IS NOT WORKING BrowserWindow.getAllWindows().filter(window => window.title === 'Upload Background')[0]?.destroy(); } catch(e){ console.error(e); } finally{ - restoreOrCreateChangeBackgroundWindow() + restoreOrCreateChangeBackgroundWindow(); } } }, { label: 'Upload a new background', type: 'normal', click: () => { try{ + // TODO: CHECK WHY THIS IS NOT WORKING BrowserWindow.getAllWindows().filter(window => window.title === 'Change Background')[0]?.destroy(); } catch(e){ console.error(e); } finally{ - restoreOrCreateUploadWindow() + restoreOrCreateUploadWindow(); } } }, { label: '', type: 'separator' }, @@ -130,9 +134,9 @@ app.whenReady().then(() => { checked: store.get('disableHardwareAcceleration'), click: () => { store.set('disableHardwareAcceleration', !store.get('disableHardwareAcceleration')); - app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) + app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }); app.exit(0) - } + }, }, //////////////////////////////////////////////////////////////////////////////// { label: 'Set framerate', type: 'submenu', submenu: @@ -142,8 +146,8 @@ app.whenReady().then(() => { click: () => { if(store.get('frameRate') !== 30){ store.set('frameRate', 30); - app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) - app.exit(0) + app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }); + app.exit(0); } }}, //////////////////////////////////////////////////////////////////////////////// @@ -152,11 +156,11 @@ app.whenReady().then(() => { click: () => { if(store.get('frameRate') !== 60){ store.set('frameRate', 60); - app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) - app.exit(0) + app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }); + app.exit(0); } - }} - ] + }}, + ] , }, { label: 'Open at startup', type: 'checkbox', @@ -165,17 +169,17 @@ app.whenReady().then(() => { store.set('openAtStartup', !store.get('openAtStartup')); app.setLoginItemSettings({ openAtLogin: store.get('openAtStartup'), - }) - app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) - app.exit(0) - } + }); + app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }); + app.exit(0); + }, }, { label: "Enable Audio (Not recommended)", type: 'checkbox', checked: store.get('enableAudio'), click: () => { store.set('enableAudio', !store.get('enableAudio')); - app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) - app.exit(0) + app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }); + app.exit(0); } }, { label: '', type: 'separator' }, //////////////////////////////////////////////////////////////////////////////// @@ -188,7 +192,34 @@ app.whenReady().then(() => { fs.mkdirSync(app.getPath('userData') + '/backgrounds'); } }); - +interface externalWindow { + x: number; + y: number; + } + interface displaySize { + width: number; + height: number; + } app.whenReady().then(() => { - useHandlers() -}) + useHandlers(); + + const displays = screen.getAllDisplays(); + + const externalDisplay = displays.find((display) => { + return display.bounds.x !== 0 || display.bounds.y !== 0; + }); + + const externalDisplayBounds = { + x: externalDisplay?.bounds.x, + y: externalDisplay?.bounds.y, + } as externalWindow; // typecast to avoid error + + const externalDisplaySize = { + width: externalDisplay?.bounds.width, + height: externalDisplay?.bounds.height, + } as displaySize; // typecast to avoid error + + if (externalDisplay) { + createExternalScreenWindow(externalDisplayBounds, externalDisplaySize); + } +}); diff --git a/packages/main/src/uploadBackroundWindow.ts b/packages/main/src/uploadBackroundWindow.ts index 51ea72f..df94712 100644 --- a/packages/main/src/uploadBackroundWindow.ts +++ b/packages/main/src/uploadBackroundWindow.ts @@ -1,6 +1,6 @@ /* es-lint-disable */ /* ts-lint-disable */ -import {BrowserWindow, app} from 'electron'; +import {BrowserWindow, app, screen} from 'electron'; import {join} from 'path'; import {URL} from 'url'; @@ -62,7 +62,7 @@ async function createUploadWindow() { let window = BrowserWindow.getAllWindows().find(w => !w.isDestroyed()); window?.webContents.session.clearCache(); - if (BrowserWindow.getAllWindows().length === 1) { + if (BrowserWindow.getAllWindows().length === 1 || BrowserWindow.getAllWindows().length === screen.getAllDisplays().length) { window = await createUploadWindow(); } else{ window = BrowserWindow.getAllWindows().filter(w => w.isMinimized())[0]; diff --git a/packages/renderer/src/App.vue b/packages/renderer/src/App.vue index e1c89c0..431296d 100644 --- a/packages/renderer/src/App.vue +++ b/packages/renderer/src/App.vue @@ -18,6 +18,13 @@ const isMainRoute:Ref = ref(!isChangeBackgroundRoute.value && !isUpload provide ("store", store); const backgroundVideo = ref(null); const {extension, shouldVideoBeMuted} = useBackground(isMainRoute,store); +try{ +window.ipcRenderer.invoke('instanceId', 'instanceId').then((id)=>{ + console.log(id); +}); +}catch(e){ + console.log(e); +} From 4a66f628467e69c4929acaa31d4429ca6b8d130c Mon Sep 17 00:00:00 2001 From: JoseMoreville <18040006@utculiacan.edu.mx> Date: Sun, 8 May 2022 01:16:42 -0600 Subject: [PATCH 2/7] feat: :construction: Each instance of background is now a different one. Now you can have different backgrounds on your screens, it should work fine with two screens but not so sure about three or more. It sould have a bg but not a different one that the second screen one. Will do some cleaning and improvements tomorrow. External screns are now different instances. --- packages/main/src/Handlers.ts | 27 +++++++---- packages/main/src/externalScreenWindow.ts | 8 ++-- packages/main/src/index.ts | 4 +- packages/main/src/mainWindow.ts | 14 ++++-- packages/renderer/externalScreen.html | 13 ++++++ packages/renderer/src/App.vue | 46 +++++++++++++++---- .../src/components/BackgroundThumbnail.vue | 10 +++- packages/renderer/src/modules/helpers.ts | 24 ++++++++-- .../src/views/BackgroundCollection.vue | 33 +++++++++++-- 9 files changed, 141 insertions(+), 38 deletions(-) create mode 100644 packages/renderer/externalScreen.html diff --git a/packages/main/src/Handlers.ts b/packages/main/src/Handlers.ts index 404156d..41b5a3c 100644 --- a/packages/main/src/Handlers.ts +++ b/packages/main/src/Handlers.ts @@ -7,18 +7,29 @@ const activeWindow = require('active-win'); export default function useHandlers(): void { ipcMain.handle("getBackground", (event, arg) => { - const file = - app.getPath("userData") + "/backgrounds/" + store.get("currentBackground"); - return file; + const collection = store.get("currentBackground"); + for (const screen in collection) { + if (Object.prototype.hasOwnProperty.call(collection, screen)) { + const background = app.getPath("userData") + "/backgrounds/" + collection[screen]; + collection[screen] = background + } + } + return collection; }); ipcMain.handle("changeBackground", (event, arg) => { - store.set( - "currentBackground", - arg.replace(`file://${app.getPath("userData")}/backgrounds/`, "") - ); + const DATA_BEFORE_UPDATE = store.get("currentBackground") + let UPDATED_DATA = { ...DATA_BEFORE_UPDATE} + for (const key in arg) { + if (Object.prototype.hasOwnProperty.call(arg, key)) { + const element = arg[key].replace(`file://${app.getPath("userData")}/backgrounds/`, ""); + UPDATED_DATA[key] = element + } + } + store.set("currentBackground", UPDATED_DATA); BrowserWindow.getAllWindows()[1].reload(); - return arg.replace(`file://${app.getPath("userData")}/backgrounds/`, ""); + BrowserWindow.getAllWindows()[2].reload(); + return UPDATED_DATA; }); ipcMain.handle("getBackgrounds", (event, arg) => { diff --git a/packages/main/src/externalScreenWindow.ts b/packages/main/src/externalScreenWindow.ts index bffdaeb..d14e472 100644 --- a/packages/main/src/externalScreenWindow.ts +++ b/packages/main/src/externalScreenWindow.ts @@ -45,7 +45,7 @@ export async function createExternalScreenWindow(position: {x: number, y: number browserWindow.on('ready-to-show', () => { browserWindow?.show(); if (import.meta.env.DEV) { - browserWindow?.webContents.openDevTools(); + //browserWindow?.webContents.openDevTools(); } }); @@ -54,9 +54,9 @@ export async function createExternalScreenWindow(position: {x: number, y: number * Vite dev server for development. * `file://../renderer/index.html` for production and test */ - const pageUrl = import.meta.env.DEV && import.meta.env.VITE_DEV_SERVER_URL !== undefined - ? import.meta.env.VITE_DEV_SERVER_URL - : new URL('../renderer/dist/index.html', 'file://' + __dirname).toString(); + const pageUrl = import.meta.env.DEV && import.meta.env.VITE_DEV_SERVER_URL !== undefined + ? import.meta.env.VITE_DEV_SERVER_URL +'externalScreen' + : new URL('../renderer/dist/externalScreen.html', 'file://' + __dirname).toString(); let data = ''; fs.readdir(`${app.getPath('userData')}/backgrounds`, async (err:Error, files: Array) => { diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index b3d7a09..a04d296 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -192,6 +192,7 @@ app.whenReady().then(() => { fs.mkdirSync(app.getPath('userData') + '/backgrounds'); } }); + interface externalWindow { x: number; y: number; @@ -200,6 +201,7 @@ interface externalWindow { width: number; height: number; } + app.whenReady().then(() => { useHandlers(); @@ -222,4 +224,4 @@ app.whenReady().then(() => { if (externalDisplay) { createExternalScreenWindow(externalDisplayBounds, externalDisplaySize); } -}); +}); \ No newline at end of file diff --git a/packages/main/src/mainWindow.ts b/packages/main/src/mainWindow.ts index 074b6f4..caf56b3 100644 --- a/packages/main/src/mainWindow.ts +++ b/packages/main/src/mainWindow.ts @@ -1,15 +1,17 @@ -import {BrowserWindow, screen, app} from 'electron'; +import {BrowserWindow, screen, app,ipcMain} from 'electron'; import {join} from 'path'; import {URL} from 'url'; const fs = require('fs'); const Store = require('electron-store'); const store = new Store(); +let browserWindow: BrowserWindow; + async function createWindow() { //browserWindow.setVisibleOnAllWorkspaces(true) // let the dock be on top of the window - const browserWindow = new BrowserWindow({ - type: 'desktop', + browserWindow = new BrowserWindow({ + type: 'desktop', x: screen.getPrimaryDisplay().workAreaSize.width - screen.getPrimaryDisplay().size.width + Math.abs(screen.getPrimaryDisplay().workAreaSize.width - screen.getPrimaryDisplay().size.width), @@ -104,4 +106,8 @@ export async function restoreOrCreateWindow() { } window.focus(); -} \ No newline at end of file +} + +ipcMain.handle('getAllScreens', () => { + return screen.getAllDisplays().length; +}); \ No newline at end of file diff --git a/packages/renderer/externalScreen.html b/packages/renderer/externalScreen.html new file mode 100644 index 0000000..444ca9c --- /dev/null +++ b/packages/renderer/externalScreen.html @@ -0,0 +1,13 @@ + + + + + + + externalScreen + + +
+ + + diff --git a/packages/renderer/src/App.vue b/packages/renderer/src/App.vue index 431296d..32fe0f6 100644 --- a/packages/renderer/src/App.vue +++ b/packages/renderer/src/App.vue @@ -12,19 +12,30 @@ const isChangeBackgroundRoute = computed(() => const isUploadBackgroundRoute = computed(() => window.location.href.includes("upload") || document.getElementsByTagName("title")[0].innerText.includes("Upload"), ); - +const isExternalScreen = computed(() => + window.location.href.includes("externalScreen") || document.getElementsByTagName("title")[0].innerText.includes("externalScreen"), +); const isMainRoute:Ref = ref(!isChangeBackgroundRoute.value && !isUploadBackgroundRoute.value); - +const NUMBER_OF_SCREENS = ref(1); +const INSTANCE_SCREEN_ID = ref(1); provide ("store", store); const backgroundVideo = ref(null); -const {extension, shouldVideoBeMuted} = useBackground(isMainRoute,store); + try{ -window.ipcRenderer.invoke('instanceId', 'instanceId').then((id)=>{ - console.log(id); -}); + window.ipcRenderer.invoke('getAllScreens').then(amount =>{ + NUMBER_OF_SCREENS.value = amount; + }); + if(isExternalScreen.value){ + window.ipcRenderer.invoke('instanceId', 'instanceId').then((id)=>{ + if(id < 2)return; + INSTANCE_SCREEN_ID.value = id; + }); + } + }catch(e){ console.log(e); } +const {extension, shouldVideoBeMuted} = useBackground(isMainRoute,store, INSTANCE_SCREEN_ID); @@ -32,24 +43,39 @@ window.ipcRenderer.invoke('instanceId', 'instanceId').then((id)=>{
- +
diff --git a/packages/renderer/src/components/BackgroundThumbnail.vue b/packages/renderer/src/components/BackgroundThumbnail.vue index 31c8a25..871ac1c 100644 --- a/packages/renderer/src/components/BackgroundThumbnail.vue +++ b/packages/renderer/src/components/BackgroundThumbnail.vue @@ -28,8 +28,10 @@ const props = defineProps<{ background: string; name?: string; + screen: number; }>(); - +// eslint-disable-next-line +const emit = defineEmits(['backgroundName']); const extension = props.background.split(".").pop(); function backgrounHover(event: MouseEvent) { @@ -40,6 +42,10 @@ function backgroundLeave(event: MouseEvent) { (event.target as HTMLVideoElement).currentTime = 0; } function backgroundClick() { - window.ipcRenderer.invoke('changeBackground', props.background); + const data = {[props.screen]: props.background}; + console.log(data); + window.ipcRenderer.invoke('changeBackground', data); + //window.ipcRenderer.invoke('changeBackground', props.background); + emit('backgroundName', props.background); } diff --git a/packages/renderer/src/modules/helpers.ts b/packages/renderer/src/modules/helpers.ts index 5cc0f05..c0fe744 100644 --- a/packages/renderer/src/modules/helpers.ts +++ b/packages/renderer/src/modules/helpers.ts @@ -5,7 +5,7 @@ interface StoreState { }; } -const useBackground = (isMainRoute: Ref, store: StoreState) => { +const useBackground = (isMainRoute: Ref, store: StoreState, screenId:Ref) => { const shouldVideoBeMuted = ref(true); const extension = ref(""); const isBackgroundActive:Ref = ref(true); @@ -44,9 +44,25 @@ const useBackground = (isMainRoute: Ref, store: StoreState) => { if (isMainRoute.value) { window.ipcRenderer .invoke("getBackground", "getBackground") - .then((backgroundLocation) => { - extension.value = backgroundLocation.split(".").pop(); - store.mutations.changeCurrentBackground(`file://${backgroundLocation}`); + .then((backgroundLocations) => { + // console.log(backgroundLocations); + for (const screen in backgroundLocations) { + if (Object.prototype.hasOwnProperty.call(backgroundLocations, screen)) { + if(screenId.value === parseInt(screen)){ + extension.value = backgroundLocations[screen].split(".").pop(); + console.log(backgroundLocations[screen], 'backgroundLocations[screen]'); + backgroundLocations[screen] = `file://${backgroundLocations[screen]}`; + store.mutations.changeCurrentBackground(backgroundLocations); + } + // const backgroundLocation = backgroundLocations[screen].split(".").pop(); + //console.log(screenId.value, 'screenId'); + //store.mutations.changeCurrentBackground(`file://${backgroundLocation}`); + + //console.log(element, 'element'); + } + } + /*extension.value = backgroundLocation.split(".").pop(); + store.mutations.changeCurrentBackground(`file://${backgroundLocation}`);*/ }); } }); diff --git a/packages/renderer/src/views/BackgroundCollection.vue b/packages/renderer/src/views/BackgroundCollection.vue index 7b163ba..42a79db 100644 --- a/packages/renderer/src/views/BackgroundCollection.vue +++ b/packages/renderer/src/views/BackgroundCollection.vue @@ -1,9 +1,13 @@