Skip to content

Commit ee978b6

Browse files
committed
Added a single global timer for running CEF message loop work (Issue 129).
Added a shell script that automates building the setup package and running the wx chromectrl example.
1 parent a694976 commit ee978b6

4 files changed

Lines changed: 72 additions & 27 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cefpython3-*
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
set -o verbose
2+
sudo rm -rf cefpython3-31.0-linux-64bit-setup/
3+
python make-setup.py -v 31.0
4+
cd cefpython3-31.0-linux-64bit-setup/
5+
sudo python setup.py install
6+
cd examples/wx/
7+
python sample1.py

cefpython/cef3/wx-subpackage/chromectrl.py

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Additional and wx specific layer of abstraction for the cefpython
22
# __author__ = "Greg Kacy <grkacy@gmail.com>"
33

4-
#--------------------------------------------------------------------------------
4+
#-------------------------------------------------------------------------------
55

66
from cefpython3 import cefpython
77
import os, sys, platform
@@ -10,9 +10,44 @@
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
1423
DEFAULT_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

1853
class 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

307337
class 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

326356
def 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

357389
def Shutdown():
358390
"""Shuts down CEF, should be called by app exiting code"""
359-
cefpython.Shutdown()
391+
DestroyMessageLoopTimer()
392+
cefpython.Shutdown()

cefpython/cef3/wx-subpackage/examples/sample1.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class MainFrame(wx.Frame):
99
def __init__(self):
1010
wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
11-
title='cefwx example1', size=(600,400))
11+
title='cefwx example1', size=(1024,768))
1212

1313
self.cefWindow = chrome.ChromeWindow(self,
1414
url=os.path.join(os.path.dirname(os.path.abspath(__file__)),
@@ -24,8 +24,12 @@ def OnClose(self, event):
2424
self.Destroy()
2525

2626
if __name__ == '__main__':
27-
chrome.Initialize()
28-
print('sample1.py: wx.version=%s' % wx.version())
27+
chrome.Initialize({
28+
"debug": True,
29+
"log_severity": chrome.cefpython.LOGSEVERITY_INFO,
30+
"release_dcheck_enabled": True,
31+
})
32+
print('[sample1.py] wx.version=%s' % wx.version())
2933
app = wx.PySimpleApp()
3034
MainFrame().Show()
3135
app.MainLoop()

0 commit comments

Comments
 (0)