Skip to content

Commit 1671a40

Browse files
committed
Add RenderHandler.OnTextSelectionChanged and Browser.Invalidate (cztomczak#403).
Add tests for OnTextSelectionChanged. Add on_load_end() helper func in unit tests.
1 parent 073f9d2 commit 1671a40

File tree

11 files changed

+123
-5
lines changed

11 files changed

+123
-5
lines changed

api/Browser.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,23 @@ machinery.
591591
Returns true if a document has been loaded in the browser.
592592

593593

594+
### Invalidate
595+
596+
| | |
597+
| --- | --- |
598+
| element_type | PaintElementType |
599+
| __Return__ | void |
600+
601+
Description from upstream CEF:
602+
> Invalidate the view. The browser will call CefRenderHandler::OnPaint
603+
> asynchronously. This method is only used when window rendering is
604+
> disabled.
605+
606+
`PaintElementType` enum values defined in cefpython module:
607+
* PET_VIEW
608+
* PET_POPUP
609+
610+
594611
### IsFullscreen
595612

596613
| | |

api/RenderHandler.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,25 @@ Called when the browser's cursor has changed. If |type| is CT_CUSTOM then
177177
Called when the scroll offset has changed.
178178

179179

180+
### OnTextSelectionChanged
181+
182+
| Parameter | Type |
183+
| --- | --- |
184+
| browser | [Browser](Browser.md) |
185+
| selected_text | str |
186+
| selected_range | list[x, y] |
187+
| __Return__ | void |
188+
189+
Description from upstream CEF:
190+
> Called when text selection has changed for the specified |browser|.
191+
> |selected_text| is the currently selected text and |selected_range| is
192+
> the character range.
193+
194+
NOTE: this callback seems to be called only when selecting text
195+
with a mouse. When selecting text programmatically using javascript
196+
code it doesn't get called.
197+
198+
180199
### StartDragging
181200

182201
| Parameter | Type |

src/browser.pyx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ cdef class PyBrowser:
247247
"GetScreenRect",
248248
"OnPopupShow", "OnPopupSize", "OnPaint", "OnCursorChange",
249249
"OnScrollOffsetChanged",
250-
"StartDragging", "UpdateDragCursor"]
250+
"StartDragging", "UpdateDragCursor",
251+
"OnTextSelectionChanged"]
251252
# JavascriptDialogHandler
252253
self.allowedClientCallbacks += ["OnJavascriptDialog",
253254
"OnBeforeUnloadJavascriptDialog",
@@ -476,6 +477,10 @@ cdef class PyBrowser:
476477
cpdef py_bool HasDocument(self):
477478
return self.GetCefBrowser().get().HasDocument()
478479

480+
cpdef py_void Invalidate(self,
481+
cef_types.cef_paint_element_type_t element_type):
482+
return self.GetCefBrowserHost().get().Invalidate(element_type)
483+
479484
cpdef py_bool IsFullscreen(self):
480485
return bool(self.isFullscreen)
481486

src/cef_v59..v66_changes.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ NEW FEATURES
7171
------------
7272

7373
+ unittests/osr_test.py - new test for off-screen rendering mode
74+
+ cefpython.SetGlobalClientHandler
75+
+ Browser.Invalidate
7476

7577
internal/cef_types.h
7678
+ cef_log_severity_t: new key LOGSEVERITY_DEBUG (no need to expose,
@@ -85,10 +87,9 @@ internal/cef_types.h
8587
cef_accessibility_handler.h
8688
+ CefAccessibilityHandler
8789
+ CefRenderHandler::GetAccessibilityHandler
88-
+ cefpython.SetGlobalClientHandler
8990

9091
cef_render_handler.h
91-
- OnTextSelectionChanged
92+
+ OnTextSelectionChanged
9293

9394
cef_browser.h
9495
+ SetAccessibilityState

src/client_handler/render_handler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,11 @@ void RenderHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
106106
REQUIRE_UI_THREAD();
107107
RenderHandler_UpdateDragCursor(browser, operation);
108108
}
109+
110+
void RenderHandler::OnTextSelectionChanged(CefRefPtr<CefBrowser> browser,
111+
const CefString& selected_text,
112+
const CefRange& selected_range) {
113+
REQUIRE_UI_THREAD();
114+
RenderHandler_OnTextSelectionChanged(browser, selected_text,
115+
selected_range);
116+
}

src/client_handler/render_handler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ class RenderHandler : public CefRenderHandler,
6464
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
6565
cef_drag_operations_mask_t operation) override;
6666

67+
void OnTextSelectionChanged(CefRefPtr<CefBrowser> browser,
68+
const CefString& selected_text,
69+
const CefRange& selected_range) override;
70+
6771
private:
6872
IMPLEMENT_REFCOUNTING(RenderHandler);
6973
};

src/extern/cef/cef_browser.pxd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ from libcpp cimport bool as cpp_bool
1111
from libcpp.vector cimport vector as cpp_vector
1212
from cef_frame cimport CefFrame
1313
cimport cef_types
14-
from cef_types cimport int64, cef_state_t
14+
from cef_types cimport int64, cef_state_t, PaintElementType
1515
from cef_types cimport CefBrowserSettings, CefPoint
1616
from cef_drag_data cimport CefDragData
1717
from cef_types cimport CefMouseEvent
@@ -87,6 +87,7 @@ cdef extern from "include/cef_browser.h":
8787
void AddWordToDictionary(const CefString& word)
8888

8989
void SetAccessibilityState(cef_state_t accessibility_state)
90+
void Invalidate(cef_types.cef_paint_element_type_t type)
9091

9192

9293
cdef cppclass CefBrowser:

src/extern/cef/cef_types.pxd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,7 @@ cdef extern from "include/internal/cef_types.h":
377377
ctypedef enum cef_focus_source_t:
378378
FOCUS_SOURCE_NAVIGATION,
379379
FOCUS_SOURCE_SYSTEM,
380+
381+
cdef cppclass CefRange:
382+
int from_val "from"
383+
int to_val "to"

src/handlers/render_handler.pyx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
include "../cefpython.pyx"
66
include "../browser.pyx"
7+
include "../string_utils.pyx"
78

89
cimport cef_types
10+
from cef_types cimport CefRange
911

1012
# cef_paint_element_type_t, PaintElementType
1113
PET_VIEW = cef_types.PET_VIEW
@@ -288,3 +290,20 @@ cdef public void RenderHandler_UpdateDragCursor(
288290
(exc_type, exc_value, exc_trace) = sys.exc_info()
289291
sys.excepthook(exc_type, exc_value, exc_trace)
290292

293+
cdef public void RenderHandler_OnTextSelectionChanged(
294+
CefRefPtr[CefBrowser] cef_browser,
295+
const CefString& selected_text,
296+
const CefRange& selected_range
297+
) except * with gil:
298+
cdef PyBrowser browser
299+
try:
300+
browser = GetPyBrowser(cef_browser, "OnTextSelectionChanged")
301+
callback = browser.GetClientCallback("OnTextSelectionChanged")
302+
if callback:
303+
callback(browser=browser,
304+
selected_text=CefToPyString(selected_text),
305+
selected_range=[selected_range.from_val,
306+
selected_range.to_val])
307+
except:
308+
(exc_type, exc_value, exc_trace) = sys.exc_info()
309+
sys.excepthook(exc_type, exc_value, exc_trace)

unittests/_common.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
g_subtests_ran = 0
1616
g_js_code_completed = False
17+
g_on_load_end_callbacks = []
1718

1819

1920
def subtest_message(message):
@@ -51,6 +52,11 @@ def do_message_loop_work(work_loops):
5152
time.sleep(0.01)
5253

5354

55+
def on_load_end(callback, *args):
56+
global g_on_load_end_callbacks
57+
g_on_load_end_callbacks.append([callback, args])
58+
59+
5460
def js_code_completed():
5561
"""Sometimes window.onload can execute before javascript bindings
5662
are ready if the document loads very fast. When setting javascript
@@ -154,6 +160,12 @@ def OnLoadEnd(self, browser, frame, http_code, **_):
154160
frame.GetSource(self.frame_source_visitor)
155161
browser.ExecuteJavascript("print('LoadHandler.OnLoadEnd() ok')")
156162

163+
subtest_message("Executing callbacks registered with on_load_end()")
164+
global g_on_load_end_callbacks
165+
for callback_data in g_on_load_end_callbacks:
166+
callback_data[0](*callback_data[1])
167+
del g_on_load_end_callbacks
168+
157169
def OnLoadingStateChange(self, browser, is_loading, can_go_back,
158170
can_go_forward, **_):
159171
if is_loading:

0 commit comments

Comments
 (0)