@@ -21,7 +21,9 @@ window.widgetWindows = {
2121 openWindows : { } ,
2222 _posCache : { } ,
2323 focused : null ,
24+ draggingWindow : null ,
2425 _shortcutsInitialized : false ,
26+ _globalListenersInitialized : false ,
2527 _handleGlobalKeyDown ( e ) {
2628 const focused = window . widgetWindows . focused ;
2729 if ( ! focused || e . repeat ) return ; // Guard against no focus or rapid-fire repeat
@@ -60,6 +62,65 @@ window.widgetWindows = {
6062 e . stopPropagation ( ) ;
6163 }
6264 }
65+ } ,
66+ _initGlobalListeners ( ) {
67+ if ( this . _globalListenersInitialized ) return ;
68+
69+ this . _handleGlobalMouseMove = this . _handleGlobalMouseMove . bind ( this ) ;
70+ this . _handleGlobalMouseUp = this . _handleGlobalMouseUp . bind ( this ) ;
71+ this . _handleGlobalMouseDown = this . _handleGlobalMouseDown . bind ( this ) ;
72+
73+ document . addEventListener ( "mouseup" , this . _handleGlobalMouseUp , true ) ;
74+ document . addEventListener ( "mousemove" , this . _handleGlobalMouseMove , true ) ;
75+ document . addEventListener ( "mousedown" , this . _handleGlobalMouseDown , true ) ;
76+
77+ this . _globalListenersInitialized = true ;
78+ } ,
79+ _handleGlobalMouseMove ( e ) {
80+ if ( this . draggingWindow ) {
81+ this . draggingWindow . _docMouseMoveHandler ( e ) ;
82+ }
83+ } ,
84+ _handleGlobalMouseUp ( e ) {
85+ if ( this . draggingWindow ) {
86+ this . draggingWindow . _dragTopHandler ( e ) ;
87+ this . draggingWindow = null ;
88+ }
89+ } ,
90+ _handleGlobalMouseDown ( e ) {
91+ const isToolbarInteraction =
92+ e . target ?. closest &&
93+ ( e . target . closest ( "#toolbars" ) ||
94+ e . target . closest ( "#aux-toolbar" ) ||
95+ e . target . closest ( ".dropdown-content" ) ||
96+ e . target . closest ( ".dropdown-trigger" ) ) ;
97+
98+ const windows = Object . values ( this . openWindows ) . filter ( win => win !== undefined ) ;
99+ let focusedAny = false ;
100+
101+ for ( let i = 0 ; i < windows . length ; i ++ ) {
102+ const win = windows [ i ] ;
103+ if (
104+ e . target === win . _frame ||
105+ win . _frame . contains ( e . target ) ||
106+ win . _fullscreenEnabled ||
107+ isToolbarInteraction
108+ ) {
109+ // Focus this window
110+ win . _frame . style . opacity = "1" ;
111+ win . _frame . style . zIndex = "10000" ;
112+ this . focused = win ;
113+ focusedAny = true ;
114+ } else {
115+ // Dim other windows
116+ win . _frame . style . opacity = ".7" ;
117+ win . _frame . style . zIndex = "0" ;
118+ }
119+ }
120+
121+ if ( ! focusedAny ) {
122+ this . focused = null ;
123+ }
63124 }
64125} ;
65126
@@ -83,21 +144,13 @@ class WidgetWindow {
83144
84145 // Drag offset for correct positioning
85146 this . _dx = this . _dy = 0 ;
86- this . _dragging = false ;
87147 // RAF throttle flag for mousemove performance
88148 this . _rafTicking = false ;
89149
90150 this . _createUIelements ( ) ;
91151 this . _setupLanguage ( ) ;
92152
93- // Global watchers
94- this . _dragTopHandler = this . _dragTopHandler . bind ( this ) ;
95- this . _docMouseMoveHandler = this . _docMouseMoveHandler . bind ( this ) ;
96- this . _docMouseDownHandler = this . _docMouseDownHandler . bind ( this ) ;
97-
98- document . addEventListener ( "mouseup" , this . _dragTopHandler , true ) ;
99- document . addEventListener ( "mousemove" , this . _docMouseMoveHandler , true ) ;
100- document . addEventListener ( "mousedown" , this . _docMouseDownHandler , true ) ;
153+ window . widgetWindows . _initGlobalListeners ( ) ;
101154
102155 if ( ! window . widgetWindows . _shortcutsInitialized ) {
103156 // Use capture phase (true) to ensure global window control shortcuts are handled
@@ -183,7 +236,7 @@ class WidgetWindow {
183236 titleEl . id = `${ this . _key } WidgetID` ;
184237
185238 this . _nonclose . onmousedown = e => {
186- this . _dragging = true ;
239+ window . widgetWindows . draggingWindow = this ;
187240 if ( this . _maximized ) {
188241 // Perform special repositioning to make the drag feel right when
189242 // restoring a window from maximized.
@@ -286,8 +339,6 @@ class WidgetWindow {
286339 * @returns {void }
287340 */
288341 _docMouseMoveHandler ( e ) {
289- if ( ! this . _dragging ) return ;
290-
291342 // Throttle using requestAnimationFrame to prevent layout thrashing
292343 if ( this . _rafTicking ) return ;
293344 this . _rafTicking = true ;
@@ -324,44 +375,12 @@ class WidgetWindow {
324375 }
325376 }
326377
327- /**
328- * @private
329- * @param {MouseEvent } e
330- * @returns {void }
331- */
332- _docMouseDownHandler ( e ) {
333- const isToolbarInteraction =
334- e . target ?. closest &&
335- ( e . target . closest ( "#toolbars" ) ||
336- e . target . closest ( "#aux-toolbar" ) ||
337- e . target . closest ( ".dropdown-content" ) ||
338- e . target . closest ( ".dropdown-trigger" ) ) ;
339-
340- if (
341- e . target === this . _frame ||
342- this . _frame . contains ( e . target ) ||
343- this . _fullscreenEnabled ||
344- isToolbarInteraction
345- ) {
346- this . _frame . style . opacity = "1" ;
347- this . _frame . style . zIndex = "10000" ;
348- window . widgetWindows . focused = this ;
349- } else {
350- this . _frame . style . opacity = ".7" ;
351- this . _frame . style . zIndex = "0" ;
352- if ( window . widgetWindows . focused === this ) {
353- window . widgetWindows . focused = null ;
354- }
355- }
356- }
357-
358378 /**
359379 * @private
360380 * @param {MouseEvent } e
361381 * @returns {void }
362382 */
363383 _dragTopHandler ( e ) {
364- this . _dragging = false ;
365384 if ( this . _fullscreenEnabled && this . _frame . style . top === "64px" && ! this . _maximized ) {
366385 this . _maximize ( ) ;
367386 this . takeFocus ( ) ;
@@ -477,9 +496,6 @@ class WidgetWindow {
477496 * @returns {void }
478497 */
479498 close ( ) {
480- document . removeEventListener ( "mouseup" , this . _dragTopHandler , true ) ;
481- document . removeEventListener ( "mousemove" , this . _docMouseMoveHandler , true ) ;
482- document . removeEventListener ( "mousedown" , this . _docMouseDownHandler , true ) ;
483499 this . onclose ( ) ;
484500 }
485501
@@ -632,15 +648,6 @@ class WidgetWindow {
632648 * @returns {void }
633649 */
634650 destroy ( ) {
635- if ( this . _dragTopHandler ) {
636- document . removeEventListener ( "mouseup" , this . _dragTopHandler , true ) ;
637- }
638- if ( this . _docMouseMoveHandler ) {
639- document . removeEventListener ( "mousemove" , this . _docMouseMoveHandler , true ) ;
640- }
641- if ( this . _docMouseDownHandler ) {
642- document . removeEventListener ( "mousedown" , this . _docMouseDownHandler , true ) ;
643- }
644651 if ( this . _widget && this . _widgetWheelHandler ) {
645652 this . _widget . removeEventListener ( "wheel" , this . _widgetWheelHandler , false ) ;
646653 this . _widget . removeEventListener ( "DOMMouseScroll" , this . _widgetWheelHandler , false ) ;
0 commit comments