gtk-Vlc does not receive mouse events

Hi all,

Here is my example code, based on the example gtk_player.c

// gcc -o gtk_player gtk_player.c $(pkg-config --libs --cflags gtk+-3.0 libvlc x11)

/* License WTFPL http://sam.zoy.org/wtfpl/ */
/* Written by Vincent Schüßler */

#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <vlc/vlc.h>

#define BORDER_WIDTH 6

void destroy(GtkWidget *widget, gpointer data);
void player_widget_on_realize(GtkWidget *widget, gpointer data);
void on_open(GtkWidget *widget, gpointer data);
void open_media(const char* uri);
void play(void);
void pause_player(void);
void on_playpause(GtkWidget *widget, gpointer data);
void on_stop(GtkWidget *widget, gpointer data);

libvlc_media_player_t *media_player;
libvlc_instance_t *vlc_inst;
GtkWidget *playpause_button;
glong timeout = 0;

void destroy(GtkWidget *widget, gpointer data) {
    gtk_main_quit();
}

void player_widget_on_realize(GtkWidget *widget, gpointer data) {
    libvlc_media_player_set_xwindow(media_player, GDK_WINDOW_XID(gtk_widget_get_window(widget)));
}

gboolean hbuttonbox_hide (gpointer user_data)
{
	if (gtk_widget_is_visible (GTK_WIDGET (user_data)) == TRUE)
	     gtk_widget_set_visible (GTK_WIDGET (user_data), FALSE);
	timeout = 0;
}

gboolean  player_widget_on_motion (GtkWidget* widget, GdkEventMotion *event, gpointer user_data)
{
	if (gtk_widget_is_visible (GTK_WIDGET (user_data)) == FALSE)
	     gtk_widget_set_visible (GTK_WIDGET (user_data), TRUE);
	else
	{
		if (timeout)
			g_source_remove(timeout);
		timeout = g_timeout_add(5000, hbuttonbox_hide, user_data);
	}
	return FALSE;
}

void on_open(GtkWidget *widget, gpointer data) {
    GtkWidget *dialog;
    dialog = gtk_file_chooser_dialog_new("Choose Media", data, GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel",GTK_RESPONSE_CANCEL, "Open", GTK_RESPONSE_ACCEPT, NULL);
    if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        char *uri;
        uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
        open_media(uri);
        g_free(uri);
    }
    gtk_widget_destroy(dialog);
}

void open_media(const char* uri) {
    libvlc_media_t *media;
    media = libvlc_media_new_location(vlc_inst, uri);
    libvlc_media_player_set_media(media_player, media);
    play();
    libvlc_media_release(media);
}

void on_playpause(GtkWidget *widget, gpointer data) {
    if(libvlc_media_player_is_playing(media_player) == 1) {
        pause_player();
    }
    else {
        play();
    }
}

void on_stop(GtkWidget *widget, gpointer data) {
    pause_player();
    // (void)libvlc_media_player_stop_async (media_player);
    (void)libvlc_media_player_stop (media_player);
}

void play(void) {
    libvlc_media_player_play(media_player);
    gtk_button_set_label(GTK_BUTTON(playpause_button), "Pause");
}

void pause_player(void) {
    libvlc_media_player_pause(media_player);
    gtk_button_set_label(GTK_BUTTON(playpause_button), "Play");
}

int main( int argc, char *argv[] ) {
    GtkWidget *window,
              *vbox,
              *overlay,
              *menubar,
              *filemenu,
              *fileitem,
              *filemenu_openitem,
              *player_widget,
              *hbuttonbox,
              *stop_button;
    
    XInitThreads();
    gtk_init (&argc, &argv);
    // setup window
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
    g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 0);
    gtk_window_set_title(GTK_WINDOW(window), "GTK+ libVLC Demo");

    overlay = gtk_overlay_new ();
    gtk_container_add(GTK_CONTAINER(window), overlay);
    
    //setup vbox
    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);

    gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);

    //setup menu
    menubar = gtk_menu_bar_new();
    filemenu = gtk_menu_new();
    fileitem = gtk_menu_item_new_with_label ("File");
    filemenu_openitem = gtk_menu_item_new_with_label("Open");
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), filemenu_openitem);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileitem);
    gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
    g_signal_connect(filemenu_openitem, "activate", G_CALLBACK(on_open), window);

    //setup player widget
    player_widget = gtk_drawing_area_new();
    gtk_box_pack_start(GTK_BOX(vbox), player_widget, TRUE, TRUE, 0);

    //setup controls
    //playpause_button = gtk_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
    playpause_button = gtk_button_new_with_label("Play");
    // gtk_button_set_use_stock(GTK_BUTTON(playpause_button), TRUE);
    stop_button = gtk_button_new_with_label ("Stop");
    g_signal_connect(playpause_button, "clicked", G_CALLBACK(on_playpause), NULL);
    g_signal_connect(stop_button, "clicked", G_CALLBACK(on_stop), NULL);
    hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), BORDER_WIDTH);
    gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_START);
    gtk_box_pack_start(GTK_BOX(hbuttonbox), playpause_button, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbuttonbox), stop_button, FALSE, FALSE, 0);
    // gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0);
    gtk_overlay_add_overlay (GTK_OVERLAY (overlay), hbuttonbox);
    gtk_overlay_set_overlay_pass_through (GTK_OVERLAY (overlay), hbuttonbox, TRUE);
    g_object_set (hbuttonbox, "margin", 20, NULL);
    gtk_widget_set_size_request (hbuttonbox, 200, 40);
    gtk_widget_set_valign(hbuttonbox, GTK_ALIGN_END);
	gtk_widget_set_halign(hbuttonbox, GTK_ALIGN_CENTER);
	
	

    //setup vlc
    vlc_inst = libvlc_new(0, NULL);
    media_player = libvlc_media_player_new(vlc_inst);
    g_signal_connect(G_OBJECT(player_widget), "realize", G_CALLBACK(player_widget_on_realize), NULL);
    g_signal_connect(G_OBJECT(player_widget), "motion-notify-event", G_CALLBACK (player_widget_on_motion), hbuttonbox);
    gtk_widget_add_events(GTK_WIDGET(player_widget), GDK_POINTER_MOTION_MASK);
    gtk_widget_show_all(window);
    gtk_widget_set_visible (hbuttonbox, FALSE);
    if (argc == 2)
       open_media(argv[1]);
    gtk_main ();

    libvlc_media_player_release(media_player);
    libvlc_release(vlc_inst);
    return 0;
}

To build the binary :

gcc -o gtk_player gtk_player.c $(pkg-config --libs --cflags gtk+-3.0 libvlc x11)

The line 172 of the file allows to activate the events of movement of the mouse.
When the mouse moves I make the menu appear. After 5 seconds the menu disappears.

172  gtk_widget_add_events(GTK_WIDGET(player_widget), GDK_POINTER_MOTION_MASK);

If I play a DVD, i can’t access the event on the video window, I can’t access the DVD menu.
To launch the DVD: ./gtk_player /media/user/MY-DVD
or 1 file : ./gtk_player video.mp4

Do you have an idea?

A drawing area does not have a backing input window. You need to use gtk_widget_set_has_window() to tell it to create one.

I’d recommend creating your own widget subclass, instead of GtkDrawingArea.

@ebassi, thank you for your answer!
I tested it, it does not solve the problem.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.