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.c221
1 files changed, 93 insertions, 128 deletions
diff --git a/mate-volume-control/gvc-stream-status-icon.c b/mate-volume-control/gvc-stream-status-icon.c
index 70501c9..d4c1509 100644
--- a/mate-volume-control/gvc-stream-status-icon.c
+++ b/mate-volume-control/gvc-stream-status-icon.c
@@ -2,6 +2,7 @@
*
* 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
@@ -25,6 +26,7 @@
#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>
@@ -36,12 +38,15 @@
struct _GvcStreamStatusIconPrivate
{
- gchar **icon_names;
- GtkWidget *dock;
- GtkWidget *bar;
- guint current_icon;
- gchar *display_name;
+ gchar **icon_names;
+ GtkImage *image;
+ GtkWidget *dock;
+ GtkWidget *bar;
+ guint current_icon;
+ gchar *display_name;
MateMixerStreamControl *control;
+ MatePanelAppletOrient orient;
+ guint size;
};
enum
@@ -59,61 +64,52 @@ 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_STATUS_ICON)
+G_DEFINE_TYPE (GvcStreamStatusIcon, gvc_stream_status_icon, GTK_TYPE_EVENT_BOX)
static gboolean
popup_dock (GvcStreamStatusIcon *icon, guint time)
{
- GdkRectangle area;
- GtkOrientation orientation;
+ GtkAllocation allocation;
GdkDisplay *display;
GdkScreen *screen;
- int x;
- int y;
+ int x, y;
GdkMonitor *monitor_num;
GdkRectangle monitor;
GtkRequisition dock_req;
- 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;
- }
+ 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);
/* position roughly */
gtk_window_set_screen (GTK_WINDOW (icon->priv->dock), screen);
- gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar),
- 1 - orientation);
+ gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar), icon->priv->orient);
- monitor_num = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), area.x, area.y);
+ monitor_num = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), allocation.x, allocation.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 (orientation == GTK_ORIENTATION_VERTICAL) {
- if (area.x + area.width + dock_req.width <= monitor.x + monitor.width)
- x = area.x + area.width;
+ 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;
else
- x = area.x - dock_req.width;
+ x = allocation.x - dock_req.width;
- if (area.y + dock_req.height <= monitor.y + monitor.height)
- y = area.y;
+ if (allocation.y + dock_req.height <= monitor.y + monitor.height)
+ y = allocation.y;
else
y = monitor.y + monitor.height - dock_req.height;
} else {
- if (area.y + area.height + dock_req.height <= monitor.y + monitor.height)
- y = area.y + area.height;
+ if (allocation.y + allocation.height + dock_req.height <= monitor.y + monitor.height)
+ y = allocation.y + allocation.height;
else
- y = area.y - dock_req.height;
+ y = allocation.y - dock_req.height;
- if (area.x + dock_req.width <= monitor.x + monitor.width)
- x = area.x;
+ if (allocation.x + dock_req.width <= monitor.x + monitor.width)
+ x = allocation.x;
else
x = monitor.x + monitor.width - dock_req.width;
}
@@ -154,17 +150,16 @@ 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 (GtkStatusIcon *status_icon,
+on_status_icon_button_press (GtkWidget *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);
@@ -175,19 +170,20 @@ on_status_icon_button_press (GtkStatusIcon *status_icon,
return FALSE;
}
-static void
-on_menu_mute_toggled (GtkMenuItem *item, GvcStreamStatusIcon *icon)
+void
+gvc_stream_status_icon_set_mute (GvcStreamStatusIcon *icon, gboolean mute)
{
- gboolean is_muted;
-
- is_muted = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item));
+ mate_mixer_stream_control_set_mute (icon->priv->control, mute);
+}
- mate_mixer_stream_control_set_mute (icon->priv->control, is_muted);
+gboolean
+gvc_stream_status_icon_get_mute (GvcStreamStatusIcon *icon)
+{
+ return mate_mixer_stream_control_get_mute (icon->priv->control);
}
-static void
-on_menu_activate_open_volume_control (GtkMenuItem *item,
- GvcStreamStatusIcon *icon)
+void
+gvc_stream_status_icon_volume_control (GvcStreamStatusIcon *icon)
{
GError *error = NULL;
@@ -213,64 +209,8 @@ on_menu_activate_open_volume_control (GtkMenuItem *item,
}
}
-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 (GtkStatusIcon *status_icon,
+on_status_icon_scroll_event (GtkWidget *event_box,
GdkEventScroll *event,
GvcStreamStatusIcon *icon)
{
@@ -372,6 +312,21 @@ 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, 0, 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;
@@ -386,10 +341,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_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), FALSE);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (icon), FALSE);
return;
} else
- gtk_status_icon_set_has_tooltip (GTK_STATUS_ICON (icon), TRUE);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (icon), TRUE);
flags = mate_mixer_stream_control_get_flags (icon->priv->control);
@@ -412,8 +367,7 @@ update_icon (GvcStreamStatusIcon *icon)
/* Apparently status icon will reset icon even if it doesn't change */
if (icon->priv->current_icon != n) {
- gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon),
- icon->priv->icon_names[n]);
+ gvc_stream_status_icon_set_icon_from_name (icon, icon->priv->icon_names[n]);
icon->priv->current_icon = n;
}
@@ -454,12 +408,28 @@ update_icon (GvcStreamStatusIcon *icon)
description);
}
- gtk_status_icon_set_tooltip_markup (GTK_STATUS_ICON (icon), markup);
+ gtk_widget_set_tooltip_markup (GTK_WIDGET (icon), markup);
g_free (markup);
}
void
+gvc_stream_status_icon_set_size (GvcStreamStatusIcon *icon,
+ guint size)
+{
+ 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)
+{
+ icon->priv->orient = orient;
+}
+
+void
gvc_stream_status_icon_set_icon_names (GvcStreamStatusIcon *icon,
const gchar **names)
{
@@ -477,7 +447,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 */
- gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon), names[0]);
+ gvc_stream_status_icon_set_icon_from_name (icon, names[0]);
update_icon (icon);
g_object_notify_by_pspec (G_OBJECT (icon), properties[PROP_ICON_NAMES]);
@@ -665,7 +635,7 @@ gvc_stream_status_icon_class_init (GvcStreamStatusIconClass *klass)
static void
on_status_icon_visible_notify (GvcStreamStatusIcon *icon)
{
- if (gtk_status_icon_get_visible (GTK_STATUS_ICON (icon)) == FALSE)
+ if (gtk_widget_get_visible (GTK_WIDGET (icon)) == FALSE)
gtk_widget_hide (icon->priv->dock);
}
@@ -674,8 +644,8 @@ on_icon_theme_change (GtkSettings *settings,
GParamSpec *pspec,
GvcStreamStatusIcon *icon)
{
- gtk_status_icon_set_from_icon_name (GTK_STATUS_ICON (icon),
- icon->priv->icon_names[icon->priv->current_icon]);
+ gvc_stream_status_icon_set_icon_from_name (icon,
+ icon->priv->icon_names[icon->priv->current_icon]);
}
static void
@@ -686,23 +656,18 @@ gvc_stream_status_icon_init (GvcStreamStatusIcon *icon)
icon->priv = GVC_STREAM_STATUS_ICON_GET_PRIVATE (icon);
- g_signal_connect (G_OBJECT (icon),
- "activate",
- G_CALLBACK (on_status_icon_activate),
- icon);
- g_signal_connect (G_OBJECT (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),
"button-press-event",
G_CALLBACK (on_status_icon_button_press),
icon);
- g_signal_connect (G_OBJECT (icon),
- "popup-menu",
- G_CALLBACK (on_status_icon_popup_menu),
- icon);
- g_signal_connect (G_OBJECT (icon),
+ g_signal_connect (GTK_WIDGET (icon),
"scroll-event",
G_CALLBACK (on_status_icon_scroll_event),
icon);
- g_signal_connect (G_OBJECT (icon),
+ g_signal_connect (GTK_WIDGET (icon),
"notify::visible",
G_CALLBACK (on_status_icon_visible_notify),
NULL);
@@ -741,8 +706,8 @@ gvc_stream_status_icon_init (GvcStreamStatusIcon *icon)
gvc_channel_bar_set_orientation (GVC_CHANNEL_BAR (icon->priv->bar),
GTK_ORIENTATION_VERTICAL);
-
- /* Set volume control frame, slider and toplevel window to follow panel theme */
+
+ /* Set volume control frame, slider and toplevel window to follow panel theme */
GtkWidget *toplevel = gtk_widget_get_toplevel (icon->priv->dock);
GtkStyleContext *context;
context = gtk_widget_get_style_context (GTK_WIDGET(toplevel));