From 10686010ed50b5f39dc0abf000c66577dbff2ff9 Mon Sep 17 00:00:00 2001 From: jtellier Date: Thu, 7 May 2009 15:13:04 -0400 Subject: Video playback fullscreen mode See http://bugzilla.gnome.org/show_bug.cgi?id=580771 --- src/Makefile.am | 2 + src/empathy-call-window-fullscreen.c | 330 ++++++++++++++++++++++++++++++++++ src/empathy-call-window-fullscreen.h | 82 +++++++++ src/empathy-call-window-fullscreen.ui | 23 +++ src/empathy-call-window.c | 240 +++++++++++++++++++++++-- src/empathy-call-window.ui | 12 ++ 6 files changed, 676 insertions(+), 13 deletions(-) create mode 100644 src/empathy-call-window-fullscreen.c create mode 100644 src/empathy-call-window-fullscreen.h create mode 100644 src/empathy-call-window-fullscreen.ui (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index f24ef3e95..9641a1837 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ empathy_SOURCES = \ empathy-about-dialog.c empathy-about-dialog.h \ empathy-accounts-dialog.c empathy-accounts-dialog.h \ empathy-call-window.c empathy-call-window.h \ + empathy-call-window-fullscreen.c empathy-call-window-fullscreen.h \ empathy-chatrooms-window.c empathy-chatrooms-window.h \ empathy-chat-window.c empathy-chat-window.h \ empathy-event-manager.c empathy-event-manager.h \ @@ -51,6 +52,7 @@ uidir = $(datadir)/empathy ui_DATA = \ empathy-accounts-dialog.ui \ empathy-call-window.ui \ + empathy-call-window-fullscreen.ui \ empathy-chatrooms-window.ui \ empathy-chat-window.ui \ empathy-ft-manager.ui \ diff --git a/src/empathy-call-window-fullscreen.c b/src/empathy-call-window-fullscreen.c new file mode 100644 index 000000000..d01d65b06 --- /dev/null +++ b/src/empathy-call-window-fullscreen.c @@ -0,0 +1,330 @@ +/* + * empathy-call-window.c - Source for EmpathyCallWindow + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "empathy-call-window-fullscreen.h" + +#include + +#include +#include + +/* The number of seconds fo which the "leave fullscreen" popup should be shown */ +#define FULLSCREEN_POPUP_TIMEOUT 5 + +G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, GTK_TYPE_WINDOW) + +/* private structure */ +typedef struct _EmpathyCallWindowFullscreenPriv EmpathyCallWindowFullscreenPriv; + +struct _EmpathyCallWindowFullscreenPriv +{ + EmpathyCallWindow *parent_window; + + GtkWidget *leave_fullscreen_popup; + GtkWidget *video_widget; + + gulong motion_handler_id; + guint popup_timeout; + gboolean popup_creation_in_progress; + gboolean dispose_has_run; +}; + +#define GET_PRIV(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreenPriv)) + +static void empathy_call_window_fullscreen_dispose (GObject *object); +static void empathy_call_window_fullscreen_finalize (GObject *object); + +static gboolean empathy_call_window_fullscreen_motion_notify (GtkWidget *widget, + GdkEventMotion *event, EmpathyCallWindowFullscreen *fs); +static gboolean empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs); + +static void +empathy_call_window_fullscreen_set_cursor_visible (EmpathyCallWindowFullscreen *fs, + gboolean show_cursor) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + if (priv->video_widget != NULL && !show_cursor) + gdk_window_set_cursor (priv->video_widget->window, gdk_cursor_new (GDK_BLANK_CURSOR)); + else + gdk_window_set_cursor (priv->video_widget->window, NULL); +} + +static void +empathy_call_window_fullscreen_add_popup_timeout (EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->popup_timeout == 0) + { + priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT, + (GSourceFunc) empathy_call_window_fullscreen_hide_popup, self); + } +} + +static void +empathy_call_window_fullscreen_remove_popup_timeout (EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->popup_timeout != 0) + { + g_source_remove (priv->popup_timeout); + priv->popup_timeout = 0; + } +} + +static void +empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) +{ + g_assert (self->is_fullscreen); + + gint leave_fullscreen_width, leave_fullscreen_height; + GdkScreen *screen; + GdkRectangle fullscreen_rect; + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + g_return_if_fail (priv->parent_window != NULL); + + if (priv->popup_creation_in_progress) + return; + + if (!gtk_window_is_active (GTK_WINDOW (priv->parent_window))) + return; + + priv->popup_creation_in_progress = TRUE; + + empathy_call_window_fullscreen_set_cursor_visible (self, TRUE); + + /* Obtaining the screen rectangle */ + screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); + gdk_screen_get_monitor_geometry (screen, + gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (priv->parent_window)->window), + &fullscreen_rect); + + /* Getting the popup window sizes */ + gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup), + &leave_fullscreen_width, &leave_fullscreen_height); + + /* Moving the popup to the top-left corner */ + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), + fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, + fullscreen_rect.y); + + gtk_widget_show_all (priv->leave_fullscreen_popup); + empathy_call_window_fullscreen_add_popup_timeout (self); + + priv->popup_creation_in_progress = FALSE; +} + +static gboolean +empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + if (priv->video_widget == NULL || !fs->is_fullscreen) + return TRUE; + + gtk_widget_hide (priv->leave_fullscreen_popup); + empathy_call_window_fullscreen_remove_popup_timeout (fs); + + empathy_call_window_fullscreen_set_cursor_visible (fs, FALSE); + + return FALSE; +} + +static void +empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + GtkBuilder *gui; + gchar *filename; + + filename = empathy_file_lookup ("empathy-call-window-fullscreen.ui", "src"); + gui = empathy_builder_get_file (filename, + "leave_fullscreen_window", &priv->leave_fullscreen_popup, + "leave_fullscreen_button", &self->leave_fullscreen_button, + NULL); + + gtk_widget_add_events (priv->leave_fullscreen_popup, GDK_POINTER_MOTION_MASK); + + g_object_unref (gui); + g_free (filename); +} + +static void +empathy_call_window_fullscreen_class_init ( + EmpathyCallWindowFullscreenClass *empathy_call_window_fullscreen_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_window_fullscreen_class); + + g_type_class_add_private (empathy_call_window_fullscreen_class, + sizeof (EmpathyCallWindowFullscreenPriv)); + + object_class->dispose = empathy_call_window_fullscreen_dispose; + object_class->finalize = empathy_call_window_fullscreen_finalize; +} + +void +empathy_call_window_fullscreen_dispose (GObject *object) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object); + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + if (priv->dispose_has_run) + return; + + if (priv->parent_window != NULL) + g_object_unref (priv->parent_window); + priv->parent_window = NULL; + + if (priv->leave_fullscreen_popup != NULL) + gtk_widget_destroy (priv->leave_fullscreen_popup); + priv->leave_fullscreen_popup = NULL; + + if (self->leave_fullscreen_button != NULL) + gtk_widget_destroy (self->leave_fullscreen_button); + self->leave_fullscreen_button = NULL; + + if (G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose) + G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose (object); + + priv->dispose_has_run = TRUE; +} + +void +empathy_call_window_fullscreen_finalize (GObject *object) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object); + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + empathy_call_window_fullscreen_remove_popup_timeout (self); + + if (priv->motion_handler_id != 0) + { + g_signal_handler_disconnect (G_OBJECT (priv->video_widget), + priv->motion_handler_id); + priv->motion_handler_id = 0; + } + + G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->finalize (object); +} + +static void +empathy_call_window_fullscreen_parent_window_notify (GtkWidget *parent_window, + GParamSpec *property, EmpathyCallWindowFullscreen *fs) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + if (!fs->is_fullscreen) + return; + + if (parent_window == GTK_WIDGET (priv->parent_window) && + gtk_window_is_active (GTK_WINDOW (parent_window)) == FALSE) + { + empathy_call_window_fullscreen_hide_popup (fs); + empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE); + } +} + +EmpathyCallWindowFullscreen * +empathy_call_window_fullscreen_new (EmpathyCallWindow *parent_window) +{ + EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN ( + g_object_new (EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, NULL)); + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + priv->parent_window = parent_window; + g_signal_connect (G_OBJECT (priv->parent_window), "notify::is-active", + G_CALLBACK (empathy_call_window_fullscreen_parent_window_notify), self); + + return self; +} + +void +empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, + gboolean sidebar_was_visible, + gint original_width, + gint original_height) +{ + g_return_if_fail (!fs->is_fullscreen); + + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + empathy_call_window_fullscreen_remove_popup_timeout (fs); + empathy_call_window_fullscreen_set_cursor_visible (fs, FALSE); + + fs->sidebar_was_visible = sidebar_was_visible; + fs->original_width = original_width; + fs->original_height = original_height; + + if (priv->motion_handler_id == 0 && priv->video_widget != NULL) + { + priv->motion_handler_id = g_signal_connect (G_OBJECT (priv->video_widget), + "motion-notify-event", G_CALLBACK (empathy_call_window_fullscreen_motion_notify), + fs); + } + + fs->is_fullscreen = TRUE; +} + +void +empathy_call_window_fullscreen_unset_fullscreen (EmpathyCallWindowFullscreen *fs) +{ + g_return_if_fail (fs->is_fullscreen); + + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + empathy_call_window_fullscreen_hide_popup (fs); + empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE); + + if (priv->motion_handler_id != 0) + { + g_signal_handler_disconnect (G_OBJECT (priv->video_widget), + priv->motion_handler_id); + priv->motion_handler_id = 0; + } + + fs->is_fullscreen = FALSE; +} + +void +empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs, + GtkWidget *video_widget) +{ + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); + + priv->video_widget = video_widget; + + if (fs->is_fullscreen == TRUE && priv->motion_handler_id == 0) { + priv->motion_handler_id = g_signal_connect (G_OBJECT (priv->video_widget), + "motion-notify-event", G_CALLBACK (empathy_call_window_fullscreen_motion_notify), + fs); + } +} + +static gboolean +empathy_call_window_fullscreen_motion_notify (GtkWidget *widget, + GdkEventMotion *event, EmpathyCallWindowFullscreen *self) +{ + empathy_call_window_fullscreen_show_popup (self); + return FALSE; +} \ No newline at end of file diff --git a/src/empathy-call-window-fullscreen.h b/src/empathy-call-window-fullscreen.h new file mode 100644 index 000000000..543f7acda --- /dev/null +++ b/src/empathy-call-window-fullscreen.h @@ -0,0 +1,82 @@ +/* + * empathy-call-window.c - Source for EmpathyCallWindow + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__ +#define __EMPATHY_CALL_WINDOW_FULLSCREEN_H__ + +#include +#include + +#include "empathy-call-window.h" + +G_BEGIN_DECLS + +typedef struct _EmpathyCallWindowFullscreen EmpathyCallWindowFullscreen; +typedef struct _EmpathyCallWindowFullscreenClass EmpathyCallWindowFullscreenClass; + +struct _EmpathyCallWindowFullscreenClass { + GtkWindowClass parent_class; +}; + +struct _EmpathyCallWindowFullscreen { + GtkWindow parent; + gboolean is_fullscreen; + + GtkWidget *leave_fullscreen_button; + + /* Those fields represent the state of the parent empathy_call_window before + it actually was in fullscreen mode. */ + gboolean sidebar_was_visible; + gint original_width; + gint original_height; +}; + +GType empathy_call_window_fullscreen_get_type(void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN \ + (empathy_call_window_fullscreen_get_type()) +#define EMPATHY_CALL_WINDOW_FULLSCREEN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreen)) +#define EMPATHY_CALL_WINDOW_FULLSCREEN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowClassFullscreen)) +#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN)) +#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN)) +#define EMPATHY_CALL_WINDOW_FULLSCREEN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ + EmpathyCallWindowFullscreenClass)) + +EmpathyCallWindowFullscreen * +empathy_call_window_fullscreen_new (EmpathyCallWindow *parent); + +void empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, + gboolean sidebar_was_visible, + gint original_width, + gint original_height); +void empathy_call_window_fullscreen_unset_fullscreen (EmpathyCallWindowFullscreen *fs); +void empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs, + GtkWidget *video_widget); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__*/ \ No newline at end of file diff --git a/src/empathy-call-window-fullscreen.ui b/src/empathy-call-window-fullscreen.ui new file mode 100644 index 000000000..90ac333d7 --- /dev/null +++ b/src/empathy-call-window-fullscreen.ui @@ -0,0 +1,23 @@ + + + + + + popup + False + True + True + False + False + + + + gtk-fullscreen + True + True + True + True + + + + diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 22a9eef44..b05999d8c 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -39,10 +40,15 @@ #include "empathy-call-window.h" +#include "empathy-call-window-fullscreen.h" #include "empathy-sidebar.h" #define BUTTON_ID "empathy-call-dtmf-button-id" +#define CONTENT_HBOX_BORDER_WIDTH 6 +#define CONTENT_HBOX_SPACING 3 +#define CONTENT_HBOX_CHILDREN_PACKING_PADDING 3 + G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW) /* signal enum */ @@ -83,6 +89,14 @@ struct _EmpathyCallWindowPriv GtkWidget *pane; GtkAction *send_video; + /* We keep a reference on the hbox which contains the main content so we can + easilly repack everything when toggling fullscreen */ + GtkWidget *content_hbox; + + /* This vbox is contained in the content_hbox. When toggling fullscreen, + it needs to be repacked. We keep a reference on it for easier access. */ + GtkWidget *vbox; + gdouble volume; GtkAdjustment *audio_input_adj; @@ -109,6 +123,8 @@ struct _EmpathyCallWindowPriv GMutex *lock; gboolean call_started; gboolean sending_video; + + EmpathyCallWindowFullscreen *fullscreen; }; #define GET_PRIV(o) \ @@ -119,7 +135,10 @@ static void empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window); static gboolean empathy_call_window_delete_cb (GtkWidget *widget, - GdkEvent*event, EmpathyCallWindow *window); + GdkEvent *event, EmpathyCallWindow *window); + +static gboolean empathy_call_window_state_event_cb (GtkWidget *widget, + GdkEventWindowState *event, EmpathyCallWindow *window); static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, EmpathyCallWindow *window); @@ -139,9 +158,26 @@ static void empathy_call_window_mic_toggled_cb ( static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, EmpathyCallWindow *window); +static void empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar, + EmpathyCallWindow *window); + static void empathy_call_window_hangup_cb (gpointer object, EmpathyCallWindow *window); +static void empathy_call_window_fullscreen_cb (gpointer object, + EmpathyCallWindow *window); + +static void empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window); + +static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_output, + GdkEventButton *event, EmpathyCallWindow *window); + +static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output, + GdkEventKey *event, EmpathyCallWindow *window); + +static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window, + guint button); + static void empathy_call_window_status_message (EmpathyCallWindow *window, gchar *message); @@ -459,8 +495,8 @@ empathy_call_window_init (EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); GtkBuilder *gui; - GtkWidget *vbox, *top_vbox; - GtkWidget *hbox, *h; + GtkWidget *top_vbox; + GtkWidget *h; GtkWidget *arrow; GtkWidget *page; GstBus *bus; @@ -485,6 +521,7 @@ empathy_call_window_init (EmpathyCallWindow *self) "camera", "toggled", empathy_call_window_camera_toggled_cb, "send_video", "toggled", empathy_call_window_send_video_toggled_cb, "show_preview", "toggled", empathy_call_window_show_preview_toggled_cb, + "menufullscreen", "activate", empathy_call_window_fullscreen_cb, NULL); priv->lock = g_mutex_new (); @@ -495,27 +532,34 @@ empathy_call_window_init (EmpathyCallWindow *self) priv->pipeline = gst_pipeline_new (NULL); - hbox = gtk_hbox_new (FALSE, 3); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 6); - gtk_paned_pack1 (GTK_PANED (priv->pane), hbox, TRUE, FALSE); + priv->content_hbox = gtk_hbox_new (FALSE, CONTENT_HBOX_SPACING); + gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), + CONTENT_HBOX_BORDER_WIDTH); + gtk_paned_pack1 (GTK_PANED (priv->pane), priv->content_hbox, TRUE, FALSE); bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); gst_bus_add_watch (bus, empathy_call_window_bus_message, self); priv->video_output = empathy_video_widget_new (bus); - gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3); + gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->video_output, + TRUE, TRUE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); + gtk_widget_add_events (priv->video_output, + GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); + g_signal_connect (G_OBJECT (priv->video_output), "button-press-event", + G_CALLBACK (empathy_call_window_video_button_press_cb), self); priv->video_tee = gst_element_factory_make ("tee", NULL); gst_object_ref (priv->video_tee); gst_object_sink (priv->video_tee); - vbox = gtk_vbox_new (FALSE, 3); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3); + priv->vbox = gtk_vbox_new (FALSE, 3); + gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->vbox, + FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); priv->video_preview = empathy_video_widget_new_with_size (bus, 160, 120); g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (vbox), priv->video_preview, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (priv->vbox), priv->video_preview, FALSE, FALSE, 0); priv->video_input = empathy_video_src_new (); gst_object_ref (priv->video_input); @@ -539,13 +583,14 @@ empathy_call_window_init (EmpathyCallWindow *self) gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow); h = gtk_hbox_new (FALSE, 3); - gtk_box_pack_end (GTK_BOX (vbox), h, FALSE, FALSE, 3); + gtk_box_pack_end (GTK_BOX (priv->vbox), h, FALSE, FALSE, 3); gtk_box_pack_end (GTK_BOX (h), priv->sidebar_button, FALSE, FALSE, 3); priv->sidebar = empathy_sidebar_new (); g_signal_connect (G_OBJECT (priv->sidebar), - "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb), - self); + "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb), self); + g_signal_connect (G_OBJECT (priv->sidebar), + "show", G_CALLBACK (empathy_call_window_sidebar_shown_cb), self); gtk_paned_pack2 (GTK_PANED (priv->pane), priv->sidebar, FALSE, FALSE); priv->dtmf_panel = empathy_call_window_create_dtmf (self); @@ -566,18 +611,30 @@ empathy_call_window_init (EmpathyCallWindow *self) gtk_widget_hide (priv->sidebar); + priv->fullscreen = empathy_call_window_fullscreen_new (self); + empathy_call_window_fullscreen_set_video_widget (priv->fullscreen, priv->video_output); + g_signal_connect (G_OBJECT (priv->fullscreen->leave_fullscreen_button), + "clicked", G_CALLBACK (empathy_call_window_fullscreen_cb), self); + g_signal_connect (G_OBJECT (self), "realize", G_CALLBACK (empathy_call_window_realized_cb), self); g_signal_connect (G_OBJECT (self), "delete-event", G_CALLBACK (empathy_call_window_delete_cb), self); + g_signal_connect (G_OBJECT (self), "window-state-event", + G_CALLBACK (empathy_call_window_state_event_cb), self); + + g_signal_connect (G_OBJECT (self), "key-press-event", + G_CALLBACK (empathy_call_window_key_press_cb), self); + empathy_call_window_status_message (self, _("Connecting...")); priv->timer = g_timer_new (); g_object_ref (priv->ui_manager); g_object_unref (gui); + g_free (filename); } static void @@ -1165,6 +1222,91 @@ empathy_call_window_delete_cb (GtkWidget *widget, GdkEvent*event, return FALSE; } +static void +show_controls (EmpathyCallWindow *window, gboolean set_fullscreen) +{ + GtkWidget *menu; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + menu = gtk_ui_manager_get_widget (priv->ui_manager, + "/menubar1"); + + if (set_fullscreen) + { + gtk_widget_hide (priv->sidebar); + gtk_widget_hide (menu); + gtk_widget_hide (priv->vbox); + gtk_widget_hide (priv->statusbar); + gtk_widget_hide (priv->toolbar); + } + else + { + if (priv->fullscreen->sidebar_was_visible) + gtk_widget_show (priv->sidebar); + + gtk_widget_show (menu); + gtk_widget_show (priv->vbox); + gtk_widget_show (priv->statusbar); + gtk_widget_show (priv->toolbar); + + gtk_window_resize (GTK_WINDOW (window), + priv->fullscreen->original_width, + priv->fullscreen->original_height); + } +} + +static void +show_borders (EmpathyCallWindow *window, gboolean set_fullscreen) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), + set_fullscreen ? 0 : CONTENT_HBOX_BORDER_WIDTH); + gtk_box_set_spacing (GTK_BOX (priv->content_hbox), + set_fullscreen ? 0 : CONTENT_HBOX_SPACING); + gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), + priv->video_output, TRUE, TRUE, + set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, + GTK_PACK_START); + gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), + priv->vbox, TRUE, TRUE, + set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, + GTK_PACK_START); +} + +static gboolean +empathy_call_window_state_event_cb (GtkWidget *widget, + GdkEventWindowState *event, EmpathyCallWindow *window) +{ + if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) + { + EmpathyCallWindowPriv *priv = GET_PRIV (window); + gboolean set_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; + + if (set_fullscreen) + { + gboolean sidebar_was_visible; + gint original_width = GTK_WIDGET (window)->allocation.width; + gint original_height = GTK_WIDGET (window)->allocation.height; + + g_object_get (priv->sidebar, "visible", + &sidebar_was_visible, NULL); + + empathy_call_window_fullscreen_set_fullscreen (priv->fullscreen, + sidebar_was_visible, original_width, original_height); + } + else + { + empathy_call_window_fullscreen_unset_fullscreen(priv->fullscreen); + } + + show_controls (window, set_fullscreen); + show_borders (window, set_fullscreen); + } + + return FALSE; +} + static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, EmpathyCallWindow *window) @@ -1289,6 +1431,16 @@ empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, FALSE); } +static void +empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar, + EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button), + TRUE); +} + static void empathy_call_window_hangup_cb (gpointer object, EmpathyCallWindow *window) @@ -1299,6 +1451,68 @@ empathy_call_window_hangup_cb (gpointer object, gtk_widget_destroy (GTK_WIDGET (window)); } +static void +empathy_call_window_fullscreen_cb (gpointer object, + EmpathyCallWindow *window) +{ + empathy_call_window_fullscreen_toggle (window); +} + +static void +empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (priv->fullscreen->is_fullscreen) + gtk_window_unfullscreen (GTK_WINDOW (window)); + else + gtk_window_fullscreen (GTK_WINDOW (window)); +} + +static gboolean +empathy_call_window_video_button_press_cb (GtkWidget *video_output, + GdkEventButton *event, EmpathyCallWindow *window) +{ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + empathy_call_window_video_menu_popup (window, event->button); + return TRUE; + } + + return FALSE; +} + +static gboolean +empathy_call_window_key_press_cb (GtkWidget *video_output, + GdkEventKey *event, EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (priv->fullscreen->is_fullscreen && event->keyval == GDK_Escape) + { + /* Since we are in fullscreen mode, toggling will bring us back to + normal mode. */ + empathy_call_window_fullscreen_toggle (window); + return TRUE; + } + + return FALSE; +} + +static void +empathy_call_window_video_menu_popup (EmpathyCallWindow *window, + guint button) +{ + GtkWidget *menu; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + menu = gtk_ui_manager_get_widget (priv->ui_manager, + "/video-popup"); + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, + button, gtk_get_current_event_time ()); + gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); +} + static void empathy_call_window_status_message (EmpathyCallWindow *window, gchar *message) diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui index ce3d85b56..33a71eef6 100644 --- a/src/empathy-call-window.ui +++ b/src/empathy-call-window.ui @@ -36,6 +36,14 @@ Video preview + + + gtk-fullscreen + menufullscreen + Fullscreen + + + @@ -46,8 +54,12 @@ + + + + -- cgit v1.2.3 From bb9f071a1edf595f89ce23b9d3cfb0955c89ab1d Mon Sep 17 00:00:00 2001 From: jtellier Date: Mon, 11 May 2009 09:54:19 -0400 Subject: Fixed coding style by removing trailing spaces and not using a mix of tabs and spaces. Removed some responsabilities from EmpathyCallWindowFullscreen. It now only manages the "Leave Fullscreen" popup and button. --- src/empathy-call-window-fullscreen.c | 180 ++++++++++++----------------------- src/empathy-call-window-fullscreen.h | 19 +--- src/empathy-call-window.c | 79 ++++++++++++--- 3 files changed, 132 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window-fullscreen.c b/src/empathy-call-window-fullscreen.c index d01d65b06..888b1dfde 100644 --- a/src/empathy-call-window-fullscreen.c +++ b/src/empathy-call-window-fullscreen.c @@ -1,7 +1,12 @@ /* - * empathy-call-window.c - Source for EmpathyCallWindow + * empathy-call-window-fullscreen.c - Source for EmpathyCallWindowFullscreen * Copyright (C) 2009 Collabora Ltd. * + * Some code is based on the Totem Movie Player, especially + * totem-fullscreen.c which has the following copyright: + * Copyright (C) 2001-2007 Bastien Nocera + * Copyright (C) 2007 Sunil Mohan Adapa + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -24,10 +29,10 @@ #include #include -/* The number of seconds fo which the "leave fullscreen" popup should be shown */ +/* The number of seconds for which the "leave fullscreen" popup should be shown */ #define FULLSCREEN_POPUP_TIMEOUT 5 -G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, GTK_TYPE_WINDOW) +G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, G_TYPE_OBJECT) /* private structure */ typedef struct _EmpathyCallWindowFullscreenPriv EmpathyCallWindowFullscreenPriv; @@ -35,11 +40,10 @@ typedef struct _EmpathyCallWindowFullscreenPriv EmpathyCallWindowFullscreenPriv; struct _EmpathyCallWindowFullscreenPriv { EmpathyCallWindow *parent_window; - + GtkWidget *leave_fullscreen_popup; GtkWidget *video_widget; - gulong motion_handler_id; guint popup_timeout; gboolean popup_creation_in_progress; gboolean dispose_has_run; @@ -52,8 +56,6 @@ struct _EmpathyCallWindowFullscreenPriv static void empathy_call_window_fullscreen_dispose (GObject *object); static void empathy_call_window_fullscreen_finalize (GObject *object); -static gboolean empathy_call_window_fullscreen_motion_notify (GtkWidget *widget, - GdkEventMotion *event, EmpathyCallWindowFullscreen *fs); static gboolean empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs); static void @@ -75,8 +77,8 @@ empathy_call_window_fullscreen_add_popup_timeout (EmpathyCallWindowFullscreen *s if (priv->popup_timeout == 0) { - priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT, - (GSourceFunc) empathy_call_window_fullscreen_hide_popup, self); + priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT, + (GSourceFunc) empathy_call_window_fullscreen_hide_popup, self); } } @@ -87,20 +89,20 @@ empathy_call_window_fullscreen_remove_popup_timeout (EmpathyCallWindowFullscreen if (priv->popup_timeout != 0) { - g_source_remove (priv->popup_timeout); - priv->popup_timeout = 0; - } + g_source_remove (priv->popup_timeout); + priv->popup_timeout = 0; + } } -static void +void empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) { - g_assert (self->is_fullscreen); - gint leave_fullscreen_width, leave_fullscreen_height; - GdkScreen *screen; - GdkRectangle fullscreen_rect; - EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + GdkScreen *screen; + GdkRectangle fullscreen_rect; + EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); + + g_assert (self->is_fullscreen); g_return_if_fail (priv->parent_window != NULL); @@ -108,30 +110,40 @@ empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) return; if (!gtk_window_is_active (GTK_WINDOW (priv->parent_window))) - return; + return; priv->popup_creation_in_progress = TRUE; empathy_call_window_fullscreen_set_cursor_visible (self, TRUE); - /* Obtaining the screen rectangle */ - screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); - gdk_screen_get_monitor_geometry (screen, - gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (priv->parent_window)->window), - &fullscreen_rect); + /* Obtaining the screen rectangle */ + screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); + gdk_screen_get_monitor_geometry (screen, + gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (priv->parent_window)->window), + &fullscreen_rect); - /* Getting the popup window sizes */ - gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup), - &leave_fullscreen_width, &leave_fullscreen_height); + /* Getting the popup window sizes */ + gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup), + &leave_fullscreen_width, &leave_fullscreen_height); - /* Moving the popup to the top-left corner */ - gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), - fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, - fullscreen_rect.y); + /* Moving the popup to the top-right corner (if the direction is LTR) or the + top-left corner (if the direction is RTL).*/ + if (gtk_widget_get_direction (priv->leave_fullscreen_popup) == GTK_TEXT_DIR_LTR) + { + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), + fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, + fullscreen_rect.y); + + } + else + { + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), fullscreen_rect.x, + fullscreen_rect.y); + } gtk_widget_show_all (priv->leave_fullscreen_popup); empathy_call_window_fullscreen_add_popup_timeout (self); - + priv->popup_creation_in_progress = FALSE; } @@ -162,7 +174,7 @@ empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self) gui = empathy_builder_get_file (filename, "leave_fullscreen_window", &priv->leave_fullscreen_popup, "leave_fullscreen_button", &self->leave_fullscreen_button, - NULL); + NULL); gtk_widget_add_events (priv->leave_fullscreen_popup, GDK_POINTER_MOTION_MASK); @@ -171,13 +183,11 @@ empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self) } static void -empathy_call_window_fullscreen_class_init ( - EmpathyCallWindowFullscreenClass *empathy_call_window_fullscreen_class) +empathy_call_window_fullscreen_class_init (EmpathyCallWindowFullscreenClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_window_fullscreen_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (empathy_call_window_fullscreen_class, - sizeof (EmpathyCallWindowFullscreenPriv)); + g_type_class_add_private (klass, sizeof (EmpathyCallWindowFullscreenPriv)); object_class->dispose = empathy_call_window_fullscreen_dispose; object_class->finalize = empathy_call_window_fullscreen_finalize; @@ -192,39 +202,23 @@ empathy_call_window_fullscreen_dispose (GObject *object) if (priv->dispose_has_run) return; - if (priv->parent_window != NULL) - g_object_unref (priv->parent_window); - priv->parent_window = NULL; - + priv->dispose_has_run = TRUE; + if (priv->leave_fullscreen_popup != NULL) gtk_widget_destroy (priv->leave_fullscreen_popup); priv->leave_fullscreen_popup = NULL; - if (self->leave_fullscreen_button != NULL) - gtk_widget_destroy (self->leave_fullscreen_button); - self->leave_fullscreen_button = NULL; - if (G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose) G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose (object); - - priv->dispose_has_run = TRUE; } void empathy_call_window_fullscreen_finalize (GObject *object) { EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object); - EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); empathy_call_window_fullscreen_remove_popup_timeout (self); - if (priv->motion_handler_id != 0) - { - g_signal_handler_disconnect (G_OBJECT (priv->video_widget), - priv->motion_handler_id); - priv->motion_handler_id = 0; - } - G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->finalize (object); } @@ -234,13 +228,13 @@ empathy_call_window_fullscreen_parent_window_notify (GtkWidget *parent_window, { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); - if (!fs->is_fullscreen) - return; + if (!fs->is_fullscreen) + return; - if (parent_window == GTK_WIDGET (priv->parent_window) && - gtk_window_is_active (GTK_WINDOW (parent_window)) == FALSE) + if (parent_window == GTK_WIDGET (priv->parent_window) && + !gtk_window_is_active (GTK_WINDOW (parent_window))) { - empathy_call_window_fullscreen_hide_popup (fs); + empathy_call_window_fullscreen_hide_popup (fs); empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE); } } @@ -254,56 +248,23 @@ empathy_call_window_fullscreen_new (EmpathyCallWindow *parent_window) priv->parent_window = parent_window; g_signal_connect (G_OBJECT (priv->parent_window), "notify::is-active", - G_CALLBACK (empathy_call_window_fullscreen_parent_window_notify), self); + G_CALLBACK (empathy_call_window_fullscreen_parent_window_notify), self); return self; } void empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, - gboolean sidebar_was_visible, - gint original_width, - gint original_height) -{ - g_return_if_fail (!fs->is_fullscreen); - - EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); - - empathy_call_window_fullscreen_remove_popup_timeout (fs); - empathy_call_window_fullscreen_set_cursor_visible (fs, FALSE); - - fs->sidebar_was_visible = sidebar_was_visible; - fs->original_width = original_width; - fs->original_height = original_height; - - if (priv->motion_handler_id == 0 && priv->video_widget != NULL) - { - priv->motion_handler_id = g_signal_connect (G_OBJECT (priv->video_widget), - "motion-notify-event", G_CALLBACK (empathy_call_window_fullscreen_motion_notify), - fs); - } - - fs->is_fullscreen = TRUE; -} - -void -empathy_call_window_fullscreen_unset_fullscreen (EmpathyCallWindowFullscreen *fs) + gboolean set_fullscreen) { - g_return_if_fail (fs->is_fullscreen); - - EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); - - empathy_call_window_fullscreen_hide_popup (fs); - empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE); - if (priv->motion_handler_id != 0) - { - g_signal_handler_disconnect (G_OBJECT (priv->video_widget), - priv->motion_handler_id); - priv->motion_handler_id = 0; - } + if (set_fullscreen) + empathy_call_window_fullscreen_remove_popup_timeout (fs); + else + empathy_call_window_fullscreen_hide_popup (fs); - fs->is_fullscreen = FALSE; + empathy_call_window_fullscreen_set_cursor_visible (fs, !set_fullscreen); + fs->is_fullscreen = set_fullscreen; } void @@ -311,20 +272,5 @@ empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs GtkWidget *video_widget) { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); - priv->video_widget = video_widget; - - if (fs->is_fullscreen == TRUE && priv->motion_handler_id == 0) { - priv->motion_handler_id = g_signal_connect (G_OBJECT (priv->video_widget), - "motion-notify-event", G_CALLBACK (empathy_call_window_fullscreen_motion_notify), - fs); - } } - -static gboolean -empathy_call_window_fullscreen_motion_notify (GtkWidget *widget, - GdkEventMotion *event, EmpathyCallWindowFullscreen *self) -{ - empathy_call_window_fullscreen_show_popup (self); - return FALSE; -} \ No newline at end of file diff --git a/src/empathy-call-window-fullscreen.h b/src/empathy-call-window-fullscreen.h index 543f7acda..53dcf40e1 100644 --- a/src/empathy-call-window-fullscreen.h +++ b/src/empathy-call-window-fullscreen.h @@ -1,5 +1,5 @@ /* - * empathy-call-window.c - Source for EmpathyCallWindow + * empathy-call-window-fullscreen.h - Header for EmpathyCallWindowFullscreen * Copyright (C) 2009 Collabora Ltd. * * This library is free software; you can redistribute it and/or @@ -31,20 +31,13 @@ typedef struct _EmpathyCallWindowFullscreen EmpathyCallWindowFullscreen; typedef struct _EmpathyCallWindowFullscreenClass EmpathyCallWindowFullscreenClass; struct _EmpathyCallWindowFullscreenClass { - GtkWindowClass parent_class; + GObjectClass parent_class; }; struct _EmpathyCallWindowFullscreen { - GtkWindow parent; + GObject parent; gboolean is_fullscreen; - GtkWidget *leave_fullscreen_button; - - /* Those fields represent the state of the parent empathy_call_window before - it actually was in fullscreen mode. */ - gboolean sidebar_was_visible; - gint original_width; - gint original_height; }; GType empathy_call_window_fullscreen_get_type(void); @@ -70,12 +63,10 @@ EmpathyCallWindowFullscreen * empathy_call_window_fullscreen_new (EmpathyCallWindow *parent); void empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, - gboolean sidebar_was_visible, - gint original_width, - gint original_height); -void empathy_call_window_fullscreen_unset_fullscreen (EmpathyCallWindowFullscreen *fs); + gboolean set_fullscreen); void empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs, GtkWidget *video_widget); +void empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *fs); G_END_DECLS diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index b05999d8c..fe633045a 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -97,6 +97,8 @@ struct _EmpathyCallWindowPriv it needs to be repacked. We keep a reference on it for easier access. */ GtkWidget *vbox; + gulong video_output_motion_handler_id; + gdouble volume; GtkAdjustment *audio_input_adj; @@ -125,6 +127,13 @@ struct _EmpathyCallWindowPriv gboolean sending_video; EmpathyCallWindowFullscreen *fullscreen; + gboolean is_fullscreen; + + /* Those fields represent the state of the window before it actually was in + fullscreen mode. */ + gboolean sidebar_was_visible_before_fs; + gint original_width_before_fs; + gint original_height_before_fs; }; #define GET_PRIV(o) \ @@ -175,6 +184,9 @@ static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_outp static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output, GdkEventKey *event, EmpathyCallWindow *window); +static gboolean empathy_call_window_video_output_motion_notify (GtkWidget *widget, + GdkEventMotion *event, EmpathyCallWindow *window); + static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window, guint button); @@ -533,7 +545,7 @@ empathy_call_window_init (EmpathyCallWindow *self) priv->pipeline = gst_pipeline_new (NULL); priv->content_hbox = gtk_hbox_new (FALSE, CONTENT_HBOX_SPACING); - gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), + gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), CONTENT_HBOX_BORDER_WIDTH); gtk_paned_pack1 (GTK_PANED (priv->pane), priv->content_hbox, TRUE, FALSE); @@ -805,6 +817,13 @@ empathy_call_window_finalize (GObject *object) EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); EmpathyCallWindowPriv *priv = GET_PRIV (self); + if (priv->video_output_motion_handler_id != 0) + { + g_signal_handler_disconnect (G_OBJECT (priv->video_output), + priv->video_output_motion_handler_id); + priv->video_output_motion_handler_id = 0; + } + /* free any data held directly by the object here */ g_mutex_free (priv->lock); @@ -1241,7 +1260,7 @@ show_controls (EmpathyCallWindow *window, gboolean set_fullscreen) } else { - if (priv->fullscreen->sidebar_was_visible) + if (priv->sidebar_was_visible_before_fs) gtk_widget_show (priv->sidebar); gtk_widget_show (menu); @@ -1249,10 +1268,9 @@ show_controls (EmpathyCallWindow *window, gboolean set_fullscreen) gtk_widget_show (priv->statusbar); gtk_widget_show (priv->toolbar); - gtk_window_resize (GTK_WINDOW (window), - priv->fullscreen->original_width, - priv->fullscreen->original_height); - } + gtk_window_resize (GTK_WINDOW (window), priv->original_width_before_fs, + priv->original_height_before_fs); + } } static void @@ -1271,7 +1289,7 @@ show_borders (EmpathyCallWindow *window, gboolean set_fullscreen) gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), priv->vbox, TRUE, TRUE, set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, - GTK_PACK_START); + GTK_PACK_START); } static gboolean @@ -1289,19 +1307,35 @@ empathy_call_window_state_event_cb (GtkWidget *widget, gint original_width = GTK_WIDGET (window)->allocation.width; gint original_height = GTK_WIDGET (window)->allocation.height; - g_object_get (priv->sidebar, "visible", - &sidebar_was_visible, NULL); + g_object_get (priv->sidebar, "visible", &sidebar_was_visible, NULL); - empathy_call_window_fullscreen_set_fullscreen (priv->fullscreen, - sidebar_was_visible, original_width, original_height); + priv->sidebar_was_visible_before_fs = sidebar_was_visible; + priv->original_width_before_fs = original_width; + priv->original_height_before_fs = original_height; + + if (priv->video_output_motion_handler_id == 0 && + priv->video_output != NULL) + { + priv->video_output_motion_handler_id = g_signal_connect ( + G_OBJECT (priv->video_output), "motion-notify-event", + G_CALLBACK (empathy_call_window_video_output_motion_notify), window); + } } else { - empathy_call_window_fullscreen_unset_fullscreen(priv->fullscreen); + if (priv->video_output_motion_handler_id != 0) + { + g_signal_handler_disconnect (G_OBJECT (priv->video_output), + priv->video_output_motion_handler_id); + priv->video_output_motion_handler_id = 0; + } } + empathy_call_window_fullscreen_set_fullscreen (priv->fullscreen, + set_fullscreen); show_controls (window, set_fullscreen); show_borders (window, set_fullscreen); + priv->is_fullscreen = set_fullscreen; } return FALSE; @@ -1463,7 +1497,7 @@ empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window) { EmpathyCallWindowPriv *priv = GET_PRIV (window); - if (priv->fullscreen->is_fullscreen) + if (priv->is_fullscreen) gtk_window_unfullscreen (GTK_WINDOW (window)); else gtk_window_fullscreen (GTK_WINDOW (window)); @@ -1487,8 +1521,8 @@ empathy_call_window_key_press_cb (GtkWidget *video_output, GdkEventKey *event, EmpathyCallWindow *window) { EmpathyCallWindowPriv *priv = GET_PRIV (window); - - if (priv->fullscreen->is_fullscreen && event->keyval == GDK_Escape) + + if (priv->is_fullscreen && event->keyval == GDK_Escape) { /* Since we are in fullscreen mode, toggling will bring us back to normal mode. */ @@ -1499,6 +1533,21 @@ empathy_call_window_key_press_cb (GtkWidget *video_output, return FALSE; } +static gboolean +empathy_call_window_video_output_motion_notify (GtkWidget *widget, + GdkEventMotion *event, EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (priv->is_fullscreen) + { + empathy_call_window_fullscreen_show_popup (priv->fullscreen); + return TRUE; + } + + return FALSE; +} + static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window, guint button) -- cgit v1.2.3 From 5bbe4a3b2586f04a855c1aaf5d58b09921adac4b Mon Sep 17 00:00:00 2001 From: jtellier Date: Mon, 11 May 2009 13:57:32 -0400 Subject: Usability fix: The "Leave Fullscreen" button is now using the "gtk-leave-fullscreen" stock id instead of "gtk-fullscreen". --- src/empathy-call-window-fullscreen.ui | 2 +- src/empathy-call-window.c | 4 ++++ src/empathy-call-window.ui | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window-fullscreen.ui b/src/empathy-call-window-fullscreen.ui index 90ac333d7..5bf5e509b 100644 --- a/src/empathy-call-window-fullscreen.ui +++ b/src/empathy-call-window-fullscreen.ui @@ -12,7 +12,7 @@ - gtk-fullscreen + gtk-leave-fullscreen True True True diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index fe633045a..c15b5a6b5 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -88,6 +88,7 @@ struct _EmpathyCallWindowPriv GtkWidget *toolbar; GtkWidget *pane; GtkAction *send_video; + GtkAction *menu_fullscreen; /* We keep a reference on the hbox which contains the main content so we can easilly repack everything when toggling fullscreen */ @@ -524,6 +525,7 @@ empathy_call_window_init (EmpathyCallWindow *self) "toolbar", &priv->toolbar, "send_video", &priv->send_video, "ui_manager", &priv->ui_manager, + "menufullscreen", &priv->menu_fullscreen, NULL); empathy_builder_connect (gui, self, @@ -1335,6 +1337,8 @@ empathy_call_window_state_event_cb (GtkWidget *widget, set_fullscreen); show_controls (window, set_fullscreen); show_borders (window, set_fullscreen); + gtk_action_set_stock_id(priv->menu_fullscreen, + (set_fullscreen ? "gtk-leave-fullscreen" : "gtk-fullscreen")); priv->is_fullscreen = set_fullscreen; } diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui index 33a71eef6..a0e1e1304 100644 --- a/src/empathy-call-window.ui +++ b/src/empathy-call-window.ui @@ -40,7 +40,6 @@ gtk-fullscreen menufullscreen - Fullscreen -- cgit v1.2.3 From 0493b4a30bc60e0b282cdae95cdc35d8bcbac481 Mon Sep 17 00:00:00 2001 From: jtellier Date: Tue, 12 May 2009 12:13:19 -0400 Subject: Fixed some coding style. - empathy-call-window-fullscreen.c and .h now has no line > 80 caracters. - The return type and the signature in the declaration of empathy_call_window_fullscreen_new and of empathy_call_window_new are on the same line. - Removed a trailing space and a tab (which was replaced by spaces). --- src/empathy-call-window-fullscreen.c | 50 ++++++++++++++++++++++++------------ src/empathy-call-window-fullscreen.h | 16 +++++++----- src/empathy-call-window.c | 6 ++--- src/empathy-call-window.h | 3 +-- 4 files changed, 48 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window-fullscreen.c b/src/empathy-call-window-fullscreen.c index 888b1dfde..33f4085b3 100644 --- a/src/empathy-call-window-fullscreen.c +++ b/src/empathy-call-window-fullscreen.c @@ -29,13 +29,16 @@ #include #include -/* The number of seconds for which the "leave fullscreen" popup should be shown */ +/* The number of seconds for which the "leave fullscreen" popup should + be shown */ #define FULLSCREEN_POPUP_TIMEOUT 5 -G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, G_TYPE_OBJECT) +G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen, + G_TYPE_OBJECT) /* private structure */ -typedef struct _EmpathyCallWindowFullscreenPriv EmpathyCallWindowFullscreenPriv; +typedef struct _EmpathyCallWindowFullscreenPriv + EmpathyCallWindowFullscreenPriv; struct _EmpathyCallWindowFullscreenPriv { @@ -56,22 +59,28 @@ struct _EmpathyCallWindowFullscreenPriv static void empathy_call_window_fullscreen_dispose (GObject *object); static void empathy_call_window_fullscreen_finalize (GObject *object); -static gboolean empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs); +static gboolean empathy_call_window_fullscreen_hide_popup ( + EmpathyCallWindowFullscreen *fs); static void -empathy_call_window_fullscreen_set_cursor_visible (EmpathyCallWindowFullscreen *fs, +empathy_call_window_fullscreen_set_cursor_visible ( + EmpathyCallWindowFullscreen *fs, gboolean show_cursor) { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); if (priv->video_widget != NULL && !show_cursor) - gdk_window_set_cursor (priv->video_widget->window, gdk_cursor_new (GDK_BLANK_CURSOR)); + { + gdk_window_set_cursor (priv->video_widget->window, + gdk_cursor_new (GDK_BLANK_CURSOR)); + } else gdk_window_set_cursor (priv->video_widget->window, NULL); } static void -empathy_call_window_fullscreen_add_popup_timeout (EmpathyCallWindowFullscreen *self) +empathy_call_window_fullscreen_add_popup_timeout ( + EmpathyCallWindowFullscreen *self) { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); @@ -83,7 +92,8 @@ empathy_call_window_fullscreen_add_popup_timeout (EmpathyCallWindowFullscreen *s } static void -empathy_call_window_fullscreen_remove_popup_timeout (EmpathyCallWindowFullscreen *self) +empathy_call_window_fullscreen_remove_popup_timeout ( + EmpathyCallWindowFullscreen *self) { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self); @@ -119,7 +129,8 @@ empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) /* Obtaining the screen rectangle */ screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); gdk_screen_get_monitor_geometry (screen, - gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (priv->parent_window)->window), + gdk_screen_get_monitor_at_window (screen, + GTK_WIDGET (priv->parent_window)->window), &fullscreen_rect); /* Getting the popup window sizes */ @@ -128,7 +139,8 @@ empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) /* Moving the popup to the top-right corner (if the direction is LTR) or the top-left corner (if the direction is RTL).*/ - if (gtk_widget_get_direction (priv->leave_fullscreen_popup) == GTK_TEXT_DIR_LTR) + if (gtk_widget_get_direction (priv->leave_fullscreen_popup) + == GTK_TEXT_DIR_LTR) { gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, @@ -137,8 +149,8 @@ empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self) } else { - gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), fullscreen_rect.x, - fullscreen_rect.y); + gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), + fullscreen_rect.x, fullscreen_rect.y); } gtk_widget_show_all (priv->leave_fullscreen_popup); @@ -183,7 +195,8 @@ empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self) } static void -empathy_call_window_fullscreen_class_init (EmpathyCallWindowFullscreenClass *klass) +empathy_call_window_fullscreen_class_init ( + EmpathyCallWindowFullscreenClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -209,7 +222,10 @@ empathy_call_window_fullscreen_dispose (GObject *object) priv->leave_fullscreen_popup = NULL; if (G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose) - G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose (object); + { + G_OBJECT_CLASS ( + empathy_call_window_fullscreen_parent_class)->dispose (object); + } } void @@ -219,7 +235,8 @@ empathy_call_window_fullscreen_finalize (GObject *object) empathy_call_window_fullscreen_remove_popup_timeout (self); - G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->finalize (object); + G_OBJECT_CLASS ( + empathy_call_window_fullscreen_parent_class)->finalize (object); } static void @@ -268,7 +285,8 @@ empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, } void -empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs, +empathy_call_window_fullscreen_set_video_widget ( + EmpathyCallWindowFullscreen *fs, GtkWidget *video_widget) { EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs); diff --git a/src/empathy-call-window-fullscreen.h b/src/empathy-call-window-fullscreen.h index 53dcf40e1..1ae1e98e7 100644 --- a/src/empathy-call-window-fullscreen.h +++ b/src/empathy-call-window-fullscreen.h @@ -28,7 +28,8 @@ G_BEGIN_DECLS typedef struct _EmpathyCallWindowFullscreen EmpathyCallWindowFullscreen; -typedef struct _EmpathyCallWindowFullscreenClass EmpathyCallWindowFullscreenClass; +typedef struct _EmpathyCallWindowFullscreenClass + EmpathyCallWindowFullscreenClass; struct _EmpathyCallWindowFullscreenClass { GObjectClass parent_class; @@ -59,14 +60,17 @@ GType empathy_call_window_fullscreen_get_type(void); (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \ EmpathyCallWindowFullscreenClass)) -EmpathyCallWindowFullscreen * -empathy_call_window_fullscreen_new (EmpathyCallWindow *parent); +EmpathyCallWindowFullscreen *empathy_call_window_fullscreen_new ( + EmpathyCallWindow *parent); -void empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs, +void empathy_call_window_fullscreen_set_fullscreen ( + EmpathyCallWindowFullscreen *fs, gboolean set_fullscreen); -void empathy_call_window_fullscreen_set_video_widget (EmpathyCallWindowFullscreen *fs, +void empathy_call_window_fullscreen_set_video_widget ( + EmpathyCallWindowFullscreen *fs, GtkWidget *video_widget); -void empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *fs); +void empathy_call_window_fullscreen_show_popup ( + EmpathyCallWindowFullscreen *fs); G_END_DECLS diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index c15b5a6b5..9a9119b97 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -1548,7 +1548,7 @@ empathy_call_window_video_output_motion_notify (GtkWidget *widget, empathy_call_window_fullscreen_show_popup (priv->fullscreen); return TRUE; } - + return FALSE; } @@ -1562,8 +1562,8 @@ empathy_call_window_video_menu_popup (EmpathyCallWindow *window, menu = gtk_ui_manager_get_widget (priv->ui_manager, "/video-popup"); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - button, gtk_get_current_event_time ()); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); + button, gtk_get_current_event_time ()); + gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); } static void diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h index 26b0e7881..cda7af2f6 100644 --- a/src/empathy-call-window.h +++ b/src/empathy-call-window.h @@ -57,8 +57,7 @@ GType empathy_call_window_get_type(void); (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW, \ EmpathyCallWindowClass)) -EmpathyCallWindow * -empathy_call_window_new (EmpathyCallHandler *handler); +EmpathyCallWindow *empathy_call_window_new (EmpathyCallHandler *handler); G_END_DECLS -- cgit v1.2.3