Merge lp:~3v1n0/indicator-sound/mute-on-secondary-activate into lp:indicator-sound/fourth

Proposed by Marco Trevisan (Treviño) on 2011-07-19
Status: Merged
Merged at revision: 254
Proposed branch: lp:~3v1n0/indicator-sound/mute-on-secondary-activate
Merge into: lp:indicator-sound/fourth
Prerequisite: lp:~3v1n0/indicator-sound/compile-with-new-API
Diff against target: 367 lines (+269/-0)
5 files modified
src/Makefile.am (+2/-0)
src/indicator-sound.c (+54/-0)
src/mute-menu-item.c (+5/-0)
src/mute-widget.c (+141/-0)
src/mute-widget.h (+67/-0)
To merge this branch: bzr merge lp:~3v1n0/indicator-sound/mute-on-secondary-activate
Reviewer Review Type Date Requested Status
Conor Curran (community) 2011-07-19 Approve on 2011-07-28
Indicator Applet Developers 2011-07-19 Pending
Review via email: mp+68399@code.launchpad.net

Description of the change

When the "secondary-activate" event is emitted, the indicator-sound should toggle the volume on/off.

This branch performs this using a new mute-widget that is used by indicator-sound to control the mute-menu-item dbus menuitem.

The code needs the libindicator support (available in lp:~3v1n0/libindicator/secondary-activate-support) and unity/unity-2d support (available in lp:~3v1n0/unity/secondary-activate-support and in lp:~3v1n0/unity-2d/secondary-activate-support)

To post a comment you must log in.
257. By Marco Trevisan (Treviño) on 2011-07-21

X and Y pointer position aren't exported anymore by libindicator

Dropping them!

Conor Curran (cjcurran) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Makefile.am'
2--- src/Makefile.am 2011-06-22 19:19:49 +0000
3+++ src/Makefile.am 2011-07-21 16:14:32 +0000
4@@ -18,6 +18,8 @@
5 transport-widget.h \
6 metadata-widget.c \
7 metadata-widget.h \
8+ mute-widget.c \
9+ mute-widget.h \
10 volume-widget.c \
11 volume-widget.h \
12 voip-input-widget.c \
13
14=== modified file 'src/indicator-sound.c'
15--- src/indicator-sound.c 2011-07-02 03:32:23 +0000
16+++ src/indicator-sound.c 2011-07-21 16:14:32 +0000
17@@ -39,6 +39,7 @@
18 #include "voip-input-widget.h"
19 #include "dbus-shared-names.h"
20 #include "sound-state-manager.h"
21+#include "mute-widget.h"
22
23 #include "gen-sound-service.xml.h"
24 #include "common-defs.h"
25@@ -49,6 +50,7 @@
26 {
27 GtkWidget* volume_widget;
28 GtkWidget* voip_widget;
29+ MuteWidget *mute_widget;
30 GList* transport_widgets_list;
31 GDBusProxy *dbus_proxy;
32 SoundStateManager* state_manager;
33@@ -75,6 +77,9 @@
34 static void indicator_sound_scroll (IndicatorObject * io,
35 IndicatorObjectEntry * entry, gint delta,
36 IndicatorScrollDirection direction);
37+static void indicator_sound_middle_click (IndicatorObject * io,
38+ IndicatorObjectEntry * entry,
39+ guint time, gpointer data);
40
41 //key/moust event handlers
42 static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data);
43@@ -97,6 +102,10 @@
44 DbusmenuMenuitem * parent,
45 DbusmenuClient * client,
46 gpointer user_data);
47+static gboolean new_mute_widget (DbusmenuMenuitem * newitem,
48+ DbusmenuMenuitem * parent,
49+ DbusmenuClient * client,
50+ gpointer user_data);
51
52 // DBUS communication
53 static GDBusNodeInfo *node_info = NULL;
54@@ -125,6 +134,7 @@
55 io_class->get_menu = get_menu;
56 io_class->get_accessible_desc = get_accessible_desc;
57 io_class->entry_scrolled = indicator_sound_scroll;
58+ io_class->secondary_activate = indicator_sound_middle_click;
59 }
60
61 static void
62@@ -137,6 +147,7 @@
63 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
64 priv->volume_widget = NULL;
65 priv->voip_widget = NULL;
66+ priv->mute_widget = NULL;
67 priv->dbus_proxy = NULL;
68 GList* t_list = NULL;
69 priv->transport_widgets_list = t_list;
70@@ -207,6 +218,9 @@
71 dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
72 DBUSMENU_METADATA_MENUITEM_TYPE,
73 new_metadata_widget);
74+ dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client),
75+ DBUSMENU_MUTE_MENUITEM_TYPE,
76+ new_mute_widget);
77 // Note: Not ideal but all key handling needs to be managed here and then
78 // delegated to the appropriate widget.
79 g_signal_connect (menu, "key-press-event", G_CALLBACK(key_press_cb), io);
80@@ -459,6 +473,36 @@
81 return TRUE;
82 }
83
84+static gboolean
85+new_mute_widget(DbusmenuMenuitem * newitem,
86+ DbusmenuMenuitem * parent,
87+ DbusmenuClient * client,
88+ gpointer user_data)
89+{
90+ IndicatorObject *io = NULL;
91+
92+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
93+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
94+
95+ io = g_object_get_data (G_OBJECT (client), "indicator");
96+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
97+
98+ if (priv->mute_widget != NULL){
99+ g_object_unref (priv->mute_widget);
100+ priv->mute_widget = NULL;
101+ }
102+
103+ priv->mute_widget = mute_widget_new(newitem);
104+ GtkMenuItem *item = mute_widget_get_menu_item (priv->mute_widget);
105+
106+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
107+ newitem,
108+ item,
109+ parent);
110+
111+ return TRUE;
112+}
113+
114 /*******************************************************************/
115 //UI callbacks
116 /******************************************************************/
117@@ -677,6 +721,16 @@
118 sound_state_manager_show_notification (priv->state_manager, value);
119 }
120
121+static void
122+indicator_sound_middle_click (IndicatorObject * io, IndicatorObjectEntry * entry,
123+ guint time, gpointer data)
124+{
125+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
126+ g_return_if_fail (priv);
127+
128+ mute_widget_toggle(priv->mute_widget);
129+}
130+
131 void
132 update_accessible_desc (IndicatorObject * io)
133 {
134
135=== modified file 'src/mute-menu-item.c'
136--- src/mute-menu-item.c 2011-02-18 13:05:58 +0000
137+++ src/mute-menu-item.c 2011-07-21 16:14:32 +0000
138@@ -63,6 +63,11 @@
139 MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE(self);
140 priv->button = NULL;
141 priv->button = dbusmenu_menuitem_new();
142+
143+ dbusmenu_menuitem_property_set(priv->button,
144+ DBUSMENU_MENUITEM_PROP_TYPE,
145+ DBUSMENU_MUTE_MENUITEM_TYPE);
146+
147 dbusmenu_menuitem_property_set_bool (priv->button,
148 DBUSMENU_MENUITEM_PROP_VISIBLE,
149 TRUE);
150
151=== added file 'src/mute-widget.c'
152--- src/mute-widget.c 1970-01-01 00:00:00 +0000
153+++ src/mute-widget.c 2011-07-21 16:14:32 +0000
154@@ -0,0 +1,141 @@
155+/*
156+Copyright 2011 Canonical Ltd.
157+
158+Authors:
159+ Marco Trevisan (Treviño) <mail@3v1n0.net>
160+
161+This program is free software: you can redistribute it and/or modify it
162+under the terms of the GNU General Public License version 3, as published
163+by the Free Software Foundation.
164+
165+This program is distributed in the hope that it will be useful, but
166+WITHOUT ANY WARRANTY; without even the implied warranties of
167+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
168+PURPOSE. See the GNU General Public License for more details.
169+
170+You should have received a copy of the GNU General Public License along
171+with this program. If not, see <http://www.gnu.org/licenses/>.
172+*/
173+
174+#ifdef HAVE_CONFIG_H
175+#include "config.h"
176+#endif
177+
178+#include <glib/gi18n.h>
179+#include <glib.h>
180+#include "mute-widget.h"
181+#include "common-defs.h"
182+#include "indicator-sound.h"
183+
184+typedef struct _MuteWidgetPrivate MuteWidgetPrivate;
185+
186+struct _MuteWidgetPrivate
187+{
188+ DbusmenuMenuitem *item;
189+ GtkMenuItem *gitem;
190+};
191+
192+#define MUTE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MUTE_WIDGET_TYPE, MuteWidgetPrivate))
193+
194+/* Prototypes */
195+static void mute_widget_class_init (MuteWidgetClass *klass);
196+static void mute_widget_init (MuteWidget *self);
197+static void mute_widget_dispose (GObject *object);
198+static void mute_widget_finalize (GObject *object);
199+
200+G_DEFINE_TYPE (MuteWidget, mute_widget, G_TYPE_OBJECT);
201+
202+static void
203+mute_widget_class_init (MuteWidgetClass *klass)
204+{
205+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
206+ gobject_class->dispose = mute_widget_dispose;
207+ gobject_class->finalize = mute_widget_finalize;
208+ g_type_class_add_private (klass, sizeof (MuteWidgetPrivate));
209+}
210+
211+static void
212+mute_widget_init (MuteWidget *self)
213+{
214+ MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self);
215+ priv->item = NULL;
216+ priv->gitem = GTK_MENU_ITEM(gtk_menu_item_new ());
217+}
218+
219+static void
220+mute_widget_dispose (GObject *object)
221+{
222+ G_OBJECT_CLASS (mute_widget_parent_class)->dispose (object);
223+}
224+
225+static void
226+mute_widget_finalize (GObject *object)
227+{
228+ MuteWidget *self = MUTE_WIDGET (object);
229+ MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self);
230+
231+ g_object_unref (priv->item);
232+ g_object_unref (G_OBJECT (priv->gitem));
233+ G_OBJECT_CLASS (mute_widget_parent_class)->finalize (object);
234+}
235+
236+GtkMenuItem *
237+mute_widget_get_menu_item(MuteWidget *self)
238+{
239+ MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self);
240+ return priv->gitem;
241+}
242+
243+MuteStatus
244+mute_widget_get_status (MuteWidget *self)
245+{
246+ g_return_val_if_fail(self, MUTE_STATUS_UNAVAILABLE);
247+ MuteStatus status = MUTE_STATUS_UNAVAILABLE;
248+ MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self);
249+
250+ GVariant *vstatus = dbusmenu_menuitem_property_get_variant(priv->item,
251+ DBUSMENU_MUTE_MENUITEM_VALUE);
252+
253+ if (g_variant_is_of_type (vstatus, G_VARIANT_TYPE_BOOLEAN))
254+ {
255+ if (g_variant_get_boolean (vstatus))
256+ status = MUTE_STATUS_MUTED;
257+ else
258+ status = MUTE_STATUS_UNMUTED;
259+ }
260+
261+ return status;
262+}
263+
264+void mute_widget_toggle (MuteWidget *self)
265+{
266+ g_return_if_fail (self);
267+ MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self);
268+ gtk_menu_item_activate (priv->gitem);
269+}
270+
271+/**
272+ * mute_widget_new:
273+ * @returns: a new #MuteWidget.
274+ **/
275+MuteWidget *
276+mute_widget_new (DbusmenuMenuitem *item)
277+{
278+ MuteWidget* widget = g_object_new(MUTE_WIDGET_TYPE, NULL);
279+ MuteWidgetPrivate* priv = MUTE_WIDGET_GET_PRIVATE(widget);
280+ priv->item = g_object_ref(item);
281+
282+ GVariant *label = dbusmenu_menuitem_property_get_variant(priv->item,
283+ DBUSMENU_MENUITEM_PROP_LABEL);
284+
285+ if (g_variant_is_of_type(label, G_VARIANT_TYPE_STRING))
286+ gtk_menu_item_set_label(priv->gitem, g_variant_get_string(label, NULL));
287+
288+ if (label)
289+ {
290+ g_debug("Added a new Mute Widget %s", g_variant_print(label, FALSE));
291+ g_variant_unref(label);
292+ }
293+
294+ return widget;
295+}
296
297=== added file 'src/mute-widget.h'
298--- src/mute-widget.h 1970-01-01 00:00:00 +0000
299+++ src/mute-widget.h 2011-07-21 16:14:32 +0000
300@@ -0,0 +1,67 @@
301+/*
302+Copyright 2011 Canonical Ltd.
303+
304+Authors:
305+ Marco Trevisan (Treviño) <mail@3v1n0.net>
306+
307+This program is free software: you can redistribute it and/or modify it
308+under the terms of the GNU General Public License version 3, as published
309+by the Free Software Foundation.
310+
311+This program is distributed in the hope that it will be useful, but
312+WITHOUT ANY WARRANTY; without even the implied warranties of
313+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
314+PURPOSE. See the GNU General Public License for more details.
315+
316+You should have received a copy of the GNU General Public License along
317+with this program. If not, see <http://www.gnu.org/licenses/>.
318+*/
319+#ifndef __MUTE_WIDGET_H__
320+#define __MUTE_WIDGET_H__
321+
322+#include <glib.h>
323+#include <glib-object.h>
324+#include <gtk/gtk.h>
325+#if GTK_CHECK_VERSION(3, 0, 0)
326+#include <libdbusmenu-gtk3/menuitem.h>
327+#else
328+#include <libdbusmenu-gtk/menuitem.h>
329+#endif
330+#include <libindicator/indicator-object.h>
331+
332+G_BEGIN_DECLS
333+
334+#define MUTE_WIDGET_TYPE (mute_widget_get_type ())
335+#define MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTE_WIDGET_TYPE, MuteWidget))
336+#define MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTE_WIDGET_TYPE, MuteWidgetClass))
337+#define IS_MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTE_WIDGET_TYPE))
338+#define IS_MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTE_WIDGET_TYPE))
339+#define MUTE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTE_WIDGET_TYPE, MuteWidgetClass))
340+
341+typedef struct _MuteWidget MuteWidget;
342+typedef struct _MuteWidgetClass MuteWidgetClass;
343+
344+struct _MuteWidgetClass {
345+ GObjectClass parent_class;
346+};
347+
348+struct _MuteWidget {
349+ GObject parent;
350+};
351+
352+typedef enum {
353+ MUTE_STATUS_UNAVAILABLE,
354+ MUTE_STATUS_MUTED,
355+ MUTE_STATUS_UNMUTED
356+} MuteStatus;
357+
358+GType mute_widget_get_type (void) G_GNUC_CONST;
359+MuteWidget* mute_widget_new (DbusmenuMenuitem *item);
360+MuteStatus mute_widget_get_status (MuteWidget *self);
361+void mute_widget_toggle (MuteWidget *self);
362+GtkMenuItem *mute_widget_get_menu_item (MuteWidget *self);
363+
364+G_END_DECLS
365+
366+#endif
367+

Subscribers

People subscribed via source and target branches