Commit 05801ced authored by Alberts Muktupāvels's avatar Alberts Muktupāvels
Browse files

bluetooth-applet: add status icon

Thanks György Balló for initial version in javascript.

https://bugzilla.gnome.org/show_bug.cgi?id=753424
parent 55114715
......@@ -47,7 +47,7 @@ PKG_CHECK_MODULES(AUTOMOUNT_MANAGER, gtk+-3.0 >= $GTK_REQUIRED gsettings-desktop
AC_SUBST(AUTOMOUNT_MANAGER_CFLAGS)
AC_SUBST(AUTOMOUNT_MANAGER_LIBS)
PKG_CHECK_MODULES(BLUETOOTH_APPLET, gtk+-3.0 >= $GTK_REQUIRED)
PKG_CHECK_MODULES(BLUETOOTH_APPLET, gtk+-3.0 >= $GTK_REQUIRED gnome-bluetooth-1.0)
AC_SUBST(BLUETOOTH_APPLET_CFLAGS)
AC_SUBST(BLUETOOTH_APPLET_LIBS)
......
......@@ -17,23 +17,420 @@
#include "config.h"
#include <bluetooth-client.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "gf-bluetooth-applet.h"
#include "gf-sd-rfkill.h"
#define GSM_DBUS_NAME "org.gnome.SettingsDaemon.Rfkill"
#define GSM_DBUS_PATH "/org/gnome/SettingsDaemon/Rfkill"
struct _GfBluetoothApplet
{
GObject parent;
GObject parent;
GtkStatusIcon *status_icon;
GfSdRfkill *rfkill;
BluetoothClient *client;
GtkTreeModel *model;
};
G_DEFINE_TYPE (GfBluetoothApplet, gf_bluetooth_applet, G_TYPE_OBJECT)
static void
turn_off_cb (GtkMenuItem *item,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
if (applet->rfkill == NULL)
return;
gf_sd_rfkill_set_bluetooth_airplane_mode (applet->rfkill, FALSE);
}
static void
send_files_cb (GtkMenuItem *item,
gpointer user_data)
{
GAppInfo *app_info;
GError *error;
error = NULL;
app_info = g_app_info_create_from_commandline ("bluetooth-sendto",
"Bluetooth Transfer",
G_APP_INFO_CREATE_NONE,
&error);
if (error != NULL)
{
g_warning ("Failed to crete GAppInfo from commandline - %s",
error->message);
g_error_free (error);
}
else
{
g_app_info_launch (app_info, NULL, NULL, &error);
if (error != NULL)
{
g_warning ("Failed to start Bluetooth Transfer - %s", error->message);
g_error_free (error);
}
}
g_clear_object (&app_info);
}
static void
turn_on_cb (GtkMenuItem *item,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
if (applet->rfkill == NULL)
return;
gf_sd_rfkill_set_bluetooth_airplane_mode (applet->rfkill, TRUE);
}
static void
settings_cb (GtkMenuItem *item,
gpointer user_data)
{
GAppInfo *app_info;
GError *error;
error = NULL;
app_info = g_app_info_create_from_commandline ("gnome-control-center bluetooth",
"Bluetooth Settings",
G_APP_INFO_CREATE_NONE,
&error);
if (error != NULL)
{
g_warning ("Failed to crete GAppInfo from commandline - %s",
error->message);
g_error_free (error);
}
else
{
g_app_info_launch (app_info, NULL, NULL, &error);
if (error != NULL)
{
g_warning ("Failed to start Bluetooth Settings - %s", error->message);
g_error_free (error);
}
}
g_clear_object (&app_info);
}
static void
popup_menu_cb (GtkStatusIcon *status_icon,
guint button,
guint activate_time,
gpointer user_data)
{
GfBluetoothApplet *applet;
GtkWidget *menu;
gboolean airplane_mode;
GtkWidget *item;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
applet = GF_BLUETOOTH_APPLET (user_data);
menu = gtk_menu_new ();
airplane_mode = FALSE;
if (applet->rfkill != NULL)
airplane_mode = gf_sd_rfkill_get_bluetooth_airplane_mode (applet->rfkill);
if (!airplane_mode)
{
item = gtk_menu_item_new_with_label (_("Turn Off"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (item, "activate", G_CALLBACK (turn_off_cb), NULL);
item = gtk_menu_item_new_with_label (_("Send Files"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (item, "activate", G_CALLBACK (send_files_cb), NULL);
}
else
{
item = gtk_menu_item_new_with_label (_("Turn On"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (item, "activate", G_CALLBACK (turn_on_cb), NULL);
}
item = gtk_menu_item_new_with_label (_("Bluetooth Settings"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (item, "activate", G_CALLBACK (settings_cb), NULL);
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
gtk_status_icon_position_menu, status_icon,
button, activate_time);
G_GNUC_END_IGNORE_DEPRECATIONS
}
static GtkTreeIter *
get_default_adapter (GfBluetoothApplet *applet)
{
gboolean valid;
GtkTreeIter iter;
valid = gtk_tree_model_get_iter_first (applet->model, &iter);
while (valid)
{
gboolean is_default;
gtk_tree_model_get (applet->model, &iter,
BLUETOOTH_COLUMN_DEFAULT, &is_default,
-1);
if (is_default)
return gtk_tree_iter_copy (&iter);
valid = gtk_tree_model_iter_next (applet->model , &iter);
}
return NULL;
}
static guint
get_n_connected_devices (GfBluetoothApplet *applet)
{
GtkTreeIter *adapter;
guint devices;
gboolean valid;
GtkTreeIter iter;
adapter = get_default_adapter (applet);
devices = 0;
if (adapter == NULL)
return 0;
valid = gtk_tree_model_iter_children (applet->model, &iter, adapter);
while (valid)
{
gboolean is_connected;
gtk_tree_model_get (applet->model, &iter,
BLUETOOTH_COLUMN_CONNECTED, &is_connected,
-1);
if (is_connected)
devices++;
valid = gtk_tree_model_iter_next (applet->model , &iter);
}
gtk_tree_iter_free (adapter);
return devices;
}
static void
gf_bluetooth_applet_sync (GfBluetoothApplet *applet)
{
guint devices;
gboolean airplane_mode;
const gchar *title;
const gchar *icon_name;
gchar *tooltip_text;
devices = get_n_connected_devices (applet);
if (devices == 0)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_status_icon_set_visible (applet->status_icon, FALSE);
G_GNUC_END_IGNORE_DEPRECATIONS
return;
}
airplane_mode = FALSE;
if (applet->rfkill != NULL)
airplane_mode = gf_sd_rfkill_get_bluetooth_airplane_mode (applet->rfkill);
if (!airplane_mode)
{
title = _("Bluetooth active");
icon_name = "bluetooth-active";
}
else
{
title = _("Bluetooth disabled");
icon_name = "bluetooth-disabled";
}
tooltip_text = g_strdup_printf (ngettext ("%d Connected Device",
"%d Connected Devices",
devices), devices);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_status_icon_set_title (applet->status_icon, title);
gtk_status_icon_set_from_icon_name (applet->status_icon, icon_name);
gtk_status_icon_set_tooltip_text (applet->status_icon, tooltip_text);
gtk_status_icon_set_visible (applet->status_icon, TRUE);
G_GNUC_END_IGNORE_DEPRECATIONS
g_free (tooltip_text);
}
static void
properties_changed_cb (GDBusProxy *proxy,
GVariant *changed_properties,
GStrv invalidated_properties,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
gf_bluetooth_applet_sync (applet);
}
static void
rfkill_proxy_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GfBluetoothApplet *applet;
GError *error;
applet = GF_BLUETOOTH_APPLET (user_data);
error = NULL;
applet->rfkill = gf_sd_rfkill_proxy_new_for_bus_finish (res, &error);
if (error != NULL)
{
g_warning ("Failed to get Rfkill proxy - %s", error->message);
g_error_free (error);
return;
}
g_signal_connect (applet->rfkill, "g-properties-changed",
G_CALLBACK (properties_changed_cb), applet);
gf_bluetooth_applet_sync (applet);
}
static void
row_changed_cb (GtkTreeModel *tree_model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
gf_bluetooth_applet_sync (applet);
}
static void
row_deleted_cb (GtkTreeModel *tree_model,
GtkTreePath *path,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
gf_bluetooth_applet_sync (applet);
}
static void
row_inserted_cb (GtkTreeModel *tree_model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer user_data)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (user_data);
gf_bluetooth_applet_sync (applet);
}
static void
gf_bluetooth_applet_dispose (GObject *object)
{
GfBluetoothApplet *applet;
applet = GF_BLUETOOTH_APPLET (object);
g_clear_object (&applet->status_icon);
g_clear_object (&applet->rfkill);
g_clear_object (&applet->client);
g_clear_object (&applet->model);
G_OBJECT_CLASS (gf_bluetooth_applet_parent_class)->dispose (object);
}
static void
gf_bluetooth_applet_class_init (GfBluetoothAppletClass *applet_class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (applet_class);
object_class->dispose = gf_bluetooth_applet_dispose;
}
static void
gf_bluetooth_applet_init (GfBluetoothApplet *applet)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
applet->status_icon = gtk_status_icon_new_from_icon_name ("bluetooth-active");
gtk_status_icon_set_visible (applet->status_icon, FALSE);
gtk_status_icon_set_title (applet->status_icon, _("Bluetooth"));
gtk_status_icon_set_tooltip_text (applet->status_icon, _("Bluetooth"));
G_GNUC_END_IGNORE_DEPRECATIONS
g_signal_connect (applet->status_icon, "popup-menu",
G_CALLBACK (popup_menu_cb), applet);
gf_sd_rfkill_proxy_new_for_bus (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
GSM_DBUS_NAME,
GSM_DBUS_PATH,
NULL,
rfkill_proxy_ready_cb,
applet);
applet->client = bluetooth_client_new ();
applet->model = bluetooth_client_get_model (applet->client);
g_signal_connect (applet->model, "row-changed",
G_CALLBACK (row_changed_cb), applet);
g_signal_connect (applet->model, "row-deleted",
G_CALLBACK (row_deleted_cb), applet);
g_signal_connect (applet->model, "row-inserted",
G_CALLBACK (row_inserted_cb), applet);
gf_bluetooth_applet_sync (applet);
}
GfBluetoothApplet *
......
......@@ -13,6 +13,7 @@ data/org.gnome.gnome-flashback.gschema.xml.in.in
gnome-flashback/gf-main.c
gnome-flashback/libautomount-manager/gsd-automount-manager.c
gnome-flashback/libautomount-manager/gsd-autorun.c
gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c
[type: gettext/glade]gnome-flashback/libdisplay-config/flashback-confirm-dialog.ui
gnome-flashback/libdisplay-config/flashback-display-config.c
gnome-flashback/libend-session-dialog/flashback-inhibit-dialog.c
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment