[totem] player: Use GdFullscreenFilter to simplify popups
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] player: Use GdFullscreenFilter to simplify popups
- Date: Wed, 28 Mar 2012 15:20:07 +0000 (UTC)
commit b443b96be9d9308c13f6999a3404b6c6331cdc0a
Author: Bastien Nocera <hadess hadess net>
Date: Wed Mar 28 12:22:39 2012 +0200
player: Use GdFullscreenFilter to simplify popups
This fixes the case where we couldn't get the popups to show
up in fullscreen in some cases.
data/fullscreen.ui | 4 -
src/Makefile.am | 2 +
src/gd-fullscreen-filter.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
src/gd-fullscreen-filter.h | 75 +++++++++++++++++++++++++
src/totem-fullscreen.c | 56 ++++++++-----------
5 files changed, 233 insertions(+), 36 deletions(-)
---
diff --git a/data/fullscreen.ui b/data/fullscreen.ui
index 8f26f65..f0cc498 100644
--- a/data/fullscreen.ui
+++ b/data/fullscreen.ui
@@ -17,7 +17,6 @@
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
- <signal name="motion-notify-event" handler="totem_fullscreen_motion_notify"/>
<signal name="enter-notify-event" handler="totem_fullscreen_control_enter_notify"/>
<signal name="leave-notify-event" handler="totem_fullscreen_control_leave_notify"/>
@@ -27,7 +26,6 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="motion-notify-event" handler="totem_fullscreen_motion_notify"/>
<child>
<object class="GtkAlignment" id="tefw_alignment">
@@ -110,7 +108,6 @@
<property name="gravity">GDK_GRAVITY_SOUTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
- <signal name="motion-notify-event" handler="totem_fullscreen_motion_notify"/>
<signal name="enter-notify-event" handler="totem_fullscreen_control_enter_notify"/>
<signal name="leave-notify-event" handler="totem_fullscreen_control_leave_notify"/>
@@ -184,7 +181,6 @@
<property name="adjustment">tcw_seek_adjustment</property>
<signal name="button-press-event" handler="totem_fullscreen_seek_slider_pressed_cb"/>
<signal name="button-release-event" handler="totem_fullscreen_seek_slider_released_cb"/>
- <signal name="motion-notify-event" handler="totem_fullscreen_motion_notify"/>
</object>
<packing>
<property name="padding">0</property>
diff --git a/src/Makefile.am b/src/Makefile.am
index 210b921..318c2dd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,6 +40,8 @@ libtotem_player_la_SOURCES = \
totem-interface.c \
totem-fullscreen.c \
totem-fullscreen.h \
+ gd-fullscreen-filter.c \
+ gd-fullscreen-filter.h \
gsd-media-keys-window.c \
gsd-media-keys-window.h \
gsd-osd-window.c \
diff --git a/src/gd-fullscreen-filter.c b/src/gd-fullscreen-filter.c
new file mode 100644
index 0000000..6206d42
--- /dev/null
+++ b/src/gd-fullscreen-filter.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * Gnome Documents is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Gnome Documents 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+#include "gd-fullscreen-filter.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/extensions/XInput2.h>
+
+G_DEFINE_TYPE (GdFullscreenFilter, gd_fullscreen_filter, G_TYPE_OBJECT)
+
+enum {
+ MOTION_EVENT = 1,
+ NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
+struct _GdFullscreenFilterPrivate {
+ gboolean is_filtering;
+};
+
+static void
+gd_fullscreen_filter_dispose (GObject *object)
+{
+ GdFullscreenFilter *self = GD_FULLSCREEN_FILTER (object);
+
+ gd_fullscreen_filter_stop (self);
+
+ G_OBJECT_CLASS (gd_fullscreen_filter_parent_class)->dispose (object);
+}
+
+static void
+gd_fullscreen_filter_init (GdFullscreenFilter *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GD_TYPE_FULLSCREEN_FILTER,
+ GdFullscreenFilterPrivate);
+}
+
+static void
+gd_fullscreen_filter_class_init (GdFullscreenFilterClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->dispose = gd_fullscreen_filter_dispose;
+
+ signals[MOTION_EVENT] =
+ g_signal_new ("motion-event",
+ GD_TYPE_FULLSCREEN_FILTER,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (klass, sizeof (GdFullscreenFilterPrivate));
+}
+
+static GdkFilterReturn
+event_filter_func (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GdFullscreenFilter *self = user_data;
+ XEvent *xevent = (XEvent *) gdk_xevent;
+
+ if (xevent->xany.type == ButtonPress ||
+ xevent->xany.type == ButtonRelease ||
+ xevent->xany.type == MotionNotify)
+ {
+ g_signal_emit (self, signals[MOTION_EVENT], 0);
+ }
+ else if (xevent->xany.type == GenericEvent)
+ {
+ /* we just assume this is an XI2 event */
+ XIEvent *ev = (XIEvent *) xevent->xcookie.data;
+
+ if (ev->evtype == XI_Motion ||
+ ev->evtype == XI_ButtonRelease ||
+ ev->evtype == XI_ButtonPress)
+ {
+ g_signal_emit (self, signals[MOTION_EVENT], 0);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+void
+gd_fullscreen_filter_start (GdFullscreenFilter *self)
+{
+ if (self->priv->is_filtering)
+ return;
+
+ self->priv->is_filtering = TRUE;
+ gdk_window_add_filter (NULL,
+ event_filter_func, self);
+}
+
+void
+gd_fullscreen_filter_stop (GdFullscreenFilter *self)
+{
+ if (!self->priv->is_filtering)
+ return;
+
+ self->priv->is_filtering = FALSE;
+ gdk_window_remove_filter (NULL,
+ event_filter_func, self);
+}
+
+GdFullscreenFilter *
+gd_fullscreen_filter_new (void)
+{
+ return g_object_new (GD_TYPE_FULLSCREEN_FILTER, NULL);
+}
diff --git a/src/gd-fullscreen-filter.h b/src/gd-fullscreen-filter.h
new file mode 100644
index 0000000..d2a6b9c
--- /dev/null
+++ b/src/gd-fullscreen-filter.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * Gnome Documents is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Gnome Documents 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+#ifndef __GD_FULLSCREEN_FILTER_H__
+#define __GD_FULLSCREEN_FILTER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GD_TYPE_FULLSCREEN_FILTER gd_fullscreen_filter_get_type()
+
+#define GD_FULLSCREEN_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GD_TYPE_FULLSCREEN_FILTER, GdFullscreenFilter))
+
+#define GD_FULLSCREEN_FILTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GD_TYPE_FULLSCREEN_FILTER, GdFullscreenFilterClass))
+
+#define GD_IS_FULLSCREEN_FILTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GD_TYPE_FULLSCREEN_FILTER))
+
+#define GD_IS_FULLSCREEN_FILTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GD_TYPE_FULLSCREEN_FILTER))
+
+#define GD_FULLSCREEN_FILTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GD_TYPE_FULLSCREEN_FILTER, GdFullscreenFilterClass))
+
+typedef struct _GdFullscreenFilter GdFullscreenFilter;
+typedef struct _GdFullscreenFilterClass GdFullscreenFilterClass;
+typedef struct _GdFullscreenFilterPrivate GdFullscreenFilterPrivate;
+
+struct _GdFullscreenFilter
+{
+ GObject parent;
+
+ GdFullscreenFilterPrivate *priv;
+};
+
+struct _GdFullscreenFilterClass
+{
+ GObjectClass parent_class;
+};
+
+GType gd_fullscreen_filter_get_type (void) G_GNUC_CONST;
+
+GdFullscreenFilter *gd_fullscreen_filter_new (void);
+void gd_fullscreen_filter_start (GdFullscreenFilter *self);
+void gd_fullscreen_filter_stop (GdFullscreenFilter *self);
+
+G_END_DECLS
+
+#endif /* __GD_FULLSCREEN_FILTER_H__ */
diff --git a/src/totem-fullscreen.c b/src/totem-fullscreen.c
index 893f983..3ef5040 100644
--- a/src/totem-fullscreen.c
+++ b/src/totem-fullscreen.c
@@ -36,6 +36,7 @@
#include "totem-interface.h"
#include "totem-time-label.h"
#include "bacon-video-widget.h"
+#include "gd-fullscreen-filter.h"
#include "gsd-media-keys-window.h"
#define FULLSCREEN_POPUP_TIMEOUT 5
@@ -51,7 +52,6 @@ G_MODULE_EXPORT gboolean totem_fullscreen_vol_slider_pressed_cb (GtkWidget *widg
G_MODULE_EXPORT gboolean totem_fullscreen_vol_slider_released_cb (GtkWidget *widget, GdkEventButton *event, TotemFullscreen *fs);
G_MODULE_EXPORT gboolean totem_fullscreen_seek_slider_pressed_cb (GtkWidget *widget, GdkEventButton *event, TotemFullscreen *fs);
G_MODULE_EXPORT gboolean totem_fullscreen_seek_slider_released_cb (GtkWidget *widget, GdkEventButton *event, TotemFullscreen *fs);
-G_MODULE_EXPORT gboolean totem_fullscreen_motion_notify (GtkWidget *widget, GdkEventMotion *event, TotemFullscreen *fs);
G_MODULE_EXPORT gboolean totem_fullscreen_control_enter_notify (GtkWidget *widget, GdkEventCrossing *event, TotemFullscreen *fs);
G_MODULE_EXPORT gboolean totem_fullscreen_control_leave_notify (GtkWidget *widget, GdkEventCrossing *event, TotemFullscreen *fs);
@@ -71,9 +71,9 @@ struct _TotemFullscreenPrivate {
guint popup_timeout;
gboolean popup_in_progress;
gboolean pointer_on_control;
- guint motion_handler_id;
- guint motion_start_time;
- guint motion_num_events;
+ GdFullscreenFilter *filter;
+ gint64 motion_start_time;
+ guint motion_num_events;
gboolean is_fullscreen;
@@ -275,24 +275,25 @@ totem_fullscreen_popup_hide (TotemFullscreen *fs)
return FALSE;
}
-G_MODULE_EXPORT gboolean
-totem_fullscreen_motion_notify (GtkWidget *widget,
- GdkEventMotion *event,
- TotemFullscreen *fs)
+static void
+totem_fullscreen_motion_notify (GdFullscreenFilter *filter,
+ TotemFullscreen *fs)
{
- int motion_delay;
+ gint64 motion_delay;
+ gint64 curr;
+ curr = g_get_monotonic_time ();
/* Only after FULLSCREEN_MOTION_NUM_EVENTS motion events,
in FULLSCREEN_MOTION_TIME milliseconds will we show
the popups */
- motion_delay = event->time - fs->priv->motion_start_time;
+ motion_delay = (curr - fs->priv->motion_start_time) / 1000;
if (fs->priv->motion_start_time == 0 ||
motion_delay < 0 ||
motion_delay > FULLSCREEN_MOTION_TIME) {
- fs->priv->motion_start_time = event->time;
+ fs->priv->motion_start_time = curr;
fs->priv->motion_num_events = 0;
- return FALSE;
+ return;
}
fs->priv->motion_num_events++;
@@ -301,8 +302,6 @@ totem_fullscreen_motion_notify (GtkWidget *widget,
fs->priv->motion_num_events > FULLSCREEN_MOTION_NUM_EVENTS) {
totem_fullscreen_show_popups (fs, TRUE);
}
-
- return FALSE;
}
void
@@ -416,14 +415,10 @@ totem_fullscreen_set_fullscreen (TotemFullscreen *fs,
fs->priv->is_fullscreen = fullscreen;
- if (fullscreen == FALSE && fs->priv->motion_handler_id != 0) {
- g_signal_handler_disconnect (G_OBJECT (fs->priv->bvw),
- fs->priv->motion_handler_id);
- fs->priv->motion_handler_id = 0;
- } else if (fullscreen != FALSE && fs->priv->motion_handler_id == 0 && fs->priv->bvw != NULL) {
- fs->priv->motion_handler_id = g_signal_connect (G_OBJECT (fs->priv->bvw), "motion-notify-event",
- G_CALLBACK (totem_fullscreen_motion_notify), fs);
- }
+ if (fullscreen == FALSE)
+ gd_fullscreen_filter_stop (fs->priv->filter);
+ else
+ gd_fullscreen_filter_start (fs->priv->filter);
}
static void
@@ -469,11 +464,14 @@ totem_fullscreen_new (GtkWindow *toplevel_window)
/* Volume */
fs->volume = GTK_WIDGET (gtk_builder_get_object (fs->priv->xml, "tcw_volume_button"));
-
+
/* Seek */
fs->seek = GTK_WIDGET (gtk_builder_get_object (fs->priv->xml, "tcw_seek_hscale"));
/* Motion notify */
+ fs->priv->filter = gd_fullscreen_filter_new ();
+ g_signal_connect (G_OBJECT (fs->priv->filter), "motion-event",
+ G_CALLBACK (totem_fullscreen_motion_notify), fs);
gtk_widget_add_events (fs->seek, GDK_POINTER_MOTION_MASK);
gtk_widget_add_events (fs->exit_button, GDK_POINTER_MOTION_MASK);
@@ -489,11 +487,6 @@ totem_fullscreen_set_video_widget (TotemFullscreen *fs,
g_return_if_fail (fs->priv->bvw == NULL);
fs->priv->bvw = bvw;
-
- if (fs->priv->is_fullscreen != FALSE && fs->priv->motion_handler_id == 0) {
- fs->priv->motion_handler_id = g_signal_connect (G_OBJECT (fs->priv->bvw), "motion-notify-event",
- G_CALLBACK (totem_fullscreen_motion_notify), fs);
- }
}
void
@@ -561,10 +554,9 @@ totem_fullscreen_finalize (GObject *object)
TotemFullscreen *fs = TOTEM_FULLSCREEN (object);
totem_fullscreen_popup_timeout_remove (fs);
- if (fs->priv->motion_handler_id != 0) {
- g_signal_handler_disconnect (G_OBJECT (fs->priv->bvw),
- fs->priv->motion_handler_id);
- fs->priv->motion_handler_id = 0;
+ if (fs->priv->filter) {
+ g_object_unref (fs->priv->filter);
+ fs->priv->filter = NULL;
}
if (fs->priv->osd != NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]