diff --git a/README.md b/README.md index 314dfc13..c1b933cf 100644 --- a/README.md +++ b/README.md @@ -156,8 +156,8 @@ directly. - [Tutorial](docs/Tutorial.md) -### API categories - +### API categories + #### Modules * [cefpython](api/cefpython.md#cefpython) module @@ -212,9 +212,9 @@ directly. * [StringVisitor](api/StringVisitor.md#stringvisitor-interface) interface * [WebRequestClient](api/WebRequestClient.md#webrequestclient-interface) interface - -### API index - + +### API index + * [Application settings](api/ApplicationSettings.md#application-settings) * [accept_language_list](api/ApplicationSettings.md#accept_language_list) * [auto_zooming](api/ApplicationSettings.md#auto_zooming) @@ -366,6 +366,7 @@ directly. * [MessageLoop](api/cefpython.md#messageloop) * [MessageLoopWork](api/cefpython.md#messageloopwork) * [PostTask](api/cefpython.md#posttask) + * [PostDelayedTask](api/cefpython.md#postdelayedtask) * [QuitMessageLoop](api/cefpython.md#quitmessageloop) * [SetGlobalClientCallback](api/cefpython.md#setglobalclientcallback) * [SetOsModalLoop](api/cefpython.md#setosmodalloop) diff --git a/api/API-index.md b/api/API-index.md index a1ab99c2..69f45920 100644 --- a/api/API-index.md +++ b/api/API-index.md @@ -153,6 +153,7 @@ * [MessageLoop](cefpython.md#messageloop) * [MessageLoopWork](cefpython.md#messageloopwork) * [PostTask](cefpython.md#posttask) + * [PostDelayedTask](cefpython.md#postdelayedtask) * [QuitMessageLoop](cefpython.md#quitmessageloop) * [SetGlobalClientCallback](cefpython.md#setglobalclientcallback) * [SetOsModalLoop](cefpython.md#setosmodalloop) diff --git a/api/cefpython.md b/api/cefpython.md index d93a16e3..ea7c54cd 100644 --- a/api/cefpython.md +++ b/api/cefpython.md @@ -23,6 +23,7 @@ Table of contents: * [MessageLoop](#messageloop) * [MessageLoopWork](#messageloopwork) * [PostTask](#posttask) + * [PostDelayedTask](#postdelayedtask) * [QuitMessageLoop](#quitmessageloop) * [SetGlobalClientCallback](#setglobalclientcallback) * [SetOsModalLoop](#setosmodalloop) @@ -229,7 +230,7 @@ Description from upstream CEF: | Parameter | Type | | --- | --- | -| threadId | int | +| thread | int | | func | object | | [args..] | mixed | | __Return__ | void | @@ -251,6 +252,20 @@ List of threads in the Renderer process: * cef.TID_RENDERER: The main thread in the renderer. Used for all webkit and V8 interaction. +### PostDelayedTask + +| Parameter | Type | +| --- | --- | +| thread | int | +| delay_ms | int | +| func | object | +| [args..] | mixed | +| __Return__ | void | + +Post a task for delayed execution on the specified thread. This +function behaves similarly to PostTask above, but with an additional +|delay_ms| argument. + ### QuitMessageLoop diff --git a/src/client_handler/task.cpp b/src/client_handler/task.cpp index 8767e515..ec032a2d 100644 --- a/src/client_handler/task.cpp +++ b/src/client_handler/task.cpp @@ -7,17 +7,23 @@ #include "include/base/cef_bind.h" void PostTaskWrapper(int threadId, int taskId) { - // Calling CefPostDelayedTask with 0ms delay seems to give - // better responsiveness than CefPostTask. In wxpython.py - // on Windows the freeze when creating popup window feels - // shorter, when compared to a call to CefPostTask. + CefPostTask( + static_cast(threadId), + CefCreateClosureTask(base::Bind( + &PyTaskRunnable, + taskId + )) + ); +} + +void PostDelayedTaskWrapper(int threadId, int64 delay_ms, int taskId) { CefPostDelayedTask( static_cast(threadId), CefCreateClosureTask(base::Bind( &PyTaskRunnable, taskId )), - 0 + delay_ms ); } diff --git a/src/client_handler/task.h b/src/client_handler/task.h index ee982169..1839d9e3 100644 --- a/src/client_handler/task.h +++ b/src/client_handler/task.h @@ -9,6 +9,7 @@ #include "include/cef_task.h" void PostTaskWrapper(int threadId, int taskId); +void PostDelayedTaskWrapper(int threadId, int64 delay_ms, int taskId); CefRefPtr CreateTask_SetCookie( CefCookieManager* obj, diff --git a/src/compile_time_constants.pxi b/src/compile_time_constants.pxi index 10ec798a..35f85002 100644 --- a/src/compile_time_constants.pxi +++ b/src/compile_time_constants.pxi @@ -1,3 +1,3 @@ # This file was generated by setup.py -DEF UNAME_SYSNAME = "Windows" +DEF UNAME_SYSNAME = "Linux" DEF PY_MAJOR_VERSION = 2 diff --git a/src/extern/cef/cef_task.pxd b/src/extern/cef/cef_task.pxd index 9ca2aaec..806cbe89 100644 --- a/src/extern/cef/cef_task.pxd +++ b/src/extern/cef/cef_task.pxd @@ -5,6 +5,7 @@ from libcpp cimport bool as cpp_bool # noinspection PyUnresolvedReferences cimport cef_types +from cef_types cimport int64 from cef_ptr cimport CefRefPtr cdef extern from "include/cef_task.h": @@ -12,7 +13,11 @@ cdef extern from "include/cef_task.h": ctypedef cef_types.cef_thread_id_t CefThreadId cdef cpp_bool CefCurrentlyOn(CefThreadId) - cdef cpp_bool CefPostTask(CefThreadId threadId, CefRefPtr[CefTask] task) + cdef cpp_bool CefPostTask(CefThreadId threadId, + CefRefPtr[CefTask] task) + cdef cpp_bool CefPostDelayedTask(CefThreadId threadId, + CefRefPtr[CefTask] task, + int64 delay_ms) cdef cppclass CefTask: pass diff --git a/src/extern/task.pxd b/src/extern/task.pxd index b4e75e14..14f2777b 100644 --- a/src/extern/task.pxd +++ b/src/extern/task.pxd @@ -11,11 +11,13 @@ from cef_cookie cimport CefCookie, CefCookieManager from cef_cookie cimport CefSetCookieCallback, CefDeleteCookiesCallback # noinspection PyUnresolvedReferences from libcpp cimport bool as cpp_bool +from cef_types cimport int64 cdef extern from "client_handler/task.h": void PostTaskWrapper(int threadId, int taskId) nogil + void PostDelayedTaskWrapper(int threadId, int64 delay_ms, int taskId) nogil cdef CefRefPtr[CefTask] CreateTask_SetCookie( CefCookieManager* obj, diff --git a/src/task.pyx b/src/task.pyx index 43f99425..2af14983 100644 --- a/src/task.pyx +++ b/src/task.pyx @@ -7,11 +7,11 @@ include "cefpython.pyx" g_taskMaxId = 0 g_tasks = {} -def PostTask(int threadId, object func, *args): +def PostTask(int thread, object func, *args): global g_tasks, g_taskMaxId # Validate threadId. - if threadId not in g_browserProcessThreads: + if thread not in g_browserProcessThreads: raise Exception("PoastTask failed: requires a browser process thread") # Validate func. @@ -31,7 +31,35 @@ def PostTask(int threadId, object func, *args): # Call C++ wrapper. cdef int cTaskId = int(g_taskMaxId) with nogil: - PostTaskWrapper(threadId, cTaskId) + PostTaskWrapper(thread, cTaskId) + + +def PostDelayedTask(int thread, int delay_ms, object func, *args): + global g_tasks, g_taskMaxId + + # Validate threadId. + if thread not in g_browserProcessThreads: + raise Exception("PoastTask failed: requires a browser process thread") + + # Validate func. + if not IsFunctionOrMethod(type(func)): + raise Exception("PostTask failed: not a function nor method") + + # Params. + cdef list params = list(args) + + # Keep func and params until PyTaskRunnable is called. + g_taskMaxId += 1 + g_tasks[str(g_taskMaxId)] = { + "func": func, + "params": params + } + + # Call C++ wrapper. + cdef int cTaskId = int(g_taskMaxId) + with nogil: + PostDelayedTaskWrapper(thread, delay_ms, cTaskId) + cdef public void PyTaskRunnable(int taskId) except * with gil: cdef object func