diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-06-20 12:45:32 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-06-20 13:48:40 +0200 |
commit | 69cc315ac143b3dc4ba971f3c3e0cb0e4a4cb3b5 (patch) | |
tree | 33faae756db80d573f14fc289f3a5efb50db50f3 | |
parent | 9cf66da0c66f848c4c8929dbe727f88f5add2486 (diff) | |
download | gtk-vlc-player-69cc315ac143b3dc4ba971f3c3e0cb0e4a4cb3b5.tar.gz |
fixed receiving click events on the gtk-player-widget on Windows
a workaround was necessary: after playing a movie, poll every 100ms for
the availability of the event window created by libVLC (in another
thread!) and disable it when found (stopping the g_timeout)
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/gtk-vlc-player/gtk-vlc-player.c | 95 |
2 files changed, 82 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac index a6fc718..0b0c309 100644 --- a/configure.ac +++ b/configure.ac @@ -131,7 +131,7 @@ case $host in AC_CHECK_HEADERS([windows.h], , [ AC_MSG_ERROR([Missing Windows headers!]) ]) - AC_CHECK_HEADERS([shellapi.h], , [ + AC_CHECK_HEADERS([shellapi.h winuser.h], , [ AC_MSG_ERROR([Missing Windows headers!]) ], [ #include <windows.h> diff --git a/lib/gtk-vlc-player/gtk-vlc-player.c b/lib/gtk-vlc-player/gtk-vlc-player.c index 301d3d3..b49b3a1 100644 --- a/lib/gtk-vlc-player/gtk-vlc-player.c +++ b/lib/gtk-vlc-player/gtk-vlc-player.c @@ -29,6 +29,14 @@ #include <assert.h> +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#include <winuser.h> +#endif + +#include <glib.h> +#include <glib/gprintf.h> + #include <gtk/gtk.h> #ifdef G_OS_WIN32 #include <gdk/gdkwin32.h> @@ -49,6 +57,10 @@ static void gtk_vlc_player_init(GtkVlcPlayer *klass); static void gtk_vlc_player_dispose(GObject *gobject); static void gtk_vlc_player_finalize(GObject *gobject); +#ifdef G_OS_WIN32 +static BOOL CALLBACK enumerate_vlc_windows_cb(HWND hWndvlc, LPARAM lParam); +static gboolean poll_vlc_event_window_cb(gpointer data); +#endif static void widget_on_realize(GtkWidget *widget, gpointer data); static gboolean widget_on_click(GtkWidget *widget, GdkEventButton *event, gpointer data); @@ -64,6 +76,8 @@ static void vlc_length_changed(const struct libvlc_event_t *event, void *userdat static void vlc_player_load_media(GtkVlcPlayer *player, libvlc_media_t *media); +#define POLL_VLC_EVENT_WINDOW_INTERVAL 100 /* milliseconds */ + /** @private */ #define GOBJECT_UNREF_SAFE(VAR) G_STMT_START { \ if ((VAR) != NULL) { \ @@ -276,32 +290,71 @@ gtk_vlc_player_finalize(GObject *gobject) G_OBJECT_CLASS(gtk_vlc_player_parent_class)->finalize(gobject); } +#ifdef G_OS_WIN32 + +static BOOL CALLBACK +enumerate_vlc_windows_cb(HWND hWndvlc, LPARAM lParam) +{ + EnableWindow(hWndvlc, FALSE); + *(gboolean *)lParam = FALSE; + + return TRUE; +} + +/** + * @brief Callback for polling the availability of a libVLC event window. + * + * If found, it is disabled and the polling stops. This results in mouse click + * events being delivered to the GtkDrawingArea widget. + * + * @param data User data (\e GtkVlcPlayer widget) + * @return \c TRUE to continue polling, \c FALSE to stop + */ +static gboolean +poll_vlc_event_window_cb(gpointer data) +{ + GtkWidget *drawing_area = gtk_bin_get_child(GTK_BIN(data)); + GdkWindow *window = gtk_widget_get_window(drawing_area); + + gboolean ret = TRUE; + + EnumChildWindows(GDK_WINDOW_HWND(window), + enumerate_vlc_windows_cb, (LPARAM)&ret); + + return ret; +} + static void widget_on_realize(GtkWidget *widget, gpointer user_data) { GtkVlcPlayer *player = GTK_VLC_PLAYER(user_data); GdkWindow *window = gtk_widget_get_window(widget); -#ifdef G_OS_WIN32 libvlc_media_player_set_hwnd(player->priv->media_player, GDK_WINDOW_HWND(window)); +} + #else + +static void +widget_on_realize(GtkWidget *widget, gpointer user_data) +{ + GtkVlcPlayer *player = GTK_VLC_PLAYER(user_data); + GdkWindow *window = gtk_widget_get_window(widget); + libvlc_media_player_set_xwindow(player->priv->media_player, GDK_WINDOW_XID(window)); -#endif } -/** - * @bug - * We don't get the signal on Windows (MinGW), after a movie starts playing. - * Using GtkEventBoxes does \b NOT help. - */ +#endif + static gboolean widget_on_click(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { GtkVlcPlayer *player = GTK_VLC_PLAYER(user_data); + GtkWidget *fullscreen_window = player->priv->fullscreen_window; - if (player->priv->fullscreen_window == NULL) + if (fullscreen_window == NULL) return TRUE; if (event->type != GDK_2BUTTON_PRESS || event->button != 1) @@ -310,14 +363,14 @@ widget_on_click(GtkWidget *widget, GdkEventButton *event, gpointer user_data) if (player->priv->isFullscreen) { gtk_widget_reparent(widget, GTK_WIDGET(player)); gtk_widget_show(widget); - gtk_widget_hide(player->priv->fullscreen_window); - gtk_window_unfullscreen(GTK_WINDOW(player->priv->fullscreen_window)); + gtk_window_unfullscreen(GTK_WINDOW(fullscreen_window)); + gtk_widget_hide(fullscreen_window); player->priv->isFullscreen = FALSE; } else { - gtk_window_fullscreen(GTK_WINDOW(player->priv->fullscreen_window)); - gtk_widget_show(player->priv->fullscreen_window); - gtk_widget_reparent(widget, player->priv->fullscreen_window); + gtk_window_fullscreen(GTK_WINDOW(fullscreen_window)); + gtk_widget_show(fullscreen_window); + gtk_widget_reparent(widget, fullscreen_window); gtk_widget_show(widget); player->priv->isFullscreen = TRUE; @@ -505,7 +558,21 @@ gtk_vlc_player_load_uri(GtkVlcPlayer *player, const gchar *uri) void gtk_vlc_player_play(GtkVlcPlayer *player) { - libvlc_media_player_play(player->priv->media_player); + if (libvlc_media_player_play(player->priv->media_player) < 0) + return; + + /* + * Workaround to get mouse click events on the drawing area widget + * that provides the low-level window for libVLC. + * On Win32, libVLC creates an event window (in a different thread) + * after playback start that "swallows" all click events. + * So we have to poll for the availability of that window and disable + * it. + */ +#ifdef G_OS_WIN32 + g_timeout_add(POLL_VLC_EVENT_WINDOW_INTERVAL, + poll_vlc_event_window_cb, player); +#endif } /** |