@@ -35,6 +35,31 @@ BrowserRenderHandler::~BrowserRenderHandler()
3535 surfaceHandles.clear ();
3636}
3737
38+ void BrowserRenderHandler::OnPopupSize (CefRefPtr<CefBrowser> browser,
39+ const CefRect& rect)
40+ {
41+ if (rect.width <= 0 || rect.height <= 0 )
42+ return ;
43+
44+ originalPopupRect = rect;
45+ popupRect = GetPopupRectInWebView (originalPopupRect);
46+ }
47+
48+ void BrowserRenderHandler::OnPopupShow (CefRefPtr<CefBrowser> browser,
49+ bool show)
50+ {
51+ if (!show)
52+ {
53+ ClearPopupRects ();
54+ browserListener->DestroyPopupSurface ();
55+ }
56+ }
57+
58+ void BrowserRenderHandler::ClearPopupRects () {
59+ popupRect.Set (0 , 0 , 0 , 0 );
60+ originalPopupRect.Set (0 , 0 , 0 , 0 );
61+ }
62+
3863bool
3964BrowserRenderHandler::GetViewRect (CefRefPtr<CefBrowser> browser, CefRect &rect)
4065{
@@ -44,37 +69,90 @@ BrowserRenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
4469 return true ;
4570}
4671
47-
72+ CefRect BrowserRenderHandler::GetPopupRectInWebView (const CefRect& originalRect)
73+ {
74+ CefRect rc (originalRect);
75+ // if x or y are negative, move them to 0.
76+ if (rc.x < 0 )
77+ rc.x = 0 ;
78+ if (rc.y < 0 )
79+ rc.y = 0 ;
80+ // if popup goes outside the view, try to reposition origin
81+ if (rc.x + rc.width > width)
82+ rc.x = width - rc.width ;
83+ if (rc.y + rc.height > height)
84+ rc.y = height - rc.height ;
85+ // if x or y became negative, move them to 0 again.
86+ if (rc.x < 0 )
87+ rc.x = 0 ;
88+ if (rc.y < 0 )
89+ rc.y = 0 ;
90+ return rc;
91+ }
4892
4993void BrowserRenderHandler::OnPaint (CefRefPtr<CefBrowser> browser,
5094 PaintElementType type, const RectList &dirtyRects,
5195 const void *data, int width, int height)
5296{
5397 (void )browser;
54- (void )type;
55- (void )dirtyRects;
5698
99+ if (type == PET_VIEW)
100+ {
101+ viewWidth = width;
102+ viewHeight = height;
103+ if (surfaceHandles.size () < 2 ) {
104+ BrowserSurfaceHandle newSurfaceHandle = 0 ;
105+ browserListener->CreateSurface (width, height,
106+ &newSurfaceHandle);
107+
108+ if (newSurfaceHandle != nullptr ) {
109+ surfaceHandles.push_back (newSurfaceHandle);
110+ }
111+ }
112+
113+ int previousSurfaceHandle = currentSurfaceHandle;
57114
58- if (surfaceHandles.size () < 2 ) {
59- BrowserSurfaceHandle newSurfaceHandle = 0 ;
60- browserListener->CreateSurface (width, height,
61- &newSurfaceHandle);
115+ currentSurfaceHandle = (++currentSurfaceHandle % surfaceHandles.size ());
62116
63- if (newSurfaceHandle != nullptr ) {
64- surfaceHandles.push_back (newSurfaceHandle);
117+ if (currentSurfaceHandle != previousSurfaceHandle) {
118+ obs_enter_graphics ();
119+ gs_texture_set_image (surfaceHandles[currentSurfaceHandle],
120+ (const uint8_t *)data, width * 4 , false );
121+ obs_leave_graphics ();
65122 }
66123 }
67-
68- int previousSurfaceHandle = currentSurfaceHandle;
69-
70- currentSurfaceHandle = (++currentSurfaceHandle % surfaceHandles.size ());
124+ else if (type == PET_POPUP && popupRect.width > 0 &&
125+ popupRect.height > 0 )
126+ {
127+ int skipPixels = 0 , x = popupRect.x ;
128+ int skipRows = 0 , y = popupRect.y ;
129+ int w = width;
130+ int h = height;
131+
132+ if (x < 0 )
133+ {
134+ skipPixels = -x;
135+ x = 0 ;
136+ }
71137
72- if (currentSurfaceHandle != previousSurfaceHandle) {
138+ if (y < 0 )
139+ {
140+ skipRows = -y;
141+ y = 0 ;
142+ }
143+ if (x + w > viewWidth)
144+ w -= x + w - viewWidth;
145+ if (y + h > viewHeight)
146+ h -= y + h - viewHeight;
147+
73148 obs_enter_graphics ();
74- gs_texture_set_image (surfaceHandles[currentSurfaceHandle],
75- (const uint8_t *) data, width * 4 , false );
149+ BrowserSurfaceHandle newTexture = 0 ;
150+ browserListener->CreatePopupSurface (width, height, x, y, &newTexture);
151+ gs_texture_set_image (newTexture,
152+ (const uint8_t *)data, w * 4 , false );
76153 obs_leave_graphics ();
77154 }
78155
79- browserListener->OnDraw (surfaceHandles[currentSurfaceHandle], width, height);
156+
157+ browserListener->OnDraw (surfaceHandles[currentSurfaceHandle], viewWidth, viewHeight);
80158}
0 commit comments