4444
4545def GetApplicationPath (file = None ):
4646 import re , os , platform
47+ # On Windows after downloading file and calling Browser.GoForward(),
48+ # current working directory is set to %UserProfile%.
49+ # Calling os.path.dirname(os.path.realpath(__file__))
50+ # returns for eg. "C:\Users\user\Downloads". A solution
51+ # is to cache path on first call.
52+ if not hasattr (GetApplicationPath , "dir" ):
53+ if hasattr (sys , "frozen" ):
54+ dir = os .path .dirname (sys .executable )
55+ elif "__file__" in globals ():
56+ dir = os .path .dirname (os .path .realpath (__file__ ))
57+ else :
58+ dir = os .getcwd ()
59+ GetApplicationPath .dir = dir
4760 # If file is None return current directory without trailing slash.
4861 if file is None :
4962 file = ""
5063 # Only when relative path.
5164 if not file .startswith ("/" ) and not file .startswith ("\\ " ) and (
5265 not re .search (r"^[\w-]+:" , file )):
53- if hasattr (sys , "frozen" ):
54- path = os .path .dirname (sys .executable )
55- elif "__file__" in globals ():
56- path = os .path .dirname (os .path .realpath (__file__ ))
57- else :
58- path = os .getcwd ()
59- path = path + os .sep + file
66+ path = GetApplicationPath .dir + os .sep + file
6067 if platform .system () == "Windows" :
6168 path = re .sub (r"[/\\]+" , re .escape (os .sep ), path )
6269 path = re .sub (r"[/\\]+$" , "" , path )
@@ -115,6 +122,15 @@ def __init__(self, url=None):
115122 # all parent panels/controls, if it's deeply embedded.
116123 self .mainPanel = wx .Panel (self , style = wx .WANTS_CHARS )
117124
125+ # Global client callbacks must be set before browser is created.
126+ clientHandler = ClientHandler ()
127+ cefpython .SetGlobalClientCallback ("OnCertificateError" ,
128+ clientHandler ._OnCertificateError )
129+ cefpython .SetGlobalClientCallback ("OnBeforePluginLoad" ,
130+ clientHandler ._OnBeforePluginLoad )
131+ cefpython .SetGlobalClientCallback ("OnAfterCreated" ,
132+ clientHandler ._OnAfterCreated )
133+
118134 windowInfo = cefpython .WindowInfo ()
119135 windowInfo .SetAsChild (self .mainPanel .GetGtkWidget ())
120136 # Linux requires adding "file://" for local files,
@@ -126,12 +142,8 @@ def __init__(self, url=None):
126142 browserSettings = g_browserSettings ,
127143 navigateUrl = url )
128144
129- clientHandler = ClientHandler ( self .browser )
145+ clientHandler . mainBrowser = self .browser
130146 self .browser .SetClientHandler (clientHandler )
131- cefpython .SetGlobalClientCallback ("OnCertificateError" ,
132- clientHandler ._OnCertificateError )
133- cefpython .SetGlobalClientCallback ("OnBeforePluginLoad" ,
134- clientHandler ._OnBeforePluginLoad )
135147
136148 jsBindings = cefpython .JavascriptBindings (
137149 bindToFrames = False , bindToPopups = True )
@@ -324,10 +336,10 @@ def Visit(self, cookie, count, total, deleteCookie):
324336 return True
325337
326338class ClientHandler :
327- mainBrowser = None
339+ mainBrowser = None # May be None for global client callbacks.
328340
329- def __init__ (self , browser ):
330- self . mainBrowser = browser
341+ def __init__ (self ):
342+ pass
331343
332344 # -------------------------------------------------------------------------
333345 # DisplayHandler
@@ -482,11 +494,12 @@ def OnProtocolExecution(self, browser, url, allowExecutionOut):
482494 allowExecutionOut [0 ] = True
483495
484496 def _OnBeforePluginLoad (self , browser , url , policyUrl , info ):
497+ # This is a global callback set using SetGlobalClientCallback().
485498 # Plugins are loaded on demand, only when website requires it,
486499 # the same plugin may be called multiple times.
487500 # This callback is called on the IO thread, thus print messages
488501 # may not be visible.
489- print ("[wxpython.py] RequestHandler::OnBeforePluginLoad ()" )
502+ print ("[wxpython.py] RequestHandler::_OnBeforePluginLoad ()" )
490503 print (" url = %s" % url )
491504 print (" policy url = %s" % policyUrl )
492505 print (" info.GetName() = %s" % info .GetName ())
@@ -497,7 +510,8 @@ def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
497510 return False
498511
499512 def _OnCertificateError (self , certError , requestUrl , callback ):
500- print ("[wxpython.py] RequestHandler::OnCertificateError()" )
513+ # This is a global callback set using SetGlobalClientCallback().
514+ print ("[wxpython.py] RequestHandler::_OnCertificateError()" )
501515 print (" certError = %s" % certError )
502516 print (" requestUrl = %s" % requestUrl )
503517 if requestUrl .startswith (
@@ -573,15 +587,37 @@ def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl):
573587 # LifespanHandler
574588 # -------------------------------------------------------------------------
575589
576- # Empty place-holders: popupFeatures, windowInfo, client, browserSettings.
590+ # ** This callback is executed on the IO thread **
591+ # Empty place-holders: popupFeatures, client.
577592 def OnBeforePopup (self , browser , frame , targetUrl , targetFrameName ,\
578593 popupFeatures , windowInfo , client , browserSettings ,\
579594 noJavascriptAccess ):
580595 print ("[wxpython.py] LifespanHandler::OnBeforePopup()" )
581596 print (" targetUrl = %s" % targetUrl )
597+ # Custom browser settings for popups:
598+ # > browserSettings[0] = {"plugins_disabled": True}
599+ # Set WindowInfo object:
600+ # > windowInfo[0] = cefpython.WindowInfo()
582601 allowPopups = True
583602 return not allowPopups
584603
604+ def _OnAfterCreated (self , browser ):
605+ # This is a global callback set using SetGlobalClientCallback().
606+ print ("[wxpython.py] LifespanHandler::_OnAfterCreated()" )
607+ print (" browserId=%s" % browser .GetIdentifier ())
608+
609+ def RunModal (self , browser ):
610+ print ("[wxpython.py] LifespanHandler::RunModal()" )
611+ print (" browserId=%s" % browser .GetIdentifier ())
612+
613+ def DoClose (self , browser ):
614+ print ("[wxpython.py] LifespanHandler::DoClose()" )
615+ print (" browserId=%s" % browser .GetIdentifier ())
616+
617+ def OnBeforeClose (self , browser ):
618+ print ("[wxpython.py] LifespanHandler::OnBeforeClose" )
619+ print (" browserId=%s" % browser .GetIdentifier ())
620+
585621 # -------------------------------------------------------------------------
586622 # JavascriptDialogHandler
587623 # -------------------------------------------------------------------------
0 commit comments