diff options
author | Lionel Landwerlin <llandwerlin@gmail.com> | 2015-11-30 23:29:36 +0000 |
---|---|---|
committer | Lionel Landwerlin <lionel.g.landwerlin@intel.com> | 2015-12-10 14:22:34 +0000 |
commit | 80208a260e2c657753a03869b2693f3c0cb94efe (patch) | |
tree | 4474bbd6187802707a612c557e413e8c221304c8 /src | |
parent | c941276bf535779cbdebfa3862569bed1f38f585 (diff) | |
download | totem-80208a260e2c657753a03869b2693f3c0cb94efe.tar.gz |
backend: embed the fullscreen top header bar in the video widget
On wayland the video has its own subsurface. It is directly painted by the
compositor on top of Totem's main window. As a result on wayland the top
header bar is not visible in fullscreen mode.
To solve this issue, we can embed the top header bar in the video widget.
This solves this issue nicely by having the same behavior on X11 and
Wayland.
https://bugzilla.gnome.org/show_bug.cgi?id=758876
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/bacon-video-widget.c | 54 | ||||
-rw-r--r-- | src/backend/bacon-video-widget.h | 4 | ||||
-rw-r--r-- | src/totem-object.c | 67 | ||||
-rw-r--r-- | src/totem-private.h | 1 |
4 files changed, 69 insertions, 57 deletions
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c index 59a9c2027..049795027 100644 --- a/src/backend/bacon-video-widget.c +++ b/src/backend/bacon-video-widget.c @@ -204,6 +204,7 @@ struct BaconVideoWidgetPrivate ClutterActor *stage; ClutterActor *texture; ClutterActor *frame; + ClutterActor *header_controls; ClutterActor *controls; ClutterActor *spinner; @@ -769,12 +770,24 @@ set_controls_visibility (BaconVideoWidget *bvw, gboolean animate) { guint8 opacity = visible ? OVERLAY_OPACITY : 0; + gint header_controls_height; + gfloat header_controls_y; + guint duration; + + gtk_widget_get_preferred_height (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (bvw->priv->header_controls)), + NULL, + &header_controls_height); + header_controls_y = visible ? 0 : -header_controls_height; + + duration = animate ? 250 : 0; /* FIXME: * Using a show/hide seems to not trigger the * controls to redraw, so let's change the opacity instead */ - clutter_actor_set_easing_duration (bvw->priv->controls, animate ? 250 : 0); + clutter_actor_set_easing_duration (bvw->priv->controls, duration); + clutter_actor_set_easing_duration (bvw->priv->header_controls, duration); clutter_actor_set_opacity (bvw->priv->controls, opacity); + clutter_actor_set_y (bvw->priv->header_controls, header_controls_y); set_show_cursor (bvw, visible); if (visible && animate) @@ -3721,6 +3734,14 @@ bacon_video_widget_get_controls_object (BaconVideoWidget *bvw) return G_OBJECT (bvw->priv->controls); } +GObject * +bacon_video_widget_get_header_controls_object (BaconVideoWidget *bvw) +{ + g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), NULL); + + return G_OBJECT (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (bvw->priv->header_controls))); +} + /* =========================================== */ /* */ /* Play/Pause, Stop */ @@ -6095,6 +6116,20 @@ bacon_video_widget_initable_init (GInitable *initable, bvw->priv->frame); clutter_actor_hide (bvw->priv->spinner); + /* Fullscreen header controls */ + bvw->priv->header_controls = gtk_clutter_actor_new (); + clutter_actor_set_name (bvw->priv->header_controls, "header-controls"); + clutter_actor_add_constraint (bvw->priv->header_controls, + clutter_bind_constraint_new (bvw->priv->stage, + CLUTTER_BIND_WIDTH, + 0)); + layout = g_object_new (CLUTTER_TYPE_ACTOR, + "layout-manager", clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, CLUTTER_BIN_ALIGNMENT_START), + NULL); + clutter_actor_set_name (layout, "layout"); + clutter_actor_add_child (layout, bvw->priv->header_controls); + clutter_actor_add_child (bvw->priv->stage, layout); + /* The controls */ bvw->priv->controls = bacon_video_controls_actor_new (); clutter_actor_set_name (bvw->priv->controls, "controls"); @@ -6250,6 +6285,23 @@ bacon_video_widget_set_rate (BaconVideoWidget *bvw, return retval; } +/** + * bacon_video_widget_set_fullscreen: + * @bvw: a #BaconVideoWidget + * @fullscreen: the new fullscreen state + * + * Sets the fullscreen state, enabling a toplevel header bar sliding from + * the top of the video widget. + **/ +void +bacon_video_widget_set_fullscreen (BaconVideoWidget *bvw, + gboolean fullscreen) +{ + g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw)); + + g_object_set (bvw->priv->header_controls, "visible", fullscreen, NULL); +} + /* * vim: sw=2 ts=8 cindent noai bs=2 */ diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h index 172c2bbe4..8d63933fc 100644 --- a/src/backend/bacon-video-widget.h +++ b/src/backend/bacon-video-widget.h @@ -186,6 +186,9 @@ gboolean bacon_video_widget_set_rate (BaconVideoWidget *bvw, gfloat new_rate); gfloat bacon_video_widget_get_rate (BaconVideoWidget *bvw); +void bacon_video_widget_set_fullscreen (BaconVideoWidget *bvw, + gboolean fullscreen); + /* Metadata */ /** * BvwMetadataType: @@ -433,6 +436,7 @@ void bacon_video_widget_unmark_popup_busy (BaconVideoWidget *bvw, const char *reason); GObject * bacon_video_widget_get_controls_object (BaconVideoWidget *bvw); +GObject * bacon_video_widget_get_header_controls_object (BaconVideoWidget *bvw); G_END_DECLS diff --git a/src/totem-object.c b/src/totem-object.c index f41962058..fcb5c4acc 100644 --- a/src/totem-object.c +++ b/src/totem-object.c @@ -1635,30 +1635,6 @@ totem_object_pause (TotemObject *totem) } } -static void -update_toolbar_visibility (TotemObject *totem, - gboolean animate) -{ - gboolean visible; - guint duration; - - if (totem->controls_visibility != TOTEM_CONTROLS_FULLSCREEN) { - visible = FALSE; - duration = 0; - } else { - g_object_get (G_OBJECT (totem->bvw), "reveal-controls", &visible, NULL); - duration = animate ? 250 : 0; - } - - if (visible) - gtk_widget_show (totem->revealer); - - /* We don't change the transition type, because it causes - * a queue resize, and it might short-circuit the animation */ - gtk_revealer_set_transition_duration (GTK_REVEALER (totem->revealer), duration); - gtk_revealer_set_reveal_child (GTK_REVEALER (totem->revealer), visible); -} - gboolean window_state_event_cb (GtkWidget *window, GdkEventWindowState *event, @@ -1682,7 +1658,8 @@ window_state_event_cb (GtkWidget *window, show_controls (totem, TRUE); } - update_toolbar_visibility (totem, FALSE); + bacon_video_widget_set_fullscreen (totem->bvw, + totem->controls_visibility == TOTEM_CONTROLS_FULLSCREEN); action = g_action_map_lookup_action (G_ACTION_MAP (totem), "fullscreen"); g_simple_action_set_state (G_SIMPLE_ACTION (action), @@ -2473,14 +2450,6 @@ update_fill (TotemObject *totem, gdouble level) } static void -on_reveal_controls_changed (GObject *gobject, - GParamSpec *pspec, - TotemObject *totem) -{ - update_toolbar_visibility (totem, TRUE); -} - -static void update_seekable (TotemObject *totem) { gboolean seekable; @@ -3960,24 +3929,13 @@ grilo_widget_setup (TotemObject *totem) } static void -child_revealed_changed_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - gboolean val; - - g_object_get (object, "child-revealed", &val, NULL); - if (!val) - gtk_widget_hide (GTK_WIDGET (object)); -} - -static void add_fullscreen_toolbar (TotemObject *totem) { - GtkWidget *item; + GtkWidget *container, *item; GMenuModel *menu; - totem->revealer = GTK_WIDGET (gtk_builder_get_object (totem->xml, "toolbar-revealer")); + container = GTK_WIDGET (bacon_video_widget_get_header_controls_object (totem->bvw)); + totem->fullscreen_header = g_object_new (TOTEM_TYPE_MAIN_TOOLBAR, "show-search-button", FALSE, "show-select-button", FALSE, @@ -4010,11 +3968,8 @@ add_fullscreen_toolbar (TotemObject *totem) G_CALLBACK (popup_menu_shown_cb), totem); totem->fullscreen_gear_button = item; - gtk_container_add (GTK_CONTAINER (totem->revealer), totem->fullscreen_header); + gtk_container_add (GTK_CONTAINER (container), totem->fullscreen_header); gtk_widget_show_all (totem->fullscreen_header); - - g_signal_connect (totem->revealer, "notify::child-revealed", - G_CALLBACK (child_revealed_changed_cb), NULL); } void @@ -4023,6 +3978,8 @@ video_widget_create (TotemObject *totem) GError *err = NULL; GtkContainer *container; BaconVideoWidget **bvw; + GdkWindow *window; + gboolean fullscreen; totem->bvw = BACON_VIDEO_WIDGET (bacon_video_widget_new (&err)); @@ -4032,6 +3989,10 @@ video_widget_create (TotemObject *totem) g_error_free (err); } + fullscreen = window && ((gdk_window_get_state (window) & GDK_WINDOW_STATE_FULLSCREEN) != 0); + + window = gtk_widget_get_window (totem->win); + bacon_video_widget_set_fullscreen (totem->bvw, fullscreen); totem->controls = bacon_video_widget_get_controls_object (totem->bvw); g_signal_connect_after (G_OBJECT (totem->bvw), @@ -4071,10 +4032,6 @@ video_widget_create (TotemObject *totem) G_CALLBACK (on_error_event), totem); g_signal_connect (G_OBJECT (totem->bvw), - "notify::reveal-controls", - G_CALLBACK (on_reveal_controls_changed), - totem); - g_signal_connect (G_OBJECT (totem->bvw), "seek-requested", G_CALLBACK (on_seek_requested_event), totem); diff --git a/src/totem-private.h b/src/totem-private.h index e844b8c90..76942b140 100644 --- a/src/totem-private.h +++ b/src/totem-private.h @@ -87,7 +87,6 @@ struct _TotemObject { BaconTimeLabel *time_rem_label; GtkWidget *header; - GtkWidget *revealer; GtkWidget *fullscreen_header; GtkWidget *fullscreen_gear_button; |