diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c index bd3d16bc80e0772ddb1fb155e2e54bcf17f96800..296aae16f08fbc135a4a9d132f2944b1c723b0f0 100644 --- a/src/backend/bacon-video-widget.c +++ b/src/backend/bacon-video-widget.c @@ -166,6 +166,8 @@ struct _BaconVideoWidget GtkWidget *broken_video; GtkWidget *video_widget; + GtkWindow *parent_toplevel; + GError *init_error; char *user_agent; @@ -200,14 +202,16 @@ struct _BaconVideoWidget gboolean got_redirect; - GdkCursor *cursor; + GdkCursor *blank_cursor; + GdkCursor *hand_cursor; + gboolean cursor_shown; + gboolean hovering_menu; /* Visual effects */ GstElement *audio_capsfilter; GstElement *audio_pitchcontrol; /* Other stuff */ - gboolean cursor_shown; gboolean uses_audio_fakesink; gdouble volume; gboolean is_menu; @@ -400,13 +404,44 @@ bvw_show_error_if_video_decoder_is_missing (BaconVideoWidget * bvw) } } +static void +update_cursor (BaconVideoWidget *bvw) +{ + GdkWindow *window; + + window = gtk_widget_get_window (GTK_WIDGET (bvw)); + + if (!gtk_window_is_active (bvw->parent_toplevel)) { + gdk_window_set_cursor (window, NULL); + return; + } + + if (bvw->hovering_menu) + gdk_window_set_cursor (window, bvw->hand_cursor); + else if (bvw->cursor_shown) + gdk_window_set_cursor (window, NULL); + else + gdk_window_set_cursor (window, bvw->blank_cursor); +} + static void bacon_video_widget_realize (GtkWidget * widget) { BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget); + GdkWindow *window; + GdkDisplay *display; GTK_WIDGET_CLASS (parent_class)->realize (widget); + window = gtk_widget_get_window (widget); + display = gdk_window_get_display (window); + bvw->hand_cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + bvw->blank_cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR); + + bvw->parent_toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (bvw))); + g_signal_connect_swapped (G_OBJECT (bvw->parent_toplevel), "notify::is-active", + G_CALLBACK (update_cursor), bvw); + bvw->missing_plugins_cancellable = g_cancellable_new (); g_object_set_data_full (G_OBJECT (bvw), "missing-plugins-cancellable", bvw->missing_plugins_cancellable, g_object_unref); @@ -420,6 +455,13 @@ bacon_video_widget_unrealize (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->unrealize (widget); + if (bvw->parent_toplevel != NULL) { + g_signal_handlers_disconnect_by_func (bvw->parent_toplevel, update_cursor, bvw); + bvw->parent_toplevel = NULL; + } + g_clear_object (&bvw->blank_cursor); + g_clear_object (&bvw->hand_cursor); + g_cancellable_cancel (bvw->missing_plugins_cancellable); bvw->missing_plugins_cancellable = NULL; g_object_set_data (G_OBJECT (bvw), "missing-plugins-cancellable", NULL); @@ -1121,7 +1163,6 @@ bvw_handle_element_message (BaconVideoWidget *bvw, GstMessage *msg) const GValue *val; GFile *file; GMountOperation *mount_op; - GtkWidget *toplevel; GstState target_state; const char *uri; @@ -1136,10 +1177,6 @@ bvw_handle_element_message (BaconVideoWidget *bvw, GstMessage *msg) GST_DEBUG ("Trying to mount location '%s'", GST_STR_NULL (uri)); - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bvw)); - if (toplevel == GTK_WIDGET (bvw) || !GTK_IS_WINDOW (toplevel)) - toplevel = NULL; - val = gst_structure_get_value (structure, "file"); if (val == NULL) goto done; @@ -1153,7 +1190,7 @@ bvw_handle_element_message (BaconVideoWidget *bvw, GstMessage *msg) bacon_video_widget_stop (bvw); bvw->target_state = target_state; - mount_op = gtk_mount_operation_new (toplevel ? GTK_WINDOW (toplevel) : NULL); + mount_op = gtk_mount_operation_new (bvw->parent_toplevel); bvw->mount_in_progress = TRUE; bvw->mount_cancellable = g_cancellable_new (); g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, @@ -1182,20 +1219,10 @@ bvw_handle_element_message (BaconVideoWidget *bvw, GstMessage *msg) switch (nav_msg_type) { case GST_NAVIGATION_MESSAGE_MOUSE_OVER: { gint active; - GdkWindow *window; - GdkDisplay *display; if (!gst_navigation_message_parse_mouse_over (msg, &active)) break; - window = gtk_widget_get_window (GTK_WIDGET (bvw)); - if (active) { - if (bvw->cursor == NULL) { - display = gdk_window_get_display (window); - bvw->cursor = gdk_cursor_new_for_display (display, GDK_HAND2); - } - } else { - g_clear_object (&bvw->cursor); - } - gdk_window_set_cursor (window, bvw->cursor); + bvw->hovering_menu = active; + update_cursor (bvw); goto done; } case GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED: { @@ -1392,7 +1419,6 @@ done: static gboolean bvw_check_missing_auth (BaconVideoWidget * bvw, GstMessage * err_msg) { - GtkWidget *toplevel; GMountOperationClass *klass; int code; @@ -1423,8 +1449,7 @@ bvw_check_missing_auth (BaconVideoWidget * bvw, GstMessage * err_msg) GST_DEBUG ("Trying to get auth for location '%s'", GST_STR_NULL (bvw->mrl)); if (bvw->auth_dialog == NULL) { - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bvw)); - bvw->auth_dialog = gtk_mount_operation_new (GTK_WINDOW (toplevel)); + bvw->auth_dialog = gtk_mount_operation_new (bvw->parent_toplevel); g_signal_connect (G_OBJECT (bvw->auth_dialog), "reply", G_CALLBACK (bvw_auth_reply_cb), bvw); } @@ -2456,8 +2481,6 @@ bacon_video_widget_finalize (GObject * object) bvw->eos_id = 0; } - g_clear_object (&bvw->cursor); - if (bvw->mount_cancellable) g_cancellable_cancel (bvw->mount_cancellable); g_clear_object (&bvw->mount_cancellable); @@ -4331,28 +4354,12 @@ void bacon_video_widget_set_show_cursor (BaconVideoWidget * bvw, gboolean show_cursor) { - GdkWindow *window; - g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw)); - - bvw->cursor_shown = show_cursor; - window = gtk_widget_get_window (GTK_WIDGET (bvw)); - - if (!window) + if (bvw->cursor_shown == show_cursor) return; - - if (show_cursor == FALSE) { - GdkCursor *cursor; - GdkDisplay *display; - - display = gdk_window_get_display (window); - cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR); - gdk_window_set_cursor (window, cursor); - g_object_unref (cursor); - } else { - gdk_window_set_cursor (window, bvw->cursor); - } + bvw->cursor_shown = show_cursor; + update_cursor (bvw); } /**