[Xfce4-commits] [xfce/xfwm4] 03/32: Implement RangeDebouncer

noreply at xfce.org noreply at xfce.org
Tue Dec 5 09:21:49 CET 2017


This is an automated email from the git hooks/post-receive script.

o   l   i   v   i   e   r       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository xfce/xfwm4.

commit 473ef8458b4e31711cbf2f7675d6bf0bbba52df5
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Wed Jun 28 22:57:26 2017 +0300

    Implement RangeDebouncer
    
    This object allows to easily listen GtkRange value when drag
    was finished. This was allowed in GTK2 with "update-policy" attribute
    set to "discontinuous" which was removed in GTK3.
---
 settings-dialogs/Makefile.am       |   4 +
 settings-dialogs/range-debouncer.c | 232 +++++++++++++++++++++++++++++++++++++
 settings-dialogs/range-debouncer.h |  44 +++++++
 settings-dialogs/tweaks-settings.c |  11 +-
 settings-dialogs/xfwm4-settings.c  |   9 +-
 5 files changed, 291 insertions(+), 9 deletions(-)

diff --git a/settings-dialogs/Makefile.am b/settings-dialogs/Makefile.am
index 4d96f2c..f477c60 100644
--- a/settings-dialogs/Makefile.am
+++ b/settings-dialogs/Makefile.am
@@ -36,6 +36,8 @@ xfwm4_settings_SOURCES = \
 	xfwm4-settings.c \
 	xfwm4-settings.h \
 	xfwm4-dialog_ui.h \
+	range-debouncer.c \
+	range-debouncer.h \
 	common.c \
 	common.h
 
@@ -61,6 +63,8 @@ xfwm4_settings_LDADD = \
 xfwm4_tweaks_settings_SOURCES = \
 	tweaks-settings.c \
 	xfwm4-tweaks-dialog_ui.h \
+	range-debouncer.c \
+	range-debouncer.h \
 	common.c \
 	common.h
 
diff --git a/settings-dialogs/range-debouncer.c b/settings-dialogs/range-debouncer.c
new file mode 100644
index 0000000..571670b
--- /dev/null
+++ b/settings-dialogs/range-debouncer.c
@@ -0,0 +1,232 @@
+/* vi:set sw=2 sts=2 ts=2 et ai tw=100: */
+/*-
+ * Copyright (c) 2017 Viktor Odintsev <zakhams at gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "range-debouncer.h"
+
+
+
+struct _RangeDebouncerClass
+{
+  GObjectClass         __parent__;
+};
+
+struct _RangeDebouncer
+{
+  GObject              __parent__;
+
+  GtkRange            *range;
+  gboolean             pressed : 1;
+
+  gulong               signal1;
+  gulong               signal2;
+  gulong               signal3;
+};
+
+enum
+{
+  PROP_0,
+  PROP_VALUE,
+  N_PROPERTIES,
+};
+
+static void              range_debouncer_finalize                        (GObject               *object);
+static void              range_debouncer_get_property                    (GObject               *object,
+                                                                          guint                  prop_id,
+                                                                          GValue                *value,
+                                                                          GParamSpec            *pspec);
+static void              range_debouncer_set_property                    (GObject               *object,
+                                                                          guint                  prop_id,
+                                                                          const GValue          *value,
+                                                                          GParamSpec            *pspec);
+
+static void              range_debouncer_weak_notify                     (RangeDebouncer *range_debouncer);
+
+static void              range_debouncer_value_changed                   (RangeDebouncer *range_debouncer);
+static gboolean          range_debouncer_button_pressed                  (RangeDebouncer *range_debouncer);
+static gboolean          range_debouncer_button_released                 (RangeDebouncer *range_debouncer);
+
+G_DEFINE_TYPE (RangeDebouncer, range_debouncer, G_TYPE_OBJECT)
+
+
+
+static void
+range_debouncer_class_init (RangeDebouncerClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = range_debouncer_finalize;
+  gobject_class->get_property = range_debouncer_get_property;
+  gobject_class->set_property = range_debouncer_set_property;
+
+  g_object_class_install_property (gobject_class, PROP_VALUE,
+                                   g_param_spec_double ("value", NULL, NULL,
+                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+                                                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+
+
+static void
+range_debouncer_init (RangeDebouncer *range_debouncer)
+{
+  range_debouncer->range = NULL;
+  range_debouncer->pressed = FALSE;
+
+  range_debouncer->signal1 = 0;
+  range_debouncer->signal2 = 0;
+  range_debouncer->signal3 = 0;
+}
+
+
+
+RangeDebouncer *
+range_debouncer_bind (GtkRange *range)
+{
+  RangeDebouncer *range_debouncer;
+
+  g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
+
+  range_debouncer = g_object_new (TYPE_RANGE_DEBOUNCER, NULL);
+  range_debouncer->range = range;
+
+  /* RangeDebouncer will be destroyed with GtkRange */
+  g_object_weak_ref (G_OBJECT (range), (GWeakNotify)range_debouncer_weak_notify, range_debouncer);
+
+  range_debouncer->signal1 =
+    g_signal_connect_swapped (range, "value-changed",
+                              G_CALLBACK (range_debouncer_value_changed), range_debouncer);
+  range_debouncer->signal2 =
+    g_signal_connect_swapped (range, "button-press-event",
+                              G_CALLBACK (range_debouncer_button_pressed), range_debouncer);
+  range_debouncer->signal3 =
+    g_signal_connect_swapped (range, "button-release-event",
+                              G_CALLBACK (range_debouncer_button_released), range_debouncer);
+
+  return range_debouncer;
+}
+
+
+
+static void
+range_debouncer_finalize (GObject *object)
+{
+  RangeDebouncer *range_debouncer = RANGE_DEBOUNCER (object);
+
+  if (G_UNLIKELY (range_debouncer->range != NULL))
+    {
+      g_signal_handler_disconnect(range_debouncer->range, range_debouncer->signal1);
+      g_signal_handler_disconnect(range_debouncer->range, range_debouncer->signal2);
+      g_signal_handler_disconnect(range_debouncer->range, range_debouncer->signal3);
+    }
+
+  G_OBJECT_CLASS (range_debouncer_parent_class)->finalize (object);
+}
+
+
+
+static void
+range_debouncer_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  RangeDebouncer *range_debouncer = RANGE_DEBOUNCER (object);
+
+  switch (prop_id)
+    {
+    case PROP_VALUE:
+      if (G_LIKELY (range_debouncer->range != NULL))
+        g_value_set_double (value, gtk_range_get_value (range_debouncer->range));
+      else
+        g_value_set_double (value, 0);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+range_debouncer_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  RangeDebouncer *range_debouncer = RANGE_DEBOUNCER (object);
+  gdouble         val_double;
+
+  switch (prop_id)
+    {
+    case PROP_VALUE:
+      val_double = g_value_get_double (value);
+      if (G_LIKELY (range_debouncer->range != NULL) &&
+          gtk_range_get_value (range_debouncer->range) != val_double)
+        {
+          gtk_range_set_value (range_debouncer->range, val_double);
+          g_object_notify (object, "value");
+        }
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+range_debouncer_weak_notify (RangeDebouncer *range_debouncer)
+{
+  range_debouncer->range = NULL;
+  g_object_unref (range_debouncer);
+}
+
+
+
+static void
+range_debouncer_value_changed (RangeDebouncer *range_debouncer)
+{
+  if (!range_debouncer->pressed)
+    g_object_notify (G_OBJECT (range_debouncer), "value");
+}
+
+
+
+static gboolean
+range_debouncer_button_pressed (RangeDebouncer *range_debouncer)
+{
+  range_debouncer->pressed = TRUE;
+  return FALSE;
+}
+
+
+
+static gboolean
+range_debouncer_button_released (RangeDebouncer *range_debouncer)
+{
+  range_debouncer->pressed = FALSE;
+  g_object_notify (G_OBJECT (range_debouncer), "value");
+  return FALSE;
+}
diff --git a/settings-dialogs/range-debouncer.h b/settings-dialogs/range-debouncer.h
new file mode 100644
index 0000000..4db04b4
--- /dev/null
+++ b/settings-dialogs/range-debouncer.h
@@ -0,0 +1,44 @@
+/* vi:set sw=2 sts=2 ts=2 et ai tw=100: */
+/*-
+ * Copyright (c) 2017 Viktor Odintsev <zakhams at gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __RANGE_DEBOUNCER_H__
+#define __RANGE_DEBOUNCER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _RangeDebouncerClass      RangeDebouncerClass;
+typedef struct _RangeDebouncer           RangeDebouncer;
+
+#define TYPE_RANGE_DEBOUNCER             (range_debouncer_get_type ())
+#define RANGE_DEBOUNCER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RANGE_DEBOUNCER, RangeDebouncer))
+#define RANGE_DEBOUNCER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  TYPE_RANGE_DEBOUNCER, RangeDebouncerClass))
+#define IS_RANGE_DEBOUNCER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RANGE_DEBOUNCER))
+#define IS_RANGE_DEBOUNCER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  TYPE_RANGE_DEBOUNCER))
+#define RANGE_DEBOUNCER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  TYPE_RANGE_DEBOUNCER, RangeDebouncerClass))
+
+GType                     range_debouncer_get_type                 (void)                           G_GNUC_CONST;
+
+RangeDebouncer *          range_debouncer_bind                     (GtkRange          *range);
+
+G_END_DECLS
+
+#endif /* __RANGE_DEBOUNCER_H__ */
diff --git a/settings-dialogs/tweaks-settings.c b/settings-dialogs/tweaks-settings.c
index d3b45c5..1ed1109 100644
--- a/settings-dialogs/tweaks-settings.c
+++ b/settings-dialogs/tweaks-settings.c
@@ -44,6 +44,7 @@
 #include <xfconf/xfconf.h>
 
 #include "xfwm4-tweaks-dialog_ui.h"
+#include "range-debouncer.h"
 #include "common.h"
 
 static Window opt_socket_id = 0;
@@ -420,23 +421,23 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/frame_opacity",
                             G_TYPE_INT,
-                            (GObject *) gtk_range_get_adjustment (GTK_RANGE (frame_opacity_scale)), "value");
+                            (GObject *) range_debouncer_bind (GTK_RANGE (frame_opacity_scale)), "value");
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/resize_opacity",
                             G_TYPE_INT,
-                            (GObject *) gtk_range_get_adjustment (GTK_RANGE (resize_opacity_scale)), "value");
+                            (GObject *) range_debouncer_bind (GTK_RANGE (resize_opacity_scale)), "value");
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/move_opacity",
                             G_TYPE_INT,
-                            (GObject *) gtk_range_get_adjustment (GTK_RANGE (move_opacity_scale)), "value");
+                            (GObject *) range_debouncer_bind (GTK_RANGE (move_opacity_scale)), "value");
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/inactive_opacity",
                             G_TYPE_INT,
-                            (GObject *) gtk_range_get_adjustment (GTK_RANGE (inactive_opacity_scale)), "value");
+                            (GObject *) range_debouncer_bind (GTK_RANGE (inactive_opacity_scale)), "value");
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/popup_opacity",
                             G_TYPE_INT,
-                            (GObject *) gtk_range_get_adjustment (GTK_RANGE (popup_opacity_scale)), "value");
+                            (GObject *) range_debouncer_bind (GTK_RANGE (popup_opacity_scale)), "value");
 
     vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main-vbox"));
     gtk_widget_show_all (vbox);
diff --git a/settings-dialogs/xfwm4-settings.c b/settings-dialogs/xfwm4-settings.c
index 45daa35..094b304 100644
--- a/settings-dialogs/xfwm4-settings.c
+++ b/settings-dialogs/xfwm4-settings.c
@@ -48,6 +48,7 @@
 
 #include "xfwm4-dialog_ui.h"
 #include "xfwm4-settings.h"
+#include "range-debouncer.h"
 #include "common.h"
 
 
@@ -561,9 +562,9 @@ xfwm_settings_constructed (GObject *object)
 
   /* Focus tab */
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/focus_delay", G_TYPE_INT,
-                          gtk_range_get_adjustment (GTK_RANGE (focus_delay_scale)), "value");
+                          range_debouncer_bind (GTK_RANGE (focus_delay_scale)), "value");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/raise_delay", G_TYPE_INT,
-                          gtk_range_get_adjustment (GTK_RANGE (focus_raise_delay_scale)), "value");
+                          range_debouncer_bind (GTK_RANGE (focus_raise_delay_scale)), "value");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/raise_on_click", G_TYPE_BOOLEAN,
                           raise_on_click_check, "active");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/raise_on_focus", G_TYPE_BOOLEAN,
@@ -630,9 +631,9 @@ xfwm_settings_constructed (GObject *object)
 
   /* Advanced tab */
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/snap_width", G_TYPE_INT,
-                          gtk_range_get_adjustment (GTK_RANGE (snap_width_scale)), "value");
+                          range_debouncer_bind (GTK_RANGE (snap_width_scale)), "value");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/wrap_resistance", G_TYPE_INT,
-                          gtk_range_get_adjustment (GTK_RANGE (wrap_resistance_scale)), "value");
+                          range_debouncer_bind (GTK_RANGE (wrap_resistance_scale)), "value");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/box_move", G_TYPE_BOOLEAN,
                           box_move_check, "active");
   xfconf_g_property_bind (settings->priv->wm_channel, "/general/box_resize", G_TYPE_BOOLEAN,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list