Cleaning: Fixes #526, Migrate taskband toolbars to WinTCShextUIHost/Controller

This commit is contained in:
Rory Fewell
2025-09-08 23:50:16 +01:00
parent 70d2042a89
commit 21d2a15d77
28 changed files with 1067 additions and 881 deletions

View File

@@ -36,6 +36,7 @@ wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
wintc_resolve_library(wintc-exec WINTC_EXEC)
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
wintc_resolve_library(wintc-shelldpa WINTC_SHELLDPA)
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
wintc_resolve_library(wintc-sndapi WINTC_SNDAPI)
@@ -47,11 +48,10 @@ set(
TASKBAND_SOURCES
src/application.c
src/application.h
src/intapi.h
src/main.c
src/meta.h
src/resources.c
src/toolbar.c
src/toolbar.h
src/window.c
src/window.h
src/start/menumod.c
@@ -65,10 +65,10 @@ set(
src/start/toolbar.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/icon.c
src/systray/icon.h
src/systray/notifarea.c
src/systray/notifarea.h
src/systray/power.c
@@ -123,6 +123,7 @@ target_include_directories(
PRIVATE ${WINTC_EXEC_INCLUDE_DIRS}
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELLDPA_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELLEXT_INCLUDE_DIRS}
PRIVATE ${WINTC_SHLANG_INCLUDE_DIRS}
PRIVATE ${WINTC_SNDAPI_INCLUDE_DIRS}
)
@@ -142,6 +143,7 @@ target_link_directories(
PRIVATE ${WINTC_EXEC_LIBRARY_DIRS}
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELLDPA_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELLEXT_LIBRARY_DIRS}
PRIVATE ${WINTC_SHLANG_LIBRARY_DIRS}
PRIVATE ${WINTC_SNDAPI_LIBRARY_DIRS}
)
@@ -161,6 +163,7 @@ target_link_libraries(
PRIVATE ${WINTC_EXEC_LIBRARIES}
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
PRIVATE ${WINTC_SHELLDPA_LIBRARIES}
PRIVATE ${WINTC_SHELLEXT_LIBRARIES}
PRIVATE ${WINTC_SHLANG_LIBRARIES}
PRIVATE ${WINTC_SNDAPI_LIBRARIES}
)

View File

@@ -12,5 +12,6 @@ bt,rt:wintc-comgtk
bt,rt:wintc-exec
bt,rt:wintc-shcommon
bt,rt:wintc-shelldpa
bt,rt:wintc-shellext
bt,rt:wintc-shlang
bt,rt:wintc-sndapi

View File

@@ -0,0 +1,16 @@
#ifndef __INTAPI_H__
#define __INTAPI_H__
//
// PUBLIC CONSTANTS
//
// Taskband host API
//
#define WINTC_TASKBAND_HOSTEXT_TOOLBAR 1
// Notification area host API
//
#define WINTC_NOTIFAREA_HOSTEXT_ICON 1
#endif

View File

@@ -11,7 +11,6 @@
#include <wintc/shelldpa.h>
#include <wintc/shlang.h>
#include "../toolbar.h"
#include "menumod.h"
#include "personal.h"
#include "progmenu.h"
@@ -125,7 +124,6 @@ void create_personal_menu(
)
{
GtkBuilder* builder;
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(toolbar_start);
// Set default states
//
@@ -266,7 +264,10 @@ void create_personal_menu(
// Transfer to popup
//
toolbar_start->personal.popup_menu =
wintc_dpa_create_popup(toolbar->widget_root, TRUE);
wintc_dpa_create_popup(
toolbar_start->start_button,
TRUE
);
wintc_widget_add_style_class(
toolbar_start->personal.popup_menu,
@@ -417,8 +418,6 @@ void open_personal_menu(
WinTCToolbarStart* toolbar_start
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(toolbar_start);
// Reset should close flag, so that selection-done knows no item has
// actually been 'activated' yet
//
@@ -431,7 +430,7 @@ void open_personal_menu(
wintc_dpa_show_popup(
toolbar_start->personal.popup_menu,
toolbar->widget_root
toolbar_start->start_button
);
}
@@ -1134,7 +1133,6 @@ static void on_personal_menu_hide(
gpointer user_data
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(user_data);
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(user_data);
// Track the last closed time, important for toggling the menu properly
@@ -1146,7 +1144,7 @@ static void on_personal_menu_hide(
//
toolbar_start->sync_button = TRUE;
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(toolbar->widget_root),
GTK_TOGGLE_BUTTON(toolbar_start->start_button),
FALSE
);
toolbar_start->sync_button = FALSE;

View File

@@ -4,6 +4,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comctl.h>
#include <wintc/shellext.h>
#include "progmenu.h"
@@ -40,14 +41,13 @@ typedef struct _PersonalStartMenuData
GArray* tuples_programs;
} PersonalStartMenuData;
typedef struct _WinTCToolbarStartClass
{
WinTCTaskbandToolbarClass __parent__;
} WinTCToolbarStartClass;
typedef struct _WinTCToolbarStart
{
WinTCTaskbandToolbar __parent__;
WinTCShextUIController __parent__;
// UI
//
GtkWidget* start_button;
// Personal data struct
//

View File

@@ -2,9 +2,10 @@
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include <wintc/shlang.h>
#include "../toolbar.h"
#include "../intapi.h"
#include "personal.h"
#include "progmenu.h"
#include "shared.h"
@@ -13,6 +14,9 @@
//
// FORWARD DECLARATIONS
//
static void wintc_toolbar_start_constructed(
GObject* object
);
static void wintc_toolbar_start_dispose(
GObject* object
);
@@ -28,7 +32,7 @@ static void on_start_button_toggled(
G_DEFINE_TYPE(
WinTCToolbarStart,
wintc_toolbar_start,
WINTC_TYPE_TASKBAND_TOOLBAR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_toolbar_start_class_init(
@@ -37,16 +41,14 @@ static void wintc_toolbar_start_class_init(
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->dispose = wintc_toolbar_start_dispose;
object_class->constructed = wintc_toolbar_start_constructed;
object_class->dispose = wintc_toolbar_start_dispose;
}
static void wintc_toolbar_start_init(
WinTCToolbarStart* self
)
{
GtkBuilder* builder;
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
// Default states
//
self->sync_button = FALSE;
@@ -70,22 +72,42 @@ static void wintc_toolbar_start_init(
// Initialize progmenu
//
self->progmenu = wintc_toolbar_start_progmenu_new();
}
// Create root widget (Start button)
//
// CLASS VIRTUAL METHODS
//
static void wintc_toolbar_start_constructed(
GObject* object
)
{
(G_OBJECT_CLASS(wintc_toolbar_start_parent_class))->constructed(object);
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(object);
// Create Start button as the toolbar
//
builder =
GtkBuilder* builder =
gtk_builder_new_from_resource(
"/uk/oddmatics/wintc/taskband/start-button.ui"
);
wintc_lc_builder_preprocess_widget_text(builder);
toolbar->widget_root =
GTK_WIDGET(
g_object_ref_sink(
gtk_builder_get_object(builder, "start-button")
)
);
wintc_builder_get_objects(
builder,
"start-button", &(toolbar_start->start_button),
NULL
);
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_TASKBAND_HOSTEXT_TOOLBAR,
GTK_TYPE_WIDGET,
toolbar_start->start_button
);
g_object_unref(G_OBJECT(builder));
@@ -93,32 +115,23 @@ static void wintc_toolbar_start_init(
// FIXME: Hard coded to the personal menu for now, 'til DBus and stuff is
// understood and we can support a 'Use classic menu' property
//
create_personal_menu(self);
create_personal_menu(toolbar_start);
// Attach signals for popup
//
g_signal_connect(
toolbar->widget_root,
toolbar_start->start_button,
"toggled",
G_CALLBACK(on_start_button_toggled),
self
toolbar_start
);
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_toolbar_start_dispose(
GObject* object
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(object);
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(object);
// Because we took a reference to the Start button from the builder, we
// must unref it now
//
g_object_unref(toolbar->widget_root);
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(object);
// FIXME: Only worrying about destroying the personal menu for now until
// the classic menu is available
@@ -139,9 +152,8 @@ void wintc_toolbar_start_toggle_menu(
WinTCToolbarStart* toolbar_start
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(toolbar_start);
GtkToggleButton* start_button = GTK_TOGGLE_BUTTON(toolbar->widget_root);
GtkToggleButton* start_button =
GTK_TOGGLE_BUTTON(toolbar_start->start_button);
// Rate-limit toggling, prevents glitchy behaviour especially when launched
// via cmdline/keyboard shortcut (so the menu loses focus then immediately

View File

@@ -3,20 +3,22 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
#include "shared.h"
//
// GTK OOP BOILERPLATE
//
#define WINTC_TYPE_TOOLBAR_START (wintc_toolbar_start_get_type())
#define WINTC_TOOLBAR_START(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TOOLBAR_START, WinTCToolbarStart))
#define WINTC_TOOLBAR_START_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TOOLBAR_START, WinTCToolbarStartClass))
#define IS_WINTC_TOOLBAR_START(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TOOLBAR_START))
#define IS_WINTC_TOOLBAR_START_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TOOLBAR_START))
#define WINTC_TOOLBAR_START_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TOOLBAR_START, WinTCToolbarStart))
#define WINTC_TYPE_TOOLBAR_START (wintc_toolbar_start_get_type())
GType wintc_toolbar_start_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCToolbarStart,
wintc_toolbar_start,
WINTC,
TOOLBAR_START,
WinTCShextUIController
)
//
// PUBLIC FUNCTIONS

View File

@@ -1,190 +0,0 @@
#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_finalize(
GObject* object
);
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->finalize = wintc_notification_behaviour_finalize;
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_finalize(
GObject* object
)
{
WinTCNotificationBehaviour* behaviour =
WINTC_NOTIFICATION_BEHAVIOUR(object);
g_free(behaviour->icon_name);
(G_OBJECT_CLASS(wintc_notification_behaviour_parent_class))
->finalize(object);
}
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;
}

View File

@@ -1,39 +0,0 @@
#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 WINTC_TYPE_NOTIFICATION_BEHAVIOUR (wintc_notification_behaviour_get_type())
#define WINTC_NOTIFICATION_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_NOTIFICATION_BEHAVIOUR, WinTCNotificationBehaviour))
#define WINTC_NOTIFICATION_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_NOTIFICATION_BEHAVIOUR, WinTCNotificationBehaviourClass))
#define IS_WINTC_NOTIFICATION_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_NOTIFICATION_BEHAVIOUR))
#define IS_WINTC_NOTIFICATION_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_NOTIFICATION_BEHAVIOUR))
#define WINTC_NOTIFICATION_BEHAVIOUR_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_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

View File

@@ -0,0 +1,497 @@
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include "icon.h"
#define TRAY_ICON_SIZE 16
//
// PRIVATE ENUMS
//
enum
{
PROP_NULL,
PROP_ICON_NAME,
N_PROPERTIES
};
//
// FORWARD DECLARATIONS
//
static void wintc_notif_area_icon_dispose(
GObject* object
);
static void wintc_notif_area_icon_finalize(
GObject* object
);
static void wintc_notif_area_icon_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
);
static void wintc_notif_area_icon_set_property(
GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec
);
static gboolean wintc_notif_area_icon_draw(
GtkWidget* widget,
cairo_t* cr
);
static void wintc_notif_area_icon_get_preferred_height(
GtkWidget* widget,
gint* minimum_height,
gint* natural_height
);
static void wintc_notif_area_icon_get_preferred_height_for_width(
GtkWidget* widget,
gint width,
gint* minimum_height,
gint* natural_height
);
static void wintc_notif_area_icon_get_preferred_width(
GtkWidget* widget,
gint* minimum_width,
gint* natural_width
);
static void wintc_notif_area_icon_get_preferred_width_for_height(
GtkWidget* widget,
gint height,
gint* minimum_width,
gint* natural_width
);
static void wintc_notif_area_icon_map(
GtkWidget* widget
);
static void wintc_notif_area_icon_realize(
GtkWidget* widget
);
static void wintc_notif_area_icon_size_allocate(
GtkWidget* widget,
GtkAllocation* allocation
);
static void wintc_notif_area_icon_unmap(
GtkWidget* widget
);
static void wintc_notif_area_icon_unrealize(
GtkWidget* widget
);
//
// STATIC DATA
//
static GParamSpec* wintc_notif_area_icon_properties[N_PROPERTIES] = { 0 };
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCNotifAreaIcon
{
GtkWidget __parent__;
GdkWindow* hwnd;
gchar* icon_name;
GdkPixbuf* pixbuf_icon;
cairo_surface_t* surface_icon;
};
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCNotifAreaIcon,
wintc_notif_area_icon,
GTK_TYPE_WIDGET
)
static void wintc_notif_area_icon_class_init(
WinTCNotifAreaIconClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
object_class->dispose = wintc_notif_area_icon_dispose;
object_class->finalize = wintc_notif_area_icon_finalize;
object_class->get_property = wintc_notif_area_icon_get_property;
object_class->set_property = wintc_notif_area_icon_set_property;
widget_class->draw = wintc_notif_area_icon_draw;
widget_class->map = wintc_notif_area_icon_map;
widget_class->realize = wintc_notif_area_icon_realize;
widget_class->size_allocate = wintc_notif_area_icon_size_allocate;
widget_class->unmap = wintc_notif_area_icon_unmap;
widget_class->unrealize = wintc_notif_area_icon_unrealize;
widget_class->get_preferred_height =
wintc_notif_area_icon_get_preferred_height;
widget_class->get_preferred_height_for_width =
wintc_notif_area_icon_get_preferred_height_for_width;
widget_class->get_preferred_width =
wintc_notif_area_icon_get_preferred_width;
widget_class->get_preferred_width_for_height =
wintc_notif_area_icon_get_preferred_width_for_height;
wintc_notif_area_icon_properties[PROP_ICON_NAME] =
g_param_spec_string(
"icon-name",
"IconName",
"The XDG icon name to use.",
"image-missing",
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY
);
g_object_class_install_properties(
object_class,
N_PROPERTIES,
wintc_notif_area_icon_properties
);
}
static void wintc_notif_area_icon_init(
WinTCNotifAreaIcon* self
)
{
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_notif_area_icon_dispose(
GObject* object
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(object);
if (notif_icon->pixbuf_icon)
{
cairo_surface_destroy(notif_icon->surface_icon);
g_clear_object(&(notif_icon->pixbuf_icon));
}
(G_OBJECT_CLASS(wintc_notif_area_icon_parent_class))
->dispose(object);
}
static void wintc_notif_area_icon_finalize(
GObject* object
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(object);
g_free(notif_icon->icon_name);
(G_OBJECT_CLASS(wintc_notif_area_icon_parent_class))
->finalize(object);
}
static void wintc_notif_area_icon_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(object);
switch (prop_id)
{
case PROP_ICON_NAME:
g_value_set_string(value, notif_icon->icon_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void wintc_notif_area_icon_set_property(
GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(object);
switch (prop_id)
{
case PROP_ICON_NAME:
wintc_notif_area_icon_set_icon_name(
notif_icon,
g_value_get_string(value)
);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static gboolean wintc_notif_area_icon_draw(
GtkWidget* widget,
cairo_t* cr
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
if (!(notif_icon->surface_icon))
{
return FALSE;
}
// We draw the icon centered vertically
//
gint height = gtk_widget_get_allocated_height(widget);
cairo_save(cr);
cairo_translate(
cr,
0.0f,
(double) ((height / 2) - (TRAY_ICON_SIZE / 2))
);
cairo_set_source_surface(
cr,
notif_icon->surface_icon,
0.0f,
0.0f
);
cairo_pattern_set_extend(
cairo_get_source(cr),
CAIRO_EXTEND_NONE
);
cairo_paint(cr);
cairo_restore(cr);
return FALSE;
}
static void wintc_notif_area_icon_get_preferred_height(
WINTC_UNUSED(GtkWidget* widget),
gint* minimum_height,
gint* natural_height
)
{
*minimum_height = TRAY_ICON_SIZE;
*natural_height = TRAY_ICON_SIZE;
}
static void wintc_notif_area_icon_get_preferred_height_for_width(
WINTC_UNUSED(GtkWidget* widget),
WINTC_UNUSED(gint width),
gint* minimum_height,
gint* natural_height
)
{
*minimum_height = TRAY_ICON_SIZE;
*natural_height = TRAY_ICON_SIZE;
}
static void wintc_notif_area_icon_get_preferred_width(
WINTC_UNUSED(GtkWidget* widget),
gint* minimum_width,
gint* natural_width
)
{
*minimum_width = TRAY_ICON_SIZE;
*natural_width = TRAY_ICON_SIZE;
}
static void wintc_notif_area_icon_get_preferred_width_for_height(
WINTC_UNUSED(GtkWidget* widget),
WINTC_UNUSED(gint height),
gint* minimum_width,
gint* natural_width
)
{
*minimum_width = TRAY_ICON_SIZE;
*natural_width = TRAY_ICON_SIZE;
}
static void wintc_notif_area_icon_map(
GtkWidget* widget
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
if (notif_icon->hwnd)
{
gdk_window_show(notif_icon->hwnd);
}
(GTK_WIDGET_CLASS(wintc_notif_area_icon_parent_class))
->map(widget);
}
static void wintc_notif_area_icon_realize(
GtkWidget* widget
)
{
(GTK_WIDGET_CLASS(wintc_notif_area_icon_parent_class))
->realize(widget);
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
GtkAllocation allocation;
GdkWindowAttr attribs;
gtk_widget_get_allocation(widget, &allocation);
attribs.x = allocation.x;
attribs.y = allocation.y;
attribs.width = allocation.width;
attribs.height = allocation.height;
attribs.event_mask = GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK;
attribs.wclass = GDK_INPUT_ONLY;
attribs.window_type = GDK_WINDOW_CHILD;
notif_icon->hwnd =
gdk_window_new(
gtk_widget_get_parent_window(widget),
&attribs,
GDK_WA_X | GDK_WA_Y
);
gtk_widget_register_window(widget, notif_icon->hwnd);
}
static void wintc_notif_area_icon_size_allocate(
GtkWidget* widget,
GtkAllocation* allocation
)
{
(GTK_WIDGET_CLASS(wintc_notif_area_icon_parent_class))
->size_allocate(widget, allocation);
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
if (gtk_widget_get_realized(widget) && notif_icon->hwnd)
{
gdk_window_move_resize(
notif_icon->hwnd,
allocation->x,
allocation->y,
allocation->width,
allocation->height
);
}
}
static void wintc_notif_area_icon_unmap(
GtkWidget* widget
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
if (notif_icon->hwnd)
{
gdk_window_hide(notif_icon->hwnd);
}
(GTK_WIDGET_CLASS(wintc_notif_area_icon_parent_class))
->map(widget);
}
static void wintc_notif_area_icon_unrealize(
GtkWidget* widget
)
{
WinTCNotifAreaIcon* notif_icon = WINTC_NOTIF_AREA_ICON(widget);
if (notif_icon->hwnd)
{
gtk_widget_unregister_window(widget, notif_icon->hwnd);
gdk_window_destroy(notif_icon->hwnd);
notif_icon->hwnd = NULL;
}
(GTK_WIDGET_CLASS(wintc_notif_area_icon_parent_class))
->unrealize(widget);
}
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_notif_area_icon_new(void)
{
return GTK_WIDGET(
g_object_new(
WINTC_TYPE_NOTIF_AREA_ICON,
NULL
)
);
}
const gchar* wintc_notif_area_icon_get_icon_name(
WinTCNotifAreaIcon* notif_icon
)
{
return notif_icon->icon_name;
}
void wintc_notif_area_icon_set_icon_name(
WinTCNotifAreaIcon* notif_icon,
const gchar* icon_name
)
{
// Bin old icon
//
if (notif_icon->icon_name)
{
g_free(notif_icon->icon_name);
}
if (notif_icon->pixbuf_icon)
{
cairo_surface_destroy(notif_icon->surface_icon);
g_clear_object(&(notif_icon->pixbuf_icon));
}
// Set new icon
//
notif_icon->icon_name = g_strdup(icon_name);
notif_icon->pixbuf_icon =
gtk_icon_theme_load_icon(
gtk_icon_theme_get_default(),
notif_icon->icon_name,
16,
GTK_ICON_LOOKUP_FORCE_SIZE,
NULL
);
if (notif_icon->pixbuf_icon)
{
notif_icon->surface_icon =
gdk_cairo_surface_create_from_pixbuf(
notif_icon->pixbuf_icon,
1,
NULL
);
}
// Finish up
//
gtk_widget_queue_draw(GTK_WIDGET(notif_icon));
g_object_notify_by_pspec(
G_OBJECT(notif_icon),
wintc_notif_area_icon_properties[PROP_ICON_NAME]
);
}

View File

@@ -0,0 +1,33 @@
#ifndef __SYSTRAY_ICON_H__
#define __SYSTRAY_ICON_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
#define WINTC_TYPE_NOTIF_AREA_ICON (wintc_notif_area_icon_get_type())
G_DECLARE_FINAL_TYPE(
WinTCNotifAreaIcon,
wintc_notif_area_icon,
WINTC,
NOTIF_AREA_ICON,
GtkWidget
)
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_notif_area_icon_new(void);
const gchar* wintc_notif_area_icon_get_icon_name(
WinTCNotifAreaIcon* notif_icon
);
void wintc_notif_area_icon_set_icon_name(
WinTCNotifAreaIcon* notif_icon,
const gchar* icon_name
);
#endif

View File

@@ -2,26 +2,27 @@
#include <gtk/gtk.h>
#include <NetworkManager.h>
#include <wintc/comgtk.h>
#include <wintc/shellext.h>
#include "behaviour.h"
#include "../intapi.h"
#include "icon.h"
#include "network.h"
//
// STATIC DATA
//
GtkWidget* s_menu_network = NULL;
GtkWidget* S_MENU_NETWORK = NULL;
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCNotificationNetworkClass
{
WinTCNotificationBehaviourClass __parent__;
};
struct _WinTCNotificationNetwork
{
WinTCNotificationBehaviour __parent__;
WinTCShextUIController __parent__;
// UI
//
GtkWidget* notif_icon;
// Network stuff
//
@@ -51,7 +52,7 @@ static void on_nm_client_notify_primary_connection(
GParamSpec* pspec,
gpointer user_data
);
static void on_widget_notif_button_press_event(
static void on_notif_icon_button_press_event(
GtkWidget* self,
GdkEventButton* event,
gpointer user_data
@@ -63,7 +64,7 @@ static void on_widget_notif_button_press_event(
G_DEFINE_TYPE(
WinTCNotificationNetwork,
wintc_notification_network,
WINTC_TYPE_NOTIFICATION_BEHAVIOUR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_notification_network_class_init(
@@ -79,14 +80,14 @@ static void wintc_notification_network_init(
WINTC_UNUSED(WinTCNotificationNetwork* self)
)
{
if (!s_menu_network)
if (!S_MENU_NETWORK)
{
GtkBuilder* builder =
gtk_builder_new_from_resource(
"/uk/oddmatics/wintc/taskband/menu-tray-nm.ui"
);
s_menu_network =
S_MENU_NETWORK =
GTK_WIDGET(
g_object_ref(gtk_builder_get_object(builder, "menu"))
);
@@ -102,15 +103,25 @@ static void wintc_notification_network_constructed(
GObject* object
)
{
WinTCNotificationBehaviour* behaviour =
WINTC_NOTIFICATION_BEHAVIOUR(object);
WinTCNotificationNetwork* network =
(G_OBJECT_CLASS(wintc_notification_network_parent_class))
->constructed(object);
WinTCNotificationNetwork* network =
WINTC_NOTIFICATION_NETWORK(object);
g_object_set(
network,
"icon-name", "network-offline",
NULL
network->notif_icon =
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_NOTIFAREA_HOSTEXT_ICON,
WINTC_TYPE_NOTIF_AREA_ICON,
object
);
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(network->notif_icon),
"network-offline"
);
// Connect to NetworkManager
@@ -126,29 +137,13 @@ static void wintc_notification_network_constructed(
// Hook up signals for widget
//
g_signal_connect(
behaviour->widget_notif,
network->notif_icon,
"button-press-event",
G_CALLBACK(on_widget_notif_button_press_event),
G_CALLBACK(on_notif_icon_button_press_event),
network
);
}
//
// PUBLIC FUNCTIONS
//
WinTCNotificationNetwork* wintc_notification_network_new(
GtkWidget* widget_notif
)
{
return WINTC_NOTIFICATION_NETWORK(
g_object_new(
WINTC_TYPE_NOTIFICATION_NETWORK,
"widget-notif", widget_notif,
NULL
)
);
}
//
// PRIVATE FUNCTIONS
//
@@ -165,10 +160,9 @@ static void nm_update_primary_connection(
if (!network->nm_primary_connection)
{
g_object_set(
network,
"icon-name", "network-offline",
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(network->notif_icon),
"network-offline"
);
return;
@@ -176,10 +170,9 @@ static void nm_update_primary_connection(
// FIXME: Decide network type and stuff
//
g_object_set(
network,
"icon-name", "network-idle",
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(network->notif_icon),
"network-idle"
);
}
@@ -231,7 +224,7 @@ static void on_nm_client_ready(
);
}
static void on_widget_notif_button_press_event(
static void on_notif_icon_button_press_event(
WINTC_UNUSED(GtkWidget* self),
GdkEventButton* event,
WINTC_UNUSED(gpointer user_data)
@@ -240,7 +233,7 @@ static void on_widget_notif_button_press_event(
if (event->button == 3)
{
gtk_menu_popup_at_pointer(
GTK_MENU(s_menu_network),
GTK_MENU(S_MENU_NETWORK),
(GdkEvent*) event
);
}

View File

@@ -3,27 +3,19 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCNotificationNetworkClass WinTCNotificationNetworkClass;
typedef struct _WinTCNotificationNetwork WinTCNotificationNetwork;
#define WINTC_TYPE_NOTIFICATION_NETWORK (wintc_notification_network_get_type())
#define WINTC_TYPE_NOTIFICATION_NETWORK (wintc_notification_network_get_type())
#define WINTC_NOTIFICATION_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_NOTIFICATION_NETWORK, WinTCNotificationNetwork))
#define WINTC_NOTIFICATION_NETWORK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_NOTIFICATION_BEHAVIOUR, WinTCNotificationNetworkClass))
#define IS_WINTC_NOTIFICATION_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_NOTIFICATION_NETWORK))
#define IS_WINTC_NOTIFICATION_NETWORK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_NOTIFICATION_NETWORK))
#define WINTC_NOTIFICATION_NETWORK_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_NOTIFICATION_NETWORK, WinTCNotificationNetwork))
GType wintc_notification_network_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCNotificationNetwork* wintc_notification_network_new(
GtkWidget* widget_notif
);
G_DECLARE_FINAL_TYPE(
WinTCNotificationNetwork,
wintc_notification_network,
WINTC,
NOTIFICATION_NETWORK,
WinTCShextUIController
)
#endif

View File

@@ -1,9 +1,11 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shellext.h>
#include "behaviour.h"
#include "../intapi.h"
#include "clock.h"
#include "icon.h"
#include "notifarea.h"
#include "power.h"
#include "volume.h"
@@ -12,6 +14,24 @@
#include "network.h"
#endif
//
// FORWARD DECLARATIONS
//
static void wintc_notification_area_ishext_ui_host_interface_init(
WinTCIShextUIHostInterface* iface
);
static void wintc_notification_area_dispose(
GObject* object
);
static GtkWidget* wintc_notification_area_get_ext_widget(
WinTCIShextUIHost* host,
guint ext_id,
GType expected_type,
gpointer ctx
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
@@ -29,46 +49,20 @@ struct _WinTCNotificationArea
WinTCClockRunner* clock_runner;
GHashTable* map_widget_to_behaviour;
GSList* list_uictl_behaviours;
};
//
// FORWARD DECLARATIONS
//
static void wintc_notification_area_dispose(
GObject* object
);
static void wintc_notification_area_append_component(
WinTCNotificationArea* notif_area,
GType component_type
);
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(
G_DEFINE_TYPE_WITH_CODE(
WinTCNotificationArea,
wintc_notification_area,
GTK_TYPE_BIN
GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE(
WINTC_TYPE_ISHEXT_UI_HOST,
wintc_notification_area_ishext_ui_host_interface_init
)
)
static void wintc_notification_area_class_init(
@@ -84,16 +78,6 @@ static void wintc_notification_area_init(
WinTCNotificationArea* self
)
{
// Create map for notification widgets --> behaviours
//
self->map_widget_to_behaviour =
g_hash_table_new_full(
g_direct_hash,
g_direct_equal,
NULL,
g_object_unref
);
// Set up UI
//
self->box_container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
@@ -123,21 +107,28 @@ static void wintc_notification_area_init(
// Create notification area icons
//
#ifndef WINTC_PKGMGR_BSDPKG
wintc_notification_area_append_component(
self,
WINTC_TYPE_NOTIFICATION_NETWORK
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_NOTIFICATION_NETWORK,
WINTC_ISHEXT_UI_HOST(self)
);
#endif
wintc_notification_area_append_component(
self,
WINTC_TYPE_NOTIFICATION_POWER
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_NOTIFICATION_POWER,
WINTC_ISHEXT_UI_HOST(self)
);
wintc_notification_area_append_component(
self,
WINTC_TYPE_NOTIFICATION_VOLUME
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_NOTIFICATION_VOLUME,
WINTC_ISHEXT_UI_HOST(self)
);
}
static void wintc_notification_area_ishext_ui_host_interface_init(
WinTCIShextUIHostInterface* iface
)
{
iface->get_ext_widget = wintc_notification_area_get_ext_widget;
}
//
// CLASS VIRTUAL METHODS
//
@@ -148,17 +139,65 @@ static void wintc_notification_area_dispose(
WinTCNotificationArea* notif_area = WINTC_NOTIFICATION_AREA(object);
g_clear_object(&(notif_area->clock_runner));
if (notif_area->map_widget_to_behaviour)
{
g_hash_table_unref(
g_steal_pointer(&(notif_area->map_widget_to_behaviour))
);
}
g_clear_slist(
&(notif_area->list_uictl_behaviours),
(GDestroyNotify) g_object_unref
);
(G_OBJECT_CLASS(wintc_notification_area_parent_class))->dispose(object);
}
//
// INTERFACE METHODS (WinTCIShextUIHost)
//
static GtkWidget* wintc_notification_area_get_ext_widget(
WinTCIShextUIHost* host,
guint ext_id,
GType expected_type,
gpointer ctx
)
{
WinTCNotificationArea* notif_area = WINTC_NOTIFICATION_AREA(host);
if (ext_id != WINTC_NOTIFAREA_HOSTEXT_ICON)
{
g_critical("notifarea: unsupported ext widget type: %d", ext_id);
return NULL;
}
if (expected_type != WINTC_TYPE_NOTIF_AREA_ICON)
{
g_critical("%s", "notifarea: invalid ext widget type");
return NULL;
}
if (!G_IS_OBJECT(ctx))
{
g_critical("%s", "notifarea: expected a GObject for icon context");
return NULL;
}
// All good, create the icon
//
GtkWidget* notif_icon = wintc_notif_area_icon_new();
gtk_box_pack_start(
GTK_BOX(notif_area->box_container),
notif_icon,
FALSE,
FALSE,
0
);
notif_area->list_uictl_behaviours =
g_slist_append(
notif_area->list_uictl_behaviours,
ctx
);
return notif_icon;
}
//
// PUBLIC FUNCTIONS
//
@@ -171,108 +210,3 @@ GtkWidget* notification_area_new(void)
)
);
}
//
// PRIVATE FUNCTIONS
//
static void wintc_notification_area_append_component(
WinTCNotificationArea* notif_area,
GType component_type
)
{
GtkWidget* widget = wintc_notification_area_append_icon(notif_area);
WinTCNotificationBehaviour* notif =
WINTC_NOTIFICATION_BEHAVIOUR(
g_object_new(
component_type,
"widget-notif", widget,
NULL
)
);
wintc_notification_area_map_widget(
notif_area,
widget,
notif
);
}
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(notif_area->box_container),
event_box,
FALSE,
FALSE,
0
);
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
);
}

View File

@@ -7,15 +7,15 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCNotificationAreaClass WinTCNotificationAreaClass;
typedef struct _WinTCNotificationArea WinTCNotificationArea;
#define WINTC_TYPE_NOTIFICATION_AREA (wintc_notification_area_get_type())
#define WINTC_TYPE_NOTIFICATION_AREA (wintc_notification_area_get_type())
#define WINTC_NOTIFICATION_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_NOTIFICATION_AREA, WinTCNotificationArea))
#define WINTC_NOTIFICATION_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_NOTIFICATION_AREA, WinTCNotificationArea))
#define IS_WINTC_NOTIFICATION_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_NOTIFICATION_AREA))
#define IS_WINTC_NOTIFICATION_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_NOTIFICATION_AREA))
#define WINTC_NOTIFICATION_AREA_GET_CLASS(obj) (G_TYPE_CHECK_INSTANCE_GET_CLASS((obj), WINTC_TYPE_NOTIFICATION_AREA))
G_DECLARE_FINAL_TYPE(
WinTCNotificationArea,
wintc_notification_area,
WINTC,
NOTIFICATION_AREA,
GtkBin
)
//
// PUBLIC FUNCTIONS

View File

@@ -2,8 +2,10 @@
#include <gtk/gtk.h>
#include <libupower-glib/upower.h>
#include <wintc/comgtk.h>
#include <wintc/shellext.h>
#include "behaviour.h"
#include "../intapi.h"
#include "icon.h"
#include "power.h"
//
@@ -51,14 +53,13 @@ static void on_up_device_battery_notify(
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCNotificationPowerClass
{
WinTCNotificationBehaviourClass __parent__;
};
struct _WinTCNotificationPower
{
WinTCNotificationBehaviour __parent__;
WinTCShextUIController __parent__;
// UI
//
GtkWidget* notif_icon;
// Power stuff
//
@@ -72,7 +73,7 @@ struct _WinTCNotificationPower
G_DEFINE_TYPE(
WinTCNotificationPower,
wintc_notification_power,
WINTC_TYPE_NOTIFICATION_BEHAVIOUR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_notification_power_class_init(
@@ -101,6 +102,16 @@ static void wintc_notification_power_constructed(
WinTCNotificationPower* power = WINTC_NOTIFICATION_POWER(object);
power->notif_icon =
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_NOTIFAREA_HOSTEXT_ICON,
WINTC_TYPE_NOTIF_AREA_ICON,
object
);
// Connect to upower, enumerate existing devices and attach signals for
// picking up new ones
//
@@ -149,22 +160,6 @@ static void wintc_notification_power_dispose(
->dispose(object);
}
//
// PUBLIC FUNCTIONS
//
WinTCNotificationPower* wintc_notification_power_new(
GtkWidget* widget_notif
)
{
return WINTC_NOTIFICATION_POWER(
g_object_new(
WINTC_TYPE_NOTIFICATION_POWER,
"widget-notif", widget_notif,
NULL
)
);
}
//
// PRIVATE FUNCTIONS
//
@@ -264,18 +259,16 @@ static void wintc_notification_power_update_icon(
{
if (up_client_get_on_battery(power->up_client))
{
g_object_set(
power,
"icon-name", "battery-missing",
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(power->notif_icon),
"battery-missing"
);
}
else
{
g_object_set(
power,
"icon-name", "ac-adapter",
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(power->notif_icon),
"ac-adapter"
);
}
@@ -337,10 +330,9 @@ static void wintc_notification_power_update_icon(
break;
}
g_object_set(
power,
"icon-name", icon_name,
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(power->notif_icon),
icon_name
);
}

View File

@@ -3,27 +3,19 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCNotificationPowerClass WinTCNotificationPowerClass;
typedef struct _WinTCNotificationPower WinTCNotificationPower;
#define WINTC_TYPE_NOTIFICATION_POWER (wintc_notification_power_get_type())
#define WINTC_TYPE_NOTIFICATION_POWER (wintc_notification_power_get_type())
#define WINTC_NOTIFICATION_POWER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_NOTIFICATION_POWER, WinTCNotificationPower))
#define WINTC_NOTIFICATION_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_NOTIFICATION_BEHAVIOUR, WinTCNotificationPowerClass))
#define IS_WINTC_NOTIFICATION_POWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_NOTIFICATION_POWER))
#define IS_WINTC_NOTIFICATION_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_NOTIFICATION_POWER))
#define WINTC_NOTIFICATION_POWER_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_NOTIFICATION_POWER, WinTCNotificationPower))
GType wintc_notification_power_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCNotificationPower* wintc_notification_power_new(
GtkWidget* widget_notif
);
G_DECLARE_FINAL_TYPE(
WinTCNotificationPower,
wintc_notification_power,
WINTC,
NOTIFICATION_POWER,
WinTCShextUIController
)
#endif

View File

@@ -1,22 +1,25 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shellext.h>
#include "../toolbar.h"
#include "../intapi.h"
#include "notifarea.h"
#include "toolbar.h"
//
// FORWARD DECLARATIONS
//
static void wintc_toolbar_notif_area_constructed(
GObject* object
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCToolbarNotifAreaClass
{
WinTCTaskbandToolbarClass __parent__;
};
struct _WinTCToolbarNotifArea
{
WinTCTaskbandToolbar __parent__;
WinTCShextUIController __parent__;
};
//
@@ -25,19 +28,38 @@ struct _WinTCToolbarNotifArea
G_DEFINE_TYPE(
WinTCToolbarNotifArea,
wintc_toolbar_notif_area,
WINTC_TYPE_TASKBAND_TOOLBAR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_toolbar_notif_area_class_init(
WINTC_UNUSED(WinTCToolbarNotifAreaClass* klass)
) {}
static void wintc_toolbar_notif_area_init(
WinTCToolbarNotifArea* self
WinTCToolbarNotifAreaClass* klass
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
GObjectClass* object_class = G_OBJECT_CLASS(klass);
toolbar->widget_root = notification_area_new();
object_class->constructed = wintc_toolbar_notif_area_constructed;
}
static void wintc_toolbar_notif_area_init(
WINTC_UNUSED(WinTCToolbarNotifArea* self)
) {}
//
// CLASS VIRTUAL METHODS
//
static void wintc_toolbar_notif_area_constructed(
GObject* object
)
{
(G_OBJECT_CLASS(wintc_toolbar_notif_area_parent_class))
->constructed(object);
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_TASKBAND_HOSTEXT_TOOLBAR,
GTK_TYPE_WIDGET,
notification_area_new()
);
}

View File

@@ -3,21 +3,20 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCToolbarNotifAreaClass WinTCToolbarNotifAreaClass;
typedef struct _WinTCToolbarNotifArea WinTCToolbarNotifArea;
#define WINTC_TYPE_TOOLBAR_NOTIF_AREA (wintc_toolbar_notif_area_get_type())
#define WINTC_TYPE_TOOLBAR_NOTIF_AREA (wintc_toolbar_notif_area_get_type())
#define WINTC_TOOLBAR_NOTIF_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifArea))
#define WINTC_TOOLBAR_NOTIF_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifAreaClass))
#define IS_WINTC_TOOLBAR_NOTIF_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TOOLBAR_NOTIF_AREA))
#define IS_WINTC_TOOLBAR_NOTIF_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TOOLBAR_NOTIF_AREA))
#define WINTC_TOOLBAR_NOTIF_AREA_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifArea))
GType wintc_toolbar_notif_area_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCToolbarNotifArea,
wintc_toolbar_notif_area,
WINTC,
TOOLBAR_NOTIF_AREA,
WinTCShextUIController
)
#endif

View File

@@ -4,22 +4,23 @@
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include <wintc/sndapi.h>
#include "behaviour.h"
#include "../intapi.h"
#include "icon.h"
#include "volume.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCNotificationVolumeClass
{
WinTCNotificationBehaviourClass __parent__;
};
struct _WinTCNotificationVolume
{
WinTCNotificationBehaviour __parent__;
WinTCShextUIController __parent__;
// UI
//
GtkWidget* notif_icon;
GtkWidget* popup_volmgmt;
@@ -66,7 +67,7 @@ static void on_snd_output_volume_changed(
gpointer user_data
);
static gboolean on_widget_notif_button_press_event(
static gboolean on_notif_icon_button_press_event(
GtkWidget* self,
GdkEventButton* event,
gpointer user_data
@@ -92,7 +93,7 @@ static void on_scale_volume_value_changed(
G_DEFINE_TYPE(
WinTCNotificationVolume,
wintc_notification_volume,
WINTC_TYPE_NOTIFICATION_BEHAVIOUR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_notification_volume_class_init(
@@ -143,15 +144,22 @@ static void wintc_notification_volume_constructed(
GObject* object
)
{
WinTCNotificationVolume* volume =
WINTC_NOTIFICATION_VOLUME(object);
WinTCNotificationBehaviour* behaviour =
WINTC_NOTIFICATION_BEHAVIOUR(volume);
WinTCNotificationVolume* volume = WINTC_NOTIFICATION_VOLUME(object);
volume->notif_icon =
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_NOTIFAREA_HOSTEXT_ICON,
WINTC_TYPE_NOTIF_AREA_ICON,
object
);
// Connect up to the notification icon widget
//
volume->popup_volmgmt =
wintc_dpa_create_popup(behaviour->widget_notif, FALSE);
wintc_dpa_create_popup(volume->notif_icon, FALSE);
volume->box_container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
volume->check_mute = gtk_check_button_new_with_label("Mute");
@@ -215,9 +223,9 @@ static void wintc_notification_volume_constructed(
);
g_signal_connect(
behaviour->widget_notif,
volume->notif_icon,
"button-press-event",
G_CALLBACK(on_widget_notif_button_press_event),
G_CALLBACK(on_notif_icon_button_press_event),
object
);
@@ -251,22 +259,6 @@ static void wintc_notification_volume_constructed(
))->constructed(object);
}
//
// PUBLIC FUNCTIONS
//
WinTCNotificationVolume* wintc_notification_volume_new(
GtkWidget* widget_notif
)
{
return WINTC_NOTIFICATION_VOLUME(
g_object_new(
WINTC_TYPE_NOTIFICATION_VOLUME,
"widget-notif", widget_notif,
NULL
)
);
}
//
// PRIVATE FUNCTIONS
//
@@ -279,10 +271,9 @@ static void wintc_notification_volume_set_have_device(
if (!have_device)
{
g_object_set(
volume,
"icon-name", "audio-volume-muted",
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(volume->notif_icon),
"audio-volume_muted"
);
}
}
@@ -365,10 +356,9 @@ static void on_snd_output_muted_changed(
);
volume->syncing_state = FALSE;
g_object_set(
volume,
"icon-name", icon_name,
NULL
wintc_notif_area_icon_set_icon_name(
WINTC_NOTIF_AREA_ICON(volume->notif_icon),
icon_name
);
}
@@ -390,8 +380,8 @@ static void on_snd_output_volume_changed(
volume->syncing_state = FALSE;
}
static gboolean on_widget_notif_button_press_event(
GtkWidget* self,
static gboolean on_notif_icon_button_press_event(
WINTC_UNUSED(GtkWidget* self),
WINTC_UNUSED(GdkEventButton* event),
gpointer user_data
)
@@ -401,7 +391,7 @@ static gboolean on_widget_notif_button_press_event(
wintc_dpa_show_popup(
volume->popup_volmgmt,
self
volume->notif_icon
);
return TRUE;

View File

@@ -3,27 +3,19 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCNotificationVolumeClass WinTCNotificationVolumeClass;
typedef struct _WinTCNotificationVolume WinTCNotificationVolume;
#define WINTC_TYPE_NOTIFICATION_VOLUME (wintc_notification_volume_get_type())
#define WINTC_TYPE_NOTIFICATION_VOLUME (wintc_notification_volume_get_type())
#define WINTC_NOTIFICATION_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_NOTIFICATION_VOLUME, WinTCNotificationVolume))
#define WINTC_NOTIFICATION_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_NOTIFICATION_BEHAVIOUR, WinTCNotificationVolumeClass))
#define IS_WINTC_NOTIFICATION_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_NOTIFICATION_VOLUME))
#define IS_WINTC_NOTIFICATION_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_NOTIFICATION_VOLUME))
#define WINTC_NOTIFICATION_VOLUME_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_NOTIFICATION_VOLUME, WinTCNotificationVolume))
GType wintc_notification_volume_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCNotificationVolume* wintc_notification_volume_new(
GtkWidget* widget_notif
);
G_DECLARE_FINAL_TYPE(
WinTCNotificationVolume,
wintc_notification_volume,
WINTC,
NOTIFICATION_VOLUME,
WinTCShextUIController
)
#endif

View File

@@ -129,6 +129,7 @@ static void taskbutton_bar_init(
window_monitor_init_management(GTK_CONTAINER(self));
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
gtk_widget_set_hexpand(GTK_WIDGET(self), TRUE);
wintc_widget_add_style_class(GTK_WIDGET(self), "wintc-taskbuttons");

View File

@@ -1,22 +1,25 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shellext.h>
#include "../toolbar.h"
#include "../intapi.h"
#include "taskbuttonbar.h"
#include "toolbar.h"
//
// FORWARD DECLARATIONS
//
static void wintc_toolbar_task_buttons_constructed(
GObject* object
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCToolbarTaskButtonsClass
{
WinTCTaskbandToolbarClass __parent__;
};
struct _WinTCToolbarTaskButtons
{
WinTCTaskbandToolbar __parent__;
WinTCShextUIController __parent__;
};
//
@@ -25,21 +28,38 @@ struct _WinTCToolbarTaskButtons
G_DEFINE_TYPE(
WinTCToolbarTaskButtons,
wintc_toolbar_task_buttons,
WINTC_TYPE_TASKBAND_TOOLBAR
WINTC_TYPE_SHEXT_UI_CONTROLLER
)
static void wintc_toolbar_task_buttons_class_init(
WINTC_UNUSED(WinTCToolbarTaskButtonsClass* klass)
) {}
static void wintc_toolbar_task_buttons_init(
WinTCToolbarTaskButtons* self
WinTCToolbarTaskButtonsClass* klass
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
GObjectClass* object_class = G_OBJECT_CLASS(klass);
// Create root widget
//
toolbar->widget_root = taskbutton_bar_new();
object_class->constructed = wintc_toolbar_task_buttons_constructed;
}
static void wintc_toolbar_task_buttons_init(
WINTC_UNUSED(WinTCToolbarTaskButtons* self)
) {}
//
// CLASS VIRTUAL METHODS
//
static void wintc_toolbar_task_buttons_constructed(
GObject* object
)
{
(G_OBJECT_CLASS(wintc_toolbar_task_buttons_parent_class))
->constructed(object);
wintc_ishext_ui_host_get_ext_widget(
wintc_shext_ui_controller_get_ui_host(
WINTC_SHEXT_UI_CONTROLLER(object)
),
WINTC_TASKBAND_HOSTEXT_TOOLBAR,
GTK_TYPE_WIDGET,
taskbutton_bar_new()
);
}

View File

@@ -3,21 +3,20 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shellext.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCToolbarTaskButtonsClass WinTCToolbarTaskButtonsClass;
typedef struct _WinTCToolbarTaskButtons WinTCToolbarTaskButtons;
#define WINTC_TYPE_TOOLBAR_TASK_BUTTONS (wintc_toolbar_task_buttons_get_type())
#define WINTC_TYPE_TOOLBAR_TASK_BUTTONS (wintc_toolbar_task_buttons_get_type())
#define WINTC_TOOLBAR_TASK_BUTTONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtons))
#define WINTC_TOOLBAR_TASK_BUTTONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtonsClass))
#define IS_WINTC_TOOLBAR_TASK_BUTTONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TOOLBAR_TASK_BUTTONS))
#define IS_WINTC_TOOLBAR_TASK_BUTTONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TOOLBAR_TASK_BUTTONS))
#define WINTC_TOOLBAR_TASK_BUTTONS_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtons))
GType wintc_toolbar_task_buttons_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCToolbarTaskButtons,
wintc_toolbar_task_buttons,
WINTC,
TOOLBAR_TASK_BUTTONS,
WinTCShextUIController
)
#endif

View File

@@ -1,94 +0,0 @@
#include <glib.h>
#include <gtk/gtk.h>
#include "toolbar.h"
//
// PRIVATE ENUMS
//
enum
{
PROP_ROOT_WIDGET = 1
};
//
// FORWARD DECLARATIONS
//
static void wintc_taskband_toolbar_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCTaskbandToolbar,
wintc_taskband_toolbar,
G_TYPE_OBJECT
)
static void wintc_taskband_toolbar_class_init(
WinTCTaskbandToolbarClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->get_property = wintc_taskband_toolbar_get_property;
g_object_class_install_property(
object_class,
PROP_ROOT_WIDGET,
g_param_spec_object(
"root-widget",
"RootWidget",
"The GtkWidget that is the root of the toolbar.",
GTK_TYPE_WIDGET,
G_PARAM_READABLE
)
);
}
static void wintc_taskband_toolbar_init(
WinTCTaskbandToolbar* self
)
{
self->widget_root = NULL;
}
//
// PRIVATE FUNCTIONS
//
GtkWidget* wintc_taskband_toolbar_get_root_widget(
WinTCTaskbandToolbar* toolbar
)
{
return toolbar->widget_root;
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_taskband_toolbar_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
)
{
WinTCTaskbandToolbar* toolbar =
WINTC_TASKBAND_TOOLBAR(object);
switch (prop_id)
{
case PROP_ROOT_WIDGET:
g_value_set_object(value, toolbar->widget_root);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

View File

@@ -1,38 +0,0 @@
#ifndef __TOOLBAR_H__
#define __TOOLBAR_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCTaskbandToolbarClass
{
GObjectClass __parent__;
} WinTCTaskbandToolbarClass;
typedef struct _WinTCTaskbandToolbar
{
GObject __parent__;
GtkWidget* widget_root;
} WinTCTaskbandToolbar;
#define WINTC_TYPE_TASKBAND_TOOLBAR (wintc_taskband_toolbar_get_type())
#define WINTC_TASKBAND_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_TASKBAND_TOOLBAR, WinTCTaskbandToolbar))
#define WINTC_TASKBAND_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_TASKBAND_TOOLBAR, WinTCTaskbandToolbarClass))
#define IS_WINTC_TASKBAND_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_TASKBAND_TOOLBAR))
#define IS_WINTC_TASKBAND_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_TASKBAND_TOOLBAR))
#define WINTC_TASKBAND_TOOLBAR_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_TASKBAND_TOOLBAR, WinTCTaskbandToolbar))
GType wintc_taskband_toolbar_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_taskband_toolbar_get_root_widget(
WinTCTaskbandToolbar* toolbar
);
#endif

View File

@@ -3,9 +3,10 @@
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include "application.h"
#include "toolbar.h"
#include "intapi.h"
#include "window.h"
#include "start/toolbar.h"
#include "systray/toolbar.h"
@@ -29,14 +30,19 @@ typedef enum
//
// FORWARD DECLARATIONS
//
static void wintc_taskband_window_ishext_ui_host_interface_init(
WinTCIShextUIHostInterface* iface
);
static void wintc_taskband_window_dispose(
GObject* object
);
static WinTCTaskbandToolbar* wintc_taskband_window_create_toolbar(
WinTCTaskbandWindow* taskband,
GType toolbar_type,
gboolean expand
static GtkWidget* wintc_taskband_window_get_ext_widget(
WinTCIShextUIHost* host,
guint ext_id,
GType expected_type,
gpointer ctx
);
static gboolean on_window_map_event(
@@ -48,7 +54,7 @@ static gboolean on_window_map_event(
//
// STATIC DATA
//
static const WinTCTaskbandToolbarId s_layout[] = {
static const WinTCTaskbandToolbarId S_LAYOUT[] = {
WINTC_TASKBAND_TOOLBAR_START,
WINTC_TASKBAND_TOOLBAR_QUICK_ACCESS,
WINTC_TASKBAND_TOOLBAR_PRE_BUTTONS,
@@ -75,18 +81,22 @@ struct _WinTCTaskbandWindow
GSList* toolbars;
WinTCTaskbandToolbar* toolbar_notifarea;
WinTCTaskbandToolbar* toolbar_start;
WinTCTaskbandToolbar* toolbar_taskbuttons;
WinTCShextUIController* uictl_notifarea;
WinTCShextUIController* uictl_start;
WinTCShextUIController* uictl_taskbuttons;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
G_DEFINE_TYPE_WITH_CODE(
WinTCTaskbandWindow,
wintc_taskband_window,
GTK_TYPE_APPLICATION_WINDOW
GTK_TYPE_APPLICATION_WINDOW,
G_IMPLEMENT_INTERFACE(
WINTC_TYPE_ISHEXT_UI_HOST,
wintc_taskband_window_ishext_ui_host_interface_init
)
)
static void wintc_taskband_window_class_init(
@@ -134,20 +144,82 @@ static void wintc_taskband_window_init(
);
}
static void wintc_taskband_window_ishext_ui_host_interface_init(
WinTCIShextUIHostInterface* iface
)
{
iface->get_ext_widget = wintc_taskband_window_get_ext_widget;
}
//
// FORWARD DECLARATIONS
// CLASS VIRTUAL METHODS
//
static void wintc_taskband_window_dispose(
GObject* object
)
{
WinTCTaskbandWindow* wnd = WINTC_TASKBAND_WINDOW(object);
WinTCTaskbandWindow* taskband = WINTC_TASKBAND_WINDOW(object);
g_clear_slist(&(wnd->toolbars), g_object_unref);
g_clear_slist(&(taskband->toolbars), g_object_unref);
(G_OBJECT_CLASS(wintc_taskband_window_parent_class))->dispose(object);
}
//
// INTERFACE METHODS (WinTCIShextUIHost)
//
static GtkWidget* wintc_taskband_window_get_ext_widget(
WinTCIShextUIHost* host,
guint ext_id,
GType expected_type,
gpointer ctx
)
{
WinTCTaskbandWindow* taskband = WINTC_TASKBAND_WINDOW(host);
// Only toolbars are supported
//
if (ext_id != WINTC_TASKBAND_HOSTEXT_TOOLBAR)
{
g_critical("taskband: unsupported ext widget type: %d", ext_id);
return NULL;
}
// No special type expected, we host any kind of widget as a 'toolbar'
//
if (expected_type != GTK_TYPE_WIDGET || !GTK_IS_WIDGET(ctx))
{
g_critical("%s", "taskband: invalid ext widget type");
return NULL;
}
// Go ahead and import the widget
//
// FIXME: We expand based on hexpand... this isn't SUPER intuitive when
// vertical taskbar support is implemented, but it'll do
//
GtkWidget* toolbar = GTK_WIDGET(ctx);
gboolean expand = gtk_widget_get_hexpand(toolbar);
taskband->toolbars =
g_slist_append(
taskband->toolbars,
toolbar
);
gtk_box_pack_start(
GTK_BOX(taskband->main_box),
toolbar,
expand,
expand,
0
);
gtk_widget_show_all(toolbar);
return ctx;
}
//
// PUBLIC FUNCTIONS
//
@@ -173,43 +245,10 @@ void wintc_taskband_window_toggle_start_menu(
)
{
wintc_toolbar_start_toggle_menu(
WINTC_TOOLBAR_START(taskband->toolbar_start)
WINTC_TOOLBAR_START(taskband->uictl_start)
);
}
//
// PRIVATE FUNCTIONS
//
static WinTCTaskbandToolbar* wintc_taskband_window_create_toolbar(
WinTCTaskbandWindow* taskband,
GType toolbar_type,
gboolean expand
)
{
WinTCTaskbandToolbar* toolbar = g_object_new(toolbar_type, NULL);
GtkWidget* root = wintc_taskband_toolbar_get_root_widget(
toolbar
);
taskband->toolbars =
g_slist_append(
taskband->toolbars,
toolbar
);
gtk_box_pack_start(
GTK_BOX(taskband->main_box),
root,
expand,
expand,
0
);
gtk_widget_show_all(root);
return toolbar;
}
//
// CALLBACKS
//
@@ -223,41 +262,41 @@ static gboolean on_window_map_event(
// Spawn toolbars
//
for (guint i = 0; i < G_N_ELEMENTS(s_layout); i++)
for (guint i = 0; i < G_N_ELEMENTS(S_LAYOUT); i++)
{
switch (s_layout[i])
switch (S_LAYOUT[i])
{
case WINTC_TASKBAND_TOOLBAR_START:
taskband->toolbar_start =
wintc_taskband_window_create_toolbar(
taskband,
taskband->uictl_start =
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_TOOLBAR_START,
FALSE
WINTC_ISHEXT_UI_HOST(taskband)
);
break;
case WINTC_TASKBAND_TOOLBAR_BUTTONS:
taskband->toolbar_taskbuttons =
wintc_taskband_window_create_toolbar(
taskband,
taskband->uictl_taskbuttons =
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_TOOLBAR_TASK_BUTTONS,
TRUE
WINTC_ISHEXT_UI_HOST(taskband)
);
break;
case WINTC_TASKBAND_TOOLBAR_NOTIFICATION_AREA:
taskband->toolbar_notifarea =
wintc_taskband_window_create_toolbar(
taskband,
taskband->uictl_notifarea =
wintc_shext_ui_controller_new_from_type(
WINTC_TYPE_TOOLBAR_NOTIF_AREA,
FALSE
WINTC_ISHEXT_UI_HOST(taskband)
);
break;
case WINTC_TASKBAND_TOOLBAR_QUICK_ACCESS:
case WINTC_TASKBAND_TOOLBAR_PRE_BUTTONS:
case WINTC_TASKBAND_TOOLBAR_POST_BUTTONS:
WINTC_LOG_DEBUG("Not implemented toolbar: %d", s_layout[i]);
WINTC_LOG_DEBUG("Not implemented toolbar: %d", S_LAYOUT[i]);
break;
}
}