X Tutup
Skip to content

Commit 2e9cb3d

Browse files
committed
Making the code more strict typed.
In cefadvanced example added more methods for the Browser object to test. Setup script "fix_includes.py" is now checking for missing 'except *' statements for cdef/cpdef functions.
1 parent e3d50a5 commit 2e9cb3d

File tree

11 files changed

+299
-156
lines changed

11 files changed

+299
-156
lines changed

cefpython/browser.pyx

Lines changed: 79 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
# If you try to keep PyBrowser() objects inside c_vector you will get segmentation
66
# faults, as they will be garbage collected.
77

8-
cdef list g_pyBrowsers = []
9-
10-
# TODO: remove:
11-
# Debug("DisplayHandler_OnTitleChange(): cdef pyBrowser: %s" % pyBrowser)
8+
cdef dict g_pyBrowsers = {}
129

1310
cdef PyBrowser GetPyBrowser(CefRefPtr[CefBrowser] cefBrowser):
1411

@@ -17,39 +14,40 @@ cdef PyBrowser GetPyBrowser(CefRefPtr[CefBrowser] cefBrowser):
1714
if <void*>cefBrowser == NULL or not cefBrowser.get():
1815
Debug("GetPyBrowser(): returning None")
1916
return None
20-
17+
2118
cdef PyBrowser pyBrowser
22-
cdef CefWindowHandle windowHandle1
23-
cdef CefWindowHandle windowHandle2
19+
cdef int browserId
2420

25-
for pyBrowser in g_pyBrowsers:
26-
if pyBrowser.cefBrowser.get():
27-
if pyBrowser.cefBrowser.get().GetIdentifier() == cefBrowser.get().GetIdentifier():
28-
return pyBrowser
29-
else:
30-
Debug("GetPyBrowser(): removing an empty reference from g_pyBrowsers")
31-
# TODO.
21+
browserId = cefBrowser.get().GetIdentifier()
22+
if browserId in g_pyBrowsers:
23+
return g_pyBrowsers[browserId]
3224

33-
Debug("GetPyBrowser(): creating new PyBrowser")
25+
for id, pyBrowser in g_pyBrowsers.items():
26+
if not pyBrowser.cefBrowser.get():
27+
Debug("GetPyBrowser(): removing an empty CefBrowser reference, browserId=%s" % id)
28+
del g_pyBrowsers[id]
29+
30+
Debug("GetPyBrowser(): creating new PyBrowser, browserId=%s" % browserId)
3431
pyBrowser = PyBrowser()
3532
pyBrowser.cefBrowser = cefBrowser
36-
g_pyBrowsers.append(pyBrowser)
33+
g_pyBrowsers[browserId] = pyBrowser
3734
return pyBrowser
3835

3936
cpdef PyBrowser GetBrowserByWindowHandle(int windowHandle):
4037

4138
cdef PyBrowser pyBrowser
42-
for pyBrowser in g_pyBrowsers:
43-
if (pyBrowser.GetWindowHandle() == windowHandle or
39+
for browserId in g_pyBrowsers:
40+
pyBrowser = g_pyBrowsers[browserId]
41+
if (pyBrowser.GetWindowHandle() == windowHandle or
4442
pyBrowser.GetUserData("__outerWindowHandle") == windowHandle):
4543
return pyBrowser
4644
return None
4745

4846
IF CEF_VERSION == 3:
49-
47+
5048
cdef CefRefPtr[CefBrowserHost] GetCefBrowserHost(
5149
CefRefPtr[CefBrowser] cefBrowser) except *:
52-
50+
5351
cdef CefRefPtr[CefBrowserHost] cefBrowserHost = cefBrowser.get().GetHost()
5452
if <void*>cefBrowserHost != NULL and cefBrowserHost.get():
5553
return cefBrowserHost
@@ -65,7 +63,7 @@ cdef class PyBrowser:
6563
IF CEF_VERSION == 1:
6664
cdef public JavascriptBindings javascriptBindings
6765
cdef public dict userData
68-
66+
6967
# Properties used by ToggleFullscreen().
7068
cdef public int isFullscreen
7169
cdef public int maximized
@@ -82,57 +80,57 @@ cdef class PyBrowser:
8280
IF CEF_VERSION == 3:
8381

8482
cdef CefRefPtr[CefBrowserHost] GetCefBrowserHost(self) except *:
85-
83+
8684
cdef CefRefPtr[CefBrowserHost] cefBrowserHost = self.GetCefBrowser().get().GetHost()
8785
if <void*>cefBrowserHost != NULL and cefBrowserHost.get():
8886
return cefBrowserHost
8987
raise Exception("PyBrowser.GetCefBrowserHost() failed: this method "
9088
"can only be called in the browser process.")
91-
89+
9290
def __init__(self):
9391

9492
self.clientCallbacks = {}
9593
self.allowedClientCallbacks = []
9694
self.userData = {}
9795

98-
cpdef object SetClientCallback(self, str name, object callback):
96+
cpdef py_void SetClientCallback(self, py_string name, object callback):
9997

10098
if not self.allowedClientCallbacks:
101-
99+
102100
# CefLoadHandler.
103101
self.allowedClientCallbacks += ["OnLoadEnd", "OnLoadError", "OnLoadStart"]
104-
102+
105103
# CefKeyboardHandler.
106104
self.allowedClientCallbacks += ["OnKeyEvent"]
107-
105+
108106
# CefV8ContextHandler.
109107
self.allowedClientCallbacks += ["OnUncaughtException"]
110-
108+
111109
# CefRequestHandler.
112-
self.allowedClientCallbacks += ["OnBeforeBrowse", "OnBeforeResourceLoad",
113-
"OnResourceRedirect", "OnResourceResponse", "OnProtocolExecution",
110+
self.allowedClientCallbacks += ["OnBeforeBrowse", "OnBeforeResourceLoad",
111+
"OnResourceRedirect", "OnResourceResponse", "OnProtocolExecution",
114112
"GetDownloadHandler", "GetAuthCredentials", "GetCookieManager"]
115-
113+
116114
# CefDisplayHandler.
117-
self.allowedClientCallbacks += ["OnAddressChange", "OnConsoleMessage",
118-
"OnContentsSizeChange", "OnNavStateChange", "OnStatusMessage",
115+
self.allowedClientCallbacks += ["OnAddressChange", "OnConsoleMessage",
116+
"OnContentsSizeChange", "OnNavStateChange", "OnStatusMessage",
119117
"OnTitleChange", "OnTooltip"]
120-
118+
121119
# LifespanHandler.
122120
self.allowedClientCallbacks += ["DoClose", "OnAfterCreated", "OnBeforeClose",
123121
"RunModal"]
124122

125123
if name not in self.allowedClientCallbacks:
126124
raise Exception("Browser.SetClientCallback() failed: unknown callback: %s" % name)
127-
125+
128126
self.clientCallbacks[name] = callback
129-
130-
cpdef object SetClientHandler(self, object clientHandler):
131-
127+
128+
cpdef py_void SetClientHandler(self, object clientHandler):
129+
132130
if not hasattr(clientHandler, "__class__"):
133131
raise Exception("Browser.SetClientHandler() failed: __class__ attribute missing")
134132
cdef dict methods = {}
135-
cdef str key
133+
cdef py_string key
136134
cdef object method
137135
cdef tuple value
138136
for value in inspect.getmembers(clientHandler, predicate=inspect.ismethod):
@@ -141,7 +139,7 @@ cdef class PyBrowser:
141139
if key and key[0] != '_':
142140
self.SetClientCallback(key, method)
143141

144-
cpdef object GetClientCallback(self, str name):
142+
cpdef object GetClientCallback(self, py_string name):
145143

146144
if name in self.clientCallbacks:
147145
return self.clientCallbacks[name]
@@ -152,7 +150,7 @@ cdef class PyBrowser:
152150

153151
IF CEF_VERSION == 1:
154152

155-
cpdef object SetJavascriptBindings(self, JavascriptBindings bindings):
153+
cpdef py_void SetJavascriptBindings(self, JavascriptBindings bindings):
156154

157155
self.javascriptBindings = bindings
158156

@@ -178,15 +176,15 @@ cdef class PyBrowser:
178176

179177
self.GetCefBrowser().get().ClearHistory()
180178

181-
cpdef object CloseBrowser(self):
179+
cpdef py_void CloseBrowser(self):
182180

183181
# In cefclient/cefclient_win.cpp there is only ParentWindowWillClose() called.
184182
# CloseBrowser() is called only for popups.
185183

186184
if self.GetUserData("__outerWindowHandle"):
187185
IF CEF_VERSION == 1:
188-
Debug("CefBrowser::ParentWindowWillClose()")
189-
self.GetCefBrowser().get().ParentWindowWillClose()
186+
Debug("CefBrowser::ParentWindowWillClose()")
187+
self.GetCefBrowser().get().ParentWindowWillClose()
190188
ELIF CEF_VERSION == 3:
191189
Debug("CefBrowserHost::ParentWindowWillClose()")
192190
self.GetCefBrowserHost().get().ParentWindowWillClose()
@@ -200,11 +198,11 @@ cdef class PyBrowser:
200198

201199
IF CEF_VERSION == 1:
202200

203-
cpdef object CloseDevTools(self):
204-
201+
cpdef py_void CloseDevTools(self):
202+
205203
self.GetCefBrowser().get().CloseDevTools()
206204

207-
cpdef object Find(self, int searchId, str searchText, py_bool forward,
205+
cpdef py_void Find(self, int searchId, py_string searchText, py_bool forward,
208206
py_bool matchCase, py_bool findNext):
209207

210208
cdef CefString cefSearchText
@@ -217,7 +215,7 @@ cdef class PyBrowser:
217215
assert IsCurrentThread(TID_UI), "Browser.GetFocusedFrame() may only be called on the UI thread"
218216
return GetPyFrame(self.GetCefBrowser().get().GetFocusedFrame())
219217

220-
cpdef PyFrame GetFrame(self, str name):
218+
cpdef PyFrame GetFrame(self, py_string name):
221219

222220
assert IsCurrentThread(TID_UI), "Browser.GetFrame() may only be called on the UI thread"
223221
cdef CefString cefName
@@ -242,7 +240,7 @@ cdef class PyBrowser:
242240

243241
return GetPyFrame(self.GetCefBrowser().get().GetMainFrame())
244242

245-
def GetOpenerWindowHandle(self):
243+
cpdef int GetOpenerWindowHandle(self) except *:
246244

247245
cdef HWND hwnd
248246
IF CEF_VERSION == 1:
@@ -251,20 +249,20 @@ cdef class PyBrowser:
251249
hwnd = self.GetCefBrowserHost().get().GetOpenerWindowHandle()
252250
return <int>hwnd
253251

254-
def GetOuterWindowHandle(self):
252+
cpdef int GetOuterWindowHandle(self) except *:
255253

256254
if self.GetUserData("__outerWindowHandle"):
257-
return self.GetUserData("__outerWindowHandle")
255+
return int(self.GetUserData("__outerWindowHandle"))
258256
else:
259257
return self.GetWindowHandle()
260258

261-
def GetUserData(self, key):
259+
cpdef object GetUserData(self, object key):
262260

263261
if key in self.userData:
264262
return self.userData[key]
265263
return None
266264

267-
def GetWindowHandle(self):
265+
cpdef int GetWindowHandle(self) except *:
268266

269267
cdef HWND hwnd
270268
IF CEF_VERSION == 1:
@@ -273,7 +271,7 @@ cdef class PyBrowser:
273271
hwnd = self.GetCefBrowserHost().get().GetWindowHandle()
274272
return <int>hwnd
275273

276-
def GetZoomLevel(self):
274+
cpdef double GetZoomLevel(self) except *:
277275

278276
IF CEF_VERSION == 1:
279277
assert IsCurrentThread(TID_UI), "Browser.GetZoomLevel() may only be called on the UI thread"
@@ -284,97 +282,98 @@ cdef class PyBrowser:
284282
zoomLevel = self.GetCefBrowserHost().get().GetZoomLevel()
285283
return zoomLevel
286284

287-
def GoBack(self):
285+
cpdef py_void GoBack(self):
288286

289287
self.GetCefBrowser().get().GoBack()
290288

291-
def GoForward(self):
289+
cpdef py_void GoForward(self):
292290

293291
self.GetCefBrowser().get().GoForward()
294292

295-
def HasDocument(self):
293+
cpdef py_bool HasDocument(self):
296294

297295
return self.GetCefBrowser().get().HasDocument()
298296

299297
IF CEF_VERSION == 1:
300298

301-
def HidePopup(self):
299+
cpdef py_void HidePopup(self):
302300

303301
self.GetCefBrowser().get().HidePopup()
304302

305-
def IsFullscreen(self):
303+
cpdef py_bool IsFullscreen(self):
306304

307305
return bool(self.isFullscreen)
308306

309-
def IsPopup(self):
307+
cpdef py_bool IsPopup(self):
310308

311309
return self.GetCefBrowser().get().IsPopup()
312310

313311
IF CEF_VERSION == 1:
314312

315-
def IsPopupVisible(self):
313+
cpdef py_bool IsPopupVisible(self):
316314

317315
assert IsCurrentThread(TID_UI), "Browser.IsPopupVisible() may only be called on the UI thread"
318316
return self.GetCefBrowser().get().IsPopupVisible()
319317

320-
def IsWindowRenderingDisabled(self):
318+
cpdef py_bool IsWindowRenderingDisabled(self):
321319

322320
return self.GetCefBrowser().get().IsWindowRenderingDisabled()
323321

324-
def Reload(self):
322+
cpdef py_void Reload(self):
325323

326324
self.GetCefBrowser().get().Reload()
327325

328-
def ReloadIgnoreCache(self):
326+
cpdef py_void ReloadIgnoreCache(self):
329327

330328
self.GetCefBrowser().get().ReloadIgnoreCache()
331329

332-
def SetFocus(self, enable):
330+
cpdef py_void SetFocus(self, enable):
333331

334332
IF CEF_VERSION == 1:
335333
self.GetCefBrowser().get().SetFocus(bool(enable))
336334
ELIF CEF_VERSION == 3:
337335
self.GetCefBrowserHost().get().SetFocus(bool(enable))
338336

339-
def SetUserData(self, key, value):
337+
cpdef py_void SetUserData(self, object key, object value):
340338

341339
self.userData[key] = value
342340

343-
def SetZoomLevel(self, zoomLevel):
341+
cpdef py_void SetZoomLevel(self, double zoomLevel):
344342

345343
IF CEF_VERSION == 1:
346-
self.GetCefBrowser().get().SetZoomLevel(<double>float(zoomLevel))
344+
self.GetCefBrowser().get().SetZoomLevel(zoomLevel)
347345
ELIF CEF_VERSION == 3:
348-
self.GetCefBrowserHost().get().SetZoomLevel(<double>float(zoomLevel))
346+
self.GetCefBrowserHost().get().SetZoomLevel(zoomLevel)
349347

350348
IF CEF_VERSION == 1:
351349

352-
def ShowDevTools(self):
350+
cpdef py_void ShowDevTools(self):
353351

354352
self.GetCefBrowser().get().ShowDevTools()
355353

356-
def StopLoad(self):
354+
cpdef py_void StopLoad(self):
357355

358356
self.GetCefBrowser().get().StopLoad()
359357

360358
IF CEF_VERSION == 1:
361359

362-
def StopFinding(self, clearSelection):
360+
cpdef py_void StopFinding(self, py_bool clearSelection):
363361

364362
self.GetCefBrowser().get().StopFinding(bool(clearSelection))
365363

366-
def ToggleFullscreen(self):
364+
cpdef py_void ToggleFullscreen(self):
367365

368366
IF UNAME_SYSNAME == "Windows":
369367

368+
cdef int windowHandle
370369
if self.GetUserData("__outerWindowHandle"):
371370
windowHandle = self.GetUserData("__outerWindowHandle")
372371
else:
373372
windowHandle = self.GetWindowHandle()
374-
373+
375374
# Offscreen browser will have an empty window handle.
376375
assert windowHandle, "Browser.ToggleFullscreen() failed: no window handle found"
377-
376+
378377
cdef HWND hwnd = <HWND><int>int(windowHandle)
379378
cdef RECT rect
380379
cdef HMONITOR monitor
@@ -384,7 +383,7 @@ cdef class PyBrowser:
384383
# Logic copied from chromium > fullscreen_handler.cc > FullscreenHandler::SetFullscreenImpl:
385384
# http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc
386385

387-
for_metro = False
386+
cdef py_bool for_metro = False
388387

389388
if not self.isFullscreen:
390389
self.maximized = IsZoomed(hwnd)
@@ -394,7 +393,10 @@ cdef class PyBrowser:
394393
self.gwlExStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
395394
GetWindowRect(hwnd, &rect)
396395
self.windowRect = (rect.left, rect.top, rect.right, rect.bottom)
397-
396+
397+
cdef int remove_style, remove_exstyle
398+
cdef int left, top, right, bottom
399+
398400
if not self.isFullscreen:
399401
remove_style = WS_CAPTION | WS_THICKFRAME
400402
remove_exstyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE

0 commit comments

Comments
 (0)
X Tutup