Skip to content

Commit 0901789

Browse files
phillipberndtAndreasBilke
authored andcommitted
Create a separate window for glimagesink instances (See #240)
1 parent 5e95327 commit 0901789

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

src/classes/action/movie.vala

+17-4
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,25 @@ namespace pdfpc {
314314
Gst.Element ad_element = this.link_additional(n, queue, bin, rect);
315315
ad_element.link(sink);
316316
sink.set("force_aspect_ratio", false);
317-
318317
Gst.Video.Overlay xoverlay = (Gst.Video.Overlay) sink;
319-
xoverlay.set_window_handle(xid);
318+
319+
if(glimagesinkFactory != null) {
320+
var overlay_widget = this.controller.overlay_widget(n, this.area);
321+
if (overlay_widget.get_realized()) {
322+
xoverlay.set_window_handle((uint*)((Gdk.X11.Window) overlay_widget.get_window()).get_xid());
323+
}
324+
else {
325+
overlay_widget.realize.connect((event) => {
326+
xoverlay.set_window_handle((uint*)((Gdk.X11.Window) overlay_widget.get_window()).get_xid());
327+
});
328+
}
329+
}
330+
else {
331+
xoverlay.set_window_handle(xid);
332+
xoverlay.set_render_rectangle(rect.x*gdk_scale, rect.y*gdk_scale,
333+
rect.width*gdk_scale, rect.height*gdk_scale);
334+
}
320335
xoverlay.handle_events(false);
321-
xoverlay.set_render_rectangle(rect.x*gdk_scale, rect.y*gdk_scale,
322-
rect.width*gdk_scale, rect.height*gdk_scale);
323336
n++;
324337
}
325338

src/classes/presentation_controller.vala

+64-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ namespace pdfpc {
3939
* Controller handling all the triggered events/signals
4040
*/
4141
public class PresentationController : Object {
42-
4342
/**
4443
* The currently displayed slide
4544
*/
@@ -1369,6 +1368,70 @@ namespace pdfpc {
13691368
gdk_scale = view.scale_factor;
13701369
return (uint*) ((Gdk.X11.Window) view.get_window()).get_xid();
13711370
}
1371+
1372+
/**
1373+
* Create a widget corresponding to the Poppler.Rectangle for the nth
1374+
* controllable's main view, and return it. The widget is automatically
1375+
* destroyed when the slide changes. Note that the widget might not
1376+
* have been realized yet right after creation.
1377+
*/
1378+
public Gtk.Widget overlay_widget(int n, Poppler.Rectangle area) {
1379+
Controllable c = (n < this.controllables.size) ? this.controllables.get(n) : null;
1380+
View.Pdf view = c.main_view;
1381+
Gdk.Rectangle rect = view.convert_poppler_rectangle_to_gdk_rectangle(area);
1382+
1383+
var widget = new Gtk.EventBox();
1384+
widget.set_size_request(rect.width, rect.height);
1385+
widget.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK);
1386+
1387+
// Find the fixed view that the view belongs to; this could be
1388+
// improved by refactoring the API. Then add the widget to it.
1389+
Gtk.Container parent = view.parent;
1390+
while(parent != null && !(parent is Gtk.Fixed)) {
1391+
parent = parent.parent;
1392+
}
1393+
if(parent == null) {
1394+
printerr("Warning: Unhandled case in presentation_controller.overlay_pos(): View is not contained in a Gtk.Fixed\n");
1395+
}
1396+
else {
1397+
var allocation = Gtk.Allocation();
1398+
view.get_allocation(out allocation);
1399+
(parent as Gtk.Fixed).put(widget, rect.x + allocation.x, rect.y + allocation.y);
1400+
1401+
// Pass events on to the underlying view
1402+
widget.motion_notify_event.connect((event) => {
1403+
event.x += allocation.x + rect.x;
1404+
event.y += allocation.y + rect.y;
1405+
view.motion_notify_event(event);
1406+
return true;
1407+
});
1408+
widget.button_press_event.connect((event) => {
1409+
event.x += allocation.x + rect.x;
1410+
event.y += allocation.y + rect.y;
1411+
view.button_press_event(event);
1412+
return true;
1413+
});
1414+
widget.button_release_event.connect((event) => {
1415+
event.x += allocation.x + rect.x;
1416+
event.y += allocation.y + rect.y;
1417+
view.button_release_event(event);
1418+
return true;
1419+
});
1420+
}
1421+
1422+
// Set up automated removal of the widget
1423+
ulong handler_id = 0;
1424+
int slide_at_setup = this.current_slide_number;
1425+
handler_id = this.update_request.connect(() => {
1426+
if(this.current_slide_number != slide_at_setup) {
1427+
widget.destroy();
1428+
this.disconnect(handler_id);
1429+
}
1430+
});
1431+
1432+
widget.show();
1433+
return widget;
1434+
}
13721435
#endif
13731436
}
13741437
}

0 commit comments

Comments
 (0)