gnome: fix clutter fullscreen issues
Seems to fix the ocasional image "corruption"
which happens when the video is put into fullscreen
by creating a new VideoWidget in the fullscreen
window and pausing rendering in the VideoWidget of
the main window, instead of moving the VideoWidget.
Refs #74096
Change-Id: Iae87f815545065cf8a799bfa50dd9865a0b8f26e
diff --git a/src/video/video_widget.cpp b/src/video/video_widget.cpp
index ac0080d..6e6b72f 100644
--- a/src/video/video_widget.cpp
+++ b/src/video/video_widget.cpp
@@ -98,6 +98,7 @@
* this will be set back to false once the black frame is rendered
*/
std::atomic_bool show_black_frame;
+ std::atomic_bool pause_rendering;
QMetaObject::Connection frame_update;
QMetaObject::Connection render_stop;
QMetaObject::Connection render_start;
@@ -411,6 +412,9 @@
auto actor = wg_renderer->actor;
g_return_if_fail(CLUTTER_IS_ACTOR(actor));
+ if (wg_renderer->pause_rendering)
+ return;
+
if (wg_renderer->show_black_frame) {
/* render a black frame set the bool back to false, this is likely done
* when the renderer is stopped so we ignore whether or not it is running
@@ -671,3 +675,13 @@
g_async_queue_push(priv->new_renderer_queue, new_video_renderer);
}
+
+void
+video_widget_pause_rendering(VideoWidget *self, gboolean pause)
+{
+ g_return_if_fail(IS_VIDEO_WIDGET(self));
+ VideoWidgetPrivate *priv = VIDEO_WIDGET_GET_PRIVATE(self);
+
+ priv->local->pause_rendering = pause;
+ priv->remote->pause_rendering = pause;
+}
diff --git a/src/video/video_widget.h b/src/video/video_widget.h
index b456a4e..64fa81f 100644
--- a/src/video/video_widget.h
+++ b/src/video/video_widget.h
@@ -55,6 +55,7 @@
GType video_widget_get_type (void) G_GNUC_CONST;
GtkWidget* video_widget_new (void);
void video_widget_push_new_renderer (VideoWidget *, Video::Renderer *, VideoRendererType);
+void video_widget_pause_rendering (VideoWidget *self, gboolean pause);
G_END_DECLS
diff --git a/src/video/videowindow.cpp b/src/video/videowindow.cpp
new file mode 100644
index 0000000..232eaed
--- /dev/null
+++ b/src/video/videowindow.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 Savoir-Faire Linux Inc.
+ * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+
+#include "videowindow.h"
+
+#include <gtk/gtk.h>
+#include <call.h>
+#include "video_widget.h"
+#include <video/previewmanager.h>
+
+struct _VideoWindow
+{
+ GtkWindow parent;
+};
+
+struct _VideoWindowClass
+{
+ GtkWindowClass parent_class;
+};
+
+typedef struct _VideoWindowPrivate VideoWindowPrivate;
+
+struct _VideoWindowPrivate
+{
+ GtkWidget *video_widget;
+
+ QMetaObject::Connection local_renderer_connection;
+ QMetaObject::Connection remote_renderer_connection;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(VideoWindow, video_window, GTK_TYPE_WINDOW);
+
+#define VIDEO_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), VIDEO_WINDOW_TYPE, VideoWindowPrivate))
+
+static void
+video_window_dispose(GObject *object)
+{
+ VideoWindow *self;
+ VideoWindowPrivate *priv;
+
+ self = VIDEO_WINDOW(object);
+ priv = VIDEO_WINDOW_GET_PRIVATE(self);
+
+ QObject::disconnect(priv->local_renderer_connection);
+ QObject::disconnect(priv->remote_renderer_connection);
+
+ G_OBJECT_CLASS(video_window_parent_class)->dispose(object);
+}
+
+static gboolean
+handle_keys(GtkWidget *self, GdkEventKey *event, G_GNUC_UNUSED gpointer user_data)
+{
+ if (event->keyval == GDK_KEY_Escape) {
+ gtk_widget_destroy(self);
+ /* the event has been fully handled */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+handle_button_press(GtkWidget *widget, GdkEventButton *event, VideoWindow *self)
+{
+ g_return_val_if_fail(IS_VIDEO_WIDGET(widget), FALSE);
+ g_return_val_if_fail(IS_VIDEO_WINDOW(self), FALSE);
+
+ /* on double click */
+ if (event->type == GDK_2BUTTON_PRESS) {
+ gtk_widget_destroy(GTK_WIDGET(self));
+ /* the event has been fully handled */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+video_window_init(VideoWindow *self)
+{
+ VideoWindowPrivate *priv = VIDEO_WINDOW_GET_PRIVATE(self);
+
+ gtk_window_set_decorated(GTK_WINDOW(self), FALSE);
+
+ /* video widget */
+ priv->video_widget = video_widget_new();
+ gtk_container_add(GTK_CONTAINER(self), priv->video_widget);
+ gtk_widget_show_all(priv->video_widget);
+
+ /* catch double click to exot full screen */
+ g_signal_connect(priv->video_widget, "button-press-event",
+ G_CALLBACK(handle_button_press),
+ self);
+
+ /* catch esc to exit fullscreen */
+ g_signal_connect(self, "key_press_event", G_CALLBACK(handle_keys), NULL);
+}
+
+static void
+video_window_class_init(VideoWindowClass *klass)
+{
+ G_OBJECT_CLASS(klass)->dispose = video_window_dispose;
+}
+
+GtkWidget *
+video_window_new(Call *call, GtkWindow *parent)
+{
+ GtkWidget *self = (GtkWidget *)g_object_new(VIDEO_WINDOW_TYPE, NULL);
+ VideoWindowPrivate *priv = VIDEO_WINDOW_GET_PRIVATE(self);
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(self), parent);
+
+ /* check if we already have a renderer */
+ video_widget_push_new_renderer(VIDEO_WIDGET(priv->video_widget),
+ call->videoRenderer(),
+ VIDEO_RENDERER_REMOTE);
+
+ /* callback for remote renderer */
+ priv->remote_renderer_connection = QObject::connect(
+ call,
+ &Call::videoStarted,
+ [=](Video::Renderer *renderer) {
+ video_widget_push_new_renderer(VIDEO_WIDGET(priv->video_widget),
+ renderer,
+ VIDEO_RENDERER_REMOTE);
+ }
+ );
+
+ /* local renderer */
+ if (Video::PreviewManager::instance()->isPreviewing())
+ video_widget_push_new_renderer(VIDEO_WIDGET(priv->video_widget),
+ Video::PreviewManager::instance()->previewRenderer(),
+ VIDEO_RENDERER_LOCAL);
+
+ /* callback for local renderer */
+ priv->local_renderer_connection = QObject::connect(
+ Video::PreviewManager::instance(),
+ &Video::PreviewManager::previewStarted,
+ [=](Video::Renderer *renderer) {
+ video_widget_push_new_renderer(VIDEO_WIDGET(priv->video_widget),
+ renderer,
+ VIDEO_RENDERER_LOCAL);
+ }
+ );
+
+ return self;
+}
diff --git a/src/video/videowindow.h b/src/video/videowindow.h
new file mode 100644
index 0000000..3dd6248
--- /dev/null
+++ b/src/video/videowindow.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Savoir-Faire Linux Inc.
+ * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+
+#ifndef _VIDEOWINDOW_H
+#define _VIDEOWINDOW_H
+
+#include <gtk/gtk.h>
+
+class Call;
+
+G_BEGIN_DECLS
+
+#define VIDEO_WINDOW_TYPE (video_window_get_type ())
+#define VIDEO_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIDEO_WINDOW_TYPE, VideoWindow))
+#define VIDEO_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), VIDEO_WINDOW_TYPE, VideoWindowClass))
+#define IS_VIDEO_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIDEO_WINDOW_TYPE))
+#define IS_VIDEO_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), VIDEO_WINDOW_TYPE))
+
+typedef struct _VideoWindow VideoWindow;
+typedef struct _VideoWindowClass VideoWindowClass;
+
+
+GType video_window_get_type (void) G_GNUC_CONST;
+GtkWidget *video_window_new (Call *call, GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* _VIDEOWINDOW_H */