Implemented python callbacks in CEF Python 3. · pythonthings/cefpython@be7dc4c · GitHub
Skip to content

Commit be7dc4c

Browse files
CzarekCzarek
authored andcommitted
Implemented python callbacks in CEF Python 3.
A call to context->Exit() was missing when converting CEF 3 values to V8 values.
1 parent d377aa8 commit be7dc4c

25 files changed

Lines changed: 499 additions & 156 deletions

cefpython/browser.pyx

Lines changed: 3 additions & 2 deletions

cefpython/cef3/client_handler/client_handler.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
4646
CefRefPtr<CefListValue> arguments = message->GetArgumentList();
4747
if (arguments->GetSize() == 3
4848
&& arguments->GetType(0) == VTYPE_INT // frameId
49-
&& arguments->GetType(1) == VTYPE_STRING // funcName
50-
&& arguments->GetType(2) == VTYPE_LIST) { // funcArguments
49+
&& arguments->GetType(1) == VTYPE_STRING // functionName
50+
&& arguments->GetType(2) == VTYPE_LIST) { // functionArguments
5151
int64 frameId = arguments->GetInt(0);
52-
CefString funcName = arguments->GetString(1);
53-
CefRefPtr<CefListValue> funcArguments = arguments->GetList(2);
52+
CefString functionName = arguments->GetString(1);
53+
CefRefPtr<CefListValue> functionArguments = arguments->GetList(2);
5454
CefRefPtr<CefFrame> frame = browser->GetFrame(frameId);
55-
V8FunctionHandler_Execute(browser, frame, funcName, funcArguments);
55+
V8FunctionHandler_Execute(browser, frame, functionName, functionArguments);
5656
return true;
5757
} else {
5858
DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \
@@ -71,7 +71,31 @@ bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
7171
", messageName = OnBrowserDestroyed");
7272
return false;
7373
}
74-
74+
} else if (messageName == "ExecutePythonCallback") {
75+
CefRefPtr<CefListValue> arguments = message->GetArgumentList();
76+
if (arguments->GetSize() == 2
77+
&& arguments->GetType(0) == VTYPE_INT // callbackId
78+
&& arguments->GetType(1) == VTYPE_LIST) { // functionArguments
79+
int callbackId = arguments->GetInt(0);
80+
CefRefPtr<CefListValue> functionArguments = arguments->GetList(1);
81+
ExecutePythonCallback(browser, callbackId, functionArguments);
82+
return true;
83+
} else {
84+
DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \
85+
", messageName = ExecutePythonCallback");
86+
return false;
87+
}
88+
} else if (messageName == "RemovePythonCallbacksForFrame") {
89+
CefRefPtr<CefListValue> arguments = message->GetArgumentList();
90+
if (arguments->GetSize() == 1 && arguments->GetType(0) == VTYPE_INT) {
91+
int frameId = arguments->GetInt(0);
92+
RemovePythonCallbacksForFrame(frameId);
93+
return true;
94+
} else {
95+
DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \
96+
", messageName = ExecutePythonCallback");
97+
return false;
98+
}
7599
}
76100
return false;
77101
}

cefpython/cef3/linux/binaries_32bit/wxpython.html

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,81 @@ <h3>Javascript bindings</h3>
7373
'python called from js and then js called from python')</a>
7474

7575

76+
77+
<h3>Javascript callbacks</h3>
78+
<script>
79+
function JSCallback(arg1) {
80+
window.alert(arg1)
81+
}
82+
</script>
83+
<pre>
84+
&lt;script&gt;
85+
function JSCallback(arg1) {
86+
window.alert(arg1)
87+
}
88+
&lt;/script&gt;
89+
</pre>
90+
<pre>
91+
def TestJSCallback(self, jsCallback):
92+
print("jsCallback.GetFunctionName() = %s" % jsCallback.GetFunctionName())
93+
print("jsCallback.GetFrame().GetIdentifier() = %s" % \
94+
jsCallback.GetFrame().GetIdentifier())
95+
jsCallback.Call("This message was sent from python using js callback")
96+
</pre>
97+
<a href="javascript:external.TestJSCallback(JSCallback)">
98+
external.TestJSCallback(JSCallback)</a>
99+
<script>
100+
function JSCallback2() {
101+
window.alert(JSON.stringify(arguments))
102+
}
103+
</script>
104+
<pre>
105+
&lt;script&gt;
106+
function JSCallback2() {
107+
window.alert(JSON.stringify(arguments))
108+
}
109+
&lt;/script&gt;
110+
</pre>
111+
<pre>
112+
def TestJSCallbackComplexArguments(self, jsObject):
113+
jsCallback = jsObject["myCallback"];
114+
jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \
115+
{"nested object":None}]], \
116+
{"nested list next":[{"deeply nested object":1}]})
117+
</pre>
118+
<a href="javascript:external.TestJSCallbackComplexArguments(
119+
{'myCallback':JSCallback2})">
120+
external.TestJSCallbackComplexArguments({"myCallback": JSCallback2})
121+
</a>
122+
123+
124+
125+
<h3>Python callbacks</h3>
126+
<script>
127+
function JSCallback3(pyCallback) {
128+
pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
129+
}
130+
</script>
131+
<pre>
132+
&lt;script&gt;
133+
function JSCallback3(pyCallback) {
134+
pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
135+
}
136+
&lt;/script&gt;
137+
</pre>
138+
<pre>
139+
def TestPythonCallback(self, jsCallback):
140+
jsCallback.Call(PyCallback)
141+
142+
def PyCallback(self, *args):
143+
message = "PyCallback() was executed successfully! Arguments: %s" \
144+
% str(args)
145+
print(message)
146+
self.mainBrowser.GetMainFrame().ExecuteJavascript(
147+
"window.alert(\"%s\")" % message)
148+
</pre>
149+
<a href="javascript:external.TestPythonCallback(JSCallback3)">
150+
external.TestPythonCallback(JSCallback3)</a>
151+
76152
</body>
77153
</html>

cefpython/cef3/linux/binaries_32bit/wxpython.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ def TestAllTypes(self, *args):
156156
def ExecuteFunction(self, *args):
157157
self.mainBrowser.GetMainFrame().ExecuteFunction(*args)
158158

159+
def TestJSCallback(self, jsCallback):
160+
print("jsCallback.GetFunctionName() = %s" % jsCallback.GetFunctionName())
161+
print("jsCallback.GetFrame().GetIdentifier() = %s" % \
162+
jsCallback.GetFrame().GetIdentifier())
163+
jsCallback.Call("This message was sent from python using js callback")
164+
165+
def TestJSCallbackComplexArguments(self, jsObject):
166+
jsCallback = jsObject["myCallback"];
167+
jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \
168+
{"nested object":None}]], \
169+
{"nested list next":[{"deeply nested object":1}]})
170+
171+
def TestPythonCallback(self, jsCallback):
172+
jsCallback.Call(self.PyCallback)
173+
174+
def PyCallback(self, *args):
175+
message = "PyCallback() was executed successfully! Arguments: %s" \
176+
% str(args)
177+
print(message)
178+
self.mainBrowser.GetMainFrame().ExecuteJavascript(
179+
"window.alert(\"%s\")" % message)
180+
159181
class MyApp(wx.App):
160182
timer = None
161183
timerID = 1

cefpython/cef3/linux/binaries_64bit/wxpython.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,34 @@ <h3>Javascript callbacks</h3>
120120
external.TestJSCallbackComplexArguments({"myCallback": JSCallback2})
121121
</a>
122122

123+
124+
125+
<h3>Python callbacks</h3>
126+
<script>
127+
function JSCallback3(pyCallback) {
128+
pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
129+
}
130+
</script>
131+
<pre>
132+
&lt;script&gt;
133+
function JSCallback3(pyCallback) {
134+
pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
135+
}
136+
&lt;/script&gt;
137+
</pre>
138+
<pre>
139+
def TestPythonCallback(self, jsCallback):
140+
jsCallback.Call(PyCallback)
141+
142+
def PyCallback(self, *args):
143+
message = "PyCallback() was executed successfully! Arguments: %s" \
144+
% str(args)
145+
print(message)
146+
self.mainBrowser.GetMainFrame().ExecuteJavascript(
147+
"window.alert(\"%s\")" % message)
148+
</pre>
149+
<a href="javascript:external.TestPythonCallback(JSCallback3)">
150+
external.TestPythonCallback(JSCallback3)</a>
151+
123152
</body>
124153
</html>

cefpython/cef3/linux/binaries_64bit/wxpython.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,16 @@ def TestJSCallbackComplexArguments(self, jsObject):
168168
{"nested object":None}]], \
169169
{"nested list next":[{"deeply nested object":1}]})
170170

171+
def TestPythonCallback(self, jsCallback):
172+
jsCallback.Call(self.PyCallback)
173+
174+
def PyCallback(self, *args):
175+
message = "PyCallback() was executed successfully! Arguments: %s" \
176+
% str(args)
177+
print(message)
178+
self.mainBrowser.GetMainFrame().ExecuteJavascript(
179+
"window.alert(\"%s\")" % message)
180+
171181
class MyApp(wx.App):
172182
timer = None
173183
timerID = 1

cefpython/cef3/linux/setup/cefpython.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ __PYX_EXTERN_C DL_IMPORT(void) ProcessMessage_OnBrowserDestroyed(int);
1616
__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>);
1717
__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(int, int64);
1818
__PYX_EXTERN_C DL_IMPORT(void) V8FunctionHandler_Execute(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, CefString &, CefRefPtr<CefListValue>);
19+
__PYX_EXTERN_C DL_IMPORT(void) RemovePythonCallbacksForFrame(int);
20+
__PYX_EXTERN_C DL_IMPORT(bool) ExecutePythonCallback(CefRefPtr<CefBrowser>, int, CefRefPtr<CefListValue>);
1921

2022
#endif /* !__PYX_HAVE_API__cefpython_py27 */
2123

cefpython/cef3/subprocess/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ subprocess:
1818
# -fPIC is required only for libraries included by Cython.
1919
g++ -Wall -Werror $(INC) $(LIB) main.cpp cefpython_app.cpp \
2020
v8function_handler.cpp v8utils.cpp javascript_callback.cpp \
21-
python_callback.cpp -lcef_dll_wrapper -lcef -o subprocess -Wl,-rpath,.
21+
-lcef_dll_wrapper -lcef -o subprocess -Wl,-rpath,.

cefpython/cef3/subprocess/Makefile-libcefpythonapp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ CC = g++
1212
CCFLAGS = -g -fPIC -Wall -Werror
1313

1414
SRC = cefpython_app.cpp v8function_handler.cpp v8utils.cpp \
15-
javascript_callback.cpp python_callback.cpp
15+
javascript_callback.cpp
1616
OBJ = $(SRC:.cpp=.o)
1717
OUT = libcefpythonapp.a
1818

cefpython/cef3/subprocess/cefpython_app.cpp

Lines changed: 17 additions & 6 deletions

0 commit comments

Comments
 (0)