44
55/* spaces
66 * Copyright (C) 2015 Dean Oemcke
7+ * Copyright (C) 2025 Jeff Schiller (Codedread)
78 */
89
910import { dbService } from './dbService.js' ;
@@ -540,18 +541,18 @@ async function showSpacesOpenWindow(windowId, editMode) {
540541
541542 // otherwise re-create it
542543 } else {
543- // TODO(codedread): Handle multiple displays and errors .
544- const displays = await chrome . system . display . getInfo ( ) ;
545- let screen = displays [ 0 ] . bounds ;
546- const window = await chrome . windows . create (
547- {
548- type : 'popup' ,
549- url,
550- height : screen . height - 100 ,
551- width : Math . min ( screen . width , 1000 ) ,
552- top : 0 ,
553- left : 0 ,
554- } ) ;
544+ // Display on the left-hand side of the appropriate display .
545+ const workArea = await getTargetDisplayWorkArea ( ) ;
546+ const windowHeight = Math . round ( workArea . height * 0.9 ) ;
547+ const windowWidth = Math . min ( workArea . width - 100 , 1000 ) ;
548+ const window = await chrome . windows . create ( {
549+ type : 'popup' ,
550+ url,
551+ height : windowHeight ,
552+ width : windowWidth ,
553+ top : workArea . top ,
554+ left : workArea . left ,
555+ } ) ;
555556 spacesOpenWindowId = window . id ;
556557 await chrome . storage . local . set ( { spacesOpenWindowId : window . id } ) ;
557558 }
@@ -618,20 +619,19 @@ async function createOrShowSpacesPopupWindow(action, tabUrl) {
618619
619620 // otherwise create it
620621 } else {
621- // TODO(codedread): Handle multiple displays and errors.
622- const displays = await chrome . system . display . getInfo ( ) ;
623- let screen = displays [ 0 ] . bounds ;
624-
625- const window = await chrome . windows . create (
626- {
627- type : 'popup' ,
628- url : popupUrl ,
629- focused : true ,
630- height : 450 ,
631- width : 310 ,
632- top : screen . height - 450 ,
633- left : screen . width - 310 ,
634- } ) ;
622+ // Display in the lower-right corner of the appropriate display.
623+ const workArea = await getTargetDisplayWorkArea ( ) ;
624+ const popupHeight = 450 ;
625+ const popupWidth = 310 ;
626+ const window = await chrome . windows . create ( {
627+ type : 'popup' ,
628+ url : popupUrl ,
629+ focused : true ,
630+ height : popupHeight ,
631+ width : popupWidth ,
632+ top : Math . round ( workArea . top + workArea . height - popupHeight ) ,
633+ left : Math . round ( workArea . left + workArea . width - popupWidth ) ,
634+ } ) ;
635635 spacesPopupWindowId = window . id ;
636636 await chrome . storage . local . set ( { spacesPopupWindowId : window . id } ) ;
637637 }
@@ -863,18 +863,17 @@ async function handleLoadSession(sessionId, tabUrl) {
863863 return curTab . url ;
864864 } ) ;
865865
866- // TODO(codedread): Handle multiple displays and errors.
867- const displays = await chrome . system . display . getInfo ( ) ;
868- let screen = displays [ 0 ] . bounds ;
869-
870- const newWindow = await chrome . windows . create (
871- {
872- url : urls ,
873- height : screen . height - 100 ,
874- width : screen . width - 100 ,
875- top : 0 ,
876- left : 0 ,
877- } ) ;
866+ // Display new session over most of the appropriate display.
867+ const workArea = await getTargetDisplayWorkArea ( ) ;
868+ const windowHeight = workArea . height - 100 ;
869+ const windowWidth = workArea . width - 100 ;
870+ const newWindow = await chrome . windows . create ( {
871+ url : urls ,
872+ height : windowHeight ,
873+ width : windowWidth ,
874+ top : workArea . top ,
875+ left : workArea . left ,
876+ } ) ;
878877
879878 // force match this new window to the session
880879 await spacesService . matchSessionToWindow ( session , newWindow ) ;
@@ -1255,5 +1254,36 @@ function moveTabToWindow(tab, windowId) {
12551254 spacesService . queueWindowEvent ( windowId ) ;
12561255}
12571256
1257+ /**
1258+ * Determines the most appropriate display to show a new window on.
1259+ * It prefers the display containing the currently focused Chrome window.
1260+ * If no window is focused, it falls back to the primary display.
1261+ * @returns {Promise<chrome.system.display.Bounds> } A promise that resolves to the work area bounds of the target display.
1262+ */
1263+ async function getTargetDisplayWorkArea ( ) {
1264+ const [ displays , currentWindow ] = await Promise . all ( [
1265+ chrome . system . display . getInfo ( ) ,
1266+ chrome . windows . getCurrent ( ) . catch ( ( ) => null ) // Catch if no window is focused
1267+ ] ) ;
1268+
1269+ let targetDisplay = displays . find ( d => d . isPrimary ) || displays [ 0 ] ; // Default to primary
1270+
1271+ // Find the display that contains the center of the current window
1272+ if ( currentWindow ) {
1273+ const windowCenterX = currentWindow . left + currentWindow . width / 2 ;
1274+ const windowCenterY = currentWindow . top + currentWindow . height / 2 ;
1275+ const activeDisplay = displays . find ( display => {
1276+ const d = display . workArea ;
1277+ return windowCenterX >= d . left && windowCenterX < ( d . left + d . width ) &&
1278+ windowCenterY >= d . top && windowCenterY < ( d . top + d . height ) ;
1279+ } ) ;
1280+ if ( activeDisplay ) {
1281+ targetDisplay = activeDisplay ;
1282+ }
1283+ }
1284+
1285+ return targetDisplay . workArea ;
1286+ }
1287+
12581288// Exports for testing.
1259- export { cleanParameter } ;
1289+ export { cleanParameter , getTargetDisplayWorkArea } ;
0 commit comments