summaryrefslogtreecommitdiff
path: root/mate-volume-control/gvc-stream-status-icon.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-volume-control/gvc-stream-status-icon.c')
-rw-r--r--mate-volume-control/gvc-stream-status-icon.c238
1 files changed, 126 insertions, 112 deletions
diff --git a/mate-volume-control/gvc-stream-status-icon.c b/mate-volume-control/gvc-stream-status-icon.c
index f48a370..558dd55 100644
--- a/mate-volume-control/gvc-stream-status-icon.c
+++ b/mate-volume-control/gvc-stream-status-icon.c
@@ -2,7 +2,6 @@
*
* Copyright (C) 2008 William Jon McCann
* Copyright (C) 2014 Michal Ratajsky <[email protected]>
- * Copyright (C) 2019 Victor Kareh <[email protected]>
*
* 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
@@ -26,7 +25,6 @@
#include <gdk/gdkkeysyms.h>
#include <libmatemixer/matemixer.h>
-#include <mate-panel-applet.h>
#define MATE_DESKTOP_USE_UNSTABLE_API
#include <libmate-desktop/mate-desktop-utils.h>
@@ -38,15 +36,12 @@
struct _GvcStreamStatusIconPrivate
{
- gchar **icon_names;
- GtkImage *image;
- GtkWidget *dock;
- GtkWidget *bar;
- guint current_icon;
- gchar *display_name;
+ gchar **icon_names;
+ GtkWidget *dock;
+ GtkWidget *bar;
+ guint current_icon;
+ gchar *display_name;
MateMixerStreamControl *control;
- MatePanelAppletOrient orient;
- guint size;
};
enum
@@ -64,52 +59,61 @@ static void gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass);
static void gvc_stream_status_icon_init (GvcStreamStatusIcon *stream_status_icon);
static void gvc_stream_status_icon_finalize (GObject *object);
-G_DEFINE_TYPE (GvcStreamStatusIcon, gvc_stream_status_icon, GTK_TYPE_EVENT_BOX)
+G_DEFINE_TYPE (GvcStreamStatusIcon, gvc_stream_status_icon, GTK_TYPE_STATUS_ICON)
static gboolean
popup_dock (GvcStreamStatusIcon *icon, guint time)
{
- GtkAllocation allocation;
+ GdkRectangle area;
+ GtkOrientation orientation;
GdkDisplay *display;
GdkScreen *screen;
- int x, y;
+ int x;
+ int y;
GdkMonitor *monitor_num;
GdkRectangle monitor;
GtkRequisition dock_req;
- screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- gtk_widget_get_allocation (GTK_WIDGET (icon), &allocation);
- gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (icon)), &allocation.x, &allocation.y);
+ screen = gtk_status_icon_get_screen (GTK_STATUS_ICON (icon));
+
+ if (gtk_status_icon_get_geometry (GTK_STATUS_ICON (icon),
+ &screen,
+ &area,
+ &orientation) == FALSE) {
+ g_warning ("Unable to determine geometry of status icon");
+ return FALSE;
+ }
/* position roughly */
gtk_window_set_screen (GTK_WINDOW (icon->priv->dock), screen);
- gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar), icon->priv->orient);
+ gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar),
+ 1 - orientation);
- monitor_num = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), allocation.x, allocation.y);
+ monitor_num = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), area.x, area.y);
gdk_monitor_get_geometry (monitor_num, &monitor);
gtk_container_foreach (GTK_CONTAINER (icon->priv->dock),
(GtkCallback) gtk_widget_show_all, NULL);
gtk_widget_get_preferred_size (icon->priv->dock, &dock_req, NULL);
- if (icon->priv->orient == MATE_PANEL_APPLET_ORIENT_LEFT || icon->priv->orient == MATE_PANEL_APPLET_ORIENT_RIGHT) {
- if (allocation.x + allocation.width + dock_req.width <= monitor.x + monitor.width)
- x = allocation.x + allocation.width;
+ if (orientation == GTK_ORIENTATION_VERTICAL) {
+ if (area.x + area.width + dock_req.width <= monitor.x + monitor.width)
+ x = area.x + area.width;
else
- x = allocation.x - dock_req.width;
+ x = area.x - dock_req.width;
- if (allocation.y + dock_req.height <= monitor.y + monitor.height)
- y = allocation.y;
+ if (area.y + dock_req.height <= monitor.y + monitor.height)
+ y = area.y;
else
y = monitor.y + monitor.height - dock_req.height;
} else {
- if (allocation.y + allocation.height + dock_req.height <= monitor.y + monitor.height)
- y = allocation.y + allocation.height;
+ if (area.y + area.height + dock_req.height <= monitor.y + monitor.height)
+ y = area.y + area.height;
else
- y = allocation.y - dock_req.height;
+ y = area.y - dock_req.height;
- if (allocation.x + dock_req.width <= monitor.x + monitor.width)
- x = allocation.x;
+ if (area.x + dock_req.width <= monitor.x + monitor.width)
+ x = area.x;
else
x = monitor.x + monitor.width - dock_req.width;
}
@@ -150,16 +154,17 @@ popup_dock (GvcStreamStatusIcon *icon, guint time)
return TRUE;
}
+static void
+on_status_icon_activate (GtkStatusIcon *status_icon, GvcStreamStatusIcon *icon)
+{
+ popup_dock (icon, GDK_CURRENT_TIME);
+}
+
static gboolean
-on_status_icon_button_press (GtkWidget *status_icon,
+on_status_icon_button_press (GtkStatusIcon *status_icon,
GdkEventButton *event,
GvcStreamStatusIcon *icon)
{
- if (event->button == 1) {
- popup_dock (icon, GDK_CURRENT_TIME);
- return TRUE;
- }
-
/* Middle click acts as mute/unmute */
if (event->button == 2) {
gboolean is_muted = mate_mixer_stream_control_get_mute (icon->priv->control);
@@ -170,20 +175,19 @@ on_status_icon_button_press (GtkWidget *status_icon,
return FALSE;
}
-void
-gvc_stream_status_icon_set_mute (GvcStreamStatusIcon *icon, gboolean mute)
+static void
+on_menu_mute_toggled (GtkMenuItem *item, GvcStreamStatusIcon *icon)
{
- mate_mixer_stream_control_set_mute (icon->priv->control, mute);
-}
+ gboolean is_muted;
-gboolean
-gvc_stream_status_icon_get_mute (GvcStreamStatusIcon *icon)
-{
- return mate_mixer_stream_control_get_mute (icon->priv->control);
+ is_muted = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item));
+
+ mate_mixer_stream_control_set_mute (icon->priv->control, is_muted);
}
-void
-gvc_stream_status_icon_volume_control (GvcStreamStatusIcon *icon)
+static void
+on_menu_activate_open_volume_control (GtkMenuItem *item,
+ GvcStreamStatusIcon *icon)
{
GError *error = NULL;
@@ -209,8 +213,64 @@ gvc_stream_status_icon_volume_control (GvcStreamStatusIcon *icon)
}
}
+static void
+on_status_icon_popup_menu (GtkStatusIcon *status_icon,
+ guint button,
+ guint activate_time,
+ GvcStreamStatusIcon *icon)
+{
+ GtkWidget *menu;
+ GtkWidget *item;
+ GtkWidget *image;
+
+ menu = gtk_menu_new ();
+
+ /*Set up theme and transparency support*/
+ GtkWidget *toplevel = gtk_widget_get_toplevel (menu);
+ /* Fix any failures of compiz/other wm's to communicate with gtk for transparency */
+ GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(toplevel));
+ GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
+ gtk_widget_set_visual(GTK_WIDGET(toplevel), visual);
+ /* Set menu and it's toplevel window to follow panel theme */
+ GtkStyleContext *context;
+ context = gtk_widget_get_style_context (GTK_WIDGET(toplevel));
+ gtk_style_context_add_class(context,"gnome-panel-menu-bar");
+ gtk_style_context_add_class(context,"mate-panel-menu-bar");
+
+ item = gtk_check_menu_item_new_with_mnemonic (_("_Mute"));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+ mate_mixer_stream_control_get_mute (icon->priv->control));
+ g_signal_connect (G_OBJECT (item),
+ "toggled",
+ G_CALLBACK (on_menu_mute_toggled),
+ icon);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Sound Preferences"));
+ image = gtk_image_new_from_icon_name ("multimedia-volume-control",
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+
+ g_signal_connect (G_OBJECT (item),
+ "activate",
+ G_CALLBACK (on_menu_activate_open_volume_control),
+ icon);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ gtk_widget_show_all (menu);
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL,
+ NULL,
+ gtk_status_icon_position_menu,
+ status_icon,
+ button,
+ activate_time);
+}
+
static gboolean
-on_status_icon_scroll_event (GtkWidget *event_box,
+on_status_icon_scroll_event (GtkStatusIcon *status_icon,
GdkEventScroll *event,
GvcStreamStatusIcon *icon)
{
@@ -312,23 +372,6 @@ on_dock_scroll_event (GtkWidget *widget,
}
static void
-gvc_stream_status_icon_set_icon_from_name (GvcStreamStatusIcon *icon,
- const gchar *icon_name)
-{
- GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
- gint icon_scale = gtk_widget_get_scale_factor (GTK_WIDGET (icon));
-
- cairo_surface_t* surface = gtk_icon_theme_load_surface (icon_theme, icon_name,
- icon->priv->size,
- icon_scale, NULL,
- GTK_ICON_LOOKUP_FORCE_SIZE,
- NULL);
-
- gtk_image_set_from_surface (GTK_IMAGE (icon->priv->image), surface);
- cairo_surface_destroy (surface);
-}
-
-static void
update_icon (GvcStreamStatusIcon *icon)
{
guint volume = 0;
@@ -343,10 +386,10 @@ update_icon (GvcStreamStatusIcon *icon)
if (icon->priv->control == NULL) {
/* Do not bother creating a tooltip for an unusable icon as it
* has no practical use */
- gtk_widget_set_has_tooltip (GTK_WIDGET (icon), FALSE);
+ gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), FALSE);
return;
} else
- gtk_widget_set_has_tooltip (GTK_WIDGET (icon), TRUE);
+ gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), TRUE);
flags = mate_mixer_stream_control_get_flags (icon->priv->control);
@@ -369,7 +412,8 @@ update_icon (GvcStreamStatusIcon *icon)
/* Apparently status icon will reset icon even if it doesn't change */
if (icon->priv->current_icon != n) {
- gvc_stream_status_icon_set_icon_from_name (icon, icon->priv->icon_names[n]);
+ gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon),
+ icon->priv->icon_names[n]);
icon->priv->current_icon = n;
}
@@ -410,47 +454,12 @@ update_icon (GvcStreamStatusIcon *icon)
description);
}
- gtk_widget_set_tooltip_markup (GTK_WIDGET (icon), markup);
+ gtk_status_icon_set_tooltip_markup (GTK_STATUS_ICON (icon), markup);
g_free (markup);
}
void
-gvc_stream_status_icon_set_size (GvcStreamStatusIcon *icon,
- guint size)
-{
-
- /*Iterate through the icon sizes so they can be kept sharp*/
- if (size < 22)
- size = 16;
- else if (size < 24)
- size = 22;
- else if (size < 32)
- size = 24;
- else if (size < 48)
- size = 32;
- else
- size = 48;
- icon->priv->size = size;
- gvc_stream_status_icon_set_icon_from_name (icon,
- icon->priv->icon_names[icon->priv->current_icon]);
-}
-
-void
-gvc_stream_status_icon_set_orient (GvcStreamStatusIcon *icon,
- MatePanelAppletOrient orient)
-{
- /*Sometimes orient does not get properly defined especially on a bottom panel
- *Use the applet orientation if it is valid, otherwise set a vertical slider
- *Otherwise bottom panels get a horizontal slider
- */
- if (orient)
- icon->priv->orient = orient;
- else
- icon->priv->orient = MATE_PANEL_APPLET_ORIENT_DOWN;
-}
-
-void
gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon,
const gchar **names)
{
@@ -468,7 +477,7 @@ gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon,
/* Set the first icon as the initial one, the icon may be immediately
* updated or not depending on whether a stream is available */
- gvc_stream_status_icon_set_icon_from_name (icon, names[0]);
+ gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon), names[0]);
update_icon (icon);
g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_ICON_NAMES]);
@@ -656,7 +665,7 @@ gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass)
static void
on_status_icon_visible_notify (GvcStreamStatusIcon *icon)
{
- if (gtk_widget_get_visible (GTK_WIDGET (icon)) == FALSE)
+ if (gtk_status_icon_get_visible (GTK_STATUS_ICON (icon)) == FALSE)
gtk_widget_hide (icon->priv->dock);
}
@@ -665,8 +674,8 @@ on_icon_theme_change (GtkSettings *settings,
GParamSpec *pspec,
GvcStreamStatusIcon *icon)
{
- gvc_stream_status_icon_set_icon_from_name (icon,
- icon->priv->icon_names[icon->priv->current_icon]);
+ gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon),
+ icon->priv->icon_names[icon->priv->current_icon]);
}
static void
@@ -677,18 +686,23 @@ gvc_stream_status_icon_init (GvcStreamStatusIcon *icon)
icon->priv = GVC_STREAM_STATUS_ICON_GET_PRIVATE (icon);
- icon->priv->image = GTK_IMAGE (gtk_image_new ());
- gtk_container_add (GTK_CONTAINER (icon), GTK_WIDGET (icon->priv->image));
-
- g_signal_connect (GTK_WIDGET (icon),
+ g_signal_connect (G_OBJECT (icon),
+ "activate",
+ G_CALLBACK (on_status_icon_activate),
+ icon);
+ g_signal_connect (G_OBJECT (icon),
"button-press-event",
G_CALLBACK (on_status_icon_button_press),
icon);
- g_signal_connect (GTK_WIDGET (icon),
+ g_signal_connect (G_OBJECT (icon),
+ "popup-menu",
+ G_CALLBACK (on_status_icon_popup_menu),
+ icon);
+ g_signal_connect (G_OBJECT (icon),
"scroll-event",
G_CALLBACK (on_status_icon_scroll_event),
icon);
- g_signal_connect (GTK_WIDGET (icon),
+ g_signal_connect (G_OBJECT (icon),
"notify::visible",
G_CALLBACK (on_status_icon_visible_notify),
NULL);