Skip to content

Commit 8fa6ed9

Browse files
committed
RequestHandler is now using 'public' declarations instead
of callbacks, need to migrate other callbacks too (Issue 9). Unicode is converted to bytes automatically when passing data to javascript (Issue 10). Tuple is converted to a list when passing to javascript (Issue 10).
1 parent 5123d93 commit 8fa6ed9

18 files changed

+235
-344
lines changed

cefexample/cefadvanced.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ <h4>Infinite recursion</h4>
8484
<h3>Javasript callbacks</h3>
8585

8686
<script>
87-
function MyJSCallback(arg1, arg2)
87+
function MyJSCallback(arg1, arg2, arg3, arg4)
8888
{
89-
alert("MyJSCallback() called\narg1="+JSON.stringify(arg1)+"\narg2="+JSON.stringify(arg2))
89+
alert("MyJSCallback() called\narg1="+JSON.stringify(arg1)+"\narg2="+JSON.stringify(arg2)+"\narg3="+JSON.stringify(arg3)+"\narg4="+JSON.stringify(arg4))
9090
}
9191
</script>
9292

cefexample/cefadvanced.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ def QuitApplication(windowID, msg, wparam, lparam):
2424
win32gui.PostQuitMessage(0)
2525
return 0
2626

27-
def WMTIMER(windowID, msg, wparam, lparam):
28-
29-
# do nothing.
30-
return 0
31-
3227
def CefAdvanced():
3328

3429
sys.excepthook = cefpython.ExceptHook # In case of exception display it, write to error.log, shutdown CEF and exit application.
@@ -52,8 +47,6 @@ def CefAdvanced():
5247
}
5348
windowID = cefwindow.CreateWindow("CefAdvanced", "cefadvanced", 800, 600, None, None, "icon.ico", wndproc)
5449

55-
cefpython.FixUIThreadResponsiveness(windowID)
56-
5750
browserSettings = dict() # See: http://code.google.com/p/cefpython/wiki/BrowserSettings
5851
browserSettings["history_disabled"] = False # Backspace key will act as "History back" action in browser.
5952
browserSettings["universal_access_from_file_urls_allowed"] = True
@@ -94,6 +87,8 @@ def CefAdvanced():
9487
# http://127.0.0.1/cefpython/src/tests/httpauthentication.php
9588
__browser = cefpython.CreateBrowser(windowID, browserSettings, "cefadvanced.html", handlers, bindings)
9689

90+
print "CefAdvanced(): browser created"
91+
9792
cefpython.MessageLoop()
9893
cefpython.Shutdown()
9994
os.kill(os.getpid(), 9) # A temporary fix for Issue 2.
@@ -142,8 +137,8 @@ def TestJavascriptCallback(jsCallback):
142137

143138
if isinstance(jsCallback, cefpython.JavascriptCallback):
144139
print("TestJavascriptCallback(): jsCallback.GetName(): %s" % jsCallback.GetName())
145-
print("jsCallback.Call(1, [2,3])")
146-
jsCallback.Call(1, [2,3])
140+
print("jsCallback.Call(1, [2,3], ('tuple', 'tuple'), 'unicode string')")
141+
jsCallback.Call(1, [2,3], ('tuple', 'tuple'), unicode('unicode string'))
147142
else:
148143
raise Exception("TestJavascriptCallback() failed: given argument is not a javascript callback function")
149144

cefpython.pyx

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@
1616
# you will get into big trouble, error messages are so much obfuscated and info
1717
# is missing that you will have no idea which chunk of code caused that error.
1818

19-
# All .pyx files need to be included here for Cython compiler.
19+
# About acquiring/releasing GIL lock, see discussion here:
20+
# https://groups.google.com/forum/?fromgroups=#!topic/cython-users/jcvjpSOZPp0
21+
22+
# Global variables.
23+
24+
global __debug
25+
__debug = False
26+
27+
global __applicationSettings
28+
__applicationSettings = None
29+
30+
# All .pyx files need to be included here.
31+
2032
include "imports.pyx"
2133
include "browser.pyx"
2234
include "frame.pyx"
@@ -36,19 +48,9 @@ include "javascriptcallback.pyx"
3648
include "pythoncallback.pyx"
3749
include "requesthandler.pyx"
3850

39-
# Global variables.
40-
__debug = False
41-
4251
# Client handler.
4352
cdef CefRefPtr[ClientHandler] __clientHandler = <CefRefPtr[ClientHandler]>new ClientHandler()
4453

45-
def FixUIThreadResponsiveness(windowID):
46-
47-
# OnBeforeResourceLoad is called on IO thread, when we acquire gil lock and execute
48-
# python code then the UI thread is not executing unless you do some UI action (minimize/restore window).
49-
cdef HWND hwnd = <HWND><int>windowID
50-
SetTimer(hwnd, 1, 10, <TIMERPROC>NULL)
51-
5254
def GetRealPath(file=None):
5355

5456
# This function is defined in 2 files: cefpython.pyx and cefwindow.py, if you make changes edit both files.
@@ -81,13 +83,20 @@ def __InitializeClientHandler():
8183
InitializeLoadHandler()
8284
InitializeKeyboardHandler()
8385
InitializeV8ContextHandler()
84-
InitializeRequestHandler()
8586

8687
def Initialize(applicationSettings={}):
8788

8889
if not "multi_threaded_message_loop" in applicationSettings:
8990
applicationSettings["multi_threaded_message_loop"] = False
9091

92+
# Issue 10: support for unicode when passing to javascript.
93+
if not "unicode_to_bytes_encoding" in applicationSettings:
94+
applicationSettings["unicode_to_bytes_encoding"] = "utf-8"
95+
96+
# We must make a copy as applicationSettings is a reference only that might get destroyed.
97+
global __applicationSettings
98+
__applicationSettings = copy.deepcopy(applicationSettings)
99+
91100
__InitializeClientHandler()
92101

93102
if __debug:
@@ -184,20 +193,25 @@ def GetBrowserByWindowID(windowID):
184193
else:
185194
return None
186195

187-
188196
def MessageLoop():
189197

190198
if __debug: print("CefRunMessageLoop()\n")
191-
CefRunMessageLoop()
199+
with nogil:
200+
CefRunMessageLoop()
192201

193202
def SingleMessageLoop():
194203

195204
# Perform a single iteration of CEF message loop processing. This function is
196205
# used to integrate the CEF message loop into an existing application message
197206
# loop.
198207

199-
if __debug: print("CefDoMessageLoopWork()\n")
200-
CefDoMessageLoopWork();
208+
# Message loop dooes significant amount of work so releasing GIL is worth it.
209+
210+
# anything that (1) can block for a significant amount of time and (2) is thread-safe should release the GIL:
211+
# https://groups.google.com/d/msg/cython-users/jcvjpSOZPp0/KHpUEX8IhnAJ
212+
213+
with nogil:
214+
CefDoMessageLoopWork();
201215

202216
def QuitMessageLoop():
203217

clienthandler.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,89 @@
11
#include "clienthandler.h"
2+
3+
// Cython doesn't know nothing about 'const' so we need to remove it,
4+
// otherwise you get compile error.
5+
6+
bool ClientHandler::OnBeforeResourceLoad(
7+
CefRefPtr<CefBrowser> browser,
8+
CefRefPtr<CefRequest> request,
9+
CefString& redirectUrl,
10+
CefRefPtr<CefStreamReader>& resourceStream,
11+
CefRefPtr<CefResponse> response,
12+
int loadFlags)
13+
{
14+
REQUIRE_IO_THREAD();
15+
return RequestHandler_OnBeforeResourceLoad(browser, request, redirectUrl, resourceStream, response, loadFlags);
16+
}
17+
18+
bool ClientHandler::OnBeforeBrowse(
19+
CefRefPtr<CefBrowser> browser,
20+
CefRefPtr<CefFrame> frame,
21+
CefRefPtr<CefRequest> request,
22+
cef_handler_navtype_t navType,
23+
bool isRedirect)
24+
{
25+
REQUIRE_UI_THREAD();
26+
return RequestHandler_OnBeforeBrowse(browser, frame, request, navType, isRedirect);
27+
}
28+
29+
void ClientHandler::OnResourceRedirect(
30+
CefRefPtr<CefBrowser> browser,
31+
const CefString& old_url,
32+
CefString& new_url)
33+
{
34+
REQUIRE_IO_THREAD();
35+
RequestHandler_OnResourceRedirect(browser, const_cast<CefString&>(old_url), new_url);
36+
}
37+
38+
void ClientHandler::OnResourceResponse(
39+
CefRefPtr<CefBrowser> browser,
40+
const CefString& url,
41+
CefRefPtr<CefResponse> response,
42+
CefRefPtr<CefContentFilter>& filter)
43+
{
44+
REQUIRE_UI_THREAD();
45+
RequestHandler_OnResourceResponse(browser, const_cast<CefString&>(url), response, filter);
46+
}
47+
48+
bool ClientHandler::OnProtocolExecution(
49+
CefRefPtr<CefBrowser> browser,
50+
const CefString& url,
51+
bool& allowOSExecution)
52+
{
53+
REQUIRE_IO_THREAD();
54+
return RequestHandler_OnProtocolExecution(browser, const_cast<CefString&>(url), allowOSExecution);
55+
}
56+
57+
bool ClientHandler::GetDownloadHandler(
58+
CefRefPtr<CefBrowser> browser,
59+
const CefString& mimeType,
60+
const CefString& fileName,
61+
int64 contentLength,
62+
CefRefPtr<CefDownloadHandler>& handler)
63+
{
64+
REQUIRE_UI_THREAD();
65+
return RequestHandler_GetDownloadHandler(browser, const_cast<CefString&>(mimeType), const_cast<CefString&>(fileName), contentLength, handler);
66+
}
67+
68+
bool ClientHandler::GetAuthCredentials(
69+
CefRefPtr<CefBrowser> browser,
70+
bool isProxy,
71+
const CefString& host,
72+
int port,
73+
const CefString& realm,
74+
const CefString& scheme,
75+
CefString& username,
76+
CefString& password)
77+
{
78+
REQUIRE_IO_THREAD();
79+
return RequestHandler_GetAuthCredentials(browser, isProxy, const_cast<CefString&>(host), port, const_cast<CefString&>(realm),
80+
const_cast<CefString&>(scheme), username, password);
81+
}
82+
83+
CefRefPtr<CefCookieManager> ClientHandler::GetCookieManager(
84+
CefRefPtr<CefBrowser> browser,
85+
const CefString& main_url)
86+
{
87+
REQUIRE_IO_THREAD();
88+
return RequestHandler_GetCookieManager(browser, const_cast<CefString&>(main_url));
89+
}

0 commit comments

Comments
 (0)