@@ -95,11 +95,39 @@ private void RegisterEvents()
9595 // Context Menu Event
9696 _webView . CoreWebView2 . ContextMenuRequested += async ( sender , args ) =>
9797 {
98+ // FAST PATH: If context menus are enabled and the user isn't listening for details,
99+ // just let the browser handle it immediately.
100+ // 1. LOCK CHECK: If manager is locked (e.g. during Nav), block immediately
101+ if ( _isLocked )
102+ {
103+ args . Handled = true ;
104+ return ;
105+ }
106+
107+ // 2. FAST PATH: If context menus are enabled and no custom listeners, allow default immediately.
108+ // This ensures "Inspect" and other standard items appear without lag.
109+ if ( _contextMenuEnabled && OnContextMenuRequested == null && OnContextMenu == null )
110+ {
111+ args . Handled = false ;
112+ return ;
113+ }
114+
115+ // Log the request for custom processing
98116 Log ( $ "ContextMenuRequested: Location={ args . Location . X } x{ args . Location . Y } , Target={ args . ContextMenuTarget . Kind } ") ;
117+
118+ // 3. SLOW PATH (Custom Handlers or Disabled Prefs)
119+ // Set handled state based on user preference
99120 args . Handled = ! _contextMenuEnabled ;
100121
122+ // If handled (user preference is disabled), we don't need to do more
123+ if ( args . Handled ) return ;
124+
125+ // Only proceed with script and deferral if someone is actually listening
126+ var deferral = args . GetDeferral ( ) ;
127+
101128 try
102129 {
130+ // To get the tagName, we need to query the DOM
103131 string script = "document.elementFromPoint(" + args . Location . X + "," + args . Location . Y + ").closest('table') ? 'TABLE' : document.elementFromPoint(" + args . Location . X + "," + args . Location . Y + ").tagName" ;
104132 string tagNameResult = await _webView . CoreWebView2 . ExecuteScriptAsync ( script ) ;
105133
@@ -112,24 +140,28 @@ private void RegisterEvents()
112140
113141 OnContextMenuRequested ? . Invoke ( this , FormatHandle ( _parentHandle ) , lnk , args . Location . X , args . Location . Y , sel ) ;
114142
115- string cleanSrc = src . Replace ( "\" " , "\\ \" " ) ;
116- string cleanLnk = lnk . Replace ( "\" " , "\\ \" " ) ;
117- string cleanSel = sel . Replace ( "\" " , "\\ \" " ) . Replace ( "\r " , "" ) . Replace ( "\n " , "\\ n" ) ;
118-
119- string json = "{" +
120- "\" x\" :" + args . Location . X + "," +
121- "\" y\" :" + args . Location . Y + "," +
122- "\" kind\" :\" " + k + "\" ," +
123- "\" tagName\" :\" " + tagName + "\" ," +
124- "\" src\" :\" " + cleanSrc + "\" ," +
125- "\" link\" :\" " + cleanLnk + "\" ," +
126- "\" selection\" :\" " + cleanSel + "\" " +
127- "}" ;
128-
129- OnContextMenu ? . Invoke ( this , FormatHandle ( _parentHandle ) , "JSON:" + json ) ;
143+ if ( OnContextMenu != null )
144+ {
145+ string cleanSrc = src . Replace ( "\" " , "\\ \" " ) ;
146+ string cleanLnk = lnk . Replace ( "\" " , "\\ \" " ) ;
147+ string cleanSel = sel . Replace ( "\" " , "\\ \" " ) . Replace ( "\r " , "" ) . Replace ( "\n " , "\\ n" ) ;
148+
149+ string json = "{" +
150+ "\" x\" :" + args . Location . X + "," +
151+ "\" y\" :" + args . Location . Y + "," +
152+ "\" kind\" :\" " + k + "\" ," +
153+ "\" tagName\" :\" " + tagName + "\" ," +
154+ "\" src\" :\" " + cleanSrc + "\" ," +
155+ "\" link\" :\" " + cleanLnk + "\" ," +
156+ "\" selection\" :\" " + cleanSel + "\" " +
157+ "}" ;
158+
159+ OnContextMenu ? . Invoke ( this , FormatHandle ( _parentHandle ) , "JSON:" + json ) ;
160+ }
130161 } ) ;
131162 }
132163 catch ( Exception ex ) { Debug . WriteLine ( "ContextMenu Error: " + ex . Message ) ; }
164+ finally { deferral . Complete ( ) ; }
133165 } ;
134166
135167 // Ad Blocking
@@ -318,6 +350,30 @@ private void RegisterEvents()
318350 {
319351 controller . AcceleratorKeyPressed += ( s , e ) =>
320352 {
353+ // 1. LOCK CHECK: If manager is locked, block F12/shortcuts
354+ if ( _isLocked )
355+ {
356+ e . Handled = true ;
357+ return ;
358+ }
359+
360+ // 2. PREFERENCE CHECK: If F12 and DevTools are disabled by user, block it.
361+ if ( e . VirtualKey == 123 && ! _areDevToolsEnabled )
362+ {
363+ e . Handled = true ;
364+ return ;
365+ }
366+
367+ // 3. FAST PATH: If DevTools are enabled and F12 is pressed, allow it immediately.
368+ if ( _areDevToolsEnabled && e . VirtualKey == 123 )
369+ {
370+ if ( string . IsNullOrEmpty ( _blockedVirtualKeys ) || ! _blockedVirtualKeys . Split ( ',' ) . Any ( k => k . Trim ( ) == "123" ) )
371+ {
372+ e . Handled = false ;
373+ return ;
374+ }
375+ }
376+
321377 var eventArgs = new WebView2AcceleratorKeyPressedEventArgs ( e , this ) ;
322378 if ( ! string . IsNullOrEmpty ( _blockedVirtualKeys ) )
323379 {
@@ -328,7 +384,10 @@ private void RegisterEvents()
328384 eventArgs . Block ( ) ;
329385 }
330386 }
387+
388+ // Only invoke if someone is listening or if it's not a standard system key
331389 OnAcceleratorKeyPressed ? . Invoke ( this , FormatHandle ( _parentHandle ) , eventArgs ) ;
390+
332391 if ( eventArgs . IsCurrentlyHandled ) e . Handled = true ;
333392 } ;
334393 }
0 commit comments