mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-05-01 11:41:30 +00:00
Enhancement: Fixes #76, Implement sound volume indicator / levels in notification area
This commit is contained in:
@@ -30,6 +30,7 @@ wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||
wintc_resolve_library(wintc-exec WINTC_EXEC)
|
||||
wintc_resolve_library(wintc-shelldpa WINTC_SHELLDPA)
|
||||
wintc_resolve_library(wintc-shllang WINTC_SHLLANG)
|
||||
wintc_resolve_library(wintc-sndapi WINTC_SNDAPI)
|
||||
|
||||
wintc_compile_resources()
|
||||
wintc_create_meta_h()
|
||||
@@ -57,10 +58,14 @@ add_executable(
|
||||
src/start/startmenuitem.h
|
||||
src/start/util.c
|
||||
src/start/util.h
|
||||
src/systray/behaviour.c
|
||||
src/systray/behaviour.h
|
||||
src/systray/clock.c
|
||||
src/systray/clock.h
|
||||
src/systray/notifarea.c
|
||||
src/systray/notifarea.h
|
||||
src/systray/volume.c
|
||||
src/systray/volume.h
|
||||
src/taskbuttons/taskbuttonbar.c
|
||||
src/taskbuttons/taskbuttonbar.h
|
||||
src/taskbuttons/windowmonitor.c
|
||||
@@ -84,6 +89,7 @@ target_include_directories(
|
||||
PRIVATE ${WINTC_EXEC_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHELLDPA_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHLLANG_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SNDAPI_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_directories(
|
||||
@@ -97,6 +103,7 @@ target_link_directories(
|
||||
PRIVATE ${WINTC_EXEC_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHELLDPA_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHLLANG_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SNDAPI_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@@ -110,6 +117,7 @@ target_link_libraries(
|
||||
PRIVATE ${WINTC_EXEC_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHELLDPA_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHLLANG_LIBRARIES}
|
||||
PRIVATE ${WINTC_SNDAPI_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
|
||||
@@ -7,3 +7,4 @@ bt,rt:wintc-comgtk
|
||||
bt,rt:wintc-exec
|
||||
bt,rt:wintc-shelldpa
|
||||
bt,rt:wintc-shllang
|
||||
bt,rt:wintc-sndapi
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
<gresources>
|
||||
<gresource prefix="/uk/oddmatics/wintc/taskband">
|
||||
<file>start-menu.css</file>
|
||||
<file>volume-popup.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
15
shell/taskband/src/res/volume-popup.css
Normal file
15
shell/taskband/src/res/volume-popup.css
Normal file
@@ -0,0 +1,15 @@
|
||||
.wintc-volmgmt > box > label
|
||||
{
|
||||
margin: 10px 20px;
|
||||
}
|
||||
|
||||
.wintc-volmgmt > box > scale
|
||||
{
|
||||
margin: 4px 0px;
|
||||
min-height: 65px;
|
||||
}
|
||||
|
||||
.wintc-volmgmt > box > checkbutton
|
||||
{
|
||||
margin: 12px 6px 4px;
|
||||
}
|
||||
173
shell/taskband/src/systray/behaviour.c
Normal file
173
shell/taskband/src/systray/behaviour.c
Normal file
@@ -0,0 +1,173 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "behaviour.h"
|
||||
|
||||
//
|
||||
// PRIVATE ENUMS
|
||||
//
|
||||
enum
|
||||
{
|
||||
PROP_WIDGET_NOTIF = 1,
|
||||
PROP_ICON_NAME
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SIGNAL_ICON_CHANGED = 0,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
//
|
||||
// STATIC DATA
|
||||
//
|
||||
static gint wintc_notification_behaviour_signals[N_SIGNALS] = { 0 };
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_notification_behaviour_get_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec
|
||||
);
|
||||
static void wintc_notification_behaviour_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
);
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCNotificationBehaviour,
|
||||
wintc_notification_behaviour,
|
||||
G_TYPE_OBJECT
|
||||
)
|
||||
|
||||
static void wintc_notification_behaviour_class_init(
|
||||
WinTCNotificationBehaviourClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->get_property = wintc_notification_behaviour_get_property;
|
||||
object_class->set_property = wintc_notification_behaviour_set_property;
|
||||
|
||||
wintc_notification_behaviour_signals[SIGNAL_ICON_CHANGED] =
|
||||
g_signal_new(
|
||||
"icon-changed",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0
|
||||
);
|
||||
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_WIDGET_NOTIF,
|
||||
g_param_spec_object(
|
||||
"widget-notif",
|
||||
"WidgetNotif",
|
||||
"The GTK widget that hosts the notification icon.",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
|
||||
)
|
||||
);
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_ICON_NAME,
|
||||
g_param_spec_string(
|
||||
"icon-name",
|
||||
"IconName",
|
||||
"The icon name to display in the notification area.",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_notification_behaviour_init(
|
||||
WinTCNotificationBehaviour* self
|
||||
)
|
||||
{
|
||||
self->icon_name = NULL;
|
||||
self->widget_notif = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_notification_behaviour_get_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec
|
||||
)
|
||||
{
|
||||
WinTCNotificationBehaviour* behaviour =
|
||||
WINTC_NOTIFICATION_BEHAVIOUR(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
g_value_set_string(value, behaviour->icon_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void wintc_notification_behaviour_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
)
|
||||
{
|
||||
WinTCNotificationBehaviour* behaviour =
|
||||
WINTC_NOTIFICATION_BEHAVIOUR(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
g_free(behaviour->icon_name);
|
||||
behaviour->icon_name = g_strdup(g_value_get_string(value));
|
||||
|
||||
g_signal_emit(
|
||||
behaviour,
|
||||
wintc_notification_behaviour_signals[SIGNAL_ICON_CHANGED],
|
||||
0
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_WIDGET_NOTIF:
|
||||
behaviour->widget_notif = GTK_WIDGET(g_value_get_object(value));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
const gchar* wintc_notification_behaviour_get_icon_name(
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
)
|
||||
{
|
||||
return behaviour->icon_name;
|
||||
}
|
||||
39
shell/taskband/src/systray/behaviour.h
Normal file
39
shell/taskband/src/systray/behaviour.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef __BEHAVIOUR_H__
|
||||
#define __BEHAVIOUR_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
typedef struct _WinTCNotificationBehaviourClass
|
||||
{
|
||||
GObjectClass __parent__;
|
||||
} WinTCNotificationBehaviourClass;
|
||||
|
||||
typedef struct _WinTCNotificationBehaviour
|
||||
{
|
||||
GObject __parent__;
|
||||
|
||||
gchar* icon_name;
|
||||
GtkWidget* widget_notif;
|
||||
} WinTCNotificationBehaviour;
|
||||
|
||||
#define TYPE_WINTC_NOTIFICATION_BEHAVIOUR (wintc_notification_behaviour_get_type())
|
||||
#define WINTC_NOTIFICATION_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_NOTIFICATION_BEHAVIOUR, WinTCNotificationBehaviour))
|
||||
#define WINTC_NOTIFICATION_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_NOTIFICATION_BEHAVIOUR, WinTCNotificationBehaviourClass))
|
||||
#define IS_WINTC_NOTIFICATION_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_NOTIFICATION_BEHAVIOUR))
|
||||
#define IS_WINTC_NOTIFICATION_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_NOTIFICATION_BEHAVIOUR))
|
||||
#define WINTC_NOTIFICATION_BEHAVIOUR_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_NOTIFICATION_BEHAVIOUR, WinTCNotificationBehaviour))
|
||||
|
||||
GType wintc_notification_behaviour_get_type(void) G_GNUC_CONST;
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
const gchar* wintc_notification_behaviour_get_icon_name(
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -3,40 +3,48 @@
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
//
|
||||
// PRIVATE ENUMS
|
||||
//
|
||||
enum
|
||||
{
|
||||
PROP_LABEL_TARGET = 1,
|
||||
};
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _TrayClockPrivate
|
||||
struct _WinTCClockRunnerClass
|
||||
{
|
||||
TrayClock* tray_clock;
|
||||
|
||||
guint clock_source_id;
|
||||
GObjectClass __parent__;
|
||||
};
|
||||
|
||||
struct _TrayClockClass
|
||||
struct _WinTCClockRunner
|
||||
{
|
||||
GtkLabelClass __parent__;
|
||||
};
|
||||
GObject __parent__;
|
||||
|
||||
struct _TrayClock
|
||||
{
|
||||
GtkLabel __parent__;
|
||||
|
||||
TrayClockPrivate* priv;
|
||||
guint clock_source_id;
|
||||
GtkLabel* label_target;
|
||||
};
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void tray_clock_finalize(
|
||||
static void wintc_clock_runner_finalize(
|
||||
GObject* object
|
||||
);
|
||||
|
||||
static void tray_clock_launch_time(
|
||||
TrayClock* tray_clock
|
||||
static void wintc_clock_runner_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
);
|
||||
static void tray_clock_update_time(
|
||||
TrayClock* tray_clock
|
||||
|
||||
static void wintc_clock_runner_launch_time(
|
||||
WinTCClockRunner* tray_clock
|
||||
);
|
||||
static void wintc_clock_runner_update_time(
|
||||
WinTCClockRunner* tray_clock
|
||||
);
|
||||
|
||||
static gboolean on_clock_timeout_elapsed(
|
||||
@@ -49,34 +57,38 @@ static gboolean on_sync_timeout_elapsed(
|
||||
//
|
||||
// GTK TYPE DEFINITION & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE_WITH_CODE(
|
||||
TrayClock,
|
||||
tray_clock,
|
||||
GTK_TYPE_LABEL,
|
||||
G_ADD_PRIVATE(TrayClock)
|
||||
G_DEFINE_TYPE(
|
||||
WinTCClockRunner,
|
||||
wintc_clock_runner,
|
||||
G_TYPE_OBJECT
|
||||
)
|
||||
|
||||
static void tray_clock_class_init(
|
||||
TrayClockClass* klass
|
||||
static void wintc_clock_runner_class_init(
|
||||
WinTCClockRunnerClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* gclass = G_OBJECT_CLASS(klass);
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
gclass->finalize = tray_clock_finalize;
|
||||
object_class->finalize = wintc_clock_runner_finalize;
|
||||
object_class->set_property = wintc_clock_runner_set_property;
|
||||
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_LABEL_TARGET,
|
||||
g_param_spec_object(
|
||||
"label-target",
|
||||
"LabelTarget",
|
||||
"The target label to manage.",
|
||||
GTK_TYPE_LABEL,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static void tray_clock_init(
|
||||
TrayClock* self
|
||||
static void wintc_clock_runner_init(
|
||||
WinTCClockRunner* self
|
||||
)
|
||||
{
|
||||
self->priv = tray_clock_get_instance_private(self);
|
||||
|
||||
// Add style class
|
||||
//
|
||||
GtkStyleContext* style = gtk_widget_get_style_context(GTK_WIDGET(self));
|
||||
|
||||
gtk_style_context_add_class(style, "clock");
|
||||
|
||||
// Establish clock - if we're not dead on the minute then delay launch to sync
|
||||
// up
|
||||
//
|
||||
@@ -85,7 +97,7 @@ static void tray_clock_init(
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
tray_clock_update_time(self);
|
||||
wintc_clock_runner_update_time(self);
|
||||
|
||||
g_timeout_add_seconds_full(
|
||||
G_PRIORITY_DEFAULT,
|
||||
@@ -97,66 +109,107 @@ static void tray_clock_init(
|
||||
}
|
||||
else
|
||||
{
|
||||
tray_clock_launch_time(self);
|
||||
wintc_clock_runner_launch_time(self);
|
||||
}
|
||||
|
||||
g_date_time_unref(time);
|
||||
}
|
||||
|
||||
//
|
||||
// FINALIZE
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void tray_clock_finalize(
|
||||
static void wintc_clock_runner_finalize(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
TrayClock* tray_clock = TRAY_CLOCK(object);
|
||||
WinTCClockRunner* clock_runner = WINTC_CLOCK_RUNNER(object);
|
||||
|
||||
if (tray_clock->priv->clock_source_id > 0)
|
||||
if (clock_runner->clock_source_id > 0)
|
||||
{
|
||||
g_source_remove(tray_clock->priv->clock_source_id);
|
||||
g_source_remove(clock_runner->clock_source_id);
|
||||
}
|
||||
|
||||
(*G_OBJECT_CLASS(tray_clock_parent_class)->finalize) (object);
|
||||
(*G_OBJECT_CLASS(wintc_clock_runner_parent_class)->finalize) (object);
|
||||
}
|
||||
|
||||
static void wintc_clock_runner_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
)
|
||||
{
|
||||
WinTCClockRunner* clock_runner = WINTC_CLOCK_RUNNER(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LABEL_TARGET:
|
||||
clock_runner->label_target =
|
||||
GTK_LABEL(g_value_get_object(value));
|
||||
|
||||
wintc_clock_runner_update_time(clock_runner);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* tray_clock_new(void)
|
||||
WinTCClockRunner* wintc_clock_runner_new(
|
||||
GtkLabel* label_target
|
||||
)
|
||||
{
|
||||
return GTK_WIDGET(
|
||||
g_object_new(TYPE_TRAY_CLOCK, NULL)
|
||||
return WINTC_CLOCK_RUNNER(
|
||||
g_object_new(
|
||||
TYPE_WINTC_CLOCK_RUNNER,
|
||||
"label-target", label_target,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static void tray_clock_launch_time(
|
||||
TrayClock* tray_clock
|
||||
static void wintc_clock_runner_launch_time(
|
||||
WinTCClockRunner* clock_runner
|
||||
)
|
||||
{
|
||||
tray_clock_update_time(tray_clock);
|
||||
wintc_clock_runner_update_time(clock_runner);
|
||||
|
||||
tray_clock->priv->clock_source_id =
|
||||
clock_runner->clock_source_id =
|
||||
g_timeout_add_seconds_full(
|
||||
G_PRIORITY_DEFAULT,
|
||||
60,
|
||||
on_clock_timeout_elapsed,
|
||||
tray_clock,
|
||||
clock_runner,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
static void tray_clock_update_time(
|
||||
TrayClock* tray_clock
|
||||
static void wintc_clock_runner_update_time(
|
||||
WinTCClockRunner* clock_runner
|
||||
)
|
||||
{
|
||||
if (clock_runner->label_target == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update target label with time
|
||||
//
|
||||
GDateTime* time = g_date_time_new_now_local();
|
||||
gchar* timestr = g_date_time_format(time, "%H:%M");
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(tray_clock), timestr);
|
||||
gtk_label_set_text(
|
||||
GTK_LABEL(clock_runner->label_target),
|
||||
timestr
|
||||
);
|
||||
|
||||
g_date_time_unref(time);
|
||||
g_free(timestr);
|
||||
@@ -169,7 +222,7 @@ static gboolean on_clock_timeout_elapsed(
|
||||
gpointer data
|
||||
)
|
||||
{
|
||||
tray_clock_update_time(TRAY_CLOCK(data));
|
||||
wintc_clock_runner_update_time(WINTC_CLOCK_RUNNER(data));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -178,7 +231,7 @@ static gboolean on_sync_timeout_elapsed(
|
||||
gpointer data
|
||||
)
|
||||
{
|
||||
tray_clock_launch_time(TRAY_CLOCK(data));
|
||||
wintc_clock_runner_launch_time(WINTC_CLOCK_RUNNER(data));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -9,24 +9,25 @@ G_BEGIN_DECLS
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
typedef struct _TrayClockPrivate TrayClockPrivate;
|
||||
typedef struct _TrayClockClass TrayClockClass;
|
||||
typedef struct _TrayClock TrayClock;
|
||||
typedef struct _WinTCClockRunnerClass WinTCClockRunnerClass;
|
||||
typedef struct _WinTCClockRunner WinTCClockRunner;
|
||||
|
||||
#define TYPE_TRAY_CLOCK (tray_clock_get_type())
|
||||
#define TRAY_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_TRAY_CLOCK, TrayClock))
|
||||
#define TRAY_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_TRAY_CLOCK, TrayClockClass))
|
||||
#define IS_TRAY_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_TRAY_CLOCK))
|
||||
#define IS_TRAY_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_TRAY_CLOCK))
|
||||
#define TRAY_CLOCK_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_TRAY_CLOCK, TrayClock))
|
||||
#define TYPE_WINTC_CLOCK_RUNNER (wintc_clock_runner_get_type())
|
||||
#define WINTC_CLOCK_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_CLOCK_RUNNER, WinTCClockRunner))
|
||||
#define WINTC_CLOCK_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_CLOCK_RUNNER, WinTCClockRunnerClass))
|
||||
#define IS_WINTC_CLOCK_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_CLOCK_RUNNER))
|
||||
#define IS_WINTC_CLOCK_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_CLOCK_RUNNER))
|
||||
#define WINTC_CLOCK_RUNNER_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_CLOCK_RUNNER, WinTCClockRunner))
|
||||
|
||||
GType tray_clock_get_type(void) G_GNUC_CONST;
|
||||
GType wintc_clock_runner_get_type(void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* tray_clock_new(void);
|
||||
WinTCClockRunner* wintc_clock_runner_new(
|
||||
GtkLabel* label_target
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +1,208 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc-comgtk.h>
|
||||
|
||||
#include "behaviour.h"
|
||||
#include "clock.h"
|
||||
#include "notifarea.h"
|
||||
#include "volume.h"
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _WinTCNotificationAreaClass
|
||||
{
|
||||
GtkBinClass __parent__;
|
||||
};
|
||||
|
||||
struct _WinTCNotificationArea
|
||||
{
|
||||
GtkBin __parent__;
|
||||
|
||||
GtkWidget* box_container;
|
||||
GtkWidget* label_clock;
|
||||
|
||||
WinTCClockRunner* clock_runner;
|
||||
|
||||
GHashTable* map_widget_to_behaviour;
|
||||
};
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static GtkWidget* wintc_notification_area_append_icon(
|
||||
WinTCNotificationArea* notif_area
|
||||
);
|
||||
static void wintc_notification_area_map_widget(
|
||||
WinTCNotificationArea* notif_area,
|
||||
GtkWidget* widget_notif,
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
);
|
||||
|
||||
static void update_notification_icon(
|
||||
GtkWidget* widget_notif,
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
);
|
||||
|
||||
static void on_behaviour_icon_changed(
|
||||
WinTCNotificationBehaviour* behaviour,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITION & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCNotificationArea,
|
||||
wintc_notification_area,
|
||||
GTK_TYPE_BIN
|
||||
)
|
||||
|
||||
static void wintc_notification_area_class_init(
|
||||
WINTC_UNUSED(WinTCNotificationAreaClass* klass)
|
||||
) {}
|
||||
|
||||
static void wintc_notification_area_init(
|
||||
WinTCNotificationArea* self
|
||||
)
|
||||
{
|
||||
// Create map for notification widgets --> behaviours
|
||||
//
|
||||
self->map_widget_to_behaviour =
|
||||
g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
|
||||
// Set up UI
|
||||
//
|
||||
self->box_container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
self->label_clock = gtk_label_new(NULL);
|
||||
|
||||
wintc_widget_add_style_class(self->box_container, "wintc-systray");
|
||||
wintc_widget_add_style_class(self->label_clock, "clock");
|
||||
|
||||
gtk_box_pack_end(
|
||||
GTK_BOX(self->box_container),
|
||||
self->label_clock,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0
|
||||
);
|
||||
|
||||
gtk_container_add(
|
||||
GTK_CONTAINER(self),
|
||||
self->box_container
|
||||
);
|
||||
|
||||
// Hook up clock runner
|
||||
//
|
||||
self->clock_runner =
|
||||
wintc_clock_runner_new(GTK_LABEL(self->label_clock));
|
||||
|
||||
// Create volume icon and behaviour for system tray
|
||||
//
|
||||
WinTCNotificationVolume* notif_volume;
|
||||
GtkWidget* widget_volume;
|
||||
|
||||
widget_volume = wintc_notification_area_append_icon(self);
|
||||
notif_volume = wintc_notification_volume_new(widget_volume);
|
||||
|
||||
wintc_notification_area_map_widget(
|
||||
self,
|
||||
widget_volume,
|
||||
WINTC_NOTIFICATION_BEHAVIOUR(notif_volume)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* notification_area_new(void)
|
||||
{
|
||||
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
GtkWidget* clock = tray_clock_new();
|
||||
return GTK_WIDGET(
|
||||
g_object_new(
|
||||
TYPE_WINTC_NOTIFICATION_AREA,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
wintc_widget_add_style_class(box, "wintc-systray");
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static GtkWidget* wintc_notification_area_append_icon(
|
||||
WinTCNotificationArea* notif_area
|
||||
)
|
||||
{
|
||||
GtkWidget* event_box = gtk_event_box_new();
|
||||
GtkWidget* image_icon = gtk_image_new();
|
||||
|
||||
gtk_widget_set_events(event_box, GDK_BUTTON_PRESS_MASK);
|
||||
|
||||
gtk_container_add(
|
||||
GTK_CONTAINER(event_box),
|
||||
image_icon
|
||||
);
|
||||
gtk_box_pack_start(
|
||||
GTK_BOX(box),
|
||||
clock,
|
||||
GTK_BOX(notif_area->box_container),
|
||||
event_box,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0
|
||||
);
|
||||
|
||||
return box;
|
||||
return event_box;
|
||||
}
|
||||
|
||||
static void wintc_notification_area_map_widget(
|
||||
WinTCNotificationArea* notif_area,
|
||||
GtkWidget* widget_notif,
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
)
|
||||
{
|
||||
g_hash_table_insert(
|
||||
notif_area->map_widget_to_behaviour,
|
||||
widget_notif,
|
||||
behaviour
|
||||
);
|
||||
|
||||
// Connect up widget to behaviour
|
||||
//
|
||||
update_notification_icon(
|
||||
widget_notif,
|
||||
behaviour
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
behaviour,
|
||||
"icon-changed",
|
||||
G_CALLBACK(on_behaviour_icon_changed),
|
||||
widget_notif
|
||||
);
|
||||
}
|
||||
|
||||
static void update_notification_icon(
|
||||
GtkWidget* widget_notif,
|
||||
WinTCNotificationBehaviour* behaviour
|
||||
)
|
||||
{
|
||||
gtk_image_set_from_icon_name(
|
||||
GTK_IMAGE(gtk_bin_get_child(GTK_BIN(widget_notif))),
|
||||
wintc_notification_behaviour_get_icon_name(behaviour),
|
||||
GTK_ICON_SIZE_SMALL_TOOLBAR
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void on_behaviour_icon_changed(
|
||||
WinTCNotificationBehaviour* behaviour,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
GtkWidget* widget_notif = GTK_WIDGET(user_data);
|
||||
|
||||
update_notification_icon(
|
||||
widget_notif,
|
||||
behaviour
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
#ifndef __NOTIFAREA_H__
|
||||
#define __NOTIFAREA_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
typedef struct _WinTCNotificationAreaClass WinTCNotificationAreaClass;
|
||||
typedef struct _WinTCNotificationArea WinTCNotificationArea;
|
||||
|
||||
#define TYPE_WINTC_NOTIFICATION_AREA (wintc_notification_area_get_type())
|
||||
#define WINTC_NOTIFICATION_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_NOTIFICATION_AREA, WinTCNotificationArea))
|
||||
#define WINTC_NOTIFICATION_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_NOTIFICATION_AREA, WinTCNotificationArea))
|
||||
#define IS_WINTC_NOTIFICATION_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_NOTIFICATION_AREA))
|
||||
#define IS_WINTC_NOTIFICATION_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_NOTIFICATION_AREA))
|
||||
#define WINTC_NOTIFICATION_AREA_GET_CLASS(obj) (G_TYPE_CHECK_INSTANCE_GET_CLASS((obj), TYPE_WINTC_NOTIFICATION_AREA))
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GtkWidget* notification_area_new(void);
|
||||
|
||||
#endif
|
||||
|
||||
430
shell/taskband/src/systray/volume.c
Normal file
430
shell/taskband/src/systray/volume.c
Normal file
@@ -0,0 +1,430 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc-comgtk.h>
|
||||
#include <wintc-shelldpa.h>
|
||||
#include <wintc-sndapi.h>
|
||||
|
||||
#include "behaviour.h"
|
||||
#include "volume.h"
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _WinTCNotificationVolumeClass
|
||||
{
|
||||
WinTCNotificationBehaviourClass __parent__;
|
||||
};
|
||||
|
||||
struct _WinTCNotificationVolume
|
||||
{
|
||||
WinTCNotificationBehaviour __parent__;
|
||||
|
||||
GtkWidget* popup_volmgmt;
|
||||
|
||||
GtkWidget* box_container;
|
||||
GtkWidget* check_mute;
|
||||
GtkWidget* scale_volume;
|
||||
|
||||
gboolean syncing_state;
|
||||
|
||||
// Sound API stuff
|
||||
//
|
||||
WinTCSndApiContext* snd_ctx;
|
||||
WinTCSndApiOutput* snd_output;
|
||||
};
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_notification_volume_constructed(
|
||||
GObject* object
|
||||
);
|
||||
|
||||
static void wintc_notification_volume_set_have_device(
|
||||
WinTCNotificationVolume* volume,
|
||||
gboolean have_device
|
||||
);
|
||||
|
||||
static void on_snd_ctx_connected_changed(
|
||||
WinTCSndApiContext* ctx,
|
||||
gboolean connected,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_snd_ctx_default_output_changed(
|
||||
WinTCSndApiContext* ctx,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static void on_snd_output_muted_changed(
|
||||
WinTCSndApiOutput* output,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_snd_output_volume_changed(
|
||||
WinTCSndApiOutput* output,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static gboolean on_widget_notif_button_press_event(
|
||||
GtkWidget* self,
|
||||
GdkEventButton* event,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static void on_check_mute_toggled(
|
||||
GtkToggleButton* self,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_scale_volume_value_changed(
|
||||
GtkRange* self,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCNotificationVolume,
|
||||
wintc_notification_volume,
|
||||
TYPE_WINTC_NOTIFICATION_BEHAVIOUR
|
||||
)
|
||||
|
||||
static void wintc_notification_volume_class_init(
|
||||
WinTCNotificationVolumeClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->constructed = wintc_notification_volume_constructed;
|
||||
}
|
||||
|
||||
static void wintc_notification_volume_init(
|
||||
WINTC_UNUSED(WinTCNotificationVolume* self)
|
||||
)
|
||||
{
|
||||
static gboolean css_added = FALSE;
|
||||
|
||||
// Add CSS once to screen - can't do this in class because GTK may not
|
||||
// have initialized first
|
||||
//
|
||||
if (!css_added)
|
||||
{
|
||||
GtkCssProvider* css_volume_popup = gtk_css_provider_new();
|
||||
|
||||
gtk_css_provider_load_from_resource(
|
||||
css_volume_popup,
|
||||
"/uk/oddmatics/wintc/taskband/volume-popup.css"
|
||||
);
|
||||
|
||||
gtk_style_context_add_provider_for_screen(
|
||||
gdk_screen_get_default(),
|
||||
GTK_STYLE_PROVIDER(css_volume_popup),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_FALLBACK
|
||||
);
|
||||
|
||||
css_added = TRUE;
|
||||
}
|
||||
|
||||
// Other init
|
||||
//
|
||||
self->syncing_state = FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_notification_volume_constructed(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(object);
|
||||
WinTCNotificationBehaviour* behaviour =
|
||||
WINTC_NOTIFICATION_BEHAVIOUR(volume);
|
||||
|
||||
// Connect up to the notification icon widget
|
||||
//
|
||||
volume->popup_volmgmt =
|
||||
wintc_dpa_create_popup(behaviour->widget_notif);
|
||||
|
||||
volume->box_container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
volume->check_mute = gtk_check_button_new_with_label("Mute");
|
||||
volume->scale_volume = gtk_scale_new_with_range(
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.05f
|
||||
);
|
||||
|
||||
gtk_scale_set_draw_value(GTK_SCALE(volume->scale_volume), FALSE);
|
||||
gtk_range_set_inverted(GTK_RANGE(volume->scale_volume), TRUE);
|
||||
|
||||
wintc_widget_add_style_class(volume->popup_volmgmt, "wintc-volmgmt");
|
||||
|
||||
gtk_box_pack_start(
|
||||
GTK_BOX(volume->box_container),
|
||||
gtk_label_new("Volume"),
|
||||
FALSE,
|
||||
FALSE,
|
||||
0
|
||||
);
|
||||
gtk_box_pack_start(
|
||||
GTK_BOX(volume->box_container),
|
||||
volume->scale_volume,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0
|
||||
);
|
||||
gtk_box_pack_start(
|
||||
GTK_BOX(volume->box_container),
|
||||
volume->check_mute,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0
|
||||
);
|
||||
|
||||
gtk_container_add(
|
||||
GTK_CONTAINER(volume->popup_volmgmt),
|
||||
volume->box_container
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
volume->check_mute,
|
||||
"toggled",
|
||||
G_CALLBACK(on_check_mute_toggled),
|
||||
object
|
||||
);
|
||||
g_signal_connect(
|
||||
volume->scale_volume,
|
||||
"value-changed",
|
||||
G_CALLBACK(on_scale_volume_value_changed),
|
||||
object
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
behaviour->widget_notif,
|
||||
"button-press-event",
|
||||
G_CALLBACK(on_widget_notif_button_press_event),
|
||||
object
|
||||
);
|
||||
|
||||
// Set initial state
|
||||
//
|
||||
wintc_notification_volume_set_have_device(volume, FALSE);
|
||||
|
||||
// Establish sound API context
|
||||
//
|
||||
volume->snd_ctx = wintc_sndapi_context_new();
|
||||
|
||||
g_signal_connect(
|
||||
volume->snd_ctx,
|
||||
"connected-changed",
|
||||
G_CALLBACK(on_snd_ctx_connected_changed),
|
||||
volume
|
||||
);
|
||||
g_signal_connect(
|
||||
volume->snd_ctx,
|
||||
"default-output-changed",
|
||||
G_CALLBACK(on_snd_ctx_default_output_changed),
|
||||
volume
|
||||
);
|
||||
|
||||
wintc_sndapi_context_connect(volume->snd_ctx);
|
||||
|
||||
// Chain up
|
||||
//
|
||||
(G_OBJECT_CLASS(
|
||||
wintc_notification_volume_parent_class
|
||||
))->constructed(object);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCNotificationVolume* wintc_notification_volume_new(
|
||||
GtkWidget* widget_notif
|
||||
)
|
||||
{
|
||||
return WINTC_NOTIFICATION_VOLUME(
|
||||
g_object_new(
|
||||
TYPE_WINTC_NOTIFICATION_VOLUME,
|
||||
"widget-notif", widget_notif,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static void wintc_notification_volume_set_have_device(
|
||||
WinTCNotificationVolume* volume,
|
||||
gboolean have_device
|
||||
)
|
||||
{
|
||||
gtk_widget_set_sensitive(volume->popup_volmgmt, have_device);
|
||||
|
||||
if (!have_device)
|
||||
{
|
||||
g_object_set(
|
||||
volume,
|
||||
"icon-name", "audio-volume-muted",
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void on_snd_ctx_connected_changed(
|
||||
WINTC_UNUSED(WinTCSndApiContext* ctx),
|
||||
gboolean connected,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
if (!connected)
|
||||
{
|
||||
wintc_notification_volume_set_have_device(volume, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_snd_ctx_default_output_changed(
|
||||
WinTCSndApiContext* ctx,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
WinTCSndApiOutput* output =
|
||||
wintc_sndapi_context_get_default_output(ctx);
|
||||
|
||||
if (volume->snd_output == output)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
volume->snd_output = output;
|
||||
|
||||
if (volume->snd_output == NULL)
|
||||
{
|
||||
wintc_notification_volume_set_have_device(volume, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
wintc_notification_volume_set_have_device(volume, TRUE);
|
||||
|
||||
g_signal_connect(
|
||||
volume->snd_output,
|
||||
"muted-changed",
|
||||
G_CALLBACK(on_snd_output_muted_changed),
|
||||
volume
|
||||
);
|
||||
g_signal_connect(
|
||||
volume->snd_output,
|
||||
"volume-changed",
|
||||
G_CALLBACK(on_snd_output_volume_changed),
|
||||
volume
|
||||
);
|
||||
}
|
||||
|
||||
static void on_snd_output_muted_changed(
|
||||
WinTCSndApiOutput* output,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
gboolean muted = wintc_sndapi_output_is_muted(output);
|
||||
gchar* icon_name = muted ? "audio-volume-muted" : "audio-volume-medium";
|
||||
|
||||
volume->syncing_state = TRUE;
|
||||
gtk_toggle_button_set_active(
|
||||
GTK_TOGGLE_BUTTON(volume->check_mute),
|
||||
muted
|
||||
);
|
||||
volume->syncing_state = FALSE;
|
||||
|
||||
g_object_set(
|
||||
volume,
|
||||
"icon-name", icon_name,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
static void on_snd_output_volume_changed(
|
||||
WinTCSndApiOutput* output,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
gdouble new_volume = wintc_sndapi_output_get_volume(output);
|
||||
|
||||
volume->syncing_state = TRUE;
|
||||
gtk_range_set_value(
|
||||
GTK_RANGE(volume->scale_volume),
|
||||
new_volume
|
||||
);
|
||||
volume->syncing_state = FALSE;
|
||||
}
|
||||
|
||||
static gboolean on_widget_notif_button_press_event(
|
||||
GtkWidget* self,
|
||||
WINTC_UNUSED(GdkEventButton* event),
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
wintc_dpa_show_popup(
|
||||
volume->popup_volmgmt,
|
||||
self
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_check_mute_toggled(
|
||||
GtkToggleButton* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
if (volume->syncing_state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wintc_sndapi_output_set_muted(
|
||||
volume->snd_output,
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self))
|
||||
);
|
||||
}
|
||||
|
||||
static void on_scale_volume_value_changed(
|
||||
GtkRange* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCNotificationVolume* volume =
|
||||
WINTC_NOTIFICATION_VOLUME(user_data);
|
||||
|
||||
if (volume->syncing_state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wintc_sndapi_output_set_volume(
|
||||
volume->snd_output,
|
||||
gtk_range_get_value(GTK_RANGE(self))
|
||||
);
|
||||
}
|
||||
29
shell/taskband/src/systray/volume.h
Normal file
29
shell/taskband/src/systray/volume.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __VOLUME_H__
|
||||
#define __VOLUME_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//
|
||||
// GTK OOP BOILERPLATE
|
||||
//
|
||||
typedef struct _WinTCNotificationVolumeClass WinTCNotificationVolumeClass;
|
||||
typedef struct _WinTCNotificationVolume WinTCNotificationVolume;
|
||||
|
||||
#define TYPE_WINTC_NOTIFICATION_VOLUME (wintc_notification_volume_get_type())
|
||||
#define WINTC_NOTIFICATION_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_NOTIFICATION_VOLUME, WinTCNotificationVolume))
|
||||
#define WINTC_NOTIFICATION_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_NOTIFICATION_BEHAVIOUR, WinTCNotificationVolumeClass))
|
||||
#define IS_WINTC_NOTIFICATION_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_NOTIFICATION_VOLUME))
|
||||
#define IS_WINTC_NOTIFICATION_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_NOTIFICATION_VOLUME))
|
||||
#define WINTC_NOTIFICATION_VOLUME_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_NOTIFICATION_VOLUME, WinTCNotificationVolume))
|
||||
|
||||
GType wintc_notification_volume_get_type(void) G_GNUC_CONST;
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCNotificationVolume* wintc_notification_volume_new(
|
||||
GtkWidget* widget_notif
|
||||
);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user