11# Additional and wx specific layer of abstraction for the cefpython
22# __author__ = "Greg Kacy <grkacy@gmail.com>"
33
4- #--------------------------------------------------------------------------------
4+ #-------------------------------------------------------------------------------
55
66from cefpython3 import cefpython
77import os , sys , platform
1010
1111#-------------------------------------------------------------------------------
1212
13+ # CEF Python application settings
14+ g_settings = None
15+
16+ def Debug (msg ):
17+ if g_settings and "debug" in g_settings and g_settings ["debug" ]:
18+ print ("[chromectrl.py] " + msg )
19+
20+ #-------------------------------------------------------------------------------
21+
1322# Default timer interval when timer used to service CEF message loop
1423DEFAULT_TIMER_MILLIS = 10
1524
25+ # A global timer for CEF message loop processing.
26+ g_messageLoopTimer = None
27+
28+ def CreateMessageLoopTimer (timerMillis ):
29+ # This function gets called multiple times for each ChromeWindow
30+ # instance.
31+ global g_messageLoopTimer
32+ Debug ("CreateMesageLoopTimer" )
33+ if g_messageLoopTimer :
34+ return
35+ g_messageLoopTimer = wx .Timer ()
36+ g_messageLoopTimer .Start (timerMillis )
37+ Debug ("g_messageLoopTimer.GetId() = " \
38+ + str (g_messageLoopTimer .GetId ()))
39+ wx .EVT_TIMER (g_messageLoopTimer , g_messageLoopTimer .GetId (),\
40+ MessageLoopTimer )
41+
42+ def MessageLoopTimer (event ):
43+ cefpython .MessageLoopWork ()
44+
45+ def DestroyMessageLoopTimer ():
46+ global g_messageLoopTimer
47+ Debug ("DestroyMessageLoopTimer" )
48+ g_messageLoopTimer .Stop ()
49+ g_messageLoopTimer = None
50+
1651#-------------------------------------------------------------------------------
1752
1853class NavigationBar (wx .Panel ):
@@ -121,19 +156,23 @@ def __init__(self, parent, url="", useTimer=True,
121156 self .Bind (wx .EVT_SET_FOCUS , self .OnSetFocus )
122157 self .Bind (wx .EVT_SIZE , self .OnSize )
123158
159+ self ._useTimer = useTimer
124160 if useTimer :
125- self .timerID = 1
126- self ._CreateTimer (timerMillis )
161+ CreateMessageLoopTimer (timerMillis )
127162 else :
163+ # Currently multiple EVT_IDLE events might be registered
164+ # when creating multiple ChromeWindow instances. This will
165+ # result in calling CEF message loop work multiple times
166+ # simultaneously causing performance penalties and possibly
167+ # some unwanted behavior (CEF Python Issue 129).
168+ Debug ("WARNING: Using EVT_IDLE for CEF message loop processing" \
169+ " is not recommended" )
128170 self .Bind (wx .EVT_IDLE , self .OnIdle )
129171
130172 self .Bind (wx .EVT_CLOSE , self .OnClose )
131- self ._useTimer = useTimer
132173
133174 def OnClose (self , event ):
134- if self ._useTimer :
135- self .timer .Stop ()
136- else :
175+ if not self ._useTimer :
137176 try :
138177 self .Unbind (wx .EVT_IDLE )
139178 except :
@@ -144,15 +183,6 @@ def OnClose(self, event):
144183 pass
145184 self .browser .ParentWindowWillClose ()
146185
147- def _CreateTimer (self , millis ):
148- self .timer = wx .Timer (self , self .timerID )
149- self .timer .Start (millis ) #
150- wx .EVT_TIMER (self , self .timerID , self .OnTimer )
151-
152- def OnTimer (self , event ):
153- """Service CEF message loop when useTimer is True"""
154- cefpython .MessageLoopWork ()
155-
156186 def OnIdle (self , event ):
157187 """Service CEF message loop when useTimer is False"""
158188 cefpython .MessageLoopWork ()
@@ -179,11 +209,11 @@ def LoadUrl(self, url, onLoadStart=None, onLoadEnd=None):
179209
180210 browser = self .GetBrowser ()
181211 if cefpython .g_debug :
182- print ( "***** ChromeCtrl: LoadUrl() self: %s" % self )
183- print ( "***** ChromeCtrl: browser: %s" % browser )
184- print ( "***** ChromeCtrl: browser id: %s" % browser .GetIdentifier ())
185- print ( "***** ChromeCtrl: mainframe: %s" % browser .GetMainFrame ())
186- print ( "***** ChromeCtrl: mainframe id: %s" % \
212+ Debug ( " LoadUrl() self: %s" % self )
213+ Debug ( " browser: %s" % browser )
214+ Debug ( " browser id: %s" % browser .GetIdentifier ())
215+ Debug ( " mainframe: %s" % browser .GetMainFrame ())
216+ Debug ( " mainframe id: %s" % \
187217 browser .GetMainFrame ().GetIdentifier ())
188218 self .GetBrowser ().GetMainFrame ().LoadUrl (url )
189219
@@ -302,7 +332,7 @@ def OnLoadEnd(self, browser, frame, httpStatusCode):
302332
303333 def OnLoadError (self , browser , frame , errorCode , errorText , failedUrl ):
304334 # TODO
305- print ( "***** ChromeCtrl: ERROR LOADING URL : %s" % failedUrl )
335+ Debug ( " ERROR LOADING URL : %s" % failedUrl )
306336
307337class CallbackClientHandler (object ):
308338 def __init__ (self , onLoadStart = None , onLoadEnd = None ):
@@ -319,14 +349,15 @@ def OnLoadEnd(self, browser, frame, httpStatusCode):
319349
320350 def OnLoadError (self , browser , frame , errorCode , errorText , failedUrl ):
321351 # TODO
322- print ( "***** ChromeCtrl: ERROR LOADING URL : %s, %s" % (failedUrl , frame .GetUrl ()))
352+ Debug ( " ERROR LOADING URL : %s, %s" % (failedUrl , frame .GetUrl ()))
323353
324354#-------------------------------------------------------------------------------
325355
326356def Initialize (settings = None , debug = False ):
327357 """Initializes CEF, We should do it before initializing wx
328358 If no settings passed a default is used
329359 """
360+ global g_settings
330361 if not settings :
331362 settings = {}
332363 if not "log_severity" in settings :
@@ -352,8 +383,10 @@ def Initialize(settings=None, debug=False):
352383 settings ["log_file" ] = "debug.log" # Set to "" to disable.
353384 settings ["release_dcheck_enabled" ] = True
354385
386+ g_settings = settings
355387 cefpython .Initialize (settings )
356388
357389def Shutdown ():
358390 """Shuts down CEF, should be called by app exiting code"""
359- cefpython .Shutdown ()
391+ DestroyMessageLoopTimer ()
392+ cefpython .Shutdown ()
0 commit comments